Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

9 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐ŸŽก LuckDraw- ๆŠฝๅฅ–ๅนณๅฐ

Java Spring Boot Architecture License

ๅŸบไบŽๅ…ญ่พนๅฝขๆžถๆž„็š„ๆŠฝๅฅ–่งฃๅ†ณๆ–นๆกˆ

ๅฟซ้€Ÿๅผ€ๅง‹ ยท ๆžถๆž„่ฎพ่ฎก ยท ๆ ธๅฟƒๅŠŸ่ƒฝ ยท ๆŠ€ๆœฏ้€‰ๅž‹


๐Ÿ“‹ ้กน็›ฎๆฆ‚่ฟฐ

LuckDraw ๆ˜ฏไธ€ไธช้‡‡็”จ**ๅ…ญ่พนๅฝขๆžถๆž„๏ผˆHexagonal Architecture๏ผ‰**ๆž„ๅปบ็š„ๆŠฝๅฅ–ๅนณๅฐใ€‚็ณป็ปŸ้€š่ฟ‡ๆธ…ๆ™ฐ็š„็ซฏๅฃไธŽ้€‚้…ๅ™จ่ฎพ่ฎก๏ผŒๅฎž็Žฐไบ†ๆ ธๅฟƒไธšๅŠก้€ป่พ‘ไธŽๅค–้ƒจไพ่ต–็š„ๅฎŒๅ…จ่งฃ่€ฆ๏ผŒๅ…ทๅค‡ๆž้ซ˜็š„ๅฏๆต‹่ฏ•ๆ€งๅ’Œๅฏ็ปดๆŠคๆ€งใ€‚

โœจ ๆ ธๅฟƒ็‰นๆ€ง

็‰นๆ€ง ๆ่ฟฐ
๐ŸŽฏ ็ตๆดปๆŠฝๅฅ– ๆ”ฏๆŒๅ•ๆฌกๆฆ‚็އใ€ๆ€ปไฝ“ๆฆ‚็އไธค็งๆŠฝๅฅ–ๆจกๅผ
๐Ÿ”„ ็Šถๆ€ๆต่ฝฌ ๅฎŒๆ•ด็š„ๆดปๅŠจ็”Ÿๅ‘ฝๅ‘จๆœŸ็Šถๆ€ๆœบ็ฎก็†
๐Ÿ“ฆ ๅˆ†ๅธƒๅผๆžถๆž„ ๆ”ฏๆŒๅˆ†ๅธƒๅผ้”ใ€ๆถˆๆฏ้˜Ÿๅˆ—ใ€ๆœๅŠกๆณจๅ†Œๅ‘็Žฐ
โšก ้ซ˜ๆ€ง่ƒฝ ้›ช่Šฑ็ฎ—ๆณ•ID็”Ÿๆˆใ€Redis็ผ“ๅญ˜ๅŠ ้€Ÿ
๐Ÿ›ก๏ธ ๅ…ญ่พนๅฝขๆžถๆž„ ๆ ธๅฟƒไธšๅŠกไธŽๅŸบ็ก€่ฎพๆ–ฝๅฎŒๅ…จ่งฃ่€ฆ
๐Ÿ”Œ ๅฏๆ’ๆ‹”่ฎพ่ฎก ็ซฏๅฃไธŽ้€‚้…ๅ™จๆจกๅผ๏ผŒๆ˜“ไบŽๆ›ฟๆขๅฎž็Žฐ

๐Ÿ—๏ธ ๆžถๆž„่ฎพ่ฎก

