• Spring Cloud根据服务名获取服务的ip端口


    本篇示例我就以Nacos注册中心为例了,下面是我注册的两个服务。其中nacos-payment-provider服务是集群,有两个实例。

    在这里插入图片描述

    方式一:通过loadBalancerClient来获取

    如果使用的Nacos为注册中心的时候会发现一个问题,当引入的依赖版本比较高的时候,RestTemplate+@LoadBalanced 通过服务名称调用的时候会报错,使用其他注册中心默认都会引用ribbon依赖,因此我们只需要在注入RestTemplate的时候加上@LoadBalanced就可以实现根据名称负载均衡调用。

    而nacos高版本依赖包没有引用ribbon依赖。ribbon早就已经彻底停更了,spring又自己出了一个loadbalancer负载均衡框架,来配合RestTemplate使用。但是他并没有自动引用loadbalancer依赖所以我们需要自己引用才可以使用。

    @Configuration
    public class ApplicationContextBean {
        @Bean
        @LoadBalanced
        public RestTemplate getRestTemplate() {
            return new RestTemplate();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    使用如下获取ip端口的前提:引用了loadbalancer来作为负载均衡

    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-loadbalancerartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    loadBalancerClient.choose()这个方法就是负载均衡的核心方法。假如服务名称为nacos-payment-provider有两个实例,一个9001一个9002,通过如下方法调用会发现每次都是在轮询。

    @Autowired
    private LoadBalancerClient loadBalancerClient;
    
    @GetMapping("/getServiceInstance")
    public ServiceInstance getServiceInstance() {
        ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-payment-provider");
        System.out.println(serviceInstance.getHost()); // ip
        System.out.println(serviceInstance.getPort()); // 端口
        System.out.println(serviceInstance.getInstanceId()); // 实例id
        System.out.println(serviceInstance.getServiceId()); // 服务id
        System.out.println(serviceInstance.getMetadata()); // 与服务实例关联的元数据
        System.out.println(serviceInstance.getScheme());    // 返回服务实例的方案
        System.out.println(serviceInstance.getUri().toString()); // 返回服务的uri地址
        return serviceInstance;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述
    在这里插入图片描述
    loadbalancer源码:

    在这里插入图片描述

    方式二:通过discoveryClient来获取

    这种方式其他注册中心也可以使用!

    @Resource
    private DiscoveryClient discoveryClient;
    
    @GetMapping("/getServiceInstanceList")
    public List getServiceInstanceList() {
    	// 根据服务名称查找所有的实例
        return discoveryClient.getInstances("nacos-payment-provider");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述
    DiscoveryClient这个其实是个接口存放于cloud-commons包当中。

    在这里插入图片描述

    既然是接口为什么他能获取到呢?我们可以看他的实现类,是有如下实现类的,也就是在nacos的服务发现依赖当中会存在他的实现类,并注入到容器当中了。其他注册中心也是同样如此。可以说这个接口是共用的,其他的注册中心都可以来实现。

    在这里插入图片描述

    方式三:通过NacosServiceManager来获取

    这个是nacos独有的!

    @Autowired
    private NacosServiceManager nacosServiceManager;
    
    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;
        
    @GetMapping("/nacos")
    public List getGatewayAddress() {
        String res = null;
        try {
            NamingService namingService = nacosServiceManager.getNamingService(nacosDiscoveryProperties.getNacosProperties());
            List allInstances = namingService.getAllInstances("nacos-payment-provider");
            return allInstances;
        } catch (NacosException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

  • 相关阅读:
    [Machine Learning][Part 8]神经网络的学习训练过程
    Linux共享内存
    vue-tabel 中使用 el-autocomplete 出现的问题
    navicat连接postgresql报错解决方案
    美客多、Lazada养号技巧有什么?如何做?
    【C语言】详解数据在内存中的存储
    多智能体进化算法求解带时间窗的VRP问题(python)
    (论文阅读24/100)Visual Tracking with Fully Convolutional Networks
    Linux由hello.c生成a.out整个过程
    关于Chrome中F12调试Console输入多行
  • 原文地址:https://blog.csdn.net/weixin_43888891/article/details/126755927