”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 通过sponge+dtm快速轻松实现高性能的电商系统

通过sponge+dtm快速轻松实现高性能的电商系统

发布于2024-11-07
浏览:637

This article demonstrates how to use the Sponge framework to quickly build a simplified high-performance e-commerce system, implementing flash sale and order functionality, while ensuring data consistency through the Distributed Transaction Manager (DTM). The architecture of the e-commerce system is shown below:

Quickly and easily implement a high-performance e-commerce system by sponge dtm

This is the source code example eshop, directory includes two identical code examples, but the code structure is slightly different, mainly to show that sponge supports the creation of microservices projects with different repository patterns, example-1-multi-repo is suitable for microservices multi-repo (multi-repo), example-2-mono-repo is suitable for microservices single repository (mono-repo).

Environment Setup

To build this e-commerce system, you need the following tools and dependencies:

  • Sponge: A tool for rapidly generating service and module code for different systems. Follow the Sponge installation guide for more information.

Additionally, the following services are required:

  • DTM: A distributed transaction manager for ensuring data consistency across multiple service calls.
  • Redis: Used in conjunction with DTM to handle flash sale caching.
  • Kafka: A message queue system for asynchronous order processing.
  • MySQL: Database for storing service data.

All services will be running on a virtual machine with the IP address 192.168.3.37.

Launching DTM Services

DTM is a core component of this system, responsible for managing distributed transactions in the flash sale and order processes. Two DTM service instances are required—one for MySQL and one for Redis storage.

You can download DTM from the following link: https://github.com/dtm-labs/dtm/releases/tag/v1.18.0

Service Name Port Configuration
DTM-MySQL HTTP: 36789, gRPC: 36790
DTM-Redis HTTP: 35789, gRPC: 35790

1. Launching DTM-MySQL Service

  • Import the required table structure into MySQL:

    • dtmcli.barrier.mysql.sql
    • dtmsvr.storage.mysql.sql
  • Modify the DTM configuration file (Sample Configuration):

   Store: # specify which engine to store trans status
     Driver: 'mysql'
     Host: '192.168.3.37'
     User: 'root'
     Password: '123456'
     Port: 3306
     Db: 'dtm'
  • Start the DTM service:
   ./dtm -c conf.yml

2. Launching DTM-Redis Service

  • Modify the DTM configuration file (Sample Configuration):
   Store: # specify which engine to store trans status
       Driver: 'redis'
       Host: '192.168.3.37'
       User: 'default'
       Password: '123456'
       Port: 6379
  • Start the DTM service:
   ./dtm -c conf.yml

Rapid Development of an E-Commerce System Using Sponge

The simplified e-commerce system consists of the following eight microservices:

  • eshop_gw: API gateway service
  • user: User service
  • product: Product service
  • order: Order service
  • stock: Stock service
  • coupon: Coupon service
  • pay: Payment service
  • flashSale: Flash sale service

1. Prepare MySQL Databases and Tables for Each Service

Import the corresponding database tables for each service into MySQL:

  • User service schema
  • Product service schema
  • Order service schema
  • Stock service schema
  • Coupon service schema
  • Payment service schema

2. Prepare Protobuf Files for Each Service

These protobuf files allow Sponge to quickly create services:

  • User service protobuf
  • Product service protobuf
  • Order service protobuf
  • Stock service protobuf
  • Coupon service protobuf
  • Payment service protobuf
  • Flash sale service protobuf
  • API Gateway protobuf

3. Generate gRPC HTTP Hybrid Service Code Based on Protobuf

Open the sponge UI page, switch to the menu Protobuf --> Create grpc http service, fill in the parameters, and generate 7 hybrid service codes that support both grpc and http: user, product, order, stock, coupon, pay, flashSale, as shown below:

Quickly and easily implement a high-performance e-commerce system by sponge dtm

After downloading the code, unzip each service code into the eshop directory.

Note: If the large repository option is enabled on the code generation page, it means that the created service is suitable for a microservice mono-repo mode.

4. Generate CRUD Code Based on MySQL Tables

Open the sponge UI page, switch to the menu Public --> Generate service handler CRUD code, fill in the parameters, and generate CRUD codes for the user, product, order, stock, coupon, and pay services, as shown below:

