Spring Cloud alibaba之Feign

JAVA项目中如何实现接口调用?

  1. Httpclient
    Httpclient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持Http协议的客户端编程工具包,并且它支持HTTP协议最新版本和建议。HttpClient相比传统JDK自带的URL Connection,提升了易用性和灵活性,是客户端发送HTTP请求变得容易,提高了开发的效率。
  2. Okhttp
    一个处理网络请求的开源项目,是安卓端最火的轻量级框架,由Square公司贡献,用于代替HttpUrlConnection和Apache HttpClient。OkHttp拥有简洁的API、高校的性能,并支持多种协议(HTTP/2和SPDY)
  3. HttpURLConnection
    HttpURLConnection是Java的标准类,它继承自URLConnection,可用于向指定网站发送GET请求、POST请求。HttpURLConection使用比较复杂,不想HttpClient那样容易使用。
  4. RestTemplate WbClient
    RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程HTTP服务的方法,能够大大提高客户端的编写效率。

上面介绍的是最常见的几种调用接口的方法,我们下面介绍的方法比上面的更简单、方便,它就是Feign。

什么是Feign

Feign是Nexflix开发的声明式、模板化的HTTP客户端,其灵感来自Retrofit、JAXRS-2.0以及WebSocket。Feign可帮助我们更加便捷、优雅地调用HTTP API。
\color{#FF0000}{Spring Cloud openfeign对Feign进行了增强,使其支持Spring MVC注解,另外还整合了Ribbon和Nacos,从而使得Feign的使用更加方便。}

优势

Feign可以做到\color{#FF0000}{使用HTTP请求远程服务时就像调用本地方法一样的体验},开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。它像Dubbo一样,consumer直接调用接口方法调用provider,而不是要通过常规的HttpClient构造请求解析返回数据。它解决了让开发者调用远程接口就跟调用本地方法一样,无需关注与远程的交互细节,更无需关注分布式环境开发。(简单地说就是A服务的Service接口去调用别的B服务的Controller接口)

Spring Cloud Alibaba快速整合Opne Feign

  1. 复制order-nacos项目,修改项目名为order-openfeign,修改其它配置。引入依赖
<!--openfeign远程调用-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. 新建Feign接口
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

/*
name指定远程调用的接口所对应的服务名
path指定远程调用的接口所对应的类的@RequestMapping
 */
@FeignClient(name = "stock-service", path = "/stock")
public interface StockFeignService {
    @RequestMapping("/reduct")
    String reduct();
}
  1. 编写订单Controller
import com.mrZhao.feign.StockFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    StockFeignService stockFeignService;

    @RequestMapping("/add")
    public String add() {
        System.out.println("下单成功!");
        String reduct = stockFeignService.reduct();
        return "Hello Feign" + reduct;
    }
}
  1. 此时stockFeignService下面有一条红色的波浪线,需要在启动类中配置上开启Feign的注解
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

最终项目结构


访问订单接口


日志配置

1.新建product-nacos子项目,controller

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/product")
public class ProductController {
    @Value("${server.port}")
    String port;

    @RequestMapping("/{id}")
    public String get(@PathVariable Integer id) {
        System.out.println("查询商品" + id);
        return "查询商品" + id + ":" + port;
    }
}

application.yml

server:
  port: 8007
spring:
  application:
    name: product-nacos
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos
        namespace: public

最终长这样


  1. 在上文中创建的order-openfeign项目中新建配置类
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 赵毅梵
 * @create 2022-04-21
 */
// 此处配置Configuration注解会全局生效 如果想指定对一个的微服务生效 就不能配置
@Configuration
public class FeignConfig {
    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}
  1. 新建feign接口
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

/*
name指定远程调用的接口所对应的服务名
path指定远程调用的接口所对应的类的@RequestMapping
 */
@FeignClient(name = "product-nacos", path = "/product")
public interface ProductFeignService {
    @RequestMapping("/{id}")
    String get(@PathVariable("id") Integer id);
}
  1. 更新Controller
import com.mrZhao.feign.ProductFeignService;
import com.mrZhao.feign.StockFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    StockFeignService stockFeignService;

    @Autowired
    ProductFeignService productFeignService;

    @RequestMapping("/add")
    public String add() {
        System.out.println("下单成功!");
        String reduct = stockFeignService.reduct();
        String s = productFeignService.get(1);
        return "Hello Feign" + reduct + s;
    }
}
  1. application.yml添加配置
# springboot默认的日志级别时info feign默认的是debug 所以日志级别不输出
logging:
  level:
    com.mrZhao.feign: debug
  1. 启动订单服务、库存服务和商品服务,访问订单接口



    日志信息也打印到了控制台


契约配置

  Spring Cloud在Feign的基础上做了扩展,使用Spring MVC的疏解来完成Feign的功能。原生的Feign是不支持Spring MVC注解的,如果你想在Spring Cloud中使用原生的注解方式来定义客户端也是可以的,通过配置契约来改变这个配置,Spring Cloud中默认的是SpringMvcContract。
  Spring Cloud 1早期版本就是用的原生Feign,随着netflix的停更替换成了Open feign。

  1. 修改契约配置,支持Feign原生的注解
/**
  *  修改契约配置,支持feign原生的注解
  *  @return
  */
@Bean
public Contract feignContract() {
  return new Cotract.Default();
}

$\color{#FF0000}{注意:修改契约配置后,stock-service不再支持springmvc的注解,需要使用Feign原生的注解}

  1. OrderFeignService中配置使用Feign原生的注解
@FeignClient(name = "stock-service", path = "/stock", configuration = FeignConfig.class)
public interface StockFeignService {
    @RequestLine("GET /reduct")
    String reduct();
}
  1. 补充:也可以通过yml方式配置契约
# feign日志局部配置
feign:
  client:
    config:
      stock-service:
        loggerLevel: BASIC
        # 设置未默认的契约(还原成原生注解)
        contract: feign.Contract.Default

超时时间设置

通过 Options 可以配置连接超时时间和读取超时时间,Options 得第一个参数是连接的超时时间(ms),默认值是2s;第二个是请求处理的超时时间(ms),默认是5s。
全局配置

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

// 此处配置Configuration注解会全局生效 如果想指定对一个的微服务生效 就不能加
@Configuration
public class FeignConfig {
    @Bean
    public Request.Options options() {
        return new Request.Options(5000, 10000);
    }
}

yml中配置

# feign日志局部配置
feign:
  client:
    config:
      stock-service:
        loggerLevel: BASIC
        # 连接超时时间,默认是2s
        connectTimeout: 5000
        # 请求处理超时时间,默认是5s
        readTimeout: 3000

\color{#FF0000}{补充说明:Feign的底层用的是Ribbon,但超时时间以Feign配置为准}
测试超时情况:

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

推荐阅读更多精彩内容