├── .github
└── workflows
│ └── maven.yml
├── .gitignore
├── LICENSE
├── README.md
├── go-push-adapter-sdk
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── .gitignore
│ └── resources
│ │ └── .gitignore
│ └── test
│ └── java
│ └── .gitignore
├── go-push-common
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── gopush
│ │ │ └── common
│ │ │ ├── Constants.java
│ │ │ ├── constants
│ │ │ ├── DeviceMessageEnum.java
│ │ │ ├── HandshakeEnum.java
│ │ │ ├── IdleEnum.java
│ │ │ ├── NodeMessageEnum.java
│ │ │ ├── RedisKeyEnum.java
│ │ │ ├── RestfulRespEnum.java
│ │ │ └── ZkGroupEnum.java
│ │ │ └── utils
│ │ │ ├── ip
│ │ │ └── IpUtils.java
│ │ │ └── zk
│ │ │ ├── ZkUtils.java
│ │ │ └── listener
│ │ │ └── ZkStateListener.java
│ └── resources
│ │ └── .gitignore
│ └── test
│ └── java
│ └── .gitignore
├── go-push-data-center
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── gopush
│ │ │ └── datacenter
│ │ │ ├── DataCenterApplication.java
│ │ │ ├── config
│ │ │ ├── GoPushDataCenterConfig.java
│ │ │ └── ZookeeperConfig.java
│ │ │ ├── dymic
│ │ │ ├── discovery
│ │ │ │ └── NodeServerDiscoveryService.java
│ │ │ └── register
│ │ │ │ └── DataCenterRegisterService.java
│ │ │ ├── infos
│ │ │ └── watchdog
│ │ │ │ ├── DataCenterInfoWatchdog.java
│ │ │ │ └── listener
│ │ │ │ ├── DataCenterInfoDataListener.java
│ │ │ │ └── event
│ │ │ │ └── DataCenterInfoEvent.java
│ │ │ ├── nodes
│ │ │ ├── handlers
│ │ │ │ ├── DeviceDisconnectHandler.java
│ │ │ │ ├── DeviceDockedHandler.java
│ │ │ │ ├── MessageToMultiDeviceHandler.java
│ │ │ │ ├── MultiMessageToDeviceHandler.java
│ │ │ │ ├── NodeInfoHandler.java
│ │ │ │ ├── PingHandler.java
│ │ │ │ └── PongHandler.java
│ │ │ ├── inbound
│ │ │ │ └── NodeChannelInBoundHandler.java
│ │ │ └── manager
│ │ │ │ ├── INode.java
│ │ │ │ ├── Node.java
│ │ │ │ └── NodeManager.java
│ │ │ └── restfuls
│ │ │ ├── aop
│ │ │ └── RestfulLoaderAspect.java
│ │ │ ├── controller
│ │ │ ├── ApisDeviceController.java
│ │ │ └── ApisPushController.java
│ │ │ ├── loader
│ │ │ └── LoaderService.java
│ │ │ └── pojo
│ │ │ ├── BaseResp.java
│ │ │ └── bo
│ │ │ ├── Device.java
│ │ │ └── LoadbanceNode.java
│ └── resources
│ │ ├── application.yml
│ │ └── banner.txt
│ └── test
│ └── java
│ └── .gitignore
├── go-push-handler-device
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── gopush
│ │ │ └── devices
│ │ │ └── handlers
│ │ │ ├── IDeviceDisconnectHandler.java
│ │ │ ├── IDeviceDockedHandler.java
│ │ │ └── IDeviceMessageHandler.java
│ └── resources
│ │ └── .gitignore
│ └── test
│ └── java
│ └── .gitignore
├── go-push-handler-node
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── gopush
│ │ │ └── nodes
│ │ │ └── handlers
│ │ │ └── INodeMessageHandler.java
│ └── resources
│ │ └── .gitignore
│ └── test
│ └── java
│ └── .gitignore
├── go-push-infos
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── gopush
│ │ │ └── infos
│ │ │ ├── datacenter
│ │ │ └── bo
│ │ │ │ ├── DataCenterInfo.java
│ │ │ │ ├── NodeClientLoaderInfo.java
│ │ │ │ └── RestfulLoaderInfo.java
│ │ │ └── nodeserver
│ │ │ └── bo
│ │ │ ├── HandlerInfo.java
│ │ │ ├── NodeLoaderInfo.java
│ │ │ ├── NodeServerInfo.java
│ │ │ └── ProcessorInfo.java
│ └── resources
│ │ └── .gitignore
│ └── test
│ └── java
│ └── .gitignore
├── go-push-monitor
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── gopush
│ │ │ └── monitor
│ │ │ ├── MonitorApplication.java
│ │ │ ├── config
│ │ │ └── ZookeeperConfig.java
│ │ │ ├── controller
│ │ │ ├── MonitorController.java
│ │ │ ├── MonitorDataController.java
│ │ │ └── pojo
│ │ │ │ └── BaseResp.java
│ │ │ └── dymic
│ │ │ └── discovery
│ │ │ ├── MonitorDataCenterService.java
│ │ │ └── MonitorNodeServerService.java
│ └── resources
│ │ ├── application.yml
│ │ ├── banner.txt
│ │ └── templates
│ │ └── monitor.html
│ └── test
│ └── java
│ └── .gitignore
├── go-push-node-server
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── gopush
│ │ │ └── nodeserver
│ │ │ ├── NodeServerApplication.java
│ │ │ ├── config
│ │ │ ├── BatchProcessorConfig.java
│ │ │ ├── GoPushNodeServerConfig.java
│ │ │ └── ZookeeperConfig.java
│ │ │ ├── devices
│ │ │ ├── BatchProcessor.java
│ │ │ ├── DeviceServerBootstrap.java
│ │ │ ├── handlers
│ │ │ │ ├── DeviceDeviceDisconnectHandler.java
│ │ │ │ ├── DeviceDeviceDockedHandler.java
│ │ │ │ ├── DevicePingHandler.java
│ │ │ │ ├── DevicePongHandler.java
│ │ │ │ ├── HandShakeHandler.java
│ │ │ │ ├── PingPongProcessor.java
│ │ │ │ └── PushRespHandler.java
│ │ │ ├── inbound
│ │ │ │ └── DeviceChannelInboundHandler.java
│ │ │ ├── senders
│ │ │ │ ├── IPushSender.java
│ │ │ │ └── PushSender.java
│ │ │ └── stores
│ │ │ │ ├── DeviceChannelStore.java
│ │ │ │ └── IDeviceChannelStore.java
│ │ │ ├── dymic
│ │ │ ├── discovery
│ │ │ │ └── DataCenterDiscoveryService.java
│ │ │ └── register
│ │ │ │ └── NodeServerRegisterService.java
│ │ │ ├── infos
│ │ │ └── watchdog
│ │ │ │ ├── NodeServerInfoWatchdog.java
│ │ │ │ └── listener
│ │ │ │ ├── PostNodeServerInfoDataListener.java
│ │ │ │ └── event
│ │ │ │ └── NodeServerInfoEvent.java
│ │ │ └── nodes
│ │ │ ├── NodeServerBootstrap.java
│ │ │ ├── handlers
│ │ │ ├── MessageToMultiDeviceHandler.java
│ │ │ ├── MultiMessageToDeviceHandler.java
│ │ │ ├── NodeBaseHandler.java
│ │ │ ├── NodeDeviceDisconnectHandler.java
│ │ │ ├── NodeDeviceDockedHandler.java
│ │ │ ├── NodeInfoHandler.java
│ │ │ ├── NodePingHandler.java
│ │ │ └── NodePongHandler.java
│ │ │ ├── inbound
│ │ │ └── NodeChannelInBoundHandler.java
│ │ │ ├── senders
│ │ │ ├── INodeSender.java
│ │ │ └── NodeSender.java
│ │ │ └── stores
│ │ │ ├── DataCenterChannelStore.java
│ │ │ └── IDataCenterChannelStore.java
│ └── resources
│ │ ├── application.yml
│ │ └── banner.txt
│ └── test
│ └── java
│ └── .gitignore
├── go-push-protocol-device
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── gopush
│ │ │ └── protocol
│ │ │ ├── device
│ │ │ ├── DeviceMessage.java
│ │ │ ├── DeviceMessageReq.java
│ │ │ ├── DeviceMessageResp.java
│ │ │ ├── HandShakeReq.java
│ │ │ ├── HandShakeResp.java
│ │ │ ├── Ping.java
│ │ │ ├── Pong.java
│ │ │ ├── PushReq.java
│ │ │ └── PushResp.java
│ │ │ └── exceptions
│ │ │ └── DeviceProtocolException.java
│ └── resources
│ │ └── .gitignore
│ └── test
│ └── java
│ └── .gitignore
├── go-push-protocol-node
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── gopush
│ │ │ └── protocol
│ │ │ ├── exceptions
│ │ │ └── NodeProtocolException.java
│ │ │ └── node
│ │ │ ├── DeviceDisconReq.java
│ │ │ ├── DeviceDisconResp.java
│ │ │ ├── DeviceDockedReq.java
│ │ │ ├── DeviceDockedResp.java
│ │ │ ├── MessageToMultiDeviceReq.java
│ │ │ ├── MessageToMultiDeviceResp.java
│ │ │ ├── MultiMessageToDeviceReq.java
│ │ │ ├── MultiMessageToDeviceResp.java
│ │ │ ├── NodeInfoReq.java
│ │ │ ├── NodeInfoResp.java
│ │ │ ├── NodeMessage.java
│ │ │ ├── NodeMessageReq.java
│ │ │ ├── NodeMessageResp.java
│ │ │ ├── Ping.java
│ │ │ └── Pong.java
│ └── resources
│ │ └── .gitignore
│ └── test
│ └── java
│ └── .gitignore
├── index.html
└── pom.xml
/.github/workflows/maven.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
3 |
4 | name: CI MAVEN
5 | on:
6 | push:
7 | branches: [ master ]
8 | pull_request:
9 | branches: [ master ]
10 |
11 | jobs:
12 | build:
13 |
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/checkout@v2
18 | - name: Set up JDK 11
19 | uses: actions/setup-java@v2
20 | with:
21 | java-version: '11'
22 | distribution: 'adopt'
23 | cache: maven
24 | - name: Build with Maven
25 | run: mvn -B package --file pom.xml
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiler Files #
2 | *.class
3 |
4 | # Package Files #
5 | *.jar
6 | *.war
7 | *.ear
8 |
9 | # IDE Files #
10 | *.iml
11 | .idea/**
12 | *.classpath
13 | *.project
14 | *.settings
15 | target/
16 |
17 | # Zip Files #
18 | *.zip
19 | *.7z
20 | *.rar
21 |
22 | # Installer Files #
23 | *.exe
24 | *.so
25 | *.dll
26 | *.cab
27 |
28 | # Log Temp Files #
29 | *.via
30 | *.tmp
31 | *.err
32 | *.keep
33 |
34 | # Version Temp Files #
35 | *.bak
36 | *.svn
37 | *.git
38 |
39 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## GoPush    
2 |
3 | ## Project Repertories
4 | - [Github](https://github.com/pinkhello/gopush)
5 | - [Gitee](https://gitee.com/openWolf/gopush)
6 |
7 | ## Depends
8 | > `Netty`、`Zookeeper`、`Redis`
9 | > `Java8`、`SpringBoot`
10 |
11 | ## Description
12 | Suitable for customer service, IM, and Iot ......
13 |
14 | [](https://github.com/pinkhello/gopush/stargazers)
15 |
16 |
17 | ## Stargazers over time
18 |
19 | [](https://starchart.cc/pinkhello/gopush)
20 |
21 |
22 | ## Frames
23 | 
24 |
--------------------------------------------------------------------------------
/go-push-adapter-sdk/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | go-push
7 | com.gopush
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | jar
12 | go-push-adapter-sdk
13 |
14 |
15 |
--------------------------------------------------------------------------------
/go-push-adapter-sdk/src/main/java/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkhello/gopush/94bbbb40b2bc20196c0388a2a8482c6cb00909df/go-push-adapter-sdk/src/main/java/.gitignore
--------------------------------------------------------------------------------
/go-push-adapter-sdk/src/main/resources/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkhello/gopush/94bbbb40b2bc20196c0388a2a8482c6cb00909df/go-push-adapter-sdk/src/main/resources/.gitignore
--------------------------------------------------------------------------------
/go-push-adapter-sdk/src/test/java/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkhello/gopush/94bbbb40b2bc20196c0388a2a8482c6cb00909df/go-push-adapter-sdk/src/test/java/.gitignore
--------------------------------------------------------------------------------
/go-push-common/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | go-push
7 | com.gopush
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | com.gopush
13 | jar
14 | go-push-common
15 |
16 |
17 |
18 |
19 | io.netty
20 | netty-all
21 | provided
22 |
23 |
24 | org.projectlombok
25 | lombok
26 |
27 |
28 |
29 | org.apache.curator
30 | curator-recipes
31 |
32 |
33 | org.apache.commons
34 | commons-lang3
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/go-push-common/src/main/java/com/gopush/common/Constants.java:
--------------------------------------------------------------------------------
1 | package com.gopush.common;
2 |
3 |
4 | import io.netty.util.AttributeKey;
5 |
6 | /**
7 | * go-push
8 | *
9 | * @类功能说明:全局常量定义
10 | * @作者:喝咖啡的囊地鼠
11 | * @创建时间:2017/6/18 下午3:02
12 | * @VERSION:
13 | */
14 | public class Constants {
15 |
16 |
17 | /*****
18 | *
19 | * Device 和 NodeServer 之间
20 | *
21 | * ***/
22 | //绑定设备
23 | public static final AttributeKey CHANNEL_ATTR_DEVICE = AttributeKey.newInstance("device");
24 |
25 | //绑定的握手状态
26 | public static final AttributeKey CHANNEL_ATTR_HANDSHAKE = AttributeKey.newInstance("handshake");
27 |
28 | //绑定的心跳间隔 // read ,write, all
29 | public static final AttributeKey CHANNEL_ATTR_IDLE = AttributeKey.newInstance("idle");
30 |
31 | /*****
32 | *
33 | * NodeServer 与 DataCenter 之间
34 | *
35 | * ***/
36 | public static final AttributeKey CHANNEL_ATTR_DATACENTER = AttributeKey.newInstance("datacenter");
37 |
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/go-push-common/src/main/java/com/gopush/common/constants/DeviceMessageEnum.java:
--------------------------------------------------------------------------------
1 | package com.gopush.common.constants;
2 |
3 | /**
4 | * @author 喝咖啡的囊地鼠
5 | * @date 2017/9/14 上午12:14
6 | */
7 | public enum DeviceMessageEnum {
8 | }
9 |
--------------------------------------------------------------------------------
/go-push-common/src/main/java/com/gopush/common/constants/HandshakeEnum.java:
--------------------------------------------------------------------------------
1 | package com.gopush.common.constants;
2 |
3 | import lombok.Getter;
4 |
5 | import java.util.Arrays;
6 |
7 | /**
8 | * @author 喝咖啡的囊地鼠
9 | * @date 2017/9/14 上午12:05
10 | */
11 | @Getter
12 | public enum HandshakeEnum {
13 | HANDSAHKE_OK(200, "握手成功"),
14 | HANDSHAKE_INVALID_DEVICE(300, "非法设备"),
15 | HANDSHAKE_INVALID_TOKEN(301, "非法Token");
16 | private int key;
17 | private String descri;
18 |
19 | HandshakeEnum(int key, String descri) {
20 | this.key = key;
21 | this.descri = descri;
22 | }
23 |
24 | public static HandshakeEnum fromKey(int key) {
25 | if (key <= 0) {
26 | return null;
27 | }
28 | return Arrays.stream(HandshakeEnum.values())
29 | .filter(a -> key == a.getKey())
30 | .findFirst()
31 | .orElse(null);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/go-push-common/src/main/java/com/gopush/common/constants/IdleEnum.java:
--------------------------------------------------------------------------------
1 | package com.gopush.common.constants;
2 |
3 | import lombok.Getter;
4 |
5 | import java.util.Arrays;
6 |
7 | /**
8 | * go-push
9 | *
10 | * @author:喝咖啡的囊地鼠
11 | * @date:2017/7/10 下午11:38
12 | */
13 | @Getter
14 | public enum IdleEnum {
15 | READ_IDLE(10),
16 | WRITE_IDLE(30),
17 | ALL_IDLE(50);
18 | private int value;
19 |
20 | IdleEnum(int value) {
21 | this.value = value;
22 | }
23 |
24 | public static IdleEnum fromValue(int value) {
25 | if (value <= 0) {
26 | return null;
27 | }
28 | return Arrays.stream(IdleEnum.values())
29 | .filter(a -> value == a.getValue())
30 | .findFirst()
31 | .orElse(null);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/go-push-common/src/main/java/com/gopush/common/constants/NodeMessageEnum.java:
--------------------------------------------------------------------------------
1 | package com.gopush.common.constants;
2 |
3 |
4 | import lombok.Getter;
5 |
6 | import java.util.Arrays;
7 |
8 | /**
9 | * @author 喝咖啡的囊地鼠
10 | * @date 2017/9/14 上午12:13
11 | */
12 | @Getter
13 | public enum NodeMessageEnum {
14 |
15 | OK(200, "OK"),
16 | FAIL(500, "FAIL");
17 |
18 |
19 | private int code;
20 | private String descri;
21 |
22 | NodeMessageEnum(int code, String descri) {
23 | this.code = code;
24 | this.descri = descri;
25 | }
26 |
27 | public static NodeMessageEnum fromCode(int code) {
28 | if (code <= 0) {
29 | return null;
30 | }
31 | return Arrays.stream(NodeMessageEnum.values())
32 | .filter(a -> code == a.getCode())
33 | .findFirst()
34 | .orElse(null);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/go-push-common/src/main/java/com/gopush/common/constants/RedisKeyEnum.java:
--------------------------------------------------------------------------------
1 | package com.gopush.common.constants;
2 |
3 | import lombok.Getter;
4 |
5 | import java.util.Arrays;
6 |
7 | /**
8 | * go-push
9 | *
10 | * @author:喝咖啡的囊地鼠
11 | * @date:2017/7/11 上午12:14
12 | */
13 | @Getter
14 | public enum RedisKeyEnum {
15 |
16 | DEVICE_KEY("DE:"),
17 | DEIVCE_TOKEN_FIELD("token"),
18 | DEVICE_NODE_FIELD("node"),
19 | DEVICE_CHANNEL_FIELD("channel");
20 |
21 | private String value;
22 |
23 | RedisKeyEnum(String value) {
24 | this.value = value;
25 | }
26 |
27 | public static IdleEnum fromValue(String value) {
28 | if (value == null || value.isEmpty()) {
29 | return null;
30 | }
31 | return Arrays.stream(IdleEnum.values())
32 | .filter(a -> value.equals(a.getValue()))
33 | .findFirst()
34 | .orElse(null);
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/go-push-common/src/main/java/com/gopush/common/constants/RestfulRespEnum.java:
--------------------------------------------------------------------------------
1 | package com.gopush.common.constants;
2 |
3 | import lombok.Getter;
4 |
5 | import java.util.Arrays;
6 |
7 | /**
8 | * @author 喝咖啡的囊地鼠
9 | * @date 2017/9/14 下午5:31
10 | */
11 | @Getter
12 | public enum RestfulRespEnum {
13 |
14 | OK(0, "成功");
15 |
16 | private int key;
17 | private String descri;
18 |
19 | RestfulRespEnum(int key, String descri) {
20 | this.key = key;
21 | this.descri = descri;
22 | }
23 |
24 |
25 | public static RestfulRespEnum fromKey(int key) {
26 | if (key <= 0) {
27 | return null;
28 | }
29 | return Arrays.stream(RestfulRespEnum.values())
30 | .filter(a -> key == a.getKey())
31 | .findFirst()
32 | .orElse(null);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/go-push-common/src/main/java/com/gopush/common/constants/ZkGroupEnum.java:
--------------------------------------------------------------------------------
1 | package com.gopush.common.constants;
2 |
3 | import lombok.Getter;
4 |
5 | import java.util.Arrays;
6 |
7 | /**
8 | * @author 喝咖啡的囊地鼠
9 | * @date 2017/9/12 上午3:16
10 | */
11 | @Getter
12 | public enum ZkGroupEnum {
13 | NODE_SERVER("/NODE-SERVER"),
14 | DATA_CENTER("/DATA-CENTER");
15 | private String value;
16 |
17 | ZkGroupEnum(String value) {
18 | this.value = value;
19 | }
20 |
21 | public static IdleEnum fromValue(String value) {
22 | if (value == null || value.isEmpty()) {
23 | return null;
24 | }
25 | return Arrays.stream(IdleEnum.values())
26 | .filter(a -> value.equals(a.getValue()))
27 | .findFirst()
28 | .orElse(null);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/go-push-common/src/main/java/com/gopush/common/utils/ip/IpUtils.java:
--------------------------------------------------------------------------------
1 | package com.gopush.common.utils.ip;
2 |
3 | import java.net.Inet4Address;
4 | import java.net.InetAddress;
5 | import java.net.NetworkInterface;
6 | import java.util.Enumeration;
7 |
8 | /**
9 | * go-push
10 | *
11 | * @类功能说明:Ip工具类
12 | * @作者:喝咖啡的囊地鼠
13 | * @创建时间:2017/6/24 上午11:23
14 | * @VERSION:
15 | */
16 | public class IpUtils {
17 |
18 | /***
19 | * 获取外网IP
20 | * @return
21 | */
22 | public static String internetIp() {
23 | try {
24 |
25 | Enumeration networks = NetworkInterface.getNetworkInterfaces();
26 | InetAddress inetAddress = null;
27 | Enumeration inetAddresses = null;
28 | while (networks.hasMoreElements()) {
29 | inetAddresses = networks.nextElement().getInetAddresses();
30 | while (inetAddresses.hasMoreElements()) {
31 | inetAddress = inetAddresses.nextElement();
32 | if (inetAddress != null
33 | && inetAddress instanceof Inet4Address
34 | && !inetAddress.isSiteLocalAddress()
35 | && !inetAddress.isLoopbackAddress()
36 | && inetAddress.getHostAddress().indexOf(":") == -1) {
37 | return inetAddress.getHostAddress();
38 | }
39 | }
40 | }
41 |
42 | return null;
43 |
44 | } catch (Exception e) {
45 |
46 | throw new RuntimeException(e);
47 | }
48 | }
49 |
50 | /**
51 | * 获取内网IP
52 | *
53 | * @return
54 | */
55 | public static String intranetIp() {
56 | try {
57 | return InetAddress.getLocalHost().getHostAddress();
58 | } catch (Exception e) {
59 | throw new RuntimeException(e);
60 | }
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/go-push-common/src/main/java/com/gopush/common/utils/zk/listener/ZkStateListener.java:
--------------------------------------------------------------------------------
1 | package com.gopush.common.utils.zk.listener;
2 |
3 | import org.apache.curator.framework.CuratorFramework;
4 | import org.apache.curator.framework.state.ConnectionState;
5 |
6 | /**
7 | * @author 喝咖啡的囊地鼠
8 | * @date 2017/9/11 下午8:58
9 | */
10 | public interface ZkStateListener {
11 |
12 | default void connectedEvent(CuratorFramework curator, ConnectionState state) {
13 | }
14 |
15 | default void reconnectedEvent(CuratorFramework curator, ConnectionState state) {
16 | }
17 |
18 | default void lostEvent(CuratorFramework curator, ConnectionState state) {
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/go-push-common/src/main/resources/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkhello/gopush/94bbbb40b2bc20196c0388a2a8482c6cb00909df/go-push-common/src/main/resources/.gitignore
--------------------------------------------------------------------------------
/go-push-common/src/test/java/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkhello/gopush/94bbbb40b2bc20196c0388a2a8482c6cb00909df/go-push-common/src/test/java/.gitignore
--------------------------------------------------------------------------------
/go-push-data-center/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | go-push
7 | com.gopush
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | go-push-data-center
13 | jar
14 |
15 | DataCenter 服务
16 |
17 |
18 |
19 |
20 | com.gopush
21 | go-push-common
22 | ${project.version}
23 |
24 |
25 | com.gopush
26 | go-push-infos
27 | ${project.version}
28 |
29 |
30 | com.gopush
31 | go-push-protocol-node
32 | ${project.version}
33 |
34 |
35 |
36 | com.gopush
37 | go-push-handler-node
38 | ${project.version}
39 |
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-web
44 |
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-starter-aop
49 |
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-starter-data-redis
54 |
55 |
56 |
57 | com.didispace
58 | spring-boot-starter-swagger
59 |
60 |
61 |
62 | org.projectlombok
63 | lombok
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/DataCenterApplication.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter;
2 |
3 | import com.didispace.swagger.EnableSwagger2Doc;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.scheduling.annotation.EnableAsync;
7 |
8 | /**
9 | * go-push
10 | *
11 | * @类功能说明:
12 | * @作者:喝咖啡的囊地鼠
13 | * @创建时间:2017/6/11 下午1:28
14 | * @VERSION:
15 | */
16 | @EnableSwagger2Doc
17 | @EnableAsync
18 | @SpringBootApplication
19 | public class DataCenterApplication {
20 |
21 | public static void main(String[] args) {
22 | SpringApplication.run(DataCenterApplication.class, args);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/config/GoPushDataCenterConfig.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.config;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.context.annotation.Configuration;
6 |
7 | /**
8 | * go-push
9 | *
10 | * @类功能说明:
11 | * @作者:喝咖啡的囊地鼠
12 | * @创建时间:2017/6/21 下午1:28
13 | * @VERSION:
14 | */
15 | @Configuration
16 | @ConfigurationProperties(prefix = "go-push.data-center")
17 | @Data
18 | public class GoPushDataCenterConfig {
19 | private String name;
20 | }
21 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/config/ZookeeperConfig.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.config;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.context.annotation.Configuration;
6 |
7 | /**
8 | * @author 喝咖啡的囊地鼠
9 | * @date 2017/9/11 下午11:44
10 | */
11 | @Data
12 | @Configuration
13 | @ConfigurationProperties(prefix = "go-push.zookeeper")
14 | public class ZookeeperConfig {
15 |
16 | private String servers;
17 |
18 | private String namespace;
19 |
20 | private String listenNamespace;
21 |
22 | private int sessionTimeout;
23 |
24 | private int connectionTimeout;
25 |
26 | private int maxRetries;
27 |
28 | private int retriesSleepTime;
29 | }
30 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/dymic/discovery/NodeServerDiscoveryService.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.dymic.discovery;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.gopush.common.constants.ZkGroupEnum;
5 | import com.gopush.common.utils.zk.ZkUtils;
6 | import com.gopush.common.utils.zk.listener.ZkStateListener;
7 | import com.gopush.datacenter.config.ZookeeperConfig;
8 | import com.gopush.datacenter.nodes.manager.NodeManager;
9 | import com.gopush.infos.nodeserver.bo.NodeServerInfo;
10 | import lombok.extern.slf4j.Slf4j;
11 | import org.apache.curator.framework.CuratorFramework;
12 | import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
13 | import org.apache.curator.framework.state.ConnectionState;
14 | import org.springframework.beans.factory.annotation.Autowired;
15 | import org.springframework.stereotype.Component;
16 |
17 | import javax.annotation.PostConstruct;
18 | import javax.annotation.PreDestroy;
19 | import java.util.HashMap;
20 | import java.util.Map;
21 | import java.util.concurrent.ConcurrentHashMap;
22 |
23 | /**
24 | * @author 喝咖啡的囊地鼠
25 | * @date 2017/9/12 上午3:13
26 | */
27 |
28 | @Slf4j
29 | @Component
30 | public class NodeServerDiscoveryService {
31 |
32 | /**
33 | * 缓存的本地服务列表
34 | */
35 | private Map nodeServerPool = new ConcurrentHashMap<>();
36 |
37 | @Autowired
38 | private ZookeeperConfig zookeeperConfig;
39 |
40 | @Autowired
41 | private NodeManager nodeManager;
42 |
43 |
44 | private ZkUtils zkUtils;
45 |
46 | @PostConstruct
47 | public void init() {
48 | zkUtils = new ZkUtils();
49 | zkUtils.init(
50 | zookeeperConfig.getServers(),
51 | zookeeperConfig.getConnectionTimeout(),
52 | zookeeperConfig.getSessionTimeout(),
53 | zookeeperConfig.getMaxRetries(),
54 | zookeeperConfig.getRetriesSleepTime(),
55 | zookeeperConfig.getListenNamespace(),
56 | new ZkStateListener() {
57 | @Override
58 | public void connectedEvent(CuratorFramework curator, ConnectionState state) {
59 | log.info("NodeServerDiscovery 链接zk成功");
60 | initNodeServerDiscovery();
61 |
62 | }
63 |
64 | @Override
65 | public void reconnectedEvent(CuratorFramework curator, ConnectionState state) {
66 | log.info("NodeServerDiscovery 重新链接zk成功");
67 | initNodeServerDiscovery();
68 | }
69 |
70 | @Override
71 | public void lostEvent(CuratorFramework curator, ConnectionState state) {
72 | log.info("NodeServerDiscovery 链接zk丢失");
73 | nodeServerPool.clear();
74 | nodeManager.clear();
75 | }
76 | });
77 |
78 | listenNodeServerDiscovery();
79 | }
80 |
81 | @PreDestroy
82 | public void destory() {
83 | nodeServerPool.clear();
84 | zkUtils.destory();
85 | }
86 |
87 | /**
88 | * 获取当前现在的Node -Server 服务列表
89 | *
90 | * @return
91 | */
92 | public Map nodeServerPool() {
93 | return new HashMap<>(nodeServerPool);
94 | }
95 |
96 | /**
97 | * 初始化node-server列表
98 | */
99 | private void initNodeServerDiscovery() {
100 | nodeServerPool.clear();
101 | Map datas = zkUtils.readTargetChildsData(ZkGroupEnum.NODE_SERVER.getValue());
102 | if (datas != null) {
103 | datas.forEach((k, v) -> nodeServerPool.put(k, JSON.parseObject(v, NodeServerInfo.class)));
104 | }
105 | nodeServerPool().forEach((k, v) -> nodeManager.put(k, v.getIntranetIp(), v.getNodePort(), v.getInternetIp(), v.getDevicePort()));
106 |
107 | }
108 |
109 | /**
110 | * 设置监听发生更新,更新缓存数据,发生新增,删除,更新
111 | */
112 | private void listenNodeServerDiscovery() {
113 | zkUtils.listenerPathChildrenCache(ZkGroupEnum.NODE_SERVER.getValue(), ((client, event) -> {
114 | switch (event.getType()) {
115 | case CHILD_ADDED:
116 | addEvent(event);
117 | break;
118 | case CHILD_REMOVED:
119 | removeEvent(event);
120 | break;
121 | case CHILD_UPDATED:
122 | updateEvent(event);
123 | break;
124 | default:
125 | break;
126 | }
127 | }));
128 | }
129 |
130 | private void updateEvent(PathChildrenCacheEvent event) {
131 | String key = toKey(event);
132 | NodeServerInfo data = toNodeServerInfo(event);
133 | log.debug("node event update! key:{}, data:{}", key, data);
134 | //只需要更新缓存数据就可以了
135 | if (nodeServerPool.containsKey(key)) {
136 | nodeServerPool.put(key, data);
137 | }
138 | }
139 |
140 | private void removeEvent(PathChildrenCacheEvent event) {
141 | String key = toKey(event);
142 | NodeServerInfo data = toNodeServerInfo(event);
143 | log.info("node event remove! key:{}, data:{}", key, data);
144 | if (nodeServerPool.containsKey(key)) {
145 | //检测Node是否还存在,存在的话移除该Node
146 | nodeManager.remove(key);
147 | nodeServerPool.remove(key);
148 | }
149 |
150 | }
151 |
152 | private void addEvent(PathChildrenCacheEvent event) {
153 | String key = toKey(event);
154 | NodeServerInfo data = toNodeServerInfo(event);
155 | log.info("node event add! key:{}, data:{}", key, data);
156 | if (!nodeServerPool.containsKey(key)) {
157 | //开启node,加入到管理器
158 | nodeManager.put(key, data.getIntranetIp(), data.getNodePort(), data.getInternetIp(), data.getDevicePort());
159 | nodeServerPool.put(key, data);
160 | } else {
161 | log.error("node already! {},{}", key, data);
162 | }
163 | }
164 |
165 |
166 | private String toKey(PathChildrenCacheEvent event) {
167 | String path = event.getData().getPath();
168 | return path.substring(path.lastIndexOf("/")).replaceAll("/", "");
169 | }
170 |
171 | private NodeServerInfo toNodeServerInfo(PathChildrenCacheEvent event) {
172 | return JSON.parseObject(event.getData().getData(), NodeServerInfo.class);
173 | }
174 |
175 | }
176 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/dymic/register/DataCenterRegisterService.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.dymic.register;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.gopush.common.constants.ZkGroupEnum;
5 | import com.gopush.common.utils.zk.ZkUtils;
6 | import com.gopush.common.utils.zk.listener.ZkStateListener;
7 | import com.gopush.datacenter.config.GoPushDataCenterConfig;
8 | import com.gopush.datacenter.config.ZookeeperConfig;
9 | import com.gopush.datacenter.infos.watchdog.DataCenterInfoWatchdog;
10 | import com.gopush.infos.datacenter.bo.DataCenterInfo;
11 | import lombok.extern.slf4j.Slf4j;
12 | import org.apache.curator.framework.CuratorFramework;
13 | import org.apache.curator.framework.state.ConnectionState;
14 | import org.apache.curator.utils.ZKPaths;
15 | import org.apache.zookeeper.CreateMode;
16 | import org.springframework.beans.factory.annotation.Autowired;
17 | import org.springframework.stereotype.Component;
18 |
19 | import javax.annotation.PostConstruct;
20 | import javax.annotation.PreDestroy;
21 |
22 | /**
23 | * @author 喝咖啡的囊地鼠
24 | * @date 2017/9/12 下午2:20
25 | */
26 |
27 | @Slf4j
28 | @Component
29 | public class DataCenterRegisterService {
30 |
31 | @Autowired
32 | private ZookeeperConfig zookeeperConfig;
33 |
34 | @Autowired
35 | private GoPushDataCenterConfig goPushDataCenterConfig;
36 |
37 | @Autowired
38 | private DataCenterInfoWatchdog watchdog;
39 |
40 | private ZkUtils zkUtils;
41 |
42 | @PostConstruct
43 | public void init() {
44 | zkUtils = new ZkUtils();
45 | zkUtils.init(
46 | zookeeperConfig.getServers(),
47 | zookeeperConfig.getConnectionTimeout(),
48 | zookeeperConfig.getSessionTimeout(),
49 | zookeeperConfig.getMaxRetries(),
50 | zookeeperConfig.getRetriesSleepTime(),
51 | zookeeperConfig.getNamespace(),
52 | new ZkStateListener() {
53 | @Override
54 | public void connectedEvent(CuratorFramework curator, ConnectionState state) {
55 | log.info("DataCenterRegister 链接zk成功");
56 | registerDataCenter();
57 |
58 | }
59 |
60 | @Override
61 | public void reconnectedEvent(CuratorFramework curator, ConnectionState state) {
62 | log.info("DataCenterRegister 重新链接zk成功");
63 | registerDataCenter();
64 | }
65 |
66 | @Override
67 | public void lostEvent(CuratorFramework curator, ConnectionState state) {
68 | log.info("DataCenterRegister 链接zk丢失");
69 | }
70 | });
71 |
72 |
73 | }
74 |
75 | @PreDestroy
76 | public void destory() {
77 | zkUtils.destory();
78 | }
79 |
80 |
81 | public void postNewData(DataCenterInfo data) {
82 | zkUtils.setNodeData(
83 | ZKPaths.makePath(ZkGroupEnum.DATA_CENTER.getValue(), goPushDataCenterConfig.getName()),
84 | JSON.toJSONString(data));
85 | }
86 |
87 | /**
88 | * 注册datacenter服务
89 | */
90 | private void registerDataCenter() {
91 |
92 | if (!zkUtils.checkExists(ZkGroupEnum.DATA_CENTER.getValue())) {
93 | boolean flag;
94 | do {
95 | flag = zkUtils.createNode(ZkGroupEnum.DATA_CENTER.getValue(), null, CreateMode.PERSISTENT);
96 | } while (!flag);
97 | }
98 | registerDataCenterInfo();
99 | }
100 |
101 | private void registerDataCenterInfo() {
102 | zkUtils.createNode(
103 | ZKPaths.makePath(ZkGroupEnum.DATA_CENTER.getValue(), goPushDataCenterConfig.getName()),
104 | JSON.toJSONString(watchdog.watch()),
105 | CreateMode.EPHEMERAL);
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/infos/watchdog/DataCenterInfoWatchdog.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.infos.watchdog;
2 |
3 | import com.gopush.common.utils.ip.IpUtils;
4 | import com.gopush.datacenter.config.GoPushDataCenterConfig;
5 | import com.gopush.datacenter.infos.watchdog.listener.event.DataCenterInfoEvent;
6 | import com.gopush.datacenter.nodes.manager.NodeManager;
7 | import com.gopush.datacenter.restfuls.loader.LoaderService;
8 | import com.gopush.infos.datacenter.bo.DataCenterInfo;
9 | import lombok.Setter;
10 | import lombok.extern.slf4j.Slf4j;
11 | import org.apache.commons.lang3.concurrent.BasicThreadFactory;
12 | import org.springframework.beans.factory.annotation.Autowired;
13 | import org.springframework.context.ApplicationEventPublisher;
14 | import org.springframework.stereotype.Component;
15 | import org.springframework.util.StringUtils;
16 |
17 | import javax.annotation.PostConstruct;
18 | import java.util.concurrent.ScheduledExecutorService;
19 | import java.util.concurrent.ScheduledThreadPoolExecutor;
20 | import java.util.concurrent.TimeUnit;
21 |
22 | /**
23 | * @author 喝咖啡的囊地鼠
24 | * @date 2017/9/15 上午8:28
25 | */
26 |
27 | @Slf4j
28 | @Component
29 | public class DataCenterInfoWatchdog {
30 |
31 | @Autowired
32 | private GoPushDataCenterConfig goPushDataCenterConfig;
33 |
34 | @Autowired
35 | private ApplicationEventPublisher applicationEventPublisher;
36 |
37 | @Autowired
38 | private NodeManager nodeManager;
39 |
40 | @Autowired
41 | private LoaderService loaderService;
42 |
43 | @Setter
44 | private int delay = 5000;
45 |
46 | private ScheduledExecutorService scheduledExecutorService;
47 |
48 | @PostConstruct
49 | public void init() {
50 | scheduledExecutorService = new ScheduledThreadPoolExecutor(1,
51 | new BasicThreadFactory.Builder().namingPattern("SendDataCenterInfo-schedule-pool-%d").daemon(true).build());
52 | scheduledExecutorService.scheduleAtFixedRate(() -> applicationEventPublisher.publishEvent(DataCenterInfoEvent.builder()
53 | .name(goPushDataCenterConfig.getName())
54 | .dataCenterInfo(watch())
55 | .build()), delay, delay, TimeUnit.MILLISECONDS);
56 | }
57 |
58 |
59 | /**
60 | * 获取系统负载信息
61 | *
62 | * @return
63 | */
64 | public DataCenterInfo watch() {
65 |
66 |
67 | String internetIp = IpUtils.internetIp();
68 | String intranetIp = IpUtils.intranetIp();
69 |
70 | return DataCenterInfo.builder()
71 | .name(goPushDataCenterConfig.getName())
72 | .internetIp(StringUtils.isEmpty(internetIp) ? intranetIp : internetIp)
73 | .intranetIp(intranetIp)
74 | .nodeClientLoaderInfos(nodeManager.loaders())
75 | .restfulLoaderInfos(loaderService.restfulLoader())
76 | .build();
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/infos/watchdog/listener/DataCenterInfoDataListener.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.infos.watchdog.listener;
2 |
3 | import com.gopush.datacenter.dymic.register.DataCenterRegisterService;
4 | import com.gopush.datacenter.infos.watchdog.listener.event.DataCenterInfoEvent;
5 | import lombok.extern.slf4j.Slf4j;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.context.event.EventListener;
8 | import org.springframework.scheduling.annotation.Async;
9 | import org.springframework.stereotype.Component;
10 |
11 | /**
12 | * @author 喝咖啡的囊地鼠
13 | * @date 2017/9/15 上午8:39
14 | */
15 | @Slf4j
16 | @Component
17 | public class DataCenterInfoDataListener {
18 | @Autowired
19 | private DataCenterRegisterService dataCenterRegisterService;
20 |
21 | @Async
22 | @EventListener(condition = "#event.dataCenterInfo != null")
23 | public void postDataToZk(DataCenterInfoEvent event) {
24 | dataCenterRegisterService.postNewData(event.getDataCenterInfo());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/infos/watchdog/listener/event/DataCenterInfoEvent.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.infos.watchdog.listener.event;
2 |
3 | import com.gopush.infos.datacenter.bo.DataCenterInfo;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | /**
10 | * @author 喝咖啡的囊地鼠
11 | * @date 2017/9/15 上午8:42
12 | */
13 | @Data
14 | @Builder
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | public class DataCenterInfoEvent {
18 | private String name;
19 | private DataCenterInfo dataCenterInfo;
20 | }
21 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/nodes/handlers/DeviceDisconnectHandler.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.nodes.handlers;
2 |
3 | import com.gopush.common.constants.NodeMessageEnum;
4 | import com.gopush.nodes.handlers.INodeMessageHandler;
5 | import com.gopush.protocol.node.DeviceDisconReq;
6 | import com.gopush.protocol.node.DeviceDisconResp;
7 | import com.gopush.protocol.node.NodeMessage;
8 | import io.netty.channel.Channel;
9 | import io.netty.channel.ChannelHandlerContext;
10 | import lombok.extern.slf4j.Slf4j;
11 | import org.springframework.stereotype.Component;
12 |
13 | /**
14 | * go-push
15 | *
16 | * @类功能说明:
17 | * @作者:喝咖啡的囊地鼠
18 | * @创建时间:2017/6/21 下午11:03
19 | * @VERSION:
20 | */
21 |
22 | @Slf4j
23 | @Component
24 | public class DeviceDisconnectHandler implements INodeMessageHandler {
25 |
26 | @Override
27 | public boolean support(NodeMessage message) {
28 | return message instanceof DeviceDisconReq;
29 | }
30 |
31 | @Override
32 | public void call(ChannelHandlerContext ctx, DeviceDisconReq message) {
33 | Channel channel = ctx.channel();
34 | channel.writeAndFlush(DeviceDisconResp.builder().result(NodeMessageEnum.OK.getCode()).build().encode());
35 | log.debug("receive DeviceDisconReq, channel:{}", channel);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/nodes/handlers/DeviceDockedHandler.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.nodes.handlers;
2 |
3 | import com.gopush.common.constants.NodeMessageEnum;
4 | import com.gopush.nodes.handlers.INodeMessageHandler;
5 | import com.gopush.protocol.node.DeviceDockedReq;
6 | import com.gopush.protocol.node.DeviceDockedResp;
7 | import com.gopush.protocol.node.NodeMessage;
8 | import io.netty.channel.Channel;
9 | import io.netty.channel.ChannelHandlerContext;
10 | import lombok.extern.slf4j.Slf4j;
11 | import org.springframework.stereotype.Component;
12 |
13 | /**
14 | * go-push
15 | *
16 | * @类功能说明:
17 | * @作者:喝咖啡的囊地鼠
18 | * @创建时间:2017/6/21 下午11:05
19 | * @VERSION:
20 | */
21 |
22 | @Slf4j
23 | @Component
24 | public class DeviceDockedHandler implements INodeMessageHandler {
25 | @Override
26 | public boolean support(NodeMessage message) {
27 | return message instanceof DeviceDockedReq;
28 | }
29 |
30 | @Override
31 | public void call(ChannelHandlerContext ctx, DeviceDockedReq message) {
32 | Channel channel = ctx.channel();
33 | channel.writeAndFlush(DeviceDockedResp.builder().result(NodeMessageEnum.OK.getCode()).build().encode());
34 | log.debug("receive DeviceDockedReq, channel:{}", channel);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/nodes/handlers/MessageToMultiDeviceHandler.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.nodes.handlers;
2 |
3 | import com.gopush.nodes.handlers.INodeMessageHandler;
4 | import com.gopush.protocol.node.MessageToMultiDeviceResp;
5 | import com.gopush.protocol.node.NodeMessage;
6 | import io.netty.channel.Channel;
7 | import io.netty.channel.ChannelHandlerContext;
8 | import lombok.extern.slf4j.Slf4j;
9 | import org.springframework.stereotype.Component;
10 |
11 | /**
12 | * go-push
13 | *
14 | * @类功能说明:
15 | * @作者:喝咖啡的囊地鼠
16 | * @创建时间:2017/6/21 下午11:07
17 | * @VERSION:
18 | */
19 |
20 | @Slf4j
21 | @Component
22 | public class MessageToMultiDeviceHandler implements INodeMessageHandler {
23 | @Override
24 | public boolean support(NodeMessage message) {
25 | return message instanceof MessageToMultiDeviceResp;
26 | }
27 |
28 | @Override
29 | public void call(ChannelHandlerContext ctx, MessageToMultiDeviceResp message) {
30 | Channel channel = ctx.channel();
31 |
32 |
33 | log.debug("receive MessageToMultiDeviceResp, channel:{}", channel);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/nodes/handlers/MultiMessageToDeviceHandler.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.nodes.handlers;
2 |
3 | import com.gopush.nodes.handlers.INodeMessageHandler;
4 | import com.gopush.protocol.node.MultiMessageToDeviceResp;
5 | import com.gopush.protocol.node.NodeMessage;
6 | import io.netty.channel.Channel;
7 | import io.netty.channel.ChannelHandlerContext;
8 | import lombok.extern.slf4j.Slf4j;
9 | import org.springframework.stereotype.Component;
10 |
11 | /**
12 | * go-push
13 | *
14 | * @类功能说明:
15 | * @作者:喝咖啡的囊地鼠
16 | * @创建时间:2017/6/21 下午11:06
17 | * @VERSION:
18 | */
19 |
20 | @Slf4j
21 | @Component
22 | public class MultiMessageToDeviceHandler implements INodeMessageHandler {
23 | @Override
24 | public boolean support(NodeMessage message) {
25 | return message instanceof MultiMessageToDeviceResp;
26 | }
27 |
28 | @Override
29 | public void call(ChannelHandlerContext ctx, MultiMessageToDeviceResp message) {
30 | Channel channel = ctx.channel();
31 |
32 | log.debug("receive MessageToMultiDeviceResp, channel:{}", channel);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/nodes/handlers/NodeInfoHandler.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.nodes.handlers;
2 |
3 | import com.gopush.common.constants.NodeMessageEnum;
4 | import com.gopush.nodes.handlers.INodeMessageHandler;
5 | import com.gopush.protocol.node.NodeInfoReq;
6 | import com.gopush.protocol.node.NodeInfoResp;
7 | import com.gopush.protocol.node.NodeMessage;
8 | import io.netty.channel.Channel;
9 | import io.netty.channel.ChannelHandlerContext;
10 | import lombok.extern.slf4j.Slf4j;
11 | import org.springframework.stereotype.Component;
12 |
13 | /**
14 | * go-push
15 | *
16 | * @类功能说明:
17 | * @作者:喝咖啡的囊地鼠
18 | * @创建时间:2017/6/21 下午11:09
19 | * @VERSION:
20 | */
21 |
22 | @Slf4j
23 | @Component
24 | public class NodeInfoHandler implements INodeMessageHandler {
25 | @Override
26 | public boolean support(NodeMessage message) {
27 |
28 | return message instanceof NodeInfoReq;
29 | }
30 |
31 | @Override
32 | public void call(ChannelHandlerContext ctx, NodeInfoReq message) {
33 | Channel channel = ctx.channel();
34 | channel.writeAndFlush(NodeInfoResp.builder().result(NodeMessageEnum.OK.getCode()).build().encode());
35 | log.debug("receive nodeInfoReq,channel:{}", channel);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/nodes/handlers/PingHandler.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.nodes.handlers;
2 |
3 | import com.gopush.nodes.handlers.INodeMessageHandler;
4 | import com.gopush.protocol.node.NodeMessage;
5 | import com.gopush.protocol.node.Ping;
6 | import com.gopush.protocol.node.Pong;
7 | import io.netty.channel.Channel;
8 | import io.netty.channel.ChannelHandlerContext;
9 | import lombok.extern.slf4j.Slf4j;
10 | import org.springframework.stereotype.Component;
11 |
12 |
13 | /**
14 | * go-push
15 | *
16 | * @类功能说明:
17 | * @作者:喝咖啡的囊地鼠
18 | * @创建时间:2017/6/21
19 | * @VERSION:
20 | */
21 | @Slf4j
22 | @Component
23 | public class PingHandler implements INodeMessageHandler {
24 |
25 | private static final String PONG = Pong.builder().build().encode();
26 |
27 | @Override
28 | public boolean support(NodeMessage message) {
29 | return message instanceof Ping;
30 | }
31 |
32 | @Override
33 | public void call(ChannelHandlerContext ctx, Ping message) {
34 | Channel channel = ctx.channel();
35 | channel.writeAndFlush(PONG);
36 | log.debug("receive ping,channel:{}", channel);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/nodes/handlers/PongHandler.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.nodes.handlers;
2 |
3 | import com.gopush.nodes.handlers.INodeMessageHandler;
4 | import com.gopush.protocol.node.NodeMessage;
5 | import com.gopush.protocol.node.Pong;
6 | import io.netty.channel.Channel;
7 | import io.netty.channel.ChannelHandlerContext;
8 | import lombok.extern.slf4j.Slf4j;
9 | import org.springframework.stereotype.Component;
10 |
11 |
12 | /**
13 | * go-push
14 | *
15 | * @类功能说明:
16 | * @作者:喝咖啡的囊地鼠
17 | * @创建时间:2017/6/21
18 | * @VERSION:
19 | */
20 |
21 | @Slf4j
22 | @Component
23 | public class PongHandler implements INodeMessageHandler {
24 | @Override
25 | public boolean support(NodeMessage message) {
26 | return message instanceof Pong;
27 | }
28 |
29 | @Override
30 | public void call(ChannelHandlerContext ctx, Pong message) {
31 | Channel channel = ctx.channel();
32 |
33 |
34 | log.debug("receive pong! channel:{}", channel);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/nodes/inbound/NodeChannelInBoundHandler.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.nodes.inbound;
2 |
3 | import com.gopush.datacenter.nodes.manager.Node;
4 | import com.gopush.protocol.node.NodeMessage;
5 | import com.gopush.protocol.node.Ping;
6 | import com.gopush.protocol.node.Pong;
7 | import io.netty.channel.Channel;
8 | import io.netty.channel.ChannelHandler;
9 | import io.netty.channel.ChannelHandlerContext;
10 | import io.netty.channel.SimpleChannelInboundHandler;
11 | import io.netty.handler.timeout.IdleState;
12 | import io.netty.handler.timeout.IdleStateEvent;
13 | import lombok.Data;
14 | import lombok.extern.slf4j.Slf4j;
15 |
16 | /**
17 | * go-push
18 | *
19 | * @类功能说明:
20 | * @作者:喝咖啡的囊地鼠
21 | * @创建时间:2017/6/24 上午12:23
22 | * @VERSION:
23 | */
24 |
25 | @Slf4j
26 | @Data
27 | @ChannelHandler.Sharable
28 | public class NodeChannelInBoundHandler extends SimpleChannelInboundHandler {
29 |
30 | private static String PING = Ping.builder().build().encode();
31 |
32 | /**
33 | * 对应的Node节点
34 | */
35 | private Node node;
36 |
37 | public NodeChannelInBoundHandler(Node node) {
38 | this.node = node;
39 | }
40 |
41 |
42 | @Override
43 | public void channelActive(ChannelHandlerContext ctx) throws Exception {
44 | log.debug("channel active, channel:{}", ctx.channel());
45 | node.active();
46 | //有发送失败的补发
47 | node.retrySendFail();
48 | }
49 |
50 | @Override
51 | public void channelInactive(ChannelHandlerContext ctx) throws Exception {
52 | log.debug("channel inactive, channel:{}", ctx.channel());
53 | node.inactive();
54 | }
55 |
56 | @Override
57 | protected void channelRead0(ChannelHandlerContext ctx, String message) throws Exception {
58 | NodeMessage nodeMessage = NodeMessage.decode(message);
59 | //是心跳的,设置节点存活
60 | if (nodeMessage instanceof Ping || nodeMessage instanceof Pong) {
61 | node.active();
62 | }
63 | node.handle(ctx, nodeMessage);
64 | }
65 |
66 |
67 | @Override
68 | public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
69 | node.reconnect(ctx);
70 | }
71 |
72 | @Override
73 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
74 | log.error("exception error:{}, channel:{}", cause, ctx.channel());
75 | ctx.close();
76 | }
77 |
78 | @Override
79 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
80 | Channel channel = ctx.channel();
81 | if (IdleStateEvent.class.isAssignableFrom(evt.getClass())) {
82 | IdleStateEvent event = (IdleStateEvent) evt;
83 | if (event.state() == IdleState.ALL_IDLE) {
84 | //发送心跳
85 | channel.writeAndFlush(PING);
86 | }
87 | if (event.state() == IdleState.READER_IDLE) {
88 | //发送心跳
89 | channel.writeAndFlush(PING);
90 | }
91 | if (event.state() == IdleState.WRITER_IDLE) {
92 | channel.writeAndFlush(PING);
93 | }
94 | } else {
95 | super.userEventTriggered(ctx, evt);
96 | }
97 | }
98 |
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/nodes/manager/INode.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.nodes.manager;
2 |
3 | import com.gopush.protocol.node.NodeMessage;
4 | import io.netty.channel.ChannelHandlerContext;
5 |
6 | /**
7 | * go-push
8 | *
9 | * @类功能说明:
10 | * @作者:喝咖啡的囊地鼠
11 | * @创建时间:2017/7/1 上午8:35
12 | * @VERSION:
13 | */
14 | public interface INode {
15 |
16 | void init();
17 |
18 | void destroy();
19 |
20 |
21 | void active();
22 |
23 | void inactive();
24 |
25 |
26 | void send(NodeMessage message);
27 |
28 | void send(NodeMessage message, boolean retry);
29 |
30 |
31 | void retrySendFail();
32 |
33 | void reconnect(ChannelHandlerContext ctx);
34 |
35 | void handle(ChannelHandlerContext ctx, NodeMessage message);
36 |
37 |
38 | int receiveCounter();
39 |
40 | int sendCounter();
41 | }
42 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/nodes/manager/NodeManager.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.nodes.manager;
2 |
3 | import com.gopush.infos.datacenter.bo.NodeClientLoaderInfo;
4 | import com.gopush.nodes.handlers.INodeMessageHandler;
5 | import io.netty.channel.EventLoopGroup;
6 | import io.netty.channel.nio.NioEventLoopGroup;
7 | import lombok.extern.slf4j.Slf4j;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.stereotype.Component;
10 |
11 | import javax.annotation.PreDestroy;
12 | import java.util.List;
13 | import java.util.Map;
14 | import java.util.concurrent.ConcurrentHashMap;
15 | import java.util.stream.Collectors;
16 |
17 | /**
18 | * go-push
19 | *
20 | * @类功能说明:
21 | * @作者:喝咖啡的囊地鼠
22 | * @创建时间:2017/6/24 下午3:33
23 | * @VERSION:
24 | */
25 |
26 | @Slf4j
27 | @Component
28 | public class NodeManager {
29 |
30 | private EventLoopGroup group = new NioEventLoopGroup();
31 |
32 | private Map nodeChannelPool = new ConcurrentHashMap<>();
33 |
34 | @Autowired
35 | private List nodeMessageHandlers;
36 |
37 | @PreDestroy
38 | public void destory() {
39 | nodeChannelPool.forEach((k, node) -> node.destroy());
40 | nodeChannelPool.clear();
41 | nodeChannelPool = null;
42 | group.shutdownGracefully();
43 | }
44 |
45 |
46 | public void clear() {
47 | nodeChannelPool.forEach((k, node) -> node.destroy());
48 | nodeChannelPool.clear();
49 |
50 | }
51 |
52 |
53 | public void remove(String nodeName) {
54 | // log.info("node remove---------{}",nodeName);
55 | if (nodeChannelPool.containsKey(nodeName)) {
56 | nodeChannelPool.get(nodeName).destroy();
57 | nodeChannelPool.remove(nodeName);
58 | }
59 | }
60 |
61 | public void put(String nodeName,
62 | String intranetIp, int nodePort,
63 | String internetIp, int devicePort) {
64 | remove(nodeName);
65 | // log.info("node add---------",nodeName);
66 | Node node = new Node(nodeName + "-client", intranetIp, nodePort, internetIp, devicePort, group, nodeMessageHandlers);
67 | node.init();
68 | nodeChannelPool.put(nodeName, node);
69 | // log.info("{}", JSON.toJSONString(nodeChannelPool));
70 | }
71 |
72 | public List loaders() {
73 | return nodeChannelPool.values().stream().map(e -> NodeClientLoaderInfo.builder().name(e.getName()).receiveCounter(e.receiveCounter()).sendCounter(e.sendCounter()).build()).collect(Collectors.toList());
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/restfuls/aop/RestfulLoaderAspect.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.restfuls.aop;
2 |
3 | import com.gopush.datacenter.restfuls.loader.LoaderService;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.aspectj.lang.ProceedingJoinPoint;
6 | import org.aspectj.lang.annotation.Around;
7 | import org.aspectj.lang.annotation.Aspect;
8 | import org.aspectj.lang.annotation.Pointcut;
9 | import org.aspectj.lang.reflect.MethodSignature;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.core.annotation.Order;
12 | import org.springframework.stereotype.Component;
13 |
14 | import java.lang.reflect.Method;
15 |
16 | /**
17 | * @author 喝咖啡的囊地鼠
18 | * @date 2017/9/15 下午12:35
19 | */
20 | @Aspect
21 | @Component
22 | @Order(0)
23 | @Slf4j
24 | public class RestfulLoaderAspect {
25 |
26 | @Autowired
27 | private LoaderService loaderService;
28 |
29 | @Pointcut("execution(public * com.gopush.datacenter.restfuls.controller..*.*(..))")
30 | public void loaderPoint() {
31 |
32 | }
33 |
34 | @Around("loaderPoint()")
35 | public Object loaderAround(ProceedingJoinPoint pjp) throws Throwable {
36 | Method method = ((MethodSignature) pjp.getSignature()).getMethod();
37 | loaderService.count(method);
38 | return pjp.proceed();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/restfuls/controller/ApisDeviceController.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.restfuls.controller;
2 |
3 | import com.gopush.common.constants.IdleEnum;
4 | import com.gopush.datacenter.dymic.discovery.NodeServerDiscoveryService;
5 | import com.gopush.datacenter.restfuls.pojo.BaseResp;
6 | import com.gopush.datacenter.restfuls.pojo.bo.Device;
7 | import com.gopush.datacenter.restfuls.pojo.bo.LoadbanceNode;
8 | import com.gopush.infos.nodeserver.bo.NodeServerInfo;
9 | import io.swagger.annotations.Api;
10 | import io.swagger.annotations.ApiOperation;
11 | import io.swagger.annotations.ApiParam;
12 | import org.springframework.beans.factory.annotation.Autowired;
13 | import org.springframework.http.ResponseEntity;
14 | import org.springframework.util.CollectionUtils;
15 | import org.springframework.web.bind.annotation.*;
16 |
17 | import java.util.Comparator;
18 | import java.util.HashMap;
19 | import java.util.Map;
20 | import java.util.UUID;
21 |
22 | /**
23 | * @author 喝咖啡的囊地鼠
24 | * @date 2017/9/14 下午3:18
25 | */
26 |
27 | @RestController
28 | @RequestMapping(value = "/apis/device")
29 | @Api(tags = "设备|链接相关")
30 | public class ApisDeviceController {
31 |
32 | @Autowired
33 | private NodeServerDiscoveryService nodeServerDiscoveryService;
34 |
35 | @ApiOperation(value = "设备注册", notes = "注册设备(一台设备只注册一次,但是可以增加APPCode)")
36 | @RequestMapping(value = "/register", method = RequestMethod.POST)
37 | public ResponseEntity> register(@RequestBody Device device) {
38 | //内部生产一个设备号给注册的设备
39 | //查找缓存,设置注册设备,没有设备的话注册,有的话检查appcode,没有的加入appcode 有的话直接返回已经注册的设备号
40 | //todo
41 | return ResponseEntity.ok(BaseResp.ok(token()));
42 | }
43 |
44 | @ApiOperation(value = "设备取消注册", notes = "取消注册设备(一台设备只注册一次)")
45 | @RequestMapping(value = "/unregister/{deviceNo}", method = RequestMethod.DELETE)
46 | public ResponseEntity unregister(@PathVariable("deviceNo") @ApiParam("设备号") String deviceNo) {
47 | //查找缓存,没有设备的话直接返回,有的话 取消注册的设备,清空设备的有效期(从而导致sdk端或者服务端关闭链接)
48 | //todo
49 | return ResponseEntity.ok(BaseResp.ok());
50 | }
51 |
52 | @ApiOperation(value = "查询设备状态", notes = "查询设备状态")
53 | @RequestMapping(value = "/{deviceNo}/state", method = RequestMethod.GET)
54 | public ResponseEntity deviceState(@PathVariable("deviceNo") @ApiParam("设备号") String deviceNo) {
55 | //查找缓存,没有设备的话直接返回,有的话 取消注册的设备,清空设备的有效期(从而导致sdk端或者服务端关闭链接)
56 | //todo 查询设备状态
57 | return ResponseEntity.ok(BaseResp.ok());
58 | }
59 |
60 |
61 | @ApiOperation(value = "设备选择链接节点", notes = "设备选择链接节点")
62 | @RequestMapping(value = "/select", method = RequestMethod.GET)
63 | public ResponseEntity> selectNode() {
64 | Map maps = new HashMap<>(nodeServerDiscoveryService.nodeServerPool());
65 | if (!CollectionUtils.isEmpty(maps)) {
66 | NodeServerInfo info = maps.values().stream()
67 | .min(Comparator.comparingInt(e -> e.getNodeLoaderInfo().getOnlineDeviceCounter()))
68 | .get();
69 | return ResponseEntity.ok(
70 | BaseResp.ok(
71 | LoadbanceNode.builder()
72 | .ip(info.getInternetIp())
73 | .port(info.getDevicePort())
74 | .readInterval(IdleEnum.READ_IDLE.getValue())
75 | .writeInterval(IdleEnum.WRITE_IDLE.getValue())
76 | .allInterval(IdleEnum.ALL_IDLE.getValue())
77 | .build()
78 | ));
79 | }
80 | return ResponseEntity.ok(BaseResp.fail(400, "无可链接节点"));
81 | }
82 |
83 |
84 | private String token() {
85 | return UUID.randomUUID().toString().replaceAll("\\-", "");
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/restfuls/controller/ApisPushController.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.restfuls.controller;
2 |
3 | import com.gopush.datacenter.restfuls.pojo.BaseResp;
4 | import com.gopush.datacenter.restfuls.pojo.bo.Device;
5 | import io.swagger.annotations.Api;
6 | import io.swagger.annotations.ApiOperation;
7 | import org.springframework.http.ResponseEntity;
8 | import org.springframework.web.bind.annotation.RequestBody;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import org.springframework.web.bind.annotation.RequestMethod;
11 | import org.springframework.web.bind.annotation.RestController;
12 |
13 | /**
14 | * @author 喝咖啡的囊地鼠
15 | * @date 2017/9/14 下午10:57
16 | */
17 |
18 |
19 | @RestController
20 | @RequestMapping(value = "/apis/push")
21 | @Api(tags = "推送消息相关")
22 | public class ApisPushController {
23 |
24 | @ApiOperation(value = "向单个设备推送消息", notes = "向单个设备推送消息")
25 | @RequestMapping(value = "/one", method = RequestMethod.POST)
26 | public ResponseEntity pushOne(@RequestBody Device device) {
27 | //todo
28 | return ResponseEntity.ok(BaseResp.ok());
29 | }
30 |
31 | @ApiOperation(value = "向多个设备推送消息", notes = "向多个设备推送消息")
32 | @RequestMapping(value = "/numerous", method = RequestMethod.POST)
33 | public ResponseEntity pushNumerous(@RequestBody Device device) {
34 | //todo
35 | return ResponseEntity.ok(BaseResp.ok());
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/restfuls/loader/LoaderService.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.restfuls.loader;
2 |
3 | import com.gopush.infos.datacenter.bo.RestfulLoaderInfo;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Component;
7 | import org.springframework.web.method.HandlerMethod;
8 | import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
9 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
10 |
11 | import javax.annotation.PostConstruct;
12 | import javax.annotation.PreDestroy;
13 | import java.lang.reflect.Method;
14 | import java.util.ArrayList;
15 | import java.util.List;
16 | import java.util.Map;
17 | import java.util.concurrent.ConcurrentHashMap;
18 | import java.util.concurrent.atomic.AtomicInteger;
19 | import java.util.stream.Collectors;
20 |
21 | /**
22 | * @author 喝咖啡的囊地鼠
23 | * @date 2017/9/15 下午12:56
24 | */
25 | @Slf4j
26 | @Component
27 | public class LoaderService {
28 |
29 | private static final int INT_ZERO = 0;
30 | private static final int INT_MAX_VAL = Integer.MAX_VALUE - 1;
31 |
32 | @Autowired
33 | private RequestMappingHandlerMapping requestMappingHandlerMapping;
34 |
35 | private Map, AtomicInteger> restfulUrlCounters = new ConcurrentHashMap<>();
36 | private Map> methodRestfulUrls = new ConcurrentHashMap<>();
37 |
38 | @PostConstruct
39 | public void init() {
40 | Map handlerMethods = requestMappingHandlerMapping.getHandlerMethods();
41 |
42 | handlerMethods.forEach((k, v) -> {
43 | List urls = k.getPatternsCondition().getPatterns().stream().sorted().collect(Collectors.toList());
44 | methodRestfulUrls.put(v.getMethod(), urls);
45 | restfulUrlCounters.put(urls, new AtomicInteger(INT_ZERO));
46 | });
47 |
48 | }
49 |
50 | @PreDestroy
51 | public void destory() {
52 | methodRestfulUrls.clear();
53 | methodRestfulUrls = null;
54 | restfulUrlCounters.clear();
55 | restfulUrlCounters = null;
56 | }
57 |
58 | public List restfulLoader() {
59 | List list = new ArrayList<>();
60 | restfulUrlCounters.forEach((k, v) -> list.add(RestfulLoaderInfo.builder().callCounter(v.get()).restfulUrl(new ArrayList(k)).build()));
61 | return list;
62 | }
63 |
64 |
65 | public void count(Method method) {
66 | if (methodRestfulUrls.containsKey(method)) {
67 | AtomicInteger count = restfulUrlCounters.get(methodRestfulUrls.get(method));
68 | int c = count.incrementAndGet();
69 | if (c >= INT_MAX_VAL) {
70 | count.set(INT_ZERO);
71 | }
72 | }
73 | }
74 |
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/restfuls/pojo/BaseResp.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.restfuls.pojo;
2 |
3 | import com.gopush.common.constants.RestfulRespEnum;
4 | import lombok.*;
5 |
6 | /**
7 | * @author 喝咖啡的囊地鼠
8 | * @date 2017/9/14 下午5:27
9 | */
10 |
11 | @Builder
12 | @AllArgsConstructor
13 | @NoArgsConstructor
14 | @EqualsAndHashCode
15 | @ToString
16 | @Getter
17 | public class BaseResp {
18 | private Integer code;
19 | private String description;
20 | private T data;
21 |
22 | public static BaseResp ok(T data) {
23 | return BaseResp.builder()
24 | .data(data)
25 | .code(RestfulRespEnum.OK.getKey())
26 | .description(RestfulRespEnum.OK.getDescri())
27 | .build();
28 | }
29 |
30 | public static BaseResp ok() {
31 | return ok(null);
32 | }
33 |
34 | public static BaseResp fail(int failCode, String failMsg) {
35 | return fail(failCode, failMsg, null);
36 | }
37 |
38 | public static BaseResp fail(int failCode, String failMsg, T data) {
39 | return BaseResp.builder().code(failCode).description(failMsg).data(data).build();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/restfuls/pojo/bo/Device.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.restfuls.pojo.bo;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | /**
11 | * @author 喝咖啡的囊地鼠
12 | * @date 2017/9/14 下午3:32
13 | */
14 | @Data
15 | @Builder
16 | @NoArgsConstructor
17 | @AllArgsConstructor
18 | @ApiModel("设备")
19 | public class Device {
20 |
21 | @ApiModelProperty(value = "设备号", required = true, example = "IMEI99999")
22 | private String deviceNo;
23 |
24 | @ApiModelProperty(value = "设备类型", required = true, example = "ios,android,other")
25 | private String type;
26 |
27 | @ApiModelProperty(value = "应用Code", example = "com.baidu")
28 | private String appCode;
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/java/com/gopush/datacenter/restfuls/pojo/bo/LoadbanceNode.java:
--------------------------------------------------------------------------------
1 | package com.gopush.datacenter.restfuls.pojo.bo;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | /**
11 | * @author 喝咖啡的囊地鼠
12 | * @date 2017/9/14 下午10:15
13 | */
14 |
15 | @Data
16 | @Builder
17 | @NoArgsConstructor
18 | @AllArgsConstructor
19 | @ApiModel("选择节点")
20 | public class LoadbanceNode {
21 | @ApiModelProperty(value = "链接IP", example = "192.168.1.1")
22 | private String ip;
23 |
24 | @ApiModelProperty(value = "链接PORT", example = "9999")
25 | private int port;
26 | @ApiModelProperty(value = "读周期", example = "10")
27 | private int readInterval;
28 | @ApiModelProperty(value = "写周期", example = "30")
29 | private int writeInterval;
30 | @ApiModelProperty(value = "读写周期", example = "50")
31 | private int allInterval;
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/go-push-data-center/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 |
2 | server:
3 | port: ${random.int[5001,5999]}
4 |
5 | spring:
6 | redis:
7 | cluster:
8 | nodes:
9 | - 127.0.0.1:6379
10 | - 127.0.0.1:6379
11 |
12 |
13 | go-push:
14 | data-center:
15 | name: DataCenter-${random.int(100)}
16 | zookeeper:
17 | servers: 192.168.99.100:32773
18 | listen-namespace: namespace-node-server
19 | namespace: namespace-data-center
20 | session-timeout: 6000
21 | connection-timeout: 6000
22 | max-retries: 1000
23 | retries-sleep-time: 2000
24 |
25 | swagger:
26 | title: GoPush Restful接口
27 | description: ${swagger.title}文档说明
28 | version: ${application.version}
29 | license: GoPush 许可
30 | license-url: https://gitee.com/openWolf/gopush/blob/master/LICENSE
31 | terms-of-service-url: https://gitee.com/openWolf/gopush/issues/new
32 | contact:
33 | name: 喝咖啡的囊地鼠
34 | url: https://gitee.com/openWolf/gopush
35 | email: null_hello@qq.com
36 | base-package: com.gopush.datacenter.restful
37 | base-path: /**
38 | exclude-path: /error,/ops/**
--------------------------------------------------------------------------------
/go-push-data-center/src/main/resources/banner.txt:
--------------------------------------------------------------------------------
1 | ${AnsiColor.BRIGHT_GREEN}
2 | _____ _ _____ _
3 | | __ \ | | / ____| | |
4 | | | | | __ _| |_ __ _| | ___ _ __ | |_ ___ _ __
5 | | | | |/ _` | __/ _` | | / _ \ '_ \| __/ _ \ '__|
6 | | |__| | (_| | || (_| | |___| __/ | | | || __/ | _____ _____ _
7 | |_____/ \__,_|\__\__,_|\_____\___|_| |_|\__\___|_| / ____| | __ \ | |
8 | ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ | | __ ___ | |__) | _ ___| |__
9 | |______|______|______|______|______|______|______|______|______|______|______| | | |_ |/ _ \| ___/ | | / __| '_ \
10 | | |__| | (_) | | | |_| \__ \ | | |
11 | \_____|\___/|_| \__,_|___/_| |_|
12 | ${AnsiColor.BRIGHT_RED}
13 | Application Version: ${application.version}${application.formatted-version}
14 | Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
--------------------------------------------------------------------------------
/go-push-data-center/src/test/java/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkhello/gopush/94bbbb40b2bc20196c0388a2a8482c6cb00909df/go-push-data-center/src/test/java/.gitignore
--------------------------------------------------------------------------------
/go-push-handler-device/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | go-push
7 | com.gopush
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | go-push-handler-device
12 | jar
13 | GoPush业务handler
14 |
15 |
16 |
17 | com.gopush
18 | go-push-protocol-device
19 | ${project.version}
20 |
21 |
33 |
34 | io.netty
35 | netty-all
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/go-push-handler-device/src/main/java/com/gopush/devices/handlers/IDeviceDisconnectHandler.java:
--------------------------------------------------------------------------------
1 | package com.gopush.devices.handlers;
2 |
3 | import io.netty.channel.Channel;
4 |
5 | /**
6 | * go-push
7 | *
8 | * @类功能说明:设备断连处理接口
9 | * @作者:喝咖啡的囊地鼠
10 | * @创建时间:2017/6/19 上午12:20
11 | * @VERSION:
12 | */
13 | public interface IDeviceDisconnectHandler {
14 |
15 |
16 | /**
17 | * channel关闭,触发
18 | *
19 | * @param channel
20 | */
21 | void channelClosed(Channel channel);
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/go-push-handler-device/src/main/java/com/gopush/devices/handlers/IDeviceDockedHandler.java:
--------------------------------------------------------------------------------
1 | package com.gopush.devices.handlers;
2 |
3 | /**
4 | * go-push
5 | *
6 | * @类功能说明:设备上线报告
7 | * @作者:喝咖啡的囊地鼠
8 | * @创建时间:2017/6/19 上午12:51
9 | * @VERSION:
10 | */
11 | public interface IDeviceDockedHandler {
12 |
13 | void upReport(String device, int channelHashCode, int[] idles);
14 | }
15 |
--------------------------------------------------------------------------------
/go-push-handler-device/src/main/java/com/gopush/devices/handlers/IDeviceMessageHandler.java:
--------------------------------------------------------------------------------
1 | package com.gopush.devices.handlers;
2 |
3 | import com.gopush.protocol.device.DeviceMessage;
4 | import io.netty.channel.ChannelHandlerContext;
5 |
6 | /**
7 | * go-push
8 | *
9 | * @类功能说明:
10 | * @作者:喝咖啡的囊地鼠
11 | * @创建时间:2017/6/11 上午11:43
12 | * @VERSION:
13 | */
14 |
15 |
16 | public interface IDeviceMessageHandler {
17 |
18 | /**
19 | * 根据各个handler 判断是不是各个handler对应处理的消息
20 | *
21 | * @param message 节点消息
22 | * @return 是否各个NodeMessage 子类的类型
23 | */
24 | boolean support(DeviceMessage message);
25 |
26 | /**
27 | * 各个消息处理句柄调用方法
28 | *
29 | * @param message 节点消息
30 | */
31 | void call(ChannelHandlerContext context, R message);
32 | }
33 |
--------------------------------------------------------------------------------
/go-push-handler-device/src/main/resources/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkhello/gopush/94bbbb40b2bc20196c0388a2a8482c6cb00909df/go-push-handler-device/src/main/resources/.gitignore
--------------------------------------------------------------------------------
/go-push-handler-device/src/test/java/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkhello/gopush/94bbbb40b2bc20196c0388a2a8482c6cb00909df/go-push-handler-device/src/test/java/.gitignore
--------------------------------------------------------------------------------
/go-push-handler-node/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | go-push
7 | com.gopush
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | go-push-handler-node
13 | jar
14 | GoPush业务handler
15 |
16 |
17 |
18 | com.gopush
19 | go-push-protocol-node
20 | ${project.version}
21 |
22 |
23 |
34 |
35 | io.netty
36 | netty-all
37 |
38 |
39 |
--------------------------------------------------------------------------------
/go-push-handler-node/src/main/java/com/gopush/nodes/handlers/INodeMessageHandler.java:
--------------------------------------------------------------------------------
1 | package com.gopush.nodes.handlers;
2 |
3 |
4 | import com.gopush.protocol.node.NodeMessage;
5 | import io.netty.channel.ChannelHandlerContext;
6 |
7 | /**
8 | * go-push
9 | *
10 | * @类功能说明:node 节点业务抽象接口
11 | * @作者:喝咖啡的囊地鼠
12 | * @创建时间:2017/6/12 上午12:28
13 | * @VERSION:
14 | */
15 | public interface INodeMessageHandler {
16 |
17 | /**
18 | * 根据各个handler 判断是不是各个handler对应处理的消息
19 | *
20 | * @param message 节点消息
21 | * @return 是否各个NodeMessage 子类的类型
22 | */
23 | boolean support(NodeMessage message);
24 |
25 |
26 | /**
27 | * 各个消息处理句柄调用方法
28 | *
29 | * @param message 节点消息
30 | */
31 | void call(ChannelHandlerContext ctx, R message);
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/go-push-handler-node/src/main/resources/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkhello/gopush/94bbbb40b2bc20196c0388a2a8482c6cb00909df/go-push-handler-node/src/main/resources/.gitignore
--------------------------------------------------------------------------------
/go-push-handler-node/src/test/java/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkhello/gopush/94bbbb40b2bc20196c0388a2a8482c6cb00909df/go-push-handler-node/src/test/java/.gitignore
--------------------------------------------------------------------------------
/go-push-infos/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | go-push
7 | com.gopush
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | go-push-infos
13 |
14 |
15 |
16 | com.alibaba
17 | fastjson
18 |
19 |
20 | org.projectlombok
21 | lombok
22 | provided
23 |
24 |
25 |
--------------------------------------------------------------------------------
/go-push-infos/src/main/java/com/gopush/infos/datacenter/bo/DataCenterInfo.java:
--------------------------------------------------------------------------------
1 | package com.gopush.infos.datacenter.bo;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @author 喝咖啡的囊地鼠
12 | * @date 2017/9/15 上午7:56
13 | */
14 | @Builder
15 | @Data
16 | @NoArgsConstructor
17 | @AllArgsConstructor
18 | public class DataCenterInfo {
19 | private String name;
20 | //内网IP
21 | private String intranetIp;
22 | //外网IP
23 | private String internetIp;
24 |
25 | private List restfulLoaderInfos;
26 |
27 | private List nodeClientLoaderInfos;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/go-push-infos/src/main/java/com/gopush/infos/datacenter/bo/NodeClientLoaderInfo.java:
--------------------------------------------------------------------------------
1 | package com.gopush.infos.datacenter.bo;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @author 喝咖啡的囊地鼠
10 | * @date 2017/9/15 上午11:39
11 | */
12 | @Builder
13 | @Data
14 | @NoArgsConstructor
15 | @AllArgsConstructor
16 | public class NodeClientLoaderInfo {
17 | private String name;
18 | private int receiveCounter;
19 | private int sendCounter;
20 | }
21 |
--------------------------------------------------------------------------------
/go-push-infos/src/main/java/com/gopush/infos/datacenter/bo/RestfulLoaderInfo.java:
--------------------------------------------------------------------------------
1 | package com.gopush.infos.datacenter.bo;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @author 喝咖啡的囊地鼠
12 | * @date 2017/9/15 上午11:17
13 | */
14 |
15 | @Builder
16 | @Data
17 | @NoArgsConstructor
18 | @AllArgsConstructor
19 | public class RestfulLoaderInfo {
20 |
21 | private int callCounter;
22 |
23 | private List restfulUrl;
24 |
25 | }
--------------------------------------------------------------------------------
/go-push-infos/src/main/java/com/gopush/infos/nodeserver/bo/HandlerInfo.java:
--------------------------------------------------------------------------------
1 | package com.gopush.infos.nodeserver.bo;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * go-push
12 | *
13 | * @类功能说明:
14 | * @作者:喝咖啡的囊地鼠
15 | * @创建时间:2017/6/20 下午8:41
16 | * @VERSION:
17 | */
18 | @Builder
19 | @Data
20 | @NoArgsConstructor
21 | @AllArgsConstructor
22 | public class HandlerInfo {
23 |
24 | private String batchExecutorName;
25 |
26 | private int receiveCounter;
27 |
28 | private int failCounter;
29 |
30 | private int retryCounter;
31 |
32 | private List processorInfos;
33 | }
34 |
--------------------------------------------------------------------------------
/go-push-infos/src/main/java/com/gopush/infos/nodeserver/bo/NodeLoaderInfo.java:
--------------------------------------------------------------------------------
1 | package com.gopush.infos.nodeserver.bo;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @author 喝咖啡的囊地鼠
12 | * @date 2017/9/10 下午1:59
13 | */
14 |
15 | @Builder
16 | @Data
17 | @NoArgsConstructor
18 | @AllArgsConstructor
19 | public class NodeLoaderInfo {
20 | private int onlineDeviceCounter;
21 | private int onlineDcCounter;
22 | private List handlerInfos;
23 | }
24 |
--------------------------------------------------------------------------------
/go-push-infos/src/main/java/com/gopush/infos/nodeserver/bo/NodeServerInfo.java:
--------------------------------------------------------------------------------
1 | package com.gopush.infos.nodeserver.bo;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @author 喝咖啡的囊地鼠
10 | * @date 2017/9/12 上午12:17
11 | */
12 | @Builder
13 | @Data
14 | @NoArgsConstructor
15 | @AllArgsConstructor
16 | public class NodeServerInfo {
17 | //名称
18 | private String name;
19 | //内网IP
20 | private String intranetIp;
21 | //外网IP
22 | private String internetIp;
23 | //对设备监听端口
24 | private int devicePort;
25 | //对内监听端口
26 | private int nodePort;
27 | //系统负载信息
28 | private NodeLoaderInfo nodeLoaderInfo;
29 | }
30 |
--------------------------------------------------------------------------------
/go-push-infos/src/main/java/com/gopush/infos/nodeserver/bo/ProcessorInfo.java:
--------------------------------------------------------------------------------
1 | package com.gopush.infos.nodeserver.bo;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * go-push
10 | *
11 | * @类功能说明:每个批处理机内部处理器 信息
12 | * @作者:喝咖啡的囊地鼠
13 | * @创建时间:2017/6/20 下午8:37
14 | * @VERSION:
15 | */
16 | @Builder
17 | @Data
18 | @NoArgsConstructor
19 | @AllArgsConstructor
20 | public class ProcessorInfo {
21 |
22 | private String batchName;
23 |
24 | private int index;
25 |
26 | private int loader;
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/go-push-infos/src/main/resources/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkhello/gopush/94bbbb40b2bc20196c0388a2a8482c6cb00909df/go-push-infos/src/main/resources/.gitignore
--------------------------------------------------------------------------------
/go-push-infos/src/test/java/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkhello/gopush/94bbbb40b2bc20196c0388a2a8482c6cb00909df/go-push-infos/src/test/java/.gitignore
--------------------------------------------------------------------------------
/go-push-monitor/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | go-push
7 | com.gopush
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | go-push-monitor
12 | jar
13 | GoPush监控服务
14 |
15 |
16 |
17 |
18 |
19 | com.gopush
20 | go-push-common
21 | ${project.version}
22 |
23 |
24 | com.gopush
25 | go-push-infos
26 | ${project.version}
27 |
28 |
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-web
33 |
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-data-redis
38 |
39 |
40 |
41 | org.projectlombok
42 | lombok
43 |
44 |
45 |
46 | org.springframework.boot
47 | spring-boot-starter-thymeleaf
48 |
49 |
50 |
51 |
52 | com.didispace
53 | spring-boot-starter-swagger
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/go-push-monitor/src/main/java/com/gopush/monitor/MonitorApplication.java:
--------------------------------------------------------------------------------
1 | package com.gopush.monitor;
2 |
3 | import com.didispace.swagger.EnableSwagger2Doc;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 |
7 | /**
8 | * go-push
9 | *
10 | * @类功能说明:监控中心
11 | * @作者:喝咖啡的囊地鼠
12 | * @创建时间:2017/6/10 上午4:43
13 | * @VERSION:
14 | */
15 | @EnableSwagger2Doc
16 | @SpringBootApplication
17 | public class MonitorApplication {
18 |
19 | public static void main(String[] args) {
20 | SpringApplication.run(MonitorApplication.class, args);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/go-push-monitor/src/main/java/com/gopush/monitor/config/ZookeeperConfig.java:
--------------------------------------------------------------------------------
1 | package com.gopush.monitor.config;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.context.annotation.Configuration;
6 |
7 | /**
8 | * @author 喝咖啡的囊地鼠
9 | * @date 2017/9/11 下午11:44
10 | */
11 | @Data
12 | @Configuration
13 | @ConfigurationProperties(prefix = "go-push.zookeeper")
14 | public class ZookeeperConfig {
15 |
16 | private String servers;
17 |
18 | private String listenNamespaceDataCenter;
19 |
20 | private String listenNamespaceNodeServer;
21 |
22 | private int sessionTimeout;
23 |
24 | private int connectionTimeout;
25 |
26 | private int maxRetries;
27 |
28 | private int retriesSleepTime;
29 | }
30 |
--------------------------------------------------------------------------------
/go-push-monitor/src/main/java/com/gopush/monitor/controller/MonitorController.java:
--------------------------------------------------------------------------------
1 | package com.gopush.monitor.controller;
2 |
3 | import io.swagger.annotations.Api;
4 | import io.swagger.annotations.ApiOperation;
5 | import org.springframework.stereotype.Controller;
6 | import org.springframework.web.bind.annotation.RequestMapping;
7 | import org.springframework.web.bind.annotation.RequestMethod;
8 |
9 | /**
10 | * @author 喝咖啡的囊地鼠
11 | * @date 2017/9/15 下午5:15
12 | */
13 | @Controller
14 | @Api(tags = "监控中心")
15 | public class MonitorController {
16 |
17 | @ApiOperation("首页跳转")
18 | @RequestMapping(value = "/", method = RequestMethod.GET)
19 | public String index() {
20 | return "redirect:/monitor";
21 | }
22 |
23 | @ApiOperation("监控中心")
24 | @RequestMapping(value = "/monitor", method = RequestMethod.GET)
25 | public String monitor() {
26 | return "monitor";
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/go-push-monitor/src/main/java/com/gopush/monitor/controller/MonitorDataController.java:
--------------------------------------------------------------------------------
1 | package com.gopush.monitor.controller;
2 |
3 | import com.gopush.infos.datacenter.bo.DataCenterInfo;
4 | import com.gopush.infos.nodeserver.bo.NodeServerInfo;
5 | import com.gopush.monitor.controller.pojo.BaseResp;
6 | import com.gopush.monitor.dymic.discovery.MonitorDataCenterService;
7 | import com.gopush.monitor.dymic.discovery.MonitorNodeServerService;
8 | import io.swagger.annotations.Api;
9 | import io.swagger.annotations.ApiOperation;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.http.ResponseEntity;
12 | import org.springframework.web.bind.annotation.RequestMapping;
13 | import org.springframework.web.bind.annotation.RequestMethod;
14 | import org.springframework.web.bind.annotation.RestController;
15 |
16 | import java.util.List;
17 |
18 | /**
19 | * @author 喝咖啡的囊地鼠
20 | * @date 2017/9/15 下午5:09
21 | */
22 | @RestController
23 | @RequestMapping("/monitor")
24 | @Api(tags = "监控数据")
25 | public class MonitorDataController {
26 |
27 | @Autowired
28 | private MonitorDataCenterService monitorDataCenterService;
29 |
30 | @Autowired
31 | private MonitorNodeServerService monitorNodeServerService;
32 |
33 | @ApiOperation(value = "数据中心监控", notes = "DataCenter 数据中心 监控数据")
34 | @RequestMapping(value = "/dc", method = RequestMethod.GET)
35 | public ResponseEntity>> dataCenterInfos() {
36 | return ResponseEntity.ok(BaseResp.ok(monitorDataCenterService.dataCenterLoader()));
37 | }
38 |
39 | @ApiOperation(value = "节点服务监控", notes = "NodeServer 节点服务 监控数据")
40 | @RequestMapping(value = "/node", method = RequestMethod.GET)
41 | public ResponseEntity>> nodeServceInfos() {
42 | return ResponseEntity.ok(BaseResp.ok(monitorNodeServerService.nodeServerLoader()));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/go-push-monitor/src/main/java/com/gopush/monitor/controller/pojo/BaseResp.java:
--------------------------------------------------------------------------------
1 | package com.gopush.monitor.controller.pojo;
2 |
3 | import com.gopush.common.constants.RestfulRespEnum;
4 | import lombok.*;
5 |
6 | /**
7 | * @author 喝咖啡的囊地鼠
8 | * @date 2017/9/14 下午5:27
9 | */
10 |
11 | @Builder
12 | @AllArgsConstructor
13 | @NoArgsConstructor
14 | @EqualsAndHashCode
15 | @ToString
16 | @Getter
17 | public class BaseResp {
18 | private Integer code;
19 | private String description;
20 | private T data;
21 |
22 | public static BaseResp ok(T data) {
23 | return BaseResp.builder()
24 | .data(data)
25 | .code(RestfulRespEnum.OK.getKey())
26 | .description(RestfulRespEnum.OK.getDescri())
27 | .build();
28 | }
29 |
30 | public static BaseResp ok() {
31 | return ok(null);
32 | }
33 |
34 | public static BaseResp fail(int failCode, String failMsg) {
35 | return fail(failCode, failMsg, null);
36 | }
37 |
38 | public static BaseResp fail(int failCode, String failMsg, T data) {
39 | return BaseResp.builder().code(failCode).description(failMsg).data(data).build();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/go-push-monitor/src/main/java/com/gopush/monitor/dymic/discovery/MonitorDataCenterService.java:
--------------------------------------------------------------------------------
1 | package com.gopush.monitor.dymic.discovery;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.gopush.common.constants.ZkGroupEnum;
5 | import com.gopush.common.utils.zk.ZkUtils;
6 | import com.gopush.common.utils.zk.listener.ZkStateListener;
7 | import com.gopush.infos.datacenter.bo.DataCenterInfo;
8 | import com.gopush.monitor.config.ZookeeperConfig;
9 | import lombok.extern.slf4j.Slf4j;
10 | import org.apache.curator.framework.CuratorFramework;
11 | import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
12 | import org.apache.curator.framework.state.ConnectionState;
13 | import org.springframework.beans.factory.annotation.Autowired;
14 | import org.springframework.stereotype.Component;
15 |
16 | import javax.annotation.PostConstruct;
17 | import javax.annotation.PreDestroy;
18 | import java.util.List;
19 | import java.util.Map;
20 | import java.util.concurrent.ConcurrentHashMap;
21 | import java.util.stream.Collectors;
22 |
23 | /**
24 | * @author 喝咖啡的囊地鼠
25 | * @date 2017/9/15 下午3:50
26 | */
27 |
28 | @Slf4j
29 | @Component
30 | public class MonitorDataCenterService {
31 |
32 | //缓存的本地服务列表
33 | private Map monitorDataCenterPool = new ConcurrentHashMap<>();
34 |
35 |
36 | @Autowired
37 | private ZookeeperConfig zookeeperConfig;
38 |
39 | private ZkUtils zkUtils;
40 |
41 | @PostConstruct
42 | public void init() {
43 | zkUtils = new ZkUtils();
44 | zkUtils.init(
45 | zookeeperConfig.getServers(),
46 | zookeeperConfig.getConnectionTimeout(),
47 | zookeeperConfig.getSessionTimeout(),
48 | zookeeperConfig.getMaxRetries(),
49 | zookeeperConfig.getRetriesSleepTime(),
50 | zookeeperConfig.getListenNamespaceDataCenter(),
51 | new ZkStateListener() {
52 | @Override
53 | public void connectedEvent(CuratorFramework curator, ConnectionState state) {
54 | log.info("MonitorDataCenter 链接zk成功");
55 | initDataCenterPool();
56 |
57 | }
58 |
59 | @Override
60 | public void reconnectedEvent(CuratorFramework curator, ConnectionState state) {
61 | log.info("MonitorDataCenter 重新链接zk成功");
62 | initDataCenterPool();
63 | }
64 |
65 | @Override
66 | public void lostEvent(CuratorFramework curator, ConnectionState state) {
67 | log.info("MonitorDataCenter 链接zk丢失");
68 | monitorDataCenterPool.clear();
69 | }
70 | });
71 |
72 | listenDataCenter();
73 | }
74 |
75 | @PreDestroy
76 | public void destory() {
77 | monitorDataCenterPool.clear();
78 | zkUtils.destory();
79 | }
80 |
81 |
82 | public List dataCenterLoader() {
83 | return monitorDataCenterPool.values().stream().collect(Collectors.toList());
84 | }
85 |
86 | private void initDataCenterPool() {
87 | monitorDataCenterPool.clear();
88 | Map datas = zkUtils.readTargetChildsData(ZkGroupEnum.DATA_CENTER.getValue());
89 | if (datas != null) {
90 | datas.forEach((k, v) -> monitorDataCenterPool.put(k, JSON.parseObject(v, DataCenterInfo.class)));
91 | }
92 | }
93 |
94 | /**
95 | * 设置监听发生更新,更新缓存数据,发生新增,删除,更新
96 | */
97 | private void listenDataCenter() {
98 | zkUtils.listenerPathChildrenCache(ZkGroupEnum.DATA_CENTER.getValue(), ((client, event) -> {
99 | switch (event.getType()) {
100 | case CHILD_ADDED:
101 | addEvent(event);
102 | break;
103 | case CHILD_REMOVED:
104 | removeEvent(event);
105 | break;
106 | case CHILD_UPDATED:
107 | updateEvent(event);
108 | break;
109 | default:
110 | break;
111 | }
112 | }));
113 | }
114 |
115 | private void updateEvent(PathChildrenCacheEvent event) {
116 | String key = toKey(event);
117 | DataCenterInfo data = toDataCenterInfo(event);
118 | log.debug(" Monitor data center event update! key:{}, data:{}", key, data);
119 | if (monitorDataCenterPool.containsKey(key)) {
120 | monitorDataCenterPool.put(key, data);
121 | }
122 | }
123 |
124 | private void removeEvent(PathChildrenCacheEvent event) {
125 | String key = toKey(event);
126 | DataCenterInfo data = toDataCenterInfo(event);
127 | log.debug(" Monitor data center event remove! key:{}, data:{}", key, data);
128 | if (monitorDataCenterPool.containsKey(key)) {
129 | monitorDataCenterPool.remove(key);
130 | }
131 |
132 | }
133 |
134 | private void addEvent(PathChildrenCacheEvent event) {
135 | String key = toKey(event);
136 | DataCenterInfo data = toDataCenterInfo(event);
137 | log.debug(" Monitor data center event add! key:{}, data:{}", key, data);
138 | if (!monitorDataCenterPool.containsKey(key)) {
139 | //开启node,加入到管理器
140 | monitorDataCenterPool.put(key, data);
141 | } else {
142 | log.error(" Monitor data center already! {},{}", key, data);
143 | }
144 | }
145 |
146 |
147 | private String toKey(PathChildrenCacheEvent event) {
148 | String path = event.getData().getPath();
149 | return path.substring(path.lastIndexOf("/")).replaceAll("/", "");
150 | }
151 |
152 | private DataCenterInfo toDataCenterInfo(PathChildrenCacheEvent event) {
153 | return JSON.parseObject(event.getData().getData(), DataCenterInfo.class);
154 | }
155 |
156 |
157 | }
158 |
--------------------------------------------------------------------------------
/go-push-monitor/src/main/java/com/gopush/monitor/dymic/discovery/MonitorNodeServerService.java:
--------------------------------------------------------------------------------
1 | package com.gopush.monitor.dymic.discovery;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.gopush.common.constants.ZkGroupEnum;
5 | import com.gopush.common.utils.zk.ZkUtils;
6 | import com.gopush.common.utils.zk.listener.ZkStateListener;
7 | import com.gopush.infos.nodeserver.bo.NodeServerInfo;
8 | import com.gopush.monitor.config.ZookeeperConfig;
9 | import lombok.extern.slf4j.Slf4j;
10 | import org.apache.curator.framework.CuratorFramework;
11 | import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
12 | import org.apache.curator.framework.state.ConnectionState;
13 | import org.springframework.beans.factory.annotation.Autowired;
14 | import org.springframework.stereotype.Component;
15 |
16 | import javax.annotation.PostConstruct;
17 | import javax.annotation.PreDestroy;
18 | import java.util.List;
19 | import java.util.Map;
20 | import java.util.concurrent.ConcurrentHashMap;
21 | import java.util.stream.Collectors;
22 |
23 | /**
24 | * @author 喝咖啡的囊地鼠
25 | * @date 2017/9/15 下午3:49
26 | */
27 |
28 | @Slf4j
29 | @Component
30 | public class MonitorNodeServerService {
31 |
32 | //缓存的本地服务列表
33 | private Map monitorNodeServerPool = new ConcurrentHashMap<>();
34 |
35 |
36 | @Autowired
37 | private ZookeeperConfig zookeeperConfig;
38 |
39 | private ZkUtils zkUtils;
40 |
41 |
42 | @PostConstruct
43 | public void init() {
44 | zkUtils = new ZkUtils();
45 | zkUtils.init(
46 | zookeeperConfig.getServers(),
47 | zookeeperConfig.getConnectionTimeout(),
48 | zookeeperConfig.getSessionTimeout(),
49 | zookeeperConfig.getMaxRetries(),
50 | zookeeperConfig.getRetriesSleepTime(),
51 | zookeeperConfig.getListenNamespaceNodeServer(),
52 | new ZkStateListener() {
53 | @Override
54 | public void connectedEvent(CuratorFramework curator, ConnectionState state) {
55 | log.info("MonitorNodeServer 链接zk成功");
56 | initNodeServerPool();
57 |
58 | }
59 |
60 | @Override
61 | public void reconnectedEvent(CuratorFramework curator, ConnectionState state) {
62 | log.info("MonitorNodeServer 重新链接zk成功");
63 | initNodeServerPool();
64 | }
65 |
66 | @Override
67 | public void lostEvent(CuratorFramework curator, ConnectionState state) {
68 | log.info("MonitorNodeServer 链接zk丢失");
69 | monitorNodeServerPool.clear();
70 | }
71 | });
72 | listenNodeServer();
73 |
74 | }
75 |
76 | @PreDestroy
77 | public void destory() {
78 | monitorNodeServerPool.clear();
79 | zkUtils.destory();
80 | }
81 |
82 |
83 | public List nodeServerLoader() {
84 | return monitorNodeServerPool.values().stream().collect(Collectors.toList());
85 | }
86 |
87 |
88 | private void initNodeServerPool() {
89 | monitorNodeServerPool.clear();
90 | Map datas = zkUtils.readTargetChildsData(ZkGroupEnum.NODE_SERVER.getValue());
91 | if (datas != null) {
92 | datas.forEach((k, v) -> monitorNodeServerPool.put(k, JSON.parseObject(v, NodeServerInfo.class)));
93 | }
94 | }
95 |
96 | private void listenNodeServer() {
97 | zkUtils.listenerPathChildrenCache(ZkGroupEnum.NODE_SERVER.getValue(), ((zkclient, event) -> {
98 | switch (event.getType()) {
99 | case CHILD_ADDED:
100 | addEvent(event);
101 | break;
102 | case CHILD_REMOVED:
103 | removeEvent(event);
104 | break;
105 | case CHILD_UPDATED:
106 | updateEvent(event);
107 | break;
108 | default:
109 | break;
110 |
111 | }
112 | }));
113 | }
114 |
115 | private void updateEvent(PathChildrenCacheEvent event) {
116 | String key = toKey(event);
117 | NodeServerInfo data = toNodeServerInfo(event);
118 | log.debug(" Monitor node event update! key:{}, data:{}", key, data);
119 | if (monitorNodeServerPool.containsKey(key)) {
120 | monitorNodeServerPool.put(key, data);
121 | }
122 | }
123 |
124 | private void removeEvent(PathChildrenCacheEvent event) {
125 | String key = toKey(event);
126 | NodeServerInfo data = toNodeServerInfo(event);
127 | log.debug(" Monitor node event remove! key:{}, data:{}", key, data);
128 | if (monitorNodeServerPool.containsKey(key)) {
129 | monitorNodeServerPool.remove(key);
130 | }
131 |
132 | }
133 |
134 | private void addEvent(PathChildrenCacheEvent event) {
135 | String key = toKey(event);
136 | NodeServerInfo data = toNodeServerInfo(event);
137 | log.debug(" Monitor node event add! key:{}, data:{}", key, data);
138 | if (!monitorNodeServerPool.containsKey(key)) {
139 | //开启node,加入到管理器
140 | monitorNodeServerPool.put(key, data);
141 | } else {
142 | log.error(" Monitor node already! {},{}", key, data);
143 | }
144 | }
145 |
146 |
147 | private String toKey(PathChildrenCacheEvent event) {
148 | String path = event.getData().getPath();
149 | return path.substring(path.lastIndexOf("/")).replaceAll("/", "");
150 | }
151 |
152 | private NodeServerInfo toNodeServerInfo(PathChildrenCacheEvent event) {
153 | return JSON.parseObject(event.getData().getData(), NodeServerInfo.class);
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/go-push-monitor/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8080
3 |
4 | go-push:
5 | zookeeper:
6 | servers: 192.168.99.100:32773
7 | listen-namespace-node-server: namespace-node-server
8 | listen-namespace-data-center: namespace-data-center
9 | session-timeout: 6000
10 | connection-timeout: 6000
11 | max-retries: 1000
12 | retries-sleep-time: 2000
13 |
14 |
15 | spring:
16 | thymeleaf:
17 | cache: false
18 |
19 | swagger:
20 | title: GoPush 监控中心接口
21 | description: ${swagger.title}文档说明
22 | version: ${application.version}
23 | license: GoPush 许可
24 | license-url: https://gitee.com/openWolf/gopush/blob/master/LICENSE
25 | terms-of-service-url: https://gitee.com/openWolf/gopush/issues/new
26 | contact:
27 | name: 喝咖啡的囊地鼠
28 | url: https://gitee.com/openWolf/gopush
29 | email: null_hello@qq.com
30 | base-package: com.gopush.monitor.controller
31 | base-path: /**
32 | exclude-path: /error,/ops/**
--------------------------------------------------------------------------------
/go-push-monitor/src/main/resources/banner.txt:
--------------------------------------------------------------------------------
1 | ${AnsiColor.BRIGHT_GREEN}
2 | __ __ _ _
3 | | \/ | (_) |
4 | | \ / | ___ _ __ _| |_ ___ _ __
5 | | |\/| |/ _ \| '_ \| | __/ _ \| '__| _____ _____ _
6 | | | | | (_) | | | | | || (_) | | / ____| | __ \ | |
7 | |_|__|_|\___/|_|_|_|_|\__\___/|_|__ ______ ______ ______ ______ ______ ______ | | __ ___ | |__) | _ ___| |__
8 | |______|______|______|______|______|______|______|______|______|______|______| | | |_ |/ _ \| ___/ | | / __| '_ \
9 | | |__| | (_) | | | |_| \__ \ | | |
10 | \_____|\___/|_| \__,_|___/_| |_|
11 |
12 | ${AnsiColor.BRIGHT_RED}
13 | Application Version: ${application.version}${application.formatted-version}
14 | Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
--------------------------------------------------------------------------------
/go-push-monitor/src/main/resources/templates/monitor.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 监控中心
6 |
7 |
8 | Hello World
9 |
10 |
--------------------------------------------------------------------------------
/go-push-monitor/src/test/java/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkhello/gopush/94bbbb40b2bc20196c0388a2a8482c6cb00909df/go-push-monitor/src/test/java/.gitignore
--------------------------------------------------------------------------------
/go-push-node-server/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | go-push
7 | com.gopush
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | go-push-node-server
12 | jar
13 | NodeServer 服务
14 |
15 |
16 |
17 |
18 | com.gopush
19 | go-push-common
20 | ${project.version}
21 |
22 |
23 | com.gopush
24 | go-push-handler-node
25 | ${project.version}
26 |
27 |
28 | com.gopush
29 | go-push-handler-device
30 | ${project.version}
31 |
32 |
33 | com.gopush
34 | go-push-infos
35 | ${project.version}
36 |
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-starter-data-redis
41 |
42 |
43 |
44 | org.springframework.boot
45 | spring-boot-starter
46 |
47 |
48 |
49 | org.springframework.boot
50 | spring-boot-starter-web
51 |
52 |
53 |
54 | org.projectlombok
55 | lombok
56 |
57 |
58 |
59 | io.netty
60 | netty-all
61 |
62 |
63 |
64 | commons-collections
65 | commons-collections
66 |
67 |
68 |
69 | org.apache.commons
70 | commons-lang3
71 |
72 |
73 |
74 | org.apache.curator
75 | curator-recipes
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/go-push-node-server/src/main/java/com/gopush/nodeserver/NodeServerApplication.java:
--------------------------------------------------------------------------------
1 | package com.gopush.nodeserver;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.scheduling.annotation.EnableAsync;
6 |
7 | /**
8 | * go-push
9 | *
10 | * @类功能说明:
11 | * @作者:喝咖啡的囊地鼠
12 | * @创建时间:2017/6/11 上午11:43
13 | * @VERSION:
14 | */
15 | @EnableAsync
16 | @SpringBootApplication
17 | public class NodeServerApplication {
18 |
19 | public static void main(String[] args) {
20 | SpringApplication.run(NodeServerApplication.class, args);
21 | }
22 |
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/go-push-node-server/src/main/java/com/gopush/nodeserver/config/BatchProcessorConfig.java:
--------------------------------------------------------------------------------
1 | package com.gopush.nodeserver.config;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.context.annotation.Configuration;
6 |
7 | /**
8 | * @author 喝咖啡的囊地鼠
9 | * @date 2017/9/11 下午11:33
10 | */
11 | @Data
12 | @Configuration
13 | @ConfigurationProperties(prefix = "go-push.node-server.batch-processor")
14 | public class BatchProcessorConfig {
15 | /**
16 | * 批量处理的定时器延时
17 | */
18 | private int delay;
19 | /**
20 | * 批量处理的大小
21 | */
22 | private int batchSize;
23 | /**
24 | * 消息队列里面超过这个大小就要进行告警
25 | */
26 | private int warnThreshold;
27 | /**
28 | * 子处理器的个数
29 | */
30 | private int processorSize;
31 |
32 | /**
33 | * 不指定线程池的时候,指定初始化默认创建的线程池的大小
34 | */
35 | private int corePoolSize;
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/go-push-node-server/src/main/java/com/gopush/nodeserver/config/GoPushNodeServerConfig.java:
--------------------------------------------------------------------------------
1 | package com.gopush.nodeserver.config;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.context.annotation.Configuration;
6 |
7 | /**
8 | * @author 喝咖啡的囊地鼠
9 | * @date 2017/9/11 下午11:02
10 | */
11 | @Data
12 | @Configuration
13 | @ConfigurationProperties(prefix = "go-push.node-server")
14 | public class GoPushNodeServerConfig {
15 | private String name;
16 | private int nodePort;
17 | private int devicePort;
18 | }
19 |
--------------------------------------------------------------------------------
/go-push-node-server/src/main/java/com/gopush/nodeserver/config/ZookeeperConfig.java:
--------------------------------------------------------------------------------
1 | package com.gopush.nodeserver.config;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.context.annotation.Configuration;
6 |
7 | /**
8 | * @author 喝咖啡的囊地鼠
9 | * @date 2017/9/11 下午11:44
10 | */
11 | @Data
12 | @Configuration
13 | @ConfigurationProperties(prefix = "go-push.zookeeper")
14 | public class ZookeeperConfig {
15 |
16 | private String servers;
17 |
18 | private String namespace;
19 |
20 | private String listenNamespace;
21 |
22 | private int sessionTimeout;
23 |
24 | private int connectionTimeout;
25 |
26 | private int maxRetries;
27 |
28 | private int retriesSleepTime;
29 | }
30 |
--------------------------------------------------------------------------------
/go-push-node-server/src/main/java/com/gopush/nodeserver/devices/DeviceServerBootstrap.java:
--------------------------------------------------------------------------------
1 | package com.gopush.nodeserver.devices;
2 |
3 | import com.gopush.nodeserver.config.GoPushNodeServerConfig;
4 | import com.gopush.nodeserver.devices.inbound.DeviceChannelInboundHandler;
5 | import io.netty.bootstrap.ServerBootstrap;
6 | import io.netty.channel.ChannelInitializer;
7 | import io.netty.channel.ChannelOption;
8 | import io.netty.channel.ChannelPipeline;
9 | import io.netty.channel.EventLoopGroup;
10 | import io.netty.channel.nio.NioEventLoopGroup;
11 | import io.netty.channel.socket.SocketChannel;
12 | import io.netty.channel.socket.nio.NioServerSocketChannel;
13 | import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
14 | import io.netty.handler.codec.LengthFieldPrepender;
15 | import io.netty.handler.codec.string.StringDecoder;
16 | import io.netty.handler.codec.string.StringEncoder;
17 | import io.netty.handler.logging.LoggingHandler;
18 | import io.netty.handler.timeout.IdleStateHandler;
19 | import io.netty.util.CharsetUtil;
20 | import lombok.extern.slf4j.Slf4j;
21 | import org.springframework.beans.factory.annotation.Autowired;
22 | import org.springframework.stereotype.Component;
23 |
24 | import javax.annotation.PostConstruct;
25 | import javax.annotation.PreDestroy;
26 |
27 | /**
28 | * go-push
29 | *
30 | * @类功能说明:设备服务启动器
31 | * @作者:喝咖啡的囊地鼠
32 | * @创建时间:2017/6/18 下午10:59
33 | * @VERSION:
34 | */
35 |
36 | @Slf4j
37 | @Component
38 | public class DeviceServerBootstrap {
39 |
40 | private EventLoopGroup bossGroup = new NioEventLoopGroup();
41 | private EventLoopGroup workGroup = new NioEventLoopGroup();
42 |
43 | @Autowired
44 | private GoPushNodeServerConfig goPushNodeServerConfig;
45 |
46 | @Autowired
47 | private DeviceChannelInboundHandler deviceChannelInboundHandler;
48 |
49 | @PostConstruct
50 | public void start() throws Exception {
51 |
52 |
53 | ServerBootstrap bootstrap = new ServerBootstrap();
54 | bootstrap.group(bossGroup, workGroup)
55 | .channelFactory(NioServerSocketChannel::new)
56 | .childHandler(new ChannelInitializer() {
57 | @Override
58 | protected void initChannel(SocketChannel socketChannel) throws Exception {
59 |
60 | ChannelPipeline pipeline = socketChannel.pipeline();
61 | pipeline.addLast("logHandler", new LoggingHandler());
62 | pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
63 | pipeline.addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));
64 | pipeline.addLast("frameEncoder", new LengthFieldPrepender(4));
65 | pipeline.addLast("stringEncoder", new StringEncoder(CharsetUtil.UTF_8));
66 | pipeline.addLast("idleStateHandler", new IdleStateHandler(300, 0, 0));
67 |
68 | pipeline.addLast("handler", deviceChannelInboundHandler);
69 | }
70 | })
71 |
72 | .option(ChannelOption.SO_BACKLOG, 1000000) //连接队列深度
73 | .option(ChannelOption.TCP_NODELAY, true) //设置 no_delay
74 | .option(ChannelOption.SO_SNDBUF, 2048).option(ChannelOption.SO_RCVBUF, 1024)
75 | .childOption(ChannelOption.TCP_NODELAY, true)
76 | .childOption(ChannelOption.SO_REUSEADDR, true)
77 | .childOption(ChannelOption.SO_SNDBUF, 2048).childOption(ChannelOption.SO_RCVBUF, 1024)
78 | .childOption(ChannelOption.SO_LINGER, 0);
79 |
80 | bootstrap.bind(goPushNodeServerConfig.getDevicePort()).sync();
81 | log.info("device server start successful! listening port: {}", goPushNodeServerConfig.getDevicePort());
82 | }
83 |
84 |
85 | @PreDestroy
86 | public void destory() {
87 | bossGroup.shutdownGracefully();
88 | workGroup.shutdownGracefully();
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/go-push-node-server/src/main/java/com/gopush/nodeserver/devices/handlers/DeviceDeviceDisconnectHandler.java:
--------------------------------------------------------------------------------
1 | package com.gopush.nodeserver.devices.handlers;
2 |
3 | import com.gopush.common.Constants;
4 | import com.gopush.common.constants.RedisKeyEnum;
5 | import com.gopush.common.utils.ip.IpUtils;
6 | import com.gopush.devices.handlers.IDeviceDisconnectHandler;
7 | import com.gopush.nodeserver.devices.BatchProcessor;
8 | import com.gopush.nodeserver.devices.stores.IDeviceChannelStore;
9 | import com.gopush.nodeserver.nodes.senders.INodeSender;
10 | import com.gopush.protocol.node.DeviceDisconReq;
11 | import io.netty.channel.Channel;
12 | import lombok.extern.slf4j.Slf4j;
13 | import org.apache.commons.collections.CollectionUtils;
14 | import org.apache.commons.lang3.StringUtils;
15 | import org.springframework.beans.factory.annotation.Autowired;
16 | import org.springframework.data.redis.core.RedisTemplate;
17 | import org.springframework.stereotype.Component;
18 |
19 | import java.util.List;
20 |
21 | /**
22 | * go-push
23 | *
24 | * @类功能说明: 批处理设备断连接后需要触发上报
25 | * @作者:喝咖啡的囊地鼠
26 | * @创建时间:2017/6/19 上午12:25
27 | * @VERSION:
28 | */
29 |
30 | @Slf4j
31 | @Component
32 | public class DeviceDeviceDisconnectHandler extends BatchProcessor