SpringCloud 入门(四) Feign声明式服务调用

1基础

1.1Feign概述

●Feign是一 个声明式的REST客户端,它用了基于接口的注解方式,很方便实现客户端配置。

●Feign最初由Netlix公司提供,但不支持SpringMVC注解,后由SpringCloud对其封装,支持了SpringMVC注解,让使用者更易于接受。

 

1.2Feign快速入门

demo  目录结构

1.2.1.在消费端(consumer)引入open-feign依赖

consumer的pom添加依赖

  <!--        添加Feign 引用 start   由于netflix 版本不支持 springmvc ;所以要使用open版本-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--        添加Feign 引用  end-->

1.2.1补充【open-feign】完整引用

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

1.2.2.编写Feign调用接口(使用服务名作为调用依据)

/**
 * 1.定义接口!
 * 2.接口上添加注解@FeignClient,设置value属性为服务提供者的应用名称
 * 3.编写调用接口,接口的声明规则和提供方接口保持一致。
 * 4.注入该接口对象,调用接口方法完成远程调用
 * backend-show-provider 是provider的名称
 */
@FeignClient(value = "backend-show-provider")
public interface ConsumerApp {
    /**
     * provider Controller名称;sayhello 请求的方法名
     *
     * @param message
     * @return
     */
    @GetMapping("/provider/sayhello2")
    String providerSayHello2(@RequestParam("message")String message);
}

1.2.3.在启动类添加@EnableFeignClients注解,开启Feign功能

consumer的application.java中添加

@SpringBootApplication
@EnableFeignClients //开启Feign的功能
public class BackendShowConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(BackendShowConsumerApplication.class,args);
    }
}

1.2.4.测试调用

consumer服务中

   @Resource
    private ConsumerApp consumerApp;
    @GetMapping(value = "/sayhello2")
    public String sayhello2(String message){

        String result = null;
        try {
            result = consumerApp.providerSayHello2(message);
        } catch (Exception exception) {
            exception.printStackTrace();
        }

        return result;
    }

provider服务代码

    @GetMapping("/sayhello2")
    public String providerSayHello2(String message,String username)   {
        System.out.println("username:"+username);
//        int a=1/0;//错误
        try {
            Thread.sleep(2000);//超时设置
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.error("provder sayhello port:{}, message:{}", port, message);

        return "Provider sayhello port:" + port + " , message:" + message;
    }

 

1.2.5.特别注意

编写Feign调用接口时候,注意方法的参数必须  @RequestParam  (例如:@RequestParam("message")String message)  否则 【status 405 reading】

1.2.6 openFeign另一种写法(使用端口号)

不推荐使用这种,在实际发布情况中,可能存在端口被暂用。需要改端口的情况

/**
 * name  名称,可以自己随意取;url 对应的服务请求地址
  */    
@FeignClient(name="providerTest",url = "http://localhost:7010")
public interface ConsumerApp {
    /**
     * provider Controller名称;sayhello 请求的方法名
     *
     * @param message
     * @return
     */
    @GetMapping("/provider/sayhello2")
    String providerSayHello2(@RequestParam("message")String message);
}

2Feign超时设置

  • Feign底层依赖于Ribbon实现负载均衡和远程调用。
  • Feign就是对Ribbon进行一次封装,Ribbon有的Feign也有。
  • 一般给Feign设置超时时间就是设置Ribbon的
  • Ribbon默认1秒超时。
  • Feign超时设置都是在调用放(consumer)设置(applicaation.yml中)
ribbon:
  ConnectTimeout: 2000 # Ribbon的连接超时时间
  ReadTimeout: 3000 # Ribbon的数据读取超时时间
  OkToRetryOnAllOperations: true # 是否对所有操作都进行重试
  MaxAutoRetriesNextServer: 1 # 切换实例的重试次数
  MaxAutoRetries: 1 # 对当前实例的重试次数

 

3Feign日志打印

  1. Feign只能记录debug级别的日志信息。所以需要在application.yml中设置日志的级别
logging:
  level:
    com.item.backed: debug  #com.item.backed为包名,也可具体指定哪个class

  1. 定义Feign日志级别Bean  (格式固定)
package com.item.backed.consumer.config;

import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignLogConfig {

    /**
     * NONE ,不记录
     * BASIC,记录基本的请求行,响应状态码数据
     * HEADERS,记录基本的请求行,响应状态码数据,记录响应头信息
     * FULL ;记录完成的请求响应数据
     * @return
     */
    @Bean
    public Logger.Level level(){
        return Logger.Level.FULL;
    }
}

  1. 启用该Bean:
,configuration = FeignLogConfig.class

 

最后查看日志

3补充

3.1Fegin支持多种http调用形式

Feign支持多种http调用形式(这里网上说不支持@GetMapping和@POSTMapping,但是本次的demo都是用的这两个,却可以运行通。) 如果使用以上两种形式请求,报错【Request method 'POST' not supported】。可以尝试更换

3.2FeginClient相关参数详解

3.2.1path

前面demo中两种@FeignClient写法都只用到两个参数(configuration、value  或者 name和url);去请求另外一个服务的Controller 路径都写在请求的方法上面。例如:

    @GetMapping("/provider/sayhello2")
    String providerSayHello2(@RequestParam("message")String message);

现在,在@FeginClinet中添加一个参数 path就行:

import com.item.backed.consumer.config.FeignLogConfig;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(value = "backend-show-provider",path = "/provider",configuration = FeignLogConfig.class)
public interface ConsumerApp {
    /**
     * provider Controller名称;sayhello 请求的方法名
     *
     * @param message
     * @return
     */
    @GetMapping("/sayhello2")
    String providerSayHello2(@RequestParam("message")String message);

}

请求如下

3.2.2configuration 自定义Fegin配置

 

配置类型 默认配置
feignDecoder ResponseEntityDecoder
feignEncoder     SpringEncoder
feignLogger       SIf4jLogger
feignContract   SpringMvcContract
feignBuilder       HystrixFeign.Builder
feignClient         LoadBalancerFeignClient或者feignClient


 

 

3.3Feign实战技巧

Feign继承
◆微服务的目标是大量复用, Feign会导致重复工作量
◆Feign提供了继承特性帮助我们解决这个问题
接口复用最多只能有一层,切忌多继承
 

 

3.4Feign多组件集成

◆Feign可以集成Ribbon实现负载均衡
◆Feign可以集成Hystrix实现命令封装
◆Feign可以集成Hystrix实现业务降级
 

 

 

Feign之HTTP性能优化
◆Feign默认使用的JDK自带的HTTP方式
◆Feign最大的优化点是更换HTTP底层实现
◆目前Apache HTTPClient是一个非常好的选择
 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值