Quickly and easily implement a high-performance e-commerce system by sponge dtm

After downloading the code, unzip the CRUD code and move the CRUD code (the api and internal directories) into the corresponding service code (if prompted with duplicate proto files, just ignore it).

Note: If the large repository option is enabled on the code generation page, it means that the created service is suitable for a microservice mono-repo mode.

5. Generate API Gateway Service Code Based on Protobuf

Open the sponge UI page, switch to the menu Protobuf --> Create grpc gateway service, fill in the parameters, and generate the API gateway service code for eshop_gw, as shown below:

Quickly and easily implement a high-performance e-commerce system by sponge dtm

After downloading the code, unzip the service code into the eshop directory.

To allow the eshop_gw service to connect to the various services, you need to generate the connection code. Open the sponge UI page, switch to the menu Public --> Generate grpc connection code, fill in the parameters, and generate the connection code for eshop_gw to connect to various grpc services, as shown below:

Quickly and easily implement a high-performance e-commerce system by sponge dtm

After downloading the code, unzip it, and move the connection code (the internal directory) into the eshop_gw service code.

Note: If the large repository option is enabled on the code generation page, it means that the created service is suitable for a microservice mono-repo mode.

6. Write Business Logic Code

At this point, the service framework is basically set up. Next, write the actual business logic code in the internal/service directory of each service.

7. Start the Services

Before starting the services, modify the configuration files of each service, including the port numbers, database connections, etc. The default HTTP port for each service is 8080, and the grpc port is 8282. Since they are running locally on the same machine (local test IP is 192.168.3.90), to avoid port conflicts, the ports of each service have been modified (ports can be found and modified in the configs/xxx.yml directory and api/xxx/v1/xxx.proto). Below are the modified ports:

Service Protocol HTTP Port gRPC Port
eshop_gw HTTP 8080 -
user HTTP, gRPC 30080 30082
product HTTP, gRPC 30180 30182
order HTTP, gRPC 30280 30282
stock HTTP, gRPC 30380 30382
coupon HTTP, gRPC 30480 30482
pay HTTP, gRPC 30580 30582
flashSale HTTP, gRPC 30680 30682

Note: If running in containers or on different machines, you don’t need to modify the default ports, just change the mapped ports.

Testing and Verification

Single Service Testing

After all services have successfully started, verify that each service is functioning properly by testing the APIs of the following 7 services: user, product, order, stock, coupon, pay, and flashSale.

Open your browser and navigate to http://localhost:/apis/swagger/index.html to check if the APIs of each service are working correctly. Besides testing the APIs on the Swagger page, you can also run gRPC API tests by filling in parameters in the internal/service/xxx_client_test.go file under each service.

Integration Testing

Once individual services pass the tests, use the API gateway service of eshop_gw to test the entire system. In your browser, visit the Swagger page of the API gateway service at http://localhost:8080/apis/swagger/index.html, as shown in the figure below:

Quickly and easily implement a high-performance e-commerce system by sponge dtm

Testing the Submit Order API

  • The submit order process uses DTM's distributed transaction model saga, mainly to verify the consistency of creating orders, deducting stock, creating payment orders, and coupon data.

  • To avoid order failure due to insufficient stock, set the stock before testing. In the Swagger page, find the API for setting product stock, and fill in the parameters. For example, set product ID to 1 and stock to 10:

   {
     "productID": 1,
     "stock": 10
   }
  • Test the submit order API by requesting both the non-buffered queue and buffered queue APIs. In the Swagger page, find the respective API and fill in the parameters, such as user ID = 1, product ID = 1, product quantity = 1, and order amount = 100:
   {
     "userID": 1,
     "productID": 1,
     "productCount": 1,
     "amount": 100,
     "couponID": 0
   }

Note: If couponID is not set to 0, it means a coupon will be used. If the coupon is invalid or expired, the order will fail. To ensure the order succeeds, find the API for creating a new coupon on the Swagger page, create a new coupon, get the coupon ID, and fill it into the couponID field of the submit order API.

