Service governance Nacos of Spring Cloud Alibaba

Posted by Imad on Fri, 31 Dec 2021 07:55:04 +0100

Spring Cloud Alibaba version dependency

Add SpringBoot, SpringCloud and SpringCloudAlibaba version dependency integration, add core dependencies in dependency management, and add dependencies to be used in dependencies

Spring cloud Alibaba Version Description: https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E

	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/>
    </parent>

    <dependencyManagement>
        <dependencies>
            <!--integration spring cloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR9</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--integration spring cloud alibaba-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.6.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

Nacos overview

Nacos provides a set of easy-to-use feature sets, which can quickly realize dynamic service discovery, service configuration, service metadata and traffic management.

Nacos documentation: https://nacos.io/zh-cn/docs/quick-start.html

Nacos map

Nacos ecological map

Nacos is used to simplify the solution of service discovery, configuration management, service governance and management, making the discovery, management, sharing and composition of micro services easier.

Build Nacos Server

To download Nacos, first determine the corresponding Nacos version of spring cloud Alibaba

		<!--click artifactId get into spring-cloud-alibaba View in dependency management nacos Version of-->
		<dependency>
             <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.6.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>


<nacos.client.version>1.4.2</nacos.client.version>

Nacos download the corresponding version: https://github.com/alibaba/nacos/releases

Windows

Start command (standalone stands for stand-alone mode, non cluster mode):

startup.cmd -m standalone

Shut down the server

shutdown.cmd

Docker deploys stand-alone Nacos

https://blog.csdn.net/qq_38628046/article/details/106875278

Service registration

Register user center service

Add dependency

		<!--nacos client-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

Configuring nacos

spring:
  application:
    name: user-center
  cloud:
    nacos:
      discovery:
        # Specify the address of the nacos server
        server-addr: IP:8848
        # Specify a namespace, create a namespace through the Web interface of Nacos, and use the production or specified namespace ID to group similar services into different groups
        # namespace: 54c13a17-6ef8-4f7d-8c4a-2f69ae06c13c
        # ShangHai
        # Specify the cluster name (e.g. divided by city and region)
        cluster-name: ShangHai
        # Metadata information
        metadata:
          instance: user
          version: 0.0.1

Open service registration and discovery

@EnableDiscoveryClient Enable the service registration discovery function
@SpringBootApplication
@EnableDiscoveryClient
public class UserApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }
}

Start service

  INFO 10312 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 18 endpoint(s) beneath base path '/actuator'
  INFO 10312 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8081 (http) with context path ''
  INFO 10312 --- [           main] c.a.c.n.registry.NacosServiceRegistry    : nacos registry, DEFAULT_GROUP user-center 192.168.179.1:8081 register finished

Check whether the service is registered


using namespace std

Service details

Register for pay Center Service

Add dependency

		<!--nacos client-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

Configuring nacos

spring:
  application:
    name: pay-center
  cloud:
    nacos:
      discovery:
        server-addr: IP:8848
        cluster-name: BeiJing
        # namespace: 54c13a17-6ef8-4f7d-8c4a-2f69ae06c13c
        metadata:
          instance: pay
          version: 0.0.1

Open service registration and discovery

@EnableDiscoveryClient Enable the service registration discovery function
@SpringBootApplication
@EnableDiscoveryClient
public class PayApplication {

    public static void main(String[] args) {
        SpringApplication.run(PayApplication.class, args);
    }
}

start log

  INFO 15440 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 19 endpoint(s) beneath base path '/actuator'
  INFO 15440 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8082 (http) with context path ''
  INFO 15440 --- [           main] o.s.cloud.commons.util.InetUtils         : Cannot determine local hostname
  INFO 15440 --- [           main] c.a.c.n.registry.NacosServiceRegistry    : nacos registry, DEFAULT_GROUP pay-center 192.168.179.1:8082 register finished

Check whether the service is registered


Service details

Service discovery

Add test interface

Add the test interface to the pay center service

@Slf4j
@RestController
public class TestController {

    @Autowired
    // DiscoveryClient is specifically responsible for service registration and discovery. It can obtain all services registered in the registry
    private DiscoveryClient discoveryClient;

    /**
     * Service discovery: obtain the specified service instance from the service center
     *
     * @return Address information of all instances of user center
     */
    @GetMapping("test")
    public List<ServiceInstance> getInstances() {
        // Query the information of all instances of the specified service
        return this.discoveryClient.getInstances("user-center");
    }
}

Perform test

Restart the project to access: http://192.168.179.1:8082/test

[
  {
    "serviceId": "user-center",
    "host": "192.168.179.1",
    "port": 8081,
    "secure": false,
    "metadata": {
      "instance": "user",
      "nacos.instanceId": "192.168.179.1#8081#ShangHai#DEFAULT_GROUP@@user-center",
      "nacos.weight": "1.0",
      "nacos.cluster": "ShangHai",
      "nacos.ephemeral": "true",
      "nacos.healthy": "true",
      "preserved.register.source": "SPRING_CLOUD",
      "version": "0.0.1"
    },
    "uri": "http://192.168.179.1:8081",
    "scheme": null,
    "instanceId": null
  }
]

When the user center is stopped, obtain the service instance address

[]

After starting the user center service, modify the service port and start the second user center service

-Dserver.port=8083

start log

  INFO 12292 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 18 endpoint(s) beneath base path '/actuator'
  INFO 12292 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8083 (http) with context path ''
  INFO 12292 --- [           main] c.a.c.n.registry.NacosServiceRegistry    : nacos registry, DEFAULT_GROUP user-center 192.168.179.1:8083 register finished

Check whether the service is registered

Service details

Then get the service instance address

[
  {
    "serviceId": "user-center",
    "host": "192.168.179.1",
    "port": 8083,
    "secure": false,
    "metadata": {
      "instance": "user",
      "nacos.instanceId": "192.168.179.1#8083#ShangHai#DEFAULT_GROUP@@user-center",
      "nacos.weight": "1.0",
      "nacos.cluster": "ShangHai",
      "nacos.ephemeral": "true",
      "nacos.healthy": "true",
      "preserved.register.source": "SPRING_CLOUD",
      "version": "0.0.1"
    },
    "uri": "http://192.168.179.1:8083",
    "scheme": null,
    "instanceId": null
  },
  {
    "serviceId": "user-center",
    "host": "192.168.179.1",
    "port": 8081,
    "secure": false,
    "metadata": {
      "instance": "user",
      "nacos.instanceId": "192.168.179.1#8081#ShangHai#DEFAULT_GROUP@@user-center",
      "nacos.weight": "1.0",
      "nacos.cluster": "ShangHai",
      "nacos.ephemeral": "true",
      "nacos.healthy": "true",
      "preserved.register.source": "SPRING_CLOUD",
      "version": "0.0.1"
    },
    "uri": "http://192.168.179.1:8081",
    "scheme": null,
    "instanceId": null
  }
]

Service call

Provision of services

Providing services in user center services

@RestController
@RequestMapping("/users")
@Slf4j
public class UserController {
    private final UserService userService;

    @GetMapping("/selectUserById/{id}")
    @CheckLogin
    public User selectUserById(@PathVariable Integer id) {
        return this.userService.findById(id);
    }
}    

Consumer services

Create RestTemplate

@Bean
public RestTemplate getRestTemplate() {
	return new RestTemplate();
}

Add calling service in pay Center Service

@Slf4j
@RestController
public class TestController {

	@Autowired
	private RestTemplate restTemplate;

    @Autowired
    // DiscoveryClient is specifically responsible for service registration and discovery. It can obtain all services registered in the registry
    private DiscoveryClient discoveryClient;

    /**
     * Service discovery: obtain the specified service instance from the service center
     *
     * @return Address information of all instances of user center
     */
    @GetMapping("test")
    public List<ServiceInstance> getInstances() {
        // Query the information of all instances of the specified service
        return this.discoveryClient.getInstances("user-center");
    }
    
    @GetMapping("test/{id}")
    public UserDTO selectUserById(@PathVariable Integer id) {
        List<ServiceInstance> instances = this.discoveryClient.getInstances("user-center");
        
        // Load balancing
        // int index = new Random().nextInt(instances.size());
		// ServiceInstance serviceInstance = instances.get(index);

        String instanceUrl = instances.stream().map(instance -> instance.getUri().toString() + "/users/selectUserById/{id}")
                .findFirst().orElseThrow(() -> new IllegalArgumentException("obtain user-center Instance failed,There are no related instances"));
        return this.restTemplate.getForObject(instanceUrl, UserDTO.class,id);
    }
}

Perform test

visit http://192.168.179.1:8082/test/1

 {
    "userName": "Xiaobai",
    "age": 20,
    "sex": "male",
}

Nacos Config configuration center

Using nacos as the configuration center is to treat nacos as a server, each micro service as a client, store the configuration files of each micro service on nacos, and then pull the configuration from nacos.

Add dependency

   <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

Create a bootstrap yml

Add the configuration of nacos config in the microservice. You cannot use the original application Instead of using YML as the configuration file, create a new bootstrap YML as configuration file

Profile priority (high to low)

bootstrap.properties -> bootstrap.yml -> application.properties -> application.yml
spring:
  cloud:
    nacos:
      config:
        server-addr: IP:8848
        file-extension: yaml # Configuration file format
  application:
    name: nacos-config-center
  profiles:
    active: dev # Environmental identification

Nacos console new configuration

The contract is greater than the configuration, which needs to be consistent with bootstrap The configuration information in the YML configuration file is consistent

The Data ID is combined according to the configuration information of the configuration file: nacos-config-center-dev.yaml

Perform test

Add test interface

@RestController
public class TestController {
    @Value("${my.nacosConfig}")
    private String nacosConfig;

    @GetMapping("/testNacosConfig")
    public String testNacosConfig() {
        return nacosConfig;
    }
}    

The test gets the configuration from the configuration center

Configure dynamic refresh

If the configuration is modified, the program cannot read the latest configuration. The configuration can be automatically updated through the Spring Cloud native annotation @ RefreshScope.

@RestController
// Enable the configured dynamic refresh function
@RefreshScope
public class TestController {
    @Value("${my.nacosConfig}")
    private String nacosConfig;

    @GetMapping("/testNacosConfig")
    public String testNacosConfig() {
        return nacosConfig;
    }
}    

The test configuration is refreshed dynamically, and the Nacos configuration information is updated before accessing

my:
 nacosConfig: nacos-server-config-update

Configure sharing

When there are more and more configurations, you will find that many configurations are repeated. Therefore, you can consider extracting the public configuration file for sharing

Shared configuration between different environments of the same service

Create to spring application. Name, and then put the public configuration of all environments in it

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql://IP:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC

Create a name to spring application. The configuration named name dev stores the configuration of the development environment

my:
 nacosConfig: dev

Create a name to spring application. The configuration named name test stores the configuration of the test environment

my:
 nacosConfig: test

Configure bootstrap yml

spring:
  cloud:
    nacos:
      config:
        server-addr: IP:8848
        file-extension: yaml # Configuration file format
        namespace: 87a4700f-1dc1-430c-8a99-de98d9e8c55a
        group: TEST_GROUP
  application:
    name: nacos-config-center
  profiles:
    active: dev # Environmental identification

Start project

INFO 55156 --- [  restartedMain] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-nacos-config-center-dev.yaml,TEST_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-nacos-config-center.yaml,TEST_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-nacos-config-center,TEST_GROUP'}]
INFO 55156 --- [  restartedMain] cn.ybzy.demo.Application                 : The following profiles are active: dev

Perform test

@RestController
@RefreshScope
public class TestController {
    @Value("${my.nacosConfig}")
    private String nacosConfig;

    @GetMapping("/testNacosConfig")
    public String testNacosConfig() {
        return nacosConfig;
    }
}    

Shared configuration between different services

Define a public configuration and then import it into the configuration files of different microservices.

Create a new configuration file in nacos and define a data ID of service common Yaml configuration for all microservices sharing

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql://IP:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC


Modify spring application. Name named profile

my:
 serverName: nacos-config

server:
  port: 7777

Modify bootstrap yaml

spring:
  cloud:
    nacos:
      config:
        server-addr: IP:8848
        file-extension: yaml # Configuration file format
        namespace: 87a4700f-1dc1-430c-8a99-de98d9e8c55a
        group: TEST_GROUP
        shared-configs[0]:
          dataId: service-common.yaml # Profile name
          refresh: true # Refresh automatically
          group: TEST_GROUP # Group name
        refresh-enabled: true # Refresh the configured main switch, which is on by default (true)
  application:
    name: nacos-config-center
  profiles:
    active: dev # Environmental identification

Start project

Located property source: [BootstrapPropertySource {name='bootstrapProperties-nacos-config-center-dev.yaml,TEST_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-nacos-config-center.yaml,TEST_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-nacos-config-center,TEST_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-service-common.yaml,TEST_GROUP'}]
INFO 48844 --- [  restartedMain] cn.ybzy.demo.Application                 : The following profiles are active: dev

INFO 48844 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 7777 (http)
INFO 48844 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
INFO 48844 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.37]

Perform test

@RestController
@RefreshScope
public class TestController {
    @Value("${my.serverName}")
    private String serverName;

    @GetMapping("/test")
    public String testNacosConfig() {
        return serverName;
    }
}    

Modify the content of the configuration center file

my:
 serverName: nacos-config-center

server:
  port: 7777

INFO 48844 --- [99-de98d9e8c55a] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-nacos-config-center-dev.yaml,TEST_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-nacos-config-center.yaml,TEST_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-nacos-config-center,TEST_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-service-common.yaml,TEST_GROUP'}]
INFO 48844 --- [99-de98d9e8c55a] o.s.boot.SpringApplication               : The following profiles are active: dev

Topics: Java Spring Boot Spring Cloud