当前位置: 首页 > news >正文

php做彩票网站个人管理系统

php做彩票网站,个人管理系统,重庆世界500强企业,做外贸的社交网站有哪些上一篇《第二十九篇#xff1a;图解TCP三次握手#xff0c;看过不会忘#xff0c;从底层说清楚#xff0c;TCP系列四》说了TCP的三次握手#xff0c;接下来我将讲解TCP四次挥手。 既然有连接就有断开#xff0c;谈到这里#xff0c;有的同学可能会想#xff0c;不就是…上一篇《第二十九篇图解TCP三次握手看过不会忘从底层说清楚TCP系列四》说了TCP的三次握手接下来我将讲解TCP四次挥手。 既然有连接就有断开谈到这里有的同学可能会想不就是TCP的断开吗简单四次挥手解决问题只要了解了四次的挥手过程就掌握了TCP的断开我只能说同学too young,too simple且让我提出几个问题去思考 连接断开是谁先发起的如果断电/断网了连接会断开吗程序奔溃了连接会断开吗什么情况下没有四次挥手连接也会断开连接断开发生在应用层还是传输层 只有掌握了断开的底层逻辑才能在工作中遇到问题不慌不忙做到游刃有余的解决问题轻松拿高薪。 一、理想状态下一个 TCP 连接可以被长期保持 前面我们说到TCP连接其实就是通过三次握手在通信双方的主机里面保存对应的通信信息即⽤于保证可靠性和流量控制而维护的某些状态信息称为连接也可以理解成“通信线路”这些状态信息包括Socket、序列号和窗⼝⼤⼩等。如下图所示 套接字由 IP 地址、端⼝号以及传输层协议(TCP或UDP)组成序列号⽤来解决乱序问题等窗⼝⼤⼩⽤来做流量控制 所以理论上如果通信双方的“连接信息”不变一直保存在双方主机则理论连接会被长期保存。 但是现实却往往是很残酷的连接经常或被动断开比如断电TCP连接信息缓存丢失导致连接遭到损坏或一方主机根据情况主动断开比如不想浪费资源内存和断开是有限的一方主机在发送完资源后用程序主动关闭连接。 二、那么下面就让我们一起来梳理哪些情况会发生连接断开 通信双方信息交互完后一方主动调用TCP软件的“连接断开方法”进行TCP四次挥手断开连接程序奔溃、使用CTRL  C、kill -9 方法杀死进程硬件奔溃主机损坏、断网等一方断电或宕机防火墙关闭连接其他情况 三、会正常执行TCP四次挥手断开连接的情况有下面几种 1.通信双方信息交互完后一方主动调用TCP软件的“连接断开方法” 比如应用程序使用HTTP协议进行信息交互当交互完后客户端因为信息发送完成主动调用close方法或实现http的程序包因为检测到通信双方长时间没有信息交互而主动发起连接断开这些都发生在应用层就是程序员开发的应用程序。 2.程序奔溃、使用CTRL  C、kill -9 方法杀死进程 因为应用程序没有主动调用TCP软件的断开流程将有OS系统自动触发TCP四次挥手断开流程。 3.防火墙关闭连接 防火墙触发TCP四次挥手断开流程。 四、TCP正常断开的四次挥手流程 1. 客户端打算关闭连接此时会发送⼀个 TCP ⾸部 FIN 标志位被置为 1 的报⽂也即 FIN 报⽂之后客户端进⼊ FIN_WAIT_1 状态。 2. 服务端收到该报⽂后就向客户端发送 ACK 应答报⽂接着服务端进⼊ CLOSED_WAIT 状态。 3. 客户端收到服务端的 ACK 应答报⽂后之后进⼊ FIN_WAIT_2 状态。 4. 等待服务端处理完数据后也向客户端发送 FIN 报⽂之后服务端进⼊ LAST_ACK 状态。 5. 客户端收到服务端的 FIN 报⽂后回⼀个 ACK 应答报⽂之后进⼊ TIME_WAIT 状态之后的2MSL时间内都是time_wait状态。 6. 服务器收到了 ACK 应答报⽂后就进⼊了 CLOSED 状态⾄此服务端已经完成连接的关闭。 7. 客户端在经过 2MSL ⼀段时间后⾃动进⼊ CLOSED 状态⾄此客户端也完成连接的关闭。 你可以看到每个⽅向都需要⼀个 FIN 和⼀个 ACK因此通常被称为四次挥⼿。 而在日常的tcp连接断开中一般只有三次挥手这是因为如果第二次与第三次挥手之间没有数据发送那么被动断开连接的一方就可能会把第二次的 ACK 与 第三次的 FIN 合并为一次挥手。四次挥手就会变成三次挥手。 五、为何需要四次挥手而不是像建立连接一样三次挥手 如果第二次与第三次挥手之间没有数据发送那么被动断开连接的一方就可能会把第二次的 ACK 与 第三次的 FIN 合并为一次挥手。四次挥手就会变成三次挥手。 延时确认捎带确认 在建立连接的第三次握手的时候有可能带上数据在连接断开的四次挥手的第二次挥手即连接断开被动方在接收到FIN报文的时候会给断开主动方发送ACK报文这个报文不会立即发送出去而是等待200ms推荐值但是这个值不能高于500ms如果在这段时间有用户数据需要发送则一同随着这个ACK发送。 六、为何需要time_wait状态 主动发起关闭连接的⼀⽅才会有 TIME-WAIT 状态。TIME _WAIT状态也称为2MSL等待状态。 MSLMaximum Segment Lifetime是最大报文段生存时间它是任何报文段被丢弃前在网络内生存的最长时间RFC1122建议是2分钟但BSD传统实现采用了30秒。 当连接转移到TIME_WAIT状态时即连接主动关闭时定时器启动为两倍的MSL。定时器超时这时才能重新使用之前连接使用的插口源IP、端口和目的IP和端口的组合即插口也叫四元组。这也是为了避免一些意想不到的边界情况。 1. time_wait帮助连接正确关闭 断开连接的被动端要确保fin报文正确到达主动端需要主动端回复ack报文通知被动端fin报文已经成功到达否则被动端会继续发送fin报文如果没有time_wait主动端接收到fin报文回复ack报文然后进入closed状态如果ack报文丢失被动端超时重发fin报文得到的将是RST报文这不符合正确关闭的目标。 注rst 报文在客户端会显示报错信息Connection closed by foreign host。 2. time_wait防止两端在就连接未关闭完全期间在同一个插口建立新连接导致新旧数据错乱 如果没有time_wait,主动端的ack丢失同时被动端再次发送fin报文此时主动端在该插口的状态为关闭建立新的连接可能会导致迟到的fin报文使新连接困惑进而导致异常。 七、为何是等待2MSL 因为断开发起方主动端回复ack报文在网络上的过期时间是一个MSL被动端在 1MSL 内没有收到主动端发出的 ACK 确认报文就会再次向主动端发出 FIN 报文被动端重发fin报文在网络上的过期时间也是一个MSL如果2MSL时间内没有再次收到被动端发送来的fin报文则主动端认为被动端已经接收到ack报文关闭了连接则主动端也关闭连接。 在2MSL时间段内如果断开主动方主动端再次接收到被动端的fin报文说明服务器端由于各种原因没有接收到客户端发出的 ACK 确认报文。客户端再次向服务器端发出 ACK 确认报文计时器重置重新开始 2MSL 的计时。直到2MSL时间内未收到fin报文正确关闭连接。 假设被动端的fin报文始终没有收到ack而2MSL内主动端也没收到fin报文则被动端在重试了一定次数后也会断掉连接如果在重试过程中fin报文又到达主动端而主动端也过了2MSL则此时被动端将收到RST报文使被动端的连接关闭。 TCP定义 在2MSL时间内连接上的插口不能再继续建立连接平静时间 对于来自某个插口的较早连接的迟到报文段 2MSL等待可防止将它解释成使用相同插口 对的新连接的一部分。但这只有在处于 2 M S L等待连接中的主机处于正常工作状态时才有效。 如果使用处于2 M S L等待端口的主机出现故障它会在 M S L秒内重新启动并立即使用故 障前仍处于2 M S L的插口对来建立一个新的连接吗如果是这样在故障前从这个连接发出而迟到的报文段会被错误地当作属于重启后新连接的报文段。无论如何选择重启后新连接的初 始序号都会发生这种情况。 为了防止这种情况RFC 793指出T C P在重启动后的M S L秒内不能建立任何连接。这就称 为平静时间(quiet time)。 只有极少的实现版遵守这一原则因为大多数主机重启动的时间都比MSL秒要长。 八、定时器 1.建立连接定时器 --- Connection-establishment Timer 如果client在连接server的时候 在发送SYN的时候 会启动一个定时器(在 3.10 版本中首次超时时间是 1 s一些老版本中是 3 s。)如果SYN包丢失了 那么1秒以后会重新发送SYN包的(当然还会启动一个新的定时器 设置成2秒超时)当然也不会一直没完没了的发SYN包 在/proc/sys/net/ipv4/tcp_syn_retries 可以设置到底要重新发送几次SYN包。 2. 重传定时器---Retransmission Timer 对于TCP发送出去的数据包 需要等待对端发来ACK才能从内存里面删除 那么如果对端没有发送ACK怎么办 重传。 在发送数据的同时再设置一个超时时间RTO如果在这个超时时间内 没有收到ACK那么就重传刚才发送的数据。 3. FIN_WAIT_2定时器 在主动关闭的一端调用完close以后(发FIN包给对端 并且收到对端对FIN的ACK)则进入到FIN_WAIT_2状态 那么这个时候如果和对端之间的网络坏了或者对端程序有问题了一直不close 或者对端机器直接掉电了 本端不能一直傻等 所以就需要这个定时器. 如果在这个定时器超时的时候还是没收到对端的FIN包 那么不好意思 不等了 直接释放这个链接。 这个定时器的时间是多少呢可以从/proc/sys/net/ipv4/tcp_fin_timeout里面看到。 4. 2MSL定时器 在2MSL时间段内如果断开主动方主动端再次接收到被动端的fin报文说明服务器端由于各种原因没有接收到客户端发出的 ACK 确认报文。客户端再次向服务器端发出 ACK 确认报文计时器重置重新开始 2MSL 的计时。直到2MSL时间内未收到fin报文正确关闭连接。 5. 坚持定时器---Persist Timer 如果某一时刻一方发现自己的 socket read buffer 满了无法接受更多的TCP data此时就是在接下来的发送包中指定通告窗口的大小为0这样对方就不能接着发送TCP data了。如果socket read buffer有了空间可以重设通告窗口的大小在接下来的 TCP segment 中告知对方。可是万一这个 TCP segment 不附带任何data所以即使这个segment丢失也不会知晓ACKs are not acknowledged, only data is acknowledged。对方没有接受到便不知通告窗口的大小发生了变化也不会发送TCP data。这样双方便会一直僵持下去。 TCP协议采用这个机制避免这种问题TCP使用了零窗口探测技术Zero Window Probe缩写为ZWP也就是说接收端在接收窗口变为0后会通知发送端发送端发现接收端窗口大小变为0会启动一个定时器这个定时器就是Persist Timer在定时器超时后会发探测报文给接收方让接收方来ack他的Window尺寸一般这个值会设置成3次每次大约30-60秒不同的实现可能会不一样。如果3次过后还是0的话有的TCP实现就会发RST把链接断了。 6. 保活计时器---Keepalive Timer 如果客户端和服务端长时间没有数据交互那么需要保活定时器来判断是否对端还活着但是这个其实很不实用因为默认是2小时没有数据交互才探测时间实在是太长了。 具体实现方法TCP每隔一段时间tcp_keepalive_intvl会发送一个特殊的 Probe Segment强制对方回应如果没有在指定的时间内回应便会重传一直到重传次数达到 tcp_keepalive_probes 便认为对方已经crash了。 # TCP KeepAlive 机制保活时间、保活时间间隔和保活探测次数 net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_intvl net.ipv4.tcp_keepalve_probes 在 Linux 上可以通过如下文件查看 cat /proc/sys/net/ipv4/tcp_keepalive_time    cat /proc/sys/net/ipv4/tcp_keepalive_intvl    cat /proc/sys/net/ipv4/tcp_keepalive_probes 默认设置是 7200 秒2 小时、75 秒和 9 次探测。 如果使用 TCP 自身的 keep-Alive 机制在 Linux 系统中最少需要经过 2 小时 11 分 15 秒才可以发现一个“死亡”连接。 这个时间是怎么计算出来的呢 其实是通过 2 小时加上 75 秒乘以 9 的总和。 如果你真的要确认对端是否活着 那么应该在应用层自己实现心跳包而不是依赖于这个保活定时器。 实际上对很多对时延要求敏感的系统中这个时间间隔是不可接受的。 如果开启了 TCP 保活需要考虑以下⼏种情况 第⼀种对端程序是正常⼯作的。当 TCP 保活的探测报⽂发送给对端, 对端会正常响应这样 TCP 保活时间会被重置等待下⼀个 TCP 保活时间的到来。 第⼆种对端程序崩溃并重启。当 TCP 保活的探测报⽂发送给对端后对端是可以响应的但由于没有该连接的有效信息会产⽣⼀个 RST 报⽂这样很快就会发现 TCP 连接已经被᯿置。 第三种是对端程序崩溃或对端由于其他原因导致报⽂不可达。当 TCP 保活的探测报⽂发送给对端后⽯沉⼤海没有响应连续⼏次达到保活探测次数后TCP 会报告该 TCP 连接已经死亡。 7. 延迟应答定时器 --- delayed ACK timer 顾名思义 这个定时器是在延迟应答的时候使用的。 为什么要延迟应答呢 比如客户端发一段数据给服务端 服务端本应该立刻回ACK给客户端的 延迟应答是为了提高网络传输的效率 比如服务端收到客户端的数据后 不是立刻回ACK给客户端 而是等一段时间(一般最大200ms)这样如果服务端要是有数据需要发给客户端那么这个ACK就和服务端的数据一起发给客户端了 这样比立即回给客户端一个ACK节省了一个数据包。 参考 【tcp】TCP协议中的7种定时器 - 简书 TCP协议的超时详解 - 简书 九、非四次挥手连接损坏 1硬件奔溃主机损坏、断网等 2一方断电或宕机 1. 没有数据传输的时候主机奔溃 如果对方在开启了TCP keepalive 保活那么如果在机器停机期间如果对方发送了保活探测报文此时未奔溃端的探测报文会石沉大海不会被响应连续几次后达到保活探测次数后TCP 会报告该 TCP 连接已经死亡。 # TCP KeepAlive 机制保活时间、保活时间间隔和保活探测次数 net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_intvl net.ipv4.tcp_keepalve_probes 在 Linux 上可以通过如下文件查看 cat /proc/sys/net/ipv4/tcp_keepalive_time    cat /proc/sys/net/ipv4/tcp_keepalive_intvl    cat /proc/sys/net/ipv4/tcp_keepalive_probes 2. 有数据传输的时候主机奔溃 数据会超时重传数据报文的重传次数达到一定阈值后内核就会判定出该 TCP 有问题然后通过 Socket 接口告诉应用程序该 TCP 连接出问题了一般就是 ETIMEOUT 错误状态码。 那具体重传几次呢 在 Linux 系统中提供一个叫 tcp_retries2 配置项默认值是 15可以通过 Cat /proc/sys/net/ipv4/tcp_retries2 查看和设置。 这个内核参数是控制在 TCP 连接建立的情况下超时重传的最大次数。 不过 tcp_retries2 设置了 15 次并不代表 TCP 超时重传了 15 次才会通知应用程序终止该 TCP 连接内核还会基于「最大超时时间」来判定。 超时重传阶段每一轮的超时时间都是倍数增长的比如第一次触发超时重传是在 2s 后第二次则是在 4s 后第三次则是 8s 后以此类推。 但是这个超时时间不会无限增加下去会受到最大超时时间的限制超时时间的计算根据一下公式来计算 其中rto_base为200msTCP_RTO_MAX为120000ms。 机器恢复后因为异常导致本方TCP连接信息丢失重启完成后收到之前 TCP 连接的报文都会回复 RST 报文以断开连接。 十、解决连接断开过程中的问题 1. time_wait 堆积过多如何解决 危害 ① 内存资源的占用 ② 对端口资源的占用一个 TCP 连接至少消耗「发起连接方」的一个本地端口 要直到端口资源是有限的只有65536如果被time_wait占用过多占满了所有端口资源则会导致无法创建新连接影响正常的使用。 原因 可能是高并发情况下高并发让服务器在短时间范围内同时占用大量端口而业务处理传输数据的时间 远远小于 TIME_WAIT的2MSL超时时间导致很多time_wait对接影响其他正常的连接。 解决 ① 修改内核参数---设置time_wait的连接重用或快速回收 net.ipv4.tcp_tw_reuse 1 表示开启重用。允许将time_wait sockets重新用于新的TCP连接默认为0表示关闭 因为重用插口新连接不能处理旧数据TCP需要能判断到达的数据是否为旧数据实现原理是根据时间戳判断是否是延迟的数据如果是则丢弃。要实现这个功能就需要开启TCP对时间戳的支持这个内核参数是net.ipv4.tcp_timestamps1默认即为 1开启这个时间戳的字段是在 TCP 头部的「选项」⾥⽤于记录 TCP 发送⽅的当前时间戳和从对端接收到的最新时间戳。 由于引⼊了时间戳我们在前⾯提到的 2MSL 问题就不复存在了因为重复的数据包会因为时间戳过期被⾃然丢弃不会对新旧数据产生混淆。 net.ipv4.tcp_tw_recycle 1 表示开启TCP连接中time_wait sockets的快速回收默认为0表示关闭。 net.ipv4.tcp_max_tw_buckets 这个值默认为 18000当系统中处于 TIME_WAIT 的连接⼀旦超过这个值时系统就会将后⾯的 TIME_WAIT 连接状态重置。 这个⽅法过于暴⼒⽽且治标不治本带来的问题远⽐解决的问题多不推荐使⽤。 ② 客户端短链接改长连接 HTTP 请求的头部 connection 设置为 keep-alive 保持存活一段时间 长连接从根本上减少了关闭连接的次数减少了TIME_WAIT状态的产生数量在高并发的系统中非常有效现在的浏览器 一般都这么进行了 。 ③ 缩减 time_wait 时间 例如 设置为 1 MSL即 2 mins ④ 不主动关闭连接 不主动关闭socket就不会产生TIME_WAIT状态 ⑤ 程序中使⽤ SO_LINGER 我们可以通过设置 socket 选项来设置调⽤ close 关闭连接⾏为。 struct linger so_linger; so_linger.l_onoff 1; so_linger.l_linger 0; setsockopt(s, SOL_SOCKET, SO_LINGER, so_linger,sizeof(so_linger)); 如果 l_onoff 为⾮ 0 且 l_linger 值为 0那么调⽤ close 后会⽴该发送⼀个 RST 标志给对端该 TCP 连接将跳过四次挥⼿也就跳过了 TIME_WAIT 状态直接关闭。 但这为跨越 TIME_WAIT 状态提供了⼀个可能不过是⼀个⾮常危险的⾏为不值得提倡。 参考 服务器出现大量TIME_WAIT状态怎么解决_最大进程打开文件timewait-CSDN博客 2. close_wait 堆积过多如何解决 危害 使服务端的服务不可用。 原因 被服务端没有发送fin报文导致没有发送的原因一般都是程序因为被阻塞比如调用远程资源或者异常代码死循环让客户端超时关闭客户端发送关闭请求服务端回复ack但是由于各种原因导致服务端程序一直在运行阻塞无法发出fin报文。 解决 ① 修改内核参数 开启TCP保活检测 ② 资源的访问一定要设置访问超时时间 比如数据库访问超时第三方资源访问超时等。 ③ 代码要规范资源要牢记释放
http://www.dnsts.com.cn/news/141591.html

相关文章:

  • 做网站书苏州优化外包
  • 平板网站开发环境石家庄网站建设电话咨询
  • html5国内网站建设影视网站建设多少钱
  • 电商网站需求分析网站和后台建设
  • 为公司制作网站想做个网站都需要什么
  • 网站建设信(信科网络)招个网站建设维护
  • 电子商务网站建设与管理考卷医疗设计网站建设
  • 1年网站网页设计表单代码模板
  • 学ui需要什么基础呢谷歌排名优化
  • 长沙做php的网站建设制作汽车网站
  • 常熟有没有做阿里巴巴网站小城市做网站
  • 平台网站模板做网站前景怎么样
  • 网站怎么做页游男女一起做暖暖网站
  • 易企网站建设静态网页效果图
  • wordpress英文站源码网站制作2019趋势
  • 网站开发需求分析的内容汽车网址都有哪些
  • 郑州网站网络营销空间域名免费申请
  • 高校网站建设要点广州网站推广¥做下拉去118cr
  • 网站建站套餐网站推广方式案例
  • 网站赏析公司做网站的价格江阴
  • 微信网站制作平台鄂尔多斯教育网站入口
  • 台州市城市建设规划局网站视频直播网站开发运营步骤
  • 深圳做网站优化长春地图
  • 怎么做贝店式的网站微小店网站建设费用
  • 新开传奇网站发布站三端互通做网站销售这几天你学到了什么
  • 冲压加工瑞安有做网站吗网盘搜索 网站开发
  • 域名备案的网站名称龙岩天宫山电话
  • 南京做网站哪家好html是建网站导航栏怎么做
  • 旅游网站建设毕业设计家教补习中心网站建设
  • 网站域名需要备案吗jsp网站开发实例标题栏