用 Laravel 打造企業級 SaaS:模組化單體與微服務的完美結合
身為一名資深 Laravel 開發者,您是否曾想過,如何將專案從單純的 CRUD 應用,提升到具備企業級擴展性、易於維護的 SaaS 平台?這篇文章,將為您揭示一個兼具開發效率與卓越效能的 「模組化單體」(Modular Monolith)架構。
我們將透過一個完整的「餐廳 SaaS 系統」實戰案例,展示核心技術選型與實作細節,助您在面試或專案中,展現超越凡響的架構思維。
您可以透過以下 GitHub 連結檢閱本專案的原始碼:https://github.com/BpsEason/modular-dining-system.git
為何如此選擇?技術棧的優雅協奏
拋開「非單體即微服務」的二元對立思維,我們讓不同的技術棧各司其職。
Laravel: 專注處理核心業務邏輯、資料庫操作、RBAC 權限與多租戶管理。它強大的生態系統是構建穩健後台服務的最佳夥伴。
FastAPI: 專注於 I/O 密集型及計算密集型任務,例如本專案的個性化推薦引擎。Python 的非同步特性(async/await)使其在高併發場景下表現卓越,完美彌補了 PHP 在此領域的不足。
透過 Docker Compose,我們將這兩種技術無縫整合,讓開發、測試與部署流程極致流暢。
第一步:告別單體,擁抱模組化骨架
傳統 Laravel 專案的程式碼常混雜在 app/Http/Controllers
中,難以維護。我們的解決方案,是使用 nwidart/laravel-modules
套件來建立獨立的模組化結構。
在專案的啟動腳本中,我們定義了清晰的資料夾結構,讓每個模組(如 CustomerProfile, Marketing, PosCore)都有自己的 Controllers
、Routes
和 Models
。
DIRS=(
"laravel-app/modules/CustomerProfile/Http/Controllers"
"laravel-app/modules/LoyaltyProgram/Http/Controllers"
"laravel-app/modules/Marketing/Http/Controllers"
"laravel-app/modules/PosCore/Http/Controllers"
"laravel-app/routes"
# ... 其他目錄
)
for dir in "${DIRS[@]}"; do
mkdir -p "$dir"
done
關鍵提示: 自動化腳本確保團隊遵循統一架構,從專案初始化就建立高水準的開發規範。
第二步:跨越語言邊界:從 Laravel 呼叫 FastAPI
真正的亮點在此!當 Marketing 模組需要發送個性化推播通知時,它不會自己處理複雜的推薦邏輯,而是優雅地將任務交給 FastAPI 服務.
瞧瞧程式碼如何協作:
Laravel 端(Marketing 模組):
使用 Http Facade 進行服務呼叫。我們在 NotificationController.php 中將任務推入隊列,確保請求能即時回應。
PHP// laravel-app/modules/Marketing/Http/Controllers/NotificationController.php public function send(Request $request) { // ... 驗證邏輯 // 將發送通知的任務推入隊列 SendPushNotification::dispatch($validated['message'], $validated['user_id']); return response()->json(['message' => 'Notification queued successfully.']); }
FastAPI 端(Recommendation 服務):
main.py 啟動一個獨立服務,提供高效的推薦 API。
Python# fastapi-service/main.py @app.get("/api/v1/recommendations/{customer_id}", response_model=RecommendationResponse) def get_recommendations(customer_id: int): # ... 推薦邏輯:讀取 Redis 快取或 MySQL 資料 recommended_items = ... return RecommendationResponse(items=recommended_items, strategy="Collaborative Filtering (KNN)")
隊列中的實際呼叫:
在 SendPushNotification Job 裡,我們使用 Laravel 的 Http Client 呼叫 FastAPI, 再將推薦結果組合成推播訊息。
PHP// laravel-app/app/Jobs/SendPushNotification.php public function handle(): void { // 呼叫 FastAPI 推薦服務 $recommendations = Http::get("http://fastapi:8000/api/v1/recommendations/{$this->userId}")->json(); $message = "Try our recommended {$recommendations['items'][0]['name']}!"; // ... 使用 LINE/SMS API 發送通知 Http::withHeaders(...)->post(env('PUSH_SERVICE_ENDPOINT'), [ 'user_id' => $this->userId, 'message' => $message, ]); }
關鍵提示: 透過將耗時的 API 呼叫放入隊列,我們徹底避免了阻塞主執行緒,大幅提升使用者體驗。
第三步:為失敗而建:強韌的任務處理
專業系統不僅為成功而設計,更要為失敗做好準備。如果推播服務失敗,我們的 SendPushNotification
Job 會觸發以下機制:
自動重試:
$this->tries = 3;
讓任務自動重試三次,大幅提高成功率。錯誤日誌: 若重試仍失敗,我們會將通知失敗的紀錄寫入
notification_logs
資料表,方便後續追蹤與分析。
// laravel-app/app/Jobs/SendPushNotification.php
public function handle(): void
{
try {
// ... 發送通知的邏輯
} catch (Throwable $e) {
// 失敗時記錄到資料庫
NotificationLog::create([
'user_id' => $this->userId,
'message' => $this->message,
'status' => 'failed',
'error_message' => $e->getMessage(),
]);
// 如果還沒達到最大重試次數,拋出例外以觸發重試
if ($this->attempts() < $this->tries) {
throw $e;
}
}
}
關鍵提示: 這種設計展現了對 系統韌性 (Resilience) 與 可觀測性 (Observability) 的深刻理解。
第四步:從源頭開始,確保 SaaS 安全
在多租戶 SaaS 架構中,資料隔離是生命線。我們結合 spatie/laravel-permission
與自定義 Middleware,構築了堅固的權限與租戶管理防線。
細粒度 RBAC: 我們定義了
admin
、manager
、staff
等角色,並賦予精細的權限,如customer.read
、order.create
。強制租戶隔離: 透過
CheckTenant
Middleware,強制每個 API 請求都必須攜帶有效的X-Tenant-ID
Header。
// laravel-app/app/Http/Middleware/CheckTenant.php
public function handle(Request $request, Closure $next): Response
{
$tenantId = $request->header('X-Tenant-ID');
if (! $tenantId || ! auth()->user()->tenant_id || (int) $tenantId !== auth()->user()->tenant_id) {
return response()->json(['message' => 'Unauthorized or invalid tenant.'], 403);
}
return $next($request);
}
關鍵提示: 這種強制性的驗證機制,從根本上確保了不同租戶的資料在邏輯上完全隔離。
第五步:一鍵部署:DevOps 的終極藝術
資深工程師的價值,在於將個人能力轉化為團隊的效率。我們透過 GitHub Actions 實現全自動化的 CI/CD 流程。
自動化測試: 程式碼提交後,自動執行 Laravel (PHPUnit)、Vue (Vitest) 和 FastAPI (Pytest) 的所有測試。
品質保證: 測試結果會生成覆蓋率報告,並上傳至 Codecov,確保程式碼品質。
無縫部署: 只要程式碼推送到
main
分支,GitHub Actions 就會自動建置 Docker 映像檔並推送到 Docker Hub,實現零停機更新。
關鍵提示: 這種流程消除了手動部署的風險,將「從程式碼提交到生產部署」變成無縫銜接的自動化藝術。
沒有留言:
張貼留言