AVOS Cloud目前还在用Ejabberd做Android的消息推送服务。当时选择Ejabberd,是因为Ejabberd是一个发展很长时间的XMPP实现,并且基于Erlang,设想能在我们自主研发的Push Server起来之间顶上一段时间。

我们自主研发的Push Server预计本月中旬就上线了。但是Ejabberd却先顶不住了。Ejabberd做推送,本身就有劣势,比如XMPP协议的冗余,XMPP协议本来就是IM协议,对推送这个简单的场景还是太复杂了一些。Ejabberd Cluster对于IM这样的场景很有优势,对于一个Ejabberd Cluster内机器来说,A用户连在A服务器,B用户连在B服务器,两者之间的通讯,Ejabberd都帮你处理了,会自动路由AB之间的消息。Ejabberd会在整个Cluster内每个节点维护session数据,每次session的变更都会在节点之间复制。但是对于推送服务来说,没有刚才提到的AB用户的通讯问题,都是服务端往client推送数据,client没有上行的数据,这个session维护的代价反而是没有必要了。

因此,使用Ejabberd推送的第一条优化手段: 不使用Ejabberd Cluster。反而采用多个独立节点的结构,每个节点之间都是独立,不组成集群。因为节点之间独立,用户数据却还需要共享,那么放弃mnesia,而采用odbc数据库的方式存储用户数据就成为自然的选择了。

那么在采用多节点之后,会出现一个问题?推送服务怎么知道应该往哪个节点推送消息,换句话说,推送服务怎么知道要推送的设备连在哪台服务器上?我们的解决办法是引入一个Router服务,它来告诉推送服务和终端设备链接到哪台服务,采用一致性哈希算法来分配连接,减少节点变更带来的影响。最后,我们使用一个简陋但是简单的办法来感知节点是否有效。这个简陋的办法就是使用crontab脚本每隔几秒向router服务发送该机器上ejabberd端口处于ESTABLISHED或LISTEN状态的链接数(netstat命令)。

优化第二条:将数据库服务跑在单独的服务器上。我们使用MySQL,MySQL的优化这里就不提了,innodb配置参数,并发线程、事务级别等等。最好也对数据库做个异步slave备份。

优化第三条,去除不必要的module,我们只用到ejabberd的数据下行和用户账户管理功能,其他模块都可以去掉,下面是一个可以去掉的模块清单:

mod_caps
mod_pubsub
mod_vcard_odbc
mod_roster_odbc
mod_privacy_odbc
mod_proxy65
mod_disco
mod_echo
mod_http_fileserver
mod_shared_roster
mod_service_log
mod_irc
mod_muc
mod_vcard_odbc
mod_adhoc
mod_configure
mod_last

如果你想记录每个账户最后一次连接的时间,可以保留mod_last模块,使用odbc方式记录。

优化第四点,ejabberd.cfg的参数优化(一般在/etc/ejabberd/ejabberd.cfg),包括:

  • loglevel, 建议设置成3,只打印warn级别以上日志。
  • listen模块,ejabberd_c2s的backlog参数,设置TCP backlog队列长度,建议设置得大一些。因为移动网络下,连接断开重连相对频繁,backlog队列较大可以保证服务端的连接accept能力。
  • shaper模块,设置流量控制,默认的normal是1.000 B/s远远不能满足需求。
  • max_fsm_queue参数,控制出队消息队列长度,建议不要设置(undefined),或者设置得较大。
  • odbc相关参数: odbc_pool_size控制连接池大小,设置大一些没关系。odbc_keepalive_interval检测连接是否存活,跟MySQL的wait_timeout保持一致,odbc_start_interval设置重连间隔,默认即可。
  • 权限控制(Access)相关参数:max_user_offline_messages设置最大保存的离线消息数目,根据你的应用需要,设置一个合理的值,我们是设置成5。max_user_sessions设置每个用户最多登录的session数目,建议设置小于等于2,防止重复登录。rigister权限控制给admin使用,预先创建一批admin账号,授予创建用户的权限。每个设备用一个uuid标示,通过这些admin账号注册到ejabberd上。

优化第五条,erlang运行时参数优化(一般在/etc/default/ejabberd文件):

  • POLL=true,开启网络层启用Polling,linux一般是epoll,BSD系统是kqueue。编译Erlang的时候必须设置启用才能启用此选项。
  • SMP=auto|enable,设置成auto或者enable,测试表明,启用SMP在多核机器上能极大地改善吞吐量。
  • ERL_MAX_PORTS,每个TCP链接都将耗费2到3个的erlang port,因此这个参数也设置得大一些,>=30万。
  • PROCESSES,进程数目尽管设置得大一些,最好是ERL_MAX_PORTS的数倍。
  • ERL_MAX_ETS_TABLES: ets表数目,如果日志中看到too many db tables的时候,可以增大此参数,默认1400。

优化第六条,TCP内核参数的优化,注意下列参数:

net.ipv4.tcp_syncookies=1
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_timestamps=1
net.ipv4.tcp_max_syn_backlog=65535
net.ipv4.tcp_fin_timeout=30

