专栏首页架构师长连接和短连接详细解析

长连接和短连接详细解析

一个完整的软件系统大多数情况下是由多个进程共同协作进行的,哪怕它们在同一台服务器上。所以,进程之间如何进行高效的通信至关重要。

单个应用程序 + 单个数据库这套基础开发套餐我相信每个人都经历过,甚至在初期它们还有可能部署在同一台服务器上。既然应用程序和数据库分属于两个不同的进程,所以这个问题本质上还是两个进程之间的通信问题。

两个进程之间如果要通信,很显然必须要建立一个连接,通过它来相互传输数据。原则上,如果两个进程在同一台服务器上,有很多种方式可以进行相互通信。不过在分布式系统中,不同的进程很多时候被部署在不同的服务器上。所以我们这次只聊基于 TCP/IP 的通信方式,因为对大家来说这是最普遍会用到的方式,不管是应用程序间的远程调用(RPC)还是应用程序与数据库间的调用(DAL),皆是如此。

通过套接字(socket)建立连接

socket 与 TCP/IP 之间是唇齿相依般的关系,联系紧密,先来看下维基百科对 socket 的定义。

socket 是计算机网络中用于在节点内发送或接收数据的内部端点。具体来说,它是网络软件 (协议栈) 中这个端点的一种表示,包含通信协议、目标地址、状态等,是系统资源的一种形式。

它在网络中所处的位置大致就是下面的黑色部分,应用层与传输层之间。

其中的传输层就是 TCP/IP 所在的地方,而你平时通过代码编写的应用程序大多属于应用层范畴,socket 在这里起到就是连接应用层与传输层的作用。

socket 的诞生是为了应用程序能够更方便的将数据经由传输层来传输,所以它本质上就是对 TCP/IP 的运用进行了一层封装,然后应用程序直接调用 socket API 即可进行通信。那么它是如何工作的呢?它分为 2 个部分,服务端需要建立 socket 来监听指定的地址,然后等待客户端来连接。而客户端则需要建立 socket 并与服务端的 socket 地址进行连接。

这图展示的就是建立 TCP/IP 连接的过程,经典的叫法为“三次握手”的过程。顾名思义,这个过程中来回产生了三次网络通信。

接下来的数据传输过程就简单很多,发送数据就是客户端往服务端通信,服务端处理完之后的数据返回则相反。

值得注意的是,传输的过程涉及到数据 Copy,不过这些 Copy 是必不可少的。其中的发送缓冲区和接收缓冲区就是套接字缓存 (socket buffer)。

连接使用完之后需要关闭,不过 TCP/IP 连接关闭过程比创建更复杂一些,次数多了一次,这就是经典的“四次握手”过程。

简单总结一下 socket。socket 是进程间数据传输的媒介,为了保证连接的可靠,你需要特别注意建立连接和关闭连接的过程。为了确保准确、完整的数据传输,客户端和服务端来回进行了多次网络通信才得以完成连接的创建和关闭,这同时也是你在运用一个连接时所花费的额外成本。

基于 socket 我们可以选择建立长连接或者短连接,在实际运用中两者都有可能被用到。

长连接和短连接的区别

先带你来认识一下它俩的区别。

长连接意味着进行一次数据传输后,不关闭连接,长期保持连通状态。如果两个应用程序之间有新的数据需要传输,则直接复用这个连接,无需再建立一个新的连接。就像下图这样。

它的优势是在多次通信中可以省去连接建立和关闭连接的开销,并且从总体上来看,进行多次数据传输的总耗时更少。缺点是需要花费额外的精力来保持这个连接一直是可用的,因为网络抖动、服务器故障等都会导致这个连接不可用,甚至是由于防火墙的原因。所以,一般我们会通过下面这几种方式来做“保活”工作,确保连接在被使用的时候是可用状态:

  1. 利用 TCP 自身的保活(Keepalive)机制来实现,保活机制会定时发送探测报文来识别对方是否可达。一般的默认定时间隔是 2 小时,你可以根据自己的需要在操作系统层面去调整这个间隔,不管是 Linux 还是 Windows 系统。
  2. 上层应用主动的定时发送一个小数据包作为“心跳”,探测是否能成功送达到另外一端。 保活功能大多数情况下用于服务端探测客户端的场景,一旦识别客户端不可达,则断开连接,缓解服务端压力。

提前多说一句,如果在做了高可用的分布式系统场景中运用长连接会更麻烦一些。因为高可用必然包含自动故障转移、故障隔离等机制。这恰恰导致了一旦发生故障,客户端需要及时发现哪些连接已处于不可用状态,并进行相应的重连,包括重新做负载均衡等工作。

了解完了长连接,那么短连接就很容易理解了。短连接意味着每一次的数据传输都需要建立一个新的连接,用完再马上关闭它。下次再用的时候重新建立一个新的连接,如此反复。

它的优势是由于每次使用的连接都是新建的,所以基本上只要能够建立连接,数据就大概率能送达到对方。并且哪怕这次传输出现异常也不用担心影响后续新的数据传输,因为届时又是一个新的连接。缺点是每个连接都需要经过三次握手和四次握手的过程,耗时大大增加。

另外,短连接还有一个致命的缺点。我们回到前面提到的维基百科对 socket 的定义,其中说到socket 包含通信协议、目标地址、状态等。实际当你在基于 socket 进行开发的时候,这些包含的具体资源主要就是这 5 个:源 IP、源端口、目的 IP、目的端口、协议,有个专业的叫法称之为“五元组”。在一台计算机上只要这五元组的值不重复,那么连接就可以被建立。然而一台计算机最多只能开启 65535 个端口,如果现在两个进程之间需要通信,作为服务端的 IP 和端口必然是固定的,因此单个客户端理论上最多只能与服务端同时建立 65535 个 socket 连接。如果除去操作系统和其它进程所占用的端口,实际还会更少。所以,一旦使用不当,在很短的时间内建立了大量连接,端口很容易被占用完。这不但会导致自身无法正常工作,还会影响到同一台计算机上的其它进程。

我猜你在项目中大多数情况使用的是短连接的方式,因为这对我们编程来说可以少考虑很多问题,潜在的这些缺点可能是你没有遇到或者意识到而已。存在必有其价值,接下去我们根据实际的案例让你清楚知道如何来选择它们。

长连接和短连接的选择

我想你肯定见过一些监控或者实时报价类系统,比如股票软件,它需要在几秒之内刷新最新的价格。像这种场景中同时包含了需要运用长连接的三个主要因素:高频、服务端主动推送和有状态。

  • 高频的原因我想你根据前面的内容也明白了,因为频次越高的话,使用短连接带来的建立连接和关闭连接的总开销越大。
  • 而服务端主动推送也需要长连接的原因是,由于服务端往往是“中心化”的,一般都是 1 个服务端为多个客户端提供服务。所以,如果使用短连接的方式,那么在客户端未主动连接到服务端的情况下,服务端并不知道需要往哪些客户端去推送数据,这是原因之一。所以此时,长连接成为了一个很好的选择。另外一个原因是,哪怕客户端通过定时的短连接轮询方式进行主动连接,除了增加了额外的建立连接和关闭连接的开销外,还可能遇到通信完成后结果数据并未发生变化,做了无用功。
  • 成熟股票软件的服务端,为了支撑更多的用户以及做高可用,必然部署了多台。但是这个业务场景,用户无法容忍由于多个服务端之间数据同步的误差导致他在客户端看到的价格刷新产生“回退”现象。所以,只能尽量保持一直连接在同一台服务器上,才能避免这个情况。这种场景被称之为“有状态”,也可以理解为是“串行”的,因为多次请求的前后需要保持“连续性”。

短连接则更适用于诸如阅读类软件的场景中,例如,很多时候用户点开一篇文章后需要花一些时间进行阅读,这个时间有长有短,并且直到用户下一次操作之前都没有数据传输发生。这个场景中包含了运用短连接的两个主要因素:低频、无状态。

  • 因为低频,所以更能容忍建立连接和关闭连接的开销。
  • 用户的下一次点击往往跳转到了其它文章,并且新打开的与当前文章并不需要具有“连续性”,所以这种场景我们称之为“无状态”的。另外,理论上同一时刻打开几篇文章也不会存在什么不妥。

通过这两个案例我们可以总结出一个决定何时运用长连接和短连接的最佳实践。

长连接适用于:两个进程之间需要高频通信并且具备服务端主动推送或者有状态(需串行)两者之一的场景,否则并不是必选项。

短连接适用于:两个进程之间通信频率较低,或者属于无状态(可并行)的场景,否则并不是必选项。

其它情况就根据所需的侧重点来,比如侧重性能就长连接,侧重编码的便捷性就选择短连接。

总结

至此,相信你应该清楚了长连接和短连接在跨进程通信中该如何选择,而且还对通过 socket 建立 TCP 连接有了一定的认识。你在实际的工作中可能遇到的场景千奇百怪,只需要保持先识别所处场景的特点,再基于这些特点来作出选择的习惯,必然至少是个不错的决策。

不过有时候我们可能需要一个中庸的方案来作为默认选择,因为很多场景中的请求并不是平稳的,甚至波动会较大,而且可能同时存在有状态和无状态的场景,此时如果单方面的选择长连接或者短连接都会产生较多的资源浪费。那么我们可以通过增加一些复杂度来实现一个能够综合长连接和短连接各自优点的方案:建立多个长连接,每次数据传输的时候独占使用,用完之后放回,再给后续使用。这种方案被称之为“连接池”。例如, 很多的数据库访问框架都内置了连接池机制,因为作为底层框架的它不知道会被使用到何种场景的系统中,所以提供了这个选项。

连接池的运作流程大致如下图。除了上面所说的,独占使用,用完放回之外,一般都会在应用程序启动时预先建立好指定数据量的连接,以更好应对冷启动后请求数快速上升带来的资源竞争问题,这个数量一般称之为最小连接数。另外,如果新的请求进来时,所有已建立的连接都在使用中,但是连接数的上限未达到指定数量,可以再建立新的长连接来使用,用完依旧放回到空闲池,相当于把连接池扩大了,这个上限数量一般称之为最大连接数。

不知道大家对长连接和短连接的运用有什么样的经验和认识呢?欢迎在下方评论区留言,我们一起讨论。

文章分享自微信公众号:
架构师修行之路

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!

如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • 长连接和短连接分析

    1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接 时...

    猿人谷
  • HTTP 长连接和短连接

    1. HTTP协议与TCP/IP协议的关系 HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用I...

    joshua317
  • [PHP] time_wait与长连接短连接

    服务端上查看tcp连接的建立情况,直接使用netstat命令来统计,看到了很多的time_wait状态的连接.这些状态是tcp连接中主动关闭的一方会出现的状态....

    陶士涵
  • 新浪长连接转为短连接的API与详解

    新浪提供了长链接转为短链接的API,可以把长链接转为 t.cn/xxx 这种格式的短链接。

    码农程序
  • 分析 HTTP,TCP 的长连接和短连接以及 sock

    HTTP 的长连接和短连接本质上是 TCP 长连接和短连接。HTTP 属于应用层协议,在传输层使用 TCP 协议,在网络层使用 IP 协议。IP 协议主要解决网...

    杰哥的IT之旅
  • 长连接和短连接区别和优缺点

    优点:面向无连接,操作简单,要求系统资源较少,速度快,由于不需要连接,可进行广播发送

    测试小兵
  • 什么是长连接、短连接?

    在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类...

    Vincent-yuan
  • MySQL 线程池&连接池&长连接&短连接

    lyb-geek
  • (八)深入浅出TCPIP之TCP长连接与短连接详解

    刚接触TCP/IP通信设计的人根据范例可以很快编出一个通信程序,据此一些人可能会认为TCP/IP编程很简单。其实不然,TCP/IP编程具有较为丰富的内容。其编程...

    用户3479834
  • TCP/IP,http,RPC、SOA、长连接短连接

    因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。

    IT技术小咖
  • HTTP的短连接、长连接管理

    打开和保持连接影响网站和 Web 应用程序性能。在 HTTP/1.x 里有多种模型:短连接, 长连接, 和 HTTP 流水线。

    JavaEdge
  • MySQL性能优化必知:长连接、短连接、连接池

    当数据库服务器和客户端位于不同的主机时,就需要建立网络连接来进行通信。客户端必须使用数据库连接来发送命令和接收应答、数据。通过提供给客户端数据库的驱动指定连接字...

    码农架构
  • Linux硬连接和软连接详解

    Lnux也有类似于windows下的快捷方式,这种快捷方式在linux下称作硬连接(hard link)或软连接(symbolic link,又称作符号链接)。

    我是李超人
  • 详解SQL Server连接(内连接、外连接、交叉连接)

    在查询多个表时,我们经常会用“连接查询”。连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志。

    程序猿小亮
  • 基础拾遗--【转】什么是长连接、短连接?

    什么是长连接,什么是短连接? 贴个经典的,看完了就应该没啥问题了 : TCP/IP通信程序设计的丰富多样性 刚接触TCP/IP通信设计的人根据范例可...

    小小科
  • 长连接短连接的区别以及使用场景

    长连接:是指在一个TCP连接上可以发送多个数据包,但是如果没有数据包发送时,也要双方发检测包以维持这个链连接

    名字是乱打的
  • 基础巩固——长连接 、短连接、心跳机制与断线重连

    本文将从长连接和短连接的概念切入,再到长连接与短连接的区别,以及应用场景,引出心跳机制和断线重连,给出代码实现。

    Janti
  • HTTP长连接和Websocket

    在HTTP1.0中使用的是非持久连接,每个TCP连接最多允许传输一个对象。首先浏览器收到服务器的响应以后,会获得HTML文件,从而解析HTML文件中包含的其他U...

    zy010101

扫码关注云+社区

领取腾讯云代金券