使用sponge+dtm快速搭建一个高性能的电商系统,秒杀抢购和订单架构的设计与实现

本文将展示如何使用 Sponge 框架快速创建一个简易版高性能电商系统,主要实现秒杀抢购和订单功能,并通过分布式事务管理器 DTM 来确保数据一致性。电商系统的架构图如下:

flash-sale-order-cache


这是源码示例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: 36790
DTM-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 statusDriver: 'mysql'Host: '192.168.3.37'User: 'root'Password: '123456'Port: 3306Db: '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 statusDriver: '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-grpc-http-pb

下载代码后,分别解压各个服务代码到eshop目录下。

注:在生成代码页面如果参数开启了大仓库类型,表示创建的服务适合微服务单仓库(mono-repo)模式。


4. 基于mysql表生成CRUD代码

打开sponge的UI页面,切换到菜单Public --> 生成service+handler CRUD代码,填写参数,分别生成user、product、order、stock、coupon、pay服务的CRUD代码,如下图所示:

eshop-service-handler

下载代码后,分别解压CRUD代码,把CRUD代码(api和internal两个目录)移动到对应服务代码中(如果提示proto文件重复,忽略即可)。

注:在生成代码页面如果参数开启了大仓库类型,表示创建的服务适合微服务单仓库(mono-repo)模式。


5. 基于protobuf生成api网关服务代码

打开sponge的UI页面,切换到菜单Protobuf --> 创建grpc网关服务,填写参数,生成eshop_gw的api网关服务代码,如下图所示:

eshop-grpc-gw-pb

下载代码后,解压服务代码到eshop目录下。

为了让eshop_gw服务可以连接各个服务,需要生成连接代码。打开sponge的UI页面,切换到菜单Public --> 生成grpc连接代码,填写参数,生成eshop_gw的连接各个grpc代码,如下图所示:

eshop-grpc-conn