具体含义请自行Google,切记,不要同时开启tcp_tw_recycle字段和tcp_timestamps字段,建议开启tcp_timestamps,原因参考雕梁哥的这篇博客

如果有开启防火墙iptables,还需要注意net.netfilter.nf_conntrack_max参数,这是用来限制防火墙跟踪链接的状态表的大小,对于推送服务来说保持大量长连接是很容易超过默认的65535的,如何配置请参考这篇文章

最后,更多的优化手段,其实就需要深入ejabberd源码了,比如存储的优化,使用redis作为离线消息存储等;erlang语言和vm层面的优化,系统层面的优化(CPU绑定、内核参数进一步调整等)。这就超过我目前的能力范围了,我们的新推送服务基于Netty和Clojure开发,以后应该不会再跟ejabberd打交道了。整体上来说,ejabberd作为一个早期推送方案,支撑百万级别的推送是没有问题的,虽然可能成本会稍微高了一些。

 

转自:http://outofmemory.cn/wr/?u=http%3A%2F%2Fblog.fnil.net%2Findex.php%2Farchives%2F276

Ejabberd作为推送服务的优化手段(转)的更多相关文章

  1. Ejabberd作为推送服务的优化手段

    AVOS Cloud目前还在用Ejabberd做Android的消息推送服务.当时选择Ejabberd,是因为Ejabberd是一个发展很长时间的XMPP实现,并且基于Erlang,设想能在我们自主研 ...

  2. Netty系列之Netty百万级推送服务设计要点

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  3. Netty_Netty系列之Netty百万级推送服务设计要点

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  4. 【netty】Netty系列之Netty百万级推送服务设计要点

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  5. Netty系列之Netty百万级推送服务设计要点(转)

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  6. Netty学习总结(3)——Netty百万级推送服务

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  7. 基于netty-socketio的web推送服务

    实时消息的推送,PC端的推送技术可以使用socket建立一个长连接来实现.传统的web服务都是客户端发出请求,服务端给出响应.但是现在直观的要求是允许特定时间内在没有客户端发起请求的情况下服务端主动推 ...

  8. 移动互联网实战--Apple的APNS桩推送服务的实现(2)

    前记: 相信大家在搞IOS推送服务的开发时, 会直接使用javapns api来简单实现, 调试也直连Apple的APNS服务(产品/测试版)来实现. 很少有人会写个APNS的桩服务, 事实也是如此. ...

  9. iOS推送服务细节回顾

    iOS推送服务细节回顾 之前在做推送功能时候,就总结过一系列证书的制作,OC代码实现和服务器搭建等经验.又过了一段时间了,前前后后对推送服务做了多次的完善和优化,有iOS客户端的,还有本地服务器端的. ...

随机推荐

  1. cisco packet 实验教程(一)

    01. 开篇:组建小型局域网 实验任务 1.利用一台型号为2960的交换机将2pc机互连组建一个小型局域网: 2.分别设置pc机的ip地址: 3.验证pc机间可以互通. 实验设备 Switch_296 ...

  2. OSX 系统无法直接用 Chrome 双击点击打开本地 html 文件

    在 Mac OS X 下,文件经常会被附加上 OS X 特有的扩展属性 ( extend attributes ),具体表现是用 ls -l 查看时会有 @ 的标记,譬如: $ ls -l index ...

  3. 16Aspx.com-PHP企业整站源码 景观石材大理石类织梦模板 含手机移动端 完整源码 APP+PC

    =============================================== 源码站长资源交易专业网-商业源码下载,VIP源码,程序交易,毕业设计交易,站长交易|- 16aspx.c ...

  4. 透过ReentrantLock窥探AQS

    背景 JDK1.5引入的并发包提供了一系列支持中等并发的类,这些组件是一系列的同步器,几乎任一同步器都可以实现其他形式的同步器,例如,可以用可重入锁实现信号量或者用信号量实现可重入锁.但是,这样做带来 ...

  5. Linux(一) 软件安装

    前言:在Linux中安装软件时,我们经常要考虑到这样几个个问题: (1).怎样安装软件;       (2).软件安装在什么地方;       (3).如何卸载删除不要的软件...... 下面,我们就 ...

  6. 网络安全---大学霸_ITDaren

    http://blog.csdn.net/u014621518/article/category/2191665

  7. [笔记]Android 源码编译

    问题: 解决方法: 下载地址ftp://ftp.gnu.org/gnu/make/make3.8.2的安装步骤:tar -zxvf make3.8.2.tar.gz在make-3.8.2目录下./co ...

  8. EasyMvc入门教程-基本控件说明(4)折叠面板

    折叠面板一般出现在管理后台,大家用的OutLook里就是用了折叠面板,样子大概是这样的: 把其中的内容替换成图标按钮,是不是就是我们常见的样子了?:)那么如何实现呢?请看例子: @{ var data ...

  9. Geographical distance

    Introduction Calculating the distance between geographical coordinates is based on some level of abs ...

  10. MR之SequenceFile具体解释

    package com.leaf.hadoop.second; import java.util.Random; import org.apache.hadoop.conf.Configuration ...