Testing the Flash Sale API

  • The flash sale process uses Kafka's message queue, DTM Redis's two-phase message, and DTM MySQL's saga distributed transaction models to verify consistency in flash sales, stock deduction, order creation, and payment order creation.

  • To avoid order failure due to insufficient stock, set the stock before testing. In the Swagger page, find the API for setting product stock and fill in the parameters. For example, set product ID to 1 and stock to 10:

   {
     "productID": 1,
     "stock": 10
   }
  • Test the flash sale API to verify data consistency. In the Swagger page, find the flash sale API and fill in the parameters, such as user ID = 1 and product ID = 1:
   {
     "userID": 1,
     "productID": 1,
     "amount": 100
   }

Stress Testing

To perform stress testing on the eshop_gw API gateway service and verify the system's performance under high concurrency, use the stress testing tool k6. Before conducting the stress test, ensure that enough stock is set to avoid order failure.

  1. For stress testing the Submit Order API scenario, use the k6 script submitOrder.js and run the following command:

    # 1000 virtual users, running for 10 seconds
    k6 run --vus 1000 --duration 10s test/k6/submitOrder.js
    
    # Alternatively, specify the number of virtual users and the number of request iterations, for example, 1000 virtual users performing 100,000 request iterations
    k6 run -u 1000 -i 100000 submit_order.js
    
  2. For stress testing the Flash Sale API scenario, use the k6 script flashSale.js and run the following command:

   # 10,000 virtual users, running for 1 second
   k6 run --vus 10000 --duration 1s test/k6/flashSale.js

Note: The results of stress testing depend on factors such as machine configuration, network environment, and database setup. Adjust accordingly based on actual conditions.

Summary

This example shows how to quickly build a high-performance e-commerce system. The system architecture is divided into user, product, order, inventory, payment, flash sale and other services, each service code (excluding business logic code) can be generated by Sponge, using DTM to ensure data consistency under high concurrency flash sale, order scenarios. By integrating Redis and Kafka, the system also has efficient caching and message queuing support, improving overall performance and scalability.

