Java skill动态指定feign的访问地址方式

 更新时间:2026年01月09日 16:43:17   作者:她又在丛中笑  
在使用Feign调用内部服务时,通过Redis查询ELB地址并进行调用,遇到的问题包括:指定的地址在Nacos服务名中不存在时,URL参数需要赋初始值;使用ThreadLocal获取当前线程信息时易出问题,建议使用MDC跨线程传递参数,并注意请求结束后的清理

场景

在有下沉节点项目的前提下,使用feign调用内部服务的时候,在redis查询需要调用的内部服务的elb地址并调用

编码

新增feign传参类

@Data
public class TestDto {
    private String id;
}

新增调用内部服务的feign接口

@FeignClient(name = "test", url = "http://localhost:1234", configuration = FeignConfig.class)
public interface TestClient {
    @PostMapping(value = "/v1/test/get_name")
    Object getNameById(@RequestParam("id") String id, @RequestBody TestDto body);
}

feign配置类逻辑修改

@Configuration
public class FeignConfig {

    @Bean
    public RequestInterceptor headerInterceptor() {
        return new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate requestTemplate) {
            	// 只有请求url的前缀是【/v1/test/】才需要指定地址
                if(requestTemplate.url().startsWith("/v1/test/")){
                	// 初始化地址信息
                	String url = "";
                	// 获取@RequestBody 中的参数
                    Object parse = JSONObject.parse(new String(requestTemplate.body()));
                    Map<String,String> info = (Map<String, String>) parse;
                    String id= info.get("id");
                    if(StringUtils.isBlank(id)){
                        // 如果body中没有id,去@RequestParam 查询
                        Map<String, Collection<String>> queries = requestTemplate.queries();
                        //================ 业务逻辑 begin
                                             .
                                             .
                                             .
                                             .
                        //================ 业务逻辑 end
                        // 拿到要访问的地址之后,配置RequestTemplate.target,这样就可以实现feign指定地址调用了
                        requestTemplate.target(url);
                    }
                }

            }
        };
    }
}

大坑

1、如果feign接口中@FeignClient注解的name值是nacos注册的服务名,那要实现动态指定访问地址的话,分以下两种情况:

  • 指定的地址在nacos的服务名中不存在,url参数一定要赋初始值,否则,就会发现requestTemplate.target 就失效了,实质是在debug日志级别会打印负载均衡失败的日志。
  • 指定的地址在nacos的服务名中存在,url参数没有硬性要求。
  • 还是建议大家,动态指定feign的访问地址,url参数最好赋一个初始值

2、requestTemplate.target(url)中的参数url内容一定是完整的地址(如:http://127.0.0.1:8080)

3、不要在这个apply()方法中使用ThreadLocal这种获取当前线程中的相关信息的类,因为feign是线程池管理的,主线程进入到feign之后,就进入到了一个子线程,在feign中的所有操作都是在一个子线程中的操作,所以使用ThreadLocal这种类时会出问题。

如果必须要在feign中获取到此次请求中的一个全局参数的话,可以考虑一下使用MDC(log4j和logback等日志框架提供的一种机制),ThreadLocal是面向单个线程的,MDC是面向单个请求的(跨线程),使用MDC就不用考虑多个线程的问题了,但一定要注意 请求结束之后要清除

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java对象流实例代码

    Java对象流实例代码

    这篇文章主要介绍了Java对象流实例代码,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • Java详解聊天窗口的创建流程

    Java详解聊天窗口的创建流程

    这篇文章主要介绍了怎么用Java来创建一个聊天窗口,聊天软件我们经常要用,但是你有想过自己怎么去实现它吗,感兴趣的朋友跟随文章往下看看吧
    2022-04-04
  • Java取整与四舍五入

    Java取整与四舍五入

    本文详细讲解了Java取整与四舍五入,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-12-12
  • java验证电话号码的方法

    java验证电话号码的方法

    这篇文章主要介绍了java验证电话号码的方法,需要的朋友可以参考下
    2014-02-02
  • Java 网络爬虫新手入门详解

    Java 网络爬虫新手入门详解

    这篇文章主要介绍了Java 网络爬虫新手入门详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Java动态脚本Groovy

    Java动态脚本Groovy

    本文介绍了Java动态脚本Groovy,Groovy是用于Java虚拟机的一种敏捷的动态语言,它是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言。使用该种语言不必编写过多的代码,同时又具有闭包和动态语言中的其他特性,需要的朋友可以参考一下
    2021-12-12
  • java连接mysql数据库详细步骤解析

    java连接mysql数据库详细步骤解析

    以下是对java连接mysql数据库的具体详细步骤进行了分析介绍,需要的朋友可以过来参考下
    2013-08-08
  • MybatisPlus中的save方法详解

    MybatisPlus中的save方法详解

    save方法是Mybatis-plus框架提供的一个添加记录的方法,它用于将一个实体对象插入到数据库表中,这篇文章主要介绍了MybatisPlus中的save方法,需要的朋友可以参考下
    2023-11-11
  • JavaMail入门教程之接收邮件(4)

    JavaMail入门教程之接收邮件(4)

    这篇文章主要为大家详细介绍了JavaMail入门教程之接收邮件的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • 一篇文章带你了解Java SpringBoot四大核心组件

    一篇文章带你了解Java SpringBoot四大核心组件

    这篇文章主要介绍了SpringBoot四大核心组件的使用小结,详细的介绍了这方面的知识,有兴趣的可以了解一下,希望能够给你带来帮助
    2021-09-09

最新评论