Java skill - 动态指定feign的访问地址
- 场景
- 编码
- 新增feign传参类
- 新增调用内部服务的feign接口
- feign配置类逻辑修改
- 大坑
场景
在有下沉节点项目的前提下,使用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 {@Beanpublic RequestInterceptor headerInterceptor() {return new RequestInterceptor() {@Overridepublic 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);}}}};}
}
大坑
- 如果feign接口中@FeignClient注解的name值是nacos注册的服务名,那要实现动态指定访问地址的话,分以下两种情况:
- 指定的地址在nacos的服务名中不存在,url参数一定要赋初始值,否则,就会发现requestTemplate.target 就失效了,实质是在
debug日志级别
会打印负载均衡失败的日志。- 指定的地址在nacos的服务名中存在,url参数没有硬性要求。
- 还是建议大家,动态指定feign的访问地址,
url参数最好赋一个初始值
requestTemplate.target(url)
中的参数url内容一定是完整的地址(如:http://127.0.0.1:8080)