」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 透過sponge+dtm快速輕鬆實現高性能的電商系統

透過sponge+dtm快速輕鬆實現高性能的電商系統

發佈於2024-11-07
瀏覽:729

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]刪除
最新教學 更多>
  • 解決Spring Security 4.1及以上版本CORS問題指南
    解決Spring Security 4.1及以上版本CORS問題指南
    彈簧安全性cors filter:故障排除常見問題 在將Spring Security集成到現有項目中時,您可能會遇到與CORS相關的錯誤,如果像“訪問Control-allo-allow-Origin”之類的標頭,則無法設置在響應中。為了解決此問題,您可以實現自定義過濾器,例如代碼段中的MyFi...
    程式設計 發佈於2025-05-22
  • 為什麼PHP的DateTime :: Modify('+1個月')會產生意外的結果?
    為什麼PHP的DateTime :: Modify('+1個月')會產生意外的結果?
    使用php dateTime修改月份:發現預期的行為在使用PHP的DateTime類時,添加或減去幾個月可能並不總是會產生預期的結果。正如文檔所警告的那樣,“當心”這些操作的“不像看起來那樣直觀。 考慮文檔中給出的示例:這是內部發生的事情: 現在在3月3日添加另一個月,因為2月在2001年只有2...
    程式設計 發佈於2025-05-22
  • C++中如何將獨占指針作為函數或構造函數參數傳遞?
    C++中如何將獨占指針作為函數或構造函數參數傳遞?
    在構造函數和函數中將唯一的指數管理為參數 unique pointers( unique_ptr [2啟示。通過值: base(std :: simelor_ptr n) :next(std :: move(n)){} 此方法將唯一指針的所有權轉移到函數/對象。指針的內容被移至功能中,在操作...
    程式設計 發佈於2025-05-22
  • Go語言如何動態發現導出包類型?
    Go語言如何動態發現導出包類型?
    與反射軟件包中的有限類型的發現能力相反,本文探索了替代方法,探索了在Runruntime。 go import( “ FMT” “去/進口商” ) func main(){ pkg,err:= incorter.default()。導入(“ time”) 如果er...
    程式設計 發佈於2025-05-22
  • 左連接為何在右表WHERE子句過濾時像內連接?
    左連接為何在右表WHERE子句過濾時像內連接?
    左JOIN CONUNDRUM:WITCHING小時在數據庫Wizard的領域中變成內在的加入很有趣,當將c.foobar條件放置在上面的Where子句中時,據說左聯接似乎會轉換為內部連接。僅當滿足A.Foo和C.Foobar標準時,才會返回結果。 為什麼要變形?關鍵在於其中的子句。當左聯接的右側...
    程式設計 發佈於2025-05-22
  • 如何在JavaScript對像中動態設置鍵?
    如何在JavaScript對像中動態設置鍵?
    在嘗試為JavaScript對象創建動態鍵時,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正確的方法採用方括號: jsobj ['key''i] ='example'1; 在JavaScript中,數組是一...
    程式設計 發佈於2025-05-22
  • 如何為PostgreSQL中的每個唯一標識符有效地檢索最後一行?
    如何為PostgreSQL中的每個唯一標識符有效地檢索最後一行?
    postgresql:為每個唯一標識符在postgresql中提取最後一行,您可能需要遇到與數據集合中每個不同標識的信息相關的信息。考慮以下數據:[ 1 2014-02-01 kjkj 在數據集中的每個唯一ID中檢索最後一行的信息,您可以在操作員上使用Postgres的有效效率: id dat...
    程式設計 發佈於2025-05-22
  • 在細胞編輯後,如何維護自定義的JTable細胞渲染?
    在細胞編輯後,如何維護自定義的JTable細胞渲染?
    在JTable中維護jtable單元格渲染後,在JTable中,在JTable中實現自定義單元格渲染和編輯功能可以增強用戶體驗。但是,至關重要的是要確保即使在編輯操作後也保留所需的格式。 在設置用於格式化“價格”列的“價格”列,用戶遇到的數字格式丟失的“價格”列的“價格”之後,問題在設置自定義單元...
    程式設計 發佈於2025-05-22
  • 在Ubuntu/linux上安裝mysql-python時,如何修復\“ mysql_config \”錯誤?
    在Ubuntu/linux上安裝mysql-python時,如何修復\“ mysql_config \”錯誤?
    mysql-python安裝錯誤:“ mysql_config找不到”“ 由於缺少MySQL開發庫而出現此錯誤。解決此問題,建議在Ubuntu上使用該分發的存儲庫。使用以下命令安裝Python-MysqldB: sudo apt-get安裝python-mysqldb sudo pip in...
    程式設計 發佈於2025-05-22
  • 編譯器報錯“usr/bin/ld: cannot find -l”解決方法
    編譯器報錯“usr/bin/ld: cannot find -l”解決方法
    錯誤:“ usr/bin/ld:找不到-l “ 此錯誤表明鏈接器在鏈接您的可執行文件時無法找到指定的庫。為了解決此問題,我們將深入研究如何指定庫路徑並將鏈接引導到正確位置的詳細信息。 添加庫搜索路徑的一個可能的原因是,此錯誤是您的makefile中缺少庫搜索路徑。要解決它,您可以在鏈接器命令中添...
    程式設計 發佈於2025-05-22
  • 如何使用組在MySQL中旋轉數據?
    如何使用組在MySQL中旋轉數據?
    在關係數據庫中使用mySQL組使用mySQL組進行查詢結果,在關係數據庫中使用MySQL組,轉移數據的數據是指重新排列的行和列的重排以增強數據可視化。在這裡,我們面對一個共同的挑戰:使用組的組將數據從基於行的基於列的轉換為基於列。 Let's consider the following ...
    程式設計 發佈於2025-05-22
  • 如何使用Python的請求和假用戶代理繞過網站塊?
    如何使用Python的請求和假用戶代理繞過網站塊?
    如何使用Python的請求模擬瀏覽器行為,以及偽造的用戶代理提供了一個用戶 - 代理標頭一個有效方法是提供有效的用戶式header,以提供有效的用戶 - 設置,該標題可以通過browser和Acterner Systems the equestersystermery和操作系統。通過模仿像Chro...
    程式設計 發佈於2025-05-22
  • eval()vs. ast.literal_eval():對於用戶輸入,哪個Python函數更安全?
    eval()vs. ast.literal_eval():對於用戶輸入,哪個Python函數更安全?
    稱量()和ast.literal_eval()中的Python Security 在使用用戶輸入時,必須優先確保安全性。強大的Python功能Eval()通常是作為潛在解決方案而出現的,但擔心其潛在風險。 This article delves into the differences betwee...
    程式設計 發佈於2025-05-22
  • 如何在Java字符串中有效替換多個子字符串?
    如何在Java字符串中有效替換多個子字符串?
    在java 中有效地替換多個substring,需要在需要替換一個字符串中的多個substring的情況下,很容易求助於重複應用字符串的刺激力量。但是,對於大字符串或使用許多字符串時,這可能是降低的。 利用正則表達式Example UsageConsider a scenario where ...
    程式設計 發佈於2025-05-22

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3