系统性能分析工具sysstat之sar命令以及nginx中打开gzip使用配置gzip_http_version值为1.0和1.1时遇到的结果乱码问题

一、系统性能分析工具:sysstat之sar命令

服务器维护常用的管理命令有很多:top、ps,、pstree、vmstat、iostat、iotop等,但好像都不全面,这里有一个比较系统全面的性能分析工具sar(System Activity Reporter系统活动情况报告)。

sar可以从多方面对系统的活动进行报告,包括文件的读写、系统调用、磁盘I/O、CPU效率、内存状况、进程活动及IPC有关的活动等。sar和iotop、iostat在一起,林戈技术笔记 8408.cn___一名IT人员的在线技术笔记

通过yum安装sysstat来实现功能:yum install -y sysstat

sar命令常用格式 sar [options] [-A] [-o file] t [n]

t为采样间隔,n为采样次数,默认值是1;

-o file表示将命令结果以二进制格式存放在文件中,file 是文件名。

options 为命令行选项

1. sar命令常用选项如下:

bash 复制代码
[hello@07 ~]#     sar --help
Usage: sar [ options ] [ <interval> [ <count> ] ]
Options are:
[ -A ] [ -b ] [ -B ] [ -C ] [ -d ] [ -h ] [ -m ] [ -p ] [ -q ] [ -r ] [ -R ]
[ -S ] [ -t ] [ -u [ ALL ] ] [ -v ] [ -V ] [ -w ] [ -W ] [ -y ]
[ -I { <int> [,...] | SUM | ALL | XALL } ] [ -P { <cpu> [,...] | ALL } ]
[ -j { ID | LABEL | PATH | UUID | ... } ] [ -n { <keyword> [,...] | ALL } ]
[ -o [ <filename> ] | -f [ <filename> ] ] [ --legacy ]
[ -i <interval> ] [ -s [ <hh:mm:ss> ] ] [ -e [ <hh:mm:ss> ] ]

2. sar命令的选项意义如下:

-A:所有报告的总和

-u:输出CPU使用情况的统计信息

-v:输出inode、文件和其他内核表的统计信息

-d:输出每一个块设备的活动信息

-r:输出内存和交换空间的统计信息

-b:显示I/O和传送速率的统计信息

-a:文件读写情况

-c:输出进程统计信息,每秒创建的进程数

-R:输出内存页面的统计信息

-y:终端设备活动情况

-w:输出系统交换活动信息

3. CPU资源监控

bash 复制代码
[hello@007 ~]# sar -u  1 3 
Linux 2.6.32-642.6.2.el6.x86_64 (04007.cn)      08/09/2019      _x86_64_        (1 CPU)
03:57:10 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
03:57:11 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
03:57:12 PM     all      0.99      0.00      0.99      0.00      0.00     98.02
03:57:13 PM     all      0.00      0.00      0.00      1.01      0.00     98.99
Average:        all      0.33      0.00      0.33      0.33      0.00     99.00

%iowait:显示用于等待I/O操作占用 CPU 总时间的百分比。

%steal:管理程序(hypervisor)为另一个虚拟进程提供服务而等待虚拟 CPU 的百分比。

%idle:显示 CPU 空闲时间占用 CPU 总时间的百分比。

  1. 若 %iowait 的值过高,表示硬盘存在I/O瓶颈

  2. 若 %idle 的值高但系统响应慢时,有可能是CPU等待分配内存,此时应加大内存容量

  3. 若 %idle 的值持续低于1,则系统的 CPU 处理能力相对较低,表明系统中最需要解决的资源是CPU

4. inode、文件和其他内核表监控

bash 复制代码
[hello@007 ~]# sar -v 1 3 
Linux 2.6.32-642.6.2.el6.x86_64 (04007.cn)      08/09/2019      _x86_64_        (1 CPU)
03:57:38 PM dentunusd   file-nr  inode-nr    pty-nr
03:57:39 PM     20890      1408     26456         2
03:57:40 PM     20899      1408     26465         2
03:57:41 PM     20907      1408     26473         2
Average:        20899      1408     26465         2

dentunusd:目录高速缓存中未被使用的条目数量

file-nr:文件句柄(file handle)的使用数量

inode-nr:索引节点句柄(inode handle)的使用数量

pty-nr:使用的pty数量

5. 内存和交换空间监控

bash 复制代码
[hello@007 ~]# sar -r 1 3 
Linux 2.6.32-642.6.2.el6.x86_64 (04007.cn)      08/09/2019      _x86_64_        (1 CPU)
04:00:53 PM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit
04:00:54 PM     71736    948272     92.97     50888    371260   1183812    116.06
04:00:55 PM     71736    948272     92.97     50888    371260   1183812    116.06
04:00:56 PM     71736    948272     92.97     50896    371260   1183812    116.06
Average:        71736    948272     92.97     50891    371260   1183812    116.06

%memused:这个值是kbmemused和内存总量(不包括swap)的一个百分比.

kbcommit:保证当前系统所需要的内存,即为了确保不溢出而需要的内存(RAM+swap).

%commit:这个值是kbcommit与内存总量(包括swap)的一个百分比.

6. 内存分页监控

bash 复制代码
[hello@007 ~]# sar -B 1 3 
Linux 2.6.32-642.6.2.el6.x86_64 (04007.cn)      08/09/2019      _x86_64_        (1 CPU)
03:58:32 PM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
03:58:33 PM      0.00    432.65     32.65      0.00     56.12      0.00      0.00      0.00      0.00
03:58:34 PM      0.00      0.00     35.00      0.00     59.00      0.00      0.00      0.00      0.00
03:58:35 PM      0.00      0.00    667.00      0.00    922.00      0.00      0.00      0.00      0.00
Average:         0.00    142.28    246.31      0.00    347.65      0.00      0.00      0.00      0.00

pgpgin/s:表示每秒从磁盘或SWAP置换到内存的字节数(KB)

pgpgout/s:表示每秒从内存置换到磁盘或SWAP的字节数(KB)

fault/s:每秒钟系统产生的缺页数,即主缺页与次缺页之和(major + minor)

majflt/s:每秒钟产生的主缺页数.

pgfree/s:每秒被放入空闲队列中的页个数

pgscank/s:每秒被kswapd扫描的页个数

pgscand/s:每秒直接被扫描的页个数

pgsteal/s:每秒钟从cache中被清除来满足内存需要的页个数

%vmeff:每秒清除的页(pgsteal)占总扫描页(pgscank+pgscand)的百分比

7. I/O和传送速率监控

bash 复制代码
[hello@007 ~]# sar -b 1 3 
Linux 2.6.32-642.6.2.el6.x86_64 (04007.cn)      08/09/2019      _x86_64_        (1 CPU)
04:01:32 PM       tps      rtps      wtps   bread/s   bwrtn/s
04:01:33 PM      0.00      0.00      0.00      0.00      0.00
04:01:34 PM      0.00      0.00      0.00      0.00      0.00
04:01:35 PM      0.00      0.00      0.00      0.00      0.00
Average:         0.00      0.00      0.00      0.00      0.00

tps:每秒钟物理设备的 I/O 传输总量

rtps:每秒钟从物理设备读入的数据总量

wtps:每秒钟向物理设备写入的数据总量

bread/s:每秒钟从物理设备读入的数据量,单位为 块/s

bwrtn/s:每秒钟向物理设备写入的数据量,单位为 块/s

8. 进程队列长度和平均负载状态监控

bash 复制代码
[hello@007 ~]# sar -q 1 3 
Linux 2.6.32-642.6.2.el6.x86_64 (04007.cn)      08/09/2019      _x86_64_        (1 CPU)
04:01:59 PM   runq-sz  plist-sz   ldavg-1   ldavg-5  ldavg-15
04:02:00 PM         0       277      0.00      0.00      0.00
04:02:01 PM         1       279      0.00      0.00      0.00
04:02:02 PM         0       278      0.00      0.00      0.00
Average:            0       278      0.00      0.00      0.00

runq-sz:运行队列的长度(等待运行的进程数)

plist-sz:进程列表中进程(processes)和线程(threads)的数量

ldavg-1:最后1分钟的系统平均负载(System load average)

ldavg-5:过去5分钟的系统平均负载

ldavg-15:过去15分钟的系统平均负载

9. 系统交换活动信息监控