ๅ…ญ่พนๅฝขๆžถๆž„ๅ›พ

                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚           API Layer                  โ”‚
                    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚
                    โ”‚  โ”‚   REST    โ”‚    โ”‚   Dubbo   โ”‚     โ”‚
                    โ”‚  โ”‚  Facade   โ”‚    โ”‚  Service  โ”‚     โ”‚
                    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                             โ”‚                โ”‚
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚         Core Domain                  โ”‚
                    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
                    โ”‚  โ”‚      Input Ports (API)        โ”‚  โ”‚
                    โ”‚  โ”‚  DrawServicePort              โ”‚  โ”‚
                    โ”‚  โ”‚  CampaignServicePort          โ”‚  โ”‚
                    โ”‚  โ”‚  PrizeServicePort             โ”‚  โ”‚
                    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
                    โ”‚                  โ”‚                   โ”‚
                    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
                    โ”‚  โ”‚      Domain Services          โ”‚  โ”‚
                    โ”‚  โ”‚  DrawServiceImpl              โ”‚  โ”‚
                    โ”‚  โ”‚  CampaignServiceImpl          โ”‚  โ”‚
                    โ”‚  โ”‚  PrizeServiceImpl             โ”‚  โ”‚
                    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
                    โ”‚                  โ”‚                   โ”‚
                    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
                    โ”‚  โ”‚      Output Ports (SPI)       โ”‚  โ”‚
                    โ”‚  โ”‚  CampaignRepositoryPort       โ”‚  โ”‚
                    โ”‚  โ”‚  WinRecordRepositoryPort      โ”‚  โ”‚
                    โ”‚  โ”‚  CacheServicePort             โ”‚  โ”‚
                    โ”‚  โ”‚  MessageQueuePort             โ”‚  โ”‚
                    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                             โ”‚
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚          Adapters Layer               โ”‚
                    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
                    โ”‚  โ”‚   DB    โ”‚ โ”‚  Redis  โ”‚ โ”‚  Kafka  โ”‚ โ”‚
                    โ”‚  โ”‚ Adapter โ”‚ โ”‚ Adapter โ”‚ โ”‚ Adapter โ”‚ โ”‚
                    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ๆจกๅ—่Œ่ดฃ

ๆจกๅ— ่Œ่ดฃ่ฏดๆ˜Ž
prizewheel-shared ๅ…ฑไบซๅธธ้‡ใ€ๆžšไธพใ€ๅทฅๅ…ท็ฑปใ€้€š็”จDTO
prizewheel-core ๆ ธๅฟƒ้ข†ๅŸŸๆจกๅž‹ใ€ไธšๅŠกๆœๅŠกใ€็ซฏๅฃๅฎšไน‰
prizewheel-adapters ๅŸบ็ก€่ฎพๆ–ฝ้€‚้…ๅ™จ๏ผˆๆ•ฐๆฎๅบ“ใ€็ผ“ๅญ˜ใ€ๆถˆๆฏ้˜Ÿๅˆ—๏ผ‰
prizewheel-api ๅฏนๅค–APIๆŽฅๅฃใ€DubboๆœๅŠกใ€ๅฏๅŠจๅ…ฅๅฃ

๐ŸŽฏ ๆ ธๅฟƒๅŠŸ่ƒฝ

1. ๆŠฝๅฅ–ๆœๅŠก

// ๆ‰ง่กŒๆŠฝๅฅ–
WinRecord record = drawService.executeDraw(participantId, campaignId);

// ๆŸฅ่ฏขไธญๅฅ–่ฎฐๅฝ•
WinRecord record = drawService.queryWinRecord(recordId);

2. ๆดปๅŠจ็ฎก็†

// ๅˆ›ๅปบๆดปๅŠจ
Long campaignId = campaignService.createCampaign(campaign);

// ๆ›ดๆ–ฐ็Šถๆ€
campaignService.updateStatus(campaignId, ActivityStatus.RUNNING.getCode());

3. ๅฅ–ๅ“ๅ‘ๆ”พ

// ๅ‘ๆ”พๅฅ–ๅ“
boolean success = prizeService.grantPrize(recordId);

๐Ÿ”ง ๆŠ€ๆœฏ้€‰ๅž‹

