自由论坛

标题: 【学习笔记】系统监测 [打印本页]

作者: prostar    时间: 2016-3-13 16:22
标题: 【学习笔记】系统监测
上面是系统安装到业务上线之前的一些基本优化,如果业务已经在线上,你要优化,第一步如何做?

首先要进行服务器数据采集,和性能监测分析
方法有
一:使用cacti,nagios,zabbix等监控工具
二:使用linux自带的一些监控指令:如vmstat,iostat,mpstat,sar等等


        CPU子系统
        内存子系统
        IO子系统  
        网络子系统


一,
cpu(Central Processing Unit)子系统

CPU 的占用主要取决于什么样的资源正在 CPU 上面运行,
比如拷贝一个文件通常占用较少CPU,只是在完成拷贝以后给一个中断让CPU知道拷贝已经完成

科学计算通常占用较多的CPU,大部分计算工作都需要在CPU上完成,内存、硬盘等子系统只做暂时的数据存储工作
要想监测和理解CPU的性能需要知道一些的操作系统的基本知识,比如:中断,进程调度,进程上下文切换,可运行队列等


cpu单核在同一个时间点只能干一件事,但单核CPU一样可以跑多任务操作系统,其实就是分CPU资源(时间片)


CPU很无辜,是个任劳任怨的打工仔,每时每刻都有工作在做(进程、线程)并且自己有一张工作清单(可运行队列),
由老板(进程调度)来决定他该干什么,他需要和老板沟通以便得到老板的想法并及时调整自己的工作(上下文切换),
部分工作做完以后还需要及时向老板汇报(中断),
所以打工仔(CPU)除了做自己该做的工作以外,还有大量时间和精力花在沟通和汇报上。


    中断    设备通知内核,完成了一次数据处理过程。也可以理解为:cpu停止下来去执行别的指令。例如:完成一次IO。或者完成一次网络数据包的发送。
    内核处理过程 --- 控制优先级,进行任务调度。
    用户进程
    上下文切换 --- 把正在占用cpu的进程放回队列中(每次内核的上下文切换,资源被用于关闭在CPU寄存器中的线程和放置在队列中)
    运行队列


那么监测CPU性能的底线是什么呢?通常我们期望我们的系统能到达以下目标:


  CPU利用率,如果CPU有100%利用率,那么应该到达这样一个平衡:65%-70% User Time,30%-35% System Time,0%-5% Idle Time;

  上下文切换,上下文切换应该和 CPU 利用率联系起来看,如果能保持上面的 CPU 利用率平衡,大量的上下文切换是可以接受的;


查看cpu信息
# cat /proc/cpuinfo   --能看到指令集,CPU核数,频率,缓存等相关信息


要采集CPU当前正在运行的信息数据,要用到下面的命令或者监控软件(nagios,zabbix等)
top
uptime        
vmstat
mpstat --需要yum install sysstat
sar  --需要yum install sysstat


# vmstat 2      每2秒钟采集一下数据
# vmstat 2 3     每2秒钟采集一次,一共采集3次

# vmstat 2
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
1  0      0  78112  63432 1519100    0    0   233    18 1906 1190 26 13 59  1  0
1  0      0  78112  63432 1519100    0    0     0     0 4180 1378 33 17 50  0  0
1  0      0  78112  63440 1519092    0    0     0    30 4284 1706 33 17 50  0  0


r    可运行队列。单核cpu,不应该超过3(经验得到的数据,只是表明大于这个值表明运行队列有点长)
b    当前被阻塞的进程,一般这些进程都是在等待某些外部资源而被阻塞。>3需要注意,而且一直出现或者经常出现,就更值得注意
in    中断数。一般代表大量设备操作成功通知内核。
cs    上下文切换。一般代表任务需要紧急被cpu处理。数字高,只能说明内核在充分发挥它的任务调度作用。不能简单通过该数字判断cpu就出现瓶颈。
us    用户进程所占用的cpu时间的百分比
sy    内核在进行任务调度所占用的cpu时间的百分比
id    cpu空闲所占用的时间百分比.仅仅0不能简单判断cpu出现瓶颈,只能说它被充分被留用。
wa    等待IO所消耗时间百分比
st    被硬件虚拟化的虚拟机所消耗掉的时间百分比


mpstat 和 vmstat 类似,不同的是 mpstat 可以输出多个处理器的数据


# mpstat  -P ALL 1    ---P ALL表示查看所有CPU核, 1表示每一秒显示一次
10:46:35 AM  CPU   %user   %nice    %sys %iowait    %irq   %soft  %steal   %idle    intr/s
10:46:36 AM  all   26.13    0.00    6.53    0.00    3.52    9.05    0.00   54.77  19478.22
10:46:36 AM    0   25.74    0.00    6.93    0.00    2.97    7.92    0.00   56.44   9740.59
10:46:36 AM    1   26.73    0.00    6.93    0.00    3.96   10.89    0.00   51.49   9739.60


==============================



