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);
}