Nacos
反对服务注册与发现,能够说这个性能时每一个服务治理的根底性能,其余模块都是基于服务注册与发现实现的。
开始实操练习:
在Nacos
源码中有个model是example[nacos-example],这个模块在develop分支中有三个demo类,
App.java、ConfigExample.java、NamingExample.java
这一节次要介绍下这个NamingExample.java
类,代码如下:
public class NamingExample { public static void main(String[] args) throws NacosException { /* 设置属性, serverAddr:连贯nacos的ip与port namespace:命名空间如果不设置则默认是public 设置的话须要在nacos console上也创立好,否则找不到相应服务的 */ Properties properties = new Properties(); properties.setProperty("serverAddr", System.getProperty("serverAddr")); properties.setProperty("namespace", System.getProperty("namespace")); /* * 这是一个工厂办法,用来创立NamingService的实现类 */ NamingService naming = NamingFactory.createNamingService(properties); /* * 向nacos注册服务 */ naming.registerInstance("nacos.test.3", "11.11.11.11", 8888, "TEST1"); naming.registerInstance("nacos.test.3", "2.2.2.2", 9999, "DEFAULT"); /* * 获取服务名称为nacos.test.3的所有实例信息 */ System.out.println(naming.getAllInstances("nacos.test.3")); /* * 与 registerInstance 相同,这个是登记服务实例的 */ naming.deregisterInstance("nacos.test.3", "2.2.2.2", 9999, "DEFAULT"); System.out.println(naming.getAllInstances("nacos.test.3")); /* * 订阅服务 */ naming.subscribe("nacos.test.3", new EventListener() { @Override public void onEvent(Event event) { System.out.println(((NamingEvent) event).getServiceName()); System.out.println(((NamingEvent) event).getInstances()); } }); }}
当初一一办法来看一边
NamingFactory
这是一个用来创立服务的动态工厂类,次要提供了两个办法,这两个办法都是通过反射来实例化NacosNamingService
类,办法参数为构造函数的参数。
public class NamingFactory { /** * Create a new naming service. * * @param serverList server list * @return new naming service * @throws NacosException nacos exception */ public static NamingService createNamingService(String serverList) throws NacosException { try { Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService"); Constructor constructor = driverImplClass.getConstructor(String.class); NamingService vendorImpl = (NamingService) constructor.newInstance(serverList); return vendorImpl; } catch (Throwable e) { throw new NacosException(NacosException.CLIENT_INVALID_PARAM, e); } } /** * Create a new naming service. * * @param properties naming service properties * @return new naming service * @throws NacosException nacos exception */ public static NamingService createNamingService(Properties properties) throws NacosException { try { Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService"); Constructor constructor = driverImplClass.getConstructor(Properties.class); NamingService vendorImpl = (NamingService) constructor.newInstance(properties); return vendorImpl; } catch (Throwable e) { throw new NacosException(NacosException.CLIENT_INVALID_PARAM, e); } }}
看下下面NamingFactory
类反射实例化时应用的构造函数
//这个构造函数其实也是将serversAddr地址赋值给`Properties`,然而灵便扩大就不如第二个,能够赋值更多的属性。public NacosNamingService(String serverList) throws NacosException { Properties properties = new Properties(); properties.setProperty(PropertyKeyConst.SERVER_ADDR, serverList); init(properties); } public NacosNamingService(Properties properties) throws NacosException { init(properties); } //这里实例化了N个属性和实例对象 private void init(Properties properties) throws NacosException { ValidatorUtils.checkInitParam(properties); this.namespace = InitUtils.initNamespaceForNaming(properties); InitUtils.initSerialization(); initServerAddr(properties); InitUtils.initWebRootContext(); initCacheDir(); initLogName(properties); this.eventDispatcher = new EventDispatcher(); this.serverProxy = new NamingProxy(this.namespace, this.endpoint, this.serverList, properties); this.beatReactor = new BeatReactor(this.serverProxy, initClientBeatThreadCount(properties)); this.hostReactor = new HostReactor(this.eventDispatcher, this.serverProxy, beatReactor, this.cacheDir, isLoadCacheAtStart(properties), initPollingThreadCount(properties)); }
接下来就在看下注册实例的源码。注册实例提供了几种重载办法,以供客户以不同维度注册实例,
@Override public void registerInstance(String serviceName, String ip, int port) throws NacosException { registerInstance(serviceName, ip, port, Constants.DEFAULT_CLUSTER_NAME); } @Override public void registerInstance(String serviceName, String groupName, String ip, int port) throws NacosException { registerInstance(serviceName, groupName, ip, port, Constants.DEFAULT_CLUSTER_NAME); } @Override public void registerInstance(String serviceName, String ip, int port, String clusterName) throws NacosException { registerInstance(serviceName, Constants.DEFAULT_GROUP, ip, port, clusterName); } @Override public void registerInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException { Instance instance = new Instance(); instance.setIp(ip); instance.setPort(port); instance.setWeight(1.0); instance.setClusterName(clusterName); registerInstance(serviceName, groupName, instance); } @Override public void registerInstance(String serviceName, Instance instance) throws NacosException { registerInstance(serviceName, Constants.DEFAULT_GROUP, instance); } //其实最重要的就是这里,下面的几个办法间接或间接调用这个办法的。 @Override public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException { //获取分组的名称 String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName); if (instance.isEphemeral()) { BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance); beatReactor.addBeatInfo(groupedServiceName, beatInfo); } serverProxy.registerService(groupedServiceName, groupName, instance); }