自从有了spring-cloud-alibaba的开源之后,springcloud中使用nacos进行服务的注册与发现就已变得非常容易,只需要引入“spring-cloud-starter-alibaba-nacos-discovery”即可,然后开启@EnableDiscoveryClient,便可以做到无缝替换eureka和consul等注册中心。
下面通过给出一个简单的案例来演示springcloud中如何使用nacos。
nacos-discovery-stater原理
首先来看一下springcloud中nacos进行服务注册与发现的原理。
服务注册
spring-cloud-starter-alibaba-nacos-discovery遵循了spring-cloud-common标准,实现了 AutoServiceRegistration、ServiceRegistry、Registration 这三个接口。
在springcloud应用的启动阶段,监听了WebServerInitializedEvent事件,当Web容器初始化完成后,即收到WebServerInitializedEvent 事件后,会触发注册的动作,调用ServiceRegistry的register方法,将服务注册到 Nacos Server。
服务发现
NacosServerList 实现了 com.netflix.loadbalancer.ServerList 接口,并在 @ConditionOnMissingBean 的条件下进行自动注入,默认集成了Ribbon。
如果需要有更加自定义的可以使用 @Autowired 注入一个 NacosRegistration 实例,通过其持有的 NamingService 字段内容直接调用 Nacos API。
nacos-service-provider
创建一个服务提供者的springcloud项目,引入如下依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <properties> <spring-cloud.version>Greenwich.SR1</spring-cloud.version> <spring-cloud.alibaba.version>0.2.1.RELEASE</spring-cloud.alibaba.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud.alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <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> </dependencies>
|
在项目的application.yml文件中配置nacos相关的配置信息如下:
如果不想使用 Nacos 作为您的服务注册与发现,可以将 spring.cloud.nacos.discovery 设置为 false。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| spring: application: name: nacos-service-provider cloud: nacos: discovery: register-enabled: true server-addr: 127.0.0.1:8848 weight: 1 namespace: dev management: endpoints: web: exposure: include: "*"
server: port: 8080
|
接着便是创建一个服务,供调用者使用,勿忘在主函数引入@EnableDiscoveryClient注解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.lazycece.scac.nacos.discovery.provider.controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
@RestController @RequestMapping("/nacos") public class NacosProviderController { @GetMapping("/provider/{name}") public String provider(@PathVariable String name) { return "hello," + name; } }
|
nacos-service-consumer
创建一个服务消费者的springcloud项目,引入如下依赖,这里多引入了open-feign和ribbon的依赖,是为了同时演示这两种方式的消费。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <properties> <spring-cloud.version>Greenwich.SR1</spring-cloud.version> <spring-cloud.alibaba.version>0.2.1.RELEASE</spring-cloud.alibaba.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud.alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <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> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency>
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies>
|
在项目的application.yml文件中配置nacos相关的配置信息如下:
如果不想使用 Nacos 作为您的服务注册与发现,可以将 spring.cloud.nacos.discovery 设置为 false.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| spring: application: name: nacos-service-consumer cloud: nacos: discovery: register-enabled: true server-addr: 127.0.0.1:8848 weight: 1 namespace: dev management: endpoints: web: exposure: include: "*"
server: port: 8081
|
创建服务消费者的代码如下,勿忘在主函数引入@EnableDiscoveryClient注解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| package com.lazycece.scac.nacos.discovery.consumer.controller;
import com.lazycece.scac.nacos.discovery.consumer.api.FeignConsumerApi; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate;
@RestController @RequestMapping("/nacos/consumer") public class NacosConsumerController {
private LoadBalancerClient loadBalancerClient; private RestTemplate restTemplate; private FeignConsumerApi feignConsumerApi;
@Autowired public NacosConsumerController(LoadBalancerClient loadBalancerClient, RestTemplate restTemplate, FeignConsumerApi feignConsumerApi) { this.loadBalancerClient = loadBalancerClient; this.restTemplate = restTemplate; this.feignConsumerApi = feignConsumerApi; }
@GetMapping("/rest/{name}") public String rest(@PathVariable String name) { ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-service-provider"); String url = String.format("http://%s:%s/nacos/provider/%s", serviceInstance.getHost(), serviceInstance.getPort(), name); System.out.println("url -> " + url); return restTemplate.getForObject(url, String.class); }
@GetMapping("/feign/{name}") public String feign(@PathVariable String name) { return feignConsumerApi.provider(name); }
@GetMapping("/ribbon/{name}") public String ribbon(@PathVariable String name) { return restTemplate.getForObject("http://nacos-service-provider/nacos/provider/" + name, String.class); } }
|
要使用rest方式消费,需要注入RestTemplate,如果需要用ribbon来进行负载均衡,则可以@LoadBalanced注解,否则可以不加。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.lazycece.scac.nacos.discovery.consumer.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate;
@Configuration public class RestTemplateConfig {
@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
|
使用feign方式消费,需要有feign的client,如下,且项目主函数还需引入@EnableFeignClients
注解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.lazycece.scac.nacos.discovery.consumer.api;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient("nacos-service-provider") @RequestMapping("/nacos") public interface FeignConsumerApi {
@GetMapping("/provider/{name}") String provider(@PathVariable String name); }
|
服务注册与发现案例验证
需要先启动nacos-server服务,安装部署详见 nacos安装部署
服务的 EndPoint
spring-cloud-starter-alibaba-nacos-discovery 在实现的时候提供了一个EndPoint,EndPoint的访问地址为 http://ip:port/actuator/nacos-discovery 。因为我们加了 spring-boot-starter-actuator 依赖,所以可以查看endpoint信息。EndPoint 的信息主要提供了两类:
- subscribe: 显示了当前有哪些服务订阅者
- NacosDiscoveryProperties: 显示了当前服务实例关于 Nacos 的基础配置
其中一个服务实例访问 EndPoint 的信息如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| { "subscribe":[
], "NacosDiscoveryProperties":{ "serverAddr":"127.0.0.1:8848", "endpoint":"", "namespace":"dev", "logName":"", "service":"nacos-service-provider", "weight":1, "clusterName":"DEFAULT", "namingLoadCacheAtStart":"false", "metadata":{
}, "registerEnabled":true, "ip":"192.168.3.8", "networkInterface":"", "port":8080, "secure":false, "accessKey":"", "secretKey":"" } }
|
nacos管界面
访问 http://localhost:8848/nacos/ 进入nacos的管理界面,查看 服务管理->服务列表 模块,便可以看到我们的服务消费者和提供者已经注册到nacos上了,如下图所示:

服务消费
这里需要先启动nacos服务,然后启动上面两个服务,访问如下地址:
http://localhost:8081/nacos/consumer/rest/lazycece
http://localhost:8081/nacos/consumer/ribbon/lazycece
http://localhost:8081/nacos/consumer/feign/lazycece
输出信息:hello,lazycece
更多springcloud nacos信息
关于 spring-cloud-starter-alibaba-nacos-discovery 中的其他配置信息如下图所示:

案例源码
案例源码地址:
https://github.com/lazycece/springcloud-actual-combat/tree/master/springcloud-ac-alibaba/springcloud-ac-alibaba-nacos-discovery