[SpringCloud] Introduction to Microservice Technology Stack 2 - Nacos Framework and Feign

Nacos

Download Nacos and run

First download the corresponding release package, mainly select the packaged and compiled nacos-server file!
https://github.com/alibaba/nacos/releases/tag/1.4.1

Unzip it to any folder that does not contain a Chinese path.
Enter bin, open the command line in this folder, and enter startup.cmd -m standaloneto start the nacos server.

The default server port is 8848. The above instructions standaloneare expressed in single body, non-cluster mode.


After waiting for the command line to run for a while, enter the URL given by nacos:http://192.168.113.1:8848/nacos/index.html

It can be seen that this is a management interface. The user name and password are both by default. nacosJust log in.


Configure Nacos

Since our current project setup is a parent-child type, we first need to import the alibaba tool library in the parent project pom.

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.5.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

Then import nacos-discovery dependencies in their respective servers

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

Very simple, right?

Finally, you only need to set the address of the nacos server in the configuration file. Unlike
eureka, the registration center here is actually the nacos server we just ran, so there is no need to create an additional project to run the server.

Configuration file writing application.yaml:

spring:
  cloud:
    nacos:
      server-addr: localhost:8848

Rebuild the corresponding module

Go back to the nacos control panel and you can see the server we generated!

Insert image description here

Nacos cluster

Insert image description here

Individual instances are grouped together to form a cluster

Clusters are often used for disaster recovery mechanisms

Instances in the same cluster will first access other local instances in the current cluster. If there is no other way, they will go to instances in other clusters.


Setting up a cluster for an instance is very simple. You only need to add the following code to the configuration file to classify it into a cluster.

spring:
  cloud:
    nacos:
      server-addr: localhost:8848

      # 设置集群名称,将这个实例归为集群SH管理
      discovery:
        cluster-name: SH

Nacos load balancing

Suppose there is a situation like this now:

  1. The service provider has 3 instances, two clusters (BJ, NJ)
  2. The service consumer has only one instance and one cluster (BJ)

It can be seen that the consumer's cluster is consistent with a cluster in the provider, so according to common sense, we hope that the consumer will directly get data from the provider under the same cluster.


However, since nacos uses polling to achieve load balancing by default, the default configuration must be modified to achieve the final effect.

Option 1: Configure the ribbon in applcation.yaml and specify the load balancing method.

service-consumer:
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

Option 2: Use injection to configure in the entry class

@Bean
NacosRule nacosRule() {
    
    
    return new NacosRule();
}

Load balancing weight value setting

  1. When the instance weight is 0, it will never be accessed
  2. Weight value range 0-1
  3. Among multiple instances in the same cluster, the one with higher weight will be accessed more frequently.

Nacos environment isolation

nacos provides environment isolation options.
From outside to inside, the environment from large to small is as follows:命名空间->分组->服务->实例

Let's first go to the "Namespace" module of the nacos control panel to add a devnamespace named arbitrarily, and copy the automatically generated ID.

Find the configuration file of any server and use the namespace field to classify the server into a certain namespace

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: BJ

        # 设置改服务器所处的命名空间
        # 这里需要填入我们之前记下来的命名空间ID
        namespace: 1688ddc5-4f48-4bdc-bb5b-8c5363edf242

After configuration is completed, restart the server

Enter the nacos console 服务管理->服务列表
and click the navigation bar above to switch namespaces.

In the picture below, we have switched to the newly created dev namespace. It can be seen that the user-server we configured has been governed by this namespace.

Insert image description here


Nacos registration details

Insert image description here

Server providers can choose between two states when registering with the registry

  1. Temporary instance status
  2. Non-temporary instance status

Temporary instances need to actively send regular heartbeat packets to the registration center to prove that they are alive, otherwise they will be removed from the registration center after timeout.

Non-temporary instances do not need to actively send packages, but the registration center confirms whether they are alive. They will be kept forever and will not be deleted due to timeout or other circumstances.

The nacos cluster uses AP mode by default, and switches to CP mode when there are non-temporary instances.


Use the field in the configuration file ephemeralto mark whether the server is a temporary instance.

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: BJ
        namespace: 1688ddc5-4f48-4bdc-bb5b-8c5363edf242

        # 设置是否为临时实例
        ephemeral: false

Nacos more configuration items

Get started quickly

