分类 Linux 下的文章

ab压力测试工具

几个压力性能相关的名字:

吞吐率(Requests per second)
概念:服务器并发处理能力的量化描述,单位是reqs/s,指的是某个并发用户数下单位时间内处理的请求数。某个并发用户数下单位时间内能处理的最大请求数,称之为最大吞吐率。
计算公式:总请求数 / 处理完成这些请求数所花费的时间,即
Request per second = Complete requests / Time taken for tests
QPS(每秒查询数)、TPS(每秒事务数)是吞吐量的常用量化指标,另外还有HPS(每秒HTTP请求数)。
跟吞吐量有关的几个重要是:并发数、响应时间。
QPS(TPS),并发数、响应时间它们三者之间的关系是:
QPS(TPS)= 并发数/平均响应时间
对于无并发的应用系统而言,吞吐量与响应时间成严格的反比关系,实际上此时吞吐量就是响应时间的倒数。前面已经说过,对于单用户的系统,响应时间(或者系统响应时间和应用延迟时间)可以很好地度量系统的性能,但对于并发系统,通常需要用吞吐量作为性能指标。 
  对于一个多用户的系统,如果只有一个用户使用时系统的平均响应时间是t,当有你n个用户使用时,每个用户看到的响应时间通常并不是n×t,而往往比n×t小很多(当然,在某些特殊情况下也可能比n×t大,甚至大很多)。这是因为处理每个请求需要用到很多资源,由于每个请求的处理过程中有许多不走难以并发执行,这导致在具体的一个时间点,所占资源往往并不多。也就是说在处理单个请求时,在每个时间点都可能有许多资源被闲置,当处理多个请求时,如果资源配置合理,每个用户看到的平均响应时间并不随用户数的增加而线性增加。实际上,不同系统的平均响应时间随用户数增加而增长的速度也不大相同,这也是采用吞吐量来度量并发系统的性能的主要原因。一般而言,吞吐量是一个比较通用的指标,两个具有不同用户数和用户使用模式的系统,如果其最大吞吐量基本一致,则可以判断两个系统的处理能力基本一致。 
并发连接数(The number of concurrent connections)
概念:某个时刻服务器所接受的请求数目,简单的讲,就是一个会话。
并发用户数(The number of concurrent users,Concurrency Level)
概念:要注意区分这个概念和并发连接数之间的区别,一个用户可能同时会产生多个会话,也即连接数。
并发用户数是指系统可以同时承载的正常使用系统功能的用户的数量。与吞吐量相比,并发用户数是一个更直观但也更笼统的性能指标。实际上,并发用户数是一个非常不准确的指标,因为用户不同的使用模式会导致不同用户在单位时间发出不同数量的请求。一网站系统为例,假设用户只有注册后才能使用,但注册用户并不是每时每刻都在使用该网站,因此具体一个时刻只有部分注册用户同时在线,在线用户就在浏览网站时会花很多时间阅读网站上的信息,因而具体一个时刻只有部分在线用户同时向系统发出请求。这样,对于网站系统我们会有三个关于用户数的统计数字:注册用户数、在线用户数和同时发请求用户数。由于注册用户可能长时间不登陆网站,使用注册用户数作为性能指标会造成很大的误差。而在线用户数和同事发请求用户数都可以作为性能指标。相比而言,以在线用户作为性能指标更直观些,而以同时发请求用户数作为性能指标更准确些。 
用户平均请求等待时间(Time per request)
计算公式:处理完成所有请求数所花费的时间/ (总请求数 / 并发用户数),即
Time per request = Time taken for tests /( Complete requests / Concurrency Level)
服务器平均请求等待时间(Time per request: across all concurrent requests)
计算公式:处理完成所有请求数所花费的时间 / 总请求数,即
Time taken for / testsComplete requests
可以看到,它是吞吐率的倒数。
同时,它也=用户平均请求等待时间/并发用户数,即Time per request / Concurrency Level
QPS每秒查询率(Query Per Second) 
  每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,在因特网上,作为域名系统服务器的机器的性能经常用每秒查询率来衡量。对应fetches/sec,即每秒的响应请求数,也即是最大吞吐能力。 (看来是类似于TPS,只是应用于特定场景的吞吐量)
 响应时间(RT) 
  响应时间是指系统对请求作出响应的时间。直观上看,这个指标与人对软件性能的主观感受是非常一致的,因为它完整地记录了整个计算机系统处理请求的时间。由于一个系统通常会提供许多功能,而不同功能的处理逻辑也千差万别,因而不同功能的响应时间也不尽相同,甚至同一功能在不同输入数据的情况下响应时间也不相同。所以,在讨论一个系统的响应时间时,人们通常是指该系统所有功能的平均时间或者所有功能的最大响应时间。当然,往往也需要对每个或每组功能讨论其平均响应时间和最大响应时间。 
  对于单机的没有并发操作的应用系统而言,人们普遍认为响应时间是一个合理且准确的性能指标。需要指出的是,响应时间的绝对值并不能直接反映软件的性能的高低,软件性能的高低实际上取决于用户对该响应时间的接受程度。对于一个游戏软件来说,响应时间小于100毫秒应该是不错的,响应时间在1秒左右可能属于勉强可以接受,如果响应时间达到3秒就完全难以接受了。而对于编译系统来说,完整编译一个较大规模软件的源代码可能需要几十分钟甚至更长时间,但这些响应时间对于用户来说都是可以接受的。

安装ab测试工具

yum install httpd-tools -y

ab工具帮助
ab是Apache超文本传输协议(HTTP)的性能测试工具。其设计意图是描绘当前所安装的Apache的执行性能,主要是显示你安装的Apache每秒可以处理多少个请求。

命令格式: ./ab [options] [http://]hostname[:port]/path
命令参数:
-A:指定连接服务器的基本的认证凭据;
-c:指定一次向服务器发出请求数;
-C:添加cookie;
-g:将测试结果输出为“gnuolot”文件;
-h:显示帮助信息;
-H:为请求追加一个额外的头;
-i:使用“head”请求方式;
-k:激活HTTP中的“keepAlive”特性;
-n:指定测试会话使用的请求数;
-p:指定包含数据的文件;
-q:不显示进度百分比;
-T:使用POST数据时,设置内容类型头;
-v:设置详细模式等级;
-w:以HTML表格方式打印结果;
-x:以表格方式输出时,设置表格的属性;
-X:使用指定的代理服务器发送请求;
-y:以表格方式输出时,设置表格属性。

参数很多,一般我们用 -c表示并发数  -n 表示请求数即可
如果只用到一个Cookie,那么只需键入命令:
ab -n 100 -C key=value http://test.com/
如果需要多个Cookie,就直接设Header:
ab -n 100 -H “Cookie: Key1=Value1; Key2=Value2” http://test.com/

使用举例:

并发100,请求1000
[root@c75 ~]# ab -n 1000 -c 100 http://192.168.255.209/monitor
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.255.209 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        nginx/1.14.0
Server Hostname:        192.168.255.209
Server Port:            80

Document Path:          /monitor
Document Length:        185 bytes

Concurrency Level:      1000              //并发请求数
Time taken for tests:   2.252 seconds     //整个测试持续的时间
Complete requests:      1000              //完成的请求数
Failed requests:        0                 //失败的请求数
Write errors:           0                 //写入失败数
Non-2xx responses:      1000              //非2xx状态请求数
Total transferred:      386000 bytes      //传输的总字节数大小
HTML transferred:       185000 bytes      //传输的总文档字节数大小
Requests per second:    444.05 [#/sec] (mean)   //每秒处理的请求数
Time per request:       2252.008 [ms] (mean)    //每个请求花费的平均时间
Time per request:       2.252 [ms] (mean, across all concurrent requests)
Transfer rate:          167.39 [Kbytes/sec] received  //转移率

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        6   40  14.2     36      69   //创建TCP连接到服务器或者代理服务器所花费的时间
Processing:    40  738 722.9    302    2138   //写入缓冲区消耗+链路消耗+服务端消耗
Waiting:       11  546 595.8    293    1930   //写入缓冲区消耗+链路消耗+服务端消耗+读取数据消耗
Total:         45  778 733.0    344    2207   //总花费时间

Percentage of the requests served within a certain time (ms)
  50%    344
  66%    752
  75%   1668
  80%   1799
  90%   1957
  95%   2073
  98%   2161
  99%   2191
 100%   2207 (longest request)

把所有请求中的相应时间记录下来并展示到csv文件(excel可以直接打开)中

ab -n100 -c10 -e result.csv http://www.baidu.com/

Linux下svn命令整理

1、将文件checkout到本地目录

svn checkout path(path是服务器上的目录)
例如:svn checkout svn://192.168.1.35/pro/domain 
如果开启了https浏览模式也可以写成:
svn checkout https://192.168.1.35/pro/domain
简写:svn co 
svn co https://192.168.1.35/pro/domain

2、往版本库中添加新的文件

svn add file 
例如:svn add test.php(添加test.php) 
svn add *.php(添加当前目录下所有的php文件) 

3、将改动的文件提交到版本库

svn commit -m “LogMessage“ [-N] [--no-unlock] PATH(如果选择了保持锁,就使用–no-unlock开关) 
例如:svn commit -m “add test file for my test“ test.php 
简写:svn ci 

4、加锁/解锁

svn lock -m “LockMessage“ [--force] PATH 
例如:svn lock -m “lock test file“ test.php 
svn unlock PATH 

5、更新到某个版本

svn update -r m path 
例如: 
svn update如果后面没有目录,默认将当前目录以及子目录下的所有文件都更新到最新版本。 
svn update -r 200 test.php(将版本库中的文件test.php还原到版本200) 
svn update test.php(更新,于版本库同步。如果在提交的时候提示过期的话,是因为冲突,需要先update,修改文件,然后清除svn resolved,最后再提交commit) 
简写:svn up 

6、查看文件或者目录状态

1)svn status path(目录下的文件和子目录的状态,正常状态不显示) 
【?:不在svn的控制中;M:内容被修改;C:发生冲突;A:预定加入到版本库;K:被锁定】 
2)svn status -v path(显示文件和子目录状态) 
第一列保持相同,第二列显示工作版本号,第三和第四列显示最后一次修改的版本号和修改人。 
注:svn status、svn diff和 svn revert这三条命令在没有网络的情况下也可以执行的,原因是svn在本地的.svn中保留了本地版本的原始拷贝。 
简写:svn st 

