Written in front

Recently, I have been studying and testing nginx server. I reviewed the knowledge of computer network a few days ago (on the one hand, I was interested in it, on the other hand, because these computer bases were forgotten in the learning process, there were many details that were very confusing). I also tried it on Linux.tcpdumpCommand to verify all previous guesses (because I don’t understand, I guess) by grabbing packets. Wireshark is still used to analyze packets.

I always thought that as long as HTTP1.1 protocol was used, the connection could be reused, saving the time consumption of shaking hands and waving hands repeatedly. However, I found that the use of “simple” long connection really involves a lot of configurations in nginx, JMeter and Tomcat.

  • JMeter has checked use keepalive by default in the configuration of HTTP request, but it does not take effect in actual use.
  • Nginx involves configuration with clientskeepalive_timeoutandkeepalive_requests, configuration with backend serverkeepalive(after 1.15.3, the upstream module has also been added.keepalive_timeoutandkeepalive_requests(not involved in this article)
  • Tomcat also has one by defaultkeepAliveTimeoutTo configure

After knowing these related configurations, on the one hand, I want to make a real battletcpdumpAnd Wireshark. On the one hand, we also want to use data to verify the three configurations of nginx, so we have the following content.


Environmental description

  • Nginx 1.14.0
  • Linux 2.6.32
  • JMeter 5.0
  • Wireshark 2.6.4
  • JMeter host IP 172.16.40.199
  • Tomcat host IP 172.16.40.201
  • Host IP 172.16.40.224 of nginx

0. Long connection timeout with client

Instruction specification

Syntax: keepalive Ou timeouttimeout [header_timeout];

Default value: keepalive Ou timeout 75s;

Context: http, server, location

The first parameter sets the maximum time that the client’s long connection remains on the server side (in this time, if the client does not initiate a new request, the long connection is closed). The second parameter is optional. Set the value of “keep alive: timeout = time” response header. You can set different values for these two parameters.

“Keep alive: timeout = time” response headers can be recognized and processed by Mozilla and Konqueror browsers. MSIE will close the long connection in about 60 seconds.

test plan

keepalive_timeout = 1

The client continuously initiates HTTP request and does not actively close the connection. Observe the release time of the connection.

Testing process

When testing with JMeter, it was found that the long connection could not be maintained. At the end of the request, JMeter initiated the connection closure itself. Modify the relevant configurations in jmeter.properties and user.properties according to the official wiki instructions. After testing, it did not take effect. Finally, the test was done with the code written by httpclient of Apache.

In the code, multiple threads are cyclically started, and each thread continuously starts 10 requests, and the client and response are not shut down after execution.

test result

Verify nginx's keep alive configuration

The result shows

As mentioned above, the test client initiates several requests and does not close the connection at the end of the request (there is a small problem here. The connection is not reused. It may be that the client connection pool needs to be configured, but I haven’t made a toss yet)

After 1 second (timeout), the nginx server initiates the shutdown request.


1. Number of long connection requests with clients

Instruction specification

Syntax: keepalive Fu requestsnumber

Default value: keepalive’requests 100

Context: http, server, location

This instruction appears in version 0.8.0

Sets the maximum number of requests that can be processed over a long connection. If the number of requests exceeds this value, the long connection will be closed.

test plan

keepalive_requests = 5

UsecurlCommand, send 8 requests (more than the number of keepalive “requests), and observe whether the connection is disconnected after 5 requests

Testing process

Initially using for loop executioncurlCommand. Once the command is executed, the connection is immediately released. After checking on the Internet, you can access it multiple times in a command, for example:

curl http://172.16.40.224:6066/NginxTest/hi http://172.16.40.224:6066/NginxTest/hi http://172.16.40.224:6066/NginxTest/hi http://172.16.40.224:6066/NginxTest/hi http://172.16.40.224:6066/NginxTest/hi http://172.16.40.224:6066/NginxTest/hi http://172.16.40.224:6066/NginxTest/hi http://172.16.40.224:6066/NginxTest/hi

In this way, the connection will be closed after 8 requests are completed.

test result

Verify nginx's keep alive configuration

The result shows

It can be seen that the first TCP connection initiated 5 HTTP requests, followed by the closing initiated by nginx.

The second TCP connection initiates the remaining three HTTP requests, followed by a client initiated shutdown


2. Number of long connections with back-end servers

Instruction specification

Syntax: keepaliveconnections

Default value: —

Context: upstream

This instruction appears in version 1.1.4

The connections parameter sets the maximum number of connections each worker process can maintain with the back-end server. These maintained connections are put into the cache. If the number of connections is greater than this value, the oldest unused connections will be closed.

test plan

keepalive = 10

Start more than keepalive test processes with JMeter, and observe the connection closure after the test.

Testing process

Use JMeter’s GUI client to edit a test script to start 50 processes and cycle the test for 120 seconds

test result

Verify nginx's keep alive configuration

The result shows

It can be seen that as of 118 seconds (JMeter gradually stops initiating test requests), TCP connections are being closed one by one. The screenshots are mostly the fin packets that the back-end server responds to. A little bit forward, you can see that the closing requests initiated by nginx are all active.

Starting from 138 seconds (the default long connection timeout time of the backend Tomcat server is 20 seconds), the remaining 10 long connections are closed by the backend server.


Last

The testing process involvestcpdumpThe order is

sudo tcpdump -i eth0 host 172.16.40.xxx -w dumplog.pcap

-I designated network card
Host specifies which IP to grab packets from
-W save the grab results to a pcap file for viewing with Wireshark

Through the above three tests, we understand and verify the long connection usage of nginx in client oriented and back-end server oriented respectively.


Advertising

The article was first published on the personal blog “verifying the keepalive configuration of nginx”