谁说 PHP 不能搞长连接:UDS 与 local-proxy(9/31)

脚本语言不常驻进程,就用 UDS + local-proxy 把短连接变成长连接

即时通讯架构实践第 9 课封面:即时通讯09:谁说 PHP 不能搞长连接:UDS 与 local-proxy

脚本语言不常驻进程,就用 UDS + local-proxy 把短连接变成长连接

《即时通讯架构核心技术》第 9 篇:谁说 PHP 不能搞长连接。

据说,php是世界上最好的语言?

phper说,不服可以点赞来辩。

如果站点架构满足以下几点:

  • 使用php这类脚本语言开发
  • 需要连接后端服务,例如RPC服务、memcache、redis等
  • 流量非常大

此时,通过短连接访问RPC服务、mc、redis会出现什么问题呢?

典型的 web 架构

典型的web架构如上:

(1) 最前端是APP或者web页面;

(2) 服务器上层是web-server进行接入;

(3) php调用后端,完成业务逻辑,拼接页面;

(4) 最后端是服务、缓存、数据库;

php作为脚本语言,不像C++/Java那样进程常驻,所以它连接后端的服务都是使用短连接。

有朋友说,可以用C写扩展?

php 与 memcache 之间的短连接通信过程

上图是一种典型场景,站点php部署在机器A上,缓存memcache部署在机器B上,之间通过短连接通信,过程为:

(1) php建立tcp短连接;

(2) 按照memcache协议发送数据;

(3) 接收memcache返回的数据;

(4) php关闭tcp短连接;

在流量小时,上述过程没有任何问题,当网站流量非常大的情况下,短连接可能会成为性能瓶颈,有什么优化办法吗?

建立连接,销毁连接很耗时。

什么是 UNIX Domain Socket?

UNIX Domain Socket是一种IPC机制,它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。

IPC, Inter-Process Communication, 进程间通信。

它可以用于同一台主机上两个没有亲缘关系的进程,并且是全双工的,提供可靠消息传递(消息不丢失、不重复、不错乱)的IPC机制。

亲缘关系是指,父子进程或者兄弟进程这种“特殊的”进程关系。

可以看到,UNIX Domain Socket的效率会远高于tcp短连接,但它只能用于同一台主机间的进程通讯,而php应用和后端服务往往是部署在不同的机器上的,此时能否利用它来进行优化呢?

优化后的架构:local-proxy

优化后的简易架构图如上:

(1) 在php应用服务器上部署一个local-proxy;

(2) php与local-proxy之间使用UNIX Domain Socket来通讯;

(3) local-proxy与后端服务进行TCP长连接通讯;

这样就大大提升了通讯效率,免除了每次请求都要进行的建立与关闭tcp短连接的开销。

实现 local-proxy 有什么要注意的?

local-proxy非常注重通用性设计,因为php有RPC、mc、redis等多种后端:

协议设计:local-proxy本身没有任何业务逻辑,只负责请求转发,上游发送过来redis协议,透传给后端的redis

这样,上游客户端不需要进行任何代码修改。

通讯方式:如上文所述,local-proxy与上游使用UNIX Domain Socket进行通讯,与下游使用tcp长连接进行通信

高效框架:这种方案是为了解决tcp短连接的效率损耗,这样对local-proxy的效率要求就非常高,可以选用成熟高效的网络框架和tcp长连接连接池技术来实现

例如libevent。

请求映射:需要将上游发过来的请求与发往下游的请求一一映射起来,这样才能正确的对应上请求包与响应包

思考过程比结论重要,希望对你有启示。

检验一下

检索练习 · 短连接的瓶颈
大流量下,php 用短连接访问 RPC、memcache、redis,瓶颈在哪里?

检索练习 · UNIX Domain Socket
关于 UNIX Domain Socket,哪项描述正确?

检索练习 · local-proxy 架构
优化后的通信链路是怎样的?

检索练习 · 通用性设计
local-proxy 为什么不解析 Redis 等协议、只做透传?

php 这边靠 local-proxy 拼出了长连接,那浏览器网页端收消息又有哪些玩法?——第 10 篇,网页端收消息的 3 种方式。

知其然,知其所以然。思路比结论更重要。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

京ICP备2025137728号-3