前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >服务之间的调用(OpenFeign)-原来如此简单

服务之间的调用(OpenFeign)-原来如此简单

作者头像
IT学习日记
发布2022-09-13 16:01:45
1.1K0
发布2022-09-13 16:01:45
举报
文章被收录于专栏:IT知识进阶学习

一:初见

  定义: OpenFeign是一个声明式的Web服务客户端、让编写Web服务客户端变得更加容易只需要创建一个接口然后添加上注解即可,同时,它集成了Ribbon,可以轻松实现负载均衡的效果。

二:疑惑

疑问一:为什么有了Ribbon和RestTemplate还要使用OpenFeign?

  1、首先、Feign的目的是为了更简单的编写Http客户端,在平常的开发中,一个服务可能被多处进行调用,所以可以将被调用的微服务封装成一些客户端来包装这些依赖的服务调用。

  2、Feign在此基础上做了封装,通过接口+注解完成对服务提供方的绑定,简化了调用服务的开发量。同时、Feign集成了Ribbon,可以更加简单的实现服务的调用。

疑问二:Feign和OpenFeign有什么区别

  注:官方已经宣布停止更新Feign组件了,所以我们可以使用OpenFeign进行代替,此处列举的区别只是做一下普及

Feign和OpenFeign有什么区别
Feign和OpenFeign有什么区别

Feign本身不支持Spring MVC的注解,它有一套自己的注解,调用方式如下:

Feign的使用
Feign的使用

三:使用OpenFeign

   (一) 使用方式:接口+注解 --> 完成对服务提供方的服务绑定,即可实现调用服务提供方的服务就像调用自己服务的API一样

   (二) 服务提供方(服务名为:CLOUD-PAYMENT-SERVICE):

注册中心
注册中心
代码语言:javascript
复制
package com.elvis.springcloud.controller;

import com.elvis.springcloud.model.CommonResult;
import com.elvis.springcloud.model.Payment;
import com.elvis.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

@RestController
@Slf4j
public class PaymentController {
    @Autowired
    private PaymentService paymentService;
    @Value("${server.port}")
    private String port;
    // 用于测试返回当前服务提供者的端口号
    @RequestMapping("/payment/test/ribbon")
    public String testCustomer(){
        return port;
    }
    // 用于模拟openFeign请求超时的API
    @RequestMapping("/payment/test/ribbon/timeout")
    public String testCustomerTimeout(){
        try{
            Thread.sleep(3000);
        }catch (Exception e){
            log.info(e.getLocalizedMessage());
        }
        return port;
    }
}

  (三) 服务消费方

1、openFeign接口,用于绑定服务提供方

代码语言:javascript
复制
package com.elvis.springcloud.feign;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
//FeignClient表示这是使用OpenFeigin调用服务的客户端,
// value属性的值是: 提供服务的消费方的服务名称,必须指定,否则无法找到对应的服务
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface OrderFeign {
    @RequestMapping("/payment/test/ribbon")
    public String testCustomer();

    @RequestMapping("/payment/test/ribbon/timeout")
    public String testCustomerTimeout();
}

  2、客户端访问消费者

代码语言:javascript
复制
package com.elvis.springcloud.controller;

import com.elvis.springcloud.feign.OrderFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class FeignOrderController {

    @Autowired
    private OrderFeign orderFeign;

    @RequestMapping("/consumer/payment/test/ribbon")
    public String testCustomer(){
        String s = orderFeign.testCustomer();
        log.info("本次提供服务的服务端端口号为:"+s);
        return s;
    }

    @RequestMapping("/payment/test/ribbon/timeout")
    public String testCustomerTimeout(){
        return orderFeign.testCustomerTimeout();
    }
}

  3、项目配置类

代码语言:javascript
复制
package com.elvis.springcloud.config;

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

@Configuration
public class FeignConfig {
    // Feign调用的日志输出级别
    @Bean
    Logger.Level  getLogger(){
        return Logger.Level.FULL;
    }
    // 随机调用服务的负载均衡算法
    @Bean
    IRule getIRule(){
        return new RandomRule();
    }
}

  4、项目配置文件

代码语言:javascript
复制
server:
  port: 8010
# 注册到eureka服务
eureka:
  client:
    register-with-eureka: true
    fetch-registy: true # 是否获取注册到eureka的服务信息
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

  5、项目主启动类

代码语言:javascript
复制
package com.elvis.springcloud;

import com.elvis.springcloud.config.IRuleConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
// 激活openFeign既可以通过Feign进行服务调用
@EnableFeignClients
// value值表示: 本次负载均衡算法作用到的服务名称
// configuration属性值表示: 自定义的算法类的Class对象
//(如果我们不使用RibbonClient注解,openFeign会默认使用Ribbon的轮询算法)
@RibbonClient(value = "CLOUD-PAYMENT-SERVICE",configuration = IRuleConfig.class)
public class ConsumerFeignOrder80 {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerFeignOrder80.class,args);
    }
}

  2、实现效果图

实现效果图
实现效果图

四: OpenFeign超时限制

  (一) 注: OpenFeign的默认请求服务的时间1秒,如果一秒内不能请求到结果则会返回请求超时的错误

OpenFeign请求超时
OpenFeign请求超时

  (二) 解决方式: 在application.yml中配置请求超时的时间限定,重启服务即可(这里推荐使用热部署插件,这样不用每次修改后都重启服务,后面会专门开一片文章进行讲解热部署插件---事半功倍哦)

代码语言:javascript
复制
ribbon:
  ReadTimeout: 5000 # 表示与服务提供放进行链接时的最大时间(毫秒)
  ConnectionTimeout: 5000 # 表示获取服务提供放资源的的最大时间(毫秒)

五: OpenFeign日志控制级别

  (一) 日志: 实际上是对请求的监控和输出,我们可以通过配置来设置日志的级别,从而打印出我们需要的日志,OpenFeign的日志级别设置如下:

代码语言:javascript
复制
  1、添加日志配置类
代码语言:javascript
复制
    // Feign调用的日志输出级别
    @Bean
    Logger.Level  getLogger(){
        // 有以下的配置类型
        return Logger.Level.FULL;
    }
在这里插入图片描述
在这里插入图片描述

2、在配置文件中设置监听指定路径下的文件日志

代码语言:javascript
复制
logging:
  level:
    com.elvis.springcloud.feign.OrderFeign: debug #日志监听的位置

  3、实现效果

日志级别输出
日志级别输出

六:小结

  通过上面的案例,发现OpenFeign的优点很多,且使用更加方便,本质就是通过: 接口 + 注解实现对服务提供者的绑定,从而轻松实现服务之间的调用,纸上得来终觉浅,绝知此事要躬行,希望你不单单只是看完文章,而是亲自进行动手,很多东西只有自己动手了才会发现其实没有想象中那么难。

  非常感谢你阅读本文,如果有什么疑问或者建议,欢迎在文章下方留言或者私信我

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022/06/15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一:初见
  • 二:疑惑
  • 三:使用OpenFeign
  • 四: OpenFeign超时限制
  • 五: OpenFeign日志控制级别
  • 六:小结
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档