RELATEED CONSULTING
相关咨询
选择下列产品马上在线沟通
服务时间:8:30-17:00
你可能遇到了下面的问题
关闭右侧工具栏

新闻中心

这里有您想知道的互联网营销解决方案
CentOS服务程序性能评估文档的示例分析

这篇文章将为大家详细讲解有关CentOS服务程序性能评估文档的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

闵行ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联建站的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:028-86922220(备注:SSL证书合作)期待与您的合作!

1概述

1.1影响Linux服务程序性能的因素

CPU、内存、磁盘I/O带宽、网络I/O带宽

1.2性能评判

CPU:user% + sys%< 70%; 程序在用户态和内核态的执行时间百分比。

内存:Swap In(si)=0; Swap Out(so)=0; 以不使用交换分区为准,如果频繁用到交换分区,内存可能不够了。

硬盘:iowait % < 20%;

网络:只要有足够带宽尽情的使用吧,达到网卡带宽linux系统表示毫无压力

其中:  %user:表示CPU处在用户模式下的时间百分比。

      %sys:表示CPU处在内核模式下的时间百分比。

      %iowait:表示CPU等待输入输出完成时间的百分比。

      swap in:即si,表示虚拟内存的页导入,即从SWAP DISK交换到RAM

      swap out:即so,表示虚拟内存的页导出,即从RAM交换到SWAP DISK。

1.3性能分析工具

常用系统命令:top、free、ps、uptime、iotop、vmstat、iostat 、dstat、sar。
使用方法:top命令把握全局,使用特定命令深入分析

常用组合方式:

(1)CPU瓶颈:top、vmstat、iostat、sar –u、sar -q

(2)内存瓶颈:free、vmstat、sar -B、sar –r、sar -W

(3)磁盘I/O瓶颈:iotop、iostat、sar -b、sar –u、sar -d

(4)网络瓶颈: dstat

2 top

2.1功能

提供了实时的对系统处理器、内存、任务等状态监视;该命令可以按CPU使用、内存使用对任务进行排序;TOP是一个动态显示过程,可以通过用户按键来不断刷新当前状态,也可以在启动时指定刷新间隔。

2.2命令输出示意图

top - 10:16:29 up 38 days, 15:48,  5 users,  load average: 0.04, 0.10, 0.05

Tasks: 569 total,   2 running, 562 sleeping,   0 stopped,   5 zombie

Cpu(s):  2.6%us,  1.3%sy,  0.4%ni, 95.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

Mem:   3839112k total,  3151560k used,   687552k free,   302944k buffers

Swap:  6078456k total,   631852k used,  5446604k free,   348548k cached

 PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                

10603 zhixiang  20   0 1225m 284m  30m S  4.6  7.6 271:48.24 vs_exe                                                                

2473 xulun     20   0  118m  43m 6932 S  3.0  1.2 964:14.99 Xvnc                                                                  

1412 xulun     30  10  232m  12m 5216 S  2.3  0.3   0:04.59 floaters                                                              

14823 chujie    20   0 1112m 247m  17m S  2.0  6.6 363:51.38 vs_exe                                                                

17772 sihao     20   0 1101m 202m  10m S  1.7  5.4 631:21.17 vs_exe                                                                

11054 sihao     20   0  906m  65m 9412 S  1.0  1.7 410:06.55 vs_exe                                                                

20782 yongtao   20   0 1049m 173m 9996 S  1.0  4.6 196:05.10 vs_exe                                                                

14637 chujie    20   0 1274m 132m 2388 S  0.7  3.5  63:20.18 KugooPopMsgServ                                                      

1439 yanyun    20   0 15428 1600  940 R  0.3  0.0   0:00.01 top                                                                  

3491 zhixiang  20   0  129m  55m  17m S  0.3  1.5  10:57.25 Xvnc                                                                  

   1 root      20   0 19344 1200  984 S  0.0  0.0   0:00.89 init    

2.3命令输出解析

Top输出的信息很多基本囊括了所有的性能指标,前五行是统计信息区,表示的是系统整体的统计信息,包括:系统负载、任务、CPU、内存等;后面的是每个进程相关信息。

第一行是任务队列信息,同uptime命令的执行结果是一样的

[yanyun@~/test]$ uptime

10:20:17 up 38 days, 15:52,  5 users,  load average: 0.00, 0.04, 0.03

