华兴证券:混合云原生架构下的 Kitex 实践

华兴证券是 CloudWeGo 企业用户,使用 Kitex 框架完成混合云部署下的跨机房调用。

企业用户如何搭建针对 kitex 的可观测性系统?如何在 K8s 集群下使用 Kitex ?

华兴证券后端研发工程师,DevOps 负责人张天将从以下 4 个方面介绍 Kitex 在多机房 K8s 集群下的实践经验,包括:

1. 针对 Kitex 的可观测性系统搭建经验;

2. 服务压力测试中遇到的问题以及解决方案;

3. Kitex 的不同连接类型在 K8s 同集群/跨集群调用下的一些问题和解决方案;

4. 实践中遇到的其他问题以及解决方案。

以下内容来自张天老师的分享。

Kitex 的可观性系统搭建

华兴证券 CloudWeGo-Kitex 使用情况

首先介绍下我们团队的 Kitex 使用情况。去年 6 月 1 日。我们团队成立。Kitex 在 7 月 12 日发布了首个版本,10 天后我们就引入了 Kitex。选择 Kitex 的原因是:我们团队早期成员比较了解 Kitex,为了快速支撑业务迭代和验证,选择最熟悉的框架,不但使用上比较习惯,对性能和功能方面也比较有把握。后来也支撑了我们 APP 的快速上线。大约 4 个月之后就上线了 APP 的第一个版本。

下图是我们的微服务调用关系图,一共有三十多个微服务,调用链路数超过 70。我们的服务分别部署在两个机房。核心业务比如交易、行情等部署在私有机房。非核心的业务,比如资讯、股票信息等部署在阿里的金融云,这样能够更好地利用金融云已有的基础设施比如 MySQL、Kafka 等,作为初创团队,能够降低整体的运维压力。考虑到性能以及安全方面的因素,两个机房之间专门拉了专线。服务之间存在一些跨机房的依赖。跨机房调用会产生很多问题,后文会详细说明。

Tracing 选型

服务数多了之后,我们需要一套链路追踪系统来描绘调用链路每个环节的耗时情况。考虑到 Kitex 原生支持 Opentracing,为减少集成成本,我们调研了符合 Opentracing 规范的产品。

排除掉收费的、客户端不支持 Go 之后,就剩阿里云的链路追踪产品和 Uber 公司出品的 Jaeger,考虑到私有机房也要部署,最终选择了 Jaeger。

Kitex 接入 Tracing

选定方案之后,开始对 Kitex 的这个功能进行测试,结果发现当时去年 9 月初的 Kitex 版本并不支持跨服务的 Tracing,原因是调用的时候,没有把 Trace 信息发送给下游,如图所示,这样上下游是两个孤立的 Trace(OpenTracing 规范里称为 Span),于是就无法通过一个 TraceID 去串起整条链路。当时任务比较急,于是我们没有等 Kitex 官方的实现,决定自研。

为了自研,我们结合 Kitex 的源码,梳理出客户端和服务端的流程。可以看出 Kitex 的上下游都内置了 Tracer 的 Hook。这里我们要解决的问题是,如何把 Span 信息进行跨服务传输?

经调研,实现透传有三种方案。

第一种是在消息层搞一个 Thrift 协议的拓展,把 Trace 信息塞进去。原因是 Thrift 本身没有 Header 结构,只能进行协议的拓展。好在 Kitex 支持自定义的协议拓展,因此具备可行性,然而开发成本较高,所以没选择这种方案。

第二种是在 IDL 里增加通用参数,在字段里存 Trace 信息。缺点是业务无关的字段要在 IDL 里,对性能有一定的影响。毕竟需要通过 Kitex 的中间件,通过反射来提取。

第三种是利用了 Kitex 提供的传输层透传能力,对业务没有侵入性。最后选择了这一种方案。

透传方案定了之后,整体的流程就清晰了。首先客户端会在 metaHandler.write 里通过 CTX 获取当前 Span,提取并写入 spanContext 到 TransInfo 中。

然后服务端,在 metaHandler.Read 里读取 spanContext 并创建 ChildOf 关系的 Span,中间件结束时 span.finish(),最后为了防止产生孤立 Trace,New 服务端时不使用 Kitex 提供的 Tracing 的 Option。

这里是因为同一个服务可能分别作为 Kitex 上下游,Tracer 如果共用,需要分别加特殊逻辑,实现上有点复杂。

Tracing 基础库

为了充分利用 Tracing 的能力,除了 Kitex,我们在基础库中也增加了 Gin、Gorm、Redis、Kafka 等组件的 Tracing。

下面展示实际的一条链路。功能是通过短信验证码进行登录。先是作为 HTTP 服务的 API 入口,然后调用了一个短信的 RPC 服务,RPC 服务里面通过 Redis 来检查验证码。通过之后调用用户服务,里面可能进行一些增加用户的 MySQL 操作。最后把用户登录事件发给 Kafka,然后运营平台进行消费,驱动一些营销活动。可以看出最耗时的部分是关于新增用户的一堆 MySQL 操作。

对错误的监控

Tracing 一般只关注调用耗时,然而一条链路中可能出现各种错误:

1. Kitex

  • Kitex RPC 返回的 err(Conn Timeout、Read Timeout 等);

  • IDL 里自定义的业务 Code(111: 用户不存在)。

2. HTTP

  • 返回的 HTTP 状态码(404、503);

  • JSON 里的业务

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值