Spring cloud Alibaba Nacos service registration and configuration center
About Nacos
Why Nacos
The first four letters are Naming and Configuration, and the last s is Service
What is it?
- A dynamic service discovery, configuration management and service management center easier to build cloud native applications
- Nacos: Dynamic Naming and Configuration Service
- Nacos is the combination of registry and configuration center
- Nacos = Eureka+Config+Bus
What can I do
- Replace Eureka as service registry
- Replace Config as service configuration center
download
https://github.com/alibaba/Nacos
file: https://nacos.io/zh-cn/index.html
Comparison of various registration centers
Services registered in discovery framework | CAP model | Console management | Community activity |
---|---|---|---|
Eureka | AP | support | Low (2.X version closed source) |
Zookeeper | CP | I won't support it | in |
Consul | CP | support | high |
Nacos | AP | support | high |
Install and run Nacos
Download Nacos from the official website first
https://github.com/alibaba/nacos/releases/tag/1.1.4
Extract the installation package and run the startup.cmd
Direct access after the command runs successfully http://localhost:8848/nacos
The default account password is nacos
Nacos as a service registry demo
Nacos based service provider
New Module
cloudalibaba-provider-payment9001
pom
- Parent pom
<!--spring cloud alibaba 2.1.0.RELEASE--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.1.0.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency>
- POM of this module
<?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"> <parent> <artifactId>cloud</artifactId> <groupId>com.liang.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloudalibaba-provider-payment9001</artifactId> <dependencies> <dependency> <groupId>com.alibaba.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.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency><dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency> </dependencies> </project>
YML
server: port: 9001 spring: application: name: nacos-payment-provider cloud: nacos: discovery: server-addr: localhost:8848 #Configure Nacos address management: endpoints: web: exposure: include: '*'
Main start
package com.liang.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @EnableDiscoveryClient @SpringBootApplication public class PaymentMain9001 { public static void main(String[] args) { SpringApplication.run(PaymentMain9001.class,args); } }
Business
package com.liang.cloud.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class PaymentController { @Value("${server.port}") private String serverPort; @GetMapping(value = "/payment/nacos/{id}") public String getPayment(@PathVariable("id") Integer id) { return "nacos registry, serverPort: "+ serverPort+"\t id"+id; } }
test
- http://localhost:9001/payment/nacos/1
- nacos console
To demonstrate the load balancing of nacos, refer to the new 9002 of 9001
cloudalibaba-provider-payment9002
Exactly the same, server port 9002
Nacos based service consumers
New Module
cloudalibaba-consumer-nacos-order83
POM
<?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"> <parent> <artifactId>cloud</artifactId> <groupId>com.liang.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloudalibaba-consumer-nacos-order83</artifactId> <dependencies> <!--SpringCloud ailibaba nacos --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.liang.springcloud</groupId> <artifactId>common</artifactId> <version>${project.version}</version> </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.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
- Why nacos supports load balancing
Introduced Ribbon
YML
server: port: 83 spring: application: name: nacos-order-consumer cloud: nacos: discovery: server-addr: localhost:8848 service-url: nacos-user-service: http://nacos-payment-provider
Main start
package com.liang.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @EnableDiscoveryClient @SpringBootApplication public class OrderNacosMain83 { public static void main(String[] args) { SpringApplication.run(OrderNacosMain83.class,args); } }
Configuration class
package com.liang.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 ApplicationContextConfig { @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } }
Business
package com.liang.cloud.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; 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; import javax.annotation.Resource; @RestController @Slf4j public class OrderNacosController { @Resource private RestTemplate restTemplate; @Value("${service-url.nacos-user-service}") //Get the service URL configured in yml private String serverURL; @GetMapping(value = "/consumer/payment/nacos/{id}") public String paymentInfo(@PathVariable("id") Long id) { return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class); } }
test
- nacos console
- http://localhost:83/consumer/payment/nacos/13
Service registry comparison
Nacos panorama
Nacos and CAP
switch
-
Nacos supports AP and CP mode switching
-
C is that all nodes see the same data at the same time; A is defined as that all requests will receive responses
-
When and what mode to choose
Generally speaking, if you do not need to store service level information and the service instance is registered through Nacos client, and can keep heartbeat reporting, you can choose the AP mode. The current mainstream services, such as Spring Cloud and Dubbo services, are applicable to the AP mode. The AP mode weakens the consistency for the service availability, so only temporary instance registration is supported under the AP mode
If you need to edit or store configuration information at the service level, then CP is required, and K8s service and DNS service are applicable to CP mode. In CP mode, persistent instances are supported. At this time, Raft protocol is used as the cluster operation mode. Before registering an instance in this mode, you must first register the service. If the service does not exist, an error will be returned.
Toggle:
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
Nacos as a service configuration center demonstration
Nacos as configuration center basic configuration
New model
pom
<?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"> <parent> <artifactId>cloud</artifactId> <groupId>com.liang.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloudalibaba-config-nacos-client3377</artifactId> <dependencies> <!--nacos-config--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--nacos-discovery--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--web + actuator--> <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> <!--General basic configuration--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
yml
- Why configure two
Nacos is the same as spring cloud config. When initializing a project, you must first pull the configuration from the configuration center, and then pull the configuration to ensure the normal startup of the project
There is a priority order when loading configuration files in spring boot. bootstrap has a higher priority than application
- bootstrap
server: port: 3377 spring: application: name: nacos-config-client cloud: nacos: discovery: server-addr: localhost:8848 #Service registry address config: server-addr: localhost:8848 #Configuration center address file-extension: yml #Specify the configuration of the yml format
- application
spring: profiles: active: dev
Main start
package com.liang.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @EnableDiscoveryClient @SpringBootApplication public class NacosConfigClientMain3377 { public static void main(String[] args) { SpringApplication.run(NacosConfigClientMain3377.class, args); } }
Business
package com.liang.cloud.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RefreshScope public class ConfigClientController { @Value("${config.info}") private String configInfo; @GetMapping("/config/info") public String getConfigInfo() { return configInfo; } }
@RefreshScope
Automatic configuration update via Spring Cloud native annotation @ RefreshScope
Add configuration information to Nacos
- Matching rules in Nacos
The composition format of dataid in Nacos and the matching rules in the spring boot configuration file
https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html
- code
Configuration add
Set DataId
Formula:
${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
prefix defaults to spring.application.name Value of
spring.profile.active It is the profile corresponding to the current environment and can be configured through the spring.profile.active To configure
File extension is the data format of the configuration content, which can be configured through the spring.cloud.nacos.config.file-extension configuration
test
Main startup class running cloud config Nacos client3377
http://localhost:3377/config/info
With dynamic refresh
Modify the yaml configuration file in Nacos, call the interface to view the configuration again, and you will find that the configuration has been refreshed
Nacos as configuration center - classified configuration
Multi environment and multi project management
Graphical management interface of Nacos
configuration management
Namespace
Namespace+Group+Data ID? Why is it so designed?
Case
- DataID
appoint spring.profile.active And the DataID of the configuration file to read different configurations in different environments
Default space + default grouping + new dev and test dataids
adopt spring.profile.active Properties can be used to read configuration files in multiple environments
http://localhost:3377/config/info
Load whatever the configuration is (test)
- Group scheme
Environment differentiation through Group
Create a new configuration file DataID on the nacos GUI console
bootstrap+application
Add a group configuration under config. Configurable as DEV_GROUP or TEST_GROUP
visit:
- Namespace scheme
Create a new Namespace for dev/test
Go back to service management - service list view
Fill in according to domain name configuration
YML:
bootstrap
visit:
Another configuration scheme:
#spring.application.name=gulimall-coupon # #spring.cloud.nacos.config.server-addr=106.13.127.122:8848 #spring.cloud.nacos.config.namespace=1986f4f3-69e0-43bb-859c-abe427b19f3a #spring.cloud.nacos.config.group=prod # #spring.cloud.nacos.config.ext-config[0].data-id=datasource.yml #spring.cloud.nacos.config.ext-config[0].group=dev #spring.cloud.nacos.config.ext-config[0].refresh=true # #spring.cloud.nacos.config.ext-config[1].data-id=mybatis.yml #spring.cloud.nacos.config.ext-config[1].group=dev #spring.cloud.nacos.config.ext-config[1].refresh=true # #spring.cloud.nacos.config.ext-config[2].data-id=other.yml #spring.cloud.nacos.config.ext-config[2].group=dev #spring.cloud.nacos.config.ext-config[2].refresh=true