开源实时消息推送系统 MPush

系统介绍

开源实时消息推送系统 MPush

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

特性和优势

  1. 源码全部开放,包括server、android、ios 、websocket等
  2. 代码质量高,全部模块化设计,真正的商用级产品,考虑到推送中遇到的大部分场景
  3. 安全性高,基于RSA精简的加密握手协议,简单,高效,安全
  4. 支持断线重连,及弱网下的快速重连,无网络下自动休眠节省电量和资源
  5. 协议简洁,接口流畅,支持数据压缩,更加节省流量
  6. 支持集群部署,支持负载均衡,基于成熟的zookeeper实现
  7. 用户路由使用redis集群,支持单写,双写,集群分组;性能好,可用性高
  8. 支持http代理,一根TCP链接接管应用大部分请求,让http请求更加及时
  9. 高度可配置化,基本上通过修改配置可满足大部分场景
  10. 扩展性强,高度模块化,基于SPI模式的可拔插设计,以满足特殊需求
  11. 监控完善,日志详细,可快速排查线上问题及服务调优

部署环境,这里将各个服务,分开部署,模拟分布式部署环境,各个服务器上可以根据情况进行集群方式部署。

主机IP端口Redis192.168.0.1186379Zookeeper192.168.0.1192181Mpush192.168.0.1203000Alloc192.168.0.1219999Android192.168.0.103

服务器版本为Centos7,最小化安装。

note:

1)最小化安装,默认网卡没有开机自动启动,可以编辑网卡文件(默认为ifcfg-eth0),将ONBOOT设置为yes

[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0

TYPE=Ethernet

BOOTPROTO=dhcp

DEFROUTE=yes

PEERDNS=yes

PEERROUTES=yes

IPV4_FAILURE_FATAL=no

IPV6INIT=yes

IPV6_AUTOCONF=yes

IPV6_DEFROUTE=yes

IPV6_PEERDNS=yes

IPV6_PEERROUTES=yes

IPV6_FAILURE_FATAL=no

NAME=eno16777736

UUID=a4ad8a0c-ff3a-4a49-87fe-639f0053873f

DEVICE=eno16777736

ONBOOT=yes

2)安装系统基本依赖包,用于编译安装软件

[root@localhost ~]# yum install net-tools vim wget make gcc g++ gc++ -y

3)关闭防火墙和SELinux,防止系统干扰导致部署不成功

[root@localhost ~]# setenforce 0

[root@localhost ~]# iptables -F

[root@localhost ~]# iptables -X


一、编译安装Redis

官网下载Redis包,这里下载的是3.2.3版本

1、编译安装Redis

[root@localhost ~]# mkdir /app

[root@localhost ~]# cd /app

[root@localhost ~]# wget http://download.redis.io/releases/redis-3.2.3.tar.gz

解压

[root@localhost ~]# tar xf redis-3.2.3.tar.gz

[root@localhost ~]# cd redis-3.2.3

编译Redis

[root@localhost redis-3.2.3]# make

安装Redis

[root@localhost redis-3.2.3]# make install

cd src && make install

make[1]: Entering directory `/app/redis-3.2.3/src'

Hint: It's a good idea to run 'make test' ;)

INSTALL install

INSTALL install

INSTALL install

INSTALL install

INSTALL install

make[1]: Leaving directory `/app/redis-3.2.3/src'

2、提供配置文件和基础数据目录(我这里将Redis执行文件复制出来了)

[root@localhost redis-3.2.3]# mkdir -pv /app/redis/{bin,conf,log,db}

mkdir: created directory ‘/app/redis’

mkdir: created directory ‘/app/redis/bin’

mkdir: created directory ‘/app/redis/conf’

mkdir: created directory ‘/app/redis/log’

mkdir: created directory ‘/app/redis/db’

[root@localhost redis-3.2.3]# cd src

[root@localhost src]# mv redis-benchmark redis-check-aof redis-check-rdb redis-cli redis-sentinel redis-server /app/redis/bin/

[root@localhost src]# cd /app/redis

提供启动配置文件

[root@localhost redis]# vim conf/redis.conf

daemonize yes

protected-mode no

pidfile /var/run/redis.pid

port 6379

timeout 0

tcp-keepalive 0

databases 16

save 900 1

save 300 10

save 60 10000

