การขยาย Django Project ไปสู่โครงสร้าง Stateless Modular Monolith ที่รองรับ Horizontal Scaling

This commit is contained in:
Flook 2025-10-27 05:03:48 +07:00
parent da0dfc555d
commit a2ac8d177d
9 changed files with 96 additions and 3 deletions

8
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

9
.idea/cremation-monorepo.iml generated Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/misc.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="temurin-21 (2)" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/cremation-monorepo.iml" filepath="$PROJECT_DIR$/.idea/cremation-monorepo.iml" />
</modules>
</component>
</project>

7
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/mobile" vcs="Git" />
</component>
</project>

View File

@ -3,10 +3,12 @@
## ภาพรวม ## ภาพรวม
โปรเจกต์นี้เป็น Monorepo แบบ Full-Stack ที่มีโครงสร้างพร้อมใช้งานสำหรับการพัฒนาและทดสอบ: โปรเจกต์นี้เป็น Monorepo แบบ Full-Stack ที่มีโครงสร้างพร้อมใช้งานสำหรับการพัฒนาและทดสอบ:
1. **Backend (Django/DRF):** โครงสร้าง Modular Monolith พร้อมระบบ Authentication ด้วย Djoser/JWT 1. **Backend (Django/DRF):** โครงสร้าง Modular Monolith พร้อมระบบ Authentication ด้วย Djoser/JWT รวมถึง Stateless โดยสมบูรณ์ เนื่องจาก Session/Cache ถูกย้ายไปเก็บที่ Redis
2. **ฐานข้อมูล (HA):** CockroachDB Cluster 3 Node (เข้ากันได้กับ PostgreSQL) 2. **ฐานข้อมูล (HA):** CockroachDB Cluster 3 Node (เข้ากันได้กับ PostgreSQL)
3. **Frontend (Web):** React + Vite + Tailwind CSS / DaisyUI และ Mobile ผ่าน Expo 3. **Frontend (Web):** React + Vite + Tailwind CSS / DaisyUI และ Mobile ผ่าน Expo
4. **Automation:** Docker Compose พร้อมตั้งค่า Database อัตโนมัติเมื่อเริ่มต้น 4. **Automation:** Docker Compose พร้อมตั้งค่า Database อัตโนมัติเมื่อเริ่มต้น
5. **Caching/Broker:** Redis สำหรับการเก็บ Session/Cache และใช้เป็น Message Broker ให้ Celery
6. **Async Processing:** Celery Worker สำหรับจัดการ Asynchronous Tasks (งานเบื้องหลัง เช่น การส่งอีเมล, การสร้างรายงาน)
## การเริ่มต้นใช้งาน (Run Local) ## การเริ่มต้นใช้งาน (Run Local)

View File

@ -28,7 +28,6 @@ DEBUG = True
ALLOWED_HOSTS = [] ALLOWED_HOSTS = []
# Application definition # Application definition
DJANGO_APPS = [ DJANGO_APPS = [
@ -191,3 +190,32 @@ DJOSER = {
'user_create': ['rest_framework.permissions.AllowAny'], 'user_create': ['rest_framework.permissions.AllowAny'],
} }
} }
# 1. ตั้งค่า Redis Cache
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
# 'redis' คือ Hostname ของ Service ใน Docker Compose
"LOCATION": "redis://redis:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"IGNORE_EXCEPTIONS": True # ป้องกันการ Crash ถ้า Redis ล่ม
}
}
}
# 2. บังคับให้ Django ใช้ Cache (Redis) ในการเก็บ Session
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
# 3. ใช้ Redis สำหรับเก็บ Token Cache (สำหรับ DRF/JWT ถ้าจำเป็น)
# CACHE_MIDDLEWARE_SECONDS = 60 * 5 # 5 นาที
# CACHE_MIDDLEWARE_KEY_PREFIX = 'auth_cache'
# CELERY CONFIGURATION
CELERY_BROKER_URL = 'redis://redis:6379/0' # ใช้ Redis เป็น Broker
CELERY_RESULT_BACKEND = 'redis://redis:6379/0' # ใช้ Redis ในการเก็บผลลัพธ์ของ Task
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Asia/Bangkok'

View File

@ -7,3 +7,6 @@ psycopg[binary]
typing_extensions typing_extensions
djoser # สำหรับ endpoints: /users/ (Register), /token/login (Login), /password/reset djoser # สำหรับ endpoints: /users/ (Register), /token/login (Login), /password/reset
djangorestframework-simplejwt # สำหรับสร้าง JWT (JSON Web Tokens) djangorestframework-simplejwt # สำหรับสร้าง JWT (JSON Web Tokens)
django-redis # สำหรับเชื่อมต่อ Django กับ Redis
redis # ไคลเอนต์ Python สำหรับ Redis
celery # ตัว Worker

View File

@ -44,6 +44,27 @@ services:
# ตั้งค่าให้ Container ตายหลังจากรัน init เสร็จ (ไม่รันซ้ำ) # ตั้งค่าให้ Container ตายหลังจากรัน init เสร็จ (ไม่รันซ้ำ)
restart: "no" restart: "no"
# Redis Service
redis:
image: redis:7-alpine
container_name: redis
ports:
- "6379:6379"
restart: always
# Celery Worker Service
celery_worker:
build:
context: ../backend
dockerfile: Dockerfile
container_name: celery_worker
volumes:
- ../backend:/app
command: celery -A cremation_backend worker -l info # รัน worker process
depends_on:
- redis # Worker ต้องรอให้ Redis พร้อม
- cockroach-1 # Worker อาจจะต้องเข้าถึง DB ด้วย
# Backend/API (DRF) # Backend/API (DRF)
backend: backend:
build: build:
@ -58,6 +79,7 @@ services:
- cockroach-1 - cockroach-1
- cockroach-2 - cockroach-2
- cockroach-3 - cockroach-3
- redis
environment: environment:
DB_HOST: cockroach-1 DB_HOST: cockroach-1
DB_PORT: 26257 DB_PORT: 26257