Spring Cloud Alibaba Nacos Discovery 初识

3,516 阅读4分钟

Nacos,用在Spring Cloud Alibaba干嘛的呢,参考官方文档中描述:

在构建云原生应用时,Nacos是一个易使用的动态服务发现、配置、管理的平台。

有了Spring Cloud Alibaba Nacos Discovery,可以通过Spring Cloud的编程模型迅速接入Nacos服务注册功能。

参考下图,Nacos完成了服务发现、配置、管理的功能

Nacos Discovery 服务注册与发现

服务注册发现解决的问题

微服务架构中,多个服务间经常需要相互调用,如果没有一个注册中心,每个服务都要维护一个它要调用的服务列表,非常麻烦、不动态、伸缩困难。

Nacos便用来解决这个问题,作为注册中心。服务提供者自动将服务注册到Nacos服务器上,后者将维护服务列表并动态刷新,注册了服务实例元数据:主机地址、端口、健康检查地址、Nacos管理主页。

安装与启动Nacos

参考Nacos的安装和启动

启动成功后,访问 http://ip:8848/nacos 可见管理页面,默认用户名/密码为 nacos / nacos

项目中引入

已经启动了Nacos服务,服务提供者、服务消费者,都需要主动把自己注册到Nacos上,才能被注册Nacos上注册的服务调用、调用Nacos上调用的服务。

这个注册的过程如何进行呢?

  • 在服务应用中引入spring-cloud-starter-alibaba-nacos-discovery

    <!--项目启动为一个spring boot web项目-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--用于服务健康检查-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!--用于将自己注册到Nacos-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    
  • 配置Nacos服务地址和将本服务注册为的名称

    spring:
      cloud:
        nacos:
          discovery:
            server-addr: 192.168.162.1:8848
      application:
        name: nacos-provider
    #web端点暴露
    management:
      endpoints:
        web:
          exposure:
            include: "*"    
    
  • 在经典的Spring boot应用配置上加一个@EnableDiscoveryClient注解

    @SpringBootApplication
    @EnableDiscoveryClient
    public class ProviderApplication {
        public static void main(String[] args) {
            SpringApplication.run(ProviderApplication.class, args);
        }
    
        @RestController
        public class EchoController{
            @GetMapping("/echo/{string}")
            public String echo(@PathVariable String string){
                return "Hello Nacos Discovery " + string;
            }
        }
    }
    

启动成功后,可以在Nacos管理页面的服务列表下看到服务已被注册上去:

小坑

我在启动的时候,没有去注意Spring Cloud和Spring boot的版本对应,一直启动报错,可以参考这个链接返回的结果得到Spring Cloud 与 Spring boot的版本对应

服务消费者

服务提供者的依赖配置,服务消费者也都需要,才能通过注册中心访问到服务提供者提供的服务。

经过查看maven依赖关系,发现spring-cloud-starter-alibaba-nacos-discovery模块中依赖了spring-cloud-starter-netflix-ribbon模块,ribbon提供了负载均衡的功能,我们可以注入它所提供的RibbonLoadBalancerClient来获取Nacos注册中心中的服务,然后结合Spring的RestTemplate进行访问:

// spring 完成了自动配置,直接注入
@Autowired
LoadBalancerClient loadBalancerClient;

@Autowired
RestTemplate restTemplate; // 省略创建为bean的过程

@GetMapping("/echo/app-name")
public String echoAppName(){
    // 负载均衡地获取一个服务提供者服务实例
    ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-provider");
    // 使用RestTemplate访问
    String requestUrl = String.format("http://%s:%s/echo/%s", serviceInstance.getHost(), serviceInstance.getPort(), applicationName);
    return restTemplate.getForObject(requestUrl, String.class);
}

启动消费者之后,可以通过启动多个不同端口地服务提供者(idea需要编辑启动配置,选中Allow parallel run),访问消费者的对外接口后,可以发现,请求被均衡的分发到不同的服务提供者服务上。

Nacos Discovery端点

对于连接到了Nacos Discovery的客户端,如服务提供者和服务消费者,spring cloud alibaba nacos discovery提供了一个EndPoint端点:

http://ip-addr/actuator/nacos-discovery

可以返回该服务所订阅的服务列表该服务nacos discovery配置信息

看一下源码,这个端点通过spring boot actuator模块中的EndPoint实现,实现类为NacosDiscoveryEndpoint

// NacosDiscoveryEndpoint.java
// 核心代码(有省略)
public Map<String, Object> nacosDiscovery() {
    // nacos discovery会给注册的服务本地生成一个NamingService实例,通过这个接口可以去订阅服务
    NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
    // 这里获得了NamingService实例所订阅的服务列表
    subscribe = namingService.getSubscribeServices();
}

总结

  • 按照官方文档的指引安装启动了Nacos
  • 实践Nacos服务发现,将服务提供者、服务消费者通过spring cloud alibaba nacos discovery模块 + 配置注册到了启动的Nacos服务器,并可以负载均衡的相互调用
  • Nacos Discovery会将服务本地生成一个NamingService实例,Nacos Discovery端点由spring boot actuator实现,提供了通过NamingService获得服务Nacos Discovery配置信息和订阅的服务列表地功能

下一篇尝试一下Nacos Config配置管理~

参考

spring-cloud-alibaba-group.github.io/github-page…

www.funtl.com/zh/spring-c…

nacos.io/zh-cn/docs/…