stop-writes-on-bgsave-error yes

rdbcompression yes

rdbchecksum yes

dir /app/redis/db

dbfilename dump-6379.rdb

loglevel notice

logfile /app/redis/log/redis.log

slave-serve-stale-data yes

slave-read-only yes

repl-disable-tcp-nodelay no

slave-priority 100

appendonly no

appendfsync everysec

no-appendfsync-on-rewrite no

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

lua-time-limit 5000

slowlog-log-slower-than 10000

slowlog-max-len 128

hash-max-ziplist-entries 512

hash-max-ziplist-value 64

list-max-ziplist-entries 512

list-max-ziplist-value 64

set-max-intset-entries 512

zset-max-ziplist-entries 128

zset-max-ziplist-value 64

activerehashing yes

client-output-buffer-limit normal 0 0 0

client-output-buffer-limit slave 256mb 64mb 60

client-output-buffer-limit pubsub 32mb 8mb 60

hz 10

aof-rewrite-incremental-fsync yes

启动Redis服务

[root@localhost redis]# /app/redis/bin/redis-server /app/redis/conf/redis.conf

查看是否启动Redis服务,并监听指定端口

[root@localhost redis]# netstat -tplan | grep redis

tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 6309/redis-server *

tcp6 0 0 :::6379 :::* LISTEN 6309/redis-server *

[root@localhost redis]# ps aux | grep redis

root 6309 0.1 0.7 136916 7572 ? Ssl 12:03 0:00 /app/redis/bin/redis-server *:6379

root 6335 0.0 0.0 112644 980 pts/0 S+ 12:08 0:00 grep --color=auto redis

使用Redis客户端测试

[root@localhost redis]# /app/redis/bin/redis-cli

127.0.0.1:6379> set mpush mpush0.0.3

OK

127.0.0.1:6379> get mpush

"mpush0.0.3"

127.0.0.1:6379>

查看Redis日志

[root@localhost redis]# tailf /app/redis/log/redis.log


二、安装Zookeeper

[root@localhost app]# ll

-rw-------. 1 root root 181352138 Sep 6 22:54 jdk-8u101-linux-x64.tar.gz

-rw-------. 1 root root 22724574 Sep 6 23:02 zookeeper-3.4.9.tar.gz

1、安装JDK并设置环境变量

[root@localhost app]# tar xf jdk-8u101-linux-x64.tar.gz

[root@localhost app]# ln -s jdk1.8.0_101 jdk

设置JAVA环境变量

[root@localhost app]# vim /etc/profile.d/java.sh

JAVA_HOME=/app/jdk

PATH=$JAVA_HOME/bin:$PATH

CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

export JAVA_HOME PATH CLASSPATH

[root@localhost app]# chmod +x /etc/profile.d/java.sh

[root@localhost app]# source /etc/profile.d/java.sh

[root@localhost app]# java -version

java version "1.8.0_101"

Java(TM) SE Runtime Environment (build 1.8.0_101-b13)

Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

2、安装Zookeeper

[root@localhost app]# tar xf zookeeper-3.4.9.tar.gz

[root@localhost app]# ln -s zookeeper-3.4.9 zookeeper

[root@localhost app]# cd zookeeper

[root@localhost zookeeper]# mkdir data

提供配置文件

[root@localhost zookeeper]# cp conf/zoo_sample.cfg conf/zoo.cfg

[root@localhost zookeeper]# vim conf/zoo.cfg

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/app/zookeeper/data

clientPort=2181

启动Zookeeper服务

[root@localhost zookeeper]# bin/zkServer.sh start

ZooKeeper JMX enabled by default

Using config: /app/zookeeper/bin/../conf/zoo.cfg

Starting zookeeper ... STARTED

查看端口监听

[root@localhost zookeeper]# netstat -tplan | grep 2181

tcp6 0 0 :::2181 :::* LISTEN 3180/java

使用Zookeeper的客户端测试

[root@localhost zookeeper]# bin/zkCli.sh

Connecting to localhost:2181

......................................................

......................................................

WATCHER::

WatchedEvent state:SyncConnected type:None path:null

[zk: localhost:2181(CONNECTED) 0]

[zk: localhost:2181(CONNECTED) 2] create mpush

[zk: localhost:2181(CONNECTED) 4] ls /

[zookeeper]


