Windows环境下的Nginx高并发实现

2019-10-09 05:48岳晋温宇黄旻亮
电子技术与软件工程 2019年17期
关键词:代理服务器后台进程

文/岳晋 温宇 黄旻亮

1 引言

Nginx是高性能的Http和反向代理服务器,在Linux环境下,其可以采用epoll作为网络I/O模型。在高并发连接的情况下,其是Apache服务器不错的替代品。Nginx具有高并发连接、内存占用低、成本低等特点。

Nginx运行时,会存在一个主进程和多个工作进程。工作进程的数目可以在配置文件中进行指定,通常设置为CPU的核数。主进程用于管理工作进程的运行,并处置工作进程的异常情况。借助于主进程和工作进程的模式,Nginx可以实现平滑升级、配置即时生效等功能。而工作进程的任务相对单一,主要用于处理业务请求,它们彼此独立,互不影响。此外,借助于异步非阻塞的工作机制,Nginx可以处理上万的并发请求。

反向代理是Nginx的主要应用场景之一。反向代理是相对于正向代理来说,一般情况下,内网的客户机通过代理服务器访问公网上服务的这种模式是正向代理。与此相反,当代理服务器的作用是将后台服务器隐藏起来,并根据客户机的请求,分发给后台服务器的这种方式是反向代理。Nginx反向代理的原理如图1所示。

图1中,Nginx代理服务器接收到来自客户端的请求,根据自己的配置,决定将该请求转发给哪个业务服务器。当业务服务器处理完该请求后,将响应结果交给Nginx代理服务器,Nginx代理服务器再将响应内容返回给客户机。

反向代理可以保护后端服务器,此外,还可以用作负载均衡,来平衡后端服务器的性能压力。Nginx通过proxy_pass命令和upstream模块,就可以实现反向代理。如果后台服务和Nginx在同一机器上,但运行在不同的端口上,Nginx可以将请求转发到后台服务运行的端口上。通常情况下,后台服务和Nginx不在一台服务器上,这时候Nginx可以将请求发送给upstream模块,再通过upstream模块转发给后台服务器。而且在upstream模块中,也可以进行负载均衡相关的配置。

Nginx的另一主要应用场景是负载均衡。负载均衡是在各服务器之间均衡业务压力,Nginx的负载均衡策略包括轮询、指定权重、fair、ip_hash和url_hash等。

2 Nginx性能调优相关配置

2.1 stub_status监控模块

Windows版本的Nginx默认开启了stub_status模块来查看Nginx的一些状态信息。此外,还需要在nginx.conf(Nginx的主要配置文件)中增加如下配置。

location/nginx_status{

stub_status;

allow 127.0.0.1;

}

这样,通过访问对应的url就可以打开监控页面。监控页面上的监控数据如下所示:

Active connections: 6

Server accepts handled requests:

12053 12053 17528

Reading: 0 Writing: 2 Waiting: 4

其中,active connection 6; 对上游服务发起的连接数,需要注意的是,如果reading或者writing的值很高,说明正在处理的数据量较大,可能是因为后台服务处理慢,这个时候需要对后台进行优化。

在使用长连接的情况下,waiting的值代表有多少个连接在等待新的请求。waiting表明Nginx已经将请求处理完毕,并且把数据返回给了客户端,该连接已经闲置,正在等待下一次请求。因此,这个值比较高说明请求处理得很快。一般应是writing和reading越小越好,而waiting越高越高。

2.2 优化性能相关的配置参数

为获取较高的并发性能,需要对Nginx的主要配置参数进行调优。主要的配置参数及调优如下。

2.2.1 multi_accept on

如果multi_accept被禁止了,Nginx的一个工作进程只能同时接受一个新的连接,否则,一个工作进程可以接受所有的新连接。这个时候在监控页面上看到的active connections通常是很低的,因此,需要开启该参数,该配置对于提高Nginx的并发至为关键。

2.2.2 worker_processes

