zoukankan      html  css  js  c++  java
  • 智联卓聘IM演进过程

    1.  卓聘IM开发背景

     智联卓聘是智联旗下高端人才招聘平台,成4年了,业务增涨每年100%速度增涨,业务增涨快在开发和上线速度要求比较高

     20166月提出IM开发需求7月初上线,开发人员三名,开发时间20天,后期可不断满足业务前期阶段我们考虑网上各种提供IM的云平台,这些平台都有一个问题,聊天记录管理上,有着各种限制和不方便,所以我们决定自己去完成一个。

    一个完整的IM,需考虑通信协议和传输协议。通信协议目前XMPPMQTT ...传输协议TCPHTTP,下面我就从前期技术选择和我们自己在IM开发中遇到问题和如何解决做一些描述。

    2.  IM 技术选型

      IM在选择上,更多我们需要考虑传输协议与通信协议使用。一个实时不经常掉线的IM必须有具有稳定可靠通信。

    通信协议无非是在UDPTCPHTTP 选择。传输协议最多使用XMPP 它是基于XML,每次一大段XML Post到服务端。如果是PC还好,手机端让人抓狂。MQTT反而短小,更适合当下,易用、耗能少。不过目前还没找到使用MQTT协议像Openfire一样强大的开源项目,就是一但出了问题我们风险无法控制。

      以下就是经常被用于IM的相关选择。

    2.1  Openfire

      在Openfire 之前,IM开发者们,一边考虑着通信协议,一边考虑使用什么样传输协议,一切从0开始做起,从Openfire开始,IM开发者发现开发IM简单很多,只要把XMPP协议了解了都可以快速开发,无论你是Web、还是手机,都有着不错开源项目可用。效率也高,后面使用了Mina,想要功能直接写插件、XMPP协议也适应了当时流行的XML。但这一切只是暂时的。

      为了保证通信稳定与安全XMPP协议XML冗余太长了,我们也有了更高效的Netty可用,关系性数据库变的不再适合存储这类数据。 XMPP要传一张图变的很痛苦。

    2.2  WebSocket

      像socket一样提供了一组API,它基于了HTPP协议,它并不是一套完整IM解决方案。在HTTP熟悉的协议中多了Upgrade: websocketConnection: Upgrade这二项,你的Nginx和新版Tomcat对这二项会有支持。最重要二个函数一个就是Send方法,一个就是Receive,简单像是我们回到了HTTP RequestResponse。可是最大问题在低版本浏览器上不能使用。

    2.3  长轮询

      谈到长轮询就不得不说Comet的技术,使的HTTP协议有了主动推送机制。Comet本身有长连接与长轮询二种方式。但是长连接在IEFirefox 下端的进度栏都会显示加载没有完成,而且 IE 上方的图标会不停的转动,表示加载正在进行。长轮询本身技术很简单,是利用HTTP超时机制,重发,看起来像是与客户端建立了个永久连接。现在的开源有Comet4jCometD

      缺点:消息实时性差,每打开一个网页都要保持一个连接,对服务器资源消耗大,发一条信息速度还好,如果是一张图或者大量信息接收时,都会直接影响服务器资源,在手机上使用不稳定。

          优点:实现简单、部署成本低兼容性好只要可以HTTP请求各种平台都可以实现,开源多相关解决方案成熟,一但出现问题我们可以第一时间解决。这是最重要的。

      在开始做IM之前,我们有几个需要考虑的自身业务特点需要考虑。

      首先,我们需要兼容全部浏览器

      让我们在客户端实现方式并不多,WebSocket好用简单,可PC低版本浏览器不能使用。但在手机上又有着广泛的支持。Openfire Smack可它的协议冗余太长,要是在客户端重新定义再到服务器端转化,效率不高。要是使用长轮询如何避免用户打个过多页,白白消耗服务器资源,使用了HTTP协议如何保持它的状态和集群搭建也是问题。

      可以同时在线多种客户端,离线后可推送。

       手机AppPC浏览器也可以同时在线、同时收发信息,我们既要可以在浏览器上使用像长轮询这样方式,同是也可以在手机上使用WebSocket这样稳定收发方式。AppPC收,或PCApp收取。而且需要在App退出后,又可以使用推送平台用户手机上。

    3. 卓聘聊聊架构

       在分析了各种方案优缺点、根据我们目前业务需求和后期扩展,我们将架构做了如下设计。

       通知服务可以随时上线、下线,动态注册在路由规则器中,前端根据需要或长轮询、或WebSocket,在路由规则器获取双方(自己和对方)ID,在通过REST服务发送的数据是带有ID的报文。通知服务在推给推送服务时,推送服务计算“规则”就可准确推送给指定客户。客户接到通知,再次通过REST服务拉取具体内容。

      架构虽然简单,可同时也遇到不少问题,以下就是架构详细介绍及遇到问题和改进方式。

    4. 存在问题及改进方式

    4.1 用户频繁在线打开N多页面产生大量长轮询

      用户浏览器可以多开同一用户打开不同浏览器、同一用户每开一个浏览器打开N多个每个一个页,产生一个连接,长轮很消耗服务资源,CometD代码中,就发现同一用户会限制长轮询个数,这是必要的安全减少服务器资源 但是不能解决实际问题 每个用户会打开很多页签这是用户习惯问题,我们无法限制。而同过观察用户行为平时我们IM在收起状态时,在整个页面右下角。(见图一),用户本身可能不会主动去操作IM工具,如果能减少这样不必要连接可以减少50%-60%无用长轮但是有二点要解决用户不主动点击登录IM

       1你的好友可以看到你在线

       2如何收到你的好友推给你的消息

      图一、

      我们采用了虚拟登录,你没有展开时不去开启长轮,只有点击展开窗口才真正的长轮

       1用户页面加载时,发出你登录信息,同过心跳保持在线状态

       2、你的好友推你信息时,我们通过拉取我们采用 Nginx+Lua+Redis ,这样请求不会打到后面服务

       3、可以将上面二个步骤做成一个连接,减少连接数。

    4.2 发送数据大小与接收速度

         最早开始做时我们对IM了解比较少,做到一半时测试时,输入内容越多或随着业务发展,要求发表情,图文时,会随着长度增加接收和发送会有影响,后来同过学习和观察发现,IM需要推拉同时使用,这也是IM普遍做法,可介绍的人比较少 见下图好处显而易见,推送时解析协议获取到一个个短小命令,而客户端接到命令再去主动拉去实际内容。

      1、发送客户端把发送内容发到指定Web服务器。

      2Web服务器收到后,生成相应指令,和具体发送内容。

      3、分别把指令传送到接收服务器,内容直接存放到数据库中

      4、接收服务收到指令后发送到后面推送服务。

      5、推送服务推到指定用户。

      6、接收用户收到指令后,再通过拉取,从数据库中拉到实际内容。

    4.3如何集群

         Web集群简单,因为是无状态的,用户每次请求都会被负载到不同服务器,不会有问题,而IM麻烦就在状态性,你不可能简单把它负载到不同服务器我们使用Hash算法可以将同一用户会被分到一台指定服务器,同时又出现其它问题,跨服务器消息传递A用户(AM)机器B用户(BM)机器 实现如下

      路由选择器保存我们全部用户及用户连接,我们可以很轻松知道,每个用户具体指向服务器。

      1、用户在登录时在路由规则器注册自己。

      2、当A用户发向B用户信息时,通过路由规则器找到B对应的推送服务

      3、推送服务相应信息通过Comet推送给指定客户。

    4.4 后续迁移

      由于前期时间和业务要求,我们很快上线,可我们要考虑后期代码重构,业务在增长,重构时我们不是推翻重来,我们考虑仅替换瓶颈服务。所以我们将发送服务和推送服务分开,(见下图)发送接口和定义协议不会变变的成本更高),我们要变的,可以方便增加或替换推送模块。图中红色区域就是可以随时被我们替换和增加黄色通信协议模块相对稳定。

      1、发送者发送数据时,我们会把内容写到数据库把命令发到接收服务中。

      2、命令接收服务可是一个消息中间件,也可以是自己写一个Netty服务去解析。

      3、把解析后结果再次发到推送服务,推送服务在PC上可能它是一个Web服务,也可能是WebSocket服务,也可以是第三方平台。当然也可以二种或多种同时存在。

    5. 总结与未来方向

      IM是一种时实要求高的系统,最大问题是用户是否可以正常登录,一但登录,就可以收发信息,而当用户量和用户同时在线交流不断增加时,集群的建设和收发速度都是影响用户体验的重要因素。IM中每个用户状态,信息敏感度都是必不可少监控项。目前我们也在不断优化自动扩容、风险监控这些方向。希望给猎头、企业HR、应聘者提供更好交流方式。

  • 相关阅读:
    ural(Timus) 1346. Intervals of Monotonicity
    SGU 223 Little Kings
    poj 1243 One Person
    poj 1185 炮兵布阵
    poj 1191 棋盘分割
    poj 1187 陨石的秘密
    ACMICPC Live Archive 2451 Brackets Sequence
    将时间格式的字符串转换成日期类型浏览器兼容解决方案
    asp.net项目发布容易忽略的debug=true
    使用微软的Ajax控件遇到的后台js提示语句不起作用的解决方案其一
  • 原文地址:https://www.cnblogs.com/shouhongxiao/p/7200253.html
Copyright © 2011-2022 走看看