下载代码后,解压代码,把连接代码(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, gRPC3008030082
productHTTP, gRPC3018030182
orderHTTP, gRPC3028030282
stockHTTP, gRPC3038030382
couponHTTP, gRPC3048030482
payHTTP, gRPC3058030582
flashSaleHTTP, 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,如下图所示:

eshop-gw-swagger


测试提交订单 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网关服务进行压力测试,验证系统在高并发场景下的性能。压测前先设置足够的库存数量,否则会导致订单失败。

  1. 压测提交订单 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
    
  2. 压测秒杀抢购 API的场景,使用k6的脚本 flashSale.js ,运行命令如下:

    # 10000个虚拟用户,持续1秒
    k6 run --vus 10000 --duration 1s test/k6/flashSale.js
    

注:压测结果与机器配置、网络环境、数据库配置等因素有关,请根据实际情况进行调整。


总结

这个例子展示了如何快速构建一个高性能的电子商务系统。系统架构分为用户、产品、订单、库存、支付、秒杀抢购等服务,每个服务代码(不含业务逻辑代码)都可以由Sponge生成,使用DTM保证高并发秒杀、订单场景下的数据一致性。通过集成Redis和Kafka,系统还具有高效的缓存和消息队列支持,提高了整体性能和可扩展性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1557904.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

前端反接保护:实用方案解析与探讨

前端反接保护通常采用肖特基二极管方案或PMOS/NMOS方案&#xff0c;本文另外介绍一种理想二极管方案。 1、肖特基二极管方案 由于肖特基二极管具有正向导通电压&#xff0c;只能用于小电流场合&#xff0c;甚至于直接使用普通的整流二极管。比如1A电流&#xff0c;设D1的正向…

【含文档】基于Springboot+Android的环境保护生活App(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

网络编程(15)——服务器如何主动退出

十五、day15 服务器主动退出一直是服务器设计必须考虑的一个方向&#xff0c;旨在能通过捕获信号使服务器安全退出。我们可以通过asio提供的信号机制绑定回调函数即可实现优雅退出。 之前服务器的主函数如下 #include "CSession.h" #include "CServer.h"…

电影《749局》路演 苗苗演绎超能力少女分享幕后故事

近日&#xff0c;国庆档科幻电影《749局》正在热映中&#xff0c;各主创们以及导演正在积极路演中&#xff0c;截至目前&#xff0c;主演苗苗已到过宁波、杭州、武汉、长沙等城市&#xff0c;在现场与观众热情互动&#xff0c;讲述电影拍摄背后的故事与感受。根据猫眼专业版数据…

Word转PDF的转换方法有哪些?这7个效率技巧,不知道就亏大了!

Word转PDF怎么转&#xff1f;我们在日常工作生活中&#xff0c;经常会用到word文档。如果是编写报告、做会议记录、制定文案等内容&#xff0c;一般都会选择创建word文档。但是如果需要发送给同事、客户或合作伙伴协作时&#xff0c;pdf格式会更加方便。 那么如何将word转为pdf…

Chapter06

6.3.1 &#xff08;1&#xff09;打印如下图案 #include <stdio.h> int main() {int i, j;int n 5; // 定义图案的行数 for (i 1; i < n; i) {// 打印前导空格 for (j 1; j < n - i; j) {printf(" ");}// 打印数字 for (j 1; j < i; j) {p…

永磁同步电机环路反步法(backstepping)控制

文章目录 1、反步控制原理1.1 李雅普诺夫稳定性定理1.2 严格反馈系统1.3 一般设计流程 2、永磁同步电机反步控制2.1 反步控制器设计2.2 反步控制仿真 参考 写在前面&#xff1a;本人能力、时间、技术有限&#xff0c;没有对一些细节进行深入研究和分析&#xff0c;也难免有不足…

【Canvas与艺术】古典绿墙象牙白框红棱六边形窗格

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>古典六边形窗格Draft1</title><style type"text/css&q…

YOLOv10改进策略【注意力机制篇】| CVPR2024 CAA上下文锚点注意力机制

一、本文介绍 本文记录的是基于CAA注意力模块的YOLOv10目标检测改进方法研究。在远程遥感图像或其他大尺度变化的图像中目标检测任务中&#xff0c;为准确提取其长距离上下文信息&#xff0c;需要解决大目标尺度变化和多样上下文信息时的不足的问题。CAA能够有效捕捉长距离依赖…

嵌入式 c 内存堆栈增长方向往低地址方向好处

如下是堆和栈内存空间使用方式有如下好处&#xff1a; 1、stack从高地址向低地址扩展&#xff0c;这样栈空间的起始位置就能确定下来&#xff1b;如果反向&#xff0c;则要考虑这个起点从哪里合适&#xff0c;要确定堆的大小。 2、可以共用中间部分区域空间&#xff0c;最大化…

高速电路中电源设计问题

DCDC芯片都有一个开关频率&#xff0c;选型的时候注意一点这个问题。 纹波&#xff1a;纹波是电源波动中的低频部分&#xff0c;一般处于5Mhz以内的频段&#xff0c;铲子来自MOS的开关动作。 噪声&#xff1a;噪声值电源波动的高频部分&#xff0c;一般高于5Mhz,成分比较复杂…

UE5运行时动态加载场景角色动画任意搭配-角色及动画(一)

通过《MMD模型及动作一键完美导入UE5》系列文章,我们可以把外部场景、角色、动画资产导入UE5,接下来我们将实现运行时动态加载这些资产,并任意组合搭配。 1、骨骼动画复用 1、大部分模型骨骼是不通用的,比如这些裙子也是有骨骼的,属于模型特有的,但是对于动画来说,很多…

OmniCorpus数据集:最大(百亿级别)多模态数据集

2024-06-12 &#xff0c;由上海人工智能实验室、哈尔滨工业大学、南京大学、复旦大学等联合创建OmniCorpus&#xff0c;一个达到百亿级别的图文交错数据集。它不仅规模空前&#xff0c;更以其多元化的数据来源和高质量的数据内容&#xff0c;为多模态大语言模型的研究提供了坚实…

Axure大屏可视化模板在多领域实践应用案例分析

Axure大屏可视化模板&#xff0c;凭借其强大的功能性和灵活性&#xff0c;在众多领域中发挥着举足轻重的作用。本文将详细探讨Axure大屏可视化模板在农业、园区管理、智慧城市、企业数据可视化和医疗领域的应用案例&#xff0c;展示其如何助力各行业实现智能化管理和决策优化。…

Mythical Beings:Web3游戏如何平衡创造内容、关注度与实现盈利的不可能三角

Web3游戏自其诞生以来&#xff0c;以去中心化和独特的代币经济体系迅速引起关注。然而&#xff0c;如何在创造内容、吸引用户和实现盈利之间达到平衡&#xff0c;始终是Web3游戏面临的核心挑战。Mythical Beings作为一款Web3卡牌游戏&#xff0c;通过创新设计和独特机制&#x…

【LeetCode: 1436. 旅行终点站 | 哈希表】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

面试题:Redis(一)

1. redis是单线程还是多线程&#xff1f; 2. IO多路复用听说过么&#xff1f; 3. Redis为什么快&#xff1f; 1. Redis是单线程还是多线程&#xff1f; 版本不同&#xff0c;Redis基于的架构也不同&#xff0c;所以单单问是单还是多线程并不严谨 3.x 之前 redis都是单线程 4.x …

微知-如何临时设置Linux系统时间?(date -s “2024-10-08 22:55:00“, time, hwclock, timedatectl)

背景 在tar解压包的时候经常出现时间不对&#xff0c;可以临时用date命令修改一下&#xff0c;也可以其他&#xff0c;本文主要介绍临时修改的方法 date命令修改 sudo date -s "2024-10-08 22:55:00"其他查看和修改的命令 本文只记录查看方式&#xff0c;修改的暂…

【java数据结构】ArrayList实例

【java数据结构】ArrayList实例 一、杨辉三角二、打扑克 一、杨辉三角 已知条件&#xff1a;给定行数的大小 思路&#xff1a;首先定义一个二维列表&#xff08;也可以称为集合&#xff09;&#xff0c;我们对每一列处理完&#xff0c;最后把每一列加起来&#xff0c;不就是完整…

某象异形滑块99%准确率方案

注意,本文只提供学习的思路,严禁违反法律以及破坏信息系统等行为,本文只提供思路 如有侵犯,请联系作者下架 该文章模型已经上线ocr识别网站,欢迎测试!!,地址:http://yxlocr.nat300.top/ocr/slider/6 所谓的顶象异形滑块,是指没有采用常规的缺口,使用各种形状的缺口…