环境 #
依赖 #
- java 8 下载地址 (opens new window),Windows安装后需要配置java环境变量
# Linux/MacOS 打开终端,Windows打开命令行提示符, 输入java -version,输出如下结果表示安装成功
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
- redis
Windows下载地址 (opens new window),默认安装即可
# Linux安装:
yum install redis 或 apt install redis
# MacOS安装:
brew install redis
- 时间
注意系统时间,最好自动同步,linux使用ntp
配置 #
进入到开发者控制台下载 (opens new window)服务端
目录结构 #
下载解压,放到任意位置即可,获得如下目录结构
├── VERSION # 版本文件
├── config # 配置文件目录
│ ├── log4j.properties # 日志配置
│ ├── redis.properties # redis客户端配置
│ ├── servers.json # 服务配置
│ ├── upush.properties # upush系统配置
│ ├── xxxxxx.upush.key # 授权证书文件,在开发者控制台项目信息中下载
│ └── vendor # 存放厂商推送配置,证书,授权文件的目录
├── libs # 依赖目录
├── vendor-libs # 厂商推送依赖目录
├── logs # 日志目录
├── run.bat # 启动脚本(windows)
├── run.sh # 启动脚本(linux,macos)
├── single-run.bat # 单机版快速启动脚本(windows)
├── single-run.sh # 单机版快速启动脚本(linux,macos)
├── stop.bat # 停止脚本(windows)
├── stop.sh # 停止脚本(linux,macos)
├── upush2-main.jar # 单机启动全部服务
├── upush2-connector.jar # connector服务
├── upush2-master.jar # master服务
├── upush2-server.jar # push server服务
├── upush2-vendor.jar # 厂商推送服务
└── vendor-libs # 厂商推送依赖目录
服务配置 #
servers.json
master配置 #
多个master服务时,通过nginx对外暴露一个地址和端口提供服务,除NGINX使用其他负载均衡也可以
{
"masters": [ // 至少配置一个master
{
"id": "master-1", // id规范必须是“master-数字”,系统中唯一
"name": "", // 任意起名,服务名字,备注名,增加可读性维护性,在系统内部无实际意义
"host": "192.168.6.15", // 本地IP地址,单机版可以写127.0.0.1
"localPort": 6132, // 本地端口,系统内部服务之间访问使用
"clientPort": 6132 // 客户端访问端口(非必须)
},
{
"id": "master-2",
"host": "192.168.6.216",
...省略
},
{
"id": "master-3",
"host": "192.168.6.44",
...省略
}
]
}
clientPort
- Nginx master负载配置范例
stream {
server {
listen 5488;
proxy_pass upush2;
proxy_connect_timeout 6;
}
upstream upush2 {
# 负载方式,默认为轮询,下为哈希一致
# hash $remote_addr consistent;
server 192.168.6.15:6132;
server 192.168.6.216:6132;
server 192.168.6.44:6132;
}
}
vendor配置 #
- 多个vendor服务时,通过nginx对外暴露一个地址和端口提供服务,除NGINX使用其他负载均衡也可以
- 如果不需要手机厂商推送,可以不配置,并且无需启动vendor服务
{
"vendors": [
{
"id": "vendor-1", // id规范必须是“vendor-数字”,系统中唯一
"name": "", // 任意起名
"host": "192.168.6.57", // 本地IP地址,单机版可以写127.0.0.1
"localPort": 5489 // 本地端口
},
{
"id": "vendor-2",
... 省略
}
]
}
servers配置 #
pushserver和connector可以组成单个集群,多个集群,跨机房部署
{
"masters": [
// ... 参照上面master服务配置
],
"vendors": [
// ... 参照上面vendor服务配置
],
"clusters": [ // 集群配置
{
"id": "cluster-1", // 集群ID,必须是“cluster-数字”,系统中唯一
"name": "", // 集群名字,任意起名
"master": "", // 设置集群连接master服务地址信息,三种配置方式:
// 1,不配置或为空时默认取masters第一个,
// 2 可配置为master服务ID,例如: master-1
// 3 直接配置地址信息,例如: 192.168.1.100:7000,当master集群通过nginx对外提供访问时可使用此方式配置
"vendor": "", // 为集群配置厂商推送服务,配置方式同上(master)
"pushservers": [
{
"id": "pushserver-1", // push server id 必须是“pushserver-数字”,系统中唯一
"name": "", // 任意起名
"localhost": "192.168.6.79", // 本地IP地址,单机版可以写127.0.0.1
"host": "", // master和push server在同一局域网内可以不写
"localPort": 5011 // 本地端口
},
{
"id": "pushserver-2",
...省略
}
],
"connectors": [
{
"id": "connector-1", // connector id 必须是“connector-数字”,系统中唯一
"name": "", // 任意起名
"localhost": "192.168.6.148", // 本地IP地址,系统内部访问使用,单机版可以写127.0.0.1
"host": "", // 外网地址,供客户端访问,必须填写,支持域名
"host6": "", // 外网ipv6地址。供客户端ipv6网络访问,不支持ipv6可以不填写
"localPort": 6357, // 本地端口,系统内部服务访问使用
"clientPort": 7357 // 外网端口,供客户端访问使用
},
{
"id": "connector-2",
...省略
},
{
"id": "connector-3",
...省略
}
]
},
{
"id": "cluster-2", // 不同集群可以部署在不同机房,如果服务部署在同一机房不同服务器,建议使用一个集群即可
"name": "",
"pushservers": [
{
"id": "pushserver-3",
...省略
}
],
"connectors": [
{
"id": "connector-4",
...省略
}
]
}
]
}
UPush配置 #
upush.properties
初次启动在本地配置好,之后可以在管理后台统一修改。
# 离线消息有效期(天)
offline.msg.expire=30
# 消息重发次数
msg.resend.num=3
# 消息重发间隔,单位秒
msg.resend.interval=6
# 消息撤回超时时间,单位秒。建议在集成系统判断是否能撤回,这个配置是辅助集成系统控制的。
msg.recall.timeout=130
# 厂商头像Url前缀
msg.avatar.url.prefix=
# 厂商推送配置url,为空时从本地取
vendor.config.url=
# 消息反馈,管理后台地址+/upush/console/v2/message/feedback
msg.feedback.url=
# 消息反馈间隔,单位秒
msg.feedback.timeout=60
# 群组消息是否支持离线消息
offline.group.msg.enable=true
# 客户端连接信息有效期(天)
pushToken.expire=30
# 客户端离线回调集成服务端请求Url,POST,application/json,
# 参数{pushToken,userId,packageName,status},其中status 0为离线,-1注销
offline.callback.url=
# 移动端单点登录包名设置,需要在android和ios之间实现单点登录时配置,包名用;分割
client.mobile.sso.packages=
#部署的国家,默认是zh
country=zh
# ssl证书文件名,格式jks, 文件放在config下, 如果需要支持wss必须配置
ssl.keystore=
# ssl密码
ssl.password=
# 连接器服务分配策略
# RR:对各个connector依次分配
# LC:最小连接调度算法是把新的连接请求分配到当前连接数最小的服务器。
# SH:散列调度算法,对客户端IP取Hash
connector.assign.policy=LC
# 如果需要支持ipv6需要每个connector都配置host6地址,但有时只是为了测试或者对应ios审核,可以单独指定connector做为ipv6客户端指定连接服务,
# 这样只需配置一个connector服务器的ipv6环境即可,格式connectorId:clusterId,例如:connector-1:cluster-1
connector.ipv6.server.alias=
# 只支持SH,或者自定义CM。建议自定义时集群负载规则要有明确的指向性,不要随机或者轮叫
cluster.assign.policy=SH
# 当上面的设置为CM时,需要配置此属性,为自定义规则类,需要实现com.upush.api.assign.ClusterAssignPolicy
cluster.assign.policy.class=
cluster.assign.policy.class
自定义集群分配范例 (opens new window),打包后把jar放到libs下即可
厂商推送配置 #
如果不使用手机厂商推送无需配置。
服务端本地配置,或者管在理后台中配置,这里展示不同厂商推送在服务端需要配置的内容。
厂商配置文件需要放在config/vendor
目录下,命名规则:包名_厂商缩写小写.properties,FCM后缀为.json
厂商推送通道,类别申请
- 苹果
# 1 证书方式, 2 http2方式(推荐)
mode=2
# production or development
env=production
# BundleId
topic=xxx.xxx.xxx
# voip,callkit(国内不允许使用)
voip=false
#方式1
# 推送证书,证书和配置文件同目录
apns.cert=XXX.p12
# 推送证书密码
apns.cert.password=123456
# VOIP推送证书,选配
voip.cert=XXX.p12
# VOIP推送证书密码,选配
voip.cert.password=123456
#方式2
teamId=XXXXXX
keyId=XXXXXXXX
pkcs8=XXXXXXXXX.p8
- 小米
# 包名
packageName=xxx.xxx.xxx
appSecret=
# 参照下面的“厂商推送类别或通道适配”说明
category.IM=123456
category.VOIP=130283
category.WORK=120176
- 华为
appId=
appSecret=
# 包名
packageName=xxx.xxx.xxx
# 入口Activity
badgeClass=xxx.xxx.xxx.XXXXActivity
# 推送模式 0:正式推送;1:测试推送,不填默认为0
pushMode=0
# 参照下面的“厂商推送类别或通道适配”说明
category.IM=IM
category.WORK=WORK
category.VOIP=VOIP
category.MARKETING=MARKETING
- OPPO
appKey=
masterSecret=
# 参照下面的“厂商推送类别或通道适配”说明
category.IM=upush_high_channel
category.VOIP=upush_high_channel
category.WORK=yoxin_sys_msg
category.MARKETING=upush_low_channel
- VIVO
appId=
appKey=
appSecret=
# 推送模式 0:正式推送;1:测试推送,不填默认为0
pushMode=1
# 参照下面的“厂商推送类别或通道适配”说明
category.IM=IM
category.VOIP=IM
category.WORK=TODO
category.MARKETING=MARKETING
- 荣耀
clientId=
clientSecret=
appId=
# 入口Activity
badgeClass=
# 包名
packageName=
# 推送模式 0:正式推送;1:测试推送,不填默认为0
pushMode=
# 参照下面的“厂商推送类别或通道适配”说明
category.IM=NORMAL
category.VOIP=NORMAL
category.WORK=NORMAL
category.MARKETING=LOW
- 魅族
appSecret=
appId=
- 谷歌
FCM控制台 (opens new window),进入到项目设置,服务账号,点击生成新的私钥,把下载文件重命名后放到config/vendor
厂商推送类别或通道适配 #
- 国内厂商推送需要申请类别或通道才能正常推送,如果不申请就按照营销消息处理。在实际开发中构建推送消息需要为各个厂商添加不同参数来指定类别或通道,增加了开发的复杂度。具体参照
厂商 | 类型 | 是否需要审核 |
---|---|---|
华为 | 类别 | 是 |
小米 | 通道 | 是 |
OPPO | 通道 | 是 |
VIVO | 类别 | 否 |
荣耀 | 重要或不重要 | 否 |
- 为了使开发人员更专注于构建消息的业务内容,UPush使用了自定义分类的方式解决各厂商之间的差异,构建消息通知时指定设置channelId,值由开发者自定义(汉字也可以但不建议),如下表示这是一条即时通信消息,"IM"即为开发者自定义的分类。
UMessageNotification.builder().channelId("IM").build()
- 在服务端配置自定义消息类别与各厂商类别或通道的映射,参照上面“厂商推送配置”实例,格式:category. + 自定义类别名 = 厂商类别或通道ID,例如:华为category.IM=IM,表示此条消息以华为的IM分类进行推送,小米category.IM=123456,表示此条消息小米会以123456的通道ID进行推送,荣耀category.IM=NORMAL,表示此条消息荣耀以重要消息进行推送
其他配置 #
redis.properties #
- redis.conf需要开启AOF,appendonly yes, appendfsync everysec 其他aof配置保持默认即可
# redis地址
redis.host=127.0.0.1
# redis端口
redis.port=6379
# redis密码
redis.password=
# 最大空闲连接数
redis.maxIdle=20
# 最小空闲连接数
redis.minIdle=6
# 最大等待连接时间
redis.maxWaitMillis=10000
# 使用的Db索引
redis.db=2
# 连接超时时间
redis.timeout=10000
# 最大活跃数
redis.maxActive=10
# 自动重连
redis.testOnBorrow=true
redis.testOnReturn=true
log4j.properties #
单机版直接把日志文件输出到本地即可,集群版可以把日志输出到日志服务器,日志服务器范例 (opens new window)
### set log levels ###
log4j.rootLogger=info , stdout , D , E, server
log4j.logger.com.upush=INFO
## console ##
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
#log4j.appender.stdout.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}[%t:%r]-[%p] %m%n
log4j.appender.stdout.layout.ConversionPattern=%X{serverAlias} %-d{yyyy-MM-dd HH:mm:ss,SSS}[%t][%p][%F:%L] %m%n
## log file ##
log4j.appender.D=org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File=./logs/${logFileName}.log
log4j.appender.D.Append=true
log4j.appender.D.Threshold=DEBUG
log4j.appender.D.layout=org.apache.log4j.PatternLayout
#log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}[%t:%r]-[%p] %m%n
log4j.appender.D.layout.ConversionPattern=%X{serverAlias} %-d{yyyy-MM-dd HH:mm:ss,SSS}[%t][%p][%F:%L] %m%n
## error log file ##
log4j.appender.E=org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File=./logs/${logFileName}.log
log4j.appender.E.Append=true
log4j.appender.E.Threshold=ERROR
log4j.appender.E.layout=org.apache.log4j.PatternLayout
#log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}[%t:%r]-[%p] %m%n
log4j.appender.E.layout.ConversionPattern=%X{serverAlias} %-d{yyyy-MM-dd HH:mm:ss,SSS}[%t][%p][%F:%L] %m%n
# 如果使用log4j服务,把注释打开。同时也可以把本地日志文件关闭掉(注释掉上面的)
## server ##
#log4j.appender.server=org.apache.log4j.net.SocketAppender
#log4j.appender.server.Port=4712
#log4j.appender.server.RemoteHost=127.0.0.1
#log4j.appender.server.ReconnectionDelay=10000
多环境配置 #
Windows打开run.bat,Linux、MacOS打开run.sh,下面以Linux为例
# 直接查看run.sh最后,例如:添加-Dactive=devel,环境名devel
... 省略
RUN_CMD="$RUN_CMD -Dfile.encoding=utf8 -Dactive=devel"
...
配置文件目录就变为config/devel
,即原本在config下的所有配置文件都要移动到config/devel