bash 复制代码
[hello@007 ~]# sar -W 1 3     
Linux 2.6.32-642.6.2.el6.x86_64 (04007.cn)      08/09/2019      _x86_64_        (1 CPU)
04:02:29 PM  pswpin/s pswpout/s
04:02:30 PM      0.00      0.00
04:02:31 PM      0.00      0.00
04:02:32 PM      0.00      0.00
Average:         0.00      0.00

pswpin/s:每秒系统换入的交换页面(swap page)数量

pswpout/s:每秒系统换出的交换页面(swap page)数量

10. 网卡流量监控

bash 复制代码
[hello@007 ~]#  sar -n DEV 1 3
Linux 2.6.32-642.6.2.el6.x86_64 (04007.cn)      08/09/2019      _x86_64_        (1 CPU)
04:27:53 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
04:27:54 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
04:27:54 PM      eth0      0.00      0.00      0.00      0.00      0.00      0.00      0.00
04:27:54 PM      eth1      2.02      1.01      0.12      0.12      0.00      0.00      0.00

04:27:54 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
04:27:55 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
04:27:55 PM      eth0      0.00      0.00      0.00      0.00      0.00      0.00      0.00
04:27:55 PM      eth1      1.00      1.00      0.06      0.18      0.00      0.00      0.00

04:27:55 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
04:27:56 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
04:27:56 PM      eth0      0.00      0.00      0.00      0.00      0.00      0.00      0.00
04:27:56 PM      eth1      1.01      1.01      0.07      0.48      0.00      0.00      0.00

Average:        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
Average:           lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
Average:         eth0      0.00      0.00      0.00      0.00      0.00      0.00      0.00
Average:         eth1      1.34      1.01      0.08      0.26      0.00      0.00      0.00

IFACE:表示设备名称

rxpck/s:表示每秒进入收取包的数量

txpck/s:每秒发送出去的包的数量

rxKB/s:每秒收取的数据量(单位KByte)

txKB/s:每秒发送的数据量

如果服务器丢包严重,就要查看一下网卡流量

如果rxpck/s数值大于4000,或者rxKB/大于5000,很有可能被×××了。

查看时时网卡流量 sar -n DEV 1 5

查看某一天的网卡流量历史 sar -n DEV -f /var/log/sa/文件名

在/var/log/sa/中有两种文件,sa开头加日期不能直接cat查看,只能用sar -f,sar加日期的文件可以直接cat

11. 系统瓶颈判断,有时需几个 sar 命令选项结合起来

怀疑CPU存在瓶颈,可用 sar -u 和 sar -q 等来查看

怀疑内存存在瓶颈,可用 sar -B、sar -r 和 sar -W 等来查看

怀疑I/O存在瓶颈,可用 sar -b、sar -u 和 sar -d 等来查看

二、nginx中打开gzip使用配置gzip_http_version值为1.0和1.1时遇到的结果乱码问题

在进行一套老业务服务器迁移的时候遇到了一个很奇怪的问题,因为发现配置大多一样,因此我将两套原来不一样的业务放到了一起,在所有nginx,php环境及业务代码部署好了之后,开始调试,但发现有一个接口的返回数据就是乱码。这乱码初看起来就是哪里压缩了一样,就想莫不是程序哪里有压缩处理,先对业务的调用进行了一翻梳理,因为是老业务,我之前也基本没有看过,在大致看了一下之后对其调用逻辑了解大致是请求nginx时会去执行lua程序,lua程序中会执行http请求本机,本机rewrite之后会再去调用php取得结果。调试之后得到了请求本机php结果时的URL,但在浏览器中发现请求这个URL返回的结果也是正常的,而就是在lua中请求了这个结果之后才出现了乱码,想来想去是不是在nginx的配置上的问题导致。

对比两个配置文件发现差异:

1. 老服务器配置

bash 复制代码
gzip on;
gzip_min_length  0k;
gzip_buffers     4 16k;
gzip_http_version 1.1;
gzip_comp_level 9;
gzip_types text/plain text/css text/xml application/x-javascript;
gzip_vary on;

#新服务器配置
gzip  on;
gzip_disable "MSIE [1-6]\.";
gzip_min_length  1k;
gzip_buffers     4 16k;
gzip_http_version 1.0;
gzip_comp_level 9;
gzip_types       text/plain application/json text/javascript application/x-javascript text/css application/xml;
gzip_vary on; 