其内容如下:10:20:17:当前时间

38 days, 15:52:系统运行时间

5 users:当前登录用户数

load average: 0.00, 0.04, 0.03:系统负载,即任务队列的平均长度。三个数值分别为  1分钟、5分钟、15分钟前到现在的平均值。

第二行为进程的信息

内容如下:569 total:进程总数

2 running,:正在运行的进程数

562 sleeping:睡眠的进程数

0 stopped:停止的进程数

5 zombie:僵尸进程数

第三行为CPU的信息

内容如下:2.6%us:用户空间占用CPU百分比

1.3%sy:内核空间占用CPU百分比

0.4%ni:用户进程空间内改变过优先级的进程占用CPU百分比

95.7%id:空闲CPU百分比

0.0%wa:等待输入输出的CPU时间百分比

第四、五行为内存信息;命令输出跟free相同

[yanyun@~]$ free

            total       used       free     shared    buffers     cached

Mem:       3839112    3256976     582136          0     143664     444992

-/+ buffers/cache:    2668320    1170792

Swap:      6078456     574772    5503684

内容如下:Mem :3839112k total:物理内存总量

3151560k used:使用的物理内存总量

687552k free:空闲内存总量

302944k buffers:用作缓冲的内存量

Swap: 6078456k total:交换区总量

631852k used:使用的交换区总量

5446604k free:空闲交换区总量

348548k cached:缓存总量。

注:buffer:可以认为是写出磁盘的缓冲区;

Cache:读出磁盘的缓存。

Linux系统使用内存的原则是:不用白不用,用了也白用;尽可能的缓存东西,所以往往看空闲内存很小,但是cache很大;Linux系统会定时启动内核线程kswapd进行缓存回收。

后面的是显示每个进程相关信息

%CPU:上次更新到现在的CPU时间占用百分比

TIME+:进程使用的CPU时间总计

%MEM:进程使用的物理内存百分比

VIRT:进程使用的虚拟内存总量,单位kb

RES:进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA

SHR:共享内存大小,单位kb

S:进程状态。(D=不可中断的睡眠状态       R=运行  S=睡眠  T=跟踪/停止  Z=僵尸进程)

2.4常用选项

top [-] [d][p][M][P]

参数说明:

d:指定每两次屏幕信息刷新之间的时间间隔。(top –d 1:每秒刷新一次)

p:指定进程ID来仅监控某个进程。(top –d 1234:只查看pid为1234的进程信息)

k:终止一个进程。Top运行时参数,系统将提示用户输入需要终止的进程PID,以及需要发送给该进程什么样的信号。使用信号9强制结束该进程。

M:根据驻留内存大小进行排序。

P:根据CPU使用百分比大小进行排序。

注:在命令行执行过程中按下数字键‘1’,可以查看到CPU每个核的相关信息。

Tasks: 564 total,   3 running, 556 sleeping,   0 stopped,   5 zombie

Cpu0  :  2.9%us,  2.9%sy,  0.0%ni, 94.2%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

Cpu1  :  2.0%us,  2.0%sy,  0.0%ni, 96.1%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

Cpu2  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

Cpu3  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

Mem:   3839112k total,  3445296k used,   393816k free,    48180k buffers

Swap:  6078456k total,   553876k used,  5524580k free,   976128k cached

 PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                              

14823 chujie    20   0 1112m 245m  16m R  3.0  6.5 373:07.82 vs_exe                                                                

5589 sihao     20   0 1019m 267m  29m R  2.0  7.1   2:24.80 vs_exe                                                                

5674 zhixiang  20   0 1103m 253m  37m S  2.0  6.8   4:17.89 vs_exe

3 iotop:

3.1功能

是一个用来监视每个线程的磁盘 I/O 使用状况的类top 工具,

注:此命令需要自行安装(yum install iotop)

3.2命令输出示意图

Total DISK READ: 50.23 M/s | Total DISK WRITE: 34.25 K/s

 TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                                            

61524 be/4 root       47.65 M/s    0.00 B/s  0.00 % 37.83 % ./relay_server

61539 be/4 root      121.77 K/s    0.00 B/s  0.00 % 26.73 % ./relay_server

61544 be/4 root      700.15 K/s    0.00 B/s  0.00 % 24.89 % ./relay_server

61543 be/4 root      528.92 K/s    0.00 B/s  0.00 % 21.29 % ./relay_server

