默认Nginx是经过优化的,而我们针对Nginx优化主要集中在配置调整上。如果优化后效果不理想,则增加硬件,如增加机器数量、结合F5负载等。
4.3节中的Nginx配置可进行的优化如下。
1)worker_processes:表示worker进程数量。worker_processes默认情况下为1,官方的建议是修改成CPU的内核数,增加worker_processes数量,充分利用I/O带宽,以减小机器I/O带来的影响。
服务器A 2C/4G,测试运行结果如下:
2)worker_connections:表示work进程连接数量,默认是1024。worker_connections优化需要考量两个指标,即内存和操作系统级别的“进程最大可打开文件数”。建议设置到65535,可根据内存自行调整。
3)keepalive_timeout:表示KeepAlive的超时时间,指定每个TCP连接最多可以保持多长时间。Nginx的默认值是75秒。
【示例】 以电商网站上传附件功能为例,客户端使用Nginx反向代理。
对于电商后台管理模块来说,运营人员每天会定时上传商品的附件,有时上传的附件较大,需要等待很久服务器才响应,有时候超过默认值后会提示“超时”等现象。经日志分析请求发现,超时等问题和Nginx的keepalive_timeout配置项相关。页面请求后端采用HTTP方式。由于HTTP底层采用TCP协议网络传输,故当上传附件时页面会向服务端发送一个请求,由于附件过大,上传处理时间超过了TCP连接最多可以保持时间,从而导致“超时”等异常。
评估附件上传的平均时长后,更改keepalive_timeout默认配置项,将其调整到500,运行过程中不再出现“超时”等现象。在后续运行过程中,发现批量上传的视频数量较多时,会出现部分视频上传失败的问题,日志提示“socket() failed (24: Too many open files) while connecting to upstream”。分析可知,是连接数不够,于是调制worker_connections默认连接数到8729。之后批量上传视频时,在视频的大小均衡且总数量偏小的情况下功能正常。但当出现视频大小不均衡并且总数量偏大情况,部分视频还会上传失败。
继续分析日志,发现由于keepalive_timeout设置过长,在上传视频时,有些请求传输的过程会很快执行完毕,如果超时时间设置过长,因处理完毕的请求连接没有被释放掉,所以会导致请求过多积累后会出现异常。
那么如何合理设置keepalive_timeout的时间呢?
优化思路:在存在一些业务功能比较耗时的情况下,可以优化程序,比如采用同步转异步、多线程等优化手段,这样可提高应用程序整体的执行效率,减少响应时间。不要因为业务功能而牺牲其他网络、系统、代理相关的服务,由于部分浏览器仅支持最多保持在60s左右,所以把keepalive_timeout调整到60s左右比较合理,如keepalive_timeout 60。
4)gzip:表示Nginx采用Gzip压缩的形式发送数据。这将减少我们发送的数据量,建议开启该功能,即gzip on。
5)gzip_proxied:允许或者禁止压缩基于请求和响应的响应流。比如,gzip_proxied any表示压缩所有的请求。
6)gzip_min_length:表示数据启用压缩的最少字节数,建议请求大于1KB及以上时进行压缩,如gzip_min_length 1000。压缩过小的数据会降低处理此请求的所有进程的速度。
7)gzip_comp_level:表示开启Gzip压缩。Gzip的压缩参数值的范围是1到9,那么,将其设置为多少合适呢?
【示例】 静态文件包括4个H5文件、4个JS、2个CSS文件,合计大小为380KB,设置gzip_comp_level参数从1到9的结果如下:
随着压缩比例升高,CPU消耗也不断升高,正常虚拟机2C/4G建议设置为4,4C/8G建设设置为5。建议根据服务器的配置取值4或5即可。
8)gzip_type:设置需要压缩的数据格式。如gzip_type text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript。
9)access_log:设置Nginx是否存储访问日志。如有其他日志记录,建议关闭这个选项,这样可以有效让读取磁盘的I/O操作执行得更快,如access_log off。
10)sendfile:表示是否使用sendfile来传输文件,若使用,可实现在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免数据在内核缓冲区和用户缓冲区之间的重复拷贝,提高操作效率,被称为零拷贝。建议开启,即sendfile on。
11)tcp_nopush:表示Nginx在一个数据包里发送所有头文件,而不是一个接一个地发送。建议开启,即tcp_nopush on。
12)tcp_nodelay:表示Nginx不要缓存数据,而是一段一段地发送。当需要及时发送数据时,就应该给应用设置这个属性,这样发送一小块数据信息时就不能立即得到返回值。建议开启,即tcp_nodelay on。
13)reset_timeout_connection:关闭不响应的客户端连接,释放客户端占有的内存空间。
14)client_header_buffer_size:表示为请求头分配一个缓冲区,这样能减少一次内存分配。当大部分请求头很大时,建议设置client_header_buffer_size。
15)large_client_header_buffers:表示请求中只有少量请求头很大,仅需在处理大头部时分配更多的空间,从而减少无谓的内存浪费。
16)client_body_buffer_size:表示处理客户端请求体buffer的大小。设置缓冲区buffer大小,可用来处理POST请求数据、上传文件。缓冲区过小会导致Nginx把内容写到磁盘,使用临时文件存储response,会引起磁盘读写I/O。