[toc]
Linux系统管理技巧2
扩展学习:
TCP/IP 三次握手。四次挥手过程 http://www.doc88.com/p-9913773324388.html
10.6 监控io性能
1.iostat命令,该命令和sar共同存在于systat安装包中,用法如下:
2. 用 iostat 1 ,同vmstat一样表示一秒输出一次io状态,用sar -b 也可以查看
- sda,sdb是硬盘
3. 比较重要的命令是 iostat -x,指标参数为%utill
当中的%util是一个重要指标,指的是io等待的时间,即占用CPU的时间,是一个时间比,当达到50%,60%的时候说明磁盘的IO太差,很忙,也就有问题。
4. iotop命令,这里需要安装 yum install -y iotop,和top命令相同
输入命令iotop
10.7 free命令查看内存使用情况
free命令可以显示当前系统未使用的和已使用的内存数目,还可以显示被内核使用的内存缓冲区。
1. free -m,-g 分别以MB或GB为单位打印内存使用情况。
2.free信息中6列的情况,total、used、free、shared、buff/cache、available,tatal=used+free+buff/cache
total:内存总数;tatal=used+free+buff/cache
used:已经使用的内存数;
free:空闲的内存数;
shared:当前已经废弃不用;
buff/cache:分配给buffer和cache的内存总共有多大;
available:系统可使用内存大小,avaliable包含free和buffer/cache剩余部分。
3. buff/cache 的区别
数据经过CPU计算(很快计算完),即将要写入磁盘(磁盘写太慢了),这时用的内存为buffer来临时存储,然后写给磁盘;CPU要计算时,需要把数据从磁盘中读出来,临时放在内存中,这部分内存就是cache。所以系统必须预留一部分空间给buff/cache.
- 另外也要注意swap的配置,如果占用的比较多说明内存不够使用了。
10.8 用ps命令查看系统进程
ps命令用于报告当前系统的进程状态。可以搭配kill指令随时中断、删除不必要的程序。ps命令是最基本同时也是非常强大的进程查看命令,使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进程有没有僵死、哪些进程占用了过多的资源等等,总之大部分信息都是可以通过执行该命令得到的。如下示例:
1. ps aux 静态的显示当前的进程状态
- ps -elf 和aux用法也是一样的
2. ps命令可以连同管道符一起使用,ps aux |grep mysql,筛选mysql进程
[root@localhost ~]# ps aux |grep mysql
[root@localhost ~]# ps aux |grep nginx
3.PID,kill+PID,这样做有点暴力,严重的时候回丢失数据,所以尽量不用
- [ ] PID :进程的ID,这个ID很有用,在linux中内核管理进程就得靠pid来识别和管理某一个程,比如我想终止某一个进程,则用kill 进程的pid有时并不能杀掉,则需要加一个-9选项了kill -9 进程pid,这样做有点暴力,严重的时候回丢失数据,所以尽量不用。
4. 在proc目录下存放了很多数字的目录,其实就是PID进程文件,可以用ls来查看
5. STAT :表示进程的状态,进程状态分为以下几种(不要求记住,但要大致了解)
-
[ ] D:不能中断的进程(通常为IO),会影响系统负载.
-
[ ] R(run):正在运行中的进程,其中包括了等待CPU的时间片的进程(某时间段内)
-
[ ] S(sleep):已经中断的进程,通常情况下,系统中大部分进程都是这个状态
-
[ ] T:已经停止或者暂停的进程,如果我们正在运行一个命令,比如说 sleep 10 如果我们按一下ctrl -z 让他暂停,那么我们用ps查看就会显示T这个状态
- fg命令恢复刚在的暂停命令
- vmstat占用cpu的时间非常短暂,只在某个时刻抓数据,基本不占用CPU。
-
[ ] W:这个好像是说,从内核2.6xx 以后,表示为没有足够的内存页分配
-
[ ] Z:僵尸进程,杀不掉,打不死的垃圾进程,占系统一小点资源,不过没有关系。如果太多,就有问题了。一般不会出现。
-
[ ] <:高优先级进程
-
[ ] N:低优先级进程
-
[ ] L:在内存中被锁了内存分页
-
[ ] s:主进程
-
[ ] l:多线程进程,该进程有多个线程.
-
[ ] +:代表在前台运行的进程,比如当前终端执行ps aux就是前台进程,前面出现的S+
10.9 用netstat命令查看网络状况
netstat命令用来打印网络连接状况、系统所开放端口、路由表等信息。
1.netstat -lnp 打印当前系统启动哪些端口
[root@localhost ~]# netstat -lnp //打印当前系统启动哪些端口
- 需要了解tcp,tcp6,udp的概念??
2.netstat -an 所有网络连接状态
[root@localhost ~]# netstat -an //打印网络链接情况
3. netstat -lntp 只看出tcp的,不包含socket;netstat -lnup 只看udp
- CLOSE,TIME_WAIT表示三次握手四次挥手的状态
4. ss -an和netstat异曲同工,不显示进程名字
5. ss -an | grep -i listen //LISTEN是大写,所以加-i,但这样不会显示进程的名字
6. 分享一个小技巧,网站并发连接数#netstat -an | awk '/^tcp/ {++sta[$NF]} END {for(key in sta) print key,"\t",sta[key]}'
ESTABLISHED 45 这是一个很重要的参数,必须在1000以内.客户端同时和你的服务器通信。
10.10 抓包工具tcpdump
1. 安装tcpdump包
如果没有tcpdump 这个命令,需要用yum install -y tcpdump命令去安装一下。
2. tcpdump-i;tcpdump-nn;tcpdump-c
- [ ] -i 选项后面跟设备名称,如果你想抓ens33网卡的包,后面则要跟eens33。
- [ ] -nn选项的作用是让第三列和第四列显示成IP+端口号的形式,如果不加-nn则显示的是主机名+服务名称。
- [ ] -c选项,指定抓包数量。
3.tcpdump -nn -i ens33 port 22 指定网卡名字,host指定ip:tcpdump host 192.168.x.x
//-n第一个n表示不把主机的网络地址转换成名字,以数字形式显示
[root@localhost ~]# tcpdump -nn -i ens33
# tcpdump -nn -i ens33 port 22 //只抓22端口的包
# tcpdump host 192.168.x.x //抓取指定ip的包
# tcpdump -nn -i ens33 tcp and not port 22 //指定抓tcp的包,但是不要22端口的
# tcpdump -nn -i ens33 port 22 and port 53 //只抓22和53端口的包
- 关注的是IP 192.168,72.130.22 > 192.168.72.1.53478 这几列是比较重要的额,可以看到数据的流向.
4.DDos 也叫udp flood攻击,只能有专门的预防攻击软件
5. tcpdump -nn -i ens33 -c 10 -i ens33 -w /tmp/1.cap //保存10次抓包到/tmp/1.cap,无法用cat查看
6. tcpdump -r /tmp/test.cap //读取抓包文件
7. wireshark工具下的抓包命令tshark
抓包命令是tshark,这条命令用于web服务器,将显示的是web访问日志,如果服务器没有配置访问日志,可以临时使用该命令查看一下当前服务器上的Web请求。要注意的是如果你的机器上没有开启Web服务,是不会显示任何内容的
tshark -n -t a -R http.request -T fields -e "frame.time" -e "ip.src" -e "http.host" -e "http.request.method" -e "http.request.uri"
扩展学习: TCP/IP 三次握手,四次挥手过程
1. Linux服务器上的11种网络连接状态
通常情况下:一个正常的TCP连接,都会有三个阶段:1、TCP三次握手;2、数据传送;3、TCP四次挥手
注:以下说明最好能结合”图2.5 :TCP的状态机”来理解。
-
[ ] SYN: (同步序列编号,Synchronize Sequence Numbers)该标志仅在三次握手建立TCP连接时有效。表示一个新的TCP连接请求。
-
[ ] ACK: (确认编号,Acknowledgement Number)是对TCP请求的确认标志,同时提示对端系统已经成功接收所有数据。
-
[ ] FIN: (结束标志,FINish)用来结束一个TCP回话.但对应端口仍处于开放状态,准备接收后续数据。
-
LISTEN:首先服务端需要打开一个socket进行监听,状态为LISTEN. /* The socket is listening for incoming connections. 侦听来自远方TCP端口的连接请求 */
-
SYN_SENT:客户端通过应用程序调用connect进行active open.于是客户端tcp发送一个SYN以请求建立一个连接.之后状态置为SYN_SENT. /*The socket is actively attempting to establish a connection. 在发送连接请求后等待匹配的连接请求 */
-
SYN_RECV:服务端应发出ACK确认客户端的SYN,同时自己向客户端发送一个SYN. 之后状态置为SYN_RECV /* A connection request has been received from the network. 在收到和发送一个连接请求后等待对连接请求的确认 */
-
ESTABLISHED: 代表一个打开的连接,双方可以进行或已经在数据交互了。/* The socket has an established connection. 代表一个打开的连接,数据可以传送给用户 */
-
FIN_WAIT1:主动关闭(active close)端应用程序调用close,于是其TCP发出FIN请求主动关闭连接,之后进入FIN_WAIT1状态./* The socket is closed, and the connection is shutting down. 等待远程TCP的连接中断请求,或先前的连接中断请求的确认 */
-
CLOSE_WAIT:被动关闭(passive close)端TCP接到FIN后,就发出ACK以回应FIN请求(它的接收也作为文件结束符传递给上层应用程序),并进入CLOSE_WAIT. /* The remote end has shut down, waiting for the socket to close. 等待从本地用户发来的连接中断请求 */
-
FIN_WAIT2:主动关闭端接到ACK后,就进入了FIN-WAIT-2 ./* Connection is closed, and the socket is waiting for a shutdown from the remote end. 从远程TCP等待连接中断请求 */
-
LAST_ACK:被动关闭端一段时间后,接收到文件结束符的应用程序将调用CLOSE关闭连接。这导致它的TCP也发送一个 FIN,等待对方的ACK.就进入了LAST-ACK . /* The remote end has shut down, and the socket is closed. Waiting for acknowledgement. 等待原来发向远程TCP的连接中断请求的确认 */
-
TIME_WAIT:在主动关闭端接收到FIN后,TCP就发送ACK包,并进入TIME-WAIT状态。/* The socket is waiting after close to handle packets still in the network.等待足够的时间以确保远程TCP接收到连接中断请求的确认 */
-
CLOSING: 比较少见./* Both sockets are shut down but we still don’t have all our data sent. 等待远程TCP对连接中断的确认 */
-
CLOSED: 被动关闭端在接受到ACK包后,就进入了closed的状态。连接结束./* The socket is not being used. 没有任何连接状态 */
TIME_WAIT状态的形成只发生在主动关闭连接的一方。
主动关闭方在接收到被动关闭方的FIN请求后,发送成功给对方一个ACK后,将自己的状态由FIN_WAIT2修改为TIME_WAIT,而必须再等2倍 的MSL(Maximum Segment Lifetime,MSL是一个数据报在internetwork中能存在的时间)时间之后双方才能把状态 都改为CLOSED以关闭连接。目前RHEL里保持TIME_WAIT状态的时间为60秒。
当然上述很多TCP状态在系统里都有对应的解释或设置,可见man tcp
2. 关于长连接和短连接:通俗点讲:短连接就是一次TCP请求得到结果后,连接马上结束.而长连接并不马上断开,而一直保持着,直到长连接TIMEOUT(具体程序都有相关参数说明).长连接可以避免不断的进行TCP三次握手和四次挥手.
长连接(keepalive)是需要靠双方不断的发送探测包来维持的,keepalive期间服务端和客户端的TCP连接状态是ESTABLISHED.目前http 1.1版本里默认都是keepalive(1.0版本默认是不keepalive的),ie6/7/8和firefox都默认用的是http 1.1版本了(如何查看当前浏览器用的是哪个版本,这里不再赘述)。Apache,java
一个应用至于到底是该使用短连接还是长连接,应该视具体情况而定。一般的应用应该使用长连接。
2.1 Linux的相关keepalive参数
a、 tcp_keepalive_time - INTEGER
How often TCP sends out keepalive messages when keepalive is enabled.
Default: 2hours.
b、 tcp_keepalive_probes - INTEGER
How many keepalive probes TCP sends out, until it decides that the
connection is broken. 在认定连接失效之前,发送多少个TCP的keepalive探测包。
Default value: 9.
缺省值是9,这个值乘以tcp_keepalive_intvl之后决定了,一个连接发送了keepalive之后可以有多少时间没有回应。
c、 tcp_keepalive_intvl - INTEGER
How frequently the probes are send out. Multiplied by
tcp_keepalive_probes it is time to kill not responding connection,
after probes started. Default value: 75sec i.e. connection
will be aborted after ~11 minutes of retries.
当探测没有确认时,重新发送探测的频度,缺省值是75秒
2、F5负载均衡上的相关参数说明
a、Keep Alive Interval
Specifies, when enabled, how frequently the system sends data over an idle TCP connection, to determine whether the connection is still valid.V
Specify: Specifies the interval at which the system sends data over an idle connection, to determine whether the connection is still valid. The default is 1800 milliseconds.
b、Time Wait
Specifies the length of time that a TCP connection remains in the TIME-WAIT state before entering the CLOSED state.
Specify: Specifies the number of milliseconds that a TCP connection can remain in the TIME-WAIT state. The defaultis 2000.
c、Idle Timeout
Specifies the length of time that a connection is idle (has no traffic) before the connection is eligible for deletion.
Specify: Specifies a number of seconds that the TCP connection can remain idle before the system deletes it. The default is 300 seconds.
3、Apache的相关参数说明
以下是Apache/2.0.61版本的默认参数和说明
a、KeepAlive:
default On.Whether or not to allow persistent connections (more than
one request per connection). Set to “Off” to deactivate.
b、MaxKeepAliveRequests:
default 100.The maximum number of requests to allow
during a persistent connection. Set to 0 to allow an unlimited amount.
We recommend you leave this number high, for maximum performance.
c、KeepAliveTimeout:
default 15. Number of seconds to wait for the next request from the
same client on the same connection.
扩展:Linux Socket 编程与 TCP/UDP协议流程
1.网络中进程之间如何通信
本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类:
- [ ] 消息传递(管道、FIFO、消息队列)
- [ ] 同步(互斥量、条件变量、读写锁、文件和写记录锁、信号量)
- [ ] 共享内存(匿名的和具名的)
- [ ] 远程过程调用(Solaris门和Sun RPC)
我们要讨论的是网络中进程之间如何通信?首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的。其实TCP/IP协议族已经帮我们解决了这个问题,网络层的“ip地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。这样利用三元组--ip地址,协议,端口就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。
使用TCP/IP协议的应用程序通常采用应用编程接口:UNIX BSD的套接字(socket)和UNIX System V的TLI(已经被淘汰),来实现网络进程之间的通信。就目前而言,几乎所有的应用程序都是采用socket,而现在又是网络时代,网络中进程通信是无处不在,这就是我为什么说“一切皆socket”。
2.什么是TCP/IP,UDP?
TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。 TCP/IP协议存在于OS中,网络服务通过OS提供,在OS中增加支持TCP/IP的系统调用——Berkeley套接字,如Socket,Connect,Send,Recv等 UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种。如图:
- TCP/IP协议族包括运输层、网络层、链路层,而socket所在位置如图,Socket是应用层与TCP/IP协议族通信的中间软件抽象层。
3.什么是Socket?
上面我们已经知道网络中的进程是通过socket来通信的,那什么是socket呢?socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。我的理解就是Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭),这些函数我们在后面进行介绍。
socket一词的起源
在组网领域的首次使用是在1970年2月12日发布的文献IETF RFC33中发现的,撰写者为Stephen Carr、Steve Crocker和Vint Cerf。根据美国计算机历史博物馆的记载,Croker写道:“命名空间的元素都可称为套接字接口。一个套接字接口构成一个连接的一端,而一个连接可完全由一对套接字接口规定。”计算机历史博物馆补充道:“这比BSD的套接字接口定义早了大约12年。”
4. socket的基本操作
既然socket是“open—write/read—close”模式的一种实现,那么socket就提供了这些操作对应的函数接口。下面以TCP为例,介绍几个基本的socket接口函数。
tcp socket 流程
5.socket中TCP的三次握手建立连接详解
我们知道tcp建立连接要进行“三次握手”,即交换三个分组。大致流程如下:
我们以张三和李四的见面来模拟该过程,这三次握手就好比两人在间隔50的地方见到对方,因为雾霾等原因不能100%确认,所以要招手来相互确认对方是否认识自己。 张三主动招手(SYN)和李四打招呼,李四还以微笑(ACK)并招手(SYN)确认是否是张三,张三点头微笑(ACK),李四看到张三的ACK后,确认后,进入了established状态。
我们看到这个过程中一共是四个动作,张三招手--李四点头微笑--李四招手--张三点头微笑。
其中李四连续进行了2个动作,先是点头微笑(回复对方),然后再次招手(寻求确认),实际上可以将这两个动作合一,招手的同时点头和微笑(syn+ack)。
于是四个动作就简化成了三个动作,张三招手--李四点头微笑并招手--张三点头微笑。这就是三次握手的本质,中间的一次动作是两个动作的合并。
我们看到有两个中间状态,syn_sent和syn_rcvd,这两个状态叫着「半打开」状态,就是向对方招手了,但是还没来得及看到对方的点头微笑。
syn_sent是主动打开方的「半打开」状态,syn_rcvd是被动打开方的「半打开」状态。客户端是主动打开方,服务器是被动打开方。
syn_sent: syn package has been sent
syn_rcvd: syn package has been received
TCP 数据传输
TCP 数据传输就是两个人隔空对话,差了一点距离,所以需要对方反复确认听见了自己的话。
张三喊了一句话(data),李四听见了之后要向张三回复自己听见了(ack)。
如果张三喊了一句,半天没听到李四回复,张三就认为自己的话被大风吹走了,李四没听见,所以需要重新喊话,这就是tcp重传。
也有可能是李四听到了张三的话,但是李四向张三的回复被大风吹走了,以至于张三没听见李四的回复。
张三并不能判断究竟是自己的话被大风吹走了还是李四的回复被大风吹走了,张三也不用管,重传一下就是。
既然会重传,李四就有可能同一句话听见了两次,这就是「去重」。「重传」和「去重」工作操作系统的网络内核模块都已经帮我们处理好了,用户层是不用关心的。 张三可以向李四喊话,同样李四也可以向张三喊话,因为tcp链接是「双工的」,双方都可以主动发起数据传输。不过无论是哪方喊话,都需要收到对方的确认才能认为对方收到了自己的喊话。
张三可能是个高射炮,一说连说了八句话,这时候李四可以不用一句一句回复,而是连续听了这八句话之后,一起向对方回复说前面你说的八句话我都听见了,这就是批量ack。
但是张三也不能一次性说了太多话,李四的脑子短时间可能无法消化太多,两人之间需要有协商好的合适的发送和接受速率,这个就是「TCP窗口大小」。
网络环境的数据交互同人类之间的对话还要复杂一些,它存在数据包乱序的现象。
同一个来源发出来的不同数据包在「网际路由」上可能会走过不同的路径,最终达到同一个地方时,顺序就不一样了。
操作系统的网络内核模块会负责对数据包进行排序,到用户层时顺序就已经完全一致了。
客户端向服务器发送一个SYN J 服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1 客户端再想服务器发一个确认ACK K+1 只有就完了三次握手,但是这个三次握手发生在socket的那几个函数中呢?请看下图:
图1、socket中发送的TCP三次握手
从图中可以看出,当客户端调用connect时,触发了连接请求,向服务器发送了SYN J包,这时connect进入阻塞状态;服务器监听到连接请求,即收到SYN J包,调用accept函数接收请求向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态;客户端收到服务器的SYN K ,ACK J+1之后,这时connect返回,并对SYN K进行确认;服务器收到ACK K+1时,accept返回,至此三次握手完毕,连接建立。
总结:客户端的connect在三次握手的第二个次返回,而服务器端的accept在三次握手的第三次返回。
6. socket中TCP的四次握手释放连接详解
上面介绍了socket中TCP的三次握手建立过程,及其涉及的socket函数。现在我们介绍socket中的四次握手释放连接的过程,请看下图: 图2、socket中发送的TCP四次握手
图示过程如下:
- [ ] 某个应用进程首先调用close主动关闭连接,这时TCP发送一个FIN M;
- [ ] 另一端接收到FIN M之后,执行被动关闭,对这个FIN进行确认。它的接收也作为文件结束符传递给应用进程,因为FIN的接收意味着应用进程在相应的连接上再也接收不到额外数据;
- [ ] 一段时间之后,接收到文件结束符的应用进程调用close关闭它的socket。这导致它的TCP也发送一个FIN N;
- [ ] 接收到这个FIN的源发送端TCP对它进行确认。
这样每个方向上都有一个FIN和ACK。
TCP 四次挥手
TCP断开链接的过程和建立链接的过程比较类似,只不过中间的两部并不总是会合成一步走,所以它分成了4个动作,张三挥手(fin)——李四伤感地微笑(ack)——李四挥手(fin)——张三伤感地微笑(ack)。
之所以中间的两个动作没有合并,是因为tcp存在「半关闭」状态,也就是单向关闭。
张三已经挥了手,可是人还没有走,只是不再说话,但是耳朵还是可以继续听,李四呢继续喊话。等待李四累了,也不再说话了,超张三挥了挥手,张三伤感地微笑了一下,才彻底结束了。
上面有一个非常特殊的状态time_wait,它是主动关闭的一方在回复完对方的挥手后进入的一个长期状态,这个状态标准的持续时间是4分钟,4分钟后才会进入到closed状态,释放套接字资源。不过在具体实现上这个时间是可以调整的。
它就好比主动分手方要承担的责任,是你提出的要分手,你得付出代价。这个后果就是持续4分钟的time_wait状态,不能释放套接字资源(端口),就好比守寡期,这段时间内套接字资源(端口)不得回收利用。
它的作用是重传最后一个ack报文,确保对方可以收到。因为如果对方没有收到ack的话,会重传fin报文,处于time_wait状态的套接字会立即向对方重发ack报文。
同时在这段时间内,该链接在对话期间于网际路由上产生的残留报文(因为路径过于崎岖,数据报文走的时间太长,重传的报文都收到了,原始报文还在路上)传过来时,都会被立即丢弃掉。
4分钟的时间足以使得这些残留报文彻底消逝。不然当新的端口被重复利用时,这些残留报文可能会干扰新的链接。
4分钟就是2个MSL,每个MSL是2分钟。MSL就是maximium segment lifetime——最长报文寿命。这个时间是由官方RFC协议规定的。至于为什么是2个MSL而不是1个MSL,我还没有看到一个非常满意的解释。
四次挥手也并不总是四次挥手,中间的两个动作有时候是可以合并一起进行的,这个时候就成了三次挥手,主动关闭方就会从fin_wait_1状态直接进入到time_wait状态,跳过了fin_wait_2状态。
参考文献:http://blog.csdn.net/banbanlin/article/details/46368031