7、删除文件

svn delete path -m “delete test fle“ 
例如:svn delete svn://192.168.1.1/pro/domain/test.php -m “delete test file” 
或者直接svn delete test.php 然后再svn ci -m ‘delete test file‘,推荐使用这种 
简写:svn (del, remove, rm) 

8、查看日志

svn log path 
例如:svn log test.php 显示这个文件的所有修改记录,及其版本号的变化 

9、查看文件详细信息

svn info path 
例如:svn info test.php 

10、比较差异

svn diff path(将修改的文件与基础版本比较) 
例如:svn diff test.php 
svn diff -r m:n path(对版本m和版本n比较差异) 
例如:svn diff -r 200:201 test.php 
简写:svn di 

11、将两个版本之间的差异合并到当前文件

svn merge -r m:n path 
例如:svn merge -r 200:205 test.php(将版本200与205之间的差异合并到当前文件,但是一般都会产生冲突,需要处理一下)

12、SVN 帮助

svn help 
svn help ci 

——————————————————————————
以上是常用命令,下面写几个不经常用的
——————————————————————————
13、版本库下的文件和目录列表

svn list path 
显示path目录下的所有属于版本库的文件和目录 
简写:svn ls 

14、创建纳入版本控制下的新目录

svn mkdir: 创建纳入版本控制下的新目录。 
用法: 
1、mkdir PATH… 
2、mkdir URL… 

创建版本控制的目录。
1、每一个以工作副本 PATH 指定的目录,都会创建在本地端,并且加入新增
调度,以待下一次的提交。
2、每个以URL指定的目录,都会透过立即提交于仓库中创建。
在这两个情况下,所有的中间目录都必须事先存在。
15、恢复本地修改

svn revert: 恢复原始未改变的工作副本文件 (恢复大部份的本地修改)。revert: 
用法: revert PATH… 
注意: 本子命令不会存取网络,并且会解除冲突的状况。但是它不会恢复 
被删除的目录 

16、代码库URL变更

svn switch (sw): 更新工作副本至不同的URL。 
用法: 
1、switch URL [PATH] 
2、switch –relocate FROM TO [PATH...] 

1、更新你的工作副本,映射到一个新的URL,其行为跟“svn update”很像,也会将
服务器上文件与本地文件合并。这是将工作副本对应到同一仓库中某个分支或者标记的
方法。
2、改写工作副本的URL元数据,以反映单纯的URL上的改变。当仓库的根URL变动
(比如方案名或是主机名称变动),但是工作副本仍旧对映到同一仓库的同一目录时使用
这个命令更新工作副本与仓库的对应关系。
17、解决冲突

svn resolved: 移除工作副本的目录或文件的“冲突”状态。 

用法: resolved PATH…
注意: 本子命令不会依语法来解决冲突或是移除冲突标记;它只是移除冲突的
相关文件,然后让 PATH 可以再次提交。
18、输出指定文件或URL的内容。

svn cat 目标[@版本]…如果指定了版本,将从指定的版本开始查找。 
svn cat -r PREV filename > filename (PREV 是上一版本,也可以写具体版本号,这样输出结果是可以提交的)

Linux下使用iptables端口转发

需要将外网访问本地IP(192.168.255.244)的8443端口转换为访问192.168.255.97的8443端口,这就需要用到iptables的端口映射

实现:

  1. 需要先开启linux的数据转发功能
# vi /etc/sysctl.conf,将net.ipv4.ip_forward=0更改为net.ipv4.ip_forward=1
# sysctl -p  //使数据转发功能生效

在255.244机器上进行相同端口转发

iptables -t nat -I PREROUTING -p tcp --dport 8443 -j DNAT --to 192.168.255.97
iptables -t nat -I POSTROUTING -p tcp --dport 8443 -j MASQUERADE

主机内部的端口映射
我们可能需要将访问主机的7979端口映射到8080端口。也可以iptables重定向完成

iptables -t nat -A PREROUTING -p tcp --dport 7979 -j REDIRECT --to-ports 8080

如果需要本机也可以访问,则需要配置OUTPUT链:

iptables -t nat -A OUTPUT -p tcp --dport 7979 -j REDIRECT --to-ports 8080

查看nat表

iptables -t nat -vnL POSTROUTING --line-number

清空 nat 表

iptables -F -t nat 

RHEL 6 或者 Oracle Linux 6, 不重启识别新添加的scsi硬盘VM虚拟机同样适用

下面看一下在系统不重启的情况,如何让系统认识新的磁盘,并能对其分区与格式化
1、在开机状态下新增磁盘
2、执行下面的命令

echo "- - -" > /sys/class/scsi_host/host0/scan

注意:
"- – -" 这三个-之间是有空格的
假如 fdisk -l 还是未发现新硬盘,则将上面命令中的host0,替换为host1,host2,....看看

查看系统日志

tail -f /var/log/messages

发现对SCSI设备进行了一次重新扫描,
然后用

fdisk -l

也看到了新增加的磁盘了,然后用fdisk分区并挂载即可;
VIA: https://serverfault.com/questions/490397/what-does-in-echo-sys-class-scsi-host-host0-scan-mean

CentOS下TIME_WAIT过多-问题处理方法

TIME_WAIT状态原理
当客户端主动关闭连接时,会发送最后一个ack,然后会进入TIME_WAIT状态,再停留2个MSL时间(约1-4分钟),进入CLOSED状态。
TCP三次握手四次挥手.png
CentOS6/7.x默认没有对系统参数进行设置,当大量TIME_WAIT产生的时候会影响系统性能,
统计TIME_WAIT状态数量

netstat -ano | grep TIME_WAIT | wc -l

查看系统当前连接状态:

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 352
ESTABLISHED 900
CLOSING 58

解决方法如下:
修改内核配置vim /etc/sysctl.conf ,加入以下内容:

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30

然后执行

/sbin/sysctl -p

让参数生效。

参数说明:

net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1  表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout  修改系統默认的 TIMEOUT 时间

更多参考:https://www.unixso.com/Linux/TIME_WAIT.html

zabbix 客户端执行netstat -p 报错

zabbix_get执行的脚本中含有netstat -lantup命令报错,原因是-p参数需要root用户才能使用

zabbix_get执行脚本时报错:

