微服务生产实战-Spring Cloud全链路上下文

实现代码详见github:  https://github.com/einarzhang/spring-cloud-chaincontext

经历过大量服务划分之后, 每个服务主要承担自己独立的业务模型和功能, 如何将请求串联等全链路的应用问题越来越多, 常见的场景问题如下: 

  1. 假如网关保存了用户的session和用户信息, 如何让后端无状态的服务知道是哪一个用户操作? 
  2. 如何通过网关的请求后,到所有的服务能知道是同一条链路
  3. 如何从网关或者某个服务开始, 将某个特征数据一直传递下去

假如我们有A,B,C,D四个服务, 调用请求顺序依次经过GATEWAY->A->B->C->D, 如何保证A, B, C, D四个服务都能知道当前操作的是哪个用户. 在spring cloud里面, 我们可以想到通过header或者参数进行显示传递, 所有需要获取用户ID的接口都需要显示指定接收参数,并在调用其他服务的时候显示设置进去. 基于此原理, 并简化开发者的显示传递和接收工作, 这里根据spring cloud的组件特征进行封装, 实现一套全链路上下文中间件.

spring cloud全链路上下文主要处理如下中间件的填充和传递问题:

  1. RestTemplate在调用下游服务时如何将链路上下文数据携带?
  2. Feign在调用下游服务时如何将链路上下文数据携带?
  3. 服务接收方如何将header或者参数中携带的相关数据设置到链路上下文中?
  4. 如何保证hystrix线程池的情况下链路上下文依然有效?

实现原理如下所示:

链路上下文定义

spring cloud体系下的许多组件已经有自己的上下文实现, 如RequestContextHolder, zuul RequestContext等, 这里我们仿照zuul的RequestContext定义链路上下文, 主要继承自ConcurrentHashMap, 可以安全存储任何数据, 并采用InheritableThreadLocal保存上下文信息.

public class ChainContextHolder extends ConcurrentHashMap<String, Object> {

    protected static Class<? extends ChainContextHolder> contextClass = ChainContextHolder.class;

    protected static final ThreadLocal<? extends ChainContextHolder> THREAD_LOCAL = new InheritableThreadLocal<ChainContextHolder>() {
        @Override
        protected ChainContextHolder initialValue() {
            try {
                return contextClass.newInstance();
            } catch (Throwable e) {
                throw new RuntimeException(e);
            }
        }
    };

    /**
     * Override the default ChainRequestContext
     *
     * @param clazz
     */
    public static void setContextClass(Class<? extends ChainContextHolder> clazz) {
        contextClass = clazz;
    }

    /**
     * Get the current ChainRequestContext
     * 
     * @return the current ChainRequestContext
     */
    public static final ChainContextHolder getCurrentContext() {
        return THREAD_LOCAL.get();
    }

    /**
     * Unsets the threadLocal context. Done at the end of the request.
     * 
     * @return
     */
    public void unset() {
        this.clear();
        THREAD_LOCAL.remove();
    }

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值