nacos provides a cloud setting configuration file. We only need to create a new configuration file in nacos and write the configuration items that need to be hot updated, and then call the configuration in bootstrap.yaml of the springboot application.

Create a new configuration file. The writing format of the configuration file ID is: <服务器名>-<类型>.yaml
The current configuration file supports yaml and properties formats.

The "server name" here must be exactly the same as the name defined in the application in springboot before this configuration item can be enabled.

Insert image description here


Add nacos-config dependency to user-server to enable dependencies

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

After adding nacos-config, create a new configuration file in the resource folder bootstrap.yaml. At this time, when springboot starts, the configuration file will be read first and then read.application.yaml

spring:
  # 服务器名称
  application:
    name: userservice
  # 服务器类型(我们之前定义为dev,这里必须写dev)
  profiles:
    active: dev

  # 其他关键性配置
  cloud:
    nacos:
      server-addr: localhost:8848
      config:
        # 设置bootstrap配置文件的后缀名
        file-extension: yaml
      discovery:
        cluster-name: BJ
        namespace: 1688ddc5-4f48-4bdc-bb5b-8c5363edf242
        ephemeral: false

Then come to UserController.javapull configuration file information

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    
    

    @Value("${pattern.dataformat}")
    private String dataFormat;

    @GetMapping("/now")
    public String now() {
    
    
        // 由于我们之前在nacos中设置的配置项配置了pattern属性,这里就可以直接调用对应的属性完成时间格式化了
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dataFormat));
    }
}

Automatic updates

application.yamlThe advantage of using the configuration file directly in nacos is that hot updates can be implemented in real time, instead of having to restart after setting it in the project.

We only need to add annotations to the beans using the nacos configuration file @RefreshScope.

@Slf4j
@RestController
@RequestMapping("/user")
@RefreshScope // 添加检测配置文件更新的注解
public class UserController {
    
    }

Or you can create a custom configuration class and dynamically obtain the specified configuration

@Component
@Data
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
    
    
    private String dataFormat;
}

We can specifically configure the configuration file that specifies the operating environment (such as dev): userservice-dev.yaml
or define the server's global (common to all environments) configuration file:userservice.yaml

Priority between configuration files: Configuration file with environment parameters > Global configuration file > application.yaml


Feign

Replaces RestTemplate

Compared with resttemplate's inefficient string splicing, feign provides a form of interface operation, allowing us to connect to the corresponding server provider more intuitively.

First introduce dependencies

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

Be sure to remember to enable the feign client in the entry class

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
@EnableFeignClients // 开启feign客户端
public class OrderApplication {
    
    }

Create an interface class to obtain the interface of the server provider

Code listing:clients/UserClient.java

// 注解内填入需要链接到的服务器名称
@FeignClient("userservice")
public interface UserClient {
    
    
    // 表示使用GET请求获取数据
    @GetMapping("/user/{id}")
    // 同理PathVariable用来填补上方路径中的id占位符
    User findById(@PathVariable("id") Long id);
}

Finally rewrite the query logic in the service

@Service
public class OrderService {
    
    

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserClient userClient;

    public Order queryOrderById(Long orderId) {
    
    
        // 查询订单
        Order order = orderMapper.findById(orderId);
        // feign客户端请求user数据库中内容
        User user = userClient.findById(order.getUserId());
        order.setUser(user);
        return order;
    }
}

After running orderservice, enter in the browser http://localhost:10087/order/101to obtain the corresponding data! In fact, the effect you see is almost the same as resttemplate


Feign custom configuration

Configure log output level

Global configuration

feign:
  client:
    config:
      default:
        loggerLevel: FULL

Local configuration (explicitly indicate the server name)

feign:
  client:
    config:
      userservice:
        loggerLevel: FULL

Or you can write it in code

Insert image description here


Performance optimization

Using the URLConnection connection pool to replace the original single link can improve the efficiency of the feign client.

Import feign-httpclient coordinates

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

Then configure the properties in the configuration file

feign:
  client:
    config:
      default:
        # 日志级别最好使用BASIC或者NONE,其他的级别比较耗费性能而且基本用不上
        loggerLevel: BASIC
  httpclient:
    enabled: true
    max-connections: 200
    max-connections-per-route: 50

Guess you like

Origin blog.csdn.net/delete_you/article/details/132941516