# zkNettyWork **Repository Path**: zhayan/zk-netty-work ## Basic Information - **Project Name**: zkNettyWork - **Description**: netty模拟rpc服务,并实现zookeeper的注册、监听 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2021-12-08 - **Last Updated**: 2022-05-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: Netty, zookeeper, Java ## README ### netty+zookeeper #### 介绍 使用netty模拟rpc调用,并在zookeeper实现服务注册、服务发现。服务端注册、客户端发现与动态监听。 zk的连接使用Curator。 [运行测试视频](doc/运行测试.mkv) ##### zookeeper服务注册 1. ZkServer[源码](rpc/src/main/java/wsz/rpc/zk/ZkServer.java):连接zk 2. 节点信息:/wsz/nettyHost:nettyPort = {"time":****, "handle": ***};time为上次请求时间,handle为上次请求处理的时间 3. 服务启动时创建(或更新)临时节点;开启监听NodeCahe。**实现服务注册** 4. RpcServer:连接Netty通道,创建ZkServer对象。 ##### zookeeper服务发现 ZkClient[源码](rpc/src/main/java/wsz/rpc/zk/ZkClient.java): 1. 连接zk 2. initRpcClients:获取主节点/wsz的所有子节点信息,生成RpcClient并缓存到clientList中 3. randomClient:clientList中获取handle排序最小的RpcClient,即优先使用耗时最低的连接。请求结束后timeCahe保存当前的请求信息time&handle 4. bindListener:监听/wsz子节点变化CHILD_ADDED/CHILD_DELETE/CHILD_UPDATED,每次监听后clientList根据handle排序。 5. 节点增加:新增RpcClient;节点删除:删除RpcClient;节点更新:用于clientList的重排序,若handle > 5000则为节点下线。**实现服务发现与负载均衡** 6. ZkTask:提供定时线程池,每5s秒使用timeCahe更新节点的内容,触发第四步的监听事件并更新clientList的信息。 ##### 模拟 1. provider*.UserServiceImpl:localhost:8080/user/4,Thread.sleep(random)进行模拟业务的请求耗时。 2. provider1:[源码](provider1/src/main/java/wsz/provider1/service/UserServiceImpl.java) 3. provider2:[源码](provider2/src/main/java/wsz/provider2/service/UserServiceImpl.java) ![服务端1](doc/provider1.png) ![服务端2](doc/provider2.png) ##### 缺点与不足 1. 负载均衡方式:缓存每次请求的信息,定时更新zk的节点信息;在监听节点更新事件中,获取handle重新赋值RpcClient,然后再重新排序。此方法存在延时。 2. 负载均衡:**每次重新获取所有服务端临时节点的RpcClient;代码动态维护临时节点的排序**;本次使用了后者。 3. 监听机制延后:如果节点下线,**删除节点的事件监听延后,会导致异常出现**。可以每次负载均衡时,直接再请求所有可用节点。