ๅˆ†็ฑป ๆŠ€ๆœฏ ็‰ˆๆœฌ ่ฏดๆ˜Ž
ๆ ธๅฟƒๆก†ๆžถ Spring Boot 2.6.0 ๅบ”็”จๆก†ๆžถ
ORMๆก†ๆžถ MyBatis 2.1.4 ๆ•ฐๆฎๆŒไน…ๅŒ–
ๆ•ฐๆฎๅบ“ MySQL 8.0+ ๅ…ณ็ณปๅž‹ๆ•ฐๆฎๅบ“
็ผ“ๅญ˜ Redis + Redisson 3.17.0 ๅˆ†ๅธƒๅผ็ผ“ๅญ˜ไธŽ้”
ๆถˆๆฏ้˜Ÿๅˆ— Kafka 2.8.0 ๅผ‚ๆญฅๆถˆๆฏๅค„็†
RPCๆก†ๆžถ Dubbo 2.7.10 ๅˆ†ๅธƒๅผๆœๅŠก่ฐƒ็”จ
ๆณจๅ†Œไธญๅฟƒ Nacos 2.0+ ๆœๅŠกๆณจๅ†ŒไธŽๅ‘็Žฐ
ไปปๅŠก่ฐƒๅบฆ XXL-Job 2.3.0 ๅˆ†ๅธƒๅผไปปๅŠก่ฐƒๅบฆ

๐Ÿš€ ๅฟซ้€Ÿๅผ€ๅง‹

็Žฏๅขƒ่ฆๆฑ‚

  • JDK 1.8+
  • MySQL 8.0+
  • Redis 6.0+
  • Kafka 2.8+
  • Nacos 2.0+

ๅฎ‰่ฃ…้ƒจ็ฝฒ

# 1. ๅ…‹้š†้กน็›ฎ
git clone 

# 2. ๅˆๅง‹ๅŒ–ๆ•ฐๆฎๅบ“
mysql -u root -p < database/prizewheel.sql

# 3. ไฟฎๆ”น้…็ฝฎ
# ็ผ–่พ‘ prizewheel-api/src/main/resources/application.yml

# 4. ๆž„ๅปบ้กน็›ฎ
mvn clean package -DskipTests

# 5. ๅฏๅŠจๆœๅŠก
java -jar prizewheel-api/target/prizewheel-api-1.0.0-SNAPSHOT.jar

้…็ฝฎ่ฏดๆ˜Ž

# ๆ•ฐๆฎๅบ“้…็ฝฎ
spring:
  datasource:
    url: jdbc:mysql://${DB_HOST:localhost}:3306/prizewheel
    username: ${DB_USER:root}
    password: ${DB_PASS:root}

# Redis้…็ฝฎ
  redis:
    host: ${REDIS_HOST:localhost}
    port: ${REDIS_PORT:6379}
    password: ${REDIS_PASS:}

# Dubbo้…็ฝฎ
dubbo:
  registry:
    address: nacos://${NACOS_HOST:localhost}:8848

๐Ÿ“ ็›ฎๅฝ•็ป“ๆž„

PrizeWheel/
โ”œโ”€โ”€ database/                     # ๆ•ฐๆฎๅบ“่„šๆœฌ
โ”‚   โ””โ”€โ”€ prizewheel.sql           # ๅปบ่กจ่„šๆœฌ
โ”œโ”€โ”€ prizewheel-shared/           # ๅ…ฑไบซๆจกๅ—
โ”‚   โ””โ”€โ”€ src/main/java/io/prizewheel/shared/
โ”‚       โ”œโ”€โ”€ constant/            # ๅธธ้‡ๅฎšไน‰
โ”‚       โ”œโ”€โ”€ model/               # ้€š็”จๆจกๅž‹
โ”‚       โ””โ”€โ”€ util/                # ๅทฅๅ…ท็ฑป
โ”œโ”€โ”€ prizewheel-core/             # ๆ ธๅฟƒ้ข†ๅŸŸๆจกๅ—
โ”‚   โ””โ”€โ”€ src/main/java/io/prizewheel/core/
โ”‚       โ”œโ”€โ”€ domain/              # ้ข†ๅŸŸๅฎžไฝ“
โ”‚       โ”œโ”€โ”€ port/                # ็ซฏๅฃๅฎšไน‰
โ”‚       โ”‚   โ”œโ”€โ”€ input/           # ่พ“ๅ…ฅ็ซฏๅฃ
โ”‚       โ”‚   โ””โ”€โ”€ output/          # ่พ“ๅ‡บ็ซฏๅฃ
โ”‚       โ””โ”€โ”€ service/             # ไธšๅŠกๆœๅŠก
โ”œโ”€โ”€ prizewheel-adapters/         # ้€‚้…ๅ™จๆจกๅ—
โ”‚   โ””โ”€โ”€ src/main/java/io/prizewheel/adapters/
โ”‚       โ”œโ”€โ”€ cache/               # ็ผ“ๅญ˜้€‚้…ๅ™จ
โ”‚       โ”œโ”€โ”€ mq/                  # ๆถˆๆฏ้˜Ÿๅˆ—้€‚้…ๅ™จ
โ”‚       โ””โ”€โ”€ persistence/         # ๆŒไน…ๅŒ–้€‚้…ๅ™จ
โ”‚           โ”œโ”€โ”€ entity/          # POๅฎžไฝ“
โ”‚           โ”œโ”€โ”€ mapper/          # MyBatis Mapper
โ”‚           โ””โ”€โ”€ repository/      # ไป“ๅ‚จๅฎž็Žฐ
โ”œโ”€โ”€ prizewheel-api/              # APIๆจกๅ—
โ”‚   โ””โ”€โ”€ src/main/java/io/prizewheel/api/
โ”‚       โ”œโ”€โ”€ config/              # ้…็ฝฎ็ฑป
โ”‚       โ”œโ”€โ”€ dto/                 # ๆ•ฐๆฎไผ ่พ“ๅฏน่ฑก
โ”‚       โ””โ”€โ”€ facade/              # ๆœๅŠก้—จ้ข
โ””โ”€โ”€ pom.xml                      # ็ˆถPOM

