Springcloud, Nacos service registration, load balancing Ribbon, http client Feign

Posted by brad_fears on Sun, 21 Nov 2021 01:54:55 +0100

        Spring cloud is a complete set of framework for implementing microservices based on spring boot. It provides such components as configuration management, service discovery, circuit breaker, intelligent routing, micro agent, control bus, global lock, decision-making, distributed session and cluster state management. Most importantly, based on SpringBoot, it will make it very convenient to develop microservice architecture.

Official website address: Spring Cloud.

Spring Cloud Environment: idea+jdk1.8+maven

Spring cloud starts the entry package structure (api packages can not be created at first). Note that some maven dependencies need to be modified into their own

  code:

sql code:

tb_orde

tb_user:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'addressee',
  `address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'address',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES (1, 'Tang Bohu', 'Shanghai');
INSERT INTO `tb_user` VALUES (2, 'Zhu Zhishan', 'Beijing');
INSERT INTO `tb_user` VALUES (3, 'Chinese sunfish', 'Guizhou');
INSERT INTO `tb_user` VALUES (4, 'Zhang Bichen', 'Xi'an');
INSERT INTO `tb_user` VALUES (5, 'Zheng Shuangshuang', 'Liaoning');
INSERT INTO `tb_user` VALUES (6, 'Fan Bingbing', 'Shandong');

SET FOREIGN_KEY_CHECKS = 1;

springcloud-parent:

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.demon</groupId>
    <artifactId>springcloud-parent</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>springcloud-order</module>
        <module>springcloud-pojo</module>
        <module>springcloud-user</module>
        <module>springcloud-api</module>
    </modules>
    <!--spring-boot Start dependence-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.8.RELEASE</version>
    </parent>
    <!--version control -->
    <properties>
        <!--spring cloud edition-->
        <spring.cloud-version>Hoxton.SR10</spring.cloud-version>
        <!--jdk edition-->
        <java.version>1.8</java.version>
        <skipTests>true</skipTests>
        <mybatis.version>2.1.1</mybatis.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
    </dependencies>
    <!--rely on-->
    <dependencyManagement>
        <dependencies>
            <!--introduce SpringCloudAlibaba Dependence 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>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

springcloud-order:

Package structure:

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-parent</artifactId>
        <groupId>com.demon</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-order</artifactId>

    <dependencies>
        <!--rely on pojo-->
        <dependency>
            <groupId>com.demon</groupId>
            <artifactId>springcloud-pojo</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
       
        <!--web Start dependence-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--introduce mysql Driver package-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!--springboot maven plug-in unit-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

yml:

server:
  port: 1314
spring:
  application:
    name: springcloud-order
  profiles:
    active: dev
  datasource:
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springcloud?characterEncoding=UTF8&&serverTimezone=Asia/Shanghai
    username: root
    password: root

controller:

package com.demon.controller;

import com.demon.order.pojo.Order;
import com.demon.service.OrderService;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Order Control layer of
 */
@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private OrderService orderService;

    /**
     * Query order information
     */
    @GetMapping(value = "/{id}")
    public Order one(@PathVariable(value = "id") Long id){
        return orderService.selectById(id);
    }

}

dao:

package com.demon.dao;

import com.demon.order.pojo.Order;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface OrderDao {
    /**
     * Query by id
     * @param id
     * @return
     */
    @Select(value = "select * from tb_order where id = #{id}")
    Order selectById(Long id);
}

service:

package com.demon.service;

import com.demon.order.pojo.Order;

public interface OrderService {
    /**
     * Query by id
     * @param id
     * @return
     */
    Order selectById(Long id);
}

impl:

package com.demon.service.impl;


import com.demon.dao.OrderDao;
import com.demon.order.pojo.Order;
import com.demon.service.OrderService;
import com.demon.user.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * Query by id
     * @param id
     * @return
     */
    @Override
    public Order selectById(Long id) {
        //1. Query order
        Order order = orderDao.selectById(id);
        //2. Query user information according to the order RestTemplate remote call method
        String url="http://localhost:10086/user/"+order.getUserId();
        User forObject = restTemplate.getForObject(url, User.class);
        //3. Packaging information
        order.setUser(forObject);
        //4. Return order information
        return order;
    }
}

Startup class:

package com.demon;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

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

    //Remote call
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

springcloud-pojo:

Order:

package com.demon.order.pojo;

import com.demon.user.pojo.User;
import lombok.Data;

import java.io.Serializable;

@Data
public class Order implements Serializable {
    private Long id;
    private Long price;
    private String name;
    private Integer num;
    private Long userId;
    private User user;
}

User:

package com.demon.user.pojo;

import lombok.Data;

import java.io.Serializable;

@Data
public class User implements Serializable {
    private Long id;
    private String username;
    private String address;
}

springcloud-user:

Package structure:

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-parent</artifactId>
        <groupId>com.demon</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-user</artifactId>

    <dependencies>
        <!--rely on pojo-->
        <dependency>
            <groupId>com.demon</groupId>
            <artifactId>springcloud-pojo</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--introduce feign-api-->

        <!--web Start dependence-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--introduce mysql Driver package-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
    </dependencies>
</project>

yml:

server:
  port: 10086
spring:
  application:
    name: springcloud-user
  profiles:
    active: dev
  datasource:
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springcloud?characterEncoding=UTF8&&serverTimezone=Asia/Shanghai
    username: root
    password: root

controller:

package com.demon.controller;

import com.demon.service.UserService;
import com.demon.user.pojo.User;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

    @Autowired
    private UserService userService;

    /**
     * Call the method of controller in user's Micro service
     */
    @GetMapping(value = "/{id}")
    public User one(@PathVariable(value = "id") Long id){
        return userService.selectById(id);
    }
}

dao:

package com.demon.dao;

import com.demon.user.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface UserDao {
    /**
     * Query user information according to id
     * @param id
     * @return
     */
    @Select(value = "select * from tb_user where id = #{id}")
    User selectById(Long id);
}

service:

package com.demon.service;

import com.demon.user.pojo.User;

public interface UserService {
    /**
     * Query user information according to id
     * @param id
     * @return
     */
    User selectById(Long id);
}

impl:

package com.demon.service.impl;

import com.demon.dao.UserDao;
import com.demon.service.UserService;
import com.demon.user.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    /**
     * Query user information according to id
     * @param id
     * @return
     */
    @Override
    public User selectById(Long id) {
        return userDao.selectById(id);
    }
}

Startup class:

package com.demon;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

According to the above calling process, there are many problems when consumers call the service provider:  :

1: How can a service consumer obtain the address information of a service provider?
2: If there are multiple service providers, how should consumers choose?
3: How do consumers know the health status of service providers?

Registry (nacos selected):

nacos registration: nacos download address

nacos download address nacos access address: http://localhost:8848/nacos

Nacos is a component of spring cloud Alibaba, which also follows the service registration and service discovery specifications defined in spring cloud. Therefore, there is not much difference between using Nacos and using Eureka for microservices.

The main differences are:

        1. Different dependence

        2. Different service addresses

nacos dependency:

Add dependencies to the springcloud parent project:

    <dependencyManagement>
        <dependencies>
            .......
            <!--introduce SpringCloudAlibaba Dependence 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>
        </dependencies>
    </dependencyManagement>

Import dependencies in spring cloud order and spring cloud user

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

Register the address of nacos in yml of spring cloud order and spring cloud user

spring:
  cloud:
    nacos:
      server-addr: localhost:8848 #nacos address configuration

Start:

First step

  Step 2:

If you don't have the following, start the class and it will appear here after startup

There are two problems in viewing nacos, so register:

However, the above is not practical. Therefore, the service hierarchical storage model:

A service can have multiple instances: and these instances are distributed in different regions. As shown below:

  Moreover, when microservices access each other, they should try to access instances in the same cluster, which should make local access faster. Access to other clusters only when this cluster is unavailable. As shown below:

Code: yml configuration cluster for spring cloud order and spring cloud user

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: SZ # Cluster name

nacos interface:  

  Only one instance is made, so two instance ports are added as 10087 and 10088:

Step 1:                                                             Step 2:

    

Replication startup view:

  However, all instances are in the SZ cluster, so: modify UserApplication3 to start

-Dserver.port=10088 -Dspring.cloud.nacos.discovery.cluster-name=HZ


View nacos:

  After setting up the nacos, write it in the UserController of the spring cloud user for viewing on the back end

Access the browser and enter: http://localhost:1314/order/101   or   http://localhost:10086/user/1

Browser page:  

 

View backend

http://localhost:1314/order/101   It is found that the access is always a receipt, so when you go back to the first point to check the OrderServiceImpl of spring cloud order, you find the dead address. 2. Therefore, the load balancing Ribbon appears

Load balancing Ribbon

Ribbon is a load balancer released by Netflix to help control HTTP client behavior. After configuring the service provider address list for the ribbon, the ribbon can automatically help service consumers request based on the load balancing algorithm.

Concept: Ribbon is a client load balancer based on Http protocol request, which can realize a wealth of load balancing algorithms.

Load balancing process (use EurekaServer to demonstrate that the port number is different from the above, but the effect is the same):  

Load balancing algorithm  :

The polling call involves many load balancing algorithms. There are many load balancing algorithms. The relationship diagram is as follows:

Built in load balancing rule class
RoundRobinRuleSimply poll the list of services to select the server.
AvailabilityFilteringRule

Ignore the following two servers:

(1) By default, if the server fails to connect three times, the server will be set to the "short circuit" state. The short circuit state will last for 30 seconds. If the connection fails again, the short circuit duration will increase geometrically.

(2) Servers with high concurrency. If the number of concurrent connections to a server is too high, clients configured with the availability filtering rule will ignore it. The maximum number of concurrent connections can be configured by the < ClientName >. < clientconfignamespace >. Activeconnectionslimit property of the client.

WeightedResponseTimeRuleEach server is given a weight value. The longer the server response time, the smaller the weight of the server. This rule will randomly select servers, and this weight value will affect the selection of servers.
ZoneAvoidanceRule [default]

Select servers based on the servers available in the region. Use Zone to classify servers. This Zone can be understood as a machine room, a rack, etc. Then poll multiple services in the Zone. It is the default load balancing rule of Ribbon.

BestAvailableRuleIgnore which servers are short circuited and select servers with low concurrency.
RandomRuleRandomly select an available server.
RetryRuleSelection logic of retry mechanism

Ribbon load balancing algorithm can be used in two ways:

1. Code mode

Register the implementation class of IRule interface (load balancing algorithm): add the following load balancing registration code to the startup class in springcloud order:

/**
 * Random load balancing algorithm
 * @return
 */
@Bean
public IRule randomRule() {
    return new RandomRule();
}

2. Configuration mode

Configure the load balancing algorithm for the specified service: add the following configuration in the core configuration file of springcloud order:

#Note that the following nodes are configured
#The specified service uses the specified load balancing algorithm
springcloud-user:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #Load balancing rules

By default, the Ribbon uses lazy loading, that is, the LoadBalanceClient will be created during the first access, and the request time will be very long. Hungry loading will be created when the project is started to reduce the time-consuming of the first access. In the core configuration file of springcloud order, add the following configuration to start hungry loading:

#Note that the following nodes are configured
#Starvation loading
ribbon:
  eager-load:
    clients: springcloud-user #Specify the user to load this service
    enabled: true #Turn on hungry loading 

Visiting the web site http://localhost:1314/order/101 Another problem is found: all three clusters can be realized; the priority load balancing of the same cluster is not realized.

Load balancing with cluster priority:

The default ZoneAvoidanceRule cannot achieve load balancing according to the same cluster priority.

Therefore, Nacos provides an implementation of NacosRule, which can preferentially select instances from the same cluster.

Modify the yml file of spring cloud order and restart

#Load balancing with cluster priority
springcloud-user:
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # Load balancing rules

However, in the OrderServiceImpl that returns the spring cloud order, check the following code:

There is a problem with the code that RestTemplate initiated the remote call:

1. Poor code readability and inconsistent programming experience

2. The parameters are complex and the URL is difficult to maintain

Solution: Feign solution

Feign

It is a declarative http client. The official address is: GitHub - OpenFeign/feign: Feign makes writing java http clients easier

1: Introduce the dependency package spring cloud starter openfeign

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

2: Add annotation @ EnableFeignClients to enable Feign function

   3: Define the remote call interface, in which the [service name] and [method signature] of the remote call are well known

package com.demon.client;

import com.demon.user.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * order Call user service (instead of string URL)=“ http://springcloud-user/user/ "+order.getUserId();)
 * 1.Use @ feignclient on the interface (value = "called service name")
 * 2.Define the method in the called interface (written based on the called controller)
 *  2.1 requestMapping The path in must be a full path (on the + method on the controller class)
 *  2.2 The PathVariable annotation must be aliased
 */
@FeignClient(value = "springcloud-user")
public interface UserClient {

    /**
     * Call the method of controller in user's Micro service
     */
    @GetMapping(value = "/user/{id}")
    public User one(@PathVariable(value = "id") Long id);
}

It is mainly based on the annotation of spring MVC to declare the information of remote call, such as:

  • Service Name: user

  • Request method: GET

  • Request path: / user/{username}

  • Request parameter: String username

  • Return value type: User

4: Inject interface, execute remote call (Interface)

Feign best practices:

Method 1 (inheritance): define a unified parent interface for the FeignClient of the consumer and the controller of the provider as the standard.

Problems: 1. Service coupling       2. The mapping in the parent interface parameter list will not be inherited

   Method 2 (extraction): extract FeignClient as an independent module, and put the POJO related to the interface and the default Feign configuration into this module for all consumers to use.

1: Create the springcloud API, and then introduce feign's starter dependency and springcloud user dependency

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

        <!--httpClient rely on-->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
        </dependency>

        <dependency>
            <groupId>org.example</groupId>
            <artifactId>springcloud-pojo</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

2: Copy the UserClient written in spring cloud order to the itheima API project
3: Introducing spring cloud API dependency in spring cloud order
4: Restart test

be careful:

Sometimes the idea will cause a wind (generally there is a problem in copying the code): all steps have been done, the dependency is correct, etc., but the package cannot be imported in OrderServiceImpl, and the UserClient is not displayed. At this time, you should check the following figure. If it is not your own, delete it and input it again. QAQ copied my last code, and then fainted for a long time. Restart idea and found that it still can't work. Accidentally put it on it and found that it wasn't written locally.

  These feignclients cannot be used when the feignclients defined are not within the scanning package scope of SpringBootApplication.

There are two ways to solve this problem:

Method 1: specify the package of FeignClient

@EnableFeignClients("com.demon.client")

Method 2: specify FeignClient bytecode

@EnableFeignClients(clients = UserClient.class)

Feign function:

Feign runs a custom configuration to override the default configuration. The configurations that can be modified are as follows:

typeeffectexplain
feign.Logger.LevelModify log levelThere are four different levels: NONE, BASIC, HEADERS and FULL
feign.codec.DecoderParser for response resultsParse the result of the http remote call, for example, parse the json string as a java object
feign.codec.EncoderRequest parameter codeEncode the request parameters for sending through http request
feign. ContractSupported annotation formatsEncode the request parameters for sending through http request
feign. RetryerFailure retry mechanismThe retry mechanism for request failure is not available by default, but the Ribbon retry mechanism will be used

Feign log configuration:

logging:
  level:
    #At what level does feign log monitor which interface
    com.demon: debug

NONE: by default, no logs are displayed
BASIC: only record the request method, URL, response status code and execution time
HEADERS: in addition to the information defined in BASIC, there are also header information of request and response
FULL: in addition to the information defined in HEADERS, there are also the body and metadata of the request and response

There are two ways:

Mode 1 configuration file mode:

feign:
  client:
    config:
      default: #default here is the global configuration. If the service name is written, it is the configuration for a micro service
        loggerLevel: BASIC #log level
      springcloud-user: #Specified service
        loggerLevel: BASIC #log level

Mode 2 code mode: (I don't understand QAQ, you can go to Baidu or other places to find it)

Feign Performance Optimization:

Feign's underlying client implementation:

  • URLConnection: it is implemented by default and does not support connection pool

  • Apache HttpClient: support connection pool

  • OKHttp: support connection pool

Therefore, optimizing Feign's performance mainly includes:

  • Use the connection pool instead of the default URLConnection

  • Log level, preferably basic or none

feign:
  client:
    config:
      default: #default here is the global configuration. If the service name is written, it is the configuration for a micro service
        loggerLevel: BASIC #log level
      springcloud-user: #Specified service
        loggerLevel: BASIC #log level
  httpclient:
    enabled: true #Enable feign's support for HttpClient
    max-connections: 200 #Maximum connections
    max-connections-per-route: 50 #Maximum connections per path

Weight configuration:

This scenario will appear in the actual deployment:

There are differences in the performance of server devices. The performance of some instances is good, while others are poor. We hope that the machines with good performance will bear more user requests.

However, by default, nacosrules are randomly selected in the same cluster, and the performance of the machine will not be considered.

Therefore, Nacos provides weight configuration to control the access frequency. The greater the weight, the higher the access frequency.

On the nacos console, find the instance list of user service and click Edit to modify the weight:

  Click Edit to enter weight modification:

  Note: the weight value cannot be changed to 0, otherwise the instance

Environmental isolation:

Nacos provides a namespace for environment isolation.

There can be multiple namespace s in nacos (environment isolation: test dev pro)

There are group s, service s, etc. under the namespace

Different namespaces are isolated from each other. For example, services in different namespaces are not visible to each other

  By default, all service s, data and group s are in the same namespace, named public:

establish

And modify the yml file class of spring cloud order

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: SZ #Cluster name
        namespace: devnamespace #Namespace, fill in ID

Finally (some of the previous drawings did not explain that the environment isolation also has dev space, which I equipped at that time):

  Note: if the springcloud user is not configured, then an error will occur when accessing the address:

  Modify one here for reference:

-Dspring.cloud.nacos.discovery.namespace=devnamespace

Topics: Java Spring Boot Spring Cloud Microservices