TCP长连接的连接池、容量控制与心跳保活

这篇具有很好参考价值的文章主要介绍了TCP长连接的连接池、容量控制与心跳保活。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、长连接与短连接

TCP 本身并没有长短连接的区别,长短与否,完全取决于我们怎么用它。

  • 短连接:每次通信时,创建 Socket;一次通信结束,调用 socket.close()。这就是一般意义上的短连接,短连接的好处是管理起来比较简单,存在的连接都是可用的连接,不需要额外的控制手段。
  • 长连接:每次通信完毕后,不会关闭连接,这样就可以做到连接的复用。长连接的好处便是省去了创建连接的耗时。

想要简单,不追求高性能,使用短连接合适,这样我们就不需要操心连接状态的管理;想要追求性能,使用长连接,我们就需要担心各种问题:比如端对端连接的维护,连接的保活。

长连接还常常被用来做数据的推送,我们大多数时候对通信的认知还是 request/response 模型,但 TCP 双工通信的性质决定了它还可以被用来做双向通信,在长连接之下,可以很方便的实现 push 模型。

1、系统瓶颈

(1) 长连接服务主要功能是收发数据,保持在线,使用的系统资源主要包括:CPU,内存,网卡;

(2) 当连接活跃时,大量数据接收与发送,会用到更多的CPU和网卡,大量用户在线的时候,需要维持这些连接,保持会话,需要用到大量内存;

2、设计难点

(1) 设计单台物理连接数100W的处理能力;

(2) CPU资源充分利用,线程的分配;

(3) 内存合理分配,数据结构选择;

(4) 异步化,剥离业务逻辑和网络IO之间的相互依赖

三、重点解决

1、连接池

长连接意味着连接是复用的,每次请求完连接不关闭,下次请求继续使用该连接。

如果请求是串行的,那完全没有问题。但在并发场景下,所有请求都需要使用该连接,为了保证连接的状态正确,加锁不可避免,如果连接只有一个,就意味着所有请求都需要排队等待。

因此长连接通常意味着连接池的存在:连接池中将保留一定数量的连接不关闭,有请求时从池中取出可用的连接,请求结束将连接返回池中。

连接池经常遇到的一个问题就是池大小的控制:

  • 过大的连接池会带来资源的浪费,同时对服务端也会带来连接压力;
  • 过小的连接池在高并发场景下会限制并发性能。

通常的解决办法是延迟创建和设置空闲时间,延迟创建是指连接只在请求到来时才创建,空闲时间是指连接在一定时间内未被使用则将被主动关闭。

这样日常情况下连接池控制在较小的尺度,当并发请求量较大时会为新的请求创建新的连接,这些连接在请求完毕后返还连接池,其中的大部分会在闲置一定时间后被主动关闭,这样就做到了并发性能和IO资源之间较好的平衡。

1、线程管理

为了充分利用CPU,需要合理的进行线程规划。整个长连接服务使用事件驱动,包括:定时器事件和IO事件(listen fd,socket fd, pipe fd), 所以线程规划就是合理给这些事件分配线程。

(1) 大量连接socket需要平均分配到各个线程;

(2) 新的连接请求量比较大,listen线程压力大,需要考虑多线程处理;

TCP长连接的连接池、容量控制与心跳保活

 文章来源地址https://www.toymoban.com/news/detail-421954.html

主要涉及到3种fd的线程分配:

(1) 监听fd,包括监听逻辑层的连接请求和监听客户端的连接请求,并且支持启动多个监听端口,每个端口多个线程同时工作,整体会按顺序分配到线程;

(2) 连接fd,包括逻辑层的连接和客户端的连接,采用fd取余线程数,保证平均分配到所有线程;

(3) pipe fd,负责本线程管道中数据的读取,每个线程一个;

这个样是的每个线程的CPU使用率相当。

2、长连接保活

长连接的第二个问题就是连接保活的问题。虽然TCP协议并没有限制一个连接可以保持多久,理论上只要不关闭连接,连接就一直存在。

但事实上由于NAT等网络设备的存在,一个连接即使没有主动关闭,它也不会一直存活。

长连接保活由于TCP自身的断开确认机制,如果一条TCP连接中间网络断开,此时客户端和服务端物理网络断开导致客户端和服务端都没有办法通知对方连接断开,这样服务端和客户端就会存在死连接,造成假在线,占用的资源得不到有效的回收,长连接保活主要有下面两种方式:

(1) TCP keepalive,通过设置Keepalive参数,TCP协议栈会在超过一定时间没有数据交互的时候,发送Keepalive探测包,如果连接几次都没有收到回包,则断开连接,优点是TCP协议栈提供的功能,稳定占用带宽较少;

(2) 采用应用层心跳包的方式,客户端定时向服务端发送心跳包,服务端收到心跳包后立即进行回包,客户端如果没有检测到回包,则断开连接;服务端检测超时还没有收到心跳包,则断开连接,优点主要是应用层有感知,可控并且可以带些业务数据,比如时间戳;

3、容量控制

在TCP连接建立到通信的流程中,为了防止一些恶意连接与攻击,长连接服务做了容量控制,体现在下面几个方面:

(1) 客户端建立TCP连接到TLS握手,再到发出登录请求返回登录结果,整个过程是连贯的,如果客户端停在中间的某一步骤而不往下进行,就会一直占用服务端资源,针对这种情况,服务端增加了定时控制,在TCP 连接之后30s,如果没有收到登录请求,服务端会主动断开连接;

