js轮询导致服务器瘫痪_演进:Tengine 从 Web 代理服务器 到 分布式推送服务器

7797b51e961d910c37f4e8919ab1867b.pngd96451aeb2921eecb69f2e485b014c2a.png

Tengine


Tengine 作为代理服务器,在集团有着广泛的应用基础,从 部署在 应用单机上的 Tengine ,到作为集群式部署的统一接入 Aserver ,可以说集团几乎所有应用机器均运行着 Tengine 。当然, Tengine 的不同部署形态,其作用也不经相同,这都得益于Tengine 作为优秀的反向代理服务器,有着 高性能、低延迟、高可用 等特性。 下图是常见的统一接入模型: 5893b3fd580df4c9dd27e94b8b7e818e.png

当前HTTP长连接业务现状


无论客户端发起的请求是 HTTP2 还是 HTTP 1.1,Tengine 作为反向代理服务器,和应用服务器之间均是短连接(除非 Tengine 配置 keepalive ),如下图所示: 2f2af39232fc5876914c5a621d32e392.png  Tengine 负责和客户端进行长连接的保活、和应用服务器使用具体负载均衡算法进行短连接调度。

当前HTTP的推送解决方案


通常推送的诉求,是需要定时的往端上发送数据, 轮询 端上 定时发送请求来轮询获取业务数据。 这是最简单且最容易想到的手段,但往往也是在实际项目中最不可能使用的方案。因为其缺点非常明显:
1、较短间隔的轮询请求会导致 Server 端无端的处理无用的 QPS ,且 QPS 与端的数量成线性正比
2、较长间隔的轮询请求,其推送时效性无法保证

应用服务处理

即, Tengine 作为反向代理服务器只完成基本的转发能力,业务 Hold 住 HTTP 的请求,并且在必要时,对其进行 response 。 e7b5435e1efb49a77de35f9527c52548.png 缺点很明显,应用需要自己维护该长连接的生命周期,而往往推送场景的使用者均是超大规模的终端设备,超大规模的长连接很明显会消耗大量应用机器资源。

HTTP2 推送(Server Push)

实际上 HTTP2 的推送功能指的是单个 request 有多个 response ,与我们长连接通道持续传输数据的需求不匹配。
这里贴上 RFC 对 Server Push 功能的介绍,在这里就不再展开了。
HTTP/2 allows a server to pre-emptively send (or "push") responses   (along with corresponding "promised" requests) to a client in   association with a previous client-initiated request.  This can be   useful when the server knows the client will need to have those   responses available in order to fully process the response to the   original request.
Tengine 单机推送 目前,主流开源 Nginx 模块有支持单机推送功能 。
推送流程
e01f0b7d1bf7912e48c4e326380572cb.png 实际上和 MQTT 的 SUB PUB 模式非常相似,只是用 HTTP 来实现而已,下面是具体流程如下: 1、A 发起请求,Tengine 劫持请求 Hold 住, Tengine 对其生产一个对应的 KeyA 。
2、B 若期望推送数据到 A ,可用 KeyA 作为参数(或者 Header ),发送 POST 数据到指定Tengine。
3、 Tengine 将收到的 B 的 POST 的数据,获取到 KeyA 对应的连接,即可返回给 A 。 缺点 1、 B 需要感知 A 的存在 B 即当A的请求到达 Tengine 时, Tengine 需要旁路发送到 B ,即需要 告知 B ,A 的存在,并且 B 需要记录 A 对应的 KeyA 。 解决方案:可以使用 Tengine 的 auth_request 功能,当然等价的也可以使用 Lua 的ngx.location.capture 方法。 2、Tengine 若是集群化部署,B 需要中心化存储 B 通常是非单体应用,即由多个微服务组成,无论在哪个环节,当 B 需要推送消息到A时,显然需要知道 A 在 Tengine 集群中的哪台机器,故B应用中,至少某个微服务需要由中心化存储(例如 redis、memcache )来决定将请求发送至哪台 Tengine 。 712afa2baee665ff0a98b595e72d811a.png

Tengine实现方案


一、Tengine 自带 中心 化存储

Tengine 对 每个 TCP 连接生成一个 key(也可以使用请求 Header 等作为 Key ),在中心化存储中保存 key 和对应机器ip的映射信息。应用只需要往Tengine集群的任意一台机器推送数据,由 Tengine 来做分布式路由。下图从推送角度描述了 Tengine 如何工作。 62a56132813a05e61839aa1b096aeb24.png 1、应用往 Tengine 集群随机一台机器推送,推送是携带对应的的 Key 以表示自己期望推送至哪个连接
2、Sc 收到 推送消息,在 Tair 中查找对应请求由哪台 Tengine 机器维护,例如查找到该推送目的连接在 Sb 。
3、Sc 转发到 Sb。
4、Sb 收到后,找到对应的客户端连接,将数据推送至客户端。 应用可以是用 vipserver 随机查找 Tengine 机器, Tengine 也可以申请一个 vip/slb ,供业务访问,依靠 vip/slb 的负载均衡能力,随机访问 Tengine 。

二、支持流式传输

通常,一个长连接希望能够接受多个推送消息,而不是一个推送消息结束后再次新建, Tengine 依托其丰富的 HTTP 处理能力,使用  multipart/form-data ,是的推送数据拥有明确的 boundary ,多次推送数据都能有明确的分界线,客户端只需单个连接,就能获得多次推送数据。

三、多协议支持

Tengine 本身支持多种协议, 无论客户端发起的是 HTTP 还是HTTP2,均能继承上述推送功能。 四、高性能 Tengine 本身作为代理服务器,转发性能是业界的标杆,我们在Tengine转发流程加入了 中心化存储能力使得 Tengine 有了分布式路由的功能。 作者信息:

陈嘉园,花名上虚,中间件技术-AliMesh&Tengine团队 高级研发工程师,负责Tengine&Ingress相关开发工作,目前主要关注云原生、Ingress等技术方向。

本文缩略图:icon by 黑夜太难熬

推荐阅读:

QPS 相比 Nginx 提升60%,阿里 Tengine 负载均衡算法揭秘

3 月全球 Web 服务器调查报告:Nginx 域名份额首超 Apache

看完这篇还不了解 Nginx,那我就哭了!

50248193a888b3018f0f50871ebc10ec.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值