森马

随着企业用户逐渐增多,面对不同场景下的需求和技术问题,CloudWeGo 团队将会持续分享不同企业的落地实践,包含不同行业面临的技术问题、选型参考和最终落地性能和使用分享,来帮助更多用户使用 CloudWeGo 。
近些年电商行业高速发展,森马电商线上业务激增,面临着高并发、高性能的业务场景需求。森马正式成为 CloudWeGo 的企业用户,通过使用 Kitex 接入 Istio,极大地提高了对高并发需求的处理能力。以下内容来自森马开发工程师梁东坡的分享。

1. 森马电商订单流转中心 —— 天枢

业务增长

森马订单流转中心 —— 天枢的主要功能是对接各大电商平台,把订单、商品、退单等信息统一处理后流转到下游系统,是下游系统和平台对接的中间枢纽。目前森马电商在运营的电商平台几十家,如:天猫、抖店、京东、拼多多等,由于每个平台的接口和对接的方式不统一,我们专门开发了这套系统,去统一对接电商平台,然后把数据处理成统一的格式发到下游系统,如:OMS 和 WMS。该系统在电商活动,如 6.18,双十一等订单峰值流量下发挥了重要作用。
从 2015 至 2021 年,森马的双十一业务量增长非常迅速。2015 年双十一的业绩有 3 亿 +,而去年的双十一业绩为 20 亿 +,2021 年商品交易总额(GMV) 更是突破百亿。随着业务的增长,对订单系统的性能稳定性要求越来越高。而且随着系统的规模增长,集群内的 Pod 数量和 Service 不断增加,对系统底层架构有很大的考验。目前从旧系统迁移的平台有:有赞、抖音、拼多多、快手等,集群内的 Pod 数已经超过 200 个,后续接入京东、唯品会、天猫等平台后,Pod 数会成倍的增长,更需要一个成熟的系统架构作为支撑。
notion image

面临问题

随着直播行业的兴起,我们请了一些网红主播和流量明星来直播带货。直播期间,订单量经常会出现几秒内突然爆发的情况,订单推送到系统后,如果系统处理较慢,订单就不能及时流入下游系统,下游系统的 OMS 不知道已经产生如此大的订单量,就会出现不能同步的情况,即超卖现象。在电商行业,超卖是很严重的问题,如果用户下单后不能及时发货,不仅需要大量的人力去跟客户解释道歉,也要以优惠券等形式赔偿用户遭受的损失,甚至会接到大量投诉,严重影响我们在电商平台的信誉,电商平台也会对我们进行处罚。我们经历过当 GMV 超过千万时,订单系统延迟超过半个小时的情况,对我们造成了极大的影响。
因此,当遇到如双十一,6.18 大促等活动时,特别是在直播时订单量短时间内暴增的情况下,森马原有的系统架构已经无法支撑,不能及时处理订单数据。这影响了我们发货及库存同步,间接地产生了不同类型的资损。
notion image

技术挑战

技术挑战主要有以下三个方面:
  • 高并发:在电商业务场景下,不管是面向用户,比如秒杀,还是面向业务,比如订单处理,如果实现不了高并发,系统就很难做大,很难适应业务的增长。
  • 高性能:除了用高并发来实现业务的快速处理外,性能也是一个挑战。例如在当前疫情状态下,各行各业都在降本增效,解决不了性能问题,就会不断地增加服务器资源,大大增加企业成本。
  • 技术保障:电商行业公司,大多资源和精力都在销售端,运营端,技术方面投入相对薄弱。因此在技术选型上需要从可靠、安全、支持等维度去考量。

2. 项目技术选型

如何选择

在开发语言的选择方面,开发语言没有好坏之分,只有这个语言在相关场景下合适不合适的问题。我们从性能、多线程、编译、效率等方面综合考虑,选择了 Golang。
在微服务框架的选择方面,团队分别用 Google 开源的 gRPC 和字节跳动开源的 CloudWeGo-Kitex 做了技术评估和性能压测。经过专业测试同学的压力测试,最终选择了 CloudWeGo-Kitex 作为我们的微服务框架。
选择 Kitex 的原因主要有两点:一是 Kitex 背后有强大的技术团队提供及时有效的技术支持;二是经过压力测试,Kitex 的性能优于其他微服务框架。

关于微服务

使用微服务框架,一定会涉及到选择第三方开源的服务注册中心,那么是选择常用的开源注册中心(Zookeeper、Eureka、Nacos、Consul 和 ETCD),还是直接选择云原生的服务网格(Istio)?接下来从流量转发、服务注册和服务发现维度介绍一下微服务集群的两种形式。
一是 Kubernetes Native,Kubernetes 集群中的每个节点都部署了一个 Kube-proxy 组件,该组件与 Kubernetes API Server 进行通信,观测服务和节点中的变化,进行负载均衡的转发。这种开源注册中心默认使用 TCP 协议,由于 K8s 负载均衡不支持 RPC 协议(HTTP2),因而需要额外的第三方服务注册中心支持。
二是基于 Istio 的服务网格,它并不需要额外的注册中心组件支持。Istio 接管了 K8s 的网络,通过 Sidecar Proxy 的方式将 Kubernetes 中的流量控制从服务层中抽离出来,Istio 基于 Enovy 的 xDS 协议扩展了其控制平面,每个 Pod 中放入原有的 Kube-proxy 路由转发功能。Istio 具备了流量管理、策略控制、可观察性等特点,将 “应用程序” 与 “网络” 解耦,因此不需要额外使用第三方注册中心。
notion image
那么这两种服务注册与发现的流程是怎样的呢?下图中左侧就是常用的服务注册中心使用流程。目标服务先把实例注册到服务注册中心,客户端从服务注册中心拿到目标实例的数据,根据负载均衡策略去选择一个服务实例,完成整个请求。
右侧是使用了基于 Istio 的服务网格。大概流程是 Client 访问目标服务的时候,流量先进入 Service 的 Proxy,被 Proxy 拦截,Proxy 会从服务发现(Pilot)拿到服务与服务实例的映射关系,同时会拿到负载均衡的策略,去选择 Service 一个实例。总体来看,这两种流程大致相同,但实现方式有所差别,各有所长。
notion image