worker_processes后面的数值一般设置为CPU的核数,代表Nginx开启的工作进程的数目。例如,worker_processes 8代表开启8个工作进程。

2.2.3 worker_connections

配置一个工作进程能够处理的并发连接请求的数目。考虑高并发场景,将其设置为一个比较大的值。例如,worker_connections 40960,在Windows服务器下,该参数一般不超过65535。

2.2.4 worker_rlimit_nofile

配置一个工作进程能够打开的文件句柄数上限。在高并发场景下,也需要设置为比较大的值,例如,worker_limit_nofile 40960。

2.2.5 sendfile

将该参数打开可以提高发送文件的效率,采用如下配置打开此参数,sendfile on。

图1:Nginx反向代理处理流程

2.2.6 tcp_nopush

打开tcp_nopush后,将会在发送响应时,把整个响应头放在一个tcp包中发送,能够达到优化吞吐的效果,建议打开。

2.2.7 tcp_nodelay

该参数打开后,会关闭Nagle算法,保证高频发送小数据报文的实时性,建议打开。

2.2.8 access_log

设置为on时,会保存Nginx代理的访问请求。将这个设置关闭,会降低磁盘IO而提升速度。在生产环境,当确保Nginx不会出现问题后,可以将该参数设置为off。

2.2.9 gzip

该参数设置是否压缩发送数据,建议打开。gzip_comp_level 数据压缩的等级,可以是1~9的任意一个值,9表示最慢但最高比例的压缩。gzip_types 设置gzip的类型。

2.2.10 open_file_cache

open_file_cache 缓存最大数目及超时时间。open_file_cache_vaild 用于设置检测缓存源文件是否超时的时间间隔。open_file_cache_min_uses设置缓存文件最小访问次数。open_file_cache_errors设置是否保存缓存文件的错误信息。

2.2.11 proxy_buffering

proxy_buffering该参数用于设置是否开启响应内容的缓冲。如果关闭该参数,那么proxy_buffers和proxy_busy_buffers_size的配置将无效。但是,proxy_buffer_size是否生效与proxy_buffering参数的设置无关。如果开启proxy_buffering下,响应内容会被Nginx先存入缓冲区中,之后再传递给客户端。缓存区的临时文件由proxy_max_temp_file_size

和proxy_temp_file_write_size决定。当内存中的无非存储响应内容时,会在磁盘中存储部分响应内容。

当关闭proxy_buffering后,Nginx不再缓存后端返回的响应内容,而是直接传递给客户端。proxy_buffers配置接收一次响应的buffer个数和每个buffer的大小。proxy_busy_buffers_size 如果系统很忙的时候,可以申请更大的proxy_buffers,官方推荐乘2。proxy_temp_path path配置临时文件目录,proxy_temp_file_write_size缓存临时文件的大小,proxy_max_temp_file_size 配置所有临时文件的总大小。配置实例如下,

proxy_buffering on;

proxy_buffer_size 64k; proxy_buffers 4 32k;

proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; proxy_max_temp_file_size 1024m;

2.2.12 keepalive

为提高并发能力,需要对长连接进行优化。主要包括keepalive_timeout和keepalive_requests,keepalive_timeout表 示keepAlive的超时时间,也就是在超时时间内,如果客户端没有后续请求过来,Nginx就会断掉这个Tcp连接。如果设置为0,表示禁用keepAlive。keepalive_timeout表示一个长连接,Nginx处理的请求上限,keepalive_timeout可以根据实际情况设置为一个较大的值。

3 Windows服务器下实现Nginx高并发的关键操作

3.1 采用Windows专用版本的Nginx

图2:10秒思考时间下,LoadRunner模拟5000用户并发压测某业务结果

