spring cloud 入门系列五:使用Feign 实现声明式服务调用

一、SpringCloudFeign概念引入通过前面的随笔,我们了解如何通过SpringCloudribbon进行负责均衡,如何通过SpringCloudHystrix进行服务断路保护,两

大家好,又见面了,我是全栈君。

一、Spring Cloud Feign概念引入
通过前面的随笔,我们了解如何通过Spring Cloud ribbon进行负责均衡,如何通过Spring Cloud Hystrix进行服务断路保护,
两者作为基础工具类框架应用在各种基础设施类微服务和业务类微服务中,并且成对存在,那么有没有更高层的封装,将两者的使用
进一步简化呢? 有! 他就是Spring Cloud Feign。它基于Netflix Feign实现,整合了Spring Cloud Ribbon和Spring Cloud Hystrix,
除了提供两者强大的功能外,还提供了一种声明式的Web服务客户端定义方式。

二、入门实例
我们还是继续使用前面随笔中的hello-service服务,这里通过Spring Cloud Feign提供的声明式服务绑定功能来实现对服务接口的调用。
我们需要新建一个feign-consumer来代替之前的hello-consumer

先给出代码结构:

  spring cloud 入门系列五:使用Feign 实现声明式服务调用

代码实现:

  1. 新建maven工程(feign-consumer)
  2. 修改pom文件,引入eureka和feign依赖
    <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.sam</groupId> <artifactId>feign-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <properties> <javaVersion>1.8</javaVersion> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR6</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- 引入eureka 客户端依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!-- 引入feign 依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> </dependencies> </project>

  3. 新建启动类
    /** * 通过@EnableFeignClients来开启spring cloud feign的支持功能 * */ @EnableFeignClients @EnableDiscoveryClient @SpringBootApplication public class FeiApp { public static void main(String[] args) { SpringApplication.run(FeiApp.class, args); } }

  4. 新建service接口
    /** * 通过@FeignClient注解指定服务名来绑定服务,这里的服务名字不区分大小写 * 然后再通过@RequestMapping来绑定服务下的rest接口 * */ @FeignClient(name="hello-service") public interface FeignConsumerService{ @RequestMapping("/hello") public void hello(); }

  5. 新建controller
    @RestController public class FeiConsumerController { @Autowired FeignConsumerService consumerService; @RequestMapping("feign-consumer") public String feignConsumer() { consumerService.hello(); return "feign consumer call finished!!!"; } }

  6. 新建application.properties
    server.port=9001 spring.application.name=feign-consumer eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka

  7. 测试,
    1. 启动服务注册中心eureka、启动两个hello-service(端口号分别为9090和9091),启动feign-consumerspring cloud 入门系列五:使用Feign 实现声明式服务调用

       

    2. 访问http://localhost:9001/feign-consumer

       

      spring cloud 入门系列五:使用Feign 实现声明式服务调用

      并且多次访问的话,会轮询调用两个hello-service服务。

 

三、参数绑定
在上面的例子中,我们实现的只是一个不带参数的rest服务绑定,然而现实的业务中不会这么简单,往往会有各种参数,
这个时候我们做如下事情:

  1. 如果服务提供方有对象参数(如User对象),那么feign-consumer工程中需要建一个路径和类名完全一样的类。
  2. 然后将服务提供方controller里面的所有方法声明进行copy(包括前面的@RequestMapping),粘贴到feign-consumer的service接口里面。

四、继承特性
根据上面参数绑定的做法,我们需要进行很多copy操作,这样比较麻烦,可以通过继承的方式进行简化。

这种实现步骤如下:

1.我们需要新建一个基础工程hello-service-api,

  代码结构:

  spring cloud 入门系列五:使用Feign 实现声明式服务调用

  代码实现:

  1. )新建maven项目hello-service-api
  2. )修改pom文件
    <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.sam</groupId> <artifactId>hello-service-api</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <properties> <javaVersion>1.8</javaVersion> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>

    你会发现其实就是一个普通的spring boot项目。

  3. )考虑到需要掩饰参数中有对象的情况,我们加个User类
    package com.sam.entity; public class User { private String name; private Integer age; public User(String name, Integer age) { super(); this.name = name; this.age = age; } public User() { super(); } 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; } }

    User必须要有一个无参数的构造器。

  4. )新建service接口
    /** * 为了同前面那个hello 接口区分开了,我们加了refactor前缀 * */ @RequestMapping("/refactor") public interface HelloService { @RequestMapping("/hello2") public String hello2(); @RequestMapping("/hello3") public User printUser(@RequestBody User user); }

