zoukankan      html  css  js  c++  java
  • 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/liuys635/p/10551253.html
      2. https://www.cnblogs.com/lenve/p/7985943.html
  • 相关阅读:
    Java三大主流框架概述
    ASP.NET的内置对象
    9月29
    第一章
    在java开发中,为什么要使用单例模式。。?
    《设计模式之禅》一书学习心得(连载中)
    网上的一些java算法题的个人练习笔记
    第四次作业
    看《构建之法》有感
    实验四
  • 原文地址:https://www.cnblogs.com/WUXIAOCHANG/p/10932714.html
Copyright © 2011-2022 走看看