出处:

http://mp.weixin.qq.com/s?__biz=MjM5NTU2MTQwNA==&mid=401006254&idx=1&sn=d69a0efc740e04ddefe3cdca14d56eb0&mpshare=1&scene=1&srcid=0302M9o0GjqZL27d4bRUBB1X#rd

于小波,系统架构师,2011年加入魅族,主要从事服务端后台开发工作,专注于系统高并发,分布式等解决方案。

直播实录关于实时推送系统的那点事

大家好,我是于小波,2011年加入魅族,现在在魅族移动互联网部门,主要负责服务端后台架构设计和开发工作。

很感谢ChinaUnix给的这个机会,非常荣幸可以和大家在这里分享我们魅族的一些技术。下面,我们进入今天的主题:关于实时推送系统的那点事。

今天的内容主要分4个方面:系统介绍、架构设计&微服务、踩过的坑&心得、监控和灰度发布。重点介绍一下第三点,也就是一个心得分享。

我们先介绍一下这个系统。

魅族推送系统主要为魅族用户提供以下服务:系统&应用升级、查找手机、联系人同步、应用商店、在线音乐、阅读、游戏中心等,这里就不一一列举了。

我们实时在线用户是2500W左右,日PV 50亿,在现有资源的情况下,推送速度最快可以到600W/分钟。

这个是我们的系统架构图。

从逻辑上划分了4层,最下面的是接入层,为用户提供TCP长连接的接入和http服务。

第二层是消息分发层,主要功能是上行业务消息的分发到各个service,下行推送消息路由到用户所接入的接入服务器,再由接入服务器发送到指定的用户。路由表就是用来保存用户的长连接信息和所在的接入服务器的位置。Webservice的功能后面会提到。

第三层是业务逻辑层,主要处理不同的业务逻辑。

第四层是存储层,存储用户的离线消息和订阅消息。

还有两个比较独立的监控平台和服务管理。

这个系统的是由很多小的服务,每一个服务功能都比较单一,而且是独立的集群,可以单独部署。这里的服务都是异步无状态,要求高并发消息处理延迟低于1ms。

还有一个推送平台,不在今天的讨论范围。

我们在开发这套系统的过程中,碰到了很多问题,下面列了几个比较典型的问题和大家一起分享。

首先,是微服务的问题:

因为所有服务都要求高性能,所以我们开发了一套RPC框架 在魅族内部叫kiev。kiev碰到了两个问题:

1、同步调用

最开始我们这套框架都是同步调用,使用简单,服务的开发效率高。可是随着用户量的增多,性能已经满足不了我们的要求。而且同步调用,我们为了提高性能使用了多线程,很多多线程的问题随之而来。于是我们改进了我们的框架,使用异步。

2、异步问题

非常多的回调函数,一套完整的业务逻辑被打散在各个回调函数来实现,代码的可维护性差,开发效率也不高,而且还有一个很突出的问题,我们在项目中使用了redis、mongodb、mysql的lib库,而这些库都是同步的,如果要做成全异步 那工作量会非常大。后面我们参照go语言用C++实现了一个协程版本的kiev,hook系统的IO调用 比如 send,recv等,把这些系统调用改成异步,达到的效果就是同步的调用,异步的性能。

我们碰到的第二个问题就是手机功耗问题。主要有两个点:

1、手机流量消耗

这里就涉及到选择怎样的协议,传统的方式就是XMPP和sip 这两个协议是纯文本协议,非常多的开源组件,能够快速的搭建一套系统,但是这两个协议都是互联网时代的产物,非常消耗流量。协议本身也非常复杂、冗余,单标准文档就是几十页。

为了降低流量,我们的系统使用的是自定义的二进制协议,可以高度定制,编解码的速度是上面两个协议的10倍以上,流量节约了50%-70%。

2、手机电量消耗

因为我们是tcp长连接服务,手机端为了保持这个长连接需要定期的发送心跳来维持。

一般的做法就是固定3分钟或者5分钟发一次心跳。因为发送心跳需要唤醒手机,如果心跳消息太频繁 就会导致电量的消耗比较大,如果太久发一次心跳又没法保证连接的稳定性。

所以我们根据不同的网络情况 指定了一套智能心跳模式,根据当前的网络情况来设定发送心跳消息的间隔。

还有我们有一个延迟推送的策略。其实很多消息对实时性的要求并没有那么高,比如说系统升级的推送,用户早几分钟或者晚几分钟收到升级的推送并没有多大的影响。针对这种情况,我们对于实时性要求不高的消息可以在手机处于唤醒状态才推送,那问题来了,服务端怎么知道手机是唤醒的呢? 其实很简单,收到用户的心跳包,再推送消息。

第三个问题消息重复问题。

移动网络的特点是不稳定、高延迟。服务端发送消息给客户端,客户端收到消息返回应答,如果应答返回失败了,服务端没有收到这个应答怎么办?

1、超时重传 这里就需要服务器保存每条消息的状态那么服务端的逻辑就会非常复杂

2、等下次客户端连接上来之后再重传。

不管是怎么样,这条消息都会重新发送,就导致客户端收到重复消息。

解决办法:改进消息流程如下图。

当客户端有消息的时候只发送一个通知告诉他,然后客户端自己上来拉取消息,当然需要告诉服务端从什么地方开始拉取。所以客户端需要保存最近收到的消息最大的序列号。

这个流程的好处就是客户不会拉取到重复消息,而且服务端不用保存每条消息的状态,真正做到了业务无状态。

第四个问题,移动网络的DNS问题。

运营商的DNS服务是很不靠谱的,经常宕机,延迟也很大,还容易被劫持。我们采用了全IP的接入方式。

具体就是客户端通过http服务拉取接入层的IP列表,然后选择一个IP直连。

这里访问http服务的时候也可能会被劫持,我们使用预埋IP的策略,优先使用域名访问,域名不可用使用预埋的IP访问。

第五个问题,海量连接的负载均衡问题。

我们单台接入服务器可以承受400W的长连接。如果使用LVS来做负载均衡肯定是不行的,首先LVS存在单点问题。

我们解决的方式:

1、在客户端获取IP列表的时候,其实就是已经排序过的,负载低的服务器IP排在前面。

2、客户端跑马策略,客户端随机选择几个IP 同时发送探测包 哪个IP响应快就用哪个IP,这里服务端需要一个策略就是收到探测包 需要根据自己的实际负载情况决定是否延迟返回。这个跑马策略解决了负载均衡的同时也解决了跨运营商网络访问慢的问题。

关于监控:我们的系统是由很多的小的服务构成,每个服务都是单独的集群,如果集群中一个服务出问题,并不会影响整个业务的使用,但是如果这种问题累计起来,最后可能会导致系统不可用。

所以,只是单纯的依靠简单的业务监控,很难发现未来可能出现的系统故障,所以 我们需要一套严格的监控体系来发现潜在的问题。我们针对每一个服务都定义了一些强监控指标。比如:

最后说一下灰度发布,灰度发布非常重要,线上的很多问题都是发布引起的,我们为了降低发布的风险,引入了灰度发布。灰度发布流程如下图:

在没有灰度发布之前我们开发人员都是凌晨才敢发布,所以我们的状态就像下面这张图。

有了灰度之后再也不用熬夜发布了。

好了,今天的分享就到这里结束了,感谢大家的支持,如果大家有什么问题的话,我们可以直接在这里一起探讨,也可以加我微信私下探讨。

【互动筛选】

Q1:灰度是什么?

A1:灰度是介于黑白之间的,平滑发布。

Q2:重复消息的问题,可否客户端保存最近接收成功但应答失败的消息id,重复推送的消息客户端直接忽略?

A2:这个客户端不知道应答发送失败了。

Q3:推送的到达时间和一次到达率能达到多少?

A3:推送到达时间300ms以内可以到达。到达率理论上是100% 因为我们有离线消息存储,推送不成功的消息会下次再推送。

Q4:移动端的消息推送,和PC端的消息推送,区别在哪儿?实现的难点又在哪儿?

A4:移动端有尽量少的功耗( 电量和流量),pc端不用考虑这个问题。而且移动网络非常不稳定。

Q5:接入服务器均衡,负载高低度量指标是什么,链接数还系统级资源负载,或者其他的?

A5:链接数是其中一个指标。

Q6:如果移动端三天或三十天未上线,服务端要保存这么久么?

A6:不会,我们离线消息有超时机制,一般都是7天。

Q7:关于预埋ip策略,老师能讲解下吗?

A7:预埋IP就是在手机端写死IP地址,如果需要变更 直接推送新的IP地址。

Q8:关于灰度发布这项技术魅族有打算开源吗?

A8:目前还没有计划。

Q9:还有一个非技术问题,设计数百万规模的推送系统,由于公司不太自信,是购买商业产品还是自研好?

A9:如果你们有100W用户了 当然是自己做,如果还没有 可以用一些开源的。有100W用户了说明你们的产品很好,当然要做的更好,吸引更多的用户。

关于实时推送系统的那点事相关推荐

  1. 专访魅族资深架构师:关于实时推送系统的那点事

    [IT名人堂]专访魅族资深架构师:关于实时推送系统的那点事 http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=4193738& ...

  2. [转]关于实时推送系统的那点事

    嘉宾介绍 于小波,系统架构师,2011年加入魅族,主要从事服务端后台开发工作,专注于系统高并发,分布式等解决方案. 直播实录 关于实时推送系统的那点事 大家好,我是于小波,2011年加入魅族,现在在魅 ...

  3. Channels ——django实时推送系统

    一.基于类的consumer 与django基于类的视图类似,Channels也提供基于类的consumers,这些consumers的类都继承自同一个类BaseConsumer.通过下面的代码可以导 ...

  4. django+python搭建消息推送系统

    django+channels+websocket完成一个实时推送系统 前言 因公司项目需求,需要建立一个展示网站,接入两台摄像机,当摄像机的照片流传过来的时候,实时展示到网页中,所以需要做一个实时推 ...

  5. php主动推送弹幕_百万在线的美拍直播弹幕系统的实时推送技术实践之路

    1.内容概述 1.jpg (30.13 KB, 下载次数: 321) 2 年前 上传 直播弹幕是直播系统的核心功能之一.如何迅速作出一个有很好扩展性的弹幕系统?如何应对业务迅速发展?相信很多工程师/架 ...

  6. 开源实时消息推送系统 MPush

    系统介绍 mpush,是一款开源的实时消息推送系统,采用java语言开发,服务端采用模块化设计,具有协议简洁,传输安全,接口流畅,实时高效,扩展性强,可配置化,部署方便,监控完善等特点.同时也是少有的 ...

  7. 设计一个百万级的消息推送系统

    2019独角兽企业重金招聘Python工程师标准>>> 前言 首先迟到的祝大家中秋快乐. 最近一周多没有更新了.其实我一直想憋一个大招,分享一些大家感兴趣的干货. 鉴于最近我个人的工 ...

  8. WEB 实时推送技术总结

    前言 随着 Web 的发展,用户对于 Web 的实时推送要求也越来越高 ,比如,工业运行监控.Web 在线通讯.即时报价系统.在线游戏等,都需要将后台发生的变化主动地.实时地传送到浏览器端,而不需要用 ...

  9. Web 实时推送技术如何弥补 HTTP 协议的缺陷? | 技术头条

    作者 | 浪里行舟 责编 | 郭芮 人工智能的现状及今后发展趋势如何?  https://edu.csdn.net/topic/ai30?utm_source=csdn_bw 随着 Web 的发展,用 ...

  10. php消息实时推送技术,基于HTTP协议之WEB消息实时推送技术原理及实现

    很早就想写一些关于网页消息实时推送技术方面的文章,但是由于最近实在忙,没有时间去写文章.本文主要讲解基于 HTTP1.1 协议的 WEB 推送的技术原理及实现.本人曾经在工作的时候也有做过一些用到网页 ...

最新文章

  1. 关于return和exit
  2. python对操作系统要求_python之--并发编程__操作系统
  3. flink 三种时间机制_Flink的时间类型和watermark机制
  4. oracle tns和sid,oracle – TNS-12505:TNS:侦听器当前不知道连接描述符中给出的SID
  5. 你还在为文件读写而烦恼?Python已经轻松帮你解决了(建议学习)
  6. 叶片制成切片的结构示意图_更集成的发动机!洞悉UTC 3D打印整体式半叶片
  7. 量化分析师的python日记_量化分析师的Python日记【第1天:谁来给我讲讲Python?】...
  8. 数据分析岗位面试必备
  9. Linux的Netfilter框架深度思考-对比Cisco的ACL
  10. @Transactional注解失效场景之——同类中方法调用,事务失效
  11. reflections歌词翻译_Reflections中文歌词
  12. 2022年最新版Android安卓面试题+答案精选(每日20题,持续更新中)【八】
  13. Linux 系统调用 fork wait exec
  14. 【系列笔记一】-USYD悉尼大学Data1002 Grok Module 3 课件 作业 assignment讲解
  15. Ant design vue pro 添加多页签
  16. 科技+卫生=智慧公厕,城市焕然一新!
  17. 【Linux CPUFreq模块】
  18. c语言函数递归相关知识及应用
  19. SSH免密登陆功能配置
  20. 干货来袭:抖音定位的重要性及抖音四步曲丨国仁网络资讯

热门文章

  1. Colorbox 参数设置-中文版
  2. jquery colorbox图片弹出效果制作
  3. 股市前复权、后复权与不复权
  4. 「笔耕不辍」常见远程调用协议
  5. SAP那些事-理论篇-13-SAP问题解决思路
  6. 用python贴吧自动回帖_python基于selenium实现贴吧自动发帖
  7. GitHub中国区前100名到底是什么样的人?
  8. OpenShift 4 - 在 GitOps 中使用 SealedSecret 保护敏感数据
  9. 赣网杯2021 CTF---MiscWebCrypto部分Writeup
  10. python公式计算_Python数学公式计算