al=false;
}
serializerType=bundle.getString("serializer.type");
serverHostName=bundle.getString("server.hostName");
serverPort=Integer.parseInt(bundle.getString("server.port"));
}
public static String getRegisterCenterType() {
return registerCenterType;
}
public static String getSerializerType() {
return serializerType;
}
public static String getLoadBalanceType() {
return loadBalanceType;
}
public static String getRegisterCenterHost() {
return registerCenterHost;
}
public static Integer getRegisterCenterPort() {
return registerCenterPort;
}
public static String getServerHostName() {
return serverHostName;
}
public static Integer getServerPort() {
return serverPort;
}
public static boolean isZookeeperDestoryIsEphemeral() {
return zookeeperDestoryIsEphemeral;
}
}
下面的代码我和声哥有些不同,我将服务注册,注销方法放在ServerUtils中,服务发现方法放在ClientUtils中:
服务的高一致性存在两种做法:
- 因为ZooKeeper存在临时节点,注册中心可以实现Client(RPC的Server)断开,注册服务信息的自动丢失
- 不设置为临时节点,手动的服务注册清除
我这里两种都实现了,虽然做两种方式不同但是功能相同的代码放在一起看起来很奇怪,这里只是做演示。选择其中一种即可。(我建议使用临时节点,当Server宕机,残留的服务信息也能及时清除)
注册实现原理图:
接口:
public interface ServiceDiscovery {
InetSocketAddress searchService(String serviceName);
void cleanLoaclCache(String serviceName);
}
public interface ServiceRegistry {
//服务注册
void register(String serviceName, InetSocketAddress inetAddress);
void cleanRegistry();
}
ZooKeeper接口实现:
public class ZookeeperServiceDiscovery implements ServiceDiscovery{
private final LoadBalancer loadBalancer;
public ZookeeperServiceDiscovery(LoadBalancer loadBalancer) {
this.loadBalancer = loadBalancer;
}
@Override
public InetSocketAddress searchService(String serviceName) {
return ZookeeperClientUtils.searchService(serviceName,loadBalancer);
}
@Override
public void cleanLoaclCache(String serviceName) {
ZookeeperClientUtils.cleanLocalCache(serviceName);
}
}
public class ZookeeperServiceRegistry implements ServiceRegistry{
@Override
public void register(String serviceName, InetSocketAddress inetAddress) {
ZookeeperServerUitls.register(serviceName,inetAddress);
}
@Override
public void cleanRegistry() {
ZookeeperServerUitls.cleanRegistry();
}
}
Factory工厂:
public class ServiceFactory {
private static String center = RpcConfig.getRegisterCenterType();
private static String lb= RpcConfig.getLoadBalanceType();
private static ServiceRegistry registry;
private static ServiceDiscovery discovery;
private static Object registerLock=new Object();
private static Object discoveryLock=new Object();
public static ServiceDiscovery getServiceDiscovery(){
if (discovery==null){
synchronized (discoveryLock){
if (discovery==null){
if ("nacos".equalsIgnoreCase(center)){
discovery= new NacosServiceDiscovery(LoadBalancerFactory.getLoadBalancer(lb));
}else if ("zookeeper".equalsIgnoreCase(center)){
discovery= new ZookeeperServiceDiscovery(LoadBalancerFactory.getLoadBalancer(lb));
}
}
}
}
return discovery;
}
public static ServiceRegistry getServiceRegistry(){
if (registry==null){
synchronized (registerLock){
if (registry==null){
if ("nacos".equalsIgnoreCase(center)){
registry= new NacosServiceRegistry();
}else if ("zookeeper&qu