大家有遇到过这种需求吗?
userId 存在于 Feign 请求的 header 或者参数中,路由是在项目中使用 feign 调用时发生的,不是网关那里的路由。
我有一个有问题的方案, 1、在 FeignInterceptor 那里拦截一下 userId 放到 ThreadLocal (只能拦截请求没找到返回怎么拦截) 2、然后在 Ribbon 的自定义路由策略 IRule 的 choose 方法中获取 ThreadLocal 里的 userId 并删除 ThreadLocal 里的值存在没有被清空的风险
求教,可行的路由方案。
1
cluulzz 2019-10-11 10:01:09 +08:00
seata 我现在就像你说的这样做,不过用的是 InheritableThreadLocal,中间用 aspect 切开...
|
2
lixueyu001 OP @cluulzz InheritableThreadLocal 会有问题吧,能否说下你的切面怎么实现的。
https://blog.csdn.net/qq_27570205/article/details/98961963 |
3
cluulzz 2019-10-11 10:37:12 +08:00
|
4
lixueyu001 OP @cluulzz 多谢 明白了,只是利用了一下 @GlobalTransactional 注解,跟 seata 没有太直接关系对吧。
我这边比较麻烦了没有一个统一的注解在 feign 调用上。 我准备给 feign 和 ribbon 默认一下 Client 为 Okhttp,给 Okhttp 加个拦截器试试。 跨线程传值用 HystrixRequestVariableDefault 应该可以。 |
5
cluulzz 2019-10-11 11:03:42 +08:00
@lixueyu001 #4 这样..跨线程那块看来我还要改..
|
6
lixueyu001 OP @lixueyu001 失败,Okhttp 的拦截器起作用的是在 Ribbon 负载后边
|
7
xuanbg 2019-10-12 14:23:36 +08:00
没能理解楼主的问题在哪? Ribbon 的路由策略和拦截有啥关系?正常配自定义路由策略就好了吧。feign 请求加请求头的问题?是的话自己实现 feignClient 就行了。
|
8
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())); |