Use Spring Cloud Feign as HTTP client to call remote HTTP service

In the Spring Cloud Netflix stack, each microservice exposes its own service in the form of an HTTP interface, so an HTTP client must be used when calling a remote service. We can use JDK native URLConnection, Apache Http Client, Netty's asynchronous HTTP Client, Spring's RestTemplate. However, the most convenient and elegant to use is Feign.

Introduction to Feign

Feign is a declarative, templated HTTP client. Using Feign in Spring Cloud, we can achieve the same coding experience as calling a local method when using HTTP to request a remote service. Developers are completely unaware that this is a remote method, let alone an HTTP request. for example:

@Autowired
 private AdvertGropRemoteService service ; // remote service
 public AdvertGroupVO foo (Integer groupId) {
     return service .findByGroupId(groupId) ; // call remote service via HTTP
 }

Developers service.findByGroupId()can complete the process of sending HTTP requests and decoding HTTP return results and encapsulating them into objects.

Definition of Feign

In order to let Feign know which address to send a request to when calling a method and what parameters the request needs to take, we need to define an interface:

@FeignClient(name = "ea")  //  [A]
public interface AdvertGroupRemoteService {
    @RequestMapping(value = "/group/{groupId}", method = RequestMethod.GET) // [B]
    AdvertGroupVO findByGroupId(@PathVariable("groupId") Integer adGroupId) // [C]
    @RequestMapping(value = "/group/{groupId}", method = RequestMethod.PUT)
    void update(@PathVariable("groupId") Integer groupId, @RequestParam("groupName") String groupName)
}

A: @FeignClientIt is used to notify the Feign component to proxy the interface (no need to write the interface implementation), and the user can directly @Autowiredinject it.

B: Indicates that a request needs to be sent @RequestMappingto when calling this method ./group/{groupId}GET

C: It has the @PathVariablesame SpringMVCmeaning as the corresponding annotation in .

When the Spring Cloud application is started, Feign will scan the @FeignClientannotated interface, generate a proxy, and register it with the Spring container. When generating a proxy, Feign will create an RequetTemplateobject for each interface method, which encapsulates all the information required by the HTTP request. The request parameter name, request method and other information are determined in this process, and Feign's templating is reflected here. .

In this example, we use Feign in combination with Eureka and Ribbon, @FeignClient(name = "ea")which means to inform Feign to query Eureka for eathe service named when calling the interface method, so as to get the service URL.

Feign的Encoder、Decoder和ErrorDecoder

The process of Feign serializing the method parameter object in the method signature into the request parameter and putting it into the HTTP request is completed by the Encoder. Similarly, the deserialization of HTTP response data into java objects is done by Decoder.

By default, Feign will convert @RequestParamthe parameters marked with annotations into strings and add them to the URL, and convert the parameters without annotations into json through Jackson and put them in the request body. Note that all unmarked parameters will be ignored if the request method is specified in , for @RequetMappingexample method:POST

@RequestMapping(value = "/group/{groupId}", method = RequestMethod.GET)
void update(@PathVariable("groupId") Integer groupId, 
            @RequestParam("groupName") String groupName,
            DataObject obj);

At this point, because it is declared that the GET request has no request body, the objparameters will be ignored.

In the Spring Cloud environment, Feign's Encoder* will only be used to encode parameters without annotations*. If you customize the Encoder, objyour Encoder will only be called when encoding parameters. For Decoder, the default will be delegated to MappingJackson2HttpMessageConverterclasses in SpringMVC for decoding. ErrorDecoder will only be called when the status code is not between 200 and 300. The function of ErrorDecoder is to return an exception based on the HTTP response information, which can be caught where the Feign interface is called. We currently use ErrorDecoder to make the Feign interface throw business exceptions for the caller to handle.

Feign的HTTP Client

By default, Feign uses JDK to URLConnectionsend HTTP requests natively. There is no connection pool, but it will maintain a long connection for each address, that is, using HTTP persistence connection. We can replace Feign's original http client with Apache's HTTP Client to obtain performance-related control capabilities such as connection pool and timeout. Spring Cloud Brixtion.SR5supports this replacement since version, first declare Apache HTTP Client and feign-httpclientdependencies in the project:

<!-- 使用Apache HttpClient替换Feign原生httpclient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>
<dependency>
    <groupId>com.netflix.feign</groupId>
    <artifactId>feign-httpclient</artifactId>
    <version>${feign-httpclient}</version>
</dependency>

Then application.propertiesadd in:

feign.httpclient.enabled=true

Summarize

Through Feign, we can make HTTP remote calls completely transparent to developers, and get the same coding experience as calling local methods. This is similar to the way Ali Dubbo exposes remote services. The difference is that Dubbo is based on a private binary protocol, while Feign is essentially an HTTP client. If you are building microservices with Spring Cloud Netflix, Feign is undoubtedly the best choice.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325766229&siteId=291194637