Nacos 服務(wù)注冊(cè)與發(fā)現(xiàn)
概述
服務(wù)注冊(cè)中心: 存儲(chǔ)服務(wù)實(shí)例和服務(wù)負(fù)載均衡策略的數(shù)據(jù)庫
本節(jié)通過實(shí)現(xiàn)一個(gè)簡單的 echo service 演示如何在您的 Spring Cloud 項(xiàng)目中啟用 Nacos 的服務(wù)發(fā)現(xiàn)功能,如下圖示:

服務(wù)提供者
服務(wù)提供方: 是指提供可復(fù)用和可調(diào)用服務(wù)的應(yīng)用方
POM
創(chuàng)建一個(gè)名為 hello-spring-cloud-alibaba-provider 的服務(wù)提供者項(xiàng)目,pom.xml 配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.funtl</groupId>
<artifactId>hello-spring-cloud-alibaba</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>hello-spring-cloud-alibaba-provider</artifactId>
<packaging>jar</packaging>
<url>http://www.funtl.com</url>
<inceptionYear>2018-Now</inceptionYear>
<licenses>
<license>
<name>Apache 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>liwemin</id>
<name>Lusifer Lee</name>
<email>lee.lusifer@gmail.com</email>
</developer>
</developers>
<dependencies>
<!-- Spring Boot Begin -->
<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.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot End -->
<!-- Spring Cloud Begin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Spring Cloud End -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.funtl.spring.cloud.alibaba.provider.ProviderApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml
在 application.yml 中配置 Nacos Server 的地址
spring:
application:
# 服務(wù)名
name: service-provider
cloud:
nacos:
discovery:
# 服務(wù)注冊(cè)中心
server-addr: 192.168.141.132:8848
server:
# 服務(wù)端口
port: 8070
management:
# 端點(diǎn)檢查(健康檢查)
endpoints:
web:
exposure:
include: "*"
Application
通過 Spring Cloud 原生注解 @EnableDiscoveryClient 開啟服務(wù)注冊(cè)發(fā)現(xiàn)功能
package com.funtl.spring.cloud.alibaba.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
Controller
編寫一個(gè) RestController 提供 RESTFul API 用于測(cè)試提供者
package com.funtl.spring.cloud.alibaba.provider.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EchoController {
@GetMapping(value = "/echo/{string}")
public String echo(@PathVariable String string) {
return "Hello Nacos Provider " + string;
}
}
驗(yàn)證是否成功
通過瀏覽器訪問 http://192.168.141.132:8848/nacos Nacos Server 網(wǎng)址
[圖片上傳失敗...(image-6bd440-1561982074518)]
你會(huì)發(fā)現(xiàn)一個(gè)服務(wù)已經(jīng)注冊(cè)在服務(wù)中了,服務(wù)名為 service-provider,通過瀏覽器訪問 http://localhost:8070/echo/hi
Hello Nacos Provider hi
服務(wù)端點(diǎn)檢查
健康檢查: 以指定方式檢查服務(wù)下掛載的實(shí)例 (Instance) 的健康度,從而確認(rèn)該實(shí)例 (Instance) 是否能提供服務(wù)。根據(jù)檢查結(jié)果,實(shí)例 (Instance) 會(huì)被判斷為健康或不健康。對(duì)服務(wù)發(fā)起解析請(qǐng)求時(shí),不健康的實(shí)例 (Instance) 不會(huì)返回給客戶端。
通過瀏覽器訪問 http://localhost:8070/actuator/nacos-discovery
{
"subscribe": [
{
"jsonFromServer": "",
"name": "service-provider",
"groupName": "DEFAULT_GROUP",
"clusters": null,
"cacheMillis": 1000,
"hosts": [],
"lastRefTime": 0,
"checksum": "",
"allIPs": false,
"key": "service-provider",
"valid": true,
"keyEncoded": "service-provider"
},
{
"jsonFromServer": "",
"name": "service-consumer",
"groupName": "DEFAULT_GROUP",
"clusters": null,
"cacheMillis": 1000,
"hosts": [],
"lastRefTime": 0,
"checksum": "",
"allIPs": false,
"key": "service-consumer",
"valid": true,
"keyEncoded": "service-consumer"
}
],
"NacosDiscoveryProperties": {
"serverAddr": "192.168.141.132:8848",
"endpoint": "",
"namespace": "",
"watchDelay": 30000,
"logName": "",
"service": "service-provider",
"weight": 1,
"clusterName": "DEFAULT",
"namingLoadCacheAtStart": "false",
"metadata": {
"preserved.register.source": "SPRING_CLOUD"
},
"registerEnabled": true,
"ip": "192.168.141.1",
"networkInterface": "",
"port": 8070,
"secure": false,
"accessKey": "",
"secretKey": ""
}
}
服務(wù)消費(fèi)者
服務(wù)消費(fèi)方: 是指會(huì)發(fā)起對(duì)某個(gè)服務(wù)調(diào)用的應(yīng)用方
服務(wù)消費(fèi)者的創(chuàng)建與服務(wù)提供者大同小異,這里采用最原始的一種方式,即顯示的使用 LoadBalanceClient 和 RestTemplate 結(jié)合的方式來訪問
POM
創(chuàng)建一個(gè)名為 hello-spring-cloud-alibaba-consumer 的服務(wù)消費(fèi)者項(xiàng)目,pom.xml 配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.funtl</groupId>
<artifactId>hello-spring-cloud-alibaba</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>hello-spring-cloud-alibaba-consumer</artifactId>
<packaging>jar</packaging>
<url>http://www.funtl.com</url>
<inceptionYear>2018-Now</inceptionYear>
<licenses>
<license>
<name>Apache 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>liwemin</id>
<name>Lusifer Lee</name>
<email>lee.lusifer@gmail.com</email>
</developer>
</developers>
<dependencies>
<!-- Spring Boot Begin -->
<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.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot End -->
<!-- Spring Cloud Begin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Spring Cloud End -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.funtl.spring.cloud.alibaba.consumer.ConsumerApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml
在 application.yml 中配置 Nacos Server 的地址
spring:
application:
# 服務(wù)名
name: service-consumer
cloud:
nacos:
discovery:
# 服務(wù)注冊(cè)中心
server-addr: 192.168.141.132:8848
server:
# 服務(wù)端口
port: 8080
management:
# 端點(diǎn)檢查(健康檢查)
endpoints:
web:
exposure:
include: "*"
Application
通過 Spring Cloud 原生注解 @EnableDiscoveryClient 開啟服務(wù)注冊(cè)發(fā)現(xiàn)功能
package com.funtl.spring.cloud.alibaba.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
Configuration
創(chuàng)建一個(gè) Java 配置類,主要作用是為了注入 RestTemplate
package com.funtl.spring.cloud.alibaba.consumer.configure;
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 ConsumerConfiguration {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Controller
package com.funtl.spring.cloud.alibaba.consumer.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class TestController {
private final RestTemplate restTemplate;
@Autowired
public TestController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping(value = "/echo/{str}")
public String echo(@PathVariable String str) {
// 使用服務(wù)名請(qǐng)求服務(wù)提供者
return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
}
}
驗(yàn)證是否成功
通過瀏覽器訪問 http://192.168.141.132:8848/nacos Nacos Server 網(wǎng)址

你會(huì)發(fā)現(xiàn)一個(gè)服務(wù)已經(jīng)注冊(cè)在服務(wù)中了,服務(wù)名為 service-consumer,通過瀏覽器訪問 http://localhost:8080/echo/hi
Hello Nacos Provider hi
服務(wù)端點(diǎn)檢查
通過瀏覽器訪問 http://localhost:8080/actuator/nacos-discovery
{
"subscribe": [
{
"jsonFromServer": "",
"name": "service-provider",
"groupName": "DEFAULT_GROUP",
"clusters": null,
"cacheMillis": 1000,
"hosts": [],
"lastRefTime": 0,
"checksum": "",
"allIPs": false,
"key": "service-provider",
"valid": true,
"keyEncoded": "service-provider"
},
{
"jsonFromServer": "",
"name": "service-consumer",
"groupName": "DEFAULT_GROUP",
"clusters": null,
"cacheMillis": 1000,
"hosts": [],
"lastRefTime": 0,
"checksum": "",
"allIPs": false,
"key": "service-consumer",
"valid": true,
"keyEncoded": "service-consumer"
}
],
"NacosDiscoveryProperties": {
"serverAddr": "192.168.141.132:8848",
"endpoint": "",
"namespace": "",
"watchDelay": 30000,
"logName": "",
"service": "service-consumer",
"weight": 1,
"clusterName": "DEFAULT",
"namingLoadCacheAtStart": "false",
"metadata": {
"preserved.register.source": "SPRING_CLOUD"
},
"registerEnabled": true,
"ip": "192.168.141.1",
"networkInterface": "",
"port": 8080,
"secure": false,
"accessKey": "",
"secretKey": ""
}
}