版本声明 本文转载于:https://dev.to/zhufuyi/quickly-and-easily-implement-a-high-performance-e-commerce-system-by-spongedtm-3ol6?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 为什么使用Firefox后退按钮时JavaScript执行停止?
    为什么使用Firefox后退按钮时JavaScript执行停止?
    导航历史记录问题:JavaScript使用Firefox Back Back 此行为是由浏览器缓存JavaScript资源引起的。要解决此问题并确保在后续页面访问中执行脚本,Firefox用户应设置一个空功能。 警报'); }; alert('inline Alert')...
    编程 发布于2025-07-01
  • 如何检查对象是否具有Python中的特定属性?
    如何检查对象是否具有Python中的特定属性?
    方法来确定对象属性存在寻求一种方法来验证对象中特定属性的存在。考虑以下示例,其中尝试访问不确定属性会引起错误: >>> a = someClass() >>> A.property Trackback(最近的最新电话): 文件“ ”,第1行, AttributeError: SomeClass...
    编程 发布于2025-07-01
  • 如何使用Python有效地以相反顺序读取大型文件?
    如何使用Python有效地以相反顺序读取大型文件?
    在python 中,如果您使用一个大文件,并且需要从最后一行读取其内容,则在第一行到第一行,Python的内置功能可能不合适。这是解决此任务的有效解决方案:反向行读取器生成器 == ord('\ n'): 缓冲区=缓冲区[:-1] ...
    编程 发布于2025-07-01
  • Java数组中元素位置查找技巧
    Java数组中元素位置查找技巧
    在Java数组中检索元素的位置 利用Java的反射API将数组转换为列表中,允许您使用indexof方法。 (primitives)(链接到Mishax的解决方案) 用于排序阵列的数组此方法此方法返回元素的索引,如果发现了元素的索引,或一个负值,指示应放置元素的插入点。
    编程 发布于2025-07-01
  • Java中假唤醒真的会发生吗?
    Java中假唤醒真的会发生吗?
    在Java中的浪费唤醒:真实性或神话?在Java同步中伪装唤醒的概念已经是讨论的主题。尽管存在这种行为的潜力,但问题仍然存在:它们实际上是在实践中发生的吗? Linux的唤醒机制根据Wikipedia关于伪造唤醒的文章,linux实现了pthread_cond_wait()功能的Linux实现,利用...
    编程 发布于2025-07-01
  • Android如何向PHP服务器发送POST数据?
    Android如何向PHP服务器发送POST数据?
    在android apache httpclient(已弃用) httpclient httpclient = new defaulthttpclient(); httppost httppost = new httppost(“ http://www.yoursite.com/script.p...
    编程 发布于2025-07-01
  • JavaScript计算两个日期之间天数的方法
    JavaScript计算两个日期之间天数的方法
    How to Calculate the Difference Between Dates in JavascriptAs you attempt to determine the difference between two dates in Javascript, consider this s...
    编程 发布于2025-07-01
  • 如何使用Java.net.urlConnection和Multipart/form-data编码使用其他参数上传文件?
    如何使用Java.net.urlConnection和Multipart/form-data编码使用其他参数上传文件?
    使用http request 上传文件上传到http server,同时也提交其他参数,java.net.net.urlconnection and Multipart/form-data Encoding是普遍的。 Here's a breakdown of the process:Mu...
    编程 发布于2025-07-01
  • eval()vs. ast.literal_eval():对于用户输入,哪个Python函数更安全?
    eval()vs. ast.literal_eval():对于用户输入,哪个Python函数更安全?
    称量()和ast.literal_eval()中的Python Security 在使用用户输入时,必须优先确保安全性。强大的Python功能Eval()通常是作为潜在解决方案而出现的,但担心其潜在风险。本文深入研究了eval()和ast.literal_eval()之间的差异,突出显示其安全性含义...
    编程 发布于2025-07-01
  • 我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    将我的加密库从mcrypt升级到openssl 问题:是否可以将我的加密库从McRypt升级到OpenSSL?如果是这样,如何?答案:是的,可以将您的Encryption库从McRypt升级到OpenSSL。可以使用openssl。附加说明: [openssl_decrypt()函数要求iv参...
    编程 发布于2025-07-01
  • 如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    How to Resolve "General error: 2006 MySQL server has gone away" While Inserting RecordsIntroduction:Inserting data into a MySQL database can...
    编程 发布于2025-07-01
  • 图片在Chrome中为何仍有边框?`border: none;`无效解决方案
    图片在Chrome中为何仍有边框?`border: none;`无效解决方案
    在chrome 在使用Chrome and IE9中的图像时遇到的一个频繁的问题是围绕图像的持续薄薄边框,尽管指定了图像,尽管指定了;和“边境:无;”在CSS中。要解决此问题,请考虑以下方法: Chrome具有忽略“ border:none; none;”的已知错误,风格。要解决此问题,请使用以下...
    编程 发布于2025-07-01
  • 找到最大计数时,如何解决mySQL中的“组函数\”错误的“无效使用”?
    找到最大计数时,如何解决mySQL中的“组函数\”错误的“无效使用”?
    如何在mySQL中使用mySql 检索最大计数,您可能会遇到一个问题,您可能会在尝试使用以下命令:理解错误正确找到由名称列分组的值的最大计数,请使用以下修改后的查询: 计数(*)为c 来自EMP1 按名称组 c desc订购 限制1 查询说明 select语句提取名称列和每个名称...
    编程 发布于2025-07-01
  • C++20 Consteval函数中模板参数能否依赖于函数参数?
    C++20 Consteval函数中模板参数能否依赖于函数参数?
    [ consteval函数和模板参数依赖于函数参数在C 17中,模板参数不能依赖一个函数参数,因为编译器仍然需要对非contexexpr futcoriations contim at contexpr function进行评估。 compile time。 C 20引入恒定函数,必须在编译时进行...
    编程 发布于2025-07-01
  • 为什么HTML无法打印页码及解决方案
    为什么HTML无法打印页码及解决方案
    无法在html页面上打印页码? @page规则在@Media内部和外部都无济于事。 HTML:Customization:@page { margin: 10%; @top-center { font-family: sans-serif; font-weight: bo...
    编程 发布于2025-07-01

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3