1.  卓聘IM开发背景

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

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

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

2.  IM 技术选型

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

通信协议无非是在UDP、TCP、HTTP 选择。传输协议最多使用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: websocket,Connection: Upgrade这二项,你的Nginx和新版Tomcat对这二项会有支持。最重要二个函数一个就是Send方法,一个就是Receive,简单像是我们回到了HTTP Request和Response。可是最大问题在低版本浏览器上不能使用。

2.3  长轮询

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

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

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

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

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

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

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

  手机App、PC浏览器也可以同时在线、同时收发信息,我们既要可以在浏览器上使用像长轮询这样方式,同是也可以在手机上使用WebSocket这样稳定收发方式。App发PC收,或PC发App收取。而且需要在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服务器。

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

  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、应聘者提供更好交流方式。

智联招聘 卓聘IM演进过程的更多相关文章

  1. node.js 89行爬虫爬取智联招聘信息

    写在前面的话, .......写个P,直接上效果图.附上源码地址  github/lonhon ok,正文开始,先列出用到的和require的东西: node.js,这个是必须的 request,然发 ...

  2. Python+selenium爬取智联招聘的职位信息

    整个爬虫是基于selenium和Python来运行的,运行需要的包 mysql,matplotlib,selenium 需要安装selenium火狐浏览器驱动,百度的搜寻. 整个爬虫是模块化组织的,不 ...

  3. python爬取智联招聘职位信息(多进程)

    测试了下,采用单进程爬取5000条数据大概需要22分钟,速度太慢了点.我们把脚本改进下,采用多进程. 首先获取所有要爬取的URL,在这里不建议使用集合,字典或列表的数据类型来保存这些URL,因为数据量 ...

  4. python爬取智联招聘职位信息(单进程)

    我们先通过百度搜索智联招聘,进入智联招聘官网,一看,傻眼了,需要登录才能查看招聘信息 没办法,用账号登录进去,登录后的网页如下: 输入职位名称点击搜索,显示如下网页: 把这个URL:https://s ...

  5. 用python抓取智联招聘信息并存入excel

    用python抓取智联招聘信息并存入excel tags:python 智联招聘导出excel 引言:前一阵子是人们俗称的金三银四,跳槽的小朋友很多,我觉得每个人都应该给自己做一下规划,根据自己的进步 ...

  6. python3爬虫抓取智联招聘职位信息代码

    上代码,有问题欢迎留言指出. # -*- coding: utf-8 -*- """ Created on Tue Aug 7 20:41:09 2018 @author ...

  7. python爬虫实战(五)--------智联招聘网

    前些天帮同事爬取一些智联招聘网上的关于数据分析的职位信息,他说要做一些数据分析看看,现在已经帮他爬完了.我本来想用Scrapy来爬的,但是不知道为什么爬取的数据和真实搜到的数据不太一样,比如:搜索到的 ...

  8. 5分钟掌握智联招聘网站爬取并保存到MongoDB数据库

    前言 本次主题分两篇文章来介绍: 一.数据采集 二.数据分析 第一篇先来介绍数据采集,即用python爬取网站数据. 1 运行环境和python库 先说下运行环境: python3.5 windows ...

  9. 用生产者消费模型爬取智联招聘python岗位信息

    爬取python岗位智联招聘 这里爬取北京地区岗位招聘python岗位,并存入EXECEL文件内,代码如下: import json import xlwt import requests from ...

随机推荐

  1. 【PHP】最详细PHP从入门到精通(二)——PHP中的函数

     PHP从入门到精通 之PHP中的函数 各位开发者朋友大家好,自上次更新PHP的相关知识,得到了大家的广泛支持.PHP的火爆程度不言而喻,函数作为PHP中极为重要的部分,应诸位的支持,博主继续跟进更新 ...

  2. 泛型(java菜鸟的课堂笔记)

                1. 泛型的简单运 用和意义   2. 泛型的上限与下限   3. 泛型和 子类继承的限制   4. 泛型类和泛型 方法   5. 泛型嵌套和泛型擦除             ...

  3. jquery表单序列化

    $(function(){ $('#send').click(function(){ $.ajax({ type: "GET", url: "test.json" ...

  4. Top 10 JavaScript编辑器,你在用哪个?

    对于JavaScript程序员来说,目前有很多很棒的工具可供选择.文本将会讨论10个优秀的支持JavaScript,HTML5和CSS开发,并且可以使用Markdown进行文档编写的文本编辑器.为什么 ...

  5. 通过JSP+servlet实现文件上传功能

    在TCP/IP中,最早出现的文件上传机制是FTP.它将文件由客户端到服务器的标准机制. 但是在JSP中不能使用FTP来上传文件,这是有JSP的运行机制所决定的. 通过为表单元素设置Method=&qu ...

  6. Mac系统占用空间大、空间不够、查看系统文件大小分布

    最近电脑老提示空间不够,甚是心烦,决定研究下,为啥空间这么快就花完了. 如图,256的空间,就剩下几个G了,其中最大头的系统占用:160G,占比60%多,我勒个擦... 正常情况下:我们可以点击管理, ...

  7. java面试基础题(三)

    程序员面试之九阴真经 谈谈final, finally, finalize的区别: final:::修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承.因此 ...

  8. Ubuntu下解决解压zip文件中文文件名乱码问题

    在Ubuntu下解压Windows下压缩的zip文件时,会出现解压出的带中文文件名的文件名乱码,这是因为Ubuntu和Windows默认的编码不同,Ubuntu下默认的编码是UTF-8,而Window ...

  9. Caused by: java.lang.RuntimeException: by java.lang.OutOfMemoryError: PermGen space(tomcat 启动时提示内存溢出)

    设置MaxPermSize大小TOMCAT_HOME/bin/catalina.bat 文件头加set JAVA_OPTS='-Xms512m -Xmx1024m -XX:MaxPermSize=51 ...

  10. 补:关于man关于SEE ALSO(参见)中代号与vim下常用命令

    1.查阅/etc/issue文件时,使用man issue发现manual中see also出现motd(5), agetty(8), mingetty(8)字样.以及文档行首的issue(5)究竟是 ...