SpringCloud-Feign declarative service call

In the previous article can be found when other API services we call by RestTemplate, the parameters needed to be spliced ​​in the URL request, if the parameter less, then perhaps we can live with, if there is more argument, then request string will splicing efficiency is low, and seem silly.

So is there a better solution? The answer is determined there is, Netflix has provided a framework for us: Feign.

Feign Web Service client is a declarative, its aim is to make Web Service calls easier. Feign provides a template for HTTP requests, through a simple interface to write and insert annotations, you can define the parameters of good information HTTP request, format, address and so on.

The Feign will be full proxy HTTP requests, we only need to call it like to call the same method can be completed service requests and related processing. Feign integration Ribbon and Hystrix (About Hystrix we revisit later), you can let us no longer need to explicitly use these two components.

Collectively, Feign has the following characteristics:

  • Pluggable annotation support, including Feign JAX-RS annotations and notes;
  • HTTP support pluggable encoder and decoder;
  • Support Hystrix and its Fallback;
  • Support Ribbon load balancing;
  • Support compression of HTTP requests and responses.

It looks a bit like RequestMapping mapping Controller layer of our springmvc mode. This model is our very favorite. Feign is @FeignClient to map services.

 

The first step, on the basis of the new original Feign a module, followed by the introduction of dependencies, dependence Feign introduction, will automatically introduce Hystrix dependent, as follows:

Copy the code
    <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <version>1.4.0.RELEASE</version>
        </dependency>
Copy the code

 

application.yml configuration is as follows:

Copy the code
server:
  port: 8083
spring:
  application:
    name: feign-consumer
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/
Copy the code

 

 

Then add in the previous article and the two provider1 provider2 two service modules several methods, as shown in the following code:

Copy the code
/**
 * Created by cong on 2018/5/8.
 */
@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello(){
        System.out.println("访问来1了......");
        return "hello1";
    }

    @RequestMapping("/hjcs")
    public List<String> laowangs(String ids){
        List<String> list = new ArrayList<>();
        list.add("laowang1");
        list.add("laowang2");
        list.add("laowang3");
        return list;
    }

    //新增的方法
    @RequestMapping(value = "/hellol", method= RequestMethod.GET)
    public String hello(@RequestParam String name) {
        return "Hello " + name;
    }

    @RequestMapping(value = "/hello2", method= RequestMethod.GET)
    public User hello(@RequestHeader String name, @RequestHeader Integer age) {
        return new User(name, age);
    }

    @RequestMapping(value = "/hello3", method = RequestMethod.POST)
    public String hello (@RequestBody User user) {
        return "Hello "+ user. getName () + ", " + user. getAge ();
    }

}
Copy the code

 

Then the code used above is required User class, as follows:

Copy the code
/ ** 
 * 2017/12/2 the Created by Cong. 
 * / 
Public class {the User 

    Private String name; 
    Private Age Integer; 

    // serialized when transmitted constructor must be available, or be wrong 
    public the User () { 
    } 
    the User public (String name, Integer Age) { 
        this.name = name; 
        this.age = Age; 
    } 

    public String getName () { 
        return name; 
    } 

    public void the setName (String name) { 
        this.name = name; 
    } 

    public Integer getAge () { 
        return Age; 
    } 

    public void the setAge (Integer Age) { 
        this.age = Age; 
    } 
}
Copy the code

 

Then the mapping service calls using Feign of @FeignClient ( "Service Name"). code show as below:

Copy the code
HJC Package Penalty for; 

Import org.springframework.cloud.netflix.feign.FeignClient; 
Import org.springframework.web.bind.annotation *;. 

/ ** 
 * the Created by Cong ON 2018/5/17. 
 * / 
// the Configuration = xxx .class class configuration Hystrix some precise attribute 
// value = "service name you used"
@FeignClient (value = "the Hello-service", fallback = FeignFallBack.class) public interface FeignService {   mapping service method // path @RequestMapping ( "/ Hello") String Hello (); @RequestMapping (value = "/ hellol", Method = RequestMethod.GET) String Hello (@RequestParam ( "name") String name); @RequestMapping (value = " / hello2 ", method = RequestMethod.GET) the User Hello (@RequestHeader ( "name") String name, @RequestHeader ( "age") Integer age); @RequestMapping(value = "/hello3", method= RequestMethod.POST) String hello(@RequestBody User user); }
Copy the code

 

Controller then injection layer FeiService this interface, remote service call, as follows:

Copy the code
/**
 * Created by cong on 2018/5/17.
 */
@RestController
public class ConsumerController {

    @Autowired
    FeignService feignService;

    @RequestMapping("/consumer")
    public String helloConsumer(){
        return feignService.hello();
    }

    @RequestMapping("/consumer2")
    public String helloConsumer2(){
        String r1 = feignService.hello("hjc");
        String r2 = feignService.hello("hjc", 23).toString();
        String r3 = feignService.hello(new User("hjc", 23));
        return r1 + "-----" + r2 + "----" + r3;
    }

}
Copy the code

 

Next, at startup class Feign module where Eureka client notes marked @EnableDiscoveryClient Feign client notes @EnableFeignClients, code is as follows:

Copy the code
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class FeignApplication {

    public static void main(String[] args) {
        SpringApplication.run(FeignApplication.class, args);
    }
}
Copy the code

 

Next Start Start type, browser type localhost: 8083 / consumer results are as follows:

 

Load balancing can be seen polling appear hello1, hello2.

 

Then continues input in the browser localhost: 8083 / consumer2, results are as follows:

 

 

Next, we performed a service degradation under Feign use declarative call to service, then we must create a new class to inherit FeignFallBack FeiService, code is as follows:

Copy the code
package hjc;

import org.springframework.stereotype.Component;

/**
 * Created by cong on 2018/5/17.
 */
@Component
public class FeignFallBack implements FeignService{
  //实现的方法是服务调用的降级方法 @Override public String hello() { return "error"; } @Override public String hello(String name) { return "error"; } @Override public User hello(String name, Integer age) { return new User(); } @Override public String hello(User user) { return "error"; } }
Copy the code

 接着我们再把那两个服务提供模块provider1,provider2模块进行停止,运行结果如下所示:

 

 可以看到我们这几个调用,都进行了服务降级了。

 

那么如果我们想精确的控制一下Hystrix的参数也是可以的,比方说跟Hystrix结合的参数,那么可以在FeignClient注解里面配置一个Configuration=XXX类.class属性,在哪个类里面精确的指定一下属性。

或者在application.yml里面配置,如下:

Copy the code
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutinMilliseconds: 5000

ribbon:
  connectTimeout: 500

#如果想对单独的某个服务进行详细配置,如下
hello-service:
  ribbon:
    connectTimeout: 500
Copy the code

 

这里满足了我们大部分场景的调用,但是有写精细场景,还是要用原生的Hystrix,跟我们之前的Hystrix用法一下,不要走Feign客户端调用就行了,如下:

Copy the code
/**
 * Created by cong on 2018/5/17.
 */
public class HjcCommand extends HystrixCommand {
    protected HjcCommand(HystrixCommandGroupKey group) {
        super(group);
    }

    @Override
    protected Object run() throws Exception {
        return null;
    }
}
Copy the code

 

那么我们如果想用原声的HystrixCommand去搞一个异步请求怎么办?代码如下:

首先再引入一个依赖,feign客户端没有默认引入进来,需要我们自己引入:

    <dependency>
            <groupId>com.netflix.hystrix</groupId>
            <artifactId>hystrix-javanica</artifactId>
            <version>1.5.9</version>
        </dependency>

接着用HystrixCommand注解方式实现:

Copy the code
/**
 * Created by cong on 2018/5/17.
 */
@Service
public class HjcCommand {

    @Autowired
    private FeignService feignService;

    //同步方式
    @HystrixCommand
    public Future<String> getEmployeesAsync(){
        return new AsyncResult<String>() {
            @Override
            public String invoke() {
                return feignService.hello("hjc");
            }
        };
    }

    //用同步方式还不如直接用Feign客户端
    @HystrixCommand
    public String getEmployeesAsync1(){
        return feignService.hello("laowang");
    }

}
Copy the code

This is not enough, we also need to declare a section, HystrixConfiguration, then, will be added to the spring HystrixConfiguration management, as follows:

Copy the code
@Configuration
public class HystrixConfiguration {

    @Bean
    public HystrixCommandAspect hystrixAspect(){
        return  new HystrixCommandAspect();
    }

}
Copy the code

 

Transfer from https://www.cnblogs.com/huangjuncong/p/9053576.html

Guess you like

Origin www.cnblogs.com/cangqinglang/p/11718608.html