- Enhanced Mermaid diagrams in the troubleshooting and workflow sections with clearer labels and emoji for better readability. - Standardized the formatting of flowchart elements to ensure consistency across documentation. - Improved the overall visual representation to align with recent updates in the English version.
424 lines
13 KiB
Markdown
424 lines
13 KiB
Markdown
# Hướng Dẫn Xử Lý Sự Cố (Troubleshooting)
|
|
|
|
> **Lưu ý**: Hướng dẫn này tập trung vào việc debug GoodGo Microservices Platform trong môi trường phát triển cục bộ (Docker Compose).
|
|
|
|
## Mục lục
|
|
|
|
1. [Chẩn đoán Chung](#chẩn-đoán-chung)
|
|
2. [Vấn đề Infrastructure](#vấn-đề-infrastructure)
|
|
- [Database (Neon/PostgreSQL)](#database-neonpostgresql)
|
|
- [Redis](#redis)
|
|
- [Traefik Gateway](#traefik-gateway)
|
|
3. [Vấn đề Service](#vấn-đề-service)
|
|
- [Service Không Khởi Động](#service-không-khởi-động)
|
|
- [Lỗi Prisma/Database](#lỗi-prismadatabase)
|
|
- [Lỗi Authentication](#lỗi-authentication)
|
|
4. [Công cụ Debug](#công-cụ-debug)
|
|
5. [Câu hỏi Thường Gặp (FAQ)](#câu-hỏi-thường-gặp-faq)
|
|
|
|
---
|
|
|
|
## Chẩn đoán Chung
|
|
|
|
Khi có sự cố, hãy làm theo danh sách kiểm tra sau:
|
|
|
|
1. **Kiểm tra Trạng thái Service**:
|
|
```bash
|
|
cd deployments/local
|
|
docker-compose ps
|
|
```
|
|
*Tất cả services nên ở trạng thái `Up` hoặc `Running`.*
|
|
|
|
2. **Xem Logs**:
|
|
```bash
|
|
# Xem logs của service cụ thể
|
|
docker-compose logs -f <service-name>
|
|
|
|
# Xem 100 dòng cuối của tất cả
|
|
docker-compose logs --tail=100
|
|
```
|
|
|
|
3. **Kiểm tra Kết nối**:
|
|
* Có thể truy cập Gateway không? `curl http://localhost/health`
|
|
* Có thể truy cập Dashboard không? http://localhost:8080
|
|
|
|
### Sơ Đồ Xử Lý Sự Cố
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
Start(["Phát Hiện Sự Cố"]) --> CheckStatus{"Kiểm tra<br/>Trạng thái Service"}
|
|
|
|
CheckStatus -->|"Tất cả Running"| CheckLogs["Xem Logs"]
|
|
CheckStatus -->|"Một số Down"| IdentifyService["Xác định Service<br/>Bị Lỗi"]
|
|
|
|
IdentifyService --> ServiceType{"Loại Service?"}
|
|
|
|
ServiceType -->|"Infrastructure"| InfraCheck["Kiểm tra<br/>Infrastructure"]
|
|
ServiceType -->|"Application"| AppCheck["Kiểm tra<br/>Application"]
|
|
|
|
InfraCheck --> DBCheck{"Database?"}
|
|
InfraCheck --> RedisCheck{"Redis?"}
|
|
InfraCheck --> TraefikCheck{"Traefik?"}
|
|
|
|
DBCheck -->|"Có"| DBSolution["Kiểm tra DATABASE_URL<br/>Verify kết nối Neon<br/>Kiểm tra IP whitelist"]
|
|
RedisCheck -->|"Có"| RedisSolution["Restart Redis<br/>Kiểm tra port mapping<br/>Verify connection string"]
|
|
TraefikCheck -->|"Có"| TraefikSolution["Kiểm tra labels<br/>Verify PathPrefix<br/>Kiểm tra health status"]
|
|
|
|
AppCheck --> ErrorType{"Loại Lỗi?"}
|
|
|
|
ErrorType -->|"Config"| ConfigFix["Kiểm tra .env variables<br/>Chạy init-project.sh"]
|
|
ErrorType -->|"Prisma"| PrismaFix["Kiểm tra migrations<br/>Regenerate client<br/>Reset database"]
|
|
ErrorType -->|"Auth"| AuthFix["Kiểm tra token expiry<br/>Verify keys<br/>Sync thời gian Docker"]
|
|
|
|
CheckLogs --> LogAnalysis{"Log Hiện<br/>Lỗi?"}
|
|
LogAnalysis -->|"Có"| ErrorType
|
|
LogAnalysis -->|"Không"| ConnCheck["Kiểm tra Kết nối"]
|
|
|
|
ConnCheck --> GatewayTest{"Gateway<br/>Truy Cập Được?"}
|
|
GatewayTest -->|"Không"| TraefikCheck
|
|
GatewayTest -->|"Có"| ServiceTest{"Service<br/>Truy Cập Được?"}
|
|
|
|
ServiceTest -->|"Không"| AppCheck
|
|
ServiceTest -->|"Có"| Resolved(["Đã Giải Quyết"])
|
|
|
|
DBSolution --> Restart["Restart Services"]
|
|
RedisSolution --> Restart
|
|
TraefikSolution --> Restart
|
|
ConfigFix --> Restart
|
|
PrismaFix --> Restart
|
|
AuthFix --> Restart
|
|
|
|
Restart --> Verify{"Đã Sửa<br/>Xong?"}
|
|
Verify -->|"Có"| Resolved
|
|
Verify -->|"Không"| DeepDebug["Debug Sâu<br/>Hơn"]
|
|
|
|
DeepDebug --> ContainerShell["Truy cập Container Shell"]
|
|
DeepDebug --> PrismaStudio["Dùng Prisma Studio"]
|
|
DeepDebug --> RedisInspect["Kiểm tra Redis"]
|
|
DeepDebug --> APITest["Test API Trực tiếp"]
|
|
|
|
style Start fill:#1a1a2e,color:#fff
|
|
style Resolved fill:#0f3460,color:#fff
|
|
style CheckStatus fill:#16213e,color:#fff
|
|
style ServiceType fill:#16213e,color:#fff
|
|
style ErrorType fill:#16213e,color:#fff
|
|
style DBCheck fill:#16213e,color:#fff
|
|
style RedisCheck fill:#16213e,color:#fff
|
|
style TraefikCheck fill:#16213e,color:#fff
|
|
style GatewayTest fill:#16213e,color:#fff
|
|
style ServiceTest fill:#16213e,color:#fff
|
|
style Verify fill:#16213e,color:#fff
|
|
style LogAnalysis fill:#16213e,color:#fff
|
|
style InfraCheck fill:#1a1a40,color:#fff
|
|
style AppCheck fill:#1a1a40,color:#fff
|
|
style DBSolution fill:#0f4c75,color:#fff
|
|
style RedisSolution fill:#0f4c75,color:#fff
|
|
style TraefikSolution fill:#0f4c75,color:#fff
|
|
style ConfigFix fill:#0f4c75,color:#fff
|
|
style PrismaFix fill:#0f4c75,color:#fff
|
|
style AuthFix fill:#0f4c75,color:#fff
|
|
style Restart fill:#3282b8,color:#fff
|
|
style DeepDebug fill:#1b262c,color:#fff
|
|
style IdentifyService fill:#1a1a40,color:#fff
|
|
style CheckLogs fill:#1a1a40,color:#fff
|
|
style ConnCheck fill:#1a1a40,color:#fff
|
|
style ContainerShell fill:#0f3460,color:#fff
|
|
style PrismaStudio fill:#0f3460,color:#fff
|
|
style RedisInspect fill:#0f3460,color:#fff
|
|
style APITest fill:#0f3460,color:#fff
|
|
```
|
|
|
|
---
|
|
|
|
## Vấn đề Infrastructure
|
|
|
|
### Database (Neon/PostgreSQL)
|
|
|
|
**Vấn đề**: `P1001: Can't reach database server` hoặc `Connection timed out`
|
|
|
|
* **Nguyên nhân 1**: Lỗi kết nối Internet (Neon là cloud DB).
|
|
* **Nguyên nhân 2**: Sai `DATABASE_URL` trong `.env`.
|
|
* **Nguyên nhân 3**: Địa chỉ IP bị chặn bởi Neon.
|
|
|
|
**Giải pháp**:
|
|
1. Ping thử: `ping neon.tech`.
|
|
2. Kiểm tra file `deployments/local/.env.local`. URL nên có dạng:
|
|
`postgres://user:pass@ep-xyz.aws.neon.tech/neondb`
|
|
3. Vào Neon Dashboard -> Settings, đảm bảo đã chọn "Allow all IPs" hoặc thêm IP hiện tại của bạn.
|
|
|
|
**Vấn đề**: `P1003: Database does not exist`
|
|
|
|
* **Nguyên nhân**: Bạn kết nối sai tên database.
|
|
* **Sửa**: Kiểm tra cuối chuỗi kết nối (thường là `/neondb`). Nếu dùng tên DB tùy chỉnh, đảm bảo nó đã được tạo trên Neon.
|
|
|
|
### Redis
|
|
|
|
**Vấn đề**: `Redis connection refused` hoặc `ECONNREFUSED`
|
|
|
|
* **Nguyên nhân**: Container Redis chưa chạy hoặc sai port mapping.
|
|
|
|
**Giải pháp**:
|
|
1. Kiểm tra trạng thái: `docker-compose ps redis`.
|
|
2. Khởi động lại: `docker-compose restart redis`.
|
|
3. Xem logs: `docker-compose logs redis`.
|
|
4. Chuỗi kết nối từ services:
|
|
* **Bên trong Docker**: `redis:6379`
|
|
* **Từ Host**: `localhost:6379`
|
|
|
|
### Traefik Gateway
|
|
|
|
**Vấn đề**: `404 Not Found` khi gọi API (ví dụ: `http://localhost/api/v1/auth`)
|
|
|
|
* **Nguyên nhân**: Service bị down hoặc Labels cấu hình sai.
|
|
|
|
**Giải pháp**:
|
|
1. Kiểm tra Traefik Dashboard tại http://localhost:8080.
|
|
* Tìm trong "HTTP Routers" và "Services".
|
|
* Nếu service không hiện, kiểm tra labels trong `docker-compose.yml`.
|
|
2. Đảm bảo `PathPrefix` trùng khớp với request:
|
|
```yaml
|
|
- "traefik.http.routers.iam.rule=PathPrefix(`/api/v1/auth`)"
|
|
```
|
|
3. Kiểm tra health checks xem service có healthy không.
|
|
|
|
**Vấn đề**: `Bad Gateway` hoặc `Gateway Timeout`
|
|
|
|
* **Nguyên nhân**: Service bị crash hoặc phản hồi quá lâu.
|
|
* **Sửa**: Xem logs cụ thể của service (`docker-compose logs iam-service`).
|
|
|
|
---
|
|
|
|
## Vấn đề Service
|
|
|
|
### Service Không Khởi Động
|
|
|
|
**Triệu chứng**: Trạng thái container là `Exited (1)` hoặc `Restarting`.
|
|
|
|
**Debug**:
|
|
1. Xem logs ngay lập tức:
|
|
```bash
|
|
docker-compose logs iam-service
|
|
```
|
|
2. **Lỗi thường gặp**: `Config validation error`
|
|
* **Sửa**: Kiểm tra biến môi trường. Chạy `./scripts/setup/init-project.sh` để copy `.env`.
|
|
3. **Lỗi thường gặp**: `PrismaClientInitializationError`
|
|
* **Sửa**: Lỗi kết nối database (xem phần Infrastructure).
|
|
|
|
### Lỗi Prisma/Database
|
|
|
|
**Lỗi**: `P2025: Record to update not found`
|
|
|
|
* **Sửa**: Lỗi logic. Đảm bảo ID tồn tại trước khi update.
|
|
|
|
**Lỗi**: `P2002: Unique constraint failed`
|
|
|
|
* **Sửa**: Bạn đang cố insert dữ liệu trùng lặp (ví dụ: trùng email).
|
|
|
|
**Lỗi**: `Migration failed`
|
|
|
|
* **Sửa**:
|
|
1. Xóa thư mục `prisma/migrations` (chỉ làm ở dev!).
|
|
2. Reset DB: `pnpm prisma migrate reset`.
|
|
3. Regenerate client: `pnpm prisma generate`.
|
|
|
|
### Lỗi Authentication
|
|
|
|
**Vấn đề**: `401 Unauthorized` dù token hợp lệ
|
|
|
|
* **Nguyên nhân 1**: Token hết hạn.
|
|
* **Nguyên nhân 2**: Public key mismatch (Service không verify được token do IAM ký).
|
|
* **Nguyên nhân 3**: Lệch giờ (Thời gian Docker khác Host).
|
|
|
|
**Giải pháp**:
|
|
1. Kiểm tra logs xem lỗi verify JWT cụ thể.
|
|
2. Restart services để refresh keys.
|
|
3. Sync thời gian Docker: restart Docker Desktop.
|
|
|
|
---
|
|
|
|
## Công cụ Debug
|
|
|
|
### 1. Truy cập Shell của Container
|
|
|
|
Để xem files hoặc chạy lệnh bên trong container:
|
|
|
|
```bash
|
|
docker-compose exec iam-service sh
|
|
# hoặc /bin/bash
|
|
```
|
|
|
|
### 2. Kiểm tra Database (Prisma Studio)
|
|
|
|
Giao diện trực quan để xem/sửa dữ liệu:
|
|
|
|
```bash
|
|
pnpm --filter @goodgo/iam-service prisma studio
|
|
# Mở http://localhost:5555
|
|
```
|
|
|
|
### 3. Kiểm tra Redis
|
|
|
|
```bash
|
|
docker-compose exec redis redis-cli
|
|
> PING
|
|
PONG
|
|
> KEYS *
|
|
1) "user:123:session"
|
|
```
|
|
|
|
### 4. Test API Trực tiếp
|
|
|
|
Dùng `curl` hoặc Postman.
|
|
|
|
```bash
|
|
# Health Check
|
|
curl -v http://localhost/api/v1/auth/health/live
|
|
|
|
# Login (ví dụ)
|
|
curl -X POST http://localhost/api/v1/auth/login \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"email":"admin@example.com", "password":"password"}'
|
|
```
|
|
|
|
---
|
|
|
|
## Câu hỏi Thường Gặp (FAQ)
|
|
|
|
**H: Tại sao thay đổi của tôi không cập nhật?**
|
|
Đ: Nếu sửa `.env` hoặc `docker-compose.yml`, bạn phải restart:
|
|
```bash
|
|
docker-compose down && docker-compose up -d
|
|
```
|
|
Nếu sửa code, hot-reloading sẽ tự chạy. Nếu không, restart container.
|
|
|
|
**H: Làm sao để reset toàn bộ hệ thống?**
|
|
Đ: Cẩn thận, lệnh này xóa toàn bộ dữ liệu!
|
|
```bash
|
|
docker-compose down -v
|
|
# -v xóa cả volumes (dữ liệu Redis, v.v.)
|
|
```
|
|
|
|
**H: Máy tính chạy rất chậm khi bật dự án.**
|
|
Đ: Docker tốn nhiều RAM.
|
|
1. Tắt các service không dùng (ví dụ `future-service`).
|
|
2. Tăng giới hạn resource trong cài đặt Docker Desktop.
|
|
|
|
---
|
|
|
|
## Mẹo Nhanh (Quick Tips)
|
|
|
|
### Lệnh Debug Nhanh
|
|
|
|
```bash
|
|
# Kiểm tra nhanh các service bị lỗi
|
|
docker-compose ps | grep -v "Up"
|
|
|
|
# Xem logs tất cả services (50 dòng cuối)
|
|
docker-compose logs -f --tail=50
|
|
|
|
# Restart service cụ thể không rebuild
|
|
docker-compose restart iam-service
|
|
|
|
# Rebuild và restart service
|
|
docker-compose up -d --build iam-service
|
|
|
|
# Kiểm tra resource usage
|
|
docker stats --no-stream
|
|
|
|
# Dọn dẹp resources không dùng
|
|
docker system prune -a --volumes
|
|
```
|
|
|
|
### Các Pattern Lỗi Thường Gặp
|
|
|
|
| Pattern Lỗi | Nguyên nhân Có thể | Cách Sửa Nhanh |
|
|
|-------------|-------------------|----------------|
|
|
| `ECONNREFUSED` | Service chưa chạy | `docker-compose restart <service>` |
|
|
| `P1001` | Database không kết nối được | Kiểm tra `DATABASE_URL` và internet |
|
|
| `P2002` | Dữ liệu trùng lặp | Kiểm tra unique constraints |
|
|
| `401 Unauthorized` | Token hết hạn/không hợp lệ | Refresh token hoặc đăng nhập lại |
|
|
| `404 Not Found` | Route sai/service down | Kiểm tra Traefik dashboard |
|
|
| `502 Bad Gateway` | Service bị crash | Xem logs service |
|
|
| `Config validation error` | Thiếu biến môi trường | Chạy `init-project.sh` |
|
|
|
|
### Mẹo Phân Tích Logs
|
|
|
|
**Những gì cần tìm trong logs:**
|
|
- `Server listening on port XXXX` = Service khởi động thành công
|
|
- `Warning:` = Vấn đề không nghiêm trọng
|
|
- `Error:` = Vấn đề nghiêm trọng cần xử lý
|
|
- `Trace:` = Chi tiết luồng thực thi
|
|
|
|
**Các pattern grep hữu ích:**
|
|
```bash
|
|
# Tìm tất cả lỗi
|
|
docker-compose logs | grep -i error
|
|
|
|
# Tìm lỗi của service cụ thể
|
|
docker-compose logs iam-service | grep -i "error\|failed"
|
|
|
|
# Tìm vấn đề database connection
|
|
docker-compose logs | grep -i "prisma\|database\|p1001\|p1003"
|
|
|
|
# Tìm vấn đề auth
|
|
docker-compose logs | grep -i "unauthorized\|401\|jwt\|token"
|
|
```
|
|
|
|
### Quản Lý Tài Nguyên
|
|
|
|
**Docker Resources Khuyến nghị:**
|
|
- **RAM**: Tối thiểu 4GB, Khuyến nghị 8GB
|
|
- **CPU**: Tối thiểu 2 cores, Khuyến nghị 4 cores
|
|
- **Disk**: Tối thiểu 10GB dung lượng trống
|
|
|
|
**Kiểm tra resource usage:**
|
|
```bash
|
|
# Tổng quan hệ thống
|
|
docker system df
|
|
|
|
# Theo từng container
|
|
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
|
|
```
|
|
|
|
**Lệnh dọn dẹp:**
|
|
```bash
|
|
# Xóa containers đã dừng
|
|
docker container prune
|
|
|
|
# Xóa images không dùng
|
|
docker image prune -a
|
|
|
|
# Xóa volumes không dùng ( mất dữ liệu!)
|
|
docker volume prune
|
|
|
|
# Tùy chọn hạt nhân ( xóa mọi thứ!)
|
|
docker system prune -a --volumes
|
|
```
|
|
|
|
### Best Practices
|
|
|
|
1. **Luôn kiểm tra logs trước** khi thay đổi gì
|
|
2. **Dùng Traefik Dashboard** (http://localhost:8080) để verify routing
|
|
3. **Giữ `.env.local` cập nhật** với credentials đúng
|
|
4. **Đừng xóa volumes** trừ khi muốn mất dữ liệu
|
|
5. **Restart Docker Desktop** nếu gặp vấn đề network lạ
|
|
6. **Dùng `docker-compose down && up`** sau khi thay đổi `.env`
|
|
7. **Giữ services đang chạy** mà bạn đang develop
|
|
8. **Tắt services** không dùng để tiết kiệm tài nguyên
|
|
|
|
### Visual Indicators
|
|
|
|
Khi đọc logs, chú ý các pattern sau:
|
|
- `[INFO]` = Hoạt động bình thường
|
|
- `[WARN]` = Cần theo dõi
|
|
- `[ERROR]` = Cần xử lý ngay
|
|
- `[DEBUG]` = Thông tin chi tiết
|
|
- `[TRACE]` = Luồng thực thi rất chi tiết
|
|
|
|
### Tài Liệu Liên Quan
|
|
|
|
- [Hướng dẫn Local Deployment](./local-deployment.md) - Hướng dẫn setup
|
|
- [Hướng dẫn Development](./development.md) - Workflow phát triển
|
|
- [Hướng dẫn Kubernetes Local](./kubernetes-local.md) - Troubleshooting K8s
|
|
- [Hướng dẫn Neon Database](./neon-database.md) - Quản lý database
|