(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.

解决该问题的办法有两种:

通过配置vi /etc/sudoers 

Cmnd_Alias MONITORING = /bin/netstat,/sbin/sudo   
%monitor        ALL=(root) NOPASSWD:MONITORING

然后在修改userparameter_script.conf文件,利用sudo执行脚本即可

通过在执行的脚本中执行

chmod +s /bin/netstat

chmod +s 的意思是
为了方便普通用户执行一些特权命令,SUID/SGID程序允许普通用户以root身份暂时执行该程序,并在执行结束后再恢复身份

Nginx: [emerg] the "ssl" parameter requires ngx_http_ssl_module in nginx.conf解决之热更新

Nginx如果未开启SSL模块,配置Https时提示错误

nginx: [emerg] the "ssl" parameter requires ngx_http_ssl_module in /usr/local/nginx/conf/nginx.conf

是因为nginx缺少http_ssl_module模块,编译安装的时候带上--with-http_ssl_module参数
Nginx开启SSL模块步骤:
安装openssl支持

yum install openssl openssl-devel -y

查看nginx原有的模块

/usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.14.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) 
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx 

增加--with-http_ssl_module参数

/usr/local/nginx/sbin/nginx --prefix=/usr/local/nginx --with-http_ssl_module
make

这里不要进行make install,否则就是覆盖安装
备份原有已安装好的nginx

mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak

复制源码目录下的 objs/nginx 覆盖/usr/local/nginx/sbin/nginx

cp ./objs/nginx /usr/local/nginx/sbin/

对新安装的进行语法测试,显示successfully表示成功

/usr/local/nginx/sbin/nginx -t  
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

重启nginx

/usr/local/nginx/sbin/nginx -s reload  重新加载,实现平滑升级

查看是否已经加入成功新编译的参数:

/usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.14.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-zlib=/opt/zlib-1.2.11 --with-pcre=/opt/pcre-8.42 --with-http_stub_status_module --with-http_realip_module --with-http_gzip_static_module --with-http_ssl_module

Kvm虚拟机静态迁移

什么是静态迁移?
静态迁移:也叫做常规迁移、离线迁移(Offline Migration)。就是在虚拟机关机或暂停的情况下从一台物理机迁移到另一台物理机。因为虚拟机的文件系统建立在虚拟机镜像上面,所以在虚拟机关机的 情况下,只需要简单的迁移虚拟机镜像和相应的配置文件到另外一台物理主机上;如果需要保存虚拟机迁移之前的状态,在迁移之前将虚拟机暂停,然后拷贝状态至目的主机,最后在目的主机重建虚拟机状态,恢复执行。这种方式的迁移过程需要显式的停止虚拟机的运行。从用户角度看,有明确的一段停机时间,虚拟机上的服务不可用。这种迁移方式简单易行,适用于对服务可用性要求不严格的场合。

说明
(1)虚拟主机各自使用本地存储存放虚拟机磁盘文件
本文实现基于本地磁盘存储虚拟机磁盘文件的迁移方式

(2)虚拟主机之间使用共享存储存放虚拟机磁盘文件
该方式只是在目标虚拟主机上重新定义虚拟机就可以了

静态迁移过程
1、确定虚拟机关闭状态

[root@dev_test_25 ~]# virsh list --all
 Id    名称                         状态
----------------------------------------------------
 -     c160                           关闭
 -     wangya_win7                    关闭
 -     winxp_test                     关闭

2、准备迁移c160虚拟机,查看该虚拟机配置的磁盘文件

[root@dev_test_25 ~]# virsh domblklist c160
Target     Source
------------------------------------------------
vda        /home/c160
hdc        -

3、导出虚拟机配置文件

virsh dumpxml c160 > /opt/c160.xml

4、拷贝配置文件到目标主机上

scp /opt/c160.xml 192.168.121.200:/etc/libvirt/qemu/

5、拷贝虚拟磁盘文件

scp -r /home/c160 192.168.121.200:/kvm

目标虚拟主机
上面已经将虚拟机磁盘文件与配置文件都已经复制到目标虚拟主机上了。下面开始配置与启动。
1、对虚拟主机进行注册

virsh define /etc/libvirt/qemu/c160.xml

2、查看目标虚拟主机环境

virsh list --all
 Id    Name                           State
----------------------------------------------------
 8     c160                           shut off

3、确认源地址和迁移后的磁盘路径一致,如果不一致做个软连接即可,否则不能启动
如原来的路径在/home/c160,迁移以后的地址在/kvm/c160 做下软连接即可:

ln -s /kvm/c160 /home/c160

4、最后启动虚拟机

virsh start c160

启动完成以后可以ssh登陆上去检查下,至此kvm静态迁移完毕。
若把虚拟机静态迁移到不同平台(不同型号的cpu)的主机上,启动的时候报错,根据错误提示修改/etc/libvirt/qemu/下面的虚拟配置文件即可。

Keepalived构建高可用MySQL互为主从自动切换

关于MySQL-HA,目前有多种解决方案,比如heartbeat、drbd、mmm、共享存储,但是它们各有优缺点。heartbeat、drbd配置较为复杂,需要自己写脚本才能实现MySQL自动切换,对于不会脚本语言的人来说,这无疑是一种脑裂问题;对于mmm,生产环境中很少有人用,且mmm管理端需要单独运行一台服务器上,要是想实现高可用,就得对mmm管理端做HA,这样增加了硬件开支;对于共享存储,数据还是放在本地较为安全,存储设备毕竟存在单点隐患。

Keepalived是一个免费开源的,用C编写的类似于layer3, 4 & 7交换机制软件,具备我们平时说的第3层、第4层和第7层交换机的功能。主要提供loadbalancing(负载均衡)和 high-availability(高可用)功能,负载均衡实现需要依赖Linux的虚拟服务内核模块(ipvs),而高可用是通过VRRP协议实现多台机器之间的故障转移服务。
keepalived.jpg
上图是Keepalived的功能体系结构,大致分两层:用户空间(user space)和内核空间(kernel space)。
内核空间:主要包括IPVS(IP虚拟服务器,用于实现网络服务的负载均衡)和NETLINK(提供高级路由及其他相关的网络功能)两个部份。
用户空间:

WatchDog:负载监控checkers和VRRP进程的状况
VRRP Stack:负载负载均衡器之间的失败切换FailOver,如果只用一个负载均稀器,则VRRP不是必须的。
Checkers:负责真实服务器的健康检查healthchecking,是keepalived最主要的功能。换言之,可以没有VRRP Stack,但健康检查healthchecking是一定要有的。
IPVS wrapper:用户发送设定的规则到内核ipvs代码
Netlink Reflector:用来设定vrrp的vip地址等。

使用MySQL双master+keepalived是一种非常好的解决方案,在MySQL-HA环境 中,MySQL互为主从关系,这样就保证了两台MySQL数据的一致性,然后用keepalived实现虚拟IP,通过keepalived自带的服务监控功能来实现MySQL故障时自动切换。

实现过程如下:
1、机器网络拓扑等信息:

MySQL-VIP:10.10.200.30    
mysqldb1:10.10.200.11    
mysqldb2:10.10.200.12   
   
OS版本:CentOS 7.4    
MySQL版本:5.7.22    
Keepalived版本:1.4.5

2、MySQL配置文件修改:
db1和db2互为主从,需要修改server-id为不同,具体参考基于GTID的主从复制过程实现:https://www.unixso.com/MySQL/gtid-master-slave.html
如上述均正确配置,现在任何一台MySQL上更新数据都会同步到另一台MySQL,即互为主从,MySQL同步在此叙述。
3、keepalived安装及配置

yum install popt popt-devel libnl libnl-devel libnfnetlink-devel -y #安装基础库文件
wget http://www.keepalived.org/software/keepalived-1.4.5.tar.gz
tar xvf keepalived-1.4.5.tar.gz
cd keepalived-1.4.5.tar.gz
./configure --prefix=/usr/local/keepalived --sbindir=/usr/local/keepalived/sbin
make && make install
ln -s /usr/local/sbin/keepalived /usr/sbin/  
ln -s /usr/local/keepalived/etc/keepalived/ /etc/keepalived
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/init.d/  
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
chmod +x /etc/init.d/keepalived  
chkconfig keepalived on   #CentOS6执行
systemctl enable keepalived

配置keepalived
默认情况下keepalived启动时会去/etc/keepalived目录下找配置文件

#vi /etc/keepalived/keepalived.conf  
global_defs {  
     notification_email {  
         xxx@xxx.com
     }  
     notification_email_from xxx@xxx.com  
     smtp_server x.x.x.x
     smtp_connect_timeout 30  
     router_id MySQL-ha  
}  
 
vrrp_instance VI_1 {  
     state BACKUP   #两台配置此处均是BACKUP  
     interface eth0  
     virtual_router_id 51  
     priority 100   #优先级,另一台改为90  
     advert_int 1  
     nopreempt  #不抢占,只在优先级高的机器上设置即可,优先级低的机器不设置  
     authentication {  
         auth_type PASS  
         auth_pass 1111  
     }  
     virtual_ipaddress {  
         10.10.200.30  
     }  
}  
 