61541 be/4 root      494.67 K/s    0.00 B/s  0.00 % 21.22 % ./relay_server

61540 be/4 root      323.44 K/s    0.00 B/s  0.00 %  8.62 % ./relay_server

61542 be/4 root      468.04 K/s    0.00 B/s  0.00 %  8.13 % ./relay_server

 480 be/3 root        0.00 B/s    0.00 B/s  0.00 %  0.02 % [jbd2/sda2-8]

   1 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % init

   2 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kthreadd]

3 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [migration/0]

3.3命令输出解析

第一行:

Total DISK READ: 50.23 M/s :磁盘每秒读出数据量

Total DISK WRITE: 34.25 K/s :磁盘每秒写入数据量

下面的是每个线程的的IO情况:

比较简单;只解释一下IO:跟top的wa意义相同,只是此处表示的一个线程的wa。

3.4常用选项

iotop [-] [d] [p]

参数说明:

d:指定每两次屏幕信息刷新之间的时间间隔。(iotop –d 1:每秒刷新一次)

p:指定线程ID来仅监控某个线程。(iotop –d 1234:只查看pid为1234的进程信息)

注:在命令行执行过程中按下字母‘o’,可以只查看有IO的线程。

pstree -p:查看进程树,可以输出进程之间的关系。

ps –eLf:查看线程。ps –ef的高级版

4 vmstat:

4.1功能

查看虚拟内存(Virtual Memory)使用状况的工具

4.2命令输出示意图

[yanyun@~/test]$ vmstat

procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----

r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st

0  0 631376 834896  15108 452024    0    0     4     4    1    2  2  1 97  0  0

4.3命令输出解析

Memory:同top的第四、五行信息。

swap:内存到swap分区换入换出速率。

io:读写磁盘速率

system in:每秒的中断数,包括时钟中断

system cs:每秒的环境(上下文)切换数;频繁切换对系统性能有影响,linux提供了线程对cpu的亲和,可以将某个线程绑定到一个核运行。

cpu:同top输出的第三行

注:swap项不为零,都用到交换分区了,内存可能已经用完已经成为系统瓶颈的一项。

4.4常用选项

vmstat 1 10:每秒刷新一次,总共刷新十次退出。

注:下面的选项都是专业的查看某一特定项的信息,有几个输出一大堆信息,用到时google吧!

-a:显示活跃和非活跃内存

-f:显示从系统启动至今的fork数量

-m:显示slabinfo

-s:显示内存相关统计信息及多种系统活动数量。

-d:显示磁盘相关统计信息。

-p:显示指定磁盘分区统计信息

5 iostat

5.1功能

用于输出CPU和磁盘I/O相关的统计信息

5.2输出结果示意图

[root@ShanWei_119_134_255_208 ~]# iostat -x

Linux 2.6.32-279.el6.x86_64 (ShanWei_119_134_255_208)   07/30/2013      _x86_64_        (16 CPU)

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

          2.63    0.00    2.25    5.98    0.00   89.14

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util

sda             195.42   163.72  194.33  126.28 28464.35  2319.94    96.02     1.16    3.63   1.41  45.30

sdb               0.33    48.97  122.71    2.70 29603.37   413.38   239.34     0.27    2.15   1.00  12.52

5.3命令输出解释

avg-cpu段:

%user: 在用户级别运行所使用的CPU的百分比.

%nice: nice操作所使用的CPU的百分比.

%sys: 在系统级别(kernel)运行所使用CPU的百分比.

%iowait: CPU等待硬件I/O时,所占用CPU百分比.

%idle: CPU空闲时间的百分比.

Device段:

tps: 每秒钟发送到的I/O请求数

Blk_read /s: 每秒读取的block数

Blk_wrtn/s: 每秒写入的block数

Blk_read:   读入的block总数

Blk_wrtn:  写入的block总数

-x选项可以查看到如下更多信息

rrqm/s:每秒这个设备相关的读取请求有多少被Merge了

wrqm/s:每秒这个设备相关的写入请求有多少被Merge了

rsec/s:每秒读取的扇区数

wsec/:每秒写入的扇区数

avgrq-sz: 平均每次设备I/O操作的数据大小 (扇区)

avgqu-sz: 平均I/O队列长度

await:平均每次设备I/O操作的等待时间(单位是毫秒)

