[Spring Cloud] 求助,怎么实现 Ribbon 按照 userId 哈希路由?

2019-10-10 23:04:48 +08:00
 lixueyu001

大家有遇到过这种需求吗?

userId 存在于 Feign 请求的 header 或者参数中,路由是在项目中使用 feign 调用时发生的,不是网关那里的路由。

我有一个有问题的方案, 1、在 FeignInterceptor 那里拦截一下 userId 放到 ThreadLocal (只能拦截请求没找到返回怎么拦截) 2、然后在 Ribbon 的自定义路由策略 IRule 的 choose 方法中获取 ThreadLocal 里的 userId 并删除 ThreadLocal 里的值存在没有被清空的风险

求教,可行的路由方案。

2785 次点击
所在节点    Java
8 条回复
cluulzz
2019-10-11 10:01:09 +08:00
seata 我现在就像你说的这样做,不过用的是 InheritableThreadLocal,中间用 aspect 切开...
lixueyu001
2019-10-11 10:27:12 +08:00
@cluulzz InheritableThreadLocal 会有问题吧,能否说下你的切面怎么实现的。
https://blog.csdn.net/qq_27570205/article/details/98961963
cluulzz
2019-10-11 10:37:12 +08:00
InheritableThreadLocal:
切面的话 seata-spring 有个注解 @GlobalTransactional

大概这样
lixueyu001
2019-10-11 10:54:19 +08:00
@cluulzz 多谢 明白了,只是利用了一下 @GlobalTransactional 注解,跟 seata 没有太直接关系对吧。
我这边比较麻烦了没有一个统一的注解在 feign 调用上。
我准备给 feign 和 ribbon 默认一下 Client 为 Okhttp,给 Okhttp 加个拦截器试试。
跨线程传值用 HystrixRequestVariableDefault 应该可以。
cluulzz
2019-10-11 11:03:42 +08:00
@lixueyu001 #4 这样..跨线程那块看来我还要改..
lixueyu001
2019-10-11 17:22:56 +08:00
@lixueyu001 失败,Okhttp 的拦截器起作用的是在 Ribbon 负载后边
xuanbg
2019-10-12 14:23:36 +08:00
没能理解楼主的问题在哪? Ribbon 的路由策略和拦截有啥关系?正常配自定义路由策略就好了吧。feign 请求加请求头的问题?是的话自己实现 feignClient 就行了。
xuanbg
2019-10-12 14:27:35 +08:00
上面说得不是很准确,不是自己实现 feignClient,是自己构建 feignClient,就像这样:
TaskClient taskClient = Feign.builder().decoder(decoder).encoder(encoder)
.requestInterceptor(template -> {
Map<String, String> map = call.getHeaders();
for (String k : map.keySet()) {
String v = map.get(k);
template.header(k, v);
}
}).target(TaskClient.class, getServiceUrl(call.getService()));

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/608039

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX