全栈工程师修炼指南
熊燚(四火)
Oracle首席软件工程师
立即订阅
2286 人已学习
课程目录
已更新 43 讲 / 共 40 讲
0/4登录后,你可以任选4讲全文学习。
课前必读 (3讲)
开篇词 | 从成长角度看,为什么你应该成为全栈工程师?
免费
学习路径 | 怎样成为一名优秀的全栈工程师?
导读 | 如何学习这个专栏?
第一章 网络协议和 Web 接口 (6讲)
01 | 网络互联的昨天、今天和明天:HTTP 协议的演化
02 | 为HTTP穿上盔甲:HTTPS
03 | 换个角度解决问题:服务端推送技术
04 | 工整与自由的风格之争:SOAP和REST
05 | 权衡的艺术:漫谈Web API的设计
06 | 特别放送:北美大厂如何招聘全栈工程师?
第二章 欢迎来到 MVC 的世界 (7讲)
07 | 解耦是永恒的主题:MVC框架的发展
08 | MVC架构解析:模型(Model)篇
09 | MVC架构解析:视图(View)篇
10 | MVC架构解析:控制器(Controller)篇
11 | 剑走偏锋:面向切面编程
12 | 唯有套路得人心:谈谈Java EE的那些模式
13 | 特别放送:选择比努力更重要
第三章 从后端到前端 (7讲)
14 | 别有洞天:从后端到前端
15 | 重剑无锋,大巧不工:JavaScript面向对象
16 | 百花齐放,百家争鸣:前端MVC框架
17 | 不一样的体验:交互设计和页面布局
18 | 千言万语不及一幅画:谈谈数据可视化
19 | 打开潘多拉盒子:JavaScript异步编程
20 | 特别放送:全栈团队的角色构成
第四章 数据持久化 (7讲)
21 | 赫赫有名的双刃剑:缓存(上)
22 | 赫赫有名的双刃剑:缓存(下)
23 | 知其然,知其所以然:数据的持久化和一致性
24 | 尺有所短,寸有所长:CAP和数据存储技术选择
25 | 设计数据持久层(上):理论分析
26 | 设计数据持久层(下):案例介绍
27 | 特别放送:聊一聊代码审查
第五章 寻找最佳实践 (6讲)
28 | Ops三部曲之一:配置管理
29 | Ops三部曲之二:集群部署
30 | Ops三部曲之三:测试和发布
31 | 防人之心不可无:网站安全问题窥视
32 | 和搜索引擎的对话:SEO的原理和基础
33 | 特别放送:聊一聊程序员学英语
第六章 专题 (7讲)
34 | 网站性能优化(上)
35 | 网站性能优化(下)
36 | 全栈开发中的算法(上)
37 | 全栈开发中的算法(下)
38 | 分页的那些事儿
39 | XML、JSON、YAML比较
40 | 全栈衍化:让全栈意味着更多
全栈工程师修炼指南
登录|注册

03 | 换个角度解决问题:服务端推送技术

四火 2019-09-16
你好,我是四火。
今天我们继续和 HTTP“过不去”。在上一讲,我们讲到了 HTTP 在安全传输方面的局限,并介绍了怎样使用经过 TLS 加密的 HTTPS 连接来解决这样的弊端。
今天,我要给你讲讲传统 HTTP 的另一个在交互模式上的局限,就是只能由客户端主动发起消息传递,而服务端只能被动响应消息的局限,并介绍它的解决办法。

Pull 模型的问题

