@FeignClient("service-id")
默认走的是 LoadBalancerFeignClient
而一旦注解加上了 url,走的就是 DefaultClient 了
这块是在哪儿处理的?我能不能手动指定使用哪一个?
可能我描述的不太清楚,再附加一些吧
背景是我们项目里要调一些其他的服务,有Eureka的,也有通过url调的。 Eureka的就不说了,直接用就行了。
url的要区分开发环境和线上环境,但他们有一些共性就是一级域名是相同的,二级域名是服务ID 所以就想偷个懒,用拦截器统一设置域名
@Component
public class MyFeignInterceptor implements RequestInterceptor {
@Value("${svc.host}")
private String svcHost;
@Override
public void apply(RequestTemplate template) {
String name = template.feignTarget().name();
if (name.toLowerCase().endsWith("xxx-svc")){
template.target("http://" + name.toLowerCase() + "." + svcHost);
}
}
}
这样执行的话,直接会报错,说服务找不到 看了下源码,在FeignClientFactoryBean里会根据@FeignClient注解里的url选择是否走负载均衡(Ribbon) 走Ribbon的话,肯定是获取不到服务的(Eureka里没有嘛)
所以目前的解决判断是@FeignClient上加一个不为空的url(随便什么都行,只要不为空) 这种看起来不太优雅。
还想过自定义Ribbon的Rule,看能不能在选择服务那拦截修改,也没成功。
想问问各位大神,有没有什么高招?
1
k9990009 2020-07-13 18:25:52 +08:00
|
2
sunzy OP @k9990009 这样写走的是 DefaultClient,我想不写 url,而让它不要走 LoadBalancerFeignClient
|
3
twogoods 2020-07-13 18:50:42 +08:00
不写 url 他怎么知道调谁啊,不知道他就要走一次基于服务名的服务发现啊,发现了多个自然就需要 LoadBalancer 了。服务发现好像没有多个实现可选吧,你想拓展继承 LoadBalancerFeignClient 自己实现一个呗
|
4
limuyan44 2020-07-13 19:04:39 +08:00
你是不是搞错需求了,是要改负载的策略还是改 client 的连接配置?当前的需求肯定是不合理的,代码写死了没有 url 必然走 loadblance,原因楼上也说了,具体可以看他的 factorybean 。
|
5
BBCCBB 2020-07-13 19:07:37 +08:00
你在说啥??
你说的 httpclient 是说用 okhttp, apache httpclient.. 还是说选择哪一个 web 实例去调用?? |
6
sunzy OP @limuyan44
factorybean 看了,硬编码通过 url 判断来搞的 我的需求是写一个 feign 拦截器,针对一批共性的 feign client,通过名称和环境,换成 url 访问…… |
7
ilumer 2020-07-14 00:50:35 +08:00
不知道你这个共性指的是啥,如果简单的话,直接在配置文件里指定 feignClient 的 url 直接走 url,不会再使用负载均衡,大概就是这样
@FeignClient(name = "${feign.name}", url = "${feign.url:null}"),如果配置中心里面没有对应的 key,这个适合就可以走负载均衡,有 key 就可以走你需要的 url |
8
wangyanrui 2020-07-14 08:18:40 +08:00
一脸懵逼的进来,没看懂描述的什么问题。
feign.SynchronousMethodHandler#client 就是真正执行远程调用的东西,根据你的需求,动态修改这个就可以了 原因看 feign.SynchronousMethodHandler#invoke 方法 |
9
sunzy OP @ilumer 共性是有一部分微服务不是走 eureka 的,并且 url 都是 serviceId+相同的后缀,并且环境
现在的解决方案是通过拦截器 ``` @Slf4j @Component public class MyFeignInterceptor implements RequestInterceptor { @Value("${svc.host}") private String svcHost; @Override public void apply(RequestTemplate template) { String name = template.feignTarget().name(); if (name.toLowerCase().endsWith("xxx-svc")){ template.target("http://" + name.toLowerCase() + "." + svcHost); } } } ``` |