发现有gzip_http_version,gzip_min_length,gzip_types的差异,gzip_types和gzip_min_length应该不会导致问题,那是gzip_http_version导致?于是修改了此项配置改成gzip_http_version 1.1,然后重启nginx发现果真问题出在这里。那是什么原因导致的这个问题呢?

为什么这样呢?我的理解是因为浏览器请求服务端基本都是http/1.1协议通信,而nginx和后端的upstream server之间默认是用HTTP/1.0协议通信的。

上述新服务器配置:nginx的gzip_http_version 配置是1.0,则使用浏览器直接请求服务器是不会被压缩的,因为在这一层上,是没有开启gzip的(1.0不是1。1)。但在后端lua中请求upstream时的通信结果被压缩了,被压缩的结果直接在lua程序中执行返回。所以看到前端返回的数据中callback是正常的字符,而后面的内容是压缩后的乱码。

2. 解决方法:

修改gzip_http_version的值为1.1当然可以解决,这样可以让后端的所有通信结果都不再gzip,从而不会导致被压缩的问题。但我想也应该有其它的办法,比如在lua请求的时候如何能支持gzip的处理。也很简单,可以安装lua_zlib让openresty或nginx可以接收gzip请求并处理解压缩即可。大致的方法如下:

bash 复制代码
#下载和安装lua_zlib,安装lua_zlib需要lua或luajit的支持,所以在cmake时需要指定lua的路径。
wget https://github.com/brimworks/lua-zlib/archive/master.zip
unzip master.zip
cd lua-zlib-master
cmake -DLUA_INCLUDE_DIR=/usr/local/openresty/luajit/include/luajit-2.1
make
cp zlib.so /usr/local/openresty/lualib/zlib.so
#然后在lua程序中就可以使用lua_zlib来接收gzip请求 
local zlib = require "zlib"
local encoding = ngx.req.get_headers()["Content-Encoding"]
ngx.req.read_body();
#判断结果是否被压缩
if encoding == "gzip" then
    local body = ngx.req.get_body_data()
    if body then
        local stream = zlib.inflate()
        ngx.req.set_body_data(stream(body))
    end
end

另外上述配置中有一项:gzip_vary on;,使用这项配置可以在http响应头中返回Vary: Accept-Encoding标头,如下:

bash 复制代码
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Fri, 26 Jul 2019 06:16:13 GMT
Server: nginx/1.6.2
Transfer-Encoding: chunked
Vary: Accept-Encoding

指定Vary: Accept-Encoding标头有什么作用呢?它就是告诉代理服务器缓存两种版本的资源:压缩和非压缩,这有助于避免一些公共代理不能正确地检测Content-Encoding标头的问题。有一些网站速度诊断性能优化里项里还有这项,即需要服务器端返回Vary:Accept-Encoding标头,可以把它简单理解成这样,设想有两个客户,一个使用的旧浏览器不支持压缩,一个使用新的浏览器支持压缩,如果他们都请求同一个网页,那么取决于谁先请求,压缩或非压缩版本便存储在CDN上。这样问题就出现了,旧浏览器请求常规网页但获得缓存的压缩版本,而新浏览器会获得缓存的非压缩版本但尝试去"解压"它。无论哪种方式都是坏消息。解决方法是,源服务器回送Vary: Accept-Encoding。

相关推荐
运维小文18 天前
prometheus自定义监控(pushgateway和blackbox)和远端存储VictoriaMetrics
云原生·prometheus·监控·linux运维·victoriametrics
黑马金牌编程3 个月前
接上篇基于Alertmanager 配置钉钉告警
linux·grafana·监控·linux运维·钉钉告警·普罗米修斯
Shenqi Lotus4 个月前
GitLab的使用
gitlab·linux运维
杰克逊的日记1 年前
服务器排障(Linux,Windows)
linux·前端·chrome·linux内核·php·linux运维
山有扶苏QWQ1 年前
Skywalking(8.7)安装以及docker镜像打包
linux运维
PC技术小能手1 年前
Linux系统解决“Key was rejected by service”
linux内核·linux驱动·linux运维
Praywu1 年前
Ingress & Ingress Controller & API Gateway
linux运维·ingress
山有扶苏QWQ1 年前
K8s部署轻量级日志收集系统EFK(elasticsearch + filebeat + kibana)
linux运维
山有扶苏QWQ1 年前
数据泵(impdb)导入Oracle分片的数据库dump文件
linux运维