nice  优先级    能调的范围是 -20到19     -20表示优先级最高,19最低

用户运行一个程序默认给的优先级为0


renice    对一个已经运行的进程进行nice值的调整
    renice 19  pid

[root@li ~]# vim /tmp/test.sh

a=1

while [ $a -lt 1000000 ]
do
        let a++
done


nice 优先级高的能够优先分配资源,跑得快,花费的时间少,负载越高,效果越明显

实验
在一个负载高的情况下做效果更好,比如一个大文件的cp

第一个终端:
[root@li ~]# time sh /tmp/test.sh

    real    0m39.363s
user    0m26.338s
sys     0m0.900s

第二个终端:
[root@li ~]# time nice --19 sh /tmp/test.sh    --19 第一个是参数的横杠,第二个是负号

real    0m26.881s
user    0m26.008s
sys     0m0.871s

--对比上面的时间,可以看到 高优先级的花费的时间少


可以把上面的实验再做一次,马上用top查出-19的pid值,并使用renice修改

renice 19  9683


[root@li ~]# time sh /tmp/test.sh

real    0m34.665s
user    0m26.277s
sys     0m0.896s

[root@li ~]# time nice --19 sh /tmp/test.sh
real    0m37.231s
user    0m26.094s
sys     0m0.905s


--从上面的时间可以看出,-19优先级的半路被改为19后,所花费的时间反而多了


注意:只有管理员才能把优先级往高调,普通用户只能调自己的,并且只能往低调,调低后还不能再调高


================================================================


# sar -u  查看cpu相关的历史数据    --这是历史数据,是每十分钟会去采集一次系统相关的数据
# sar -u 2 3    --两秒一次,显示三次(不是历史数据,是当前动态数据)



sysstat  --> 提供 sar 命令        (system activity reporter)

sar的特点:可以对过去时间的系统状态进行分析,但不能对某个进程进行深入分析,只能对系统的整体情况进行分析。

yum install sysstat   -y        

# service sysstat start

# chkconfig sysstat on



安装systat包后,就会自动在 /var/log/sa/saxx 产生数据   xx代表日期
可以使用sar -f /var/log/sa/saxx  去访问  加参数就可以访问不同类型的性能数据

        指定查询之前的日期与固定时间点的方法


     sar -u -f /var/log/sa/sa18    --查看这个月已经过的18号的cpu历史数据

     sar -u -f /var/log/sa/sa18  -s 09:00:00 -e 10:00:00    --指定只看18号9点到10点的cpu历史数据



保存性能数据
sar支持保存成两种格式的文件,一种是文本文件,一种是二进制文件 (只有通过sar自己的命令 -f 参数 才能看)

保存为文本文件,可以直接cat命令查看
sar -p 1 5 > /tmp/test/sar1.txt

保存为二进制文件
sar -p  1 5  -o /tmp/test/sar2.txt 1>/dev/null        --会显示到屏幕,可以用1>/dev/null
file /tmp/test/sar2.txt      --是data类型文件
sar -f /tmp/test/sar2.txt     --使用-f参数读取  



=================================================================


内存子系统

同步 异步

        client -- squid  -- web
        web   -- memcache --  mysql

        CPU---内存(swap)---磁盘  (异步)

内存” 包括物理内存和虚拟内存(swap)
虚拟内存(Virtual Memory)把计算机的内存空间扩展到硬盘,
物理内存(RAM)和硬盘的一部分空间(SWAP)组合在一起作为虚拟内存为计算机提供了一个连贯的虚拟内存空间,
好处是我们拥有的内存 ”变多了“,可以运行更多、更大的程序,
坏处是把部分硬盘当内存用整体性能受到影响,硬盘读写速度要比内存慢几个数量级,
并且 RAM 和 SWAP 之间的交换增加了系统的负担。



    虚拟内存
把内存上暂时用不到的数据,但不能不用的数据,临时保存到磁盘(swap)或者磁盘文件(虚拟内存文件)中。或者物理内存不够用了,会使用到swap虚拟内存.
但需要用到这些数据的时候,就重新从磁盘上读取到内存中。
由内核kswapd进程完成

ps -ef |grep kswapd



# free
             total       used       free     shared    buffers     cached
Mem:       3801928    3656892     145036          0      88336    2898552
-/+ buffers/cache:     670004    3131924
Swap:      4194296        796    4194296


linux的内存使用和windows不一样,windows使用过的内存,当程序关闭会释放。linux使用过的内存,程序关闭也不释放,而是缓存(buffer+cached)
所以上面看到used3656892几乎用完,这是一个误区.你应该看第二行的670004才是使用的内存.
# echo $[670004+88336+2898552]
3656892
# echo $[3131924-88336-2898552]
145036

注意生产环境不要使用下面的命令
echo 3 > /proc/sys/vm/drop_caches  --此命令是扔掉内存中的缓存



    内存页(page) 默认是4K大小。这是操作内存数据的最小基本单位(类似于文件系统里的block)
    内存分页(paging) 内核经常扫描内存,如果发现内存的空闲空间低于某个值,那么就会把内存上的数据同步到硬盘。
这些一般都是曾经打开过的文件,这些文件数据加载到内存中,然后已经被修改过,

# /usr/bin/time -v mysql  --此命令显示的倒数第二行有内存页的大小
......
    Page size (bytes): 4096
    Exit status: 1


# /usr/bin/time -v date
    ...
        Major (requiring I/O) page faults: 0    主要页面故障
        Minor (reclaiming a frame) page faults: 204 次要页面故障
    ...
        Page size (bytes): 4096 《--内存页为4K





主要页面故障:(类似于缓存未命中miss)
    当执行某个进程的时候,进程需要读取某些数据,而这些数据在cache,buffer(在内存中)找不到,就会产生一次主要页面故障。

次要页面故障: (类似于缓存命中hit)
    进程在执行的时候,需要的数据在内存中可以找到,就叫做次要页面故障。

系统为了提高访问效率,总是把数据缓存起来,以便在内存中直接操作数据,减少磁盘的读写。
其实就是一个尽可能减少主要页面故障,增加次要页面故障的过程


小实例测试:
/usr/bin/time -v firefox    运行两次可以看到,第二次运行已经主要页面故障为0了,因为进程所需的数据已经在内存中,并且感觉到firefox打开速度变快


echo 3 > /proc/sys/vm/drop_caches  --此命令是扔掉内存中的缓存

然后再用/usr/bin/time -v firefox 执行,会发现主要页面故障又不为0了,而且明显感觉到firefox打开速度变慢.说明缓存没有命中




记住几点:
物理内存与虚拟内存交换的单位就是内存页
内存页大小为4096
内核会在物理内存不够时,使用虚拟内存或者是物理内存有空闲时,也会使用虚拟内存(会使用最近最少使用算法 LRU,把最近不常用的也会给虚拟内存)
内存里的数据会在满足特定条件时才会写到磁盘(这些条件可以通过修改内核参数来实现优化)
linux系统会把你访问过的程序或文件都缓存起来,甚至你的程序关闭也不释放相关的缓存.




查看内存状态相关的命令
free,top,vmstat,sar


# 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      0 2258668   7692 1052824    0    0   134    21  298  423  4  1 95  1  0   


--从上面的比较可以看到,vmstat里的free,buff,cache的值对应free 命令里的free,buffers,cached



si 有多少数据从swap到内存
so 有多少数据从内存到swap

bi 有多少数据从块设备读取到内存中
bo 有多少数据从内存中写到块设备中


      


# sar -B 2 3
Linux 2.6.32-279.el6.x86_64 (li.cluster.com)     04/25/2014     _x86_64_    (2 CPU)

11:28:53 AM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
11:28:55 AM      0.00      0.00     45.23      0.00    368.34      0.00      0.00      0.00      0.00
11:28:57 AM      0.00     19.90     78.11      0.00    533.33      0.00      0.00      0.00      0.00
11:28:59 AM      0.00      0.00     46.50      0.00    177.50      0.00      0.00      0.00      0.00
Average:         0.00      6.67     56.67      0.00    360.00      0.00      0.00      0.00      0.00



pgpgin/s   每秒从磁盘page in内存的 kilobytes
pgpgout/s  每秒从内存page out磁盘的 kilobytes
fault/s       每秒的(major+minor) page faults之和
majflt/s   每秒的major page faults数

--如果pgpgin和pgpgout很多,majflt/fault这个内存miss率很高.而且系统运行的程序也是固定的,这就有可能说明内存不够用了.造成缓存不了所有数据,以致内存命中率低


到底怎么样才说明内存不够?
结合free,vmstat,sar命令综合分析
如果你使用vmstat看到swapd使用比较多,free+buff+cache的值很小,并且si和so比较频繁,说明可用内存很小,并且swap使用很多,swap交互也频繁,表明内存遇到瓶颈了
如果你使用sar -B来看,看到pgpgin/s和pgpgout/s很频繁说明内存和磁盘交互很频繁。majflt/s除以fault/s得到内存MISS率变高,而且pgfree/s可用内存列表变小。也能说明内存不够了。


=================================================



内核参数的基本操作:
sysctl -a   --查看当前所有内核参数及其对应的值

内核参数配置文件
/etc/sysctl.conf
修改保存后,sysctl -p让其生效
例如:
# sysctl -a |grep ip_forward   
net.ipv4.ip_forward = 1
这个参数对应的/proc路径为/proc/sys/net/ipv4/ip_forward

# sysctl -a |grep file-max
fs.file-max = 381908
这个参数对应的/proc路径为/proc/sys/fs/file-max

2,如何修改内核参数

临时修改,重启后不生效;如
# echo 1 > /proc/sys/net/ipv4/ip_forward
# sysctl -w net.ipv4.ip_forward=1


永久生效,需要修改/etc/sysctl.conf配置文件
net.ipv4.ip_forward = 1        --修改,没有此参数就手动加上
保存后,记得要用sysctl -p使之生效