svctm: 平均每次设备I/O操作的服务时间 (单位是毫秒)

%util:在统计时间内所有处理IO时间,所以该参数暗示了设备的繁忙程度

5.4常用选项

iostat -d 2 6:每隔2秒,显示一次设备统计信息.总共输出6次.

-x:查看设备的使用率、响应时间

6 dstat

6.1功能

是一个全能系统信息统计工具,只能对整个系统进行监控而不能对某一个进程或某一个程序进行深入分析;监控项包括:cpu、磁盘、内存、网卡、进程、系统(彩色界面linux下面不多见啊!)

注:此命令需要自行安装(yum install dstat)

6.2命令输出示意图

[root@ShanWei_119_134_255_208 ~]# dstat -cdlmnpy

----total-cpu-usage---- -dsk/total- ---load-avg--- ------memory-usage----- -net/total- ---procs--- ---system--

usr sys idl wai hiq siq| read  writ| 1m   5m  15m | used  buff  cach  free| recv  send|run blk new| int   csw

 3   2  89   6   0   0|  28M 1367k|5.41 5.07 4.87|4019M  172M 58.5G  267M|   0     0 |  0 0.0 1.3|8608    35k

 2   1  85  12   0   0|  21M  828k|5.41 5.07 4.87|4020M  172M 58.6G  243M| 191k   15M|  0 6.0   0|5711    18k

 1   1  80  18   0   0|5828k 4804k|5.41 5.07 4.87|4018M  172M 58.6G  260M| 190k   17M|2.0 3.0   0|5802    12k

6.3命令输出解释

前面基本都解释过了......

6.4常用选项

dstat –cdlmnpsy:cdlmnpsy这几个选项基本囊括了常用的,当然还有很多dstat –-help一下吧。

7 sar

7.1功能

System Activity Reporter系统活动情况报告,是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,包括:文件的读写情况、系统调用的使用情况、磁盘I/O、CPU效率、内存使用状况、进程活动及IPC有关的活动等。

7.2命令输出示意图

[root@localhost ~]# sar -r 1 100

Linux 2.6.32-220.el6.x86_64 (localhost.localdomain)     07/30/2013      _x86_64_        (8 CPU)

03:17:59 PM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit

03:18:00 PM   4988488   3062224     38.04    639136   2115404     72404      0.44

03:18:01 PM   4984464   3066248     38.09    639136   2115404     98060      0.60

03:18:02 PM   4985152   3065560     38.08    639136   2115420     97972      0.60

03:18:03 PM   4985400   3065312     38.08    639136   2115420     97972      0.60

[root@localhost ~]# sar -B 1 100

Linux 2.6.32-220.el6.x86_64 (localhost.localdomain)     07/30/2013      _x86_64_        (8 CPU)

03:19:09 PM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff

03:19:10 PM      0.00    157.14  45415.48      0.00  15541.67      0.00      0.00      0.00      0.00

03:19:11 PM      0.00      0.00     40.40      0.00     75.76      0.00      0.00      0.00      0.00

03:19:12 PM      0.00      0.00   5542.34      0.00   1584.68      0.00      0.00      0.00      0.00

[root@localhost ~]# sar -b 1 100

Linux 2.6.32-220.el6.x86_64 (localhost.localdomain)     07/30/2013      _x86_64_        (8 CPU)

03:19:38 PM       tps      rtps      wtps   bread/s   bwrtn/s

03:19:39 PM     12.50      0.00     12.50      0.00    181.82

03:19:40 PM      0.00      0.00      0.00      0.00      0.00

03:19:41 PM      7.14      0.00      7.14      0.00    128.57

[root@localhost ~]# sar -W 1 100

Linux 2.6.32-220.el6.x86_64 (localhost.localdomain)     07/30/2013      _x86_64_        (8 CPU)

03:20:10 PM  pswpin/s pswpout/s

03:20:11 PM      0.00      0.00

03:20:12 PM      0.00      0.00

03:20:13 PM      0.00      0.00

[root@localhost ~]# sar -d 1 100

Linux 2.6.32-220.el6.x86_64 (localhost.localdomain)     07/30/2013      _x86_64_        (8 CPU)

03:20:48 PM       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util

03:20:49 PM    dev8-0      7.69      0.00     79.12     10.29      0.00      0.14      0.14      0.11

03:20:49 PM   dev8-16      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

