feign自定义第三方接口;配置化Feign接口URL;调用指定IP的feign服务

最近接手一个项目,各子工程之间通过feign调用;各服务部署在K8S上,通过nacos管理配置;由于服务部署的机器无法开放端口等原因,导致本机服务与测试环境网络端口无法互通,故需要重写feign的调用地址;个人总结的方法有以下几种:

目录

 第一种:feignclient配置URL

第二种:实现RequestInterceptor接口;

第三种:重写feign的client的execute方法;


 第一种:feignclient配置URL

        在feignclient里写一个固定地址或者写一个可配置的地址,这样可以在配置文件里指定,这种方式在创建feign客户端的时候就需要规划好。

        1.1 固定地址

@FeignClient(name = "feignCustomerService", url = "http://localhost:8080")
public interface FeignCustomerService {/*** 请求客户的接口*/@RequestMapping(value = "order/update", method = RequestMethod.POST)@Headers(value = "Content-Type: application/json")OrderHttpResponse updateOrder(@RequestBody OrderUpdateDTO orderUpdateDTO);}

1.2 可配置的地址

@FeignClient(name = "feignCustomerService", url = "${customer.url}")
public interface FeignCustomerService {@RequestMapping(value = "test/list", method = RequestMethod.POST)@Headers(value = "Content-Type: application/json")OrderHttpResponse updateTest(@RequestBody OrderUpdateDTO orderUpdateDTO);}

配置文件配置地址

customer.url=http://localhost:8080

第二种:实现RequestInterceptor接口;

        这种方式具有局限性,在nacos上注册的服务IP与本机IP不一致的时候(连接VPN)可能依旧调不通服务,但是实现RequestInterceptor接口可以处理全局请求(header,身份认证等)

@Component
public class Oauth2TokenRequestInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate requestTemplate) {// 获取请求中的消息头ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();String requestHeader = request.getHeader(HttpHeaders.AUTHORIZATION);if (StringUtils.isNotBlank(requestHeader) && requestHeader.startsWith("Bearer ")) {// 将消息头塞入到请求模板中requestTemplate.header(HttpHeaders.AUTHORIZATION, requestHeader);}//重写URL,访问指定服务String url = target.url();String newUrl = "http://localhost:8080";template.target(newUrl );}
}

第三种:重写feign的client的execute方法;

        这种方式可以自定义负载均衡的策略,也可以自定义访问指定服务IP,这里以FeignBlockingLoadBalancerClient为例

配置类

package com.***.redirect;import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;import java.util.Map;@Getter
@Setter
@RefreshScope
@ConfigurationProperties("localbalance")
@Component
public class LocalFeignPerpreties {private Boolean enable;private Map<String,String> rule;
}

配置文件配置内容:

localbalance:enable: truerule:aiflow-sys: http://IP:8888/SERVICEaiflow-auth: http://IP:8888/SERVICE

重写FeignBlockingLoadBalancerClient 的execute方法

package com.***.redirect;import feign.Client;
import feign.Request;
import feign.RequestTemplate;
import feign.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient;
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
import org.springframework.context.annotation.Primary;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.util.UriComponentsBuilder;import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.*;//@ConditionalOnBean
//@Primary
@Slf4j
public class LocalBlockingLoadBalancerClient extends FeignBlockingLoadBalancerClient {private Client delegate;private BlockingLoadBalancerClient loadBalancerClient;@Autowiredprivate LocalFeignPerpreties localFeignPerpreties;public LocalBlockingLoadBalancerClient(Client delegate,BlockingLoadBalancerClient loadBalancerClient) {super(delegate, loadBalancerClient);this.delegate = delegate;this.loadBalancerClient = loadBalancerClient;}@Overridepublic Response execute(Request request, Request.Options options) throws IOException {try {log.info("feign -> 配置化客户端");Boolean enable = localFeignPerpreties.getEnable();if (enable) {String url = request.url();RequestTemplate requestTemplate = request.requestTemplate();String name = requestTemplate.feignTarget().name();Map<String, String> urlMap = localFeignPerpreties.getRule();if (urlMap != null && urlMap.containsKey(name)) {URI uri = URI.create(url);StringBuffer strbuf = new StringBuffer();strbuf.append(urlMap.get(name)).append(uri.getPath());if (StringUtils.isNotBlank(uri.getQuery())) {strbuf.append("?").append(uri.getQuery());}requestTemplate.target(urlMap.get(name));Map<String, Collection<String>> headers = request.headers();Map<String, Collection<String>> newheaders = new HashMap<>();//处理请求头ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest attributesRequest = attributes.getRequest();Enumeration<String> headerNames = attributesRequest.getHeaderNames();if (headerNames != null) {while (headerNames.hasMoreElements()) {String element = headerNames.nextElement();String elementVal = attributesRequest.getHeader(element);newheaders.put(element, new ArrayList<String>() {{add(elementVal);}});}}//构建新的requestRequest newRequest = buildRequest(request, strbuf.toString(), newheaders);return super.getDelegate().execute(newRequest, options);}}} catch (Exception e) {e.printStackTrace();}log.info("feign -> 默认客户端");return super.execute(request, options);}protected Request buildRequest(Request request,String reconstructedUrl,Map<String, Collection<String>> headers) {return Request.create(request.httpMethod(), reconstructedUrl, headers,request.body(), Charset.forName("UTF-8"), request.requestTemplate());}}

使配置类和重写的client生效

package com.***.redirect;import feign.Client;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;//@ConditionalOnProperty(prefix = ReBalancerProperties.prefix,name = "enable",havingValue = "true")
@Configuration
@EnableConfigurationProperties(value = {LocalFeignPerpreties.class})
public class ReBalancerConfiguration {@Beanpublic Client feignReBalancer(BlockingLoadBalancerClient discoveryClient) {return new LocalBlockingLoadBalancerClient(new Client.Default(null, null),discoveryClient);}
}

        到这里基本上可以满足重写feign URL的需求了,这个前提条件是代码在application启动类的下一级,如果不在启动类的同级或者下一级,是无法扫描到相关类的,这时我们可以注解完成扫描,需要在启动类上加上相关注解

package com.***.annotation;import com.***.ReBalancerConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
import org.springframework.context.annotation.Import;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import(ReBalancerConfiguration.class)
@AutoConfigurationPackage
public @interface EnableLocalFeignClient {
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/189192.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT线程的使用 循环中程序的等待

QT线程的使用 循环中程序的等待 先看效果1 pro文件2 头文件3 源文件4 ui文件先看效果 1 pro文件 QT += concurrent2 头文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H

简述MyBatis、MyBatis-Plus、以及MyBatis-Plus的简单运用

什么是MyBatis MyBatis是一个开源的Java持久层框架&#xff0c;用于简化与关系型数据库的交互。它通过将SQL语句与Java代码进行分离&#xff0c;提供了一种优雅的方式来处理数据库操作。 MyBatis的核心思想是将SQL语句与Java方法进行映射&#xff0c;使得开发人员可以通过配置…

集成开发环境PyCharm的使用【侯小啾python领航计划系列(三)】

集成开发环境 PyCharm 的使用【侯小啾python领航计划系列(三)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ�…

【Vue3+Ts项目】硅谷甄选 — 搭建后台管理系统模板

一、 项目初始化 一个项目要有统一的规范&#xff0c;需要使用eslintstylelintprettier来对我们的代码质量做检测和修复&#xff0c;需要使用husky来做commit拦截&#xff0c;需要使用commitlint来统一提交规范&#xff08;即统一提交信息&#xff09;&#xff0c;需要使用pre…

剑指 Offer(第2版)面试题 12:矩阵中的路径

剑指 Offer&#xff08;第2版&#xff09;面试题 12&#xff1a;矩阵中的路径 剑指 Offer&#xff08;第2版&#xff09;面试题 12&#xff1a;矩阵中的路径解法1&#xff1a;回溯 剑指 Offer&#xff08;第2版&#xff09;面试题 12&#xff1a;矩阵中的路径 题目来源&#x…

Python | 轻量ORM框架Peewee的基础使用(增删改查、自动创建模型类、事务装饰器)

文章目录 01 简介02 安装03 自动创建模型类04 基础使用4.1 查询4.2 新增4.3 更新4.4 删除 05 事务 01 简介 在使用python开发的过程中&#xff0c;有时需要一些简单的数据库操作&#xff0c;而Peewee正是理想的选择&#xff0c;它是一个小巧而灵活的 Python ORM&#xff08;对…

hadoop-3.3.5安装过程

准备资源三台虚拟机&#xff1a; 1&#xff09;准备3台服务器&#xff08;关闭防火墙、静态IP、主机名称&#xff09; 2&#xff09;安装JDK 3&#xff09;配置环境变量 4&#xff09;安装Hadoop 5&#xff09;配置环境变量 安装虚拟机&#xff08;略&#xff09;--1台即…

SQL练习

建数据库&#xff1a; mysql> create database worker; Query OK, 1 row affected (0.00 sec) mysql> CREATE TABLE worker (-> 部门号 int(11) NOT NULL,-> 职工号 int(11) NOT NULL,-> 工作时间 date NOT NULL,-> 工资 float(8,2) NOT NULL,-> 政治面貌…

如何删除mac苹果电脑上面的流氓软件?

在使用苹果电脑的过程中&#xff0c;有时候我们也会遇到一些不需要的软件。无论是因为不再需要&#xff0c;或者是为了释放磁盘空间&#xff0c;删除这些软件是很重要的。本文将为大家介绍怎样删除苹果电脑上的软件&#xff01; CleanMyMac X全新版下载如下: https://wm.make…

elementUI实现根据屏幕大小自适应换行,栅格化布局

需求&#xff1a; 默认一行展示4个卡片&#xff1b;当屏幕小于某个大小的时候&#xff0c;一行展示3个卡片&#xff1b;再小就展示2个&#xff1b;以此类推&#xff0c;最小就展示1个。 效果卡片样式如下图&#xff1a; 默认一行4个 屏幕缩小到某个阈值&#xff0c;一行展示…

Linux:vim的简单使用

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》 文章目录 前言一、vim的基本概念二、vim的基本操作三、vim正常模式命令集四、vim底行模式命令集五、.xxx.swp的解决总结 前言 本文是对Linux中vim使用的总结 一、vim的基本概念 …

iOS Class Guard 成功了,但无法区分差异

iOS Class Guard 成功了&#xff0c;但无法区分差异 我正在开发一个静态库&#xff0c;并使用 Polidea 的 iOS Class Guard 来混淆我的静态库。我按照步骤在项目的根路径中下载 obfuscate_project&#xff0c;更改其中所需的名称&#xff0c;最后在终端中运行 bash obfuscate_p…

【android开发-09】android中AlertDialog和ProgressDialog的用法介绍

1&#xff0c;AlertDialog的用法 AlertDialog是Android中用于创建对话框的类&#xff0c;通常用于显示消息、警告或确认信息。对话框是一种重要的用户界面元素&#xff0c;可以在应用程序中提供即时反馈或获取用户的确认。 下面是一个简单的示例代码&#xff0c;展示了如何在…

算法通关村第六关—二叉树的层次遍历经典问题(白银)

二叉树的层次遍历经典问题 一、层次遍历简介 广度优先遍历又称层次遍历&#xff0c;过程如下&#xff1a;  层次遍历就是从根节点开始&#xff0c;先访问根节点下面一层全部元素&#xff0c;再访问之后的层次&#xff0c;图里就是从左到右一层一层的去遍历二叉树&#xff0c…

学习笔记8——JUC入门基础知识

学习笔记系列开头惯例发布一些寻亲消息 链接&#xff1a;https://baobeihuijia.com/bbhj/contents/3/199561.html 进程和线程:进程是资源分配的最小单位&#xff0c;线程是CPU调度的最小单位 进程和线程的主要区别&#xff08;总结&#xff09;_进程和线程的区别-CSDN博客进程…

Flink的部署模式和运行模式

集群角色 Flink提交作业和执行任务&#xff0c;需要几个关键组件&#xff1a; 客户端&#xff1a;代码由客户端获取并作转换&#xff0c;之后提交给Jobmanager Jobmanager就是Flink集群的管事人&#xff0c;对作业进行中央调度管理&#xff1b;当从客户端获取到转换过的作业后…

NRF24L01 无线收发模块与 Arduino 的应用

NRF24L01 是一款常用的无线收发模块&#xff0c;与 Arduino 兼容性良好&#xff0c;可以用于实现无线通信和数据传输。本文将介绍如何将 NRF24L01 模块与 Arduino 配合使用&#xff0c;包括硬件的连接和配置&#xff0c;以及相应的代码示例。 一、引言 NRF24L01 是一款基于 2.…

CentOS或RHEL安装vscode

下载rpm安装包 网络下载或者下载到本地再上传到服务器&#xff0c;点击访问国内下载地址&#xff0c;不需要积分curl -fOL https://github.com/coder/code-server/releases/download/v4.19.1/code-server-4.19.1-amd64.rpm安装 rpm -i code-server-4.19.1-amd64.rpm关闭和禁用…

STM32F407-14.3.9-01输出比较模式

输出比较模式 此功能用于控制输出波形&#xff0c;或指示已经过某一时间段。 当捕获/比较寄存器与计数器之间相匹配时&#xff0c;输出比较功能&#xff1a; ● 将为相应的输出引脚分配一个可编程值&#xff0c;该值由输出比较模式&#xff08;TIMx_CCMRx 寄存器中的 OCxM⑦…

Python批量Git Pull,对文件夹批量进行Pull操作

效果展示 说明 本来是想写的完善一些&#xff0c;但由于是自用&#xff0c;所以写出来后发现已经解决了自己的问题&#xff0c;所有 2和3功能没有写。 执行的话&#xff0c;需要 cmd 之后 直接 Python BatchGitPull.py 运行下面代码即可。 里面同时涉及到其他Pyhon知识点(写给…