【分布式事务】阿里Seata(GTS)

推荐:

https://www.sofastack.tech/blog/seata-distributed-transaction-deep-dive/      Seata 分布式事务实践和开源详解(各种XA/TCC/saga等)

https://segmentfault.com/a/1190000043797986  Seata的可观测实践   //  日志、度量等实现方案

 实现原理: https://zhuanlan.zhihu.com/p/32684212

业务场景:

场景一:分库分表场景下的分布式事务

 

TODO:从可观测材料复制

 

场景二:跨服务场景下的分布式事务

TODO:从可观测材料复制

 

Seata架构

 

 

TODO:从可观测材料复制

  • Transaction Coordinator(TC)事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。
  • Transaction Manager(TM)控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议,TM 定义全局事务的边界。
  • Resource Manager(RM)控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。RM 负责定义分支事务的边界和行为。

跨服务事务ID的传递

https://www.cnblogs.com/ciel717/p/16185061.html

  • 消费者:SeataFeignClient替换了默认的feignClient,把xid放到了requestHeader里。

  SeataFeignClient.execute:塞到消息头

@Override
public Response execute(Request request, Request.Options options) throws IOException {
    //设置xid
    Request modifiedRequest = getModifyRequest(request);
    //调用下游服务
    return this.delegate.execute(modifiedRequest, options);
}

private Request getModifyRequest(Request request) {
    String xid = RootContext.getXID();
    if (StringUtils.isEmpty(xid)) {
        return request;
    }
    Map<String, Collection<String>> headers = new HashMap<>(MAP_SIZE);
    //设置xid到消息头
    headers.putAll(request.headers());
    List<String> seataXid = new ArrayList<>();
    seataXid.add(xid);
    headers.put(RootContext.KEY_XID, seataXid);
    return Request.create(request.method(), request.url(), headers, request.body(),request.charset());
}
  • Provider:拦截器实现

   SeataHandlerInterceptor.preHandle():通过WebMvcConfigure::addInterceptors中绑定该拦截器

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) {
    String xid = RootContext.getXID();
    //从消息头中获取xid
    String rpcXid = request.getHeader(RootContext.KEY_XID);
    if (log.isDebugEnabled()) {
        log.debug("xid in RootContext {} xid in RpcContext {}", xid, rpcXid);
    }
    if (xid == null && rpcXid != null) {
        // 设置xid
        RootContext.bind(rpcXid);
        if (log.isDebugEnabled()) {
            log.debug("bind {} to RootContext", rpcXid);
        }
    }
    return true;
}

 

可观测实践:

  • 分布式事务消息链路较复杂Seata 在解决了用户易用性和分布式事务一致性这些问题的同时,需要多次 TC 与 TM、RM 之间的交互,尤其当微服务的链路变复杂时,Seata 的交互链路也会呈正相关性增加。这种情况下,其实我们就需要引入可观测的能力来观察、分析事物链路。
  • 异常链路、故障排查难定位,性能优化无从下手在排查 Seata 的异常事务链路时,传统的方法需要看日志,这样检索起来比较麻烦。在引入可观测能力后,帮助我们直观的分析链路,快速定位问题;为优化耗时的事务链路提供依据。
  • 可视化、数据可量化可视化能力可让用户对事务执行情况有直观的感受;借助可量化的数据,可帮助用户评估资源消耗、规划预算。

 可观测能力:

Metrics 维度

模块设计

posted @ 2022-12-10 18:13  飞翔在天  阅读(60)  评论(0编辑  收藏  举报