V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
lixueyu001
V2EX  ›  Java

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

  •  
  •   lixueyu001 · Oct 10, 2019 · 3506 views
    This topic created in 2403 days ago, the information mentioned may be changed or developed.

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

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

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

    求教,可行的路由方案。

    8 replies    2019-10-12 14:27:35 +08:00
    cluulzz
        1
    cluulzz  
       Oct 11, 2019
    seata 我现在就像你说的这样做,不过用的是 InheritableThreadLocal,中间用 aspect 切开...
    lixueyu001
        2
    lixueyu001  
    OP
       Oct 11, 2019
    @cluulzz InheritableThreadLocal 会有问题吧,能否说下你的切面怎么实现的。
    https://blog.csdn.net/qq_27570205/article/details/98961963
    cluulzz
        3
    cluulzz  
       Oct 11, 2019
    InheritableThreadLocal:
    切面的话 seata-spring 有个注解 @GlobalTransactional

    大概这样
    lixueyu001
        4
    lixueyu001  
    OP
       Oct 11, 2019
    @cluulzz 多谢 明白了,只是利用了一下 @GlobalTransactional 注解,跟 seata 没有太直接关系对吧。
    我这边比较麻烦了没有一个统一的注解在 feign 调用上。
    我准备给 feign 和 ribbon 默认一下 Client 为 Okhttp,给 Okhttp 加个拦截器试试。
    跨线程传值用 HystrixRequestVariableDefault 应该可以。
    cluulzz
        5
    cluulzz  
       Oct 11, 2019
    @lixueyu001 #4 这样..跨线程那块看来我还要改..
    lixueyu001
        6
    lixueyu001  
    OP
       Oct 11, 2019
    @lixueyu001 失败,Okhttp 的拦截器起作用的是在 Ribbon 负载后边
    xuanbg
        7
    xuanbg  
       Oct 12, 2019
    没能理解楼主的问题在哪? Ribbon 的路由策略和拦截有啥关系?正常配自定义路由策略就好了吧。feign 请求加请求头的问题?是的话自己实现 feignClient 就行了。
    xuanbg
        8
    xuanbg  
       Oct 12, 2019
    上面说得不是很准确,不是自己实现 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()));
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3037 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 07:56 · PVG 15:56 · LAX 00:56 · JFK 03:56
    ♥ Do have faith in what you're doing.