virtual_server 10.10.200.30 3306 {  
     delay_loop 2   #每个2秒检查一次real_server状态  
     lb_algo wrr   #LVS算法  
     lb_kind DR    #LVS模式  
     persistence_timeout 60   #会话保持时间  
     protocol TCP  
     real_server 10.10.200.11 3306 {  
         weight 3  
         notify_down /usr/local/mysql/bin/mysql.sh  #检测到服务down后执行的脚本  
         TCP_CHECK {  
             connect_timeout 10    #连接超时时间  
             nb_get_retry 3       #重连次数  
             delay_before_retry 3   #重连间隔时间  
             connect_port 3306   #健康检查端口
         }
     }  
} 

检测服务down后所要执行的脚本

#!/bin/sh    
killall keepalived    

赋予执行权限

chmod +x /usr/local/mysql/bin/mysql.sh  

此脚本是上面配置文件notify_down选项所用到的,keepalived使用notify_down选项来检查real_server 的服务状态,检测到real_server服务故障时,执行强制杀死keepalived进程,从而实现MySQL故障自动转移。
操作完成以后启动keepalived服务

systemctl keepalived start
或
/usr/local/keepalived/sbin/keepalived –D 

mysqldb2:10.10.200.12 机器上也依此安装keeplaived服务
配置keepalived文件,优先级为90、无抢占设置、real_server为本机IP这三个地方不同:

vi /etc/keepalived/keepalived.conf
global_defs {  
     notification_email {  
         xxx@xxx.com  
     }  
     notification_email_from xxx@xxx.com  
     smtp_server x.x.x.x  
     smtp_connect_timeout 30  
     router_id MySQL-ha  
}  
 
vrrp_instance VI_1 {  
     state BACKUP  
     interface eth0  
     virtual_router_id 51  
     priority 90  
     advert_int 1  
     authentication {  
         auth_type PASS  
         auth_pass 1111  
     }  
     virtual_ipaddress {  
         10.10.200.30
     }  
}  
 
virtual_server 10.10.200.30 3306 {  
     delay_loop 2  
     lb_algo wrr  
     lb_kind DR  
     persistence_timeout 60  
     protocol TCP  
     real_server 10.10.200.12 3306 {  
         weight 3  
         notify_down /usr/local/mysql/bin/mysql.sh  
         TCP_CHECK {  
             connect_timeout 10  
             nb_get_retry 3  
             delay_before_retry 3  
             connect_port 3306  
         }
     }
}

复制mysql.sh脚本、启动keepalived服务
测试
停止MySQL服务,看keepalived健康检查程序是否会触发我们编写的脚本,然后登录VIP,看是否能登录,在登录之两台MySQL服务器都要授权允许从远程登录,在切换时执行了一个MySQL查询命令,从执行show databases到显示出结果时间为2-3秒,会有

ERROR 2006 (HY000): MySQL server has gone away

报错信息,是因为keepalived切换大概为1-3秒左右,这3秒左右VIP是空白期,代码里面最好能实现多次重连数据库,从而规避,keepalived只能做到对3306的健康检查,但是做不到比如像 MySQL复制中的slave-SQL、slave-IO进程的检查,总之Keeplavied+Mysql互为主从是一个低廉的负载均衡解决方案。

Nginx中虚拟目录alias和root目录说明

Nginx的配置中,alias目录和root目录是有区别的:
1、alias指定的目录是准确的,即location匹配访问的path目录下的文件直接是在alias目录下查找的;
2、root指定的目录是location匹配访问的path目录的上一级目录,这个path目录一定要是真实存在root指定目录下的;
3、使用alias标签的目录块中不能使用rewrite的break(具体原因不明);另外,alias指定的目录后面必须要加上"/"符号!!
4、alias虚拟目录配置中,location匹配的path目录如果后面不带"/",那么访问的url地址中这个path目录后面加不加"/"不影响访问,访问时它会自动加上"/";
如果location匹配的path目录后面加上"/",那么访问的url地址中这个path目录必须要加上"/",访问时它不会自动加上"/"。如果不加上"/",访问就会失败!
5、root目录配置中,location匹配的path目录后面带不带"/",都不会影响访问。

nginx指定文件路径有两种方式root和alias,指令的使用方法和作用域:
[root]
语法:root path
默认值:root html
配置段:http、server、location、if
[alias]
语法:alias path
配置段:location

root与alias主要区别在于nginx如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上。
root的处理结果是:root路径+location路径
alias的处理结果是:使用alias路径替换location路径
alias是一个目录别名的定义,root则是最上层目录的定义。

还有一个重要的区别是alias后面必须要用“/”结束,否则会找不到文件的,而root则可有可无。
所以,一般情况下,在nginx配置中的良好习惯是:
在location /中配置root目录;
在location /path中配置alias虚拟目录。
alias在使用正则匹配时,必须捕捉要匹配的内容并在指定的内容处使用。

CentOS上部署rsync同步文件

rsync特点:
快速:第一次同步时 rsync 会复制全部内容,但在下一次只传输修改过的文件。rsync在传输数据过程中可以实行压缩及解压缩操作,以使用更少的带宽。   
安全:可以使用rcp、ssh等方式来传输文件,也可以用直接的socket连接。
安装rsync:

yum install rsync -y

安装xinetd启停rsync

yum install xinetd -y

安装完后要修改以下配置文件:

vi /etc/xinetd.d/rsync
# default: off
# description: The rsync server is a good addition to an ftp server, as it \
#       allows crc checksumming etc.
service rsync
{
        disable = no
        flags           = IPv6
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/bin/rsync
        server_args     = --daemon --config=/etc/rsyncd.conf
        log_on_failure  += USERID
}

默认disable = yes,这里需要把yes改成no,保存退出。
配置rsync的主配置文件及密码文件:

cat /etc/rsyncd.conf 
pid file = /var/run/rsync.pid
port = 873
log file = /var/log/rsyncd.log
lock file = /var/run/rsync.lock 
 
[resources]
path = /data/rsync_file/
secrets file = /etc/rsyncd.pass
#设置运行链接的IP地址
hosts allow = 10.10.100.2
hosts deny = *
list = true
uid = 0
gid = 0
#rsync连接时的用户名,要和客户端rsync的命令一致
auth users = imguser
# 该目录是否只读
read only = no
transfer logging = yes
log format = %t: host %h (%a) %o %f (%l bytes). Total %b bytes.  
timeout = 600

创建密码文件

touch /etc/rsyncd.pass

权限修改、密码文件

chown root:root /etc/rsyncd.pass
chmod 600 /etc/rsyncd.pass
cat /etc/rsyncd.pass
imguser:ysxxx            #账号:密码(名字随便写,只要和上边配置文件里的一致即可),格式(一行一个用户)

在每个模块(如以上的[resources])后指定path路径时,路径后不能留空格;
将rsync添加为系统服务并在系统3和5级别下启动:

# chkconfig --add rsync
# chkconfig --level 35 rsync on
# /etc/init.d/xinetd restart
Stopping xinetd:                                           [  OK  ]
Starting xinetd:                                           [  OK  ]

查看是否启动:

netstat -tpln | grep 873
tcp        0      0 :::873                      :::*                        LISTEN      23737/xinetd  

到此,服务器端的配置已完成。

客户端安装

yum install rsync -y

创建一个密码文件:

cat /etc/rsyncd.pass
ysxxx

chmod 600 /etc/rsyncd.pass   #设置权限

同步/data/test下面所有文件到resources

