ToB企服应用市场:ToB评测及商务社交产业平台
标题:
使用sponge+dtm快速搭建一个高性能的电商系统,秒杀抢购和订单架构的设计与
[打印本页]
作者:
河曲智叟
时间:
2024-12-18 10:53
标题:
使用sponge+dtm快速搭建一个高性能的电商系统,秒杀抢购和订单架构的设计与
本文将展示如何使用 Sponge 框架快速创建一个浅易版高性能电商系统,主要实现秒杀抢购和订单功能,并通过分布式事务管理器 DTM 来确保数据一致性。电商系统的架构图如下:
这是源码示例eshop,目次下包括了两个一样的代码示例,只是代码结构稍有不同,主要是为了展示说明sponge支持创建不同堆栈模式的微服务项目,example-1-multi-repo是适合微服务多堆栈(multi-repo),example-2-mono-repo是适合微服务单堆栈(mono-repo)。
准备情况
为了构建这个电商系统,准备生成代码工具:
Sponge
: 快速创建不同类型服务和模块代码。点击 Sponge 安装说明 以获取更多信息。
准备以下依赖服务:
DTM
:分布式事务管理器,用于包管系统在多服务调用中的数据一致性。
Redis
:结合 DTM,用作秒杀抢购的缓存。
Kafka
:作为订单系统的消息队列,用于处理订单异步消息。
MySQL
:为各个服务提供数据存储。
全部这些服务将运行在虚拟机中,虚拟机的 IP 地点为 192.168.3.37。
启动 DTM 服务
DTM 是本系统的核心组件之一,负责管理订单和秒杀抢购的分布式事务。必要启动两个 DTM 服务实例,分别用于 MySQL 和 Redis 存储。
DTM下载地点:https://github.com/dtm-labs/dtm/releases/tag/v1.18.0
服务名端口配置DTM-MySQLHTTP: 36789, gRPC: 36790DTM-RedisHTTP: 35789, gRPC: 35790
1. 启动使dtm-mysql服务
在 MySQL 中导入 DTM 必要的表结构:
dtmcli.barrier.mysql.sql
dtmsvr.storage.mysql.sql
修改 DTM 配置文件 (示例配置文件):
Store: # specify which engine to store trans status
Driver: 'mysql'
Host: '192.168.3.37'
User: 'root'
Password: '123456'
Port: 3306
Db: 'dtm'
# 使用注册与发现(sponge的dtm驱动已支持etcd、consul、nacos)
#MicroService:
#Driver: 'dtm-driver-sponge'
#Target: 'etcd://127.0.0.1:2379/dtmservice'
#EndPoint: 'grpc://127.0.0.1:36790'
复制代码
启动 DTM 服务:
#dtm 服务端口 http: 36789, grpc: 36790
./dtm -c conf.yml
复制代码
2. 启动dtm-redis服务
修改 DTM 配置文件 (示例配置文件):
Store: # specify which engine to store trans status
Driver: 'redis'
Host: '192.168.3.37'
User: 'default'
Password: '123456'
Port: 6379
# 修改默认dtm服务端口
HttpPort: 35789
GrpcPort: 35790
# 如果使用注册与发现(sponge的dtm驱动已支持etcd\consul\nacos),则需要配置如下(使用http协议)
#MicroService:
#Driver: 'dtm-driver-sponge'
#Target: 'etcd://127.0.0.1:2379/dtmservice'
#EndPoint: 'http://127.0.0.1:35789'
复制代码
启动 DTM 服务:
#dtm 服务端口 http: 35789, grpc: 35790
./dtm -c conf.yml
复制代码
使用sponge快速构建电商系统
浅易版电商系统由以下 8 个微服务组成:
eshop_gw
:API 网关服务
user
:用户服务
product
:商品服务
order
:订单服务
stock
:库存服务
coupon
:优惠券服务
pay
:支付服务
flashSale
:秒杀抢购服务
1. 准备各个服务mysql数据库和表
将以下服务对应的数据库表导入 MySQL:
user 服务的库和表
product 服务的库和表
order 服务的库和表
stock 服务的库和表
coupon 服务的库和表
pay 服务的库和表
2. 准备各个服务的protobuf文件
这些protobuf文件给sponge快速创建服务:
user 服务的protobuf文件
product 服务的protobuf文件
order 服务的protobuf文件
stock 服务的protobuf文件
coupon 服务的protobuf文件
pay 服务的protobuf文件
flashSale 秒杀抢购服的protobuf文件
eshop_gw api 网关服务的protobuf文件
3. 基于protobuf生成gRPC+HTTP混合服务代码
打开sponge的UI页面,切换到菜单Protobuf --> 创建grpc+http服务,填写参数,分别生成7个支持grpc+http混合服务代码user、product、order、stock、coupon、pay、flashSale,如下图所示:
下载代码后,分别解压各个服务代码到eshop目次下。
注:在生成代码页面假如参数开启了大堆栈类型,表示创建的服务适合微服务单堆栈(mono-repo)模式。
4. 基于mysql表生成CRUD代码
打开sponge的UI页面,切换到菜单Public --> 生成service+handler CRUD代码,填写参数,分别生成user、product、order、stock、coupon、pay服务的CRUD代码,如下图所示:
下载代码后,分别解压CRUD代码,把CRUD代码(api和internal两个目次)移动到对应服务代码中(假如提示proto文件重复,忽略即可)。
注:在生成代码页面假如参数开启了大堆栈类型,表示创建的服务适合微服务单堆栈(mono-repo)模式。
5. 基于protobuf生成api网关服务代码
打开sponge的UI页面,切换到菜单Protobuf --> 创建grpc网关服务,填写参数,生成eshop_gw的api网关服务代码,如下图所示:
下载代码后,解压服务代码到eshop目次下。
为了让eshop_gw服务可以连接各个服务,必要生成连接代码。打开sponge的UI页面,切换到菜单Public --> 生成grpc连接代码,填写参数,生成eshop_gw的连接各个grpc代码,如下图所示:
下载代码后,解压代码,把连接代码(internal目次)移动到eshop_gw服务代码中。
注:在生成代码页面假如参数开启了大堆栈类型,表示创建的服务适合微服务单堆栈(mono-repo)模式。
6. 填写业务逻辑代码
到此为止,服务框架已经基本搭建完毕。接下来分别在各服务的 internal/service 目次下编写实际的业务逻辑代码。
7. 启动服务
启动服务前先修改各个服务的配置文件,修改端口、数据库连接等信息。各个服务默认的http端口(8080),grpc端口(8282),由于在同一台主机当地(当地测试ip为192.168.3.90)运行,为了防止端口冲突,所以在配置已经修改了各个服务的端口(在configs/xxx.yml目次下和api/xxx/v1/xxx.proto中修改端口),下面是已修改的端口:
服务协议HTTP 端口gRPC 端口eshop_gwHTTP8080-userHTTP, gRPC3008030082productHTTP, gRPC3018030182orderHTTP, gRPC3028030282stockHTTP, gRPC3038030382couponHTTP, gRPC3048030482payHTTP, gRPC3058030582flashSaleHTTP, gRPC3068030682 注:假如在容器或不同机器上运行,不必要修改默认的端口,只需修改映射端口。
测试与验证
单个服务测试
各个服务启动成功之后,先验证单个服务是否正常运行,分别测试user、product、order、stock、coupon、pay、flashSale这7个服务的api。
在欣赏器访问 http://localhost:<服务端口>/apis/swagger/index.html,验证各个服务的api是否正常,除了在swaggers页面测试api,也可以在各个服务下的internal/service/xxx_client_test.go 文件中填写参数后运行测试grpc api。
集成测试
各个服务测试正常后,通过eshop_gw的api网关服务测试整个系统是否正常运行。在欣赏器访问api网关服务的swagger页面,http://localhost:8080/apis/swagger/index.html,如下图所示:
测试提交订单 API
提交订单使用了dtm的分布式事务模式saga,主要验证创建订单、扣减库存、创建支付订单、优惠券数据是否一致。
为了避免库存不足导致订单失败,测试前先设置库存,在swagger页面找到设置产品库存api,填写参数,比方产品id为1、库存为10
{
"productID": 1,
"stock": 10
}
复制代码
测试提交订单分别哀求无缓冲队列和缓冲队列的api,在swagger页面找到对应的api,填写参数,比方用户id为1、产品id为1、产品数量为1、订单金额为100
{
"userID": 1,
"productID": 1,
"productCount": 1,
"amount": 100,
"couponID": 0
}
复制代码
注:假如设置couponID不为0,表示使用优惠券,假如优惠券失效或过期,会导致订单失败。假如想使得订单成功的话,在swagger页面找到创建优惠券api创建新的优惠券,然后获取得到优惠券id,填写到提交订单api的couponID字段。
测试秒杀抢购API
秒杀抢购使用了kafka的消息队列、dtm+redis的二阶段消息、dtm+mysql的saga两个分布式事务模式,主要验证秒杀抢购、扣减库存、创建订单、扣减库存、创建支付订单数据是否一致。
为了避免库存不足导致订单失败,测试前先设置库存,在swagger页面找到设置产品库存api,填写参数,比方产品id为1、库存为10
{
"productID": 1,
"stock": 10
}
复制代码
测试秒杀抢购api,验证数据是否一致,在swagger页面找到秒杀抢购api,填写参数,比方用户id为1、产品id为1
{
"userID": 1,
"productID": 1,
"amount": 100
}
复制代码
压力测试
这里使用压力测试工具k6对eshop_gw的api网关服务进行压力测试,验证系统在高并发场景下的性能。压测前先设置充足的库存数量,否则会导致订单失败。
压测提交订单 API的场景,使用k6的脚本 submitOrder.js ,运行命令如下:
# 1000个虚拟用户,持续10秒
k6 run --vus 1000 --duration 10s test/k6/submitOrder.js
# 或者,指定虚拟用户数和请求迭代次数,例如1000个虚拟用户共同完成迭代请求100000次
k6 run -u 1000 -i 100000 submit_order.js
复制代码
压测秒杀抢购 API的场景,使用k6的脚本 flashSale.js ,运行命令如下:
# 10000个虚拟用户,持续1秒
k6 run --vus 10000 --duration 1s test/k6/flashSale.js
复制代码
注:压测结果与机器配置、网络情况、数据库配置等因素有关,请根据实际情况进行调解。
总结
这个例子展示了如何快速构建一个高性能的电子商务系统。系统架构分为用户、产品、订单、库存、支付、秒杀抢购等服务,每个服务代码(不含业务逻辑代码)都可以由Sponge生成,使用DTM包管高并发秒杀、订单场景下的数据一致性。通过集成Redis和Kafka,系统还具有高效的缓存和消息队列支持,提高了整体性能和可扩展性。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4