03:20:49 PM       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util

03:20:50 PM    dev8-0     10.47      0.00    148.84     14.22      0.08      7.22      7.11      7.44

03:20:50 PM   dev8-16      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

7.3命令输出解释

kbmemfree:这个值和free命令中的free值基本一致,所以它不包括buffer和cache的空间.

kbmemused:这个值和free命令中的used值基本一致,所以它包括buffer和cache的空间.

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

kbbuffers和kbcached:这两个值就是free命令中的buffer和cache.

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

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

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)的百分比

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

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

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

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

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

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

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

7.4常用选项

sar –[u][r][B][b][q][W][d]

参数说明:

-u:CPU资源监控

-r:内存和交换空间监控

-B:内存分页监控

-b:IO和传输速率监控

-q:进程队列系统负载监控

-W:系统交换分区活动监控

-d:设备使用状况监控

8 tmpfs

8.1定义

tmpfs文件系统是一种基于内存的文件系统,挂载在/dev/shm下面。

8.2特点

动态改变大小;访问快、完全驻留在RAM中;当然系统重启就没了。

8.3使用方法

1、 linux下面POSIX标准的共享内存是基于此文件系统实现的(还有一套System V标准的共享内存实现方式);

2、 将文件创建在/dev/shm下面都将直接使用tmpfs;所以如果不需要考虑机器重启后数据的丢失,把数据放在这下面吧,释放你的磁盘压力!

3、 tmpfs的默认大小是物理内存的一半。将最大容量调到40G,并且文件节点数量调到1000000,可以通过下面的命令:

mount -o size=40G -o nr_inodes=1000000 -o noatime,nodiratime -o remount /dev/shm

4、如果需要永久修改tmpfs文件系统的大小,需要修改/etc/fstab

9 crontab:

9.1功能

定时调度一些命令的执行,相当于系统级别的定时器。在/var/spool/cron/有一些以用户名命名的文件,表示的是这个用户的定时执行任务。

9.2配置方法

格式说明:

  * * * * * /command path

前五个字段可以取整数值,指定何时开始工作(分钟 小时 日期 月份 星期),第六个域是字符串,到期执行的脚本、程序等

43 21 * * *                 每天21:43 执行

0 17 * * 1                  每周一的 17:00 执行

0,10 17 * * 0,2,3           每周日,周二,周三的 17:00和 17:10 执行

0-10 17 1 * *               毎月1日从 17:00到7:10 毎隔1分钟 执行

0 0 1,15 * 1                毎月1日和 15日和 一日的 0:00 执行

42 4 1 * *                 毎月1日的 4:42分 执行

0 21 * * 1-6               周一到周六 21:00 执行

0,10,20,30,40,50 * * * *   每隔10分 执行

*/10 * * * *            每隔10分 执行

* 1 * * *             从1:0到1:59 每隔1分钟 执行

0 1 * * *             1:00 执行

0 */1 * * *            毎时0分 每隔1小时 执行

0 * * * *             毎时0分 每隔1小时 执行

2 8-20/3 * * *          8:02,11:02,14:02,17:02,20:02 执行

30 5 1,15 * *           1日 和 15日的 5:30 执行

如下配置表示:每天3:00执行这个脚本/opt/ clear_old_file.sh;

这个脚本功能是:删除/data1 /data2这两个目录下的五天之内没有访问过的文件

0 3 * * * (cd /opt/ && ./clear_old_file.sh > /dev/null &)

[root@ShanWei_119_134_255_208 ~]# cat /opt/clear_old_file.sh

#!/bin/sh

find /data1/* -type f -atime +5 -exec rm {} \;

find /data2/* -type f -atime +5 -exec rm {} \;

exit 0

10 proc:待续…

/proc 文件系统是 GNU/Linux 特有的。它是一个虚拟的文件系统,此文件系统完全驻留在RAM中,因此在该目录中的所有文件都不会消耗磁盘空间。通过它能够非常简便地了解系统中的内核信息、硬件信息等;还可以通过它进行系统内核的参数的配置。许多命令实际上只是从 /proc 的文件中收集信息,然后按照它们自己的格式组织后显示出来;像前面介绍的命令基本就是这么干的。

关于“CentOS服务程序性能评估文档的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。


文章标题:CentOS服务程序性能评估文档的示例分析
文章出自:http://lswzjz.com/article/ghgohs.html