在实际压测并发能力的过程中,发现当并发超过1023后,Nginx会拒绝连接,并打印错误日志“maximum number of descriptors supported by select() is 1024 while waiting for request”。主要原因是在Windows环境下,尽管修改了worker_connections,但无法生效。为解决此问题,可以在网站http://nginx.org/en/download.html上获取修改了最大文件描述符限制的Nginx版本,该版本的Nginx尽管无非使用epoll机制,但该专用版本已经提供了尽可能多的功能,并针对Windows环境做了优化,其可以支持每秒几千到几万的并发请求。并且,其商业版本也可以提供付费的技术支持服务。因此,在Windows环境下,为提高并发能力,需使用Windows专用版本的Nginx。

3.2 解决高并发情形下的Windows服务器TCP连接端口耗尽问题

在每秒创建的新连接比较多且持续创建的情况下,运行一段时间后,Nginx会拒绝连接,并打印错误日志。“An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue is full while connecting to upstream”,该 报错的原因主要有两种情况,第一种就是TCP连接端口耗尽,第二种是超过了socket队列能够处理的最大连接。其中,第二种情况可以通过配置backlog解决,如,listen 8080 backlog=40960。

第一种TCP连接端口耗尽的情况,在Windows环境下比较难处理。Windows server 2008在默认情况下,给TCP连接提供的端口只有16384个,可以通过在命令行输入“netsh int ipv4 show dynamicport tcp”查看。对于每个新的客户端连接,Nginx除了和客户端建立连接外,和后端服务器也建立了一个临时的TCP连接。这个临时的TCP连接就是端口耗尽的根源

根据TCP/IP原理,TCP连接在进行“四次挥手”断开连接时,首先断开连接的一方会进入“timewait”状态,在timewait状态内,由(源ip,源端口,目的ip,目的端口)组成的四元组是不允许被重用的。

针对TCP连接端口耗尽问题,在Windows服务器上,可以通过多种方式改善该问题,第一种是通过“netsh int ipv4 set dynamicport tcp start=5000 num=60000”,增加TCP连接的可用端口数。第二种是通过在注册表的HKEY_LOCAL_MACHINESYSTEMCurrentControlSetserviceTcpipParameters增加TcpTimedWaitDelay的REG_DWORD参数,并将其设置为30。这种方法是将TCP连接timewait的时间(范围为30秒到240秒)降低为30秒,修改完成后,重启机器生效。

此外,还可以对客户端请求进行限速,对单个ip短时间内多个TCP连接排队处理。

另外,可以在upstream中配置keepalive xxx,其中xxx可以设置为1000。原因是nginx和后端服务器之间的连接为短连接,且无连接复用,这样在高并发场景下,会造成端口的耗尽。通过以上配置,并配合proxy_http_version 1.1和proxy_set_header Connection "",就可以较好地解决端口耗尽问题。

通过对配置的调优,在Windows环境下,也达到了上万的活跃连接数,如下监控数据所示。

Active connections: 10003

Server accepts handled requests:

559064 559064 7196725

Reading: 0 Writing: 6678 Waiting: 3324

使用Nginx反向代理某一Web服务,并使用LoadRunner进行压力测试,模拟5000用户并发访问该服务,其测试结果如图2所示。

图2中,第一行的图代表用户的并发数,其是从0逐渐增加到5000,然后再下降到0。第二行的图是HPS(hits per second)的结果图,图中瞬时HPS可以达到2500以上,说明该方案在Windows环境下可以提供较高的并发能力。

4 结论

Windows环境下,Nginx的并发性能会存在一定的瓶颈。本文通过对Nginx的主要配置进行调优,并采用Windows专用版本的Nginx,较好地解决了高并发情形下TCP连接端口耗尽等性能瓶颈,并实现了Windows生产环境下的Nginx高并发处理。

猜你喜欢
代理服务器后台进程
债券市场对外开放的进程与展望
地铁信号系统中代理服务器的设计与实现
IP地址隐藏器
后台暗恋
前台、后台精彩花絮停不了
以“后台”的名义节省电池用量
社会进程中的新闻学探寻
电力调度中后台监控系统的应用
我国高等教育改革进程与反思
Linux僵死进程的产生与避免