正在显示
9 个修改的文件
包含
411 行增加
和
1 行删除
| @@ -16,6 +16,12 @@ | @@ -16,6 +16,12 @@ | ||
| 16 | <dependency> | 16 | <dependency> |
| 17 | <groupId>com.crossoverjie.netty</groupId> | 17 | <groupId>com.crossoverjie.netty</groupId> |
| 18 | <artifactId>netty-action-common</artifactId> | 18 | <artifactId>netty-action-common</artifactId> |
| 19 | + <exclusions> | ||
| 20 | + <exclusion> | ||
| 21 | + <artifactId>log4j</artifactId> | ||
| 22 | + <groupId>log4j</groupId> | ||
| 23 | + </exclusion> | ||
| 24 | + </exclusions> | ||
| 19 | </dependency> | 25 | </dependency> |
| 20 | 26 | ||
| 21 | 27 | ||
| @@ -60,6 +66,15 @@ | @@ -60,6 +66,15 @@ | ||
| 60 | <groupId>ch.qos.logback</groupId> | 66 | <groupId>ch.qos.logback</groupId> |
| 61 | <artifactId>logback-classic</artifactId> | 67 | <artifactId>logback-classic</artifactId> |
| 62 | </dependency> | 68 | </dependency> |
| 69 | + <dependency> | ||
| 70 | + <groupId>org.slf4j</groupId> | ||
| 71 | + <artifactId>slf4j-api</artifactId> | ||
| 72 | + </dependency> | ||
| 73 | + <dependency> | ||
| 74 | + <groupId>ch.qos.logback</groupId> | ||
| 75 | + <artifactId>logback-core</artifactId> | ||
| 76 | + </dependency> | ||
| 77 | + | ||
| 63 | 78 | ||
| 64 | <dependency> | 79 | <dependency> |
| 65 | <groupId>junit</groupId> | 80 | <groupId>junit</groupId> |
| 1 | package com.crossoverjie.netty.action.zk; | 1 | package com.crossoverjie.netty.action.zk; |
| 2 | 2 | ||
| 3 | +import com.crossoverjie.netty.action.zk.thread.RegistryZK; | ||
| 4 | +import com.crossoverjie.netty.action.zk.util.AppConfiguration; | ||
| 5 | +import com.crossoverjie.netty.action.zk.util.ZKUtil; | ||
| 3 | import org.slf4j.Logger; | 6 | import org.slf4j.Logger; |
| 4 | import org.slf4j.LoggerFactory; | 7 | import org.slf4j.LoggerFactory; |
| 8 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 5 | import org.springframework.boot.CommandLineRunner; | 9 | import org.springframework.boot.CommandLineRunner; |
| 6 | import org.springframework.boot.SpringApplication; | 10 | import org.springframework.boot.SpringApplication; |
| 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; | 11 | import org.springframework.boot.autoconfigure.SpringBootApplication; |
| 8 | 12 | ||
| 13 | +import java.net.InetAddress; | ||
| 14 | + | ||
| 9 | /** | 15 | /** |
| 10 | * @author crossoverJie | 16 | * @author crossoverJie |
| 11 | */ | 17 | */ |
| @@ -14,14 +20,24 @@ public class Application implements CommandLineRunner{ | @@ -14,14 +20,24 @@ public class Application implements CommandLineRunner{ | ||
| 14 | 20 | ||
| 15 | private final static Logger LOGGER = LoggerFactory.getLogger(Application.class); | 21 | private final static Logger LOGGER = LoggerFactory.getLogger(Application.class); |
| 16 | 22 | ||
| 23 | + @Autowired | ||
| 24 | + private AppConfiguration appConfiguration ; | ||
| 17 | 25 | ||
| 26 | + @Autowired | ||
| 27 | + private static ZKUtil zkUtil ; | ||
| 18 | 28 | ||
| 19 | public static void main(String[] args) { | 29 | public static void main(String[] args) { |
| 20 | SpringApplication.run(Application.class, args); | 30 | SpringApplication.run(Application.class, args); |
| 21 | LOGGER.info("启动应用成功"); | 31 | LOGGER.info("启动应用成功"); |
| 32 | + | ||
| 22 | } | 33 | } |
| 23 | 34 | ||
| 24 | @Override | 35 | @Override |
| 25 | public void run(String... args) throws Exception { | 36 | public void run(String... args) throws Exception { |
| 37 | + //获得本机IP | ||
| 38 | + String addr = InetAddress.getLocalHost().getHostAddress(); | ||
| 39 | + Thread thread = new Thread(new RegistryZK(addr, appConfiguration.getPort())); | ||
| 40 | + thread.setName("registry-zk"); | ||
| 41 | + thread.start() ; | ||
| 26 | } | 42 | } |
| 27 | } | 43 | } |
| 1 | +package com.crossoverjie.netty.action.zk.cache; | ||
| 2 | + | ||
| 3 | +import com.crossoverjie.netty.action.zk.util.ZKUtil; | ||
| 4 | +import com.google.common.cache.LoadingCache; | ||
| 5 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 6 | +import org.springframework.stereotype.Component; | ||
| 7 | + | ||
| 8 | +import java.util.ArrayList; | ||
| 9 | +import java.util.List; | ||
| 10 | +import java.util.Map; | ||
| 11 | +import java.util.concurrent.atomic.AtomicLong; | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * Function: 服务器节点缓存 | ||
| 15 | + * | ||
| 16 | + * @author crossoverJie | ||
| 17 | + * Date: 2018/8/19 01:31 | ||
| 18 | + * @since JDK 1.8 | ||
| 19 | + */ | ||
| 20 | +@Component | ||
| 21 | +public class ServerCache { | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + @Autowired | ||
| 25 | + private LoadingCache<String,String> cache ; | ||
| 26 | + | ||
| 27 | + @Autowired | ||
| 28 | + private ZKUtil zkUtil ; | ||
| 29 | + | ||
| 30 | + private AtomicLong index = new AtomicLong() ; | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + public void addCache(String key){ | ||
| 34 | + cache.put(key, key); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 更新所有缓存/先删除 再新增 | ||
| 40 | + * @param currentChilds | ||
| 41 | + */ | ||
| 42 | + public void updateCache(List<String> currentChilds){ | ||
| 43 | + cache.invalidateAll() ; | ||
| 44 | + for (String currentChild : currentChilds) { | ||
| 45 | + String key = currentChild.split("-")[1] ; | ||
| 46 | + addCache(key) ; | ||
| 47 | + } | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * 获取所有的服务列表 | ||
| 53 | + * @return | ||
| 54 | + */ | ||
| 55 | + public List<String> getAll(){ | ||
| 56 | + | ||
| 57 | + List<String> list = new ArrayList<>() ; | ||
| 58 | + | ||
| 59 | + if (cache.size() == 0){ | ||
| 60 | + List<String> allNode = zkUtil.getAllNode(); | ||
| 61 | + for (String node : allNode) { | ||
| 62 | + String key = node.split("-")[1] ; | ||
| 63 | + addCache(key) ; | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + for (Map.Entry<String, String> entry : cache.asMap().entrySet()) { | ||
| 67 | + list.add(entry.getKey()); | ||
| 68 | + } | ||
| 69 | + return list ; | ||
| 70 | + | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + /** | ||
| 74 | + * 选取服务器 | ||
| 75 | + * @return | ||
| 76 | + */ | ||
| 77 | + public String selectServer(){ | ||
| 78 | + List<String> all = getAll(); | ||
| 79 | + if (all.size() == 0){ | ||
| 80 | + throw new RuntimeException("路由列表为空") ; | ||
| 81 | + } | ||
| 82 | + Long position = index.incrementAndGet() % all.size(); | ||
| 83 | + if (position < 0){ | ||
| 84 | + position = 0L ; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + return all.get(position.intValue()) ; | ||
| 88 | + } | ||
| 89 | +} |
| 1 | +package com.crossoverjie.netty.action.zk.config; | ||
| 2 | + | ||
| 3 | +import com.crossoverjie.netty.action.zk.util.AppConfiguration; | ||
| 4 | +import com.google.common.cache.CacheBuilder; | ||
| 5 | +import com.google.common.cache.CacheLoader; | ||
| 6 | +import com.google.common.cache.LoadingCache; | ||
| 7 | +import org.I0Itec.zkclient.ZkClient; | ||
| 8 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 9 | +import org.springframework.beans.factory.annotation.Value; | ||
| 10 | +import org.springframework.context.annotation.Bean; | ||
| 11 | +import org.springframework.context.annotation.Configuration; | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * Function: | ||
| 15 | + * | ||
| 16 | + * @author crossoverJie | ||
| 17 | + * Date: 2018/8/24 01:28 | ||
| 18 | + * @since JDK 1.8 | ||
| 19 | + */ | ||
| 20 | +@Configuration | ||
| 21 | +public class AppConfig { | ||
| 22 | + | ||
| 23 | + @Autowired | ||
| 24 | + private AppConfiguration appConfiguration ; | ||
| 25 | + | ||
| 26 | + @Bean | ||
| 27 | + public ZkClient buildZKClient(){ | ||
| 28 | + return new ZkClient(appConfiguration.getZkAddr(), 5000); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + @Bean | ||
| 33 | + public LoadingCache<String,String> buildCache(){ | ||
| 34 | + return CacheBuilder.newBuilder() | ||
| 35 | + .build(new CacheLoader<String, String>() { | ||
| 36 | + @Override | ||
| 37 | + public String load(String s) throws Exception { | ||
| 38 | + return null; | ||
| 39 | + } | ||
| 40 | + }); | ||
| 41 | + } | ||
| 42 | +} |
| 1 | +package com.crossoverjie.netty.action.zk.thread; | ||
| 2 | + | ||
| 3 | +import com.crossoverjie.netty.action.zk.util.AppConfiguration; | ||
| 4 | +import com.crossoverjie.netty.action.zk.util.SpringBeanFactory; | ||
| 5 | +import com.crossoverjie.netty.action.zk.util.ZKUtil; | ||
| 6 | +import org.slf4j.Logger; | ||
| 7 | +import org.slf4j.LoggerFactory; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * Function: | ||
| 11 | + * | ||
| 12 | + * @author crossoverJie | ||
| 13 | + * Date: 2018/8/24 01:37 | ||
| 14 | + * @since JDK 1.8 | ||
| 15 | + */ | ||
| 16 | +public class RegistryZK implements Runnable { | ||
| 17 | + | ||
| 18 | + private static Logger logger = LoggerFactory.getLogger(RegistryZK.class); | ||
| 19 | + | ||
| 20 | + private ZKUtil zkUtil; | ||
| 21 | + | ||
| 22 | + private AppConfiguration appConfiguration ; | ||
| 23 | + | ||
| 24 | + private String ip; | ||
| 25 | + private int port; | ||
| 26 | + | ||
| 27 | + public RegistryZK(String ip, int port) { | ||
| 28 | + this.ip = ip; | ||
| 29 | + this.port = port; | ||
| 30 | + zkUtil = SpringBeanFactory.getBean(ZKUtil.class) ; | ||
| 31 | + appConfiguration = SpringBeanFactory.getBean(AppConfiguration.class) ; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + @Override | ||
| 35 | + public void run() { | ||
| 36 | + | ||
| 37 | + //创建父节点 | ||
| 38 | + zkUtil.createRootNode(); | ||
| 39 | + | ||
| 40 | + //是否要将自己注册到 ZK | ||
| 41 | + if (appConfiguration.isZkSwitch()){ | ||
| 42 | + String path = appConfiguration.getZkRoot() + "/ip-" + ip + ":" + port; | ||
| 43 | + zkUtil.createNode(path, path); | ||
| 44 | + logger.info("注册 zookeeper 成功,msg=[{}]", path); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + //注册监听服务 | ||
| 48 | + zkUtil.subscribeEvent(appConfiguration.getZkRoot()); | ||
| 49 | + | ||
| 50 | + } | ||
| 51 | +} |
netty-action-zk/src/main/java/com/crossoverjie/netty/action/zk/util/AppConfiguration.java
0 → 100644
| 1 | +package com.crossoverjie.netty.action.zk.util; | ||
| 2 | + | ||
| 3 | +import org.springframework.beans.factory.annotation.Value; | ||
| 4 | +import org.springframework.stereotype.Component; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * Function: | ||
| 8 | + * | ||
| 9 | + * @author crossoverJie | ||
| 10 | + * Date: 2018/8/24 01:43 | ||
| 11 | + * @since JDK 1.8 | ||
| 12 | + */ | ||
| 13 | +@Component | ||
| 14 | +public class AppConfiguration { | ||
| 15 | + | ||
| 16 | + @Value("${app.zk.root}") | ||
| 17 | + private String zkRoot; | ||
| 18 | + | ||
| 19 | + @Value("${app.zk.addr}") | ||
| 20 | + private String zkAddr; | ||
| 21 | + | ||
| 22 | + @Value("${app.zk.switch}") | ||
| 23 | + private boolean zkSwitch; | ||
| 24 | + | ||
| 25 | + @Value("${server.port}") | ||
| 26 | + private int port; | ||
| 27 | + | ||
| 28 | + public int getPort() { | ||
| 29 | + return port; | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + public void setPort(int port) { | ||
| 33 | + this.port = port; | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + public String getZkRoot() { | ||
| 37 | + return zkRoot; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + public void setZkRoot(String zkRoot) { | ||
| 41 | + this.zkRoot = zkRoot; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + public String getZkAddr() { | ||
| 45 | + return zkAddr; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + public void setZkAddr(String zkAddr) { | ||
| 49 | + this.zkAddr = zkAddr; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + public boolean isZkSwitch() { | ||
| 53 | + return zkSwitch; | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + public void setZkSwitch(boolean zkSwitch) { | ||
| 57 | + this.zkSwitch = zkSwitch; | ||
| 58 | + } | ||
| 59 | +} |
netty-action-zk/src/main/java/com/crossoverjie/netty/action/zk/util/SpringBeanFactory.java
0 → 100644
| 1 | +package com.crossoverjie.netty.action.zk.util; | ||
| 2 | + | ||
| 3 | +import org.springframework.beans.BeansException; | ||
| 4 | +import org.springframework.context.ApplicationContext; | ||
| 5 | +import org.springframework.context.ApplicationContextAware; | ||
| 6 | +import org.springframework.stereotype.Component; | ||
| 7 | + | ||
| 8 | +@Component | ||
| 9 | +public final class SpringBeanFactory implements ApplicationContextAware{ | ||
| 10 | + private static ApplicationContext context; | ||
| 11 | + | ||
| 12 | + public static <T> T getBean(Class<T> c){ | ||
| 13 | + return context.getBean(c); | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + public static <T> T getBean(String name,Class<T> clazz){ | ||
| 18 | + return context.getBean(name,clazz); | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + @Override | ||
| 22 | + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { | ||
| 23 | + context = applicationContext; | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + | ||
| 27 | +} |
| 1 | +package com.crossoverjie.netty.action.zk.util; | ||
| 2 | + | ||
| 3 | +import com.alibaba.fastjson.JSON; | ||
| 4 | +import com.crossoverjie.netty.action.zk.cache.ServerCache; | ||
| 5 | +import org.I0Itec.zkclient.IZkChildListener; | ||
| 6 | +import org.I0Itec.zkclient.ZkClient; | ||
| 7 | +import org.slf4j.Logger; | ||
| 8 | +import org.slf4j.LoggerFactory; | ||
| 9 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 10 | +import org.springframework.stereotype.Component; | ||
| 11 | + | ||
| 12 | +import java.util.List; | ||
| 13 | + | ||
| 14 | +/** | ||
| 15 | + * Function: Zookeeper 工具 | ||
| 16 | + * | ||
| 17 | + * @author crossoverJie | ||
| 18 | + * Date: 2018/8/19 00:33 | ||
| 19 | + * @since JDK 1.8 | ||
| 20 | + */ | ||
| 21 | +@Component | ||
| 22 | +public class ZKUtil { | ||
| 23 | + | ||
| 24 | + private static Logger logger = LoggerFactory.getLogger(ZKUtil.class); | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + @Autowired | ||
| 28 | + private ZkClient zkClient; | ||
| 29 | + | ||
| 30 | + @Autowired | ||
| 31 | + private AppConfiguration appConfiguration ; | ||
| 32 | + | ||
| 33 | + @Autowired | ||
| 34 | + private ServerCache serverCache ; | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * 创建父级节点 | ||
| 39 | + */ | ||
| 40 | + public void createRootNode(){ | ||
| 41 | + boolean exists = zkClient.exists(appConfiguration.getZkRoot()); | ||
| 42 | + if (exists){ | ||
| 43 | + return; | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + //创建 root | ||
| 47 | + zkClient.createPersistent(appConfiguration.getZkRoot()) ; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + /** | ||
| 51 | + * 写入指定节点 临时目录 | ||
| 52 | + * | ||
| 53 | + * @param path | ||
| 54 | + * @param value | ||
| 55 | + */ | ||
| 56 | + public void createNode(String path, String value) { | ||
| 57 | + zkClient.createEphemeral(path, value); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + | ||
| 61 | + /** | ||
| 62 | + * 监听事件 | ||
| 63 | + * | ||
| 64 | + * @param path | ||
| 65 | + */ | ||
| 66 | + public void subscribeEvent(String path) { | ||
| 67 | + zkClient.subscribeChildChanges(path, new IZkChildListener() { | ||
| 68 | + @Override | ||
| 69 | + public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception { | ||
| 70 | + logger.info("清除/更新本地缓存 parentPath=【{}】,currentChilds=【{}】", parentPath,currentChilds.toString()); | ||
| 71 | + | ||
| 72 | + //更新所有缓存/先删除 再新增 | ||
| 73 | + serverCache.updateCache(currentChilds) ; | ||
| 74 | + } | ||
| 75 | + }); | ||
| 76 | + | ||
| 77 | + | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + | ||
| 81 | + /** | ||
| 82 | + * 获取所有注册节点 | ||
| 83 | + * @return | ||
| 84 | + */ | ||
| 85 | + public List<String> getAllNode(){ | ||
| 86 | + List<String> children = zkClient.getChildren("/route"); | ||
| 87 | + logger.info("查询所有节点成功=【{}】", JSON.toJSONString(children)); | ||
| 88 | + return children; | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + /** | ||
| 92 | + * 关闭 ZK | ||
| 93 | + */ | ||
| 94 | + public void closeZK() { | ||
| 95 | + logger.info("正在关闭 ZK"); | ||
| 96 | + zkClient.close(); | ||
| 97 | + logger.info("关闭 ZK 成功"); | ||
| 98 | + | ||
| 99 | + } | ||
| 100 | +} |
| @@ -6,4 +6,15 @@ server.port=8083 | @@ -6,4 +6,15 @@ server.port=8083 | ||
| 6 | # 是否打开swagger | 6 | # 是否打开swagger |
| 7 | swagger.enable = true | 7 | swagger.enable = true |
| 8 | 8 | ||
| 9 | -logging.level.root=info | ||
| 9 | +logging.level.root=info | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | +# 是否注册 zk | ||
| 14 | +app.zk.switch=true | ||
| 15 | + | ||
| 16 | +# zk 地址 | ||
| 17 | +app.zk.addr=10.1.241.103:2181 | ||
| 18 | + | ||
| 19 | +# zk 注册根节点 | ||
| 20 | +app.zk.root=/route |
-
请 注册 或 登录 后发表评论