-------------------------------


与内存和swap有关的内核参数调整


# cat /proc/sys/vm/swappiness
60
swappiness表示使用swap分区的使用程度,可以适当调整swappiness=0的时候表示尽可能使用物理内存空间.swappiness=100积极使用swap.

--基本调优规则为:如果物理内存够大,那么就尽量不要使用swap,可以把此参数调小如swappiness=10.


# cat /proc/sys/vm/dirty_background_ratio
10
--这里表示内存里的脏数据(dirty data)到达10%,会触发写到磁盘


# cat /proc/sys/vm/dirty_ratio
20

--这里表示内存里的脏数据到达20%时,就不能再写入脏数据了,也就表示要让应用程序等待了,等这个值下降,才能继续写

            
        程序经cpu处理的数据--》内存 --》 磁盘
            ------->   快递点 ---> 附近住户
        

--这两个参数合起来理解就是:内存脏数据到dirty_background_ratio定义的10%时,就会触发数据写到磁盘(但是这个过程是异步的,也就是说还是会有别的应用程序的脏数据能继续写到内存),如果应用程序往内存里写的比内存往磁盘里写得快,还是有可能达到dirty_ratio定义的20%时,那么就要让写脏数据的应用程序等待,直到它降低到20%以下,再继续写


理解了上面两个参数的意思,现在如何来调整
1,dirty_background_ratio
把它调大,会提高写入磁盘速度(因为一次写的数据量大);但这样也有缺点,有可能一次写的数据量过大,造成磁盘IO峰值。还有就是如果物理内存不够,调大,会压缩物理内存缓存的空间,会进一步造成内存命中率下降.
把它调小,虽然速度会较慢,但可以削平IO峰值


2,在应用程序写内存繁忙时,可以把dirty_ratio调大,可以缓解应用程序的等待。如果物理内存不够,调大,会压缩物理内存缓存的空间,会进一步造成内存命中率下降.



====================================================================


IO子系统


    vmstat,iostat,sar
    IO,输出输入 input and ouput。
    一个IO,指的是从磁盘把数据读出来或者把数据写到磁盘上,就称之为一个IO,一个IO读写的大小为一个OS block.(linux下默认为4096字节,但rhel6的boot分区默认为1024字节)

    IOPS 每秒钟完成多少个IO    (io per second)
        10k RPM <--每分钟一万转,120 IOPS
        15k RPM <--每分钟15000转, 150-200 IOPS

硬盘的硬件特性我们这里改变不了,但是可以调整OS block大小.
block size   越大,IO吞吐量大,但浪费空间较多
         越小,IO吞吐量小,但浪费空间较少



