Spring Cloud Nacos 集成Ribbon

1、注册

@Configuration(proxyBeanMethods = false)
@ConditionalOnRibbonNacos
public class NacosRibbonClientConfiguration {

   @Autowired
   private PropertiesFactory propertiesFactory;

   @Bean
   @ConditionalOnMissingBean
   public ServerList<?> 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 = new NacosServerList(nacosDiscoveryProperties);
      serverList.initWithNiwsConfig(config);
      return serverList;
   }

   @Bean
   @ConditionalOnMissingBean
   public NacosServerIntrospector nacosServerIntrospector() {
      return new NacosServerIntrospector();
   }

}

在这里注册了ServerList,和NacosServerIntrospector。其中,用NacosServerList来覆盖了ribbonServerList的默认实现,在ribbon的DynamicServerListLoadBalancer中提供服务。

在com.netflix.loadbalancer.DynamicServerListLoadBalancer#updateListOfServers方法中有一个servers = serverListImpl.getUpdatedListOfServers(),这里替换成了NacosServerList的方法,用来获取服务列表。

2、更新服务列表

//com.alibaba.cloud.nacos.ribbon.NacosServerList#getUpdatedListOfServers
public List<NacosServer> getUpdatedListOfServers() {
   return getServers();
}
//com.alibaba.cloud.nacos.ribbon.NacosServerList#getServers
private List<NacosServer> getServers() {
   try {
       //获取group
      String group = discoveryProperties.getGroup();
       //掉用NamingService获取服务列表
      List<Instance> instances = discoveryProperties.namingServiceInstance()
            .selectInstances(serviceId, group, true);
       //返回服务列表
      return instancesToServerList(instances);
   }
   catch (Exception e) {
      throw new IllegalStateException(
            "Can not get service instances from nacos, serviceId=" + serviceId,
            e);
   }
}
public NamingService namingServiceInstance() {
   return nacosServiceManager.getNamingService(this.getNacosProperties());
}
public List<Instance> selectInstances(String serviceName, String groupName, boolean healthy) throws NacosException {
    return selectInstances(serviceName, groupName, healthy, true);
}
public List<Instance> selectInstances(String serviceName, String groupName, boolean healthy, boolean subscribe)
        throws NacosException {
    return selectInstances(serviceName, groupName, new ArrayList<String>(), healthy, subscribe);
}
public List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy,
        boolean subscribe) throws NacosException {
    
    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);
    }
    //过滤
    return selectInstances(serviceInfo, healthy);
}
public ServiceInfo getServiceInfo(final String serviceName, final String groupName, final String 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);
}

过滤服务列表,将不可用的服务移除

private List<Instance> selectInstances(ServiceInfo serviceInfo, boolean healthy) {
    List<Instance> list;
    if (serviceInfo == null || CollectionUtils.isEmpty(list = serviceInfo.getHosts())) {
        return new ArrayList<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

private List<NacosServer> instancesToServerList(List<Instance> instances) {
   List<NacosServer> result = new ArrayList<>();
   if (CollectionUtils.isEmpty(instances)) {
      return result;
   }
   for (Instance instance : instances) {
      result.add(new NacosServer(instance));
   }

   return result;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Nacos是一个非常流行的微服务注册中心和配置中心,而Ribbon则是一个负载均衡组件。结合起来,可以实现服务的自动发现和负载均衡。 下面是一个简单的示例: 1. 在pom.xml文件中添加依赖: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> ``` 2. 在application.properties或application.yml中配置NacosRibbon: ```yaml # Nacos配置 spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 # Ribbon配置 service-provider.ribbon.listOfServers=localhost:8081,localhost:8082 service-provider.ribbon.NIWSServerListClassName=com.netflix.loadbalancer.ConfigurationBasedServerList ``` 3. 创建一个Ribbon的配置类,用于自定义负载均衡策略等: ```java @Configuration public class RibbonConfig { @Bean public IRule ribbonRule() { return new RandomRule(); // 随机负载均衡策略 } @Bean public IPing ribbonPing() { return new PingUrl(false, "/health"); // 检查服务健康状态的URL } } ``` 4. 在服务消费方的代码中,注入RestTemplate对象,并使用@LoadBalanced注解: ```java @RestController public class ConsumerController { @Autowired private RestTemplate restTemplate; @GetMapping("/hello") public String hello() { String url = "http://service-provider/hello"; return restTemplate.getForObject(url, String.class); } @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } } ``` 在这里,我们使用了"http://service-provider/hello"作为服务提供方的URL,而不是具体的IP和端口。这是因为Ribbon会根据服务名自动选择一个可用的实例。 以上就是使用Spring Cloud NacosRibbon调用服务的基本步骤。需要注意的是,在使用Nacos作为注册中心时,服务提供方需要在启动时注册自己。可以参考Nacos的官方文档或者Spring Cloud官方文档进行配置和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值