2.重构hello-sevice服务

  1. )修改pom文件
    <!-- 引入 hello-service-api的依赖,以继承其提供的接口 --> <dependency> <groupId>com.sam</groupId> <artifactId>hello-service-api</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>

  2. )HelloController implements HelloService,并实现interface中的接口
    @RestController public class HelloController implements HelloService{ Logger logger = LoggerFactory.getLogger(HelloController.class); @Autowired DiscoveryClient discoveryClient; @RequestMapping("/hello") public String hello() throws Exception { ServiceInstance instance = discoveryClient.getLocalServiceInstance(); //打印服务的服务id logger.info("*********" + instance.getServiceId()); return "hello,this is hello-service"; } @Override public String hello2() { return "hello,this is hello2-service"; } @Override public User printUser(@RequestBody User user) { return user; }  }

    controller实现接口的方法时,不需要@RequestMapping注解,只需要类注解@RestController即可。

3.重构feign-consumer服务

  1. )修改POM文件
    <!-- 引入 hello-service-api的依赖,以继承其提供的接口 --> <dependency> <groupId>com.sam</groupId> <artifactId>hello-service-api</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>

  2. )让FeignConsumerService extends hello-service-api中的HelloService
    /** * 通过@FeignClient注解指定服务名来绑定服务,这里的服务名字不区分大小写 * 然后再通过@RequestMapping来绑定服务下的rest接口 * */ @FeignClient(name="hello-service") public interface FeignConsumerService extends HelloService{ @RequestMapping("/hello") public void hello(); }

    只需要继承即可。

  3. )修改controller,追加方法
    @RestController public class FeiConsumerController { @Autowired FeignConsumerService consumerService; @RequestMapping("feign-consumer") public String feignConsumer() { consumerService.hello(); return "feign consumer call finished!!!"; }  @RequestMapping("feign-consumer-user") public User feignConsumer2(User user) { consumerService.hello2(); return consumerService.printUser(user); } }

     

4.测试

spring cloud 入门系列五:使用Feign 实现声明式服务调用

 

五、其他
由于Spring Cloud Feign是通过ribbon和hystrix实现具体功能的,因此可以直接通过配置这两个来实现功能
1.ribbon配置方式:
  通过ribbon.<key>=<value>的方式进行全局配置,比如
    ribbon.ConnectTimeout=500
    ribbon.ReadTimeout=5000
  通过<client>.ribbon.<key>=<value>的方式进行指定服务配置,比如
    #这里的<client>为@FeignClient(value=”hello-service”)指定的服务名
    hello-service.ribbon.ConnectTimeout=500
    hello-service.ribbon.ReadTimeout=500
2.hystrix配置方式:
  通过hystrix.command.default.xxx进行全局配置
    如:hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
  通过hystrix.command.<commandKey>.xxx进行指定配置,这里的<commandKey>可以为方法名
    如:hystrix.command.hello.execution.isolation.thread.timeoutInMilliseconds=5000
3.请求压缩配置,支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。
  feign.compression.request.enabled=true;

  feigan.compression.response.enabled=true;

4.日志配置
  Spring Cloud Feign在构建被@FeignClient注解修饰的服务客户端是,会为每一个客户端都创建一个feign.Logger实例,我们可以利用该日志对象进行Log分析。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/120906.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 用户表的设计_角色和权限管理数据表设计

    用户表的设计_角色和权限管理数据表设计基于角色的访问控制:(javaWeb编程口诀)用户表角色表,用户角色中间表。角色表权限表,角色权限中间表。一个用户可有多个角色,一个角色又可有多个权限。这就是用户-角色-权限授权的模型。为何不直接让用户对应权限?角色=一定数量的权限集合将特定用户的权限封装到一个角色。封装,或者面向对象设计的体现。不足:此时,在用户之上加一个userGroup用户组的概念。可给单个用户授权或特定用户组授权。这样,一次授权,多个用户得到相同权限,此时用户所拥有的权限是用户个人权限+用户所在组权限用户组,用户与角色三者的关系

  • dump文件分析工具有哪些_java分析dump文件

    dump文件分析工具有哪些_java分析dump文件与具有众多的内存转储机制一样,Linux下也有众多的内存转储分析工具,下面将会逐一做简单介绍。Lcrash是随LKCD一起发布的一个内内存储分析工具。随着LKCD开发的停止,lcrash的开发也同时停止了。目前它的代码已经被合并进入Crash工具中。Alicia(AdvancedLinuxCrash-dumpInteractiveAnalyzer,高级Linux崩溃…

  • handlersocket mysql,MySQL插件HandlerSocket

    handlersocket mysql,MySQL插件HandlerSocketHandlerSocket是MySQL的一个插件,用来实现NoSQL功能,用于跳过MySQL的SQL层面,直接访问内部的InnoDB存储引擎。wgethttp://dev.mysql.com/get/Downloads/MySQL-5.5/MySQL-client-5.5.11-1.rhel4.i386.rpmwgethttp://dev.mysql.com/get/Downloads/…

  • javascript 类数组概念详解

    javascript 类数组概念详解

  • rcnn算法详解_rcnn目标检测

    rcnn算法详解_rcnn目标检测这是一篇比较早的ObjectDetection算法,发表在2014年的CVPR,也是R-CNN系列算法的开山之作,网上可以搜到很多相关的博客讲解,本篇博文没有按论文顺序来讲述,而是结合自己经验来看这个算法,希望给初学者一个直观的感受,细节方面不需要太纠结,因为很多部分在后来的算法中都改进了。论文:Richfeaturehierarchiesforaccurateobjectdetect

  • word公式编号及交叉引用技巧[通俗易懂]

    word公式编号及交叉引用技巧[通俗易懂]在给word内公式编号时,经常会遇到各种问题,本文记录我应用word时给公式编号及交叉引用的技巧。

    2022年10月23日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号