๐Ÿ“Š ๆ€ง่ƒฝๆŒ‡ๆ ‡

ๆŒ‡ๆ ‡ ๆ•ฐๅ€ผ ่ฏดๆ˜Ž
ๆŠฝๅฅ–ๅ“ๅบ”ๆ—ถ้—ด < 30ms ๅ•ๆฌกๆŠฝๅฅ–่€—ๆ—ถ
ๅนถๅ‘ๆ”ฏๆŒ 8000+ QPS ๅ•ๆœบๅนถๅ‘ๅค„็†่ƒฝๅŠ›
ID็”Ÿๆˆ้€Ÿๅบฆ 40w+/s ้›ช่Šฑ็ฎ—ๆณ•ๅ•ๆœบ็”Ÿๆˆ่ƒฝๅŠ›

๐Ÿ“ ๅผ€ๅ‘่ง„่Œƒ

ๅ‘ฝๅ่ง„่Œƒ

็ฑปๅž‹ ่ง„่Œƒ ็คบไพ‹
็ฑปๅ ๅคง้ฉผๅณฐ DrawServiceImpl
ๆ–นๆณ•ๅ ๅฐ้ฉผๅณฐ executeDraw
ๅธธ้‡ ๅ…จๅคงๅ†™ไธ‹ๅˆ’็บฟ MAX_RETRY_COUNT
ๅŒ…ๅ ๅ…จๅฐๅ†™ io.prizewheel.core

ๆžถๆž„่ง„่Œƒ

  • ๆ ธๅฟƒๆจกๅ—(prizewheel-core)ไธไพ่ต–ไปปไฝ•ๅค–้ƒจๆก†ๆžถ
  • ๆ‰€ๆœ‰ๅค–้ƒจไพ่ต–้€š่ฟ‡้€‚้…ๅ™จๆจกๅ—ๅผ•ๅ…ฅ
  • ็ซฏๅฃๅฎšไน‰ไฝฟ็”จๆŽฅๅฃ๏ผŒ้€‚้…ๅ™จๅฎž็ŽฐๆŽฅๅฃ

๐Ÿ“„ ่ฎธๅฏ่ฏ

ๆœฌ้กน็›ฎ้‡‡็”จ MIT ่ฎธๅฏ่ฏใ€‚


โญ ๅฆ‚ๆžœ่ฟ™ไธช้กน็›ฎๅฏนๆ‚จๆœ‰ๅธฎๅŠฉ๏ผŒ่ฏท็ป™ไธ€ไธช Star ๆ”ฏๆŒไธ€ไธ‹๏ผ

About

LuckDraw is a marketing lottery platform with DDD architecture. It uses Fibonacci hashing to achieve O(1) time complexity for draws, supporting multiple strategies, state machine management, rule engine, statistics, points system and templates. The distributed tech stack includes Spring Boot, MyBatis, Redis, Kafka, Dubbo and Nacos.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages