Spring Cloud Alibaba(四):Nacos服务注册与发现、与Spring、Boot、Cloud集成

Nacos 提供了 SDKOpen API 的方式来完成服务注册与发现等操作。

Nacos 为 Spring,Spring Boot,Spring Cloud 集成提供了相应的 JAR 包和示例。

Nacos官网Spring Cloud > Spring Cloud AlibabaGithub > Spring Cloud AlibabaGithub > Spring Cloud Alibaba WikiGithub > Spring Cloud Alibaba Wiki > Nacos discoveryGithub > Nacos

服务注册与发现

Nacos 提供了 SDKOpen API 的方式来完成服务注册与发现等操作,Open API 是 REST 接口,所以 SDK 本质上是对 HTTP 请求的封装。下面是 Open API 演示服务注册与发现。

服务注册

注册一个服务实例到Nacos 服务,上报实例的服务名、IP地址、端口号,这三个参数是必须;上传还可以包括命名空间ID,权重,是否上线,是否健康,扩展信息,集群名,分组名,是否临时实例。

请求:

1
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080'

返回:

1
ok

服务发现

请求:

1
curl -X GET 'http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName'

返回:

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
{
"name": "DEFAULT_GROUP@@nacos.naming.serviceName",
"groupName": "DEFAULT_GROUP",
"clusters": "",
"cacheMillis": 10000,
"hosts": [
{
"instanceId": "192.168.0.120#8080#DEFAULT#DEFAULT_GROUP@@nacos.naming.serviceName",
"ip": "192.168.0.120",
"port": 8080,
"weight": 1.0,
"healthy": true,
"enabled": true,
"ephemeral": true,
"clusterName": "DEFAULT",
"serviceName": "DEFAULT_GROUP@@nacos.naming.serviceName",
"metadata": {},
"instanceHeartBeatInterval": 5000,
"instanceIdGenerator": "simple",
"instanceHeartBeatTimeOut": 15000,
"ipDeleteTimeout": 30000
}
],
"lastRefTime": 1618117076330,
"checksum": "",
"allIPs": false,
"reachProtectionThreshold": false,
"valid": true
}

发布配置

请求:

1
curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld"

返回:

1
true

获取配置

请求:

1
curl -X GET "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test"

返回:

1
HelloWorld

Nacos Spring

Nacos 为 Spring 集成提供了 nacos-spring-context 包。提供了注解的方式很方便地实现服务注册与发现。

官方文档 > Nacos Spring,完整示列代码请参考:nacos-spring-config-example

Nacos Spring Boot

Nacos 为 Spring Boot 集成提供了 starter 包:nacos-config-spring-boot-starter

通过自动配置以及其他 Spring 编程模型的习惯用法为 Spring Boot 应用程序在服务注册与发现方面提供和 Nacos 的无缝集成。 通过一些简单的注解,就可以快速注册一个服务。

完整示例代码可参考:nacos-spring-boot-discovery-example

添加依赖

创建 Spring Boot 应用,添加 nacos-discovery-spring-boot-starter依赖。

1
2
3
4
5
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>

注意:版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。

配置Nacos服务

application.properties 中配置 Nacos server 的地址。

1
nacos.discovery.server-addr=127.0.0.1:8848

注册服务

通过调用 Nacos Open API 向 Nacos server 注册一个名称为 example 服务

1
curl -X PUT 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=example&ip=127.0.0.1&port=8080'

服务发现

使用 @NacosInjected 注入 Nacos 的 NamingService 实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Controller
@RequestMapping("discovery")
public class DiscoveryController {

@NacosInjected
private NamingService namingService;

@RequestMapping(value = "/get", method = GET)
@ResponseBody
public List<Instance> get(@RequestParam String serviceName) throws NacosException {
// 发现服务
return namingService.getAllInstances(serviceName);
}
}

@SpringBootApplication
public class NacosDiscoveryApplication {

public static void main(String[] args) {
SpringApplication.run(NacosDiscoveryApplication.class, args);
}
}

启动 Spring Boot 应用,调用 curl http://localhost:8080/discovery/get?serviceName=example,返回内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[
{
"instanceId": "127.0.0.1-8080-DEFAULT-example",
"ip": "127.0.0.1",
"port": 8080,
"weight": 1.0,
"healthy": true,
"cluster": {
"serviceName": null,
"name": "",
"healthChecker": {
"type": "TCP"
},
"defaultPort": 80,
"defaultCheckPort": 80,
"useIPPort4Check": true,
"metadata": {}
},
"service": null,
"metadata": {}
}
]

如果没有注册服,返回的是一个为空 JSON 数组[]

Nacos Spring Cloud

Nacos 基于 Spring Cloud 规范为集成提供 spring-cloud-starter-alibaba-nacos-config包,可以与 Spring Boot 和 Spring Cloud 无缝衔接,支持 Feign 调用。

示例代码:spring-cloud-alibaba/spring-cloud-alibaba-examples/nacos-example/

添加依赖

1
2
3
4
5
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>${latest.version}</version>
</dependency>

注意

更多版本对应关系参考:版本说明 Wiki

服务提供者

配置服务提供者,从而服务提供者可以通过 Nacos 的服务注册发现功能将其服务注册到 Nacos server 上。

  1. application.properties 中配置 Nacos server 的地址:

    1
    2
    3
    4
    server.port=8070
    spring.application.name=service-provider

    spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
  2. 通过 Spring Cloud 原生注解 @EnableDiscoveryClient 开启服务注册发现功能:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    @SpringBootApplication
    @EnableDiscoveryClient
    public class NacosProviderApplication {

    public static void main(String[] args) {
    SpringApplication.run(NacosProviderApplication.class, args);
    }

    @RestController
    class EchoController {
    @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
    public String echo(@PathVariable String string) {
    return "Hello Nacos Discovery " + string;
    }
    }
    }

    :Spring Boot 项目引入的spring-cloud-starter-alibaba-nacos-discovery包中开启了自动配置,@EnableDiscoveryClient注解可以忽略。

服务消费者

  1. 配置服务消费者,从而服务消费者可以通过 Nacos 的服务注册发现功能从 Nacos server 上获取到它要调用的服务。

    1
    2
    3
    4
    server.port=8080
    spring.application.name=service-consumer

    spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
  2. 发现服务:通过 Spring Cloud 原生注解 @EnableDiscoveryClient 开启服务注册发现功能。给 RestTemplate 实例添加 @LoadBalanced 注解,开启 @LoadBalancedRibbon 的集成。

    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
    @SpringBootApplication
    @EnableDiscoveryClient
    public class NacosConsumerApplication {

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
    return new RestTemplate();
    }

    public static void main(String[] args) {
    SpringApplication.run(NacosConsumerApplication.class, args);
    }

    @RestController
    public class TestController {

    private final RestTemplate restTemplate;

    @Autowired
    public TestController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}

    @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
    public String echo(@PathVariable String str) {
    return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
    }
    }
    }
  3. 启动 ProviderApplicationConsumerApplication ,调用 http://localhost:8080/echo/2018,返回内容为 Hello Nacos Discovery 2018

Nacos自动配置

Nacos Spring Cloud 包spring-cloud-starter-alibaba-nacos-discovery 依赖关系:

Nacos Spring Cloud Discovery

引入了 spring-cloud-commons,该包主要为 Spring Cloud 的服务注册发现,负载均衡,服务熔断,服务监控,服务调用提供了抽象,为 RestTemplate 启用了 Ribbon 负载均衡。

引入了 spring-cloud-starter-netflix-ribbon,该包是客户端侧负载均衡具体实现。

spring-cloud-alibaba-nacos-discovery为 Nacos 服务发现,服务发现客户端配置,服务注册,集成 Ribbon 负载均衡、配置管理服务 提供了自动配置。

spring.factories

1
2
3
4
5
6
7
8
9
10
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration,\
com.alibaba.cloud.nacos.ribbon.RibbonNacosAutoConfiguration,\
com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration,\
com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration,\
com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration,\
com.alibaba.cloud.nacos.discovery.reactive.NacosReactiveDiscoveryClientConfiguration,\
com.alibaba.cloud.nacos.discovery.configclient.NacosConfigServerAutoConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.alibaba.cloud.nacos.discovery.configclient.NacosDiscoveryClientConfigServiceBootstrapConfiguration

基于以上自动配置,@EnableDiscoveryClient@LoadBalanced注解实际是可以省略的。

Spring Cloud Alibaba(四):Nacos服务注册与发现、与Spring、Boot、Cloud集成

http://blog.gxitsky.com/2021/04/09/SpringCloudAlibaba-04-nacos-discovery-springboot/

作者

光星

发布于

2021-04-09

更新于

2022-06-17

许可协议

评论