• Nacos注册中心6-Client端(获取调用服务的提供者列表)


    0. 环境

    • nacos版本:1.4.1
    • Spring Cloud : 2020.0.2
    • Spring Boot :2.4.4
    • Spring Cloud alibaba: 2.2.5.RELEASE

    测试代码:github.com/hsfxuebao/s…

    1. 获取调用服务的提供者列表

    请求时机:Client端在调用服务提供者具体方法时,才能调用

    1. public ZoneAwareLoadBalancer(IClientConfig clientConfig, IRule rule,
    2. IPing ping, ServerList<T> serverList, ServerListFilter<T> filter,
    3. ServerListUpdater serverListUpdater) {
    4. super(clientConfig, rule, ping, serverList, filter, serverListUpdater);
    5. }
    6. public DynamicServerListLoadBalancer(IClientConfig clientConfig, IRule rule, IPing ping,
    7. ServerList<T> serverList, ServerListFilter<T> filter,
    8. ServerListUpdater serverListUpdater) {
    9. super(clientConfig, rule, ping);
    10. this.serverListImpl = serverList;
    11. this.filter = filter;
    12. this.serverListUpdater = serverListUpdater;
    13. if (filter instanceof AbstractServerListFilter) {
    14. ((AbstractServerListFilter) filter).setLoadBalancerStats(getLoadBalancerStats());
    15. }
    16. restOfInit(clientConfig);
    17. }
    18. void restOfInit(IClientConfig clientConfig) {
    19. boolean primeConnection = this.isEnablePrimingConnections();
    20. // turn this off to avoid duplicated asynchronous priming done in BaseLoadBalancer.setServerList()
    21. this.setEnablePrimingConnections(false);
    22. enableAndInitLearnNewServersFeature();
    23. updateListOfServers();
    24. if (primeConnection && this.getPrimeConnections() != null) {
    25. this.getPrimeConnections()
    26. .primeConnections(getReachableServers());
    27. }
    28. this.setEnablePrimingConnections(primeConnection);
    29. LOGGER.info("DynamicServerListLoadBalancer for client {} initialized: {}", clientConfig.getClientName(), this.toString());
    30. }
    31. com.netflix.loadbalancer.DynamicServerListLoadBalancer#updateListOfServers
    32. @VisibleForTesting
    33. public void updateListOfServers() {
    34. List<T> servers = new ArrayList<T>();
    35. if (serverListImpl != null) {
    36. servers = serverListImpl.getUpdatedListOfServers();
    37. LOGGER.debug("List of Servers for {} obtained from Discovery client: {}",
    38. getIdentifier(), servers);
    39. if (filter != null) {
    40. servers = filter.getFilteredListOfServers(servers);
    41. LOGGER.debug("Filtered List of Servers for {} obtained from Discovery client: {}",
    42. getIdentifier(), servers);
    43. }
    44. }
    45. updateAllServerList(servers);
    46. }
    47. com.alibaba.cloud.nacos.ribbon.NacosServerList#getUpdatedListOfServers
    48. @Override
    49. public List<NacosServer> getUpdatedListOfServers() {
    50. return getServers();
    51. }
    52. private List<NacosServer> getServers() {
    53. try {
    54. String group = discoveryProperties.getGroup();
    55. List<Instance> instances = discoveryProperties.namingServiceInstance()
    56. .selectInstances(serviceId, group, true);
    57. return instancesToServerList(instances);
    58. }
    59. catch (Exception e) {
    60. throw new IllegalStateException(
    61. "Can not get service instances from nacos, serviceId=" + serviceId,
    62. e);
    63. }
    64. }
    65. 复制代码

    com.alibaba.nacos.client.naming.NacosNamingService#selectInstances:

    1. @Override
    2. public List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy,
    3. boolean subscribe) throws NacosException {
    4. ServiceInfo serviceInfo;
    5. if (subscribe) {
    6. // 获取到要调用服务的serviceInfo
    7. serviceInfo = hostReactor.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName),
    8. StringUtils.join(clusters, ","));
    9. } else {
    10. serviceInfo = hostReactor
    11. .getServiceInfoDirectlyFromServer(NamingUtils.getGroupedName(serviceName, groupName),
    12. StringUtils.join(clusters, ","));
    13. }
    14. // todo 从serviceInfo的所有instance实例中过滤出所有可用的
    15. return selectInstances(serviceInfo, healthy);
    16. }
    17. 复制代码

    其中 getServiceInfo方法上一篇Nacos注册中心5-Client端(更新本地服务)中已经信息分析了,我们看一下selectInstances(serviceInfo, healthy)

    1. private List<Instance> selectInstances(ServiceInfo serviceInfo, boolean healthy) {
    2. List<Instance> list;
    3. if (serviceInfo == null || CollectionUtils.isEmpty(list = serviceInfo.getHosts())) {
    4. return new ArrayList<Instance>();
    5. }
    6. Iterator<Instance> iterator = list.iterator();
    7. // 迭代服务的所有instance实例
    8. while (iterator.hasNext()) {
    9. Instance instance = iterator.next();
    10. // 若当前instance不是健康的,或不可用,或其权重小于等于0,则从列表中将其删除
    11. if (healthy != instance.isHealthy() || !instance.isEnabled() || instance.getWeight() <= 0) {
    12. iterator.remove();
    13. }
    14. }
    15. // 返回的这个列表中包含的instance都是可用的
    16. return list;
    17. }
    18. 复制代码

    2. 方法调用图

    参考文章

    nacos-1.4.1源码分析(注释)
    springcloud-source-study学习github地址
    深度解析nacos注册中心
    mac系统如何安装nacos

  • 相关阅读:
    UE5 在骨骼动画模型上绘制贴图
    NOIP2022 (退役录)Goodbye OI!
    淘宝API商品详情测试工具,返回数据说明
    QVHZO-A-06/18、QVHZE-A-06/36比例流量控制阀放大器
    Vue-1.8生命周期
    [附源码]Python计算机毕业设计Django线上社区管理系统
    printjs打印表格的时候多页的时候第一页出现空白
    Rust 使用Cargo
    使用gateway对用户认证(用于确定用户是否登录)
    iOS适配Unity-2019
  • 原文地址:https://blog.csdn.net/BASK2311/article/details/127686150