Brief introduction to Nacos
Nacos(Official website )Dedicated to helping you discover, configure and manage your microservices. It provides a set of simple and practical functions that enable you to realize dynamic service discovery, service configuration management, and service and traffic management.
Nacos makes it easier and faster for you to build, and you can use it Nacos on Cloud Or compile and run the source code to publish and manage the microservice platform. It is an infrastructure that supports a modern service centric application architecture using microservices or cloud native methods.
Nacos provides four functions
- Service discovery and service health check: Nacos enables services to easily register themselves and discover other services through DNS or HTTP interfaces. Nacos also provides real-time health checks of services to prevent sending requests to unhealthy hosts or service instances. Nacos supports health check of transport layer (PING or TCP) and application layer (such as HTTP, MySQL, user defined). For the health check of services in complex cloud environment and network topology environment (such as VPC, edge network, etc.), Nacos provides two health check modes: agent reporting mode and server-side active detection mode. Nacos also provides a unified health check dashboard to help you manage service availability and traffic according to health status. Dynamic service discovery is critical to service centric (e.g. micro services and cloud native) application architecture.
- Dynamic configuration management: dynamic configuration services allow you to manage the configuration of all services in a centralized and dynamic manner in all environments. Nacos eliminates the need to redeploy applications and services during configuration updates, which makes configuration changes more efficient and agile. Dynamic configuration service allows you to manage the application configuration and service configuration of all environments in a centralized, external and dynamic way. Dynamic configuration eliminates the need to redeploy applications and services when configuration changes, making configuration management more efficient and agile. Configuration centralized management makes it easier to implement stateless services and make it easier for services to expand flexibly on demand. Nacos provides a simple and easy-to-use UI (console sample Demo) to help you manage the configuration of all services and applications. Nacos also provides a series of out of the box configuration management features, including configuration version tracking, Canary release, one click rollback configuration and client configuration update status tracking, to help you more safely manage configuration changes and reduce the risks caused by configuration changes in the production environment.
- Dynamic DNS Service: Nacos supports weighted routing, making it easier for you to realize middle tier load balancing, flexible routing strategy, traffic control and simple DNS resolution services in the production environment in the data center. It can help you easily implement DNS based service discovery to eliminate the risk of coupling to the vendor's private service discovery API.
- Service and metadata management: Nacos provides an easy-to-use visual interface to help you manage service metadata, configuration, kubernetes DNS, service health and indicator statistics. Nacos enables you to manage all services and metadata in the data center from the perspective of micro service platform construction, including service description, life cycle, static dependency analysis of services, health status of services, traffic management of services, routing and security policies, SLA of services and the most important statistics of metrics.
Nacos map
(picture from https://nacos.io/zh-cn/docs/what-is-nacos.html )
Version relationship with Spring Cloud Alibaba
Spring Cloud Alibaba version relationship:
This blog uses
Spring Boot 2.3.12
Spring Cloud Alibaba 2.2.7
nacos 2.0.3
Download, operation and deployment of Nacos
There are two ways: one is to download binary files for compilation and operation, and the other is to deploy using docker. (I'll use docker deployment here, and make a brief introduction to binary file download, compilation and operation)
Binary download compile run
You can download the binaries and run the Nacos server using a script
Download addresses of various versions of Nacos
The latest version is 2.0.4, but the client doesn't seem to be updated in time, so it doesn't matter to use 2.0.3 first
Windows Download: directly download the zip suffix Nacos server compressed package.
Windows running
startup.cmd -m standalone
Linux download
In tar Right click on the GZ file to copy the link address, and then use the wget command to download it.
wget https://github.com/alibaba/nacos/releases/download/2.0.4/nacos-server-2.0.3.tar.gz
decompression
tar -zxvf nacos-server-2.0.3.tar.gz
cd to the folder where the script is located, and then use the script file to run the Nacos service
./startup.sh -m standalone
docker pull image operation
nacos in docker hub
I downloaded version 2.0.3, which corresponds to the spring cloud version and the spirng boot version
docker pull nacos/nacos-server:v2.0.3
Run a basic Nacos server and try it. nacos 2.0 should release these two ports
9848 is a new client gRPC request server port in nacos 2.0, which is used for clients to initiate connections and requests to the server
docker run -itd --name nacos-quick -e MODE=standalone -p 8848:8848 -p 9848:9848 nacos/nacos-server:v2.0.3
Query whether host ports 8848 and 9848 are open
firewall-cmd --query-port=8848/tcp firewall-cmd --query-port=9848/tcp
If it is no, enter the following command to open these two ports
firewall-cmd --permanent --add-port=8848/tcp firewall-cmd --permanent --add-port=9848/tcp
Restart the firewall (restart the firewall after modifying the configuration) to make the modification take effect
firewall-cmd --reload
Go to the server console to open the firewall,
For alicloud, you also need to manually add ports in the security group. The configuration can be accessed by those IP S. Otherwise, it's useless for your firewall to open the port.
Access the management interface (add / nacos path because there is a default configuration server.servlet.contextPath=/nacos)
ip:8848/nacos
The default account and password are both nacos
Login with default account password
Basic introduction and use of Nacos service registration and discovery
Dynamic service discovery is critical to service centric (such as micro services and cloud native) application architecture. Nacos supports DNS based and RPC based (Dubbo, gRPC) service discovery. Nacos also provides real-time health checks to prevent requests from being sent to unhealthy service instances.
Service is a first-class citizen of the Nacos world. Nacos supports the discovery, configuration and management of almost all mainstream types of services:
- Kubernetes Service
- gRPC & Dubbo RPC Service
- Spring Cloud RESTful Service
Eureka also has the function of service registration and discovery, but due to Eureka 2 0 closed source and the advantages of Nacos itself (online service management, configuration dynamic refresh, etc.).
function | Nacos | Eureka | explain |
---|---|---|---|
Registration Center | yes | yes | Basic functions of service governance, responsible for service centric registration |
Configuration center | yes | no | Eureka needs the cooperation of Config to implement the configuration center, and does not provide a management interface |
Configure dynamic refresh | yes | no | Eureka needs the cooperation of Config, MQ and Webhook to realize the dynamic refresh of configuration, while Nacos uses Netty to maintain the real-time push of TCP long connection |
Availability zone AZ | yes | yes | Divide the service cluster into different regions, realize regional isolation, and provide automatic disaster recovery switching |
grouping | yes | no | Nacos can manage groups according to business and environment |
metadata | yes | yes | Provide service tag data, such as environment or service identification |
weight | yes | no | Nacos provides weight setting function by default to adjust the bearing flow pressure |
health examination | yes | yes | Nacos supports the health check initiated by the client or server, and Eureka is the heartbeat initiated by the client |
load balancing | yes | yes | Responsible equalization strategy is provided, and Eureka adopts Ribbon |
Management interface | yes | no | Nacos supports online service management, and Eureka just previews the service status |
Basic code structure
Create the main project springcloud, select maven, and directly – > next
Fill in project related information
Create subproject:
On the project: right click – > New – > module – > maven – > next
Create a Nacos provider sub module
Again, create a Nacos consumer sub module
The Nacos consumer structure is as follows
The Nacos provider structure is as follows
The overall structure is as follows
Code related documents
Root project
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> <groupId>com.xt</groupId> <artifactId>springcloud</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>nacos-provider</module> <module>nacos-consumer</module> </modules> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.12.RELEASE</version> </parent> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <spring-cloud-alibaba-version>2.2.7.RELEASE</spring-cloud-alibaba-version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba-version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.22</version> <scope>provided</scope> </dependency> </dependencies> </dependencyManagement> </project>
Nacos consumer subproject
Register this project with the nacos server and consume the Nacos provider service
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"> <parent> <artifactId>springcloud</artifactId> <groupId>com.xt</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>nacos-consumer</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <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-actuator</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
application.yml profile
server: port: 8085 spring: application: name: nacos-consumer cloud: nacos: discovery: server-addr: deploy nacos server Server IP:8848
Startup class
There are two ways to consume services, one is RestTemplate and the other is Feign. I use the first one here
package com.xt.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication @EnableDiscoveryClient public class NacosConsumerApplication { @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args){ SpringApplication.run(NacosConsumerApplication.class, args); } }
controller
package com.xt.springcloud.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; 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;} @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET) public String echo(@PathVariable String str) { return restTemplate.getForObject("http://nacos-provider/echo/" + str, String.class); } }
Nacos provider subproject
Register services with the nacos server to provide services for Nacos provider consumption
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"> <parent> <artifactId>springcloud</artifactId> <groupId>com.xt</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>nacos-provider</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
application.yml profile
<?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>springcloud</artifactId> <groupId>com.xt</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>nacos-provider</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
Entity class, which I use to count the number of services provided by each Nacos provider service
package com.xt.springcloud.entity; import lombok.Data; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import java.util.concurrent.atomic.AtomicInteger; @Component @Data public class CountNumber { AtomicInteger atomicInteger; public CountNumber(){ this.atomicInteger = new AtomicInteger(); } }
service layer
package com.xt.springcloud.service; import com.xt.springcloud.entity.CountNumber; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Service; @Service public class EchoService { @Autowired CountNumber countNumber; public int queryCount(){ return countNumber.getAtomicInteger().get(); } public void addOnce(){ countNumber.getAtomicInteger().addAndGet(1); } }
controller
package com.xt.springcloud.controller; import com.xt.springcloud.service.EchoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.concurrent.atomic.AtomicInteger; @RestController public class EchoController { @Autowired EchoService echoService; @GetMapping("/") public ResponseEntity index() { return new ResponseEntity("index error", HttpStatus.INTERNAL_SERVER_ERROR); } @GetMapping("/error") public ResponseEntity test() { return new ResponseEntity("error", HttpStatus.INTERNAL_SERVER_ERROR); } @GetMapping("/echo/{string}") public String echo(@PathVariable String string) { echoService.addOnce(); String ans = "hello Nacos Discovery :" + string; int cnt = echoService.queryCount(); ans += "I am"+3+"No. producer instance"; //During the demonstration, I will manually change the print and string to make each output clearer. Change it every time a service is running ans+="I was called"+cnt+"second"; System.out.println(ans); return ans; } }
Startup class
package com.xt.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class NacosProviderApplication { public static void main(String[] args) { SpringApplication.run(NacosProviderApplication.class,args); } }
Test run (test load balancing at the same time)
I plan to start three Nacos providers to provide services (the following is already configured), and click on the top right corner of the IDEA as shown in the figure
Add spring boot app
Add two as shown in the figure
Then start each Nacos provider service in turn. Remember to change the application once every run The port number of the configuration file of YML, otherwise the port conflict will occur
After three nacos provider services and one nacos consumer service are started, we can view them on the management page provided by nacos
http://Server ip:8848/nacos
On the management page provided by nacos, you can see that the service instance we are running has been registered with the nacos server
You can also manage, edit, offline, adjust the weight of load balancing, and so on
We use Nacos consumer to make 10 requests to Nacos provider to see the consumption of Nacos provider
I found that in the process of sending 10 requests to consumers and 10 requests from consumers to providers, the instances of providers 1, 2 and 3 took turns, which may indicate that the default load balancing strategy of nacos is polling (but not necessarily, because it is only from the surface, we can understand it by looking at the source code)
After modifying the weight of the No. 1 provider instance to 100 on the console page provided by nacos, launch 10 more requests. The result appears to be polling. It seems that the modified weight of the console has not played a role. Then it seems likely that nacos load balancing did not work.
Because we also use the @ LoadBalanced annotation here to achieve client load balancing
The Ribbon component is used at the bottom of the @ LoadBalanced annotation to realize client load balancing
At the same time, we can find in the package of Nacos discovery that it relies on the ribbon component
Nacos has implemented the custom IRule implementation class NacosRule. Therefore, you need to turn the NacosRule instance into a bean to facilitate Spring container management. Modify the NacosConsumerApplication class as follows: restart the NacosConsumerApplication
package com.xt.springcloud; import com.alibaba.cloud.nacos.ribbon.NacosRule; import com.netflix.loadbalancer.IRule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Scope; import org.springframework.web.client.RestTemplate; /** * @Author: codingXT * @Date: 2022-01-22-14:29 * @Description: */ @SpringBootApplication @EnableDiscoveryClient public class NacosConsumerApplication { @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } @Bean @Scope(value = "prototype") public IRule loadBalanceRule() { return new NacosRule(); } public static void main(String[] args){ SpringApplication.run(NacosConsumerApplication.class, args); } }
Then restart the Nacos consumer service to make it effective. Other provider s do not need to restart.
I have restarted here, and then modified the weight of the No. 1 provider service instance on port 8081 to 100
192.168.56.1 is the IP address of my Ethernet adapter VirtualBox host only network
This network card is a virtual network card of virtualbox. It should be installed automatically by IDEA and used as an authentication server. (I don't know very well. Someone who knows kicks me in the comment area)
Use postman to initiate 300 batch requests to see if the weight modification of the nacos console takes effect
postman sends multiple requests in batches You can see this
After 300 requests, run starts batch requests
Then provider instance 1 was called 296 times
provider instance 2 was called 3 times
provider instance 3 was called once
It seems that the load balancing of nacos has played a role, and most requests have been forwarded to the No. 1 provider instance
Basic principles of service registration and discovery
Service registration
Spring Cloud Nacos Discovery follows the spring cloud common standard and implements three interfaces: AutoServiceRegistration, ServiceRegistry and Registration.
During the startup phase of the spring cloud application, the WebServerInitializedEvent event is monitored. After the Web container is initialized, that is, after receiving the WebServerInitializedEvent event, the registration action will be triggered. Call the register method of ServiceRegistry to register the service with the Nacos Server.
Service discovery
NacosServerList implements com netflix. loadbalancer. Serverlist interface and automatically inject it under the condition of @ ConditionOnMissingBean. Ribbon is integrated by default.
If you need more customized, you can use @ Autowired to inject a NacosRegistration instance and directly call the Nacos API through the contents of its NamingService field.
Other configuration items of nacos:
Configuration item | key | Default value | explain |
---|---|---|---|
Server address | spring.cloud.nacos.discovery.server-addr | ||
service name | spring.cloud.nacos.discovery.service | spring.application.name | |
weight | spring.cloud.nacos.discovery.weight | 1 | The value range is 1 to 100. The larger the value, the greater the weight |
adapter name | spring.cloud.nacos.discovery.network-interface | When the IP is not configured, the registered IP is the IP address corresponding to the network card. If this item is not configured, the address of the first network card is taken by default | |
Registered IP address | spring.cloud.nacos.discovery.ip | Highest priority | |
Registered port | spring.cloud.nacos.discovery.port | -1 | By default, it is not configured and will be detected automatically |
Namespace | spring.cloud.nacos.discovery.namespace | One of the common scenarios is the separation and isolation of registrations in different environments, such as the isolation of resources (such as configuration and services) between development and test environments and production environments. | |
AccessKey | spring.cloud.nacos.discovery.access-key | ||
SecretKey | spring.cloud.nacos.discovery.secret-key | ||
Metadata | spring.cloud.nacos.discovery.metadata | Use Map format configuration | |
Log file name | spring.cloud.nacos.discovery.log-name | ||
Access point | spring.cloud.nacos.discovery.endpoint | UTF-8 | The entry domain name of a service in the region. Through this domain name, you can dynamically get the server address |
Is Ribbon integrated | ribbon.nacos.enabled | true |
References:
- https://github.com/alibaba/nacos/wiki/
- https://kaven.blog.csdn.net/article/details/121207295
- https://nacos.io/zh-cn/
- https://nacos.io/en-us/docs/quick-start-spring-cloud.html
- https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/readme-zh.md
- https://www.cnblogs.com/yuer02/p/14785802.html
(blogging is mainly to summarize and sort out their own learning. Most of the materials come from books, online materials and their own practice. It is not easy to sort out, but it is inevitable to have shortcomings. If there are mistakes, please comment and correct them in the comment area. At the same time, thank the bloggers and authors for their hard sorting out resources and shared knowledge.)