開源實時消息推送系統 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)關閉防火牆等,防止系統安全導致訪問失敗


分享到:


相關文章: