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

先给出代码结构:

  

代码实现:

  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-consumer
    2. 访问http://localhost:9001/feign-consumer

      

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

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

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

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

这种实现步骤如下:

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

  代码结构:

  

  代码实现:

  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是通过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分析。

spring cloud 入门系列五:使用Feign 实现声明式服务调用的更多相关文章

  1. SpringCloud系列-利用Feign实现声明式服务调用

    上一篇文章<手把手带你利用Ribbon实现客户端的负载均衡>介绍了消费者通过Ribbon调用服务实现负载均衡的过程,里面所需要的参数需要在请求的URL中进行拼接,但是参数太多会导致拼接字符 ...

  2. SpringCloud学习笔记(3):使用Feign实现声明式服务调用

    简介 Feign是一个声明式的Web Service客户端,它简化了Web服务客户端的编写操作,相对于Ribbon+RestTemplate的方式,开发者只需通过简单的接口和注解来调用HTTP API ...

  3. springCould:使用Feign 实现声明式服务调用

    一.Spring Cloud Feign概念引入通过前面的随笔,我们了解如何通过Spring Cloud ribbon进行负责均衡,如何通过Spring Cloud Hystrix进行服务断路保护,两 ...

  4. SpringCloud(四):使用Feign实现声明式服务调用

    一.Feign介绍Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单.使用Feign,只需要创建一个接口并注解.它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解 ...

  5. spring cloud 入门系列:总结

    从我第一次接触Spring Cloud到现在已经有3个多月了,当时是在博客园里面注册了账号,并且看到很多文章都在谈论微服务,因此我就去了解了下,最终决定开始学习Spring Cloud.我在一款阅读A ...

  6. Spring Cloud Feign声明式服务调用(转载)+遇到的问题

    转载:原文 总结: 1.pom添加依赖 2.application中填写正确的eureka配置 3.启动项中增加注解 @EnableFeignClients 4.填写正确的调用接口 通过原文使用Fei ...

  7. spring cloud 入门系列四:使用Hystrix 实现断路器进行服务容错保护

    在微服务中,我们将系统拆分为很多个服务单元,各单元之间通过服务注册和订阅消费的方式进行相互依赖.但是如果有一些服务出现问题了会怎么样? 比如说有三个服务(ABC),A调用B,B调用C.由于网络延迟或C ...

  8. spring cloud 系列第4篇 —— feign 声明式服务调用 (F版本)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.feign 简介 在上一个用例中,我们使用ribbon+restTem ...

  9. Spring Cloud Feign 声明式服务调用

    目录 一.Feign是什么? 二.Feign的快速搭建 三.Feign的几种姿态 参数绑定 继承特性 四.其他配置 Ribbon 配置 Hystrix 配置 一.Feign是什么? ​ 通过对前面Sp ...

随机推荐

  1. findbugs, checkstyle, pmd的myeclipse7.5+插件安装(转:http://blog.csdn.net/priestmoon/article/details/63941)

    CheckStyle (1)下载net.sf.eclipsecs_5.3.0.201012121300-updatesite-.zip (2)打开MyEclipse,Help->Software ...

  2. 深度剖析malloc、free和new、delete

    1.malloc,free是C语言的函数,而new,delete是操作符,属于C++的语法,一定注意这两个不再是函数了,而是操作符. 2.malloc和new对于分配基础类型变量和数组变量,它们除了语 ...

  3. Learn Lua in 15 Minutes

    原文地址:http://tylerneylon.com/a/learn-lua/ Learn Lua in 15 Minutes more or less For a more in-depth Lu ...

  4. Linux C 下的大文件操作

    这里说的大文件指大小超过4G的文件. 在32位环境下,linux默认打开.读.写超过4G的文件会返回错误.定义如下宏可以突破这个限制,对read/write和fread/fwrite同时有效. 注意它 ...

  5. java的map

    Map是一种把键对象和值对象进行关联的容器,而一个值对象又可以是一个Map,依次类推,这样就可形成一个多级映射. 这里有详细的论述http://www.oracle.com/technetwork/c ...

  6. java中,用json格式转换遇到问题

    将list转为JSONObject类,报 org/apache/commons/lang/exception/NestableRuntimeException是什么原因? 还需要导入这些包common ...

  7. iOS开发 支付之银联支付集成

    iOS开发之银联支付集成 最近在做支付这一块的东西,就记录下来以便以后参考和各位交流学习,这里是银联支付 银联官网在这里,这里能下载SDK或者是看文档.文档嘛,对银联来说,还是不要看的太仔细的好,以前 ...

  8. 【Coding算法导论】第4章:最大子数组问题

    Coding算法导论 本系列文章主要针对算法导论一书上的算法,将书中的伪代码用C++实现 代码未经过大量数据测试,如有问题,希望能在回复中指出! (一)问题描述 给定一个数组,求数组中连续的子数组的和 ...

  9. Android LruCache技术原理

    概述 记得在很早之前,我有写过一篇文章Android高效加载大图.多图解决方案,有效避免程序OOM,这篇文章是翻译自Android Doc的,其中防止多图OOM的核心解决思路就是使用LruCache技 ...

  10. Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...