Feign详细使用-Spring Cloud学习第四天(非原创)

文章大纲

一、Feign是什么
二、Feign的基本实现
三、Feign的继承特性
四、Feign配置详解
五、项目源码与参考资料下载
六、参考文章

一、Feign是什么

前面几篇文章我们详细的介绍了Ribbon、RestTemplate、Hystrix组件,这些组件是我们Spring Cloud中非常基础的组件,小伙伴们在使用的过程中可能也发现了这些东西都是同时出现的,而且配置也都非常相似,每次开发都有很多相同的代码,因此,Spring Cloud基于Netflix Feign整合了Ribbon和Hystrix,让我们的开发工作变得更加简单,就像Spring Boot是对Spring+SpringMVC的简化一样。Spring Cloud Feign不仅在配置上大大简化了开发工作,同时还提供了一种声明式的Web服务客户端定义方式。

二、Feign的基本实现

1. 创建基本的Spring Boot项目

创建后项目结构如下:

2. pom.xml文件添加依赖

这里要添加的依赖主要是spring-cloud-starter-eureka和spring-cloud-starter-feign,如下:

<?xml version="1.0" encoding="UTF-8"?>
<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.wxc</groupId>
    <artifactId>feign-consumer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <spring-cloud.version>Dalston.SR3</spring-cloud.version>
    </properties>
    <dependencies>
        <!-- 其他依赖 -->
        <!-- 自己添加的依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

3. 添加业务逻辑

3.1 创建服务类
com.wxc.test包下新建HelloService.java,定义一个HelloService接口,通过@FeignClient注解来指定服务名进而绑定服务,然后再通过SpringMVC中提供的注解来绑定服务提供者提供的接口,这相当于绑定了一个名叫hello-service(这里hello-service大小写无所谓)的服务提供者提供的/hello接口。我们来看一下我服务提供者提供的接口,如下:

package com.wxc.test.service;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient("hello-service")
public interface HelloService {
    @RequestMapping("/hello")
    String hello();
}

3.2 创建controller类
com.wxc.controller新建FeignConsumerController.java

package com.wxc.test.controller;

import com.wxc.test.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FeignConsumerController {
    @Autowired
    HelloService helloService;

    @RequestMapping(value = "/hello",method = RequestMethod.GET)
    public String hello() {
        return helloService.hello();
    }

    //测试参数传递
    @RequestMapping(value = "/hello1", method = RequestMethod.GET)
    public String hello1(@RequestParam String name) {
        return "hello " + name + "!";
    }
}

4. 配置静态资源

application.properties文件中添加以下内容:

spring.application.name=feign-consumer
server.port=2005
eureka.client.service-url.defaultZone=http://peer1:1111/eureka,http://peer2:1112/eureka

5. 创建项目启动类

com.wxc.test包下创建FeignConsumerApplication.java

package com.wxc.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class FeignConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(FeignConsumerApplication.class, args);
    }
}

6. 项目启动与访问

访问前,确保注册中心和服务提供者都正常启动,访问http://localhost:2005/hello1?name=吴先生

访问http://localhost:2005/hello

三、Feign的继承特性

参考文章:https://mp.weixin.qq.com/s/6ApgudWoUzAhg6BEcRmSBw
温馨提示
服务提供者和服务消费者的耦合度太高,此时如果服务提供者修改了一个接口的定义,服务消费者可能也得跟着变化,进而带来很多未知的工作量,因此小伙伴们在使用继承特性的时候,要慎重考虑。

四、Feign配置详解

1. 简介

到目前为止,小伙伴们对Feign的使用已经掌握的差不多了,我们在前文也提到Feign是对Ribbon和Hystrix的整合,那么在Feign中,我们要如何配置Ribbon和Hystrix呢?带着这两个问题,我们来看看本文的内容。

2. 资源文件添加配置

2.1 Ribbon配置
ribbon的配置其实非常简单,直接在application.properties中配置即可,如下:

# 设置连接超时时间
ribbon.ConnectTimeout=600
# 设置读取超时时间
ribbon.ReadTimeout=6000
# 对所有操作请求都进行重试
ribbon.OkToRetryOnAllOperations=true
# 切换实例的重试次数
ribbon.MaxAutoRetriesNextServer=2
# 对当前实例的重试次数
ribbon.MaxAutoRetries=1

这个参数的测试方式很简单,我们可以在服务提供者的hello方法中睡眠5s,然后调节这个参数就能看到效果。下面的参数是我们配置的超时重试参数,超时之后,首先会继续尝试访问当前实例1次,如果还是失败,则会切换实例访问,切换实例一共可以切换两次,两次之后如果还是没有拿到访问结果,则会报Read timed out executing GET http://hello-service/hello
但是这种配置是一种全局配置,就是是对所有的请求生效的,如果我想针对不同的服务配置不同的连接超时和读取超时,那么我们可以在属性的前面加上服务的名字,如下:

# 设置针对hello-service服务的连接超时时间
hello-service.ribbon.ConnectTimeout=600
# 设置针对hello-service服务的读取超时时间
hello-service.ribbon.ReadTimeout=6000
# 设置针对hello-service服务所有操作请求都进行重试
hello-service.ribbon.OkToRetryOnAllOperations=true
# 设置针对hello-service服务切换实例的重试次数
hello-service.ribbon.MaxAutoRetriesNextServer=2
# 设置针对hello-service服务的当前实例的重试次数
hello-service.ribbon.MaxAutoRetries=1

2.2 Hystrix配置
Feign中Hystrix的配置和Ribbon有点像,基础配置如下:

# 设置熔断超时时间
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
# 关闭Hystrix功能(不要和上面的配置一起使用)
feign.hystrix.enabled=false
# 关闭熔断功能
hystrix.command.default.execution.timeout.enabled=false

这种配置也是全局配置,如果我们想针对某一个接口配置,比如/hello接口,那么可以按照下面这种写法,如下:

# 设置熔断超时时间
hystrix.command.hello.execution.isolation.thread.timeoutInMilliseconds=10000
# 关闭熔断功能
hystrix.command.hello.execution.timeout.enabled=false

2.3 其他配置
Spring Cloud Feign支持对请求和响应进行GZIP压缩,以提高通信效率,配置方式如下:

# 配置请求GZIP压缩
feign.compression.request.enabled=true
# 配置响应GZIP压缩
feign.compression.response.enabled=true
# 配置压缩支持的MIME TYPE
feign.compression.request.mime-types=text/xml,application/xml,application/json
# 配置压缩数据大小的下限
feign.compression.request.min-request-size=2048

Feign为每一个FeignClient都提供了一个feign.Logger实例,我们可以在配置中开启日志,开启方式很简单,分两步:
第一步:application.properties中配置日志输出
application.properties中配置如下内容,表示设置日志输出级别:

# 开启日志 格式为logging.level.+Feign客户端路径
logging.level.org.sang.HelloService=debu

第二步:入口类中配置日志Bean
入口类中配置日志Bean,如下:

@Bean
Logger.Level feignLoggerLevel() {
    return Logger.Level.FULL;
}

OK,如此之后,控制台就会输出请求的详细日志。

3. 编写业务逻辑

我们之前还有一篇文章专门讲Hystrix服务降级的问题,那么在Feign中如何配置Hystrix的服务降级呢?我们先建立一个接口HelloService2.java

package com.wxc.test.service;

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


@FeignClient(value = "hello-service",fallback = HelloServiceFallback.class)
public interface HelloService2 {
    @RequestMapping("/hello")
    String hello();

    @RequestMapping(value = "/hello1", method = RequestMethod.GET)
    String hello(@RequestParam("name") String name);
}

创建其实现类HelloServiceFallback.java

package com.wxc.test.service;

import org.springframework.stereotype.Component;


@Component
public class HelloServiceFallback implements HelloService2 {
    @Override
    public String hello() {
        return "hello error";
    }

    @Override
    public String hello(String name) {
        return "error " + name;
    }
}

修改FeignConsumerController.java内容如下:

package com.wxc.test.controller;

import com.wxc.test.service.HelloService;
import com.wxc.test.service.HelloService2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FeignConsumerController {
//    @Autowired
//    HelloService helloService;

    @Autowired
    HelloService2 helloService;

    @RequestMapping(value = "/hello",method = RequestMethod.GET)
    public String hello() {
        return helloService.hello();
    }

    //测试参数传递
    @RequestMapping(value = "/hello1", method = RequestMethod.GET)
    public String hello1(@RequestParam String name) {
        return "hello " + name + "!";
    }
}

4. 项目运行与访问

我们只打开服务注册中心,并运行feign-consumer

在浏览器输入http://localhost:2005/hello进行访问

可以看到已经熔断成功

五、项目源码与参考资料下载

链接:https://pan.baidu.com/s/1pk38lvq0fe4RHcP-REQECQ
提取码:huud

六、参考文章

  1. https://www.cnblogs.com/lenve/p/7985943.html
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容