rsync -avzrP /data/test/* --password-file=/etc/rsyncd.pass imguser@10.1.151.241::resources

rsync -avz 同步目录|文件 用户名@IP::模块名

-a 参数,相当于-rlptgoD,-r 是递归 -l 是链接文件,意思是拷贝链接文件;-p 表示保持文件原有权限;-t 保持文件原有时间;-g 保持文件原有用户组;-o 保持文件原有属主;-D 相当于块设备文件;
-z 传输时压缩;
-P 传输进度;
-v 传输时的进度等信息,和-P有点关系,自己试试。可以看文档;

另外:
定制欢迎信息文件rsyncd.motd
如:

[root@211 rsync]# cat rsyncd.motd
+++++++++++++++++++++++++++
+       wellcome rsyncd    +
+++++++++++++++++++++++++++

注意:rsync密码服务端格式为usrname:pwd 但客户端格式为pwd

BASH脚本:/bin/sh^M:bad interpreter: No such file or directory解决

在Linux中执行.sh脚本,异常/bin/sh^M: bad interpreter: No such file or directory。
分析:这是不同系统编码格式引起的:在windows系统中编辑的.sh文件可能有不可见字符,所以在Linux系统下执行会报以上异常信息。
解决:1)在windows下转换:
利用一些编辑器如UltraEdit或EditPlus等工具先将脚本编码转换,再放到Linux中执行。转换方式如下(UltraEdit):File-->Conversions-->DOS->UNIX即可。
2)也可在Linux中转换:
首先要确保文件有可执行权限

chmod a+x filename 

然后修改文件格式

vi filename 

利用如下命令查看文件格式

:set ff 或 :set fileformat 

可以看到如下信息
fileformat=dos 或 fileformat=unix
利用如下命令修改文件格式

:set ff=unix 或 :set fileformat=unix 
:wq (存盘退出)

最后再执行即可

FastDFS 一个tracker配置多个Storage Group

一个tracker配置多个Storage Group步骤如下:
1、修改相应storage的storage_group2.conf配置文件,以下三个参数需注意:

group_name=group2
port=23001
base_path=/data/fastdfs_group2
store_path0=/data/fastdfs_group2

2、修改storage的mod_fastdfs.conf

group_count = 2   #storage的个数
[group2]
group_name=group2
storage_server_port=23001
store_path_count=1
store_path0=/data/fastdfs_group2

注释掉mod_fastdfs.conf 中的下面两项,要么访问会报502错误。


---阅读剩余部分---

提取jks证书配置Nginx使其支持https

证书配置在nginx上,对外提供https服务,内部和tomcat做反向代理走http,提取jks证书步骤如下:
提取jks证书(keytool命令安装jdk以后就默认安装了)
查看jks文件中的entry

keytool -list -keystore server.jks

查看是否有entries,如果有下个命令需要加 -srcalias 参数指定entry

转换jks文件为p12

keytool -importkeystore -srckeystore server.jks -destkeystore server.p12 -deststoretype PKCS12

查看新格式(pkcs12)证书库

keytool -deststoretype PKCS12 -keystore server.p12 -list

使用openssl提取证书并合并

openssl pkcs12 -in server.p12 -nokeys -clcerts -out server-ssl.crt
openssl pkcs12 -in server.p12 -nokeys -cacerts -out gs_intermediate_ca.crt

server-ssl.crt是SSL证书,gs_intermediate_ca.crt是中级证书,合并到一起才是nginx所需要的证书

cat server-ssl.crt gs_intermediate_ca.crt > server.crt

提取私钥及免密码

openssl pkcs12 -nocerts -nodes -in server.p12 -out server.key

避免重启是总是要输入私有key的密码

openssl rsa -in server.key -out server.key.unsecure

配置nginx


worker_processes  8;

error_log  logs/error.log  notice;

pid        logs/nginx.pid;


events {
    worker_connections  65535;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout 300;
    proxy_read_timeout 300;
    add_header Access-Control-Allow-Origin *;
    client_max_body_size    1000m;
    client_header_buffer_size 100m;
    large_client_header_buffers 4 102400k;
    set_real_ip_from  10.201.21.199;
    real_ip_header    X-Forwarded-For;
    real_ip_recursive on;
    ssl_certificate   /etc/pki/cn/server.crt;
    ssl_certificate_key /etc/pki/cn/server.key;
    include gzip.conf;
    include apmweb_upstream.conf;


    server {
        listen       80;
        listen       443 ssl;
        server_name  localhost;

        ssl_certificate   /etc/pki/cn/server.crt;
        ssl_certificate_key /etc/pki/cn/server.key;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers "EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
        ssl_prefer_server_ciphers on;
        ssl_session_timeout 1d;
        ssl_stapling on;
        ssl_stapling_verify on;
        add_header Strict-Transport-Security max-age=15768000;

        #proxy_redirect http:// $scheme://;
        proxy_redirect ~^http://inamp.xxx.com/(.*)$  https://inamp.xxx.com/$1;

        port_in_redirect on;
        proxy_set_header Host $host:$server_port;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;

        location / {
            root   /data/apm_static;
            index  index.html index.htm;
        }

       location ~*  ^/$ {
        rewrite ^/$ http://inamp.xxx.com/enrolment_web/enrolment/index.htm ;
       }

        include apmweb_tomcat.conf;

        error_page  404              /404.html;
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }


    }

}

apmweb_tomcat.conf内容

           location ~* ^/management_service.*$ {
           include deny.conf;

           proxy_pass http://apmserapp6300;
           include proxy.conf;

           error_log  logs/apm_management_service_error.log error;
           access_log  logs/apm_management_service_access.log  main;
       

apmweb_upstream.conf内容

    upstream apmwebapp6300 {
      server 10.101.1.160:6300 weight=1 max_fails=2 fail_timeout=10s;
      server 10.101.1.161:6300 weight=1 max_fails=2 fail_timeout=10s;
      server 10.101.1.162:6300 weight=1 max_fails=2 fail_timeout=10s;
    }
.......

gzip.conf

gzip on;
gzip_comp_level 2;
gzip_http_version 1.1;
gzip_proxied any;
gzip_min_length 1;
gzip_buffers 16 8k;
gzip_types text/plain text/css application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript application/jsp application/html application/htm;

Tomcat查看占用CPU过高的原因

应用服务器服务起来以后占用CPU一直很高,排查方法如下:
1、使用top命令查看使用CPU过高的进程的pid,按“shift+P”键按照cpu从高到低排列,按“shift+M”键按照内存用高到低排列。
2、根据pid定位占用cpu的线程,并按照占用从高到低排列

#此处的pid为15217
$ ps -mp 15254 -o THREAD,tid,time|sort -rn|head -10 
USER     %CPU PRI SCNT WCHAN  USER SYSTEM   TID     TIME
tomcat   99.9   -    - -         -      -     - 05:10:34
tomcat   99.8  19    - -         -      - 15820 05:10:05
tomcat    0.0  19    - poll_s    -      - 15921 00:00:00
tomcat    0.0  19    - poll_s    -      - 15917 00:00:00
tomcat    0.0  19    - poll_s    -      - 15257 00:00:05
tomcat    0.0  19    - futex_    -      - 15922 00:00:00
tomcat    0.0  19    - futex_    -      - 15920 00:00:00
tomcat    0.0  19    - futex_    -      - 15919 00:00:00
tomcat    0.0  19    - futex_    -      - 15918 00:00:00

3、将占用cpu高的线程id转换为16进制格式

printf "%x\n" 15820
3dcc

4、打印线程的堆栈信息

jstack 15254 | grep 3dcc -A 30

"Thread-2" prio=10 tid=0x00007fe7745cc800 nid=0x3dcc runnable [0x00007fe744c4a000]
   java.lang.Thread.State: RUNNABLE
        at com.yueworldframework.core.support.EventHelper$1.run(EventHelper.java:50)
        at java.lang.Thread.run(Thread.java:745)

"GC Daemon" daemon prio=10 tid=0x00007fe774347800 nid=0x3d04 in Object.wait() [0x00007fe7459dd000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000fd7b8530> (a sun.misc.GC$LatencyLock)
        at sun.misc.GC$Daemon.run(GC.java:117)
        - locked <0x00000000fd7b8530> (a sun.misc.GC$LatencyLock)

"Service Thread" daemon prio=10 tid=0x00007fe7740aa000 nid=0x3bdd runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" daemon prio=10 tid=0x00007fe7740a7800 nid=0x3bdb waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" daemon prio=10 tid=0x00007fe7740a4800 nid=0x3bd9 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x00007fe77409a800 nid=0x3bd8 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=10 tid=0x00007fe774083800 nid=0x3bb9 in Object.wait() [0x00007fe746dec000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000fd7b0da0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
        - locked <0x00000000fd7b0da0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)

根据输出信息定位或将结果发给开发。

Nginx目录浏览功能autoindex设置

Nginx默认是不允许列出整个目录的。如需此功能,打开nginx.conf文件或你要启用目录浏览虚拟主机的配置文件,在server或location 段里添加上autoindex on;来启用目录流量,下面会分情况进行说明。

另外Nginx的目录流量有两个比较有用的参数,可以根据自己的需求添加:

autoindex_exact_size off;
默认为on,显示出文件的确切大小,单位是bytes。
改为off后,显示出文件的大概大小,单位是kB或者MB或者GB

autoindex_localtime on;
默认为off,显示的文件时间为GMT时间。
改为on后,显示的文件时间为文件的服务器时间

1、整个虚拟主机开启目录流量

在server段添加

location / {
autoindex on;
autoindex_localtime on; #之类的参数写这里
}

2、单独目录开启目录流量
2.1:直接二级目录开启目录流量

location /down {
autoindex on;
}

2.2:虚拟目录开启目录流量

location /tools {
alias /data/tools/;
autoindex on;
}

详细参照:http://nginx.org/en/docs/http/ngx_http_autoindex_module.html

dd创建测试文件

使用dd这个linux命令可以创建一定大小文件。

linux创建文件命令:dd命令
把指定的输入文件拷贝到指定的输出文件中,并且在拷贝的过程中可以进行格式转换。语法:
CODE:[Copy to clipboard]dd 〔选项〕
QUOTE:

if =输入文件(或设备名称)。
of =输出文件(或设备名称)。
ibs = bytes 一次读取bytes字节,即读入缓冲区的字节数。
skip = blocks 跳过读入缓冲区开头的ibs*blocks块。
obs = bytes 一次写入bytes字节,即写 入缓冲区的字节数。
bs = bytes 同时设置读/写缓冲区的字节数(等于设置obs和obs)。
cbs = bytes 一次转换bytes字节。
count = blocks 只拷贝输入的blocks块。
conv = ASCII 把EBCDIC码转换为ASCII码。
conv = ebcdic 把ASCII码转换为EBCDIC码。
conv = ibm 把ASCII码转换为alternate EBCDIC码。
conv = blick 把变动位转换成固定字符。
conv = ublock 把固定们转换成变动位
conv = ucase 把字母由小写变为大写。
conv = lcase 把字母由大写变为小写。
conv = notrunc 不截短输出文件。
conv = swab 交换每一对输入字节。
conv = noerror 出错时不停止处理。
conv = sync 把每个输入记录的大小都调到ibs的大小(用ibs填充)。
fdformat命令
低级格式化软盘。

创建一个2G的文件

dd if=/dev/zero  of=/tmp/test bs=1M count=2048

得到最恰当的block size
通过比较dd指令输出中所显示的命令执行时间,即可确定系统最佳的block size大小:

dd if=/dev/zero bs=1024 count=1000000 of=/root/1Gb.filedd if=/dev/zero bs=2048 count=500000 of=/root/1Gb.file
dd if=/dev/zero bs=4096 count=250000 of=/root/1Gb.file
dd if=/dev/zero bs=8192 count=125000 of=/root/1Gb.file

测试硬盘读写速度
通过两个命令输出的执行时间,可以计算出测试硬盘的读/写速度:

dd if=/root/1Gb.file bs=64k | dd of=/dev/null
dd if=/dev/zero of=/root/1Gb.file bs=1024 count=1000000

iostat命令参数说明

Linux系统中的 iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视。它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况。同vmstat一样,iostat也有一个弱点,就是它不能对某个进程进行深入分析,仅对系统的整体情况进行分析。iostat属于sysstat软件包。
用yum install sysstat 直接安装。

1.命令格式:
iostat[参数][时间][次数]

2.命令功能:
通过iostat方便查看CPU、网卡、tty设备、磁盘、CD-ROM 等等设备的活动情况,负载信息。

3.命令参数:

-C 显示CPU使用情况
-d 显示磁盘使用情况
-k 以 KB 为单位显示
-m 以 M 为单位显示
-N 显示磁盘阵列(LVM) 信息
-n 显示NFS 使用情况
-p[磁盘] 显示磁盘和分区的情况
-t 显示终端和CPU的信息
-x 显示详细信息
-V 显示版本信息

[root@huafadb1 ~]# iostat 1
Linux 2.6.32-642.el6.x86_64 (huafadb1) 05/14/2018 x86_64 (64 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle

       0.01    0.00    0.01    0.00    0.00   99.98

Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda 0.44 1.42 5.86 376234 1550788
dm-0 0.80 1.30 5.86 343586 1550704
dm-1 0.00 0.01 0.00 2600 0
up-1 2.93 0.74 41.03 195418 10859128
sdb 5.86 1.51 81.92 399706 21683632
up-3 2.93 0.77 40.90 204288 10824504
dm-2 0.00 0.01 0.00 3298 24

avg-cpu: %user %nice %system %iowait %steal %idle

       0.02    0.00    0.03    0.02    0.00   99.94
参数说明:

rrqms:每秒这个设备相关的读取请求有多少被Merge了(当系统调用需要读取数据的时候,VFS将请求发到各个FS,如果FS发现不同的读取请求读取的是相同Block的数据,FS会将这个请求合并Merge)
wrqm/s:每秒这个设备相关的写入请求有多少被Merge了。
rsec/s:The number of sectors read from the device per second.
wsec/s:The number of sectors written to the device per second.
rKB/s:The number of kilobytes read from the device per second.
wKB/s:The number of kilobytes written to the device per second.
avgrq-sz:平均请求扇区的大小,The average size (in sectors) of the requests that were issued to the device.
avgqu-sz:是平均请求队列的长度。毫无疑问,队列长度越短越好,The average queue length of the requests that were issued to the device.
await:每一个IO请求的处理的平均时间(单位是微秒毫秒)。这里可以理解为IO的响应时间,一般地系统IO响应时间应该低于5ms,如果大于10ms就比较大了。
这个时间包括了队列时间和服务时间,也就是说,一般情况下,await大于svctm,它们的差值越小,则说明队列时间越短,反之差值越大,队列时间越长,说明系统出了问题。
svctm:表示平均每次设备I/O操作的服务时间(以毫秒为单位)。如果svctm的值与await很接近,表示几乎没有I/O等待,磁盘性能很好。
如果await的值远高于svctm的值,则表示I/O队列等待太长,系统上运行的应用程序将变慢。
%util: 在统计时间内所有处理IO时间,除以总共统计时间。例如,如果统计间隔1秒,该设备有0.8秒在处理IO,而0.2秒闲置,那么该设备的%util = 0.8/1 = 80%,
所以该参数暗示了设备的繁忙程度,一般地,如果该参数是100%表示磁盘设备已经接近满负荷运行了(当然如果是多磁盘,即使%util是100%,因为磁盘的并发能力,所以磁盘使用未必就到了瓶颈)。

使用FIO测试云主机IOPS及写入读取速度

先安装fio工具:

yum install fio -y

fio参数说明:

filename=/dev/emcpowerb 支持文件系统或者裸设备,-filename=/dev/sda2或-filename=/dev/sdb
direct=1                 测试过程绕过机器自带的buffer,使测试结果更真实
rw=randwread             测试随机读的I/O
rw=randwrite             测试随机写的I/O
rw=randrw                测试随机混合写和读的I/O
rw=read                  测试顺序读的I/O
rw=write                 测试顺序写的I/O
rw=rw                    测试顺序混合写和读的I/O
bs=4k                    单次io的块文件大小为4k
bsrange=512-2048         同上,提定数据块的大小范围
size=5g                  本次的测试文件大小为5g,以每次4k的io进行测试
numjobs=30               本次的测试线程为30
runtime=1000             测试时间为1000秒,如果不写则一直将5g文件分4k每次写完为止
ioengine=psync           io引擎使用pync方式,如果要使用libaio引擎,需要yum install libaio-devel包
rwmixwrite=30            在混合读写的模式下,写占30%
group_reporting          关于显示结果的,汇总每个进程的信息
此外
lockmem=1g               只使用1g内存进行测试
zero_buffers             用0初始化系统buffer
nrfiles=8                每个进程生成文件的数量

测试命令(创建100G容量大小的文件)

fio -direct=1 -iodepth=128 -rw=write -ioengine=libaio -bs=4k -size=100G -numjobs=1 -runtime=1000 -group_reporting -name=test -filename=/data/test111
运行结果:
test: (g=0): rw=write, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=128
fio-2.0.13
Starting 1 process
test: Laying out IO file(s) (1 file(s) / 102400MB)
Jobs: 1 (f=1): [W] [100.0% done] [0K/129.3M/0K /s] [0 /33.1K/0  iops] [eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=594: Mon May 14 10:27:54 2018
  write: io=102400MB, bw=129763KB/s, iops=32440 , runt=808070msec
    slat (usec): min=0 , max=80322 , avg=12.06, stdev=24.73
    clat (usec): min=222 , max=254410 , avg=3932.47, stdev=5007.90
     lat (usec): min=622 , max=254416 , avg=3944.82, stdev=5007.26
    clat percentiles (usec):
     |  1.00th=[ 1288],  5.00th=[ 1560], 10.00th=[ 1736], 20.00th=[ 1992],
     | 30.00th=[ 2224], 40.00th=[ 2480], 50.00th=[ 2736], 60.00th=[ 3088],
     | 70.00th=[ 3536], 80.00th=[ 4320], 90.00th=[ 6624], 95.00th=[ 9664],
     | 99.00th=[21120], 99.50th=[37632], 99.90th=[54528], 99.95th=[78336],
     | 99.99th=[177152]
    bw (KB/s)  : min=20720, max=215424, per=100.00%, avg=129801.50, stdev=19878.75
    lat (usec) : 250=0.01%, 750=0.01%, 1000=0.09%
    lat (msec) : 2=20.47%, 4=56.01%, 10=18.78%, 20=3.20%, 50=1.33%
    lat (msec) : 100=0.09%, 250=0.02%, 500=0.01%
  cpu          : usr=4.88%, sys=36.64%, ctx=9409837, majf=0, minf=23
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.1%
     issued    : total=r=0/w=26214400/d=0, short=r=0/w=0/d=0

Run status group 0 (all jobs):
  WRITE: io=102400MB, aggrb=129763KB/s, minb=129763KB/s, maxb=129763KB/s, mint=808070msec, maxt=808070msec

Disk stats (read/write):
  vdb: ios=0/26203032, merge=0/3962, ticks=0/90681446, in_queue=90672667, util=100.00%

100%随机,100%读,4K

[root@test-db data]# fio -filename=/dev/vdb1 -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=4k -size=100G -numjobs=50 -runtime=180 -group_reporting -name=rand_100read_4k
运行结果:
rand_100read_4k: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=psync, iodepth=1
...
rand_100read_4k: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=psync, iodepth=1
fio-2.0.13
Starting 50 threads
Jobs: 50 (f=50): [rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr] [100.0% done] [47544K/0K/0K /s] [11.9K/0 /0  iops] [eta 00m:00s]
rand_100read_4k: (groupid=0, jobs=50): err= 0: pid=25884: Mon May 14 14:59:44 2018
  read : io=8454.3MB, bw=48091KB/s, iops=12022 , runt=180018msec
    clat (usec): min=318 , max=167471 , avg=4156.60, stdev=8363.94
     lat (usec): min=318 , max=167472 , avg=4156.89, stdev=8363.95
    clat percentiles (usec):
     |  1.00th=[ 1032],  5.00th=[ 1176], 10.00th=[ 1240], 20.00th=[ 1352],
     | 30.00th=[ 1464], 40.00th=[ 1688], 50.00th=[ 1832], 60.00th=[ 1944],
     | 70.00th=[ 2064], 80.00th=[ 2288], 90.00th=[15808], 95.00th=[18560],
     | 99.00th=[20608], 99.50th=[39168], 99.90th=[134144], 99.95th=[144384],
     | 99.99th=[156672]
    bw (KB/s)  : min=  231, max= 7248, per=2.00%, avg=961.78, stdev=384.46
    lat (usec) : 500=0.05%, 750=0.20%, 1000=0.51%
    lat (msec) : 2=64.37%, 4=19.62%, 10=2.88%, 20=10.62%, 50=1.52%
    lat (msec) : 100=0.02%, 250=0.23%
  cpu          : usr=0.00%, sys=0.02%, ctx=1813752, majf=18446744073709550866, minf=18446744073698419008
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued    : total=r=2164296/w=0/d=0, short=r=0/w=0/d=0

Run status group 0 (all jobs):
   READ: io=8454.3MB, aggrb=48090KB/s, minb=48090KB/s, maxb=48090KB/s, mint=180018msec, maxt=180018msec

Disk stats (read/write):
  vdb: ios=2163559/42, merge=23/10, ticks=8925036/223, in_queue=8922540, util=99.94%

100%随机,100%写, 4K

[root@test-db data]# fio -filename=/dev/vdb1 -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=4k -size=100G -numjobs=50 -runtime=180 -group_reporting -name=rand_100write_4k
运行结果:
rand_100write_4k: (g=0): rw=randwrite, bs=4K-4K/4K-4K/4K-4K, ioengine=psync, iodepth=1
...
rand_100write_4k: (g=0): rw=randwrite, bs=4K-4K/4K-4K/4K-4K, ioengine=psync, iodepth=1
fio-2.0.13
Starting 50 threads
Jobs: 50 (f=50): [wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww] [100.0% done] [0K/47996K/0K /s] [0 /11.1K/0  iops] [eta 00m:00s]
rand_100write_4k: (groupid=0, jobs=50): err= 0: pid=25963: Mon May 14 15:08:43 2018
  write: io=8445.5MB, bw=48039KB/s, iops=12009 , runt=180024msec
    clat (usec): min=558 , max=248717 , avg=4160.45, stdev=8315.33
     lat (usec): min=559 , max=248717 , avg=4161.04, stdev=8315.34
    clat percentiles (usec):
     |  1.00th=[ 1256],  5.00th=[ 1528], 10.00th=[ 1656], 20.00th=[ 1816],
     | 30.00th=[ 1928], 40.00th=[ 2024], 50.00th=[ 2128], 60.00th=[ 2224],
     | 70.00th=[ 2384], 80.00th=[ 2704], 90.00th=[ 8768], 95.00th=[17792],
     | 99.00th=[24448], 99.50th=[38656], 99.90th=[130560], 99.95th=[191488],
     | 99.99th=[226304]
    bw (KB/s)  : min=  220, max= 4272, per=2.00%, avg=960.02, stdev=343.97
    lat (usec) : 750=0.04%, 1000=0.28%
    lat (msec) : 2=36.58%, 4=48.13%, 10=5.45%, 20=6.74%, 50=2.59%
    lat (msec) : 100=0.05%, 250=0.14%
  cpu          : usr=0.00%, sys=0.08%, ctx=1907994, majf=0, minf=18446744073699280913
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued    : total=r=0/w=2162044/d=0, short=r=0/w=0/d=0

Run status group 0 (all jobs):
  WRITE: io=8445.5MB, aggrb=48039KB/s, minb=48039KB/s, maxb=48039KB/s, mint=180024msec, maxt=180024msec

Disk stats (read/write):
  vdb: ios=148/2158380, merge=22/10, ticks=256/8928184, in_queue=8926408, util=99.96%

100%顺序,100%读 ,4K

fio -filename=/dev/vdb1 -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=4k -size=100G -numjobs=50 -runtime=180 -group_reporting -name=sqe_100read_4k
运行结果:
sqe_100read_4k: (g=0): rw=read, bs=4K-4K/4K-4K/4K-4K, ioengine=psync, iodepth=1
fio-2.0.13
Starting 50 threads
Jobs: 50 (f=50): [RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR] [100.0% done] [59996K/0K/0K /s] [14.1K/0 /0  iops] [eta 00m:00s]
sqe_100read_4k: (groupid=0, jobs=50): err= 0: pid=26047: Mon May 14 15:13:02 2018
  read : io=10599MB, bw=60295KB/s, iops=15073 , runt=180006msec
    clat (usec): min=253 , max=550591 , avg=3315.70, stdev=26406.30
     lat (usec): min=254 , max=550591 , avg=3315.95, stdev=26406.30
    clat percentiles (usec):
     |  1.00th=[ 1176],  5.00th=[ 1240], 10.00th=[ 1256], 20.00th=[ 1288],
     | 30.00th=[ 1336], 40.00th=[ 1368], 50.00th=[ 1416], 60.00th=[ 1480],
     | 70.00th=[ 1528], 80.00th=[ 1592], 90.00th=[ 1736], 95.00th=[ 2800],
     | 99.00th=[17792], 99.50th=[18816], 99.90th=[522240], 99.95th=[528384],
     | 99.99th=[536576]
    bw (KB/s)  : min=   15, max= 2475, per=2.00%, avg=1206.47, stdev=634.32
    lat (usec) : 500=0.01%, 750=0.01%, 1000=0.04%
    lat (msec) : 2=92.64%, 4=3.87%, 10=1.05%, 20=2.03%, 50=0.01%
    lat (msec) : 250=0.01%, 500=0.17%, 750=0.15%
  cpu          : usr=0.05%, sys=0.23%, ctx=2697397, majf=0, minf=18446744073708900853
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued    : total=r=2713362/w=0/d=0, short=r=0/w=0/d=0

Run status group 0 (all jobs):
   READ: io=10599MB, aggrb=60294KB/s, minb=60294KB/s, maxb=60294KB/s, mint=180006msec, maxt=180006msec

Disk stats (read/write):
  vdb: ios=2711304/55, merge=1805/10, ticks=8899022/202, in_queue=8898860, util=100.00%

100%顺序,100%写 ,4K

fio -filename=/dev/vdb1 -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=4k -size=100G -numjobs=50 -runtime=180 -group_reporting -name=sqe_100write_4k
运行结果:
sqe_100write_4k: (g=0): rw=write, bs=4K-4K/4K-4K/4K-4K, ioengine=psync, iodepth=1
...
sqe_100write_4k: (g=0): rw=write, bs=4K-4K/4K-4K/4K-4K, ioengine=psync, iodepth=1
fio-2.0.13
Starting 50 threads
Jobs: 50 (f=50): [WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW] [100.0% done] [0K/55788K/0K /s] [0 /13.1K/0  iops] [eta 00m:00s]
sqe_100write_4k: (groupid=0, jobs=50): err= 0: pid=26100: Mon May 14 15:17:24 2018
  write: io=10002MB, bw=56896KB/s, iops=14224 , runt=180019msec
    clat (usec): min=583 , max=457330 , avg=3513.01, stdev=9958.13
     lat (usec): min=584 , max=457331 , avg=3513.60, stdev=9958.13
    clat percentiles (usec):
     |  1.00th=[ 1224],  5.00th=[ 1384], 10.00th=[ 1480], 20.00th=[ 1592],
     | 30.00th=[ 1672], 40.00th=[ 1752], 50.00th=[ 1832], 60.00th=[ 1928],
     | 70.00th=[ 2096], 80.00th=[ 2480], 90.00th=[ 6368], 95.00th=[12480],
     | 99.00th=[20608], 99.50th=[37120], 99.90th=[166912], 99.95th=[268288],
     | 99.99th=[346112]
    bw (KB/s)  : min=  152, max= 2432, per=2.01%, avg=1141.03, stdev=401.10
    lat (usec) : 750=0.01%, 1000=0.11%
    lat (msec) : 2=65.06%, 4=21.62%, 10=7.36%, 20=4.40%, 50=1.24%
    lat (msec) : 100=0.08%, 250=0.06%, 500=0.07%
  cpu          : usr=0.05%, sys=0.38%, ctx=2547790, majf=0, minf=18446744073708899536
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued    : total=r=0/w=2560604/d=0, short=r=0/w=0/d=0

Run status group 0 (all jobs):
  WRITE: io=10002MB, aggrb=56896KB/s, minb=56896KB/s, maxb=56896KB/s, mint=180019msec, maxt=180019msec

Disk stats (read/write):
  vdb: ios=63/2558949, merge=0/275, ticks=12/8897256, in_queue=8895411, util=100.00%

100%随机,70%读,30%写 4K

fio -filename=/dev/vdb1 -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=4k -size=100G -numjobs=50 -runtime=180 -group_reporting -name=randrw_70read_4k
运行结果:
randrw_70read_4k: (g=0): rw=randrw, bs=4K-4K/4K-4K/4K-4K, ioengine=psync, iodepth=1
...
randrw_70read_4k: (g=0): rw=randrw, bs=4K-4K/4K-4K/4K-4K, ioengine=psync, iodepth=1
fio-2.0.13
Starting 50 threads
Jobs: 50 (f=50): [mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm] [100.0% done] [48012K/20800K/0K /s] [12.3K/5200 /0  iops] [eta 00m:00s]
randrw_70read_4k: (groupid=0, jobs=50): err= 0: pid=26162: Mon May 14 15:29:18 2018
  read : io=8430.4MB, bw=47954KB/s, iops=11988 , runt=180020msec
    clat (usec): min=304 , max=177969 , avg=3045.60, stdev=5103.08
     lat (usec): min=304 , max=177970 , avg=3045.87, stdev=5103.08
    clat percentiles (usec):
     |  1.00th=[  860],  5.00th=[ 1048], 10.00th=[ 1160], 20.00th=[ 1320],
     | 30.00th=[ 1448], 40.00th=[ 1560], 50.00th=[ 1656], 60.00th=[ 1768],
     | 70.00th=[ 1896], 80.00th=[ 2128], 90.00th=[ 4384], 95.00th=[17792],
     | 99.00th=[20352], 99.50th=[28544], 99.90th=[41216], 99.95th=[57088],
     | 99.99th=[127488]
    bw (KB/s)  : min=  206, max= 4424, per=2.00%, avg=959.77, stdev=408.18
  write: io=3613.8MB, bw=20556KB/s, iops=5138 , runt=180020msec
    clat (usec): min=569 , max=157336 , avg=2617.23, stdev=2821.20
     lat (usec): min=570 , max=157337 , avg=2617.81, stdev=2821.20
    clat percentiles (usec):
     |  1.00th=[ 1096],  5.00th=[ 1432], 10.00th=[ 1592], 20.00th=[ 1768],
     | 30.00th=[ 1912], 40.00th=[ 2040], 50.00th=[ 2160], 60.00th=[ 2288],
     | 70.00th=[ 2416], 80.00th=[ 2576], 90.00th=[ 2864], 95.00th=[ 3472],
     | 99.00th=[19328], 99.50th=[20352], 99.90th=[22400], 99.95th=[37632],
     | 99.99th=[52992]
    bw (KB/s)  : min=   62, max= 1888, per=2.00%, avg=411.23, stdev=178.61
    lat (usec) : 500=0.06%, 750=0.22%, 1000=2.28%
    lat (msec) : 2=61.13%, 4=27.68%, 10=3.02%, 20=4.48%, 50=1.07%
    lat (msec) : 100=0.04%, 250=0.01%
  cpu          : usr=0.01%, sys=0.08%, ctx=2743663, majf=0, minf=18446744073698904078
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued    : total=r=2158165/w=925122/d=0, short=r=0/w=0/d=0

Run status group 0 (all jobs):
   READ: io=8430.4MB, aggrb=47953KB/s, minb=47953KB/s, maxb=47953KB/s, mint=180020msec, maxt=180020msec
  WRITE: io=3613.8MB, aggrb=20555KB/s, minb=20555KB/s, maxb=20555KB/s, mint=180020msec, maxt=180020msec

Disk stats (read/write):
  vdb: ios=2154562/923535, merge=0/0, ticks=6503566/2394699, in_queue=8896553, util=99.93%

执行结果说明:

io=执行了多少M的IO

bw=平均IO带宽
iops=IOPS
runt=线程运行时间
slat=提交延迟
clat=完成延迟
lat=响应时间
bw=带宽
cpu=利用率
IO depths=io队列
IO submit=单个IO提交要提交的IO数
IO complete=Like the above submit number, but for completions instead.
IO issued=The number of read/write requests issued, and how many of them were short.
IO latencies=IO完延迟的分布

io=总共执行了多少size的IO
aggrb=group总带宽
minb=最小.平均带宽.
maxb=最大平均带宽.
mint=group中线程的最短运行时间.
maxt=group中线程的最长运行时间.

ios=所有group总共执行的IO数.
merge=总共发生的IO合并数.
ticks=Number of ticks we kept the disk busy.
io_queue=花费在队列上的总共时间.
util=磁盘利用率

Nginx请求报Not Allowed 405解决方法

nginx不允许向静态文件提交post方式的请求,否则会返回“HTTP/1.1 405 Method not allowed”错误,
405.jpg
解决方法有三种:
一、重定向405错误码到200
在nginx server{}里面添加以下内容,root为站点的根目录

   location ~ (.*\.json) {
        root  html;
        error_page 405 =200 $1;
   }

最后reload nginx即可。
二、转换静态文件接收的POST请求到GET方法

upstream static80 {
    server localhost:80;
}

server {
    listen 80;
    ...

    error_page 405 =200 @405;
    location @405 {
        root  html;
        proxy_method GET;
        proxy_pass http://static80;
    }
}

三、安装编译的时候修改源码(不推荐此方法)
源码文件位于/nginx源码目录/src/http/modules/ngx_http_static_module.c,找到如下代码:

if (r->method & NGX_HTTP_POST) {
     return NGX_HTTP_NOT_ALLOWED;
}

整段注释掉,然后重新编译 make,不需要make install,把编译生成的nginx文件复制到sbin下的nginx文件,重启nginx即可。

最新

分类

归档

评论

  • 安安: 都是af
  • Liang: 嗯,有点不通顺·
  • 王庭威: “MySQL互为主从...
  • Liang: 贴下编译参数和步骤,...
  • shao3911: 您好,为什么我在编译...
  • aliang: 先看是yum安装还是...
  • aliang: 将原来的nginx安...
  • yen: 3、如果要回滚的话,...
  • yen: 刚好需要升级ngin...
  • 文雨: 一些新的method...

其它