1、注册
@Configuration(proxyBeanMethods=false)@ConditionalOnRibbonNacospublicclassNacosRibbonClientConfiguration{@AutowiredprivatePropertiesFactory propertiesFactory;@Bean@ConditionalOnMissingBeanpublicServerList<?>ribbonServerList(IClientConfig config,NacosDiscoveryProperties nacosDiscoveryProperties){if(this.propertiesFactory.isSet(ServerList.class, config.getClientName())){ServerList serverList=this.propertiesFactory.get(ServerList.class, config,
config.getClientName());return serverList;}NacosServerList serverList=newNacosServerList(nacosDiscoveryProperties);
serverList.initWithNiwsConfig(config);return serverList;}@Bean@ConditionalOnMissingBeanpublicNacosServerIntrospectornacosServerIntrospector(){returnnewNacosServerIntrospector();}}
在这里注册了ServerList,和NacosServerIntrospector。其中,用NacosServerList来覆盖了ribbonServerList的默认实现,在ribbon的DynamicServerListLoadBalancer中提供服务。
在com.netflix.loadbalancer.DynamicServerListLoadBalancer#updateListOfServers方法中有一个servers = serverListImpl.getUpdatedListOfServers(),这里替换成了NacosServerList的方法,用来获取服务列表。
2、更新服务列表
//com.alibaba.cloud.nacos.ribbon.NacosServerList#getUpdatedListOfServerspublicList<NacosServer>getUpdatedListOfServers(){returngetServers();}
//com.alibaba.cloud.nacos.ribbon.NacosServerList#getServersprivateList<NacosServer>getServers(){try{//获取groupString group= discoveryProperties.getGroup();//掉用NamingService获取服务列表List<Instance> instances= discoveryProperties.namingServiceInstance().selectInstances(serviceId, group,true);//返回服务列表returninstancesToServerList(instances);}catch(Exception e){thrownewIllegalStateException("Can not get service instances from nacos, serviceId="+ serviceId,
e);}}
publicNamingServicenamingServiceInstance(){return nacosServiceManager.getNamingService(this.getNacosProperties());}
publicList<Instance>selectInstances(String serviceName,String groupName,boolean healthy)throwsNacosException{returnselectInstances(serviceName, groupName, healthy,true);}
publicList<Instance>selectInstances(String serviceName,String groupName,boolean healthy,boolean subscribe)throwsNacosException{returnselectInstances(serviceName, groupName,newArrayList<String>(), healthy, subscribe);}
publicList<Instance>selectInstances(String serviceName,String groupName,List<String> clusters,boolean healthy,boolean subscribe)throwsNacosException{ServiceInfo serviceInfo;String clusterString=StringUtils.join(clusters,",");if(subscribe){//直接获取服务列表
serviceInfo= serviceInfoHolder.getServiceInfo(serviceName, groupName, clusterString);if(null== serviceInfo){//获取服务信息,参见上一篇
serviceInfo= clientProxy.subscribe(serviceName, groupName, clusterString);}}else{//获取服务信息,参见上一篇
serviceInfo= clientProxy.queryInstancesOfService(serviceName, groupName, clusterString,0,false);}//过滤returnselectInstances(serviceInfo, healthy);}
publicServiceInfogetServiceInfo(finalString serviceName,finalString groupName,finalString clusters){
NAMING_LOGGER.debug("failover-mode: "+ failoverReactor.isFailoverSwitch());String groupedServiceName=NamingUtils.getGroupedName(serviceName, groupName);String key=ServiceInfo.getKey(groupedServiceName, clusters);if(failoverReactor.isFailoverSwitch()){return failoverReactor.getService(key);}return serviceInfoMap.get(key);}
过滤服务列表,将不可用的服务移除
privateList<Instance>selectInstances(ServiceInfo serviceInfo,boolean healthy){List<Instance> list;if(serviceInfo==null||CollectionUtils.isEmpty(list= serviceInfo.getHosts())){returnnewArrayList<Instance>();}Iterator<Instance> iterator= list.iterator();while(iterator.hasNext()){Instance instance= iterator.next();if(healthy!= instance.isHealthy()||!instance.isEnabled()|| instance.getWeight()<=0){
iterator.remove();}}return list;}
将服务包装成NacosServer返回
NacosServer继承了Server
privateList<NacosServer>instancesToServerList(List<Instance> instances){List<NacosServer> result=newArrayList<>();if(CollectionUtils.isEmpty(instances)){return result;}for(Instance instance: instances){
result.add(newNacosServer(instance));}return result;}