线上nginx proxy buffer导致的性能问题

最近有一个项目访问量突然变大,但发现前端的nginx负载会很高,导致出现4xx和5xx的异常,响应时间也变长了。今天有时间,解决了一下。下面记录一下解决思路和方法。
我们这个项目部署在azure。最前端是azure 的负载均衡器(lb),lb后面是2台nginx主机,型号是D2v3(2核8G)。在我们实际使用中,一台nginx主机rpm达到30k,cpu,内存,网络都是没有任何压力的。所以一台主机支持的最大访问量应该远远大于30k。但今天这个项目rpm撑到3k的时候,系统负载就很高了。这个项目后端应用向客户端下发一些数据,所以会比一般的项目流量大上很多。

下面是处理过程:
1、查看监控


通过grafana发现,系统cpu负载已经超过了2,最高的时候都超过了3,并且cpu消耗在io上的时间平均占到了20%左右。通过对比同时段的磁盘读写情况,基本可以断定是磁盘IO不够导致的。
但是磁盘IO为什么会不够呢?
2、磁盘IO慢,首先想到的是不是因为日志写的太多了。所以尝试给nginx设置日志buffer和刷新时间。
给access_log 增加两个参数buffer=512k flush=2s。表示日志攒够512k写一次磁盘。如果buffer没写满,强制2秒写一次磁盘。
修改后,观察效果,发现变化不大。所以断定,应该不是写日志导致的。
3、通过iostat命令来确定是那块磁盘有问题。

sda是系统分区所用磁盘,系统和软件会装在这个目录。sdb是azure自带的临时目录所用磁盘,重启主机后会情况。sdd是我们的数据目录所用磁盘,日志会放到这个目录。通过iostat发现,io压力主要集中在sda上。这就进一步能确定iowait跟nginx日志无关。
因为通过iotop发现确实是nginx进程在进行大量的写操作,所以断定应该是nginx proxy时将数据临时写入本地磁盘了。
4、nginx有几个相关的参数。

proxy_buffering:   设置是否缓存后端的responses。默认值是on,开启缓存。
proxy_temp_file_write_size:  开启缓存后,此值限制每次写入临时文件的大小。默认8k或者16k。
proxy_max_temp_file_size: 此值限制缓存文件的最大值。默认1G
proxy_temp_path: 指定缓存文件目录。可以在http,server和location分别定义。

5、根据azure的文档,os磁盘性能不是特别好,建议只运行系统。所以我把nginx的缓存目录全部改到我们的数据目录上。经测试,性能会好一些,但系统负载和iowait依然比较搞,但是异常少了很多。
6、彻底解决这个问题,应该是上性能更好的ssd。但是出于成本的考虑,并且项目访问总量不是也别大,估计同时需要缓存的文件不会很多,所以我决定将这个项目的proxy 缓存目录设置到内存盘里。
7、现在linux一般会开启tmpfs,就是系统将内存挂载到系统目录/dev/shm上。这个目录对应的是系统内存。默认大小为系统总内存的一半,但是并不真正占用这么多内存,其他应用依然可以使用这部分内存。相比自己创建ramdisk,少了格式化的操作,可谓是开箱即用。
8、为这是项目指定proxy_temp_path 到/dev/shm目录里

proxy_temp_path /dev/shm/proxy_temp 1 2;

修改后,iowait瞬间将为0,系统负载也降到0.1以下。/dev/shm只多了2g左右空间使用。
9、做好内存相关的监控,防止内存缓存文件撑爆内存。

至此,这件事情完美解决。

原文地址:https://blog.51cto.com/14601432/2485017

时间: 2024-12-08 15:57:26

线上nginx proxy buffer导致的性能问题的相关文章

FPM打包工具制作线上nginx的RPM包

一.安装FPM打包工具 1.FPM是ruby的模块,先安装FPM依赖的包 [[email protected] ~]#  yum -y install ruby rubygems ruby-devel rpm-build 2.因国内网络环境,访问http://rubygems.org/站点时不稳定,所以增加国内toabao提供的一个镜像站点,把原来的站点移除 [[email protected] ~]#  gem sources -a https://ruby.taobao.org/ [[ema

线上Nginx状态码为400解决

今天某公司对接我公司的一个api业务.当天下午客户在自己的线上业务平台下发送了第一个POST请求,结果我方在前端Nginx收到了状态码为400的响应.之前没有遇到过,google后得出结论,怀疑是客户系统在发送HTTP请求时,发送的请求头(Request Header)太大导致的.又想到客户公司是做安全的公司.所以在请求其他系统的时候,会多加一些加密参数到http请求头中. Nginx的http请求头由下面参数控制: client_header_buffer_size    默认  1k; la

线上nginx访问日志切割脚本

1.说明 随着时间的增加,nginx 的访问日志会越来越大,下图是新部署的线上 zabbix 监控网站运行了十几天左右产生的访问日志达到213M. 所以必须进行日志分割,要求如下: 1.每天的日志单独生成一个文件 2.保留30天的访问日志 2.编写脚本 vim /usr/local/nginx/logs/nginx_log_rotate.sh #! /bin/bash logs_path="/usr/local/nginx/logs/" log_name="access.lo

git 因线上分支名重复导致无法拉取代码

有时 git pull 或 git fetch 时发现 git 报了个异常,说法像是无法将线上某个分支与本地分支合并,由于分支是...(很长的hash)但是分支却是...(很长的hash) 仔细查查后发现是 git 远端出现了重复的分支名导致的,故此删除掉重复的那个不需要的远端分支即可 git push origin :origin/branchName 其作用是提交一个空的分支到远端的 branchName 的分支,由于分支为空,git 便将其删除了. 然后发现了一同开发的队友出问题了,明明远

线上nginx的一次“no live upstreams while connecting to upstream ”分析

先描述一下环境,前段的负载均衡转发给nginx,nginx再转发给后端的应用服务器. nginx配置文件如下: upstream ads { server ap1:8888 max_fails=1 fail_timeout=60s; server ap2:8888 max_fails=1 fail_timeout=60s; } 出现的现象是: 日志里面每隔一两分钟就会记录一条类似 *379803415 no live upstreams while connecting to upstream 

线上nginx日志无切割引起的祸

状况:lnmp环境下nginx反向代理服务器,部分网站无法访问,重启服务器后ok 拿到权限后安装zabbix监控,负载Ok , IO报警: Disk I/O is overloaded on xss152 使用命令工具查看io状况,top下78%wa........................ [[email protected] /]#  iostat -x 1 10  avg-cpu:  %user   %nice %system %iowait  %steal   %idle     

vue cli 解决跨域 线上 nginx 反向代理配置

前后分离 axios 接 api 跨域问题如图: 解决办法: 1. npm start 本地开发环境解决: 在webpack配置文件 /config/index.js 里找到 proxyTable 开启代理 changeOrigin:true, proxyTable: { '/api':{ target:'http://xx.xx.xx.xx:5568', changeOrigin:true, pathRewrite:{ '^/api':'/api' } } }, 2. npm run buil

性能测试之线上引流测试--让性能测试更真实更丰富

为什么要做引流测试 目前为止大部分的测试是在测试环境下,通过模拟用户的行为来对系统进行验证,包括功能以及性能.在这个过程中,你可能会遇到以下问题: 用户访问行为比较复杂,模拟很难和用户行为一致,模拟不够真实; 线下模拟场景有限,会出现业务覆盖不全的情况.引流测试就是为了解决以上问题,通过把线上的真实流量复制到线下环境,解决测试环境模拟不够真实,或覆盖不够全面的问题. 引流的做法 目前不少公司对引流测试进行了实践,主要有以下4种引流方式: 以上几种办法各有利弊,有的是需要自己开发相应的工具来支持.

(转) 发布或重启线上服务时抖动问题解决方案

转自 http://www.cnblogs.com/LBSer/p/3703967.html 相关: load.jstack.Java编译.Java运行模式 一.问题描述       在发布或重启某线上某服务时(jetty8作为服务器),常常发现有些机器的load会飙到非常高(高达70),并持续较长一段时间(5分钟)后回落(图1),与此同时响应时间曲线(图2)也与load曲线一致.注:load飙高的初始时刻是应用服务端口打开,流量打入时(Load指的是运行队列(run-queue)的长度:L=等