系统性能分析工具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。

相关推荐
杰克逊的日记6 个月前
服务器排障(Linux,Windows)
linux·前端·chrome·linux内核·php·linux运维
山有扶苏QWQ10 个月前
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运维
微思xmws1 年前
控制台的启动日志消失了?关键在于这些步骤!
linux·rhce·rhca·运维工程师·linux运维