Nacos use experience

Function is introduced

Core functions include service registration, service heartbeat, service synchronization, service discovery and service health check

The service registry

The Nacos Client registers its services with the Nacos Server by sending REST requests and provides its own metadata, such as IP addresses and ports. When Nacos Server receives the registration request, it stores the metadata information in a two-tier memory Map.

Service is the heart

After a service is registered, the Nacos Client maintains a timed heartbeat to continuously notify the Nacos Server that the service is always available and prevents it from being culled. By default, heartbeat is sent every 5 seconds.

Service synchronization

Nacos Server clusters synchronize service instances with each other to ensure the consistency of service information.

Service discovery

When the service consumer (Nacos Client) invokes the service provider’s service, it will send a REST request to the Nacos Server to obtain the service manifest registered above and cache it locally in the Nacos Client. At the same time, a scheduled task is started in Nacos Client to periodically pull the server’s latest registry information to the local cache

Service health check

Nacos Server starts a scheduled task to check the health of registered service instances, sets its healthy attribute to false for instances that have not received a client heartbeat for more than 15 seconds (the client service does not detect it), and if an instance has not received a heartbeat for more than 30 seconds, Reject the instance directly (the deleted instance is re-registered if the heartbeat is resumed)

Nacos use

Version selection

You can find descriptions of the features supported by each release in Nacos’s Release Notes and blog, and the current recommended stable release is 1.3.1.

Environment preparation

Nacos relies on the Java environment to run. If you build and run Nacos from code and need to configure the Maven environment for this, make sure you install it in one of the following versions:

  1. The 64-bit OS supports Linux, Unix, Mac, and Windows. Linux, Unix, and Mac are recommended.
  2. 64-bit JDK 1.8+.
  3. Maven 3.2 x +.

Download the source code or install the package

You can get Nacos both from source code and distribution packages.

Download the source code from Github

git clone https://github.com/alibaba/nacos.git
cd nacos/
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U  
ls -al distribution/target/

// change the $version to your actual path
cd distribution/target/nacos-server-$version/nacos/bin
Copy the code

Download the compressed package after compilation

You can download the nacos-server-$version.zip package from the latest stable version.

Unzip nacos-server-$version.zip or tar -xvf nacos-server-$version.tar.gz CD nacos/binCopy the code

Start the server

Linux/Unix/Mac

Startup command (standalone stands for standalone mode, not cluster mode):

sh startup.sh -m standalone
Copy the code

If you are using Ubuntu, or if you run the script, an error message [[symbol cannot be found, try the following:

bash startup.sh -m standalone
Copy the code

Windows

Start command:

cmd startup.cmd
Copy the code

Or double-click the startup. CMD file to run it.

Service registry & Discovery and configuration management

The service registry

The curl -x POST 'http://127.0.0.1:8848/nacos/v1/ns/instance? ServiceName = nacos. Naming. ServiceName&ip = 20.18.7.10 & port = 8080 'Copy the code

Service discovery

The curl -x GET http://127.0.0.1:8848/nacos/v1/ns/instance/list? serviceName=nacos.naming.serviceName'Copy the code

Release configuration

The curl -x POST "http://127.0.0.1:8848/nacos/v1/cs/configs? dataId=nacos.cfg.dataId&group=test&content=HelloWorld"Copy the code

Access to the configuration

The curl -x GET http://127.0.0.1:8848/nacos/v1/cs/configs?. dataId=nacos.cfg.dataId&group=test"Copy the code

Shut down the server

Linux/Unix/Mac

sh shutdown.sh
Copy the code

Windows

cmd shutdown.cmd
Copy the code

Or double-click the shutdown.cmd file to run it.

Projects using

The service registry

First we use the service registry feature of Nacos.

The Nacos service starts

Download Nacos from the Nacos website and start it. After startup, go to the console, http://ip:8848, and you can see the configuration information (the default username and password are both nacos).

Create a new parent project

Create a new Learn project, poM file is

<? The 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" > The < modelVersion > 4.0.0 < / modelVersion > < groupId > zyz. SpringCloudAlibaba < / groupId > < artifactId > Learn < / artifactId > <packaging> POM </packaging> <version> 1.0-snapshot </version> <modules> <module>NacosDiscovery</module> </modules> <parent>  <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> The < version > 2.1.3. RELEASE < / version > < relativePath / > <! -- lookup parent from repository --> </parent> <properties> <java.version>1.8</java.version> <lomback.version>1.8.4</lomback.version> </properties> <dependencyManagement> <dependencies> <! - introduction of springcloud version - > < the dependency > < groupId > org. Springframework. Cloud < / groupId > <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.SR3</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> < artifactId > spring - the cloud - alibaba - dependencies < / artifactId > < version > 2.1.1. RELEASE < / version > < type > pom < type > <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <repositories> <repository> <id>spring</id> <url>https://maven.aliyun.com/repository/spring</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> </project>Copy the code

Create a producer application

Create a subproject nacos-discovery-test with poM file as nacos-discovery-test

<? The 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" > < the parent > < artifactId > Learn < / artifactId > < groupId > zyz. SpringCloudAlibaba < / groupId > < version > 1.0 - the SNAPSHOT < / version > < / parent > The < modelVersion > 4.0.0 < / modelVersion > < artifactId > nacos - discovery - the test < / artifactId > < dependencies > < the 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>  </dependencies> </project>Copy the code

Create a new class in the subproject

package appliaction; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @EnableDiscoveryClient public class NacosProviderDemoApplication { public static void main(String[] args) { SpringApplication.run(NacosProviderDemoApplication.class,args); } @RestController public class EchoController { @GetMapping(value = "/echo/{string}") public String echo(@PathVariable String string){ return "Hello Nacos Discovery " + string; }}}Copy the code

Add the configuration file application.yml

spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
  application:
    name: nacos-provider
server:
  port: 8081
Copy the code

Start the project

There are two ways to start:

  1. Start the IDE directly: Find the main class ProviderApplication of the nacos-discovery-provider-Example project and use the main method to start the application.
  2. Start after package compilation: Execute MVN Clean Package in nacos-discovery-provider-example project to package project compilation. Then run the java-jar nacos-discovery-provider-example.jar command to start the application.

validation

Enter that address http://127.0.0.1:8848/nacos/v1/ns/catalog/instances? in your browser ServiceName = NACOS-Provider&ClusterName =DEFAULT&pageSize= 10&pageno = 1&NamespaceID =, and click the jump, you can see that the service node has been successfully registered with nacOS Server.

Service discovery

Integrated Ribbon

For ease of use, NacosServerList realized com.net flix loadbalancer. ServerList interface, and in the conditions of the @ ConditionOnMissingBean automatic injection. If you have customization requirements, you can implement your own ServerList.

Nacos Discovery Starter integrates the Ribbon by default, so components that use the Ribbon for load balancing can be discovered using Nacos services.

Use RestTemplate and FeignClient

Let’s take a look at the nacos-discovery-consumer-Example project code and show how RestTemplate works with FeignClient.

Create a new subproject nacos-discovery-Consumer

Pom file for

<? The 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" > < the parent > < artifactId > Learn < / artifactId > < groupId > zyz. SpringCloudAlibaba < / groupId > < version > 1.0 - the SNAPSHOT < / version > < / parent > The < modelVersion > 4.0.0 < / modelVersion > < artifactId > nacos - discovery - the consumer < / artifactId > < dependencies > < the 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.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies> </project>Copy the code

Creating a Configuration File

The application.yml file is:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
  application:
    name: nacos-consumer
server:
  port: 8082
Copy the code

Create three classes

Here are three class files to create:

  1. NacosController: Controller class for external request access
  2. EchoService: Feign service class used to remotely invoke other services
  3. NacosConsumerApp: Startup class

NacosController class

package com.zyz.controller; import com.zyz.sevice.EchoService; 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; import javax.annotation.Resource; @RestController public class NacosController { @Autowired private RestTemplate restTemplate; @Resource private EchoService echoService; @GetMapping(value = "/echo-rest/{str}") public String rest(@PathVariable String str){ return restTemplate.getForObject("http://nacos-provider/echo/" + str, String.class); } @GetMapping(value = "/echo-feign/{str}") public String feign(@PathVariable String str){ return echoService.echo(str); }}Copy the code

The EchoService class

package com.zyz.sevice;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "nacos-provider")
public interface EchoService {

    @GetMapping(value = "/echo/{str}")
    String echo(@PathVariable("str") String str);
}

Copy the code

NacosConsumerApp class

package com.zyz; 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.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class NacosConsumerApp { //Instantiate RestTemplate Instance @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(NacosConsumerApp.class,args); }}Copy the code

Start the application

Same as service registration

validation

Type http://127.0.0.1:18083/echo-rest/1234 in your browser’s address bar, click on the jump, You can see that the browser displays the message “Hello nacos Discovery 1234” returned by nacos-discovery-provider-example, proving that the service discovery is in effect.

Type http://127.0.0.1:18083/echo-feign/12345 in your browser’s address bar, click on the jump, You can see that the browser displays the message “Hello nacos Discovery 12345” returned by nacos-discovery-provider-example, proving that the service discovery has taken effect.

Configuration center

Nacos also provides a configuration hub that provides multiple environment configurations and dynamic refreshes.

Create a new subproject nacos-config

Pom file
<? The 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" > < the parent > < artifactId > Learn < / artifactId > < groupId > zyz. SpringCloudAlibaba < / groupId > < version > 1.0 - the SNAPSHOT < / version > < / parent > < modelVersion > 4.0.0 < / modelVersion > < artifactId > nacos - config < / artifactId > < properties > < Java version > 1.8 < / Java version > </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <! <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-nacos-config</artifactId> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId> <version>21.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>Copy the code
The configuration file

Create two new configuration files on Nacos as shown below:

Development environment:

Test environment:

Configuration files in the project

bootstrap.xml

spring:
  cloud:
    nacos:
      config:
        server-addr: localhost:8848
        file-extension: yml
  application:
    name: config-center
  profiles:
    active: dev
Copy the code

application.yml

spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
server:
  port: 8081
Copy the code
The Controller class
package com.zyz.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @Slf4j @RefreshScope public class ConfigController { @Value("${config}") private String config; @Autowired private DiscoveryClient discoveryClient; @RequestMapping("/getConfig") public Object getConfig() { return config; }}Copy the code
Start the class
package com.zyz; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class ConfigApplication { public static void main(String[] args) { SpringApplication.run(ConfigApplication.class, args); }}Copy the code

Launch parameters

Start the project, input: http://localhost:8081//getConfig

Output:

This is the test environmentCopy the code

Success.