SpringCloud实战5-Feign声明式服务调用

在前面的文章中可以发现当我们通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还可以忍受,一旦有多个参数的话,这时拼接请求字符串就会效率低下,并且显得好傻。

那么有没有更好的解决方案呢?答案是确定的有,Netflix已经为我们提供了一个框架:Feign。

Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。

而Feign则会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了Ribbon和Hystrix(关于Hystrix我们后面再讲),可以让我们不再需要显式地使用这两个组件。

总起来说,Feign具有如下特性:

  • 可插拔的注解支持,包括Feign注解和JAX-RS注解;
  • 支持可插拔的HTTP编码器和解码器;
  • 支持Hystrix和它的Fallback;
  • 支持Ribbon的负载均衡;
  • 支持HTTP请求和响应的压缩。

这看起来有点像我们springmvc模式的Controller层的RequestMapping映射。这种模式是我们非常喜欢的。Feign是用@FeignClient来映射服务的。

首先第一步,在原来的基础上新建一个Feign模块,接着引入相关依赖,引入Feign依赖,会自动引入Hystrix依赖的,如下:

    <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>

application.yml配置如下:

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

接着在前面文章中的的的两个provider1和provider2两个模块的服务新增几个方法,如下代码所示:

/*** 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 ();}}

接着是上面代码所需用到的User类,代码如下:

/*** Created by cong 2017/12/2.*/
public class User {private String name;private Integer age;//序列化传输的时候必须要有空构造方法,不然会出错public User() {}public User(String name, Integer age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}
}

接下来用Feign的@FeignClient(“服务名称”)映射服务调用。代码如下:

package hjc;import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.*;/*** Created by cong on 2018/5/17.*/
//configuration = xxx.class  这个类配置Hystrix的一些精确属性//value=“你用到的服务名称”
@FeignClient(value = "hello-service",fallback = FeignFallBack.class)
public interface FeignService {//服务中方法的映射路径@RequestMapping("/hello")String hello();@RequestMapping(value = "/hellol", method= RequestMethod.GET)String hello(@RequestParam("name") String name) ;@RequestMapping(value = "/hello2", method= RequestMethod.GET)User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age);@RequestMapping(value = "/hello3", method= RequestMethod.POST)String hello(@RequestBody User user);
}

接着在Controller层注入FeiService这个接口,进行远程服务调用,代码如下:

/*** Created by cong on 2018/5/17.*/
@RestController
public class ConsumerController {@AutowiredFeignService 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;}}

接着在Feign模块的启动类哪里打上Eureka客户端的注解@EnableDiscoveryClient  Feign客户端的注解@EnableFeignClients,代码如下:

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

接着启动启动类,浏览器上输入localhost:8083/consumer  运行结果如下:

可以看到负载均衡轮询出现hello1,hello2。

接着继续在浏览器上输入localhost:8083/consumer2,运行结果如下:

接下来我们进行Feign声明式调用服务下的,服务降级的使用,那么我们就必须新建一个FeignFallBack类来继承FeiService,代码如下:

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

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

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

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

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

hystrix:command:default:execution:isolation:thread:timeoutinMilliseconds: 5000ribbon:connectTimeout: 500#如果想对单独的某个服务进行详细配置,如下
hello-service:ribbon:connectTimeout: 500

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

/*** Created by cong on 2018/5/17.*/
public class HjcCommand extends HystrixCommand {protected HjcCommand(HystrixCommandGroupKey group) {super(group);}@Overrideprotected Object run() throws Exception {return null;}
}

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

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

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

接着用HystrixCommand注解方式实现:

/*** Created by cong on 2018/5/17.*/
@Service
public class HjcCommand {@Autowiredprivate FeignService feignService;//同步方式@HystrixCommandpublic Future<String> getEmployeesAsync(){return new AsyncResult<String>() {@Overridepublic String invoke() {return feignService.hello("hjc");}};}//用同步方式还不如直接用Feign客户端@HystrixCommandpublic String getEmployeesAsync1(){return feignService.hello("laowang");}}

这样还不行,我们还需要声明一个切面,HystrixConfiguration,接着,将HystrixConfiguration加入到spring管理,代码如下:

@Configuration
public class HystrixConfiguration {@Beanpublic HystrixCommandAspect hystrixAspect(){return  new HystrixCommandAspect();}}

转载于:https://www.cnblogs.com/handsome1013/p/10948243.html

SpringCloud实战5-Feign声明式服务调用相关推荐