天枢系统基本架构

抖音、快手、拼多多和有赞等这样成熟的平台在产生订单时,都会将订单以消息推送的形式发送到服务网格中。我们先后通过 Ingress Gateway 网格入口管理程序、VirtualService 把订单转发到网格的不同服务中,内部再通过不同服务之间进行调用。其中,Kitex 作为微服务的 RPC 框架,服务发现和服务注册均是基于云原生的服务网格 Istio。
notion image

Kitex 接入 Istio

那么 Kitex 接入 Istio 是怎么实现的呢?如下图所示,服务端注册服务之后,在创建客户端的时候,客户端的 Server-host 要写实际集群中的内网地址,例如:server-douyin.default.svc.cluster.local,如上文所说,不用再搭配第三方的服务注册中心。
notion image
由于 Kitex 使用 gRPC 协议,在创建客户端的时候需指定使用 gRPC 协议:
notion image
在 Istio 中怎么部署我们的客户端或者服务端呢?有以下两种方式:
1. 为命名空间开启自动注入:kubectl label namespace default istio-injection=enabled。注入之后会产生两个重要的容器,一是 Istio-proxy,负责流量拦截和流量代理,比如做流量转发;二是 Server-douyin,是负责开发的应用容器。
notion image
2. 把 Go 代码打包的镜像部署到集群中:
例如我们创建了一个 Deployment,名为 Server-douyin,另外作为服务端需要创建相应的 Service。

压测对比

我们将 Kitex 和 gRPC 在以下相同服务器硬件资源和网络环境下进行了压测对比:
  • 压测工具:JMeter;
  • 阿里云 ECS (8 vCPU,16 GiB,5 台);
  • 集群:Kubernetes 1.20.11;
  • 服务网格:Istio v1.10.5.39。
notion image
通过对比发现,在指定时间相同的情况下,Kitex 在单位时间内处理订单数量更多。在指定订单数量的情况下,Kitex 对于处理相同数量的订单所需时间更短,且订单量越大,这种性能差别越明显。总体来看,Kitex 在处理大批订单时优势非常突出。

Kitex 产生性能优势的原因

CloudWeGo 团队来森马做技术支持时讲到对自研网络库 Netpoll 做了一些性能优化,比如:
  • 连接利用率;
  • 调度延迟优化;
  • 优化 I/O 调用;
  • 序列化 / 反序列化优化;
  • .......
更多资料可以查看 CloudWeGo 官网:CloudWeGo

CloudWeGo 团队技术支持

森马选择 Kitex 之后,CloudWeGo 技术团队给予了足够的技术支持,包括现场支持和远程协助。这也让森马团队对使用 Kitex 有了信心,不管遇到什么样的技术难题,都会有强大的技术团队来协助解决。
notion image

3. 后续规划

Thrift 和 Protobuf 如何选择

我们在项目初期选择 gRPC 协议 Protobuf 是因为选择了 Istio 服务网格,而选择 Istio 服务网格主要是因为它有多流量转发和服务治理等功能,例如在电商场景下,不同平台的推送消息都可以通过 VirtualService 转发到不同的服务,相当方便。但是目前每个 Pod 中放入原有的 Kube-proxy 路由转发功能,会增加响应延迟。由于 Sidecar 拦截流量时跳数更多,会消耗更多的资源。
而对于 Thrift,它是 Kitex 默认支持的协议,字节官方对它做了很多性能上的优化,如:使用 SIMD 优化 Thrift 编码,减少函数调用,减少内存操作等,还开源了高性能 Thrift 编解码器 Frugal ,Frugal 具有无需生成代码、高性能(在多核场景下,Frugal 的性能可以达到传统编解码方式的 5 倍)和稳定性等特点,进一步提升了性能和开发效率。
因此,森马目前也在考虑在下一次系统版本的架构中改用 Thrift 协议。

服务、合作共赢

森马开发的电商相关产品不仅可以为自己电商品牌所使用,产品成熟后还可以服务于其他相似的电商公司。因此我们也希望和 Kitex 官方有更深的技术合作,如电商云。
欢迎企业用户扫描二维码,填写企业支持问卷,并加入飞书交流群,获取 CloudWeGo 团队企业技术支持。
打开飞书,扫描左侧二维码填写企业支持问卷,扫描右侧二维码可加入飞书交流群
notion image

4. 更多资讯

 
Loading...
目录
文章列表
王小扬博客
产品
Think
Git
软件开发
计算机网络
CI
DB
设计
缓存
Docker
Node
操作系统
Java
大前端
Nestjs
其他
PHP