根據nacos官方的介紹,Nacos 致力於幫助您發現、配置和管理微服務。Nacos 提供了一組簡單易用的特性集,幫助您快速實現動態服務發現、服務配置、服務元資料及流量管理。 具有服務發現和服務健康監測動態配置服務動態 DNS 服務服務及其元資料管理等關鍵特點。與Eureka的對比,可參考SpringCloud學習之【Eureka實現服務註冊與發現】

nacos基本架構及概念


  • 服務 (Service)

    服務是指一個或一組軟體功能(例如特定資訊的檢索或一組操作的執行),其目的是不同的客戶端可以為不同的目的重用(例如通過跨程序的網路呼叫)。Nacos 支援主流的服務生態,如 Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful Service.

  • 服務註冊中心 (Service Registry)

    服務註冊中心,它是服務,其例項及元資料的資料庫。服務例項在啟動時註冊到服務登錄檔,並在關閉時登出。服務和路由器的客戶端查詢服務登錄檔以查詢服務的可用例項。服務註冊中心可能會呼叫服務例項的健康檢查 API 來驗證它是否能夠處理請求。

  • 服務元資料 (Service Metadata)

    服務元資料是指包括服務端點(endpoints)、服務標籤、服務版本號、服務例項權重、路由規則、安全策略等描述服務的資料

  • 服務提供方 (Service Provider)

    是指提供可複用和可呼叫服務的應用方

  • 服務消費方 (Service Consumer)

    是指會發起對某個服務呼叫的應用方

  • 配置 (Configuration)

    在系統開發過程中通常會將一些需要變更的引數、變數等從程式碼中分離出來獨立管理,以獨立的配置檔案的形式存在。目的是讓靜態的系統工件或者交付物(如 WAR,JAR 包等)更好地和實際的物理執行環境進行適配。配置管理一般包含在系統部署的過程中,由系統管理員或者運維人員完成這個步驟。配置變更是調整系統執行時的行為的有效手段之一。

  • 配置管理 (Configuration Management)

    在資料中心中,系統中所有配置的編輯、儲存、分發、變更管理、歷史版本管理、變更審計等所有與配置相關的活動統稱為配置管理。

  • 名字服務 (Naming Service)

    提供分散式系統中所有物件(Object)、實體(Entity)的“名字”到關聯的元資料之間的對映管理服務,例如 ServiceName -> Endpoints Info, Distributed Lock Name -> Lock Owner/Status Info, DNS Domain Name -> IP List, 服務發現和 DNS 就是名字服務的2大場景。

  • 配置服務 (Configuration Service)

    在服務或者應用執行過程中,提供動態配置或者元資料以及配置管理的服務提供者。

以上引自nacos官方文件

前提準備


安裝

使用Nacos作為應用的服務註冊中心之前,需要下載的Nacos並啟動Nacos Server。Nacos的安裝使用,可以參考 Nacos 快速開始

這一點與Eureka的使用有所的區別。因為SpringCloud原生支援Eureka,Eureka Server 採用的是Peer to Peer(點對點) 對等通訊,是一種去中心化的架構。所以Euraka只需通過@EnableEurekaServer註解,就能把一個服務例項啟用為服務註冊中心

啟動
  • Linux/Unix/Mac:sh startup.sh -m standalone
  • Windows:cmd startup.cmd -m standalone
  1. nacos可以以單機和叢集兩種模式啟動,分別對應-m standalone-m cluster
  2. startup.shstartup.cmd指令碼位於Nacos解壓後的bin目錄下,啟動之後訪問http://127.0.0.1:8848/nacos/,可看到Nacos的服務管理介面如下

應用註冊


一旦nacos啟動成功,意味著我們已經有了一個服務註冊中心了,接下來我們將來分別建立服務提供者·alibaba-nacos-discovery-server和服務消費者alibaba-nacos-discovery-client-common,分別演示服務的註冊與發現

服務提供方

目錄結構如下:

pom.xml依賴配置如以下:

 <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<optional>true</optional>
</dependency>
</dependencies> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>0.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

啟動類增加@EnableDiscoveryClient註解,開啟Spring Cloud的服務註冊與發現

@EnableDiscoveryClient
@SpringBootApplication
public class AlibabaNacosDiscoveryServerApplication { public static void main(String[] args) {
SpringApplication.run(AlibabaNacosDiscoveryServerApplication.class, args);
} }

提供介面服務TestController

@RestController
public class TestController { private static Logger log = LoggerFactory.getLogger(TestController.class); @GetMapping("/hello")
public String hello(@RequestParam String name) {
log.info("invoked name = " + name);
return "hello " + name;
}
}

新增配置:

# 應用名
spring.application.name=alibaba-nacos-discovery-server
# 埠
server.port=8001
# Nacos服務註冊中心地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

啟動:

INFO 25148 --- [           main] o.s.c.a.n.registry.NacosServiceRegistry  : nacos registry, alibaba-nacos-discovery-server 192.168.10.211:8001 register finished

訪問nacos管理頁面:

服務消費方

目錄結構如下:

pom.xml依賴配置如以下:

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>0.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<optional>true</optional>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency> <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>

啟動類增加@EnableDiscoveryClient註解,開啟Spring Cloud的服務註冊與發現,新增@EnableFeignClients註解,用於controller裡多種呼叫方式演示

@EnableDiscoveryClient
@SpringBootApplication
public class AlibabaNacosDiscoveryServerApplication { public static void main(String[] args) {
SpringApplication.run(AlibabaNacosDiscoveryServerApplication.class, args);
} }

提供介面服務TestController,提供多種服務呼叫方式,分別為Feign、RestTemplate、WebClient:

@RestController
public class TestController { @Autowired
private LoadBalancerClient loadBalancerClient; @Autowired
private RestTemplate restTemplate; @Autowired
private WebClient.Builder webClientBuilder; @Autowired
private TestFeignClient client; /* original */
@GetMapping("/test")
public String test() {
// 通過spring cloud common中的負載均衡介面選取服務提供節點實現介面呼叫
ServiceInstance serviceInstance = loadBalancerClient.choose("alibaba-nacos-discovery-server");
String url = serviceInstance.getUri() + "/hello?name=" + "gaohb";
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(url, String.class);
return "Invoke : " + url + ", return : " + result;
} /* feign */
@GetMapping("/testFeign")
public String testFeign() {
String result = client.hello("gaohb");
return "Return : " + result;
} /* RestTemplate */
@GetMapping("/testRestTemplate")
public String testRestTemplate() {
String result = restTemplate.getForObject("http://alibaba-nacos-discovery-server/hello?name=gaohb", String.class);
return "Return : " + result;
} /* webClient */
@GetMapping("/testWebClient")
public Mono<String> testWebClient() {
Mono<String> result = webClientBuilder.build()
.get()
.uri("http://alibaba-nacos-discovery-server/hello?name=gaohb")
.retrieve()
.bodyToMono(String.class);
return result;
} }

新增feign客戶端TestFeignClient,用於宣告式呼叫服務演示:

@FeignClient("alibaba-nacos-discovery-server")
public interface TestFeignClient { @GetMapping("/hello")
String hello(@RequestParam(name = "name") String name);
}

另外是RestTemplateWebClient.Builder註冊到Spring容器,用於RestTemplate和WebClient.Builder兩種服務呼叫方式演示

@Configuration
public class TestConfig { @Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
} @Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
} }

新增配置:

# 應用名
spring.application.name=alibaba-nacos-discovery-client-common
# 埠
server.port=9000
# Nacos服務註冊中心地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

啟動:

INFO 25148 --- [           main] o.s.c.a.n.registry.NacosServiceRegistry  : nacos registry, alibaba-nacos-discovery-common 192.168.10.211:9000 register finished

訪問nacos管理頁面,服務也正常註冊:

訪問

http://localhost:9000/test
http://localhost:9000/testFeign
http://localhost:9000/testRestTemplate
http://localhost:9000/testWebClient

可以看到服務正常呼叫,結果分別如下:

Invoke : http://your_ip:8001/hello?name=AceLin_H, return : hello AceLin_H
Return : hello AceLin_H
Return : hello AceLin_H
hello AceLin_H