如何查看块大小?
1,在格式化时  mkfs.ext4 /dev/sda7   --会在格式化的信息里看到
2,使用dumpe2fs
# dumpe2fs /dev/sda1  |grep -i "block size"
dumpe2fs 1.41.12 (17-May-2010)
Block size:               1024        --在rhel6里boot分区默认会为1024
# dumpe2fs /dev/sda7  |grep -i "block size"
dumpe2fs 1.41.12 (17-May-2010)
Block size:               4096        --在rhel6其它分区默认会为4096
3,# stat /boot/grub/grub.conf  |head -2    --用stat命令查看一个文件,可以看到此文件所在分区的块大小
  File: `/boot/grub/grub.conf'
  Size: 1093          Blocks: 6          IO Block: 1024   regular file



如何改变块大小?
在格式化时使用-b参数指定
如:
# mkfs.ext4 -b 2048 /dev/sda7    --在rhel6.5里测试的可用块大小为1024,2048,4096,8192,16384,32768,65536这几种(8192-65536可以格式化,但挂载不了)



IO 可分为顺序 IO 和 随机 IO 两种


IO的类型:
    随机IO
        一般的硬盘处理效率最慢的就是随机IO。每个IO完成的数据量非常低。

    顺序IO
        这些IO涉及数据都是连续存放在磁盘上。



顺序 IO 是指同时顺序请求大量数据,比如数据库执行大量的查询、流媒体服务等,
顺序 IO 可以同时很快的移动大量数据。
相对随机 IO 而言,顺序 IO 更应该重视每次 IO 的吞吐能力(KB per IO);
随机IO更重视每秒的IO次数IOPS



# iostat
Linux 2.6.32-279.el6.x86_64 (li.cluster.com)     04/25/2014     _x86_64_    (2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           9.72    0.57    1.34    1.71    0.00   86.66

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda              24.47      2157.44        43.86   17100165     347648
md127             0.02         0.13         0.00       1016          0
dm-0              0.01         0.08         0.00        672          0



tps    每秒的IO传输次数
Blk_read/s  每秒读了多少个block(一个block单位为512bytes)
Blk_wrtn/s  每秒写了多少个block   
Blk_read    两次查看的时间间隔内,一共读了多少块(Blk_read/s乘以两次查看时间间隔秒数),如果只看一次,或者看多次的第一次,是表示从开机到现在读的总量
Blk_wrtn    两次查看的时间间隔内,一共写了多少块(Blk_wrtn/s乘以两次查看时间间隔秒数),如果只看一次,或者看多次的第一次,是表示从开机到现在总的读的总量



# iostat 2     --每两秒显示所有的分区IO状态
# iostat /dev/sda*  2  --每两秒显示所有分区的io状态


# iostat -kx -d sda 2 3   
--查看sda的IO状态报告,每两秒打印一次,总共三次 ; -k是表示把默认以每秒多少块显示成每次多少KB;-x打印了一些扩展选项
Linux 2.6.32-279.el6.x86_64 (li.cluster.com)     04/25/2014     _x86_64_    (2 CPU)

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               7.82     4.13   22.09    1.29  1028.68    21.69    89.83     0.15    6.45   2.02   4.72

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00     3.50    0.00    3.00     0.00    26.00    17.33     0.02    8.00   7.50   2.25


rrqm/s    每秒的读请求数
wrqm/s    每秒的写请求数
r/s    每秒完成多少个读IO
w/s    每秒完成多少个写IO <--  IOPS=(r/s+w/s)
rsec/s    每秒读取了多少扇区的数据。 一个扇区=512字节数据
wsec/s    每秒写了多少扇区的数据。
rkB/s   每秒读了多少kb数据
wkB/s    每秒写了多少kb数据

avgrq-sz  平均请求数据的大小

avgqu-sz  是平均请求队列的长度。毫无疑问,队列长度越短越好。

await
    平均完成IO需要等待多少时间, 包含服务时间,还有在队列中等待的时间。

svctm
    服务时间,从IO请求产生到,完成IO的时间。从源代码里可以看出:
(r/s+w/s)*(svctm/1000)=util。
举例子:如果util达到100%,那么此时svctm=1000/(r/s+w/s),
假设IOPS是1000,那么svctm大概在1毫秒左右,如果长时间大于这个数值,
说明系统出了问题。
不过前面已经说过在磁盘阵列等多盘系统中util可能出现偏大的情况,所以svctm相应的也可能偏大。


%util
    磁盘带宽使用百分比。如果一直都是100%,说明磁盘很忙。


其它查IO相关的命令

# vmstat
bi:表示读的block数
bo:表示写的block数


# sar -b    --可以查看历史的io读写信息



IO的主要优化方法是在存储讨论:
raid
存储多路径
lvm
分布式存储
IO调度算法



2.6内核四种IO调度算法的区别和比较

# cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq]     --默认使用的是cfq算法


        5 6    7 8 9 10    3000000     3000001
    1--------------------------XXX
第N次IO请求    请求地址
1          5
2          300000
3          6
4          300001
5         7
6        8
7        9
8        10



noop:大致按照IO请求的时间顺序来处理,先来先处理,但也会做一些相邻IO请求的合并。按上面图处理顺序就可能是1,3,2,4....。但如果请求IO在物理上地址非常随机,则效率不高.
cfq:把IO请求按物理地址排序,按物理地址顺序处理。这样的话磁盘读写效率高,但有可能会造成先请求的IO因为地址太远,而出来等待太久的情况.
deadline:在cfq的基础上加了IO队列来维护等待的IO。如果IO等待过长,超过特定值,会优先处理。
anticipatory:基于预测的IO算法,类似DeadLine,也维护了三个请求对列;区别在于当它处理完一个I/O请求后并不会直接返回处理下一个请求,而是等待6ms(默认),如果这时候有新来的针对当前扇区相邻扇区的请求,那么会直接处理它,当等待时间结束后,调度器才返回处理下一个对列请求
试想一下,如果系统有频繁的针对邻近扇区的I/O请求,那么这种预测算法必然大幅提高整体的吞吐量,毕竟节约了那么多寻道时间



修改方法:
临时改:
echo deadline > /sys/block/sda/queue/scheduler

永久改:
1,把命令放到/etc/rc.local里
2,把elevator=deadline放到grub.conf里kenrel参数里(比如放到rhgb quiet前面)


=======================================================================






网络子系统


网络的监测是所有 Linux 子系统里面最复杂的,有太多的因素在里面,
比如:延迟、阻塞、冲突、丢包等,更糟的是与 Linux 主机相连的路由器、
交换机、无线信号都会影响到整体网络并且很难判断是因为 Linux 网络子系统的问题还是别的设备的问题,
增加了监测和判断的复杂度。现在我们使用的所有网卡都称为自适应网卡,
意思是说能根据网络上的不同网络设备导致的不同网络速度和工作模式进行自动调整。


网络子系统
线序:
568B    橙白    橙    绿白    蓝    蓝白    绿    棕白    棕
568A    1,3对换,2,6对换   

两台windows直连使用568A标准,并安装IPX/SPX协议可以进行局域网游戏等



1、检查是否通电
    # mii-tool     

2、检查网卡的工作模式和修改
    # ethtool eth0
    # ethtool -s eth0 speed 10 duplex half autoneg off    --把网卡改成10M/s的速率,半双工,关闭自动协商
    # ethtool -s eth0 speed 100 duplex full autoneg on    --把网卡改成100M/s的速率,全双工,打开自动协商


3,用一些工具扫描内网用户,如arp-scan


软件包路径在 笔记目录/arch/arp_scan_soft/
arp-scan-1.6.tar.gz
libpcap-1.4.0-1.20130826git2dbcaa1.el6.x86_64.rpm
libpcap-devel-1.4.0-1.20130826git2dbcaa1.el6.x86_64.rpm

    # arp-scan -l --interface br0    --查看局域网内所有机器的IP和MAC地址的对应

    # arp -a  --查看所有和本机联系过并且仍然保存在arp缓存列表里的机器的IP和MAC地址的对应

    # ip neigh   --类似arp -a,但速度较快




4、检测网卡的当前负载

    # sar -n DEV 2

02:09:37 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
02:09:39 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
02:09:39 PM      eth0    659.69    255.10     40.16    344.18      0.00      0.00      0.00
02:09:39 PM       br0    659.69    255.10     31.14    344.18      0.00      0.00      2.55
02:09:39 PM    vmnet1      0.00      0.00      0.00      0.00      0.00      0.00      0.00
02:09:39 PM    vmnet2      0.00      0.00      0.00      0.00      0.00      0.00      0.00
02:09:39 PM    virbr0      0.00      0.00      0.00      0.00      0.00      0.00      0.00
02:09:39 PM virbr0-nic      0.00      0.00      0.00      0.00      0.00      0.00      0.00


rxpck/s   每秒收到的数据包数
txpck/s      每秒发送的数据包数
rxpck/s      每秒收到的kb
txpck/s      每秒发送的kb


   
    # cat /proc/net/dev



5,两台主机之间有网线(或无线)、路由器、交换机等设备,
测试两台主机之间的网络性能的一个办法就是在这两个系统之间互发数据并统计结果,看看吞吐量、延迟、速率如何。
iptraf 就是一个很好的查看本机网络吞吐量的好工具,支持文字图形界面,很直观。


    yum install iptraf

    # iptraf        --直接打开,选择你要查看统计数据
    # iptraf -d eth0    --直接看eth0的统计数据



6,netperf 运行在 client/server 模式下,比 iptraf 能更多样化的测试终端的吞吐量。

    笔记目录/arch/arp_scan_soft/netperf-2.7.0.tar.gz
   
    解压
    ./configure
    make
    make install
   
    安装完成后会有netserver(服务器端命令)和netperf(客户端命令)这两个命令
# which netserver
/usr/local/bin/netserver
# which netperf
/usr/local/bin/netperf



    测试方法:服务器和客户端都要安装此软件
    在服务器上
# netserver
Starting netserver with host 'IN(6)ADDR_ANY' port '12865' and family AF_UNSPEC
# netstat -ntlup |grep 12865    --端口为12865
tcp        0      0 :::12865                    :::*                        LISTEN      18366/netserver     



    在客户端上
# netperf -H 10.1.1.8 -l 30       --这里表示一次测试时间为30秒

MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.1.1.8 (10.1.1.8) port 0 AF_INET
# netperf -H 10.1.1.8 -l 30

Recv   Send    Send                          
Socket Socket  Message  Elapsed              
Size   Size    Size     Time     Throughput  
bytes  bytes   bytes    secs.    10^6bits/sec  

87380  16384  16384    30.39      87.39   --这里的87.39的单位是10^6bits,所以要算每秒多少MB就应该$[87.39*1000000/8/1000/1000]算得多少MB/s大概为10M多/s(因为百M局域网理论值为12.5MB/s)


===============================================================


tcp/ip连接过程及状态


见笔记目录里的图
    笔记目录/arch/png/tcp-state
    笔记目录/arch/png/tcp-state2
连接过程大概分为三大部分


1,三次握手
知识点: syn,ack,syn_flood攻击;
相关状态ISTEN,SYN_SENT,SYN_RCVD,ESTABLISHED
2,数据传输
知识点:超时重传,快速重传,流量控制,拥塞控制(慢启动,拥塞避免,拥塞发生,快速恢复);
相关状态:ESTABLISHED
3,四次挥手
知识点:主动关闭,被动关闭,MSL(Maximum Segment Lifetime);
相关状态:
FIN_WAIT_1;CLOSE_WAIT,FIN_WAIT_2;LAST_ACK;TIME_WAIT;CLOSING;CLOSED



syn 同步序列号 synchronous
ack 确认号    acknowledgement



syn_flood攻击
syn_flood攻击属于DDos攻击(分布式拒绝服务攻击)
原理:利用发送大量伪造的TCP连接请求,但只做三次握手的第一次SYN包,当服务器回应第二次syn+ack包,所以不回应第三次握手,造成服务器会有大量的SYN_RCVD状态,并且会重试5次继续回应syn+ack包,直到塞满TCP连接等待队列,耗尽资源.         


syn_flood的基本诊断:
1,服务器突然连接不够用了,大量客户反映无法连接服务器
2,服务器相比平常多出大量的SYN_RCVD状态的连接
# ss -s        --用此命令查出有大量的不正常的timewait和synrecv
# netstat -n |grep ^tcp |awk '{print $NF}' |sort |uniq -c |awk BEGIN'{print "状态\t\t连接数"} {print $2"\t"$1}'     --查出有大量的不正常的SYN_RCVD状态



应急处理
写shell脚本使用iptables将攻击嫌疑IP给禁止,过一段时间再解禁。但这种做法容易把正常客户给禁掉,只做应急处理

比如:写一个类似我下面的脚本
#!/bin/bash

touch /tmp/denyiplist.txt

netstat -nt |awk '$NF~"SYN_RECV" {print $0}' | grep :80 |awk -F: '{print $8}' |sort |uniq -c |awk '$1>10 {print $2}' |while read ip
do
        grep $ip /tmp/denyiplist.txt &> /dev/null
        if [ $? -ne 0 ];then
        iptables -A INPUT -p tcp --dport 80 -s $ip -j REJECT
        echo "$ip" >> /tmp/denyiplist.txt
at now + 3 days << EOF
iptables -D INPUT -p tcp --dport 80 -s $ip -j REJECT
sed -i "/$ip/"d /tmp/denyiplist.txt
EOF
        fi
done


--把上面的脚本放到时间任务里,过一段时间(自定义)就执行一次



如果你是一个小网站,经常会受到同行的攻击。你可以加httpd上加防DDOS模块来做一下辅助防护。

如:Apache防DDOS模块mod_evasiv


========================================================================



调整内核参数做微调(syn_flood相关)

1,net.ipv4.tcp_synack_retries = 1   --默认为5,改小(1-2),极端就暂时改为0,表示减小服务器回应syn+ack包的重试次数
2,net.ipv4.tcp_max_syn_backlog = 4096    --默认为2048,可以适当调大,此参数表示syn的等待队列长度,加大队列长度,可以支持更多的连接,但队列长度的设定与内存大小也有关系
3,net.ipv4.tcp_abort_on_overflow = 1   --改为1,表示如果tcp连接实在太多,处理不过来,就直接拒绝

4,net.ipv4.tcp_syncookies = 1     --连接实在太多,队列满了,tcp会使用一种特殊的cookies的方法来处理连接.(防syn_flood有一定效果,但是高负载并且没有受到syn_flood攻击,建议关闭)




调整内核参数做微调(keep_alive相关)
tcp面向连接的  (但这个连接因为是通过网络,所以并不是把client到server整个连接路线都去监测和检测,所以才需要两端来维护tcp_ip的11状态来确认整个连接线路的情况)

        深圳    --》     北京
        client         server

tcp keep_alive
如果client端因为非正常原因(如断电这种)掉线,server端过一段时间后会去探测client是否alive


空连接攻击

1,net.ipv4.tcp_keepalive_time = 1800    --默认为7200秒(两小时),server在7200秒没有收到客户端信息,会发送探测包确认它是否alive.适当调小,如调成1800秒
2,net.ipv4.tcp_keepalive_probes = 3     --默认9次,表示server需要9次探测client是否alive,9次都没回应,就断开这个tcp连接。可以适当调小
3,net.ipv4.tcp_keepalive_intvl = 20    --75秒,表示server探测的时间间隔。适当调小


超时重传
快速重传
流量控制
拥塞控制(慢启动,拥塞避免,拥塞发生,快速恢复)
net.ipv4.tcp_fack = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_dsack = 1
net.ipv4.tcp_window_scaling = 1




在四次挥手时,大量的time_wait状态会影响你的新的连接进来



net.ipv4.ip_local_port_range = 1024  65535  --tcp连接本地分配的端口号范围,可以把随机端口全部分配给它

net.ipv4.tcp_timestamps  = 1   --默认为1,不用调,主要是配合下面的tw_reuse和rw_recycle使用的(打开tw_reuse和rw_recycle必须要打开这个参数)
net.ipv4.tcp_tw_reuse  = 1  --默认为0,改为1表示打开time_wait状态连接的快速重用
net.ipv4.tcp_tw_recycle    = 1   --默认为0,改为1表示打开time_wait状态连接的快速回收

net.ipv4.tcp_max_tw_buckets = 262144   --服务能维护的最大time_wait数量,在内存足够可以再适当调大
net.ipv4.tcp_fin_timeout =30  --默认为60,表示FIN-WAIT-2状态的时间,适当调小



=======================================================================



通过linux下双网卡绑定加强网卡性能和高可用性


准备一台kvm虚拟机,双网卡同网段


linux双网卡绑定(七种模式)


这里使用一台kvm虚拟机来测试(两张网卡物理上要同网段)

注意:如果使用vmware workstation版本来测试的话,在做网卡切换时有可能会造成虚拟机死机等情况(所以用kvm做比较容易实现效果)


# cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0"
BOOTPROTO="none"
NM_CONTROLLED="no"
ONBOOT="yes"
MASTER=bond0
SLAVE=yes


# cat /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE="eth1"
BOOTPROTO="none"
NM_CONTROLLED="no"
ONBOOT="yes"
MASTER=bond0
SLAVE=yes


# cat /etc/sysconfig/network-scripts/ifcfg-bond0     --此文件不存在,手动创建
DEVICE="bond0"
BOOTPROTO="static"
IPADDR=10.1.1.6
NETMASK=255.255.255.0
NM_CONTROLLED="no"
ONBOOT="yes"



# cat /etc/modprobe.d/bond.conf     --这个文件也不存在,手动创建(名字随意,在此目录以.conf结尾就可以)
alias bond0 bonding
options bond0 miimon=100 mode=1        --miimon=100表示系统每100ms监测一次链路连接状态,mode=1表示为主备模式


# /etc/init.d/NetworkManager stop
# /etc/init.d/network restart     --第一次重启有报错,再重启一次就没问题了
# /etc/init.d/network restart
# chkconfig NetworkManager off
# chkconfig network on



验证
1,使用ifconfig查看(可以看到三个网卡MAC地址一致)
# ifconfig |grep -E "eth|bond" -A 1
bond0     Link encap:Ethernet  HWaddr 00:0C:29:F4:4CE  
          inet addr:10.1.1.6  Bcast:10.1.1.255  Mask:255.255.255.0
--
eth0      Link encap:Ethernet  HWaddr 00:0C:29:F4:4CE  
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
--
eth1      Link encap:Ethernet  HWaddr 00:0C:29:F4:4CE  
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1



2,查看网卡状态
# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.6.0 (September 26, 2009)

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: None
Currently Active Slave: eth0      --主备模式目前正在使用的主网卡
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth0
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:f4:4c:de    --eth0的MAC
Slave queue ID: 0

Slave Interface: eth1
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:f4:4c:e8    --eth1的MAC,在这里看是和ifconfig看不一样的
Slave queue ID: 0


或者使用iptraf来看
# yum install iptraf
# iptraf    --打开所有网卡查看(可以找另一台机器去ping他,模拟有数据包),只有bond0和eth0有数据包,说明eth0为主,eth1为备



3,测试主备切换

ifconfig eth0 down模拟网卡eth0出问题,再查看状态

# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.6.0 (September 26, 2009)

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: None
Currently Active Slave: eth1      --主网卡成为eth1了
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth0        
MII Status: down         --eth0的状态为down了
Speed: Unknown
Duplex: Unknown
Link Failure Count: 1
Permanent HW addr: 00:0c:29:f4:4c:de
Slave queue ID: 0

Slave Interface: eth1
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:f4:4c:e8
Slave queue ID: 0



使用ifconfig eth0 up把eth0启来,但active网卡并没有切回到eth0,需要你把/etc/init.d/network restart一下才会切回到eth0


=============================================

负载模式的讨论


# cat /etc/modprobe.d/bond.conf
alias bond0 bonding
options bond0 miimon=100 mode=0     --改为0模式,重启kvm(重启network服务的话状态还是1模拟,所以把虚拟机重启一下),再查看状态


# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.6.0 (September 26, 2009)

Bonding Mode: load balancing (round-robin)
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth0
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:f4:4c:de
Slave queue ID: 0

Slave Interface: eth1
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:f4:4c:e8
Slave queue ID: 0


测试:
还是使用iptraf来测试,会发现bond0,eth0,eth1的网卡都会有数据包,并且bond0的数据包为eth0和eth1的总和
ifconfig eth0 down断掉一个网卡后,只有bond0和eth1有数据包


--上面的两种模式可以scp一个大文件来测试速率(但一定要用一台远程机器来测,不要用宿主机和KVM虚拟机来测,因为宿主机和KVM虚拟机直接SCP,速率不是网速,是IO的速率);测试的结果都为100M网络.负载模式是可以提高带宽,但我们这里是虚拟机不是实际物理网卡(还需要交换机的支持)


======================================================================



ulimit控制操作系统资源限制

文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符。程序刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误。如果此时去打开一个新的文件,它的文件描述符会是3


# sysctl -a | grep fs.file-max
fs.file-max = 388892        --系统打开文件数限制


# ulimit -n
1024                --系统控制每一个进程打开的文件数限制


# ulimit -SHn 65535    --临时修改每一个进程打开文件数限制


# vim /etc/security/limits.conf      --永久修改一个用户的资源限制

oracle  soft nproc     65535
oracle  hard nproc     65535
oracle  soft nofile    65535
oracle  hard nofile    65535
nginx   soft nproc     65535
nginx   hard nproc     65535
nginx   soft nofile    65535
nginx   hard nofile    65535



===================================================================







欢迎光临 自由论坛 (http://deva.wicp.net/discuz/) Powered by Discuz! X3.2