三、安装MPush

使用群文件提供的mpush-release-0.0.3.tar.gz,或者下载https://github.com/mpusher/mpush代码,自己打包,都可以

[root@localhost app]# ll

total 186716

-rw-------. 1 root root 181352138 Sep 6 22:54 jdk-8u101-linux-x64.tar.gz

-rw-------. 1 root root 9840899 Sep 7 02:28 mpush-release-0.0.3.tar.gz

1、安装JDK并设置环境变量

[root@localhost app]# tar xf jdk-8u101-linux-x64.tar.gz

[root@localhost app]# ln -s jdk1.8.0_101 jdk

设置JAVA环境变量

[root@localhost app]# vim /etc/profile.d/java.sh

JAVA_HOME=/app/jdk

PATH=$JAVA_HOME/bin:$PATH

CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

export JAVA_HOME PATH CLASSPATH

[root@localhost app]# chmod +x /etc/profile.d/java.sh

[root@localhost app]# source /etc/profile.d/java.sh

[root@localhost app]# java -version

java version "1.8.0_101"

Java(TM) SE Runtime Environment (build 1.8.0_101-b13)

Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

2、安装Mpush

[root@localhost app]# tar xf mpush-release-0.0.3.tar.gz

[root@localhost app]# ln -s mpush-0.0.3 mpush

编辑Mpush配置文件(注意,只需要修改mpush.conf配置文件即可,不需要修改reference.conf),修改默认提供的Redis、Zookeeper服务器地址和端口信息。注意,加上mp.http.proxy-enabled=true

[root@localhost mpush]# vim conf/mpush.conf

mp.log.level=warn

mp.min-heartbeat=3m

mp.net.connect-server-port=3000

mp.security.private-key="MIIBNgIBADANBgkqhkiG9w0BAQEFAASCASAwggEcAgEAAoGBAKCE8JYKhsbydMPbiO7BJVq1pbuJWJHFxOR7L8Hv3ZVkSG4eNC8DdwAmDHYu/wadfw0ihKFm2gKDcLHp5yz5UQ8PZ8FyDYvgkrvGV0ak4nc40QDJWws621dm01e/INlGKOIStAAsxOityCLv0zm5Vf3+My/YaBvZcB5mGUsPbx8fAgEAAoGAAy0+WanRqwRHXUzt89OsupPXuNNqBlCEqgTqGAt4Nimq6Ur9u2R1KXKXUotxjp71Ubw6JbuUWvJg+5Rmd9RjT0HOUEQF3rvzEepKtaraPhV5ejEIrB+nJWNfGye4yzLdfEXJBGUQzrG+wNe13izfRNXI4dN/6Q5npzqaqv0E1CkCAQACAQACAQACAQACAQA="

mp.security.public-key="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCghPCWCobG8nTD24juwSVataW7iViRxcTkey/B792VZEhuHjQvA3cAJgx2Lv8GnX8NIoShZtoCg3Cx6ecs+VEPD2fBcg2L4JK7xldGpOJ3ONEAyVsLOttXZtNXvyDZRijiErQALMTorcgi79M5uVX9/jMv2Ggb2XAeZhlLD28fHwIDAQAB"

mp.zk.server-address="192.168.0.119:2181"

mp.zk.namespace=mpush

mp.http.proxy-enabled=true

mp.redis={

#redis 集群配置,group 是个二维数组,第一层表示有多少组集群,每个组下面可以有多台机器

cluster-group:[["192.168.0.118:6379"]]//格式是ip:port:password,密码可以没有ip:port

}

[root@localhost mpush]# chmod +x bin/*.sh

[root@localhost mpush]# bin/mp.sh start

MPush JMX enabled by default

Using config: /app/mpush/bin/../conf/mpush.conf

Starting mpush ... STARTED

[root@localhost mpush]# bin/mp.sh start

MPush JMX enabled by default

Using config: /app/mpush/bin/../conf/mpush.conf

Starting mpush ... STARTED

查看启动情况和端口监听情况

[root@localhost mpush]#netstat -tplan | grep java

tcp6 0 0 :::47188 :::* LISTEN 3358/java

tcp6 0 0 :::3000 :::* LISTEN 3358/java

tcp6 0 0 :::3001 :::* LISTEN 3358/java

