根據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
- nacos可以以單機和集群兩種模式啟動,分別對應
-m standalone
和-m cluster
startup.sh
或startup.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);
}
另外是RestTemplate
和 WebClient.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