  1. SpringCloud Feign声明式服务调用

    SpringCloud Feign声明式服务调用 1. 加入pom依赖 2. Application.java上声明@EnableFeignClients 3. @FeignClient声明接口调用服 ...

  2. SpringCloud之声明式服务调用 Feign(三)

    一 Feign简介 Feign是一种声明式.模板化的HTTP客户端,也是netflix公司组件.使用feign可以在远程调用另外服务的API,如果调用本地API一样. 我们知道,阿里巴巴的doubbo ...

  3. 两个子集pom互相调用_声明式服务调用组件Feign

    什么是Feign?    Feign是SpringCloud组件中的一个轻量级RESTful的HTTP服务客户端.Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务. 什么是 ...

  4. Spring Cloud微服务之Feign——声明式服务间调用

    目录 写在前面 服务间调用常见的方案 方案一:HttpClient 方案二:RestTemplate 方案三:Feign 框架版本问题及可能遇到的坑 搭建服务注册中心 搭建服务1--service-a ...

  5. springcloud(七)-Feign声明式REST调用

    前言 前面我们使用的RestTemplate实现REST API调用,代码大致如下: public User findById(@PathVariable Long id) {return restT ...

  6. Spring Cloud Feign 1(声明式服务调用Feign 简介)

    Spring Cloud Feign基于Netflix Feign 同时整合了Spring Cloud Ribbon和Spring Cloud Hytrix,除了提供两者的强大功能外,它还提供了一种声 ...

  7. 04.声明式服务调用:Spring Cloud Feign(Greenwich.SR2)

    1.Feign是什么 Feign是整合了Ribbon与Hystrix外,还提供了声明式的Web服务客户端定义方式.采用了声明式API接口的风格,将Java Http客户端绑定到它的内部.Feign的首 ...

  8. feign和ajax,SpringCloud-feign 声明式服务调用

    以前学习java,一般就一个后端,都要学习如何在容器中运行,如tomcat,weblogic,现在微服务颠覆了这一切,一个系统要被拆分成多个服务,服务与服务间需要通信,让我想到了前端的ajax,jav ...

  9. 声明式服务调用feign原理图解

    https://www.cnblogs.com/crazymakercircle/p/11965726.html

最新文章

  1. oracle查看联机日志,oracle联机日志和归档日志
  2. 软件测试人员需要了解关于自动化的什么(译)
  3. 浮点数和整数的区别python_Python中整数和浮点数
  4. android 中 Proguard 和JNI 相关
  5. parallels desktop网络初始化失败_秘籍在手,训练不愁!特斯拉AI负责人Karpathy的超全神经网络训练套路...
  6. 19.Silverlight调用webservice上传多个文件
  7. 递归调用方法时栈内存是如何变化的?(使用内存图演示递归调用过程)
  8. 故障公告:IIS应用程序池停止工作造成博客站点无法访问
  9. Newtonsoft.Json 获取匿名类数据
  10. Linux中环境变量文件及配置
  11. Linux网络服务-Web Service之【apache的功能、安装、配置文件介绍以及实验实例】(三)...
  12. 第三章 比特币的实现机制
  13. Python collection模块与深浅拷贝
  14. android播放器录制视频,Android播放器的录制实践
  15. 如何为自己的在线办公软件 ONLYOFFICE Docs 服务器的字体库添加字体
  16. 中国顶级黑客Top10,最后一位你猜是谁
  17. 微信小程序使用 ocr 身份证识别
  18. DDOS硬件防火墙DIY技术揭密
  19. Excel技能培训之六-定位功能,隔行插入删除空行,分组插入空行,高亮行列间差异,复制筛选后的数据
  20. 数据结构算法Day01

热门文章

  1. 一句话评论设计模式六大原则--转
  2. Oracle11gExp导出空表方法
  3. 《认清C++语言》---谈谈const
  4. 有一段时间没来这里了,
  5. html5新增属性有哪些,HTML5 新增属性
  6. jsp页面间的传值方法
  7. hadoop java操作hdfs
  8. 如何利用抽象工厂更换数据库
  9. Jmeter之线程组详解
  10. OpenBSD 6.0 将移除 Linux 子系统以改进安全