tcp6 0 0 :::3002 :::* LISTEN 3358/java

tcp6 0 0 192.168.0.120:45801 192.168.0.119:2181 ESTABLISHED 3358/java

可以看到端口已经处于监听状态

[root@localhost mpush]# tailf -n 30 logs/mpush.log

2016-09-21 13:35:13.427 - [main] INFO - console - launch mpush server...

2016-09-21 13:35:13.439 - [main] WARN - com.mpush.tools.Utils - getExtranetAddress is null

2016-09-21 13:35:13.488 - [main] INFO - console - begin start bootstrap chain...

2016-09-21 13:35:13.489 - [main] INFO - console - start next bootstrap job [ZKBoot]

2016-09-21 13:35:13.759 - [main] INFO - console - init zk client, config=ZKConfig{hosts='192.168.0.119:2181', digest='mpush', namespace='mpush', maxRetries=3, baseSleepTimeMs=3000, maxSleepMs=5000, sessionTimeout=5000, connectionTimeout=5000, localCachePath='/'}

2016-09-21 13:35:13.818 - [main] INFO - console - init zk client waiting for connected...

2016-09-21 13:35:13.891 - [main] INFO - console - start next bootstrap job [RedisBoot]

2016-09-21 13:35:13.894 - [main] INFO - console - begin init redis cluster

2016-09-21 13:35:13.990 - [main] WARN - c.m.zk.listener.ZKRedisNodeWatcher - refresh zk redis node cache, data=[{"redisNodeList":[{"host":"192.168.0.118","port":6379}]}]

2016-09-21 13:35:14.003 - [main] INFO - console - init redis cluster success...

2016-09-21 13:35:14.051 - [main] WARN - com.mpush.tools.Utils - getExtranetAddress is null

2016-09-21 13:35:14.066 - [main] INFO - console - start next bootstrap job [ServerBoot]

2016-09-21 13:35:14.087 - [main] INFO - console - init zk client success...

2016-09-21 13:35:14.267 - [mp-boss-p-2-t-1] INFO - console - server start success on:3000

2016-09-21 13:35:14.267 - [mp-boss-p-2-t-1] INFO - console - start ConnectionServer success listen:3000

2016-09-21 13:35:14.288 - [mp-boss-p-2-t-1] INFO - console - register server node={"ip":"192.168.0.120","port":3000,"extranetIp":"192.168.0.120"} to zk name=/cs/hosts/machine

2016-09-21 13:35:14.289 - [mp-boss-p-2-t-1] INFO - console - start next bootstrap job [ServerBoot]

2016-09-21 13:35:14.307 - [epollEventLoopGroup-2-1] INFO - console - server start success on:3001

2016-09-21 13:35:14.307 - [epollEventLoopGroup-2-1] INFO - console - start GatewayServer success listen:3001

2016-09-21 13:35:14.312 - [epollEventLoopGroup-2-1] INFO - console - register server node={"ip":"192.168.0.120","port":3001} to zk name=/gs/hosts/machine

2016-09-21 13:35:14.313 - [epollEventLoopGroup-2-1] INFO - console - start next bootstrap job [ServerBoot]

2016-09-21 13:35:14.318 - [mp-worker-p-3-t-1] INFO - console - server start success on:3002

2016-09-21 13:35:14.318 - [mp-worker-p-3-t-1] INFO - console - start AdminServer success listen:3002

2016-09-21 13:35:14.318 - [mp-worker-p-3-t-1] INFO - console - start next bootstrap job [HttpProxyBoot]

2016-09-21 13:35:14.318 - [mp-worker-p-3-t-1] INFO - console - start next bootstrap job [MonitorBoot]

2016-09-21 13:35:14.325 - [mp-worker-p-3-t-1] INFO - console - start next bootstrap job [LastBoot]

2016-09-21 13:35:14.326 - [mp-worker-p-3-t-1] INFO - console - end start bootstrap chain...

2016-09-21 13:35:14.326 - [mp-worker-p-3-t-1] INFO - console - ===================================================================

2016-09-21 13:35:14.326 - [mp-worker-p-3-t-1] INFO - console - ====================MPUSH SERVER START SUCCESS=====================

2016-09-21 13:35:14.326 - [mp-worker-p-3-t-1] INFO - console - ===================================================================