(2) 服务统计了正在进行TLS握手,正在进行登录校验的连接数量,分别设置上限,防止同时出现大量请求的时候,对后端服务的冲击;

(3) 增加了会话通信过程中Buffer内存使用量的上限,防止对端不接收数据,导致服务端数据积压;

(4) 增加了IP统计服务,建立连接后,会将新连接的IP等信息发送到IP统计服务,对整个服务的客户端IP 情况作统计监控,增加IP黑名单功能;

 

到了这里,关于TCP长连接的连接池、容量控制与心跳保活的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java.net.SocketTimeoutException: Read timed out,tcp连接心跳[TCP Keep-Alive],socket模拟http

     读超时con.setReadTimeout(3 * 60 * 60 * 1000);已设置为3小时。 日志 日志发现 等待了 3小时,抛出了异常 经过排查,是因为 后端防火墙,连接空闲20分钟,连接就会被丢弃。 解决办法是,使用 socket.setKeepAlive(true); 注意HttpURLConnection的connection.setRequestProperty(\\\"Connection\\\", \\\"keep-alive\\\");是不

    2024年02月07日
    浏览(26)
  • 没有accept还能建立tcp连接吗?

    首先什么是accept?以下是常见的接收网络请求的伪代码 以上代码中的accept通常是调用linux accept方法,以下是该方法的描述 It extracts the first connection request on the queue of pending connections for the listening socket, sockfd, creates a new connected socket, and returns a new file descriptor referring to that sock

    2024年02月16日
    浏览(27)
  • TCP 保活机制(keepalive)

    TCP保活机制是内核提供的一个心跳机制,当TCP连接异常时,能够通过保活机制释放TCP连接,确保资源不泄露。 SO_KEEPALIVE选项:SOL_SOCKET级别选项,用于开启和关闭TCP保活机制。 TCP_KEEPIDLE选项:IPPROTO_TCP级别选项,保活探测报文发送时间,简单理解就是多长时间没有收到TCP报文

    2024年02月13日
    浏览(32)
  • 网络协议--TCP的保活定时器

    许多TCP/IP的初学者会很惊奇地发现可以没有任何数据流通过一个空闲的TCP连接。也就是说,如果TCP连接的双方都没有向对方发送数据,则在两个TCP模块之间不交换任何信息。例如,没有可以在其他网络协议中发现的轮询。这意味着我们可以启动一个客户与服务器建立一个连接

    2024年02月06日
    浏览(32)
  • Linux内核源码剖析之TCP保活机制(KeepAlive)

    版本信息: Linux内核2.6.24(大部分centos、ubuntu应该都在3.1+。但是2.6的版本比较稳定,后续版本本质变化也不是很大) ipv4 协议 https://blog.csdn.net/ComplexMaze/article/details/124201088 本文使用案例如上地址,感谢案例的分享,本篇文章核心部分还是在Linux内核源码分析~ 为什么写下这

    2024年02月12日
    浏览(39)
  • SO_KEEPALIVE、TCP_KEEPIDLE、TCP_KEEPINTVL、保活包

    SO_KEEPALIVE 是一个套接字选项,用于设置是否启用 keepalive 机制。在这段代码中没有涉及到 SO_KEEPALIVE 选项的设置。 当 SO_KEEPALIVE 被设置为非零值时,表示启用 keepalive 机制。keepalive 是一种用于检测连接是否仍然有效的机制。通过定期发送一些特定的探测数据,可以检测到网络

    2024年02月14日
    浏览(29)
  • 计算机网络 运输层下 | TCP概述 可靠传输 流量控制 拥塞控制 连接管理

    TCP是面向连接的运输协议 每一条TCP只能有两个端点,点对点 提供可靠的全双工交付 面向字节流,但占用很多资源 不提供广播和多播服务 所以从某种意义来说 UDP是一种更加有效的工作方式 TCP面向流的概念 把字节写入发送缓冲,加上TCP首部构成TCP报文段,从接收缓存读取字

    2024年02月04日
    浏览(37)
  • 详解TCP、HTTP中的保活机制 | Keepalive和Keep-Alive

    目录 🌲 HTTP 的 Keep-Alive 🌲 TCP 的 Keepalive 🌲 最后总结 🌲 参考资料 TCP 的 Keepalive 和 HTTP 的 Keep-Alive 是一个东西吗? 这是个好问题,应该有不少人都会搞混,因为这两个东西看上去太像了,很容易误以为是同一个东西。 事实上, 这两个完全是两样不同东西 ,实现的层面也

    2024年02月12日
    浏览(30)
  • 为什么WebSocket需要前端心跳检测,有没有原生的检测机制?

    本文代码 github、gitee、npm 在web应用中,WebSocket是很常用的技术。通过浏览器的WebSocket构造函数就可以建立一个WebSocket连接。但当需要应用在具体项目中时,几乎都会进行心跳检测。 设置心跳检测,一是让通讯双方确认对方依旧活跃,二是浏览器端及时检测当前网络线路可用

    2024年02月03日
    浏览(47)
  • C# Tcplistener,Tcp服务端,Tcp心跳包服务器简易封装

    我最近有个需求要写Tcp服务端,我发现Tcp服务端的回调函数比较麻烦,简化Tcp的服务,我打算自己封装一个简单的Tcp服务端。 C# TCP应用编程三 异步TCP应用编程 C# Tcpclient Tcplistener 服务器接收多个客户端消息通讯 关于C#Socket断开重连问题 我最近有个Tcp服务端的项目,发现TcpL

    2024年01月19日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包