/xian-zookeeper/src/main/java/info/xiancloud/zookeeper/service_discovery_new/group/ZkGroupDiscovery.java

https://github.com/happyyangyuan/xian · Java · 216 lines · 184 code · 18 blank · 14 comment · 8 complexity · 025ec2f4a917ee374df03b0614fff500 MD5 · raw file

  1. package info.xiancloud.zookeeper.service_discovery_new.group;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.google.common.cache.CacheBuilder;
  4. import com.google.common.cache.CacheLoader;
  5. import com.google.common.cache.LoadingCache;
  6. import com.google.common.cache.RemovalListener;
  7. import info.xiancloud.core.LocalUnitsManager;
  8. import info.xiancloud.core.distribution.GroupProxy;
  9. import info.xiancloud.core.distribution.service_discovery.GroupDiscovery;
  10. import info.xiancloud.core.distribution.service_discovery.GroupInstance;
  11. import info.xiancloud.core.distribution.service_discovery.GroupInstanceIdBean;
  12. import info.xiancloud.core.util.LOG;
  13. import info.xiancloud.zookeeper.ZkConnection;
  14. import info.xiancloud.zookeeper.ZkPathManager;
  15. import info.xiancloud.zookeeper.service_discovery_new.ZkServiceInstanceAdaptor;
  16. import org.apache.curator.x.discovery.ServiceDiscovery;
  17. import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
  18. import org.apache.curator.x.discovery.ServiceInstance;
  19. import org.apache.curator.x.discovery.ServiceProvider;
  20. import org.apache.curator.x.discovery.details.FastjsonServiceDefinitionSerializer;
  21. import org.apache.curator.x.discovery.details.InstanceProvider;
  22. import java.io.IOException;
  23. import java.util.ArrayList;
  24. import java.util.Collection;
  25. import java.util.List;
  26. import java.util.concurrent.TimeUnit;
  27. /**
  28. * @author happyyangyuan
  29. */
  30. public class ZkGroupDiscovery implements GroupDiscovery {
  31. private ServiceDiscovery<GroupProxy> serviceDiscovery;
  32. private LoadingCache<String, ServiceProvider<GroupProxy>> serviceProviders = CacheBuilder.newBuilder()
  33. .expireAfterAccess(30, TimeUnit.MINUTES)//30分钟后没人使用就释放这个监听器
  34. .removalListener((RemovalListener<String, ServiceProvider<GroupProxy>>) notification -> {
  35. try {
  36. //释放watcher
  37. notification.getValue().close();
  38. } catch (IOException e) {
  39. LOG.error(e);
  40. }
  41. })
  42. .build(new CacheLoader<String, ServiceProvider<GroupProxy>>() {
  43. @Override
  44. public ServiceProvider<GroupProxy> load(String groupName) throws Exception {
  45. ServiceProvider<GroupProxy> serviceProvider = serviceDiscovery.serviceProviderBuilder()
  46. .serviceName(groupName)
  47. .build();
  48. serviceProvider.start();
  49. return serviceProvider;
  50. }
  51. });
  52. private LoadingCache<String, InstanceProvider<GroupProxy>> nonCachedInstanceProviders = CacheBuilder.newBuilder()
  53. .build(new CacheLoader<String, InstanceProvider<GroupProxy>>() {
  54. @Override
  55. public InstanceProvider<GroupProxy> load(String groupName) throws Exception {
  56. return new InstanceProvider<GroupProxy>() {
  57. @Override
  58. public List<ServiceInstance<GroupProxy>> getInstances() throws Exception {
  59. return (List<ServiceInstance<GroupProxy>>) serviceDiscovery.queryForInstances(groupName);
  60. }
  61. @Override
  62. public ServiceInstance<GroupProxy> getInstance(String id) {
  63. try {
  64. return serviceDiscovery.queryForInstance(groupName, id);
  65. } catch (Exception e) {
  66. throw new RuntimeException(e);
  67. }
  68. }
  69. };
  70. }
  71. });
  72. public void init() {
  73. serviceDiscovery = ServiceDiscoveryBuilder.builder(GroupProxy.class)
  74. .basePath(ZkPathManager.getGroupBasePath())
  75. .serializer(new ZkServiceInstanceSerializer())
  76. .serializer(new FastjsonServiceDefinitionSerializer<>(GroupProxy.class))
  77. .client(ZkConnection.client)
  78. .build();
  79. try {
  80. serviceDiscovery.start();
  81. } catch (Exception e) {
  82. throw new RuntimeException(e);
  83. }
  84. }
  85. public void destroy() {
  86. try {
  87. nonCachedInstanceProviders.invalidateAll();
  88. serviceProviders.invalidateAll();//释放所有watcher
  89. serviceDiscovery.close();
  90. } catch (IOException e) {
  91. throw new RuntimeException(e);
  92. }
  93. }
  94. /**
  95. * 向zk server注册本节点内所有units;
  96. * 注意,必须先init然后才可以执行本方法
  97. */
  98. public void selfRegister() {
  99. LocalUnitsManager.unitMap(unitMap -> {
  100. unitMap.forEach((groupName, unitsIgnored) -> {
  101. try {
  102. ServiceInstance<GroupProxy> serviceInstance = ZkServiceInstanceAdaptor.thisCuratorServiceInstance(groupName);
  103. serviceDiscovery.registerService(serviceInstance);
  104. } catch (Exception e) {
  105. LOG.error(e);
  106. //the registration should not be interrupted due to one error.
  107. }
  108. });
  109. });
  110. }
  111. /**
  112. * 注销本节点内所有unit实例
  113. */
  114. public void selfUnregister() {
  115. LocalUnitsManager.unitMap(unitMap -> {
  116. unitMap.forEach((groupName, unitListIgnored) -> {
  117. try {
  118. ServiceInstance<GroupProxy> serviceInstance = ZkServiceInstanceAdaptor.thisCuratorServiceInstance(groupName);
  119. serviceDiscovery.unregisterService(serviceInstance);
  120. } catch (Exception e) {
  121. LOG.error(e);
  122. //should not be interrupted due to one error.
  123. }
  124. });
  125. });
  126. }
  127. @Override
  128. public void register(GroupInstance groupInstance) throws Exception {
  129. serviceDiscovery.registerService(ZkServiceInstanceAdaptor.curatorServiceInstance(groupInstance));
  130. }
  131. @Override
  132. public void unregister(GroupInstance groupInstance) throws Exception {
  133. serviceDiscovery.unregisterService(ZkServiceInstanceAdaptor.curatorServiceInstance(groupInstance));
  134. }
  135. @Override
  136. public GroupInstance lb(String name) {
  137. try {
  138. ServiceInstance<GroupProxy> instance = serviceProviders.get(name).getInstance();
  139. if (instance == null)
  140. instance = serviceProviders.get(name).getProviderStrategy()
  141. .getInstance(nonCachedInstanceProviders.get(name));
  142. return ZkServiceInstanceAdaptor.groupInstance(instance);
  143. } catch (Exception e) {
  144. throw new RuntimeException(e);
  145. }
  146. }
  147. @Override
  148. public List<GroupInstance> all(String name) {
  149. try {
  150. List<ServiceInstance<GroupProxy>> instances = serviceProviders.get(name).getAllInstances();
  151. if (instances.isEmpty())
  152. instances = nonCachedInstanceProviders.get(name).getInstances();
  153. List<GroupInstance> groupInstances = new ArrayList<>();
  154. for (ServiceInstance<GroupProxy> instance : instances) {
  155. groupInstances.add(ZkServiceInstanceAdaptor.groupInstance(instance));
  156. }
  157. return groupInstances;
  158. } catch (Exception e) {
  159. throw new RuntimeException(e);
  160. }
  161. }
  162. @Override
  163. public GroupInstance firstInstance(String name) {
  164. try {
  165. Collection<ServiceInstance<GroupProxy>> instances = serviceProviders.get(name).getAllInstances();
  166. if (instances.isEmpty())
  167. instances = nonCachedInstanceProviders.get(name).getInstances();
  168. if (instances.isEmpty()) return null;
  169. return ZkServiceInstanceAdaptor.groupInstance(instances.iterator().next());
  170. } catch (Throwable e) {
  171. throw new RuntimeException(e);
  172. }
  173. }
  174. @Override
  175. public GroupInstance instance(String groupInstanceId) {
  176. String groupName = new GroupInstanceIdBean(groupInstanceId).getGroup();
  177. ServiceInstance<GroupProxy> instance = serviceProviders.getUnchecked(groupName).getInstance(groupInstanceId);
  178. if (instance == null)
  179. instance = nonCachedInstanceProviders.getUnchecked(groupName).getInstance(groupInstanceId);
  180. return ZkServiceInstanceAdaptor.groupInstance(instance);
  181. }
  182. @Override
  183. public List<String> queryForNames() {
  184. try {
  185. LOG.info(new JSONObject() {{
  186. put("type", "queryZkForNames");
  187. /*put("description", "这个查询动作不能过于频繁,否则会有性能问题");*/
  188. }});
  189. return serviceDiscovery.queryForNames();
  190. } catch (Exception e) {
  191. throw new RuntimeException(e);
  192. }
  193. }
  194. @Override
  195. public GroupProxy newestDefinition(String name) {
  196. return serviceProviders.getUnchecked(name).getNewestServiceDefinition();
  197. }
  198. }