让我们来思考这样一个场景,假设你设计了一款网页版的即时聊天工具,现在你使用浏览器打开了聊天页面,正在和朋友愉快地聊天。这时有朋友给你发送了一条消息,可是由于 HTTP 本身机制的限制,服务端无法主动推送消息,告知浏览器上的聊天页面“你有一条消息”,进而影响到了消息的即时送达。那么,这个问题怎么解决?
你可能会立即想到轮询(Poll),比如浏览器每隔十秒钟去问一下服务端是不是有新消息不就完了嘛。这看起来是个好思路,但明显存在这样两个问题:
消息还是不够即时。换言之,假如正好在某次询问之后服务器收到了消息,那么这条消息的获取延迟可能达到至少十秒。
大量的请求 - 响应,带宽和服务器资源浪费。如果你开着聊天工具页面一个小时,除了这一条消息,却没有进一步的聊天行为,于是按照每十秒发送一次请求计算,一共发起了 360 次请求,而其中居然只有 1 次返回了聊天消息是有实际意义的。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《全栈工程师修炼指南》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(15)

  • 許敲敲
    谢谢老师给这么多资料
    2019-09-16
    1
  • 💢 星星💢
    老师我看不懂英文资料,是不是多看看就会有感觉了?有没有啥秘诀。。。

    作者回复: 最佳实践那一章的最后一篇特别放送,我会讲一讲程序员怎么学英语。可以期待一下。

    2019-11-15
  • liansng

    Location:
    wss://echo.websocket.org
    Message:
    Rock it with HTML5 WebSocket

    这个的操作方式我没太看懂,老师可以帮忙解释一下吗?

    作者回复: 这是你打开 https://www.websocket.org/echo.html 的时候,它已经默认帮你填好的内容

    2019-10-22
  • vip3
    老师您好,请教个问题。

    我想让pad和PC之上的两个应用全双工通信,想到两种办法。

    一是和服务器建立websocket连接,让其作为通讯的中转,但是这种方法网络不好的情况下容易挂掉;

    为了解决办法一的问题,想了第二个方法,在PC上启动一个websocket server,让pad应用与PC应用内启的这个server建立连接,实现局域网内部全双工通信,但这有个限制,必须要求pad和PC连到同一局域网下。但是因为PC可能连接着网线,也可能在用无线网络,且无线网络不止一个,我检测不出来PC和pad连接的是否是同一子网。

    所以想问问老师,有没有什么办法能解决上述两个办法的问题?
    2019-10-16
  • angry noob
    老师你好,我有个疑问,是关于comet: 客户端必须在服务端结束当次传输后才能向服务端发送消息,服务端会采用分块传输,也就是"我说完你再说",客户端这时候有新的请求就只能等着才能发送?要是长时间不结束客户端的请求就没法发送了嘛?

    作者回复: 好问题,是这样的,HTTP/1.1 Comet 的一个局限性就在这里,也就是说,传输是单工的,从协议的角度来说,服务端的响应分多次返回,因此这个过程中,返回并没有传输完,那么对于该次 HTTP 连接来说,客户端也就无法发送新的请求。

    当然,除了升级到 HTTP/2 或者采用其他技术以外,对于这个问题本身,还是有一些改进办法的,你可以思考一下。:)

    2019-09-29
  • CC
    思考题 1:

    工作中主要用到 Pull,还没有使用到 Push。



    思考题 2:

    Push 的优势还有:
    - 客户端可以提前 cache push 过来的内容,在其他页面上使用。
    - 服务端可以决定 push 的优先级,把影响 performance 的重要资源优先 push。
    - 客户端可以根据自己的情况,选择是否接受 push,或者限制数量。


    Pull 的 stateless 带来的优势强大,其他的优势还没有查到。

    作者回复: 👍,你也可以看看其他回答

    2019-09-25
  • pyhhou
    思考题:
    1. 在实际的项目中用 pull 的例子比较多,没怎么接触过 push,感觉上 push 的话是不是会相对来说复杂些,因为要维护不同 client 的状态;相对来说 pull 的话,只用基于 request 参数做相应的 response 即可

    2. 这里我在想,pull 的无状态优势只是对于服务器端来说的,如果在客户端,对于 pull 来说,是不是需要保存服务器的状态?另外,由于 push 是有状态的,那么状态在服务器上的存储会不会成为一个难题?从分析来看,pull 的缺点是 push 的优点,push 的缺点又是 pull 的优点,我想到了前一章我们讲过对称加密和非对称加密,对称加密高效但是 key 不易分享,非对称加密 key 易分享但是不高效,因此 HTTPS 将他们两个做了个结合。这里或许我们也可以将 push 和 pull 结合起来使用,比如,消息更新的时候,服务器端使用 push 通知客户端更新资源,然后客户端使用 pull 获取资源,这样会不会比单一使用 pull 或 push 更好?

    很赞同老师说的,学习就是需要去用自己学过的东西对比理解和分析新学的东西,深度理解他们的本质思想,以及区别和共同点,这样才能形成知识体系,这会对新知识的掌握更快,对技术也会有更高维度的认识

    关于学习全栈专栏的认识:
    学完了这几章,感觉自己知道的东西还是太少,老师推荐的文章都很好,也很有深度,但是有些文章真的没有时间去仔细推敲,我在想,先把整个专栏跟下来,对全栈知识有个宏观的认识,然后在仔细阅读这些著作,老师你觉得这样是否可行呢?

    收获很多,谢谢老师

    作者回复: 感谢回复。

    1. 正确。

    2. 不一定。而且即便客户端需要保持服务端状态,也比服务端保持客户端状态,要简单得多(数量上是 1 和 N 的关系,在横向扩展的时候,这个 N 就可能成为瓶颈)

    你说的这个 push-pull 结合的方式很好,其实它是一种非常常见的实现方式,你可以想想互联网有哪些应用。:)

    2019-09-24
    1
  • jxs1211
    请问今天的课堂实例如果要自己用代码来实现,前后段代码是否有相关的实例代码可以做参考?

    作者回复: 你可以自己尝试实现一个最简单的 Comet:

    客户端,你甚至都不用写 JavaScript,一个普通的 get 请求即可——浏览器直接访问某一个服务端暴露的接口(URL)。

    服务端则是往响应中写数据,使用按块传输,返回类型设置为 plain/text,随便写一点数据并 flush,然后 sleep 10 秒,再写一点并 flush,再 sleep 10 秒,如是多次,这样可以模拟多次返回。

    这样,你会看到浏览器一直在加载,页面十秒十秒地新增新的内容。

    2019-09-22
  • sky
    之前一个项目中IM是用websocket实现的。
    2019-09-18
  • 靠人品去赢
    老师你好,文章写的真好?但是我有点疑问,就是看comet是一个单工的,也就是“我说完了,你再说”。但是他还是一个基于HTTP协议的,我的理解就是keep-alive。那问题来了我要是用HTTP2.0的话是不是可以把comet转化为双工的呢,因为HTTP2.0是双工通讯?

    作者回复: HTTP/2 确实有了专门的 server push,但这个最主要用来解决资源的预加载问题。因此,如果要完全替代 Comet,实现任意时刻的推送,可以使用 SSE 等技术,或者是将 server push 和 SSE 等技术结合起来(即让浏览器端预留一个回调来响应服务端的推送)。

    2019-09-17
  • tyul
    第一个问题,我们的后台系统里的二维码扫码登录用的就是 Pull 的形式,每隔一段时间就去轮询有没有扫码,有没有确认登录,对于后台这类系统是可以满足需求的;在调度系统里的状态实时推送里用到了 WebSocket 技术,可以实时反馈任务的执行情况。

    第二个问题,Push 模型的优势是高效性和实时性,Pull 模型的优点除了无状态外,优势可能是实现起来更方便,不用引入新的框架

    作者回复: 对于大多数分布式的系统来说,Pull 确实要比 Push 实现起来方便一些,但是也不绝对。至于你说的“是否引入新的框架”这个描述比较模糊,两种方式和是否引入框架没有必然联系。

    2019-09-16
  • Mandalorian
    老师讲得真好。

    提问🙋,Comet这种假PUSH方式,由客户端发起的HTTP请求服务器不释放,但是会受超时限制吧?

    作者回复: 非常好的问题!

    是的,完全正确。你可以考虑这样几点:
    1. 客户端和服务端,还有网关等中间节点,都要商定好一个最大的超时时间。并且,业务端配置的超时时间要稍短于其它,以留足余量。
    2. 服务端即便没有消息需要推送,也要定期返回一个无业务意义的消息,以避免超时发生。
    3. 客户端如果在若干个推送周期后,可以结束连接,休息一段时间,再重新连接。

    2019-09-16
  • 记忆犹存
    Push 的模型
    优点:响应及时
    缺点:
    a.如果客户端接收不及时,造成数据包堆积;
    b. 需要客户端做流控处理;

    Pull模型
    优点:
    a. 提取消息方便
    b. 传输失败不用重试
    缺点:实时性差

    作者回复: 感谢分享!

    对于 Push 模型,你说的内容都是正确的,就提一点,对于你提到的数据包堆积和流控的问题,可以引入第三方的消息队列服务来协调消息发布者和订阅者,来缓解你说的问题。

    对于 Pull 模型,“传输失败不用重试”这个不对,因为是不是重试并非 Push 或 Pull 的区别,二者都可以重试,也都可以不重试,取决于设计。其它正确。

    当然,这是一个开放性问题,还有其它的优缺点,你也可以看看其他人的答复。

    2019-09-16
  • 许童童
    四火老师讲得真好,服务端推送模型最后都可以看作是Comet和WebSocket的变形。

    作者回复: 谢谢。
    很多技术都是相通的,学习全栈技术都是可以用类比的方式进行的。

    2019-09-16
  • 饭团
    1)公司一个简单的聊天业务系统!就用了push模型!
    2)push模型处理信息比poll稍微复杂一些!存在解包封包!需要定一套消息结构!

    作者回复: 感谢分享!
    关于第 2) 个答复:解包和封包其实并不是 push 和 poll 的本质区别,poll 也可以由解包封包,也可以定义一套消息结构。

    2019-09-16
    1
收起评论
15
返回
顶部