1.1:第七层:应用层的功能:
为应用软件提供接口,使应用程序可以使用网络服务。常见的应用层协议:
http(80)、ftp(20/21)、smtp(25)、pop3(110)、telnet(23)、dns(53)等
1.2:第六层:表示层的功能:
数据的编码和解码、数据的加密和解密、数据和压缩和解压缩,常见的标准有JPEG/ASCII等
1.3:第五层:会话层的功能:
创建、管理和终止表示层实体之间的会话链接,在设各或节点之间提供会话控制,它在系统之间协调通讯过程,并提供3种不一样的方式来组织它们之间的通讯:单工、半双工和全双工
1.4:第四层:传输层的功能:
负责创建端到端的链接,保证报文在端到端之间的传输。提供可靠TCP及不可靠UDP的传输机制,服务点编址、分段与重组、链接控制、流量控制、差错控制。
1.5:第三层:网络层的功能:
定义逻辑地址,逻辑寻址,将数据分组从源传输到目的,路径选择、路由发现、维护路由表,功能是隔离广播域;隔离广播,路由选择;维护路由表,寻址及转发,流量管理并链接广域网
1.6:第二层:数据链路层的功能:
组帧、物理编址,将数据帧从链路上的一个节点传递到另外一个节点,流量控制、差错控制、接入控制
1.7:第一层:物理层的功能:
在介质上传递比特流,定义接口和媒体的物理特性,定义比特的表示、数据传输速率、信号的传输模式(单工、半双工、全双工),定义网络物理拓扑(网状、星型、环型、总线型等)linux
TCP,全称Transfer Control Protocol,中文名为传输控制协议,它工做在OSI的传输层,提供面向链接的可靠传输服务,TCP的工做主要是创建链接,而后从应用层程序中接收数据并进行传输。TCP采用虚电路链接方式进行工做,在发送数据前它须要在发送方和接收方创建一个链接,数据在发送出去后,发送方会等待接收方给出一个确认性的应答,不然发送方将认为此数据丢失,并从新发送此数据。apache
在创建链接的时候,所谓的客户端与服务端是相对应的,即要看是谁主动链接的谁,若是A主动链接B那么A就是客户端而B是服务端,若是返过来B主动链接A,那么B就是客户端而A就成了服务端。
3.1:链接过程:
第一次握手:客户端发送SYN标志位为1的请求到服务端,并随机生成一个seq 序列号x,其中seq是随机产生的数据包的序列号。
第二次握手:服务器收到客户端请求并返回SYN=1,ACK=1,seq=y,ack=x+1,其中ACK=1表示是响应报文,seq=y是服务器随机产生的数据包序列号,ack=x+1是确认客户端序列号有效并返回给客户端确认。
第三次握手:客户端收到服务器的确认ack=x+1有效的验证信息,即在本身发送的序列号基础之上加了1表示服务器收到并返回,表示第二次链接有效,而后客户端恢回复ACK=1,seq=x+1,ack=y+1,这是讲服务器发来+1后的序列号当作本身的seq序列号,确认号ack使用服务器的随机号y再加1即ack=y+1,这样客户端就完成了第三次的验证在讲数据包发给服务器,服务器收到后验证确认号是在本身的seq之上加了1,表示没有问题就开始传输数据。
注:
ACK :TCP协议规定,只有ACK=1时有效,也规定链接创建后全部发送的报文的ACK必须为1
Seq:序号,4字节,范围为0^32—1^32,共4284967296,达到时从新开始计算
在第三次的时候SYN等于0,由于SYN(SYNchronization) 只i在链接创建时用来同步序号,当SYN=1而ACK=0时,代表这是一个链接请求报文,对方若赞成创建链接,则应在响应报文中使SYN=1和ACK=1. 所以, SYN置1就表示这是一个链接请求或链接接受报文,链路创建成功以后就将标志位置为0。
SYN(synchronous创建联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急) Sequence number(顺序号码) Acknowledge number(确认号码)安全
TCP断开要四次是由于TCP传输数全双工的,即数据是在同一时间内两条数据链路双向互相传输的,所以每一个方向都要单独关闭一次,断开须要客户端到服务端断开一次,而服务端到客户端也须要断开一次,这样的断开才是完整的断开,
第一次断开:客户方发给服务器一个FIN为1的请求,FIN为1表示是一个断开链接的请求,即表示数据传输完毕请求断开,并发送seq序列号和Ack确认号。
第二次断开:服务器收到客户端请求并返回ACK标志位为1,Ack为Seq+1等于201,并将对方的Ack做为本身的Seq序列号的确认数据包,biao 接收到请求赞成断开。
第三次断开:服务器发送ACK=1,FIN=1,Seq等于客户端第一次请求断开的Ack确认号+1,即Seq等于501的断开请求给客户端。
第四次断开:客户端发送ACK=1,Ack在上一步Seq上+1等于502,并使用在第二次断开中服务器发送的Ack确号201做为本次的序列号发给服务器表示赞成断开,服务器收到后验证序列号是第二次的,验证Ack是第三次+1的,确认没有问题后赞成断开,而后将端口置为TIME_WAIT状态,等待2 MSL时间后置为关闭状态,被动方收到主动方的报文确认Ack确认号没有问题后将端口置为CLOSED,至此端口关闭。
SYN(synchronous创建联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急) Sequence number(顺序号码) Acknowledge number(确认号码)
四次断开的图形示意以下:服务器
TCP端口一共有十一种状态,CLOSE_WAIT表示是程序y关闭链接,而TIME_WAIT只占用一个socket链接,到时间以后会释放,所以大量的CLOSE_WAIT是比大量的TIME_WAIT影响更大,另外还有FIN_WAIT1和FIN_WAIT2,若是有FIN_WAIT2也表示服务有问题,如下是每一个端口状态的含义:
5.1:CLOSED:端口默认是关闭状态。
5.2:LISTEN: 服务器程序开始监听一个端口,就是LISTEN状态。
5.3:SYN_RCVD:三次握手的第二次握手后的端口状态,是收到了客户端发送的SYN_SENT数据包以后的状态,这个状态很短暂,正常在服务器上是不多看到的,除非服务器故意不发送最后一次握手数据包,服务器返回给客户端SYN确认以后就会将在本身的端口置为SYN_RCVD。
5.4:SYN_SENT:SYN_SENT状态表示客户端已发送SYN=1的请求链接报文,发送以后客户端就会将本身的端口状态置为SYN_SENT。
5.5:ESTABLISHED:表示已经链接成功,客户端收到服务器的确认报文会回复服务器,而后就将端口置为ESTABLISHED,服务器第三次收到客户端的Ack确认就会将端口置为ESTABLISHED并开始传输数据。
5.6:FIN_WAIT_1:出如今主动关闭方,FIN_WAIT_1状态其实是当SOCKET在ESTABLISHED状态时,当任意一方想主动关闭链接,向对方发送了FIN=1的断开链接请求报文,此时该SOCKET即 进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,固然在实际的正常状况下,不管对方何种状况下,都应该马 上回应ACK报文,因此FIN_WAIT_1状态通常是比较难见到的,而FIN_WAIT_2状态还有时经常能够用netstat看到。
5.7:FIN_WAIT_2:出如今主动关闭方,当被动方回应FIN_WAIT_1的ACK报文后,则进入到FIN_WAIT_2状态
5.8:TIME_WAIT:出如今主动关闭方,表示收到了对方的FIN请求关闭报文,并发送出了ACK报文,就等2MSL后便可回到CLOSED可用状态了。若是FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,能够直接进入到TIME_WAIT状态,而无须通过FIN_WAIT_2状态。
5.9:CLOSING: 这种状态比较特殊,实际状况中应该是不多见,属于一种比较罕见的例外状态。正常状况下,当你发送FIN报文后,按理来讲是应该先收到(或同时收到)对方的 ACK报文,再收到对方的FIN报文。可是CLOSING状态表示你发送FIN报文后,并无收到对方的ACK报文,反而却也收到了对方的FIN报文。什 么状况下会出现此种状况呢?其实细想一下,也不可贵出结论:那就是若是双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报 文的状况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET链接。
5.10:CLOSE_WAIT: 表示在等待关闭端口,这种状态存在于被动关闭的一方。
5.11:LAST_ACK: 是被动关闭方在主动关闭一方在发送FIN报文后,最后等待对方的ACK报文,当再次收到ACK报文后,也便可以进入到CLOSED可用状态了。
5.12:区分主动断开和被动端口方的端口状态:
主动端口方:SYN_SENT、FIN_WAIT一、FIN_WAIT二、CLOSING、TIME_WAIT 。
被动断开方:LISTEN、SYN_RCVD、CLOSE_WAIT、LAST_ACK 。
都具备的:CLOSED 、ESTABLISHED 。
5.13:关于优化:
socket就是一个TCP链接,包括源地址、源端口、目标地址、目标端口和协议(TCP|UDP),0端口是保留不能使用的,所以服务器的最大端口使用数量为63353个,最大65536个端口是由于TCP报文头部有个端口长度为2^16次方等于65536,查看当前打开的端口范围# cat /proc/sys/net/ipv4/ip_local_port_range,单个IP地址能接受的最大并发为六万多,1万个TIME_WAIT大约使用1MB的内存CPU占用更小,所以资源使用很小能够忽略不计,可是会占用一个socket,能够经过在负载上配置多个公网IP地址以提升高并发的问题,
[root@localhost ~]# cat /proc/sys/net/ipv4/tcp_tw_recycle
0 #用于快速回收处于TIME_WAIT状态的socket以便从新分,在负载服务器不能打开,会致使经过nat上网的后续用户没法打开网页,由于后面的访问用户时间戳小于前面的用户,会致使数据包被负载服务器丢弃,能够在内网使用,可是一般建议关闭。
[root@localhost ~]# cat /proc/sys/net/ipv4/tcp_tw_reuse
0 #kernel会复用处于TIME_WAIT状态的socket,即容许将TIME_WAIT状态得socket用于直接新的TCP链接,负载服务器建议打开
[root@localhost ~]# cat /proc/sys/net/ipv4/tcp_timestamps
1 #记录数据包的时间戳,判断是新的数据包仍是旧的,若是是旧的就丢弃,配合上面两个选项的时候必定要打开才生效。网络
Apache 2.X 支持插入式并行处理模块,称为多路处理模块(Multi-Processing Modules,MPM),在linux 系统,有3个不一样类型的版本可供选择,具体以下:
6.1:Prefork MPM: 预派生模式,有一个主控制进程,而后生成多个子进程,使用select模型,最大并发1024,每一个子进程有一个独立的线程响应用户请求,相对比较占用内存,可是比较稳定,能够设置最大和最小进程数,是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景。
优势:稳定
缺点:慢,占用资源,不适用于高并发场景
配置文件原内容:
#prefork MPM
#StartServers: number of server processes to start
#MinSpareServers: minimum number of server processes which are kept spare
#MaxSpareServers: maximum number of server processes which are kept spare
#MaxRequestWorkers: maximum number of server processes allowed to start
#MaxConnectionsPerChild: maximum number of connections a server process serves
#before terminating多线程
<IfModule mpm_prefork_module>
StartServers 5 #定义apache服务在启动时启动的子进程数量
MinSpareServers 5 #定义最小空闲进程数,空闲进程就是没有处理用户请求的进程数
MaxSpareServers 10 #定义最大空闲进程数
MaxRequestWorkers 250 #定义在prefork模式下的最大并发链接数,表示了apache的最大并发处理能力,超过的链接请求将被排队等候处理。
MaxConnectionsPerChild 0 #进程生命周期内,处理的最大请求数目。达到该数目后,进程将死掉。若是设置为0,表示没有限制。该参数的意义在于,避免了可能存在的内存泄露带来的系统问题。
</IfModule>并发
若是肯定合适的MaxRequestWorkers呢?
首先,经过top命令查看apache进程占用的资源,主要看%CPU和%MEM这两个指标,例如,每一个进程的CPU占用率不超过1%,每一个进程的内存占用率不超过2%,考虑内存限制,比较合适的apache进程数量为50个,而后,逐步测试最大值。经过观测得来的CPU和内存的指标有必定的偏差,通常能够适当调节这个数值,例如调到1.5或者2倍,再经过峰值场景下的机器是否卡顿来判断是继续上调仍是下调。
6.2:woker MPM:是一种多进程和多线程混合的模型,有一个控制进程,启动多个子进程,每一个子进程里面包含固定的线程,使用线程程来处理请求,当线程不够使用的时候会再启动一个新的子进程,而后在进程里面再启动线程处理请求,因为其使用了线程处理请求,所以能够承受更高的并发。
优势:相比prefork 占用的内存较少,能够同时处理更多的请求
缺点:使用keep-alive的长链接方式,某个线程会一直被占据,即便没有传输数据,也须要一直等待到超时才会被释放。若是过多的线程,被这样占据,也会致使在高并发场景下的无服务线程可用。(该问题在prefork模式下,一样会发生)
配置文件原内容详解:
#worker MPM
#StartServers: initial number of server processes to start
#MinSpareThreads: minimum number of worker threads which are kept spare
#MaxSpareThreads: maximum number of worker threads which are kept spare
#ThreadsPerChild: constant number of worker threads in each server process
#MaxRequestWorkers: maximum number of worker threads
#MaxConnectionsPerChild: maximum number of connections a server process serves
#before terminating异步
<IfModule mpm_worker_module>
StartServers 3 # #定义apache服务在启动时启动的子进程数量,默认是3个
MinSpareThreads 75 # 整个控制进程保持最小数的空闲线程数
MaxSpareThreads 250 # 整个控制进程保持最大数的空闲线程数
#ThreadLimit 64 # 每一个子进程能够启动的线程数量上限值,默认没有设置
ThreadsPerChild 25 # 每一个子进程启动的线程默认数量,开启启动两个子进程每一个子进程25个 线程,就是apache 启动后开启25个线程。
MaxRequestWorkers 400 # 全部子进程加起来的线程数量最大值,数量等于最大启动的进程数*ThreadsPerChild(每一个进程的线程数)
MaxConnectionsPerChild 0 # 每一个子进程被请求多少次服务后被kill掉从新生成一个新的子进程,为了解决内存回收方面的问题,0为不设置
</IfModule>
6.3:event MPM:Apache中最新的模式,属于事件驱动模型(epoll),每一个进程响应多个请求,在如今版本里的已是稳定可用的模式。它和worker模式很像,最大的区别在于,它解决了keep-alive场景下,长期被占用的线程的资源浪费问题(某些线程由于被keep-alive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)。event MPM中,会有一个专门的线程来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又容许它释放。这样加强了高并发场景下的请求处理能力。
event只在有数据发送的时候才开始创建链接,链接请求才会触发工做线程,即便用了TCP的一个选项,叫作延迟接受链接TCP_DEFER_ACCEPT,加了这个选项后,若客户端只进行TCP链接,不发送请求,则不会触发Accept操做,也就不会触发工做线程去干活,进行了简单的防***(TCP链接),可使用Telnet进行测试验证:
主机192.168.10.130为客户端机器,192.168.10.131为apache服务器机器使用event模式:
在192.168.10.130上telnet 192.168.10.131 80,而后在192.168.10.130客户端机器上使用netstat查看,发现链接已经创建,处于ESTABLISHED状态,而后再到apache服务器192.168.10.131使用netstat查看,发现是处于SYN_RECV状态。
优势:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又容许它释放
缺点:没有线程安全控制
配置文件内容:
#event MPM
#StartServers: initial number of server processes to start
#MinSpareThreads: minimum number of worker threads which are kept spare
#MaxSpareThreads: maximum number of worker threads which are kept spare
#ThreadsPerChild: constant number of worker threads in each server process
#MaxRequestWorkers: maximum number of worker threads
#MaxConnectionsPerChild: maximum number of connections a server process serves
#before terminating
<IfModule mpm_event_module>
StartServers 3 #apache服务启动的子进程数,默认3个
MinSpareThreads 75 #控制进程保持最小的空闲线程数
MaxSpareThreads 250 #控制进程保持的最大空闲线程数
ThreadsPerChild 25 #每一个子进程启动的线程数
MaxRequestWorkers 400 #并发最大请求数,也就是全部子进程加起来的线程数量,woker模式下的400就是并发400,可是因为是异步处理请求的,所以这里的400比woker模型下的并发处理速度要快不少,由于event省略了工做线程的会话保持。
MaxConnectionsPerChild 0 #每一个子进程请求多少次之后被kill掉从新生成一个新的子进程。
</IfModule>socket