springcloud: how do microservices communicate? Component communication component: detailed explanation of feign (6)

0 Preface

In the last issue, we built a gateway, configuration center, and registration center. If you haven’t read the previous articles, you can first understand:
springcloud: what is distributed microservice and how to learn microservice (1)
springcloud: what technologies and core components are involved in microservice (2)
springcloud: gateway component gateway detailed explanation (3) )
springcloud: detailed explanation of registry and configuration center components nacos (4)
springcloud: nanny-style tutorial - building microservices from scratch (5)

But there is still a core problem that has not been solved, that is the communication problem between microservices. For example, we need to call the product list data in our order service, and the product list data is obtained in the product service, then we need to call the interface of the product service in the order service. This kind of inter-service call is called inter-group communication

Currently commonly used component communication is RestTemplate and feign. The use of RestTemplate is relatively troublesome, and it needs to write lower-level information such as service IP, while feign does not need it, which is more in line with the local call method.

Based on the concept of getting started quickly with the most core technologies, we will first explain the more commonly used feign components. More details on RestTemplate later

1. Introduction to Feign

Feign is a declarative web service client that makes calling between services easier. Makes the whole call as simple as a local call.

Feign includes Hystrix and ribbon. Therefore, feign supports interface load balancing, as well as interface fusing, downgrading, and current limiting. And supports compression of Http requests and responses.
insert image description here

2. Feign use

1. To use feign, we need to introduce the dependencies of feign

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

It should be noted that Feign is a POST request by default. If you want to support a GET request with parameters, you need to introduce the feign-httpclient dependency

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

At the same time, because it is a web api, Spring web dependencies must also be introduced. It has been introduced and there is no need to repeat it.

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

2. Add the annotation @EnableFeignClients to the startup class of the caller service

2.1 Call the service directly through IP

If you call directly through IP, you only need to create the Feign interface class in the caller's service. Where name is the service name, url is the actual interface address, if there are multiple, they can be separated by commas

What is written in the interface is the URL address corresponding to the controller. For example, there is a list interface in the user controller, and the url is list. Then the corresponding method in the Feign interface class should be consistent with the interface address in the controller

@FeignClient(name = "order-server",url = "localhost:8081")
public interface OrderApi {
    
    @GetMapping("list")
    public List<Order> list();
    
}

There is a point to note, if the interface prefix in the controller is unified, such as /user. In the feign interface class, it cannot be declared through @RequestMapping, but this prefix must be added to each method, as follows:

@FeignClient(name = "order-server",url = "localhost:8081")
public interface OrderApi {

    String PREFIX = "order";
    String LIST = PREFIX + "/list";
    String PAGE = PREFIX + "/page";

    @GetMapping(LIST)
    public List<Order> list();

    @GetMapping(PAGE)
    public List<Order> page();
    
}

2.2 Calling through nacos

You can use the service name directly without defining the url. Create the interface in the caller

@FeignClient(name = "product-server",url = "localhost:9091")
public interface ProductApi {

    @GetMapping("list")
    public List<Product> list();
}

test

We test based on the springcloud project built in the previous lesson. In order not to affect the code of the previous lesson, we will create a separate springcloud2 for testing in this chapter.

1. Introduce dependencies in the order-server service

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
            <version>10.10.1</version>
        </dependency>
        <-- 因为要使用Product实体类,所以需要引入product-server -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>product-server-feign</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>

2. Create the ProductApi interface class in the order-server

@FeignClient(name = "product-server",url = "localhost:9091")
public interface ProductApi {

    @GetMapping("list")
    public List<Product> list();
}

3. Add the @EnableFeignClients annotation to the order-server startup class

4. Create an interface in the OrderController of the order-server to call the methods in the feign interface class

@RestController
@AllArgsConstructor
public class OrderController {
    private final IOrderService orderService;
    private final ProductApi productApi;

    @GetMapping("list")
    public List<Order> list(){
        return orderService.list();
    }

    @GetMapping("listProduct")
    public List<Product> listProduct(){
        return productApi.list();
    }

}

5. Test access http://localhost/order-server/listProduct

You can see that we have called the list interface of the product service in the order service, and the result returns the product list information
insert image description here

2.3 Retry and timeout

Feign includes ribbon, so you can use ribbon's retry and timeout mechanism, just modify it in the configuration file:

  • retry configuration
#同一台实例最大重试次数,不包括首次调用
ribbon.MaxAutoRetries=1
#重试负载均衡其他的实例最大重试次数,不包括首次调用
ribbon.MaxAutoRetriesNextServer=1
#是否所有操作都重试
ribbon.OkToRetryOnAllOperations=false
  • Timeout configuration: The connection timeout here refers to the time to connect to the interface, and the business logic timeout refers to the execution time of the business logic after the connection is successful.
#连接超时时间(ms)
ribbon.ConnectTimeout=1000
#业务逻辑超时时间(ms)
ribbon.ReadTimeout=6000

2.4 Service fuse and downgrade

Before configuring circuit breaker downgrade, we need to understand what is service circuit breaker? What is a service downgrade?

Service fuse: When the number of consecutive connection failures reaches the threshold, an error will be reported directly, and subsequent identical requests will also report an error directly. This measure is called fuse. It is equivalent to our common fuse. When it is determined that the service cannot be accessed, the subsequent connection is directly disconnected.

Service degradation: When the number of consecutive connection failures reaches the threshold or times out, the requester is given a guarantee message, which can be:
(1) Return a friendly page, such as a retry button, contact email or some basic static pages
( 2) Return the prompt information, write the data into MQ, and retry through MQ later
(3) Return friendly prompt information, such as "come later", "service is busy, please try again later", etc., Do nothing else
We call such measures as de-escalation.

By default, feign will not use Hytrix for service downgrade, so if you want to use it, you need to open it in the configuration file:

feign.hystrix.enabled=true

Fusing, downgrading configuration

Feign uses the fallback class to implement the callback method after the request fails
1. Create a callback class

@Component
public class UserProviderBack implements UserApi {

    @Override
	public Map findById(@RequestParam("id") Integer id){
	// 降级,给出友好性提示
        return "服务走远了,请稍后重试";
    }
    
    @Override
	public Map getMap(@RequestParam Map<String,Object> map){
	// 熔断,直接返回空数据
       return null;
   }	
 
}

2. Declare the callback class

@FeignClient(name="user-provider",fallback= UserProviderBack.class)
public interface UserApi {

    @GetMapping("/findById")
	public Map findById(@RequestParam("id") Integer id);
    
    @GetMapping("/getMap")
	public Map getMap(@RequestParam Map<String,Object> map);	
 
}

Well, this is the end of our explanation of the feign component in this issue. We do not recommend using feign to implement the current limiting configuration. If it is to be done, it is also processed in fallback. The current limiting measures in microservices will be explained in detail later. . The test code in this article has also been put into the git project , welcome to download and experience

next notice

1. Advanced explanation of microservice framework

Follow the official account for more fresh content

insert image description here

Guess you like

Origin blog.csdn.net/qq_24950043/article/details/123947704