智联卓聘 卓聘IM(聊聊)开发实践
1. 卓聘IM开发背景
智联卓聘是智联旗下高端人才招聘平台,成立快4年多,业务增涨每年以100%速度增涨快,同时对产品和研发速度都比较高。
2015年提出IM开发,主要用于后选人与猎头及时交流,降低后选人与猎头沟通成本。我们首先考虑就是网上各种IM的云平台,而这些平台都有一个问题,聊天记录管理上有着各种限制和不方便,所以我们决定自己去完成一个。
2. IM 技术选型
前期主要是PC版本的IM工具开发,(实际当时我们还没有自己APP),像大多数网站一样。把聊天功能仅嵌入网页的一角。有消息时弹出,没有消息时收起。
首先想到用Openfire,XML冗余大、在数据二进制流传输上有着各种问题。我们的开发时间就一个月,二个后端,一个前端。资源严重不足。我没有时间翻看它的源码,不仔细去看源码我是很担心一但出问题风验是不可控制的。
我们转向了WebSocket,它基于了HTPP协议,很好解决了网页HTTP通信协议的无状态性。仅仅在HTTP熟悉的协议中多了Upgrade: websocket,Connection: Upgrade这二项,最大问题是在低版本浏览器上无法使用。
最后像大多数IM开发者我们选择了,长轮询这样方式。开发成本低、是个浏览器就能用。开源的有Comet4j、CometD拿来就能用,几天就能看完源码。
3、IM演进过程
3.1 原始版
决定使用长轮询后,长轮询这样方式对服务器消耗资源是很大的,问题是如何集群。
我们做法在用户登录IM时,把用户ID 做一次Hash,就可把用户分到一台具体推送服务中,要发送信息给你好友时,用ID查询就可得到它在那台机器,直接推送信息到这台机器就可以。

在简单快速完成了第一阶段任务后,随之而来问题也越来越多,长轮询请求过多,而这些请求不是用户聊天产生的,而是因为用户打开了一个个带有聊天网页产生的。同时也发现用户聊天内容不断增多,输入的聊天内容越长推送越慢。
3.2 改进版
同一用户打开N多个页面。都会产生N个长轮询连接,在CometD代码中,就发现同一用户会限制长轮询个数。但是现实中不能这么解决问题。 用户打开很多页签,这是用户习惯问题。同过观察用户行为,平时IM在收起状态时,(在整个页面右下角,见图),用户不会主动去操作IM工具,如果能减少这样不必要连接就可以减少50%-60%无用长轮询,但是有以下二点需要解决。
1、你的好友可以看到你是在线状态 。
2、你如何收到你的好友消息。

我们解决方案是,在页面加载IM工具时用户自动登录,同过用心跳保持在线状态。你的好友推送信息给你时,我们通过短轮询拉取。我们采用 Nginx+Lua+Redis方式。这样请求就不会打到后面服务器上。
最早开始做IM工具时了解比较少。用户发送文本内容越大越多时,直接影响了直个服务器推送消息的速度。IM需要做成推拉模式才是理想方式。用户在发送内容给好友时,把具体内容存储后返回一个ID,同时生成一个带有ID的命令包发给推送服务,前端在接收到ID的命令包后进行解析,再根据ID去拉取具体内容。

随着业务扩大和需求不断增加,APP也要上线IM功能,使用长轮询方式无论是在耗电、还是在稳定性上用户体验都很差。如果再单独为APP建立一套IM,无论是在业务上还是成本上都是不能接受的。关键问题是如何打通PC与APP用户之间实时交流。
3.3 进阶版
由于上一版本我们将发送和接收已经分开,所以发送信息时我们不需要改变原有模块,需要改变就是APP的接收方式,把以前长轮询能改为WebSocket,同时不影响以前PC接收方式,最好方式是让前端选择使用长轮询还是WebSocket还是其它。所以我们把架构做了如下调整。

我们增加了“通知服务”模块,在前端与推送服务之间建立了或长轮询或WebSocket连接,把以前直接发给推送服务模块的“指令”改成发往通知服务模块。通知服务模块目前是一组消息队列。而推送服务还兼顾者消息订阅者功能。在分析路由规则后直接把信息推送给指定前端。
4、 总结与未来方向
IM是一种时实怀要求很高的系统,最大问题是,用户是否可以正常登录,一但登录,就可以收发信息,而当用户量和用户同时在线交流不断增加时,集群的建设和收发速度都是直接影响用户体验的重要因素。IM中每个用户状态,信息敏感度都是必不可少监控项。目前我们也在不断优化自动扩容、风险监控这些方向。希望给猎头、企业HR、应聘者提供更好交流方式。
智联卓聘 卓聘IM(聊聊)开发实践的更多相关文章
- 智联招聘 卓聘IM演进过程
1. 卓聘IM开发背景 智联卓聘是智联旗下高端人才招聘平台,成立快4年了,业务增涨每年以100%速度增涨,业务增涨快在开发和上线速度要求也比较高. 2016年6月提出IM开发需求,7月初上线,开发人 ...
- node.js 89行爬虫爬取智联招聘信息
写在前面的话, .......写个P,直接上效果图.附上源码地址 github/lonhon ok,正文开始,先列出用到的和require的东西: node.js,这个是必须的 request,然发 ...
- python_selenium智联搜索
python_selenium智联搜索 妹子要去招聘会工作,奈何网上仅仅提供招聘会的公司名字,没有提供招聘的职位,SO我写了个小代码给妹子在智联上面搜索职位,由于时间紧迫,前程的就不写了 #!/usr ...
- 用python抓取智联招聘信息并存入excel
用python抓取智联招聘信息并存入excel tags:python 智联招聘导出excel 引言:前一阵子是人们俗称的金三银四,跳槽的小朋友很多,我觉得每个人都应该给自己做一下规划,根据自己的进步 ...
- python3爬虫抓取智联招聘职位信息代码
上代码,有问题欢迎留言指出. # -*- coding: utf-8 -*- """ Created on Tue Aug 7 20:41:09 2018 @author ...
- python爬虫实战(五)--------智联招聘网
前些天帮同事爬取一些智联招聘网上的关于数据分析的职位信息,他说要做一些数据分析看看,现在已经帮他爬完了.我本来想用Scrapy来爬的,但是不知道为什么爬取的数据和真实搜到的数据不太一样,比如:搜索到的 ...
- 5分钟掌握智联招聘网站爬取并保存到MongoDB数据库
前言 本次主题分两篇文章来介绍: 一.数据采集 二.数据分析 第一篇先来介绍数据采集,即用python爬取网站数据. 1 运行环境和python库 先说下运行环境: python3.5 windows ...
- 万物智联,腾讯云 IoT 边缘计算揭秘——云+未来峰会开发者专场回顾
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 背景:现在是万物互联的时代,智能穿戴设备,智能家居,无人商业,改变了我们的生活方式.预计到2021年,全球物联网设数将达到150亿,超过手机 ...
- Python+selenium爬取智联招聘的职位信息
整个爬虫是基于selenium和Python来运行的,运行需要的包 mysql,matplotlib,selenium 需要安装selenium火狐浏览器驱动,百度的搜寻. 整个爬虫是模块化组织的,不 ...
随机推荐
- Redis 小白指南(一)- 简介、安装、GUI 和 C# 驱动介绍
Redis 小白指南(一)- 简介.安装.GUI 和 C# 驱动介绍 目录 简介 安装 入门指令 GUI 工具 C# 驱动介绍 简介 ANSI C 编写,开源,基于内存,可持久化,一个键值对的数据库, ...
- python 列表转字典
def func_data(text): data = dict() for kv in text.split(','): k_v = kv.split(':') data[k_v[0]] = k_v ...
- Qt之新手打包发布程序
工具:电脑必备.QT下的windeployqt Qt 官方开发环境使用的动态链接库方式,在发布生成的exe程序时,需要复制一大堆 dll,如果自己去复制dll,很可能丢三落四,导致exe在别的电脑里无 ...
- Redis 小白指南(四)- 数据的持久化保存(草稿)
Redis 小白指南(四)- 数据的持久化保存 简介 因为 redis 将数据保存在内存中,很容易诱发的一个问题就是,程序崩溃或服务器重启等情况如何保证数据的正常存储. 当我们以 redis 作为主数 ...
- python对mysql数据库操作的三种不同方式
首先要说一下,在这个暑期如果没有什么特殊情况,我打算用python尝试写一个考试系统,希望能在下学期的python课程实际使用,并且尽量在此之前把用到的相关技术都以分篇博客的方式分享出来,有想要交流的 ...
- python str的一些方法
在python有各种各样的string操作函数.在历史上string类在python中经历了一段轮回的历史.在最开始的时候,python有一个专门的string的module,要使用string的方法 ...
- 向EXECL文件中导入数据的同时插入图片
因为项目需要在导出数据到EXECL文档的同时还需要导出图片进去,在处理是遇到的一些问题,在此记录一下. 首先代码写好之后放测试服务器上去执行的时候报错了,报检索 COM 类工厂中 CLSID 为 {0 ...
- 架构师之路--应用架构的选型和dubbo
这个选型主要决定于系统复杂度.先回顾一下. 1>单一应用架构:对于一个流量很小的网站来说,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本.之前在上家公司做过一个微信公众号的开发就是基 ...
- java音视频编解码问题:16/24/32位位音频byte[]转换为小端序short[],int[],以byte[]转short[]为例
前言:Java默认采用大端序存储方式,实际编码的音频数据是小端序,如果处理单8bit的音频当然不需要做转换,但是如果是16bit或者以上的就需要处理成小端序字节顺序. 注:大.小端序指的是字节的存储顺 ...
- ios移动端原生滚动条滚动不灵敏问题
最近开发微信页面的时候遇到了这个问题, 因为移动端浏览器的原生滚动条样式很好,不像pc端那么难看,所以在页面需要滚动的地方用了原生的滚动条,这种滚动条在安卓浏览器中没有任何问题,但是在ios微信浏览器 ...