[root@localhost mpush]# cat logs/mpush.log | grep error

[root@localhost mpush]#

可以看到日志中服务器已经启动,且日志中没有错误信息


四、安装Alloc服务(此服务建议部署到tomcat或者其他环境中,在此仅提供测试使用)

使用群文件提供的mpush-alloc-1.0-jar-with-dependencies.jar,或者下载https://github.com/mpusher/alloc代码,自己打包,都可以

[root@localhost app]# ll

total 188064

-rw-------. 1 root root 181352138 Sep 6 22:54 jdk-8u101-linux-x64.tar.gz

-rw-------. 1 root root 11221246 Sep 21 05:21 mpush-alloc-1.0-jar-with-dependencies.jar

1、安装JDK并设置环境变量

[root@localhost app]# tar xf jdk-8u101-linux-x64.tar.gz

[root@localhost app]# ln -s jdk1.8.0_101 jdk

设置JAVA环境变量

[root@localhost app]# vim /etc/profile.d/java.sh

JAVA_HOME=/app/jdk

PATH=$JAVA_HOME/bin:$PATH

CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

export JAVA_HOME PATH CLASSPATH

[root@localhost app]# chmod +x /etc/profile.d/java.sh

[root@localhost app]# source /etc/profile.d/java.sh

[root@localhost app]# java -version

java version "1.8.0_101"

Java(TM) SE Runtime Environment (build 1.8.0_101-b13)

Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

2、提供alloc配置文件

[root@localhost app]# vim alloc.conf

mp.log.level=debug

mp.zk.namespace=mpush

mp.zk.server-address="192.168.0.119:2181"

启动alloc

[root@localhost app]# java -jar -Dmp.conf=alloc.conf mpush-alloc-1.0-jar-with-dependencies.jar > alloc.log 2>&1 < /dev/null &

查看日志和启动情况

[root@localhost app]# netstat -tplan | grep java

tcp6 0 0 :::9999 :::* LISTEN 3187/java

tcp6 0 0 192.168.0.121:57930 192.168.0.120:3001 ESTABLISHED 3187/java

tcp6 0 0 192.168.0.121:45079 192.168.0.119:2181 ESTABLISHED 3187/java

可以看到9999端口已经处于监听状态,且已经与我们的Zookeeper(192.168.0.119)、MPush(192.168.0.120)建立了通信

[root@localhost app]# tailf alloc.log

省略部分日志

2016-09-21 14:01:22.493 - [nioEventLoopGroup-2-1] INFO - c.m.c.g.GatewayClientChannelHandler - client connect channel=[id: 0x070321da, L:/192.168.0.121:57930 - R:/192.168.0.120:3001]

2016-09-21 14:01:22.530 - [main] INFO - console - ===================================================================

2016-09-21 14:01:22.531 - [main] INFO - console - ====================ALLOC SERVER START SUCCESS=====================

2016-09-21 14:01:22.531 - [main] INFO - console - ===================================================================

可以看到ALLOC已经启动成功

浏览器测试

开源实时消息推送系统 MPush

可以看到,Alloc已经正常工作


五、完整测试

1、Android测试

note:注意,Android和Alloc、Mpush必须在一个网中且相互可以访问(Alloc、Mpush在公网除外)

1)填写Alloc服务器地址,注意以http://开头,且加端口号

2)填写发送的消息

3)点击Start Push

4)点击Send Push

开源实时消息推送系统 MPush

正常情况,客户端会受到由服务器端推送过来的消息

开源实时消息推送系统 MPush

2、模拟IM

客户端1使用Android手机,客户端2使用浏览器模拟,客户端2给客户端1发送消息。

客户端1

1)填写Alloc服务器地址

2)输入用户ID:user-0

3)点击Start Push

客户端2,使用Chrome插件POSTMAN模拟

开源实时消息推送系统 MPush

六、常见问题

1、报错redis.clients.jedis.exceptions.JedisDataException: DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface.

Redis protected-mode 是3.2 之后加入的新特性,禁用即可

2、没收收到PUSH信息

1)查看服务器日志看是否有报错

2)手机浏览器和PC浏览器输入alloc地址(http://alloc-IP:9999,alloc-IP替换成Alloc服务器IP),查看是否有内容输出

3)关闭防火墙等,防止系统安全导致访问失败


分享到:


相關文章: