动态

详情 返回 返回

fiberhouse framework[go web、cmd應用框架]

Fiberhouse Framework

  • https://github.com/lamxy/fiberhouse

    🏠 關於 Fiberhouse

Fiberhouse 是基於 Fiber 的高性能、可裝配的 Go Web 框架,內置全局管理器、配置器、統一日誌器、驗證包裝器以及數據庫、緩存、中間件、統一異常處理等框架組件,開箱即用。

  • 提供了強大的全局管理容器,支持自定義組件一次註冊到處使用的能力,方便開發者按需替換和功能擴展,
  • 在框架層面約定了應用啓動器、全局上下文、業務分層等接口以及內置默認實現,支持自定義實現和模塊化開發,
  • 使得 FiberHouse 像裝配"傢俱"的"房子"一樣可以按需構建靈活的、完整的 Go Web 應用。

🏆 開發方向

提供高性能、可擴展、可定製,開箱即用的 Go Web 框架

✨ 功能

  • 高性能: 基於 Fiber 框架,提供極速的 HTTP 性能,支持對象池、goroutine池、緩存、異步等性能優化措施
  • 模塊化設計: 清晰的分層架構設計,定義了標準的接口契約和實現,支持團隊協作、擴展和模塊化開發
  • 全局管理器: 全局對象管理容器,無鎖設計、即時註冊、延遲初始化、單例特性,支持可替代第三方依賴注入工具的依賴解決方案、以及生命週期的統一管理
  • 全局配置管理: 統一配置文件加載、解析和管理,支持多格式配置、環境變量覆蓋,適應不同的應用場景
  • 統一日誌管理: 高性能日誌系統,支持結構化日誌、同步異步寫入器,以及各種日誌源標識管理
  • 統一異常處理: 統一異常定義和處理機制,支持錯誤碼模塊化管理、集成參數驗證器、錯誤追蹤,以及友好的調試體驗
  • 參數驗證: 集成開源驗證包裝器,支持註冊自定義語言驗證器、tag標籤規則和多語言翻譯器
  • 數據庫支持: 集成 MySQL、MongoDB 驅動組件以及對數據庫模型基類的支持
  • 緩存組件: 內置高性能的本地、遠程和二級緩存組件的組合使用和管理,以及對緩存模型基類的支持
  • 任務隊列: 集成基於 Redis 的高性能 C/S 架構異步任務隊列,支持任務調度、延時執行和失敗重試等功能
  • API 文檔: 集成 swag 文檔工具,支持自動生成 API 文檔
  • 命令行應用: 完整的命令行應用框架支持,遵循統一的模塊化設計,支持團隊協作、功能擴展和模塊化開發
  • 樣例模板: 提供完整的Web應用和CMD應用樣例模板結構,涵蓋了常見場景和最佳實踐,開發者稍作修改即可直接套用
  • 更多: 持續優化和更新中...

🏗️ 架構説明

frame/                              # FiberHouse 框架核心
├── 接口定義層
│   ├── application_interface.go    # 應用啓動器接口定義
│   ├── command_interface.go        # 命令行應用接口定義  
│   ├── context_interface.go        # 全局上下文接口定義
│   ├── json_wraper_interface.go    # JSON 包裝器接口定義
│   ├── locator_interface.go        # 服務定位器接口定義
│   └── model_interface.go          # 數據模型接口定義
├── 應用啓動層
│   ├── applicationstarter/         # Web 應用啓動器實現
│   │   └── web_starter.go          # 基於 Fiber 的應用啓動器
│   ├── commandstarter/             # 命令行應用啓動器實現
│   │   └── cmdline_starter.go      # 命令行應用啓動器
│   └── bootstrap/                  # 應用引導程序
│       └── bootstrap.go            # 統一引導入口
├── 配置管理層
│   └── appconfig/                  # 應用配置管理
│       └── config.go               # 多格式配置文件加載和管理
├── 全局管理層
│   ├── globalmanager/              # 全局對象容器管理
│   │   ├── interface.go            # 全局管理器接口
│   │   ├── manager.go              # 全局管理器實現
│   │   └── types.go                # 全局管理器類型定義
│   └── global_utility.go           # 全局工具函數
├── 數據訪問層
│   └── database/                   # 數據庫驅動支持
│       ├── dbmysql/                # MySQL 數據庫組件
│       │   ├── interface.go        # MySQL 接口定義
│       │   ├── mysql.go            # MySQL 連接實現
│       │   └── mysql_model.go      # MySQL 模型基類
│       └── dbmongo/                # MongoDB 數據庫組件
│           ├── interface.go        # MongoDB 接口定義
│           ├── mongo.go            # MongoDB 連接實現
│           └── mongo_model.go      # MongoDB 模型基類
├── 緩存系統層
│   └── cache/                      # 高性能緩存組件
│       ├── cache_interface.go      # 緩存接口定義
│       ├── cache_option.go         # 緩存配置選項
│       ├── cache_utility.go        # 緩存工具函數
│       ├── cache_errors.go         # 緩存錯誤定義
│       ├── helper.go               # 緩存助手函數
│       ├── cache2/                 # 二級緩存實現
│       │   └── level2_cache.go     # 本地+遠程二級緩存
│       ├── cachelocal/             # 本地緩存實現
│       │   ├── local_cache.go      # 內存緩存實現
│       │   └── type.go             # 本地緩存類型
│       └── cacheremote/            # 遠程緩存實現
│           ├── cache_model.go      # 遠程緩存模型基類
│           └── redis_cache.go      # Redis 緩存實現
├── 組件庫層
│   └── component/                  # 框架核心組件
│       ├── dig_container.go        # 基於dig依賴注入容器包裝
│       ├── jsoncodec/              # JSON 編解碼器
│       │   └── sonicjson.go        # 基於 Sonic 的高性能 JSON編解碼器
│       ├── jsonconvert/            # JSON 轉換工具
│       │   └── convert.go          # 轉換核心實現
│       ├── mongodecimal/           # MongoDB 十進制處理
│       │   └── mongo_decimal.go    # MongoDB Decimal128 支持
│       ├── validate/               # 參數驗證組件
│       │   ├── type_interface.go   # 驗證器接口定義
│       │   ├── validate_wrapper.go # 驗證器包裝實現
│       │   ├── en.go               # 英文驗證器實現
│       │   ├── zh_cn.go            # 簡體中文驗證器實現
│       │   ├── zh_tw.go            # 繁體中文驗證器實現
│       │   └── example/            # 註冊示例
│       ├── tasklog/                # 任務日誌組件
│       │   └── logger_adapter.go   # 日誌適配器
│       └── writer/                 # 日誌寫入器
│           ├── async_channel_writer.go     # 異步通道寫入器
│           ├── async_diode_writer.go       # 異步二極管寫入器
│           ├── async_diode_writer_test.go  # 異步寫入器測試
│           └── sync_lumberjack_writer.go   # 同步滾動日誌寫入器
├── 中間件層
│   └── middleware/                 # HTTP 中間件
│       └── recover/                # 異常恢復中間件
│           ├── config.go           # 恢復中間件配置
│           └── recover.go          # 恢復中間件實現
├── 響應處理層
│   └── response/                   # 統一響應處理
│       └── response.go             # 響應對象池和序列化
├── 異常處理層
│   └── exception/                  # 統一異常處理
│       ├── types.go                # 異常類型定義
│       └── exception_error.go      # 異常錯誤實現
├── 工具層
│   ├── utils/                      # 通用工具函數
│   │   └── common.go               # 通用工具實現
│   └── constant/                   # 框架常量
│       ├── constant.go             # 全局常量定義
│       └── exception.go            # 異常常量定義
├── 業務分層
│   ├── api.go                      # API 層接口定義
│   ├── service.go                  # 服務層接口定義
│   ├── repository.go               # 倉儲層接口定義
│   └── task.go                     # 任務層接口定義
└── 佔位模塊
    ├── mq/                         # 消息隊列(待實現)
    ├── plugins/                    # 插件支持(待實現)
    └── component/
        ├── i18n/                   # 國際化(待實現)
        └── rpc/                    # RPC 支持(待實現)
        

🚀 快速開始

環境要求

  • Go 1.24 或更高版本,推薦升級到1.25+
  • MySQL 5.7+ 或 MongoDB 4.0+
  • Redis 5.0+

docker 啓動數據庫、緩存容器用於框架調式

  • docker compose文件,見: docker-compose.yml
  • 啓動命令: docker compose up -d

cd  frame/docs/docker_compose_db_redis_yaml/
docker compose up -d

安裝

FiberHouse 運行需要 Go 1.24 或更高版本。如果您需要安裝或升級 Go,請訪問 Go 官方下載頁面。
要開始創建項目,請創建一個新的項目目錄並進入該目錄。然後,在終端中執行以下命令,使用 Go Modules 初始化您的項目:


go mod init github.com/your/repo

項目設置完成後,您可以使用go get命令安裝FiberHouse框架:


go get github.com/lamxy/fiberhouse

main文件示例

參考樣例: example_main/main.go

package main

import (
    "github.com/lamxy/fiberhouse/example_application"
    "github.com/lamxy/fiberhouse/example_application/module"
    "github.com/lamxy/fiberhouse/frame"
    "github.com/lamxy/fiberhouse/frame/applicationstarter"
    "github.com/lamxy/fiberhouse/frame/bootstrap"
)

func main() {
    // bootstrap 初始化啓動配置(全局配置、全局日誌器),配置目錄默認為當前工作目錄"."下的`example_config/`
    // 可以指定絕對路徑或基於工作目錄的相對路徑
    cfg := bootstrap.NewConfigOnce("./example_config")
    
    // 日誌目錄默認為當前工作目錄"."下的`example_main/logs`
    // 可以指定絕對路徑或基於工作目錄的相對路徑
    logger := bootstrap.NewLoggerOnce(cfg, "./example_main/logs")

    // 初始化全局應用上下文
    appContext := frame.NewAppContextOnce(cfg, logger)

    // 初始化應用註冊器、模塊/子系統註冊器和任務註冊器對象,注入到應用啓動器
    appRegister := example_application.NewApplication(appContext)  // 需實現應用註冊器接口,見frame.ApplicationRegisterer接口定義,參考example_application/application.go樣例實現
    moduleRegister := module.NewModule(appContext)  // 需實現模塊註冊器接口,見樣例模塊module/module.go的實現
    taskRegister := module.NewTaskAsync(appContext)  // 需實現任務註冊器接口,見樣例任務module/task.go的實現

        // 實例化 Web 應用啓動器
        webStarter := &applicationstarter.WebApplication{
            // 實例化框架啓動器 // 公共框架實現
            FrameStarter: applicationstarter.NewFrameApplication(appContext,
              option.WithAppRegister(appRegister),
              option.WithModuleRegister(moduleRegister),
              option.WithTaskRegister(taskRegister),
            ),
            // 實例化核心應用啓動器 // 核心支持可替代,只要實現CoreStarter接口,默認基於fiber實現
            CoreStarter: applicationstarter.NewCoreFiber(appContext),
        }
    
    // 運行框架應用啓動器
    applicationstarter.RunApplicationStarter(webStarter)
}

快速體驗

  • web應用快速體驗

# 克隆框架
git clone https://github.com/lamxy/fiberhouse.git

# 進入框架目錄
cd fiberhouse

# 安裝依賴
go mod tidy

# 進入example_main/
cd example_main/

# 查看README
cat README_go_build.md

# 構建應用: windows環境為例,其他環境請參考交叉編譯
# 退回到應用根目錄(默認工作目錄),在工作目錄下執行以下命令,構建應用
# 當前工作目錄為 fiberhouse/,構建產物輸出到 example_main/target/ 目錄
cd ..
# windows環境構建產物保留.exe後綴,linux環境無需保留後綴
go build "-ldflags=-X 'main.Version=v0.0.1'" -o ./example_main/target/examplewebserver.exe ./example_main/main.go

# 運行應用
# 退回到應用根目錄(默認工作目錄),在工作目錄下執行以下命令,啓動應用
./example_main/target/examplewebserver.exe
# or Linux、 MacOS
./example_main/target/examplewebserver

訪問hello world接口: http://127.0.0.1:8080/example/hello/world

您將收到響應: {"code":0,"msg":"ok","data":"Hello World!"}


curl -sL  "http://127.0.0.1:8080/example/hello/world"

# 響應:
{
    "code": 0,
    "msg": "ok",
    "data": "Hello World!"
}
  • Cmd應用快速體驗

# mysql數據庫準備
mysqlsh root:root@localhost:3306 

# 創建一個test庫
CREATE DATABASE IF NOT EXISTS test CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

# 克隆框架
git clone https://github.com/lamxy/fiberhouse.git

# 進入框架目錄
cd fiberhouse

# 安裝依賴
go mod tidy

# 進入example_application/command/
cd example_application/command/

# 查看README
cat README_go_build.md

# 當前工作目錄: command/
# windows環境構建產物保留.exe後綴,Linux or MacOS環境無需保留後綴
go build -o ./target/cmdstarter.exe ./main.go 

# 設置cmd應用的環境變量,windows環境,將讀取application_cmd_dev.yml配置文件
set APP_ENV_application_appType=cmd
set APP_ENV_application_env=dev

# Linux or MacOS 環境
# export APP_ENV_application_appType=cmd
# export APP_ENV_application_env=dev

# 執行cmd命令腳本,查看幫助
./target/cmdstarter.exe -h 
# or 
./target/cmdstarter -h

# 執行子命令,查看控制枱日誌輸出
./target/cmdstarter.exe test-orm -m ok
# or 
./target/cmdstarter test-orm -m ok

# 控制枱輸出 ok
# result:  ExampleMysqlService.TestOK: OK --from: ok

📖 使用指南

  • examples樣例模板項目結構
  • 依賴注入工具説明和使用
  • 通過框架的全局管理器實現無需依賴注入工具來解決依賴關係
  • 樣例 curd API實現
  • 如何添加新的模塊和新的api
  • task異步任務的使用樣例
  • 緩存組件使用樣例
  • cmd命令行應用的使用樣例

examples樣例應用模板目錄結構

  • 架構概覽與説明
example_application/                    # 樣例應用根目錄
├── 應用配置層
│   ├── application.go                  # 應用註冊器實現
│   ├── constant.go                     # 應用級常量定義
│   └── customizer_interface.go         # 應用定製器接口
├── API 接口層
│   └── api-vo/                         # API 值對象定義
│       ├── commonvo/                   # 通用 VO
│       │   └── vo.go                   # 通用值對象
│       └── example/                    # 示例模塊 VO
│           ├── api_interface.go        # API 接口定義
│           ├── requestvo/              # 請求 VO
│           │   └── example_reqvo.go    # 示例請求對象
│           └── responsevo/             # 響應 VO
│               └── example_respvo.go   # 示例響應對象
├── 命令行框架應用層
│   └── command/                        # 命令行程序
│       ├── main.go                     # 命令行main入口
│       ├── README_go_build.md          # 構建説明
│       ├── application/                
│       │   ├── application.go          # 命令應用配置和邏輯
│       │   ├── constants.go            # 命令常量
│       │   ├── functions.go            # 命令工具函數
│       │   └── commands/               # 具體命令腳本實現
│       │       ├── test_orm_command.go # ORM 測試命令
│       │       └── test_other_command.go # 其他更多開發的命令腳本...
│       ├── component/                  # 命令行組件
│       │   ├── cron.go                 # 定時任務組件
│       │   └── readme.md               # 組件説明
│       └── target/                     # 構建產物
│           └── cmdstarter.exe          # 命令行可執行文件
├── 異常處理層
│   ├── get_exceptions.go               # 異常獲取器
│   └── example-module/                 # 示例模塊異常,其他模塊異常,每個模塊獨立目錄
│       └── exceptions.go               # 模塊異常彙總
├── 中間件層
│   └── middleware/                     # 應用級中間件
│       └── register_app_middleware.go  # 應用中間件註冊器
├── 模塊(子系統)層
│   └── module/                         # 業務模塊
│       ├── module.go                   # 模塊註冊器
│       ├── route_register.go           # 路由註冊器
│       ├── swagger.go                  # Swagger 文檔配置
│       ├── task.go                     # 異步任務註冊器
│       ├── api/                        # 模塊級 API 中間件
│       │   └── register_module_middleware.go
│       ├── command-module/             # 命令行腳本專用的業務模塊
│       │   ├── entity/                 # 實體定義
│       │   │   └── mysql_types.go      # MySQL 類型定義
│       │   ├── model/                  # 數據模型
│       │   │   ├── mongodb_model.go    # MongoDB 模型
│       │   │   └── mysql_model.go      # MySQL 模型
│       │   └── service/                # 業務服務
│       │       ├── example_mysql_service.go  # MySQL 服務示例
│       │       └── mongodb_service.go        # MongoDB 服務示例
│       ├── common-module/           # 通用模塊
│       │   ├── attrs/                  # 屬性定義
│       │   │   └── attr1.go            # 屬性示例
│       │   ├── command/                # 通用命令
│       │   ├── fields/                 # 通用字段
│       │   │   └── timestamps.go       # 時間戳字段
│       │   ├── model/                  # 通用模型
│       │   ├── repository/             # 通用倉儲
│       │   ├── service/                # 通用服務
│       │   └── vars/                   # 通用變量
│       │       └── vars.go             # 變量定義
│       ├── constant/                # 常量定義
│       │   └── constants.go            # 模塊常量
│       └── example-module/          # 用於展示的核心樣例模塊
│           ├── api/                    # API 控制器層
│           │   ├── api_provider_wire_gen.go    # Wire 依賴注入生成文件
│           │   ├── api_provider.go             # API 提供者,提供依賴關係
│           │   ├── common_api.go               # 通用 API 控制器
│           │   ├── example_api.go              # 示例 API 控制器
│           │   ├── health_api.go               # 健康檢查 API 控制器
│           │   ├── README_wire_gen.md          # Wire 生成説明
│           │   └── register_api_router.go      # API 路由註冊
│           ├── dto/                    # 數據傳輸對象
│           ├── entity/                 # 實體層
│           │   └── types.go            # 類型定義
│           ├── model/                  # 模型層
│           │   ├── example_model.go            # 示例模型
│           │   ├── example_mysql_model.go      # MySQL 示例模型
│           │   └── model_wireset.go            # 模型 Wire 集合
│           ├── repository/             # 倉儲層
│           │   ├── example_repository.go       # 示例倉儲
│           │   ├── health_repository.go        # 健康檢查倉儲
│           │   └── repository_wireset.go       # 倉儲 Wire 集合
│           ├── service/                # 服務層
│           │   ├── example_service.go          # 示例服務
│           │   ├── health_service.go           # 健康檢查服務
│           │   ├── service_wireset.go          # 服務 Wire 集合
│           │   └── test_service.go             # 測試服務
│           └── task/                   # 任務層
│               ├── names.go            # 任務名稱定義
│               ├── task.go             # 任務註冊器
│               └── handler/            # 任務處理器
│                   ├── handle.go       # 任務處理邏輯
│                   └── mount.go        # 任務掛載器
├── 工具層
│   └── utils/                          # 應用工具
│       └── common.go                   # 通用工具函數
└── 自定義驗證器層
    └── validatecustom/                 # 自定義驗證器
        ├── tag_register.go             # 標籤註冊器
        ├── validate_initializer.go     # 驗證器初始化
        ├── tags/                       # 自定義標籤
        │   ├── new_tag_hascourses.go   # 課程驗證標籤
        │   └── tag_startswith.go       # 前綴驗證標籤
        └── validators/                 # 多語言驗證器
            ├── ja.go                   # 日語驗證器
            ├── ko.go                   # 韓語驗證器
            └── langs_const.go          # 語言常量

依賴注入工具説明和使用

  • 依賴注入工具和庫

    • google wire: 依賴注入代碼生成工具,官方地址 https://github.com/google/wire
    • uber dig: 依賴注入容器,推薦僅在應用啓動階段使用,官方地址 https://github.com/uber-go/dig
  • google wire使用説明和示例,參考:

    • example_application/module/example-module/api/api_provider.go
    • example_application/module/example-module/api/README_wire_gen.md
  • uber dig使用説明和示例,參考:

    • frame/component/dig_container.go

通過框架的全局管理器實現無需依賴注入工具來解決依賴關係

  • 見註冊路由示例: example_application/module/example-module/api/register_api_router.go
func RegisterRouteHandlers(ctx frame.ContextFramer, app fiber.Router) {
    // 獲取exampleApi處理器
    exampleApi, _ := InjectExampleApi(ctx) // 由wire編譯依賴注入生成注入函數獲取ExampleApi
    
    // 獲取CommonApi處理器,直接NewCommonHandler
    
    // 直接New,無需依賴注入(Wire注入),內部依賴走全局管理器延遲獲取依賴組件,
    // 見 common_api.go: api.CommonHandler
    commonApi := NewCommonHandler(ctx) 
    
    // 獲取註冊更多api處理器並註冊相應路由...
    
    // 註冊Example模塊的路由
    exampleGroup := app.Group("/example")
    // hello world
    exampleGroup.Get("/hello/world", exampleApi.HelloWorld).Name("ex_get_example_test")
}
  • 見CommonHandler通過全局管理器實現無需事先依賴注入服務組件: example_application/module/example-module/api/common_api.go
// CommonHandler 示例公共處理器,繼承自 frame.ApiLocator,具備獲取上下文、配置、日誌、註冊實例等功能
type CommonHandler struct {
    frame.ApiLocator
    KeyTestService string // 定義依賴組件的全局管理器的實例key。通過key即可由 h.GetInstance(key) 方法獲取實例,或由 frame.GetMustInstance[T](key) 泛型方法獲取實例,
                          // 無需wire或其他依賴注入工具
}

// NewCommonHandler 直接New,無需依賴注入(Wire) TestService對象,內部走全局管理器獲取依賴組件
func NewCommonHandler(ctx frame.ContextFramer) *CommonHandler {
    return &CommonHandler{
        ApiLocator:     frame.NewApi(ctx).SetName(GetKeyCommonHandler()),
        
        // 註冊依賴的TestService實例初始化器並返回註冊實例key,通過 h.GetInstance(key) 方法獲取TestService實例
        KeyTestService: service.RegisterKeyTestService(ctx), 
    }
}

// TestGetInstance 測試獲取註冊實例,通過 h.GetInstance(key) 方法獲取TestService註冊實例,無需編譯階段的wire依賴注入
func (h *CommonHandler) TestGetInstance(c *fiber.Ctx) error {
    t := c.Query("t", "test")
    
    // 通過 h.GetInstance(h.KeyTestService) 方法獲取註冊實例
    testService, err := h.GetInstance(h.KeyTestService)
        if err != nil {
        return err
    }
    
    if ts, ok := testService.(*service.TestService); ok {
        return response.RespSuccess(t + ":" + ts.HelloWorld()).JsonWithCtx(c)
    }
    
    return fmt.Errorf("類型斷言失敗")
}

樣例 curd API實現

  • 定義實體類型: 見example_application/module/example-module/entity/types.go
// Example
type Example struct {
    ID                bson.ObjectID             `json:"id" bson:"_id,omitempty"`
    Name              string                    `json:"name" bson:"name"`
    Age               int                       `json:"age" bson:"age,minsize"` // minsize 取int32存儲數據
    Courses           []string                  `json:"courses" bson:"courses,omitempty"`
    Profile           map[string]interface{}    `json:"profile" bson:"profile,omitempty"`
    fields.Timestamps `json:"-" bson:",inline"` // inline: bson文檔序列化自動提升嵌入字段即自動展開繼承的公共字段
}
  • 路由註冊:見 example_application/module/example-module/api/register_api_router.go
func RegisterRouteHandlers(ctx frame.ContextFramer, app fiber.Router) {
    // 獲取exampleApi處理器
    exampleApi, _ := InjectExampleApi(ctx) // 由wire編譯依賴注入獲取
    
    // 註冊Example模塊的路由
    // Example 路由組
    exampleGroup := app.Group("/example")
    
    // hello world 路由
    exampleGroup.Get("/hello/world", exampleApi.HelloWorld).Name("ex_get_example_test")
    
    // CURD 路由
    exampleGroup.Get("/get/:id", exampleApi.GetExample).Name("ex_get_example")
    exampleGroup.Get("/on-async-task/get/:id", exampleApi.GetExampleWithTaskDispatcher).Name("ex_get_example_on_task")
    exampleGroup.Post("/create", exampleApi.CreateExample).Name("ex_create_example")
    exampleGroup.Get("/list", exampleApi.GetExamples).Name("ex_get_examples")
}
  • 定義樣例Api處理器: 見 example_application/module/example-module/api/example_api.go
// ExampleHandler 示例處理器,繼承自 frame.ApiLocator,具備獲取上下文、配置、日誌、註冊實例等功能
type ExampleHandler struct {
    frame.ApiLocator
    Service        *service.ExampleService 
    KeyTestService string                  
}

func NewExampleHandler(ctx frame.ContextFramer, es *service.ExampleService) *ExampleHandler {
    return &ExampleHandler{
        ApiLocator:     frame.NewApi(ctx).SetName(GetKeyExampleHandler()),
        Service:        es,
        KeyTestService: service.RegisterKeyTestService(ctx),
    }
}

// GetKeyExampleHandler 定義和獲取 ExampleHandler 註冊到全局管理器的實例key
func GetKeyExampleHandler(ns ...string) string {
    return frame.RegisterKeyName("ExampleHandler", frame.GetNamespace([]string{constant.NameModuleExample}, ns...)...)
}

// GetExample 獲取樣例數據
func (h *ExampleHandler) GetExample(c *fiber.Ctx) error {
    // 獲取語言
    var lang = c.Get(constant.XLanguageFlag, "en")

    id := c.Params("id")

    // 構造需要驗證的結構體
    var objId = &requestvo.ObjId{
        ID: id,
    }
    // 獲取驗證包裝器對象
    vw := h.GetContext().GetValidateWrap()

    // 獲取指定語言的驗證器,並對結構體進行驗證
    if errVw := vw.GetValidate(lang).Struct(objId); errVw != nil {
        var errs validator.ValidationErrors
        if errors.As(errVw, &errs) {
            return vw.Errors(errs, lang, true)
        }
    }

    // 從服務層獲取數據
    resp, err := h.Service.GetExample(id)
    if err != nil {
        return err
    }

    // 返回成功響應
    return response.RespSuccess(resp).JsonWithCtx(c)
}
  • 定義樣例服務: 見 example_application/module/example-module/service/example_service.go
// ExampleService 樣例服務,繼承 frame.ServiceLocator 服務定位器接口,具備獲取上下文、配置、日誌、註冊實例等功能
type ExampleService struct {
    frame.ServiceLocator                               // 繼承服務定位器接口
    Repo                 *repository.ExampleRepository // 依賴的組件: 樣例倉庫,構造參數注入。由wire工具依賴注入
}

func NewExampleService(ctx frame.ContextFramer, repo *repository.ExampleRepository) *ExampleService {
    name := GetKeyExampleService()
    return &ExampleService{
        ServiceLocator: frame.NewService(ctx).SetName(name),
        Repo:           repo,
    }
}

// GetKeyExampleService 獲取 ExampleService 註冊鍵名
func GetKeyExampleService(ns ...string) string {
    return frame.RegisterKeyName("ExampleService", frame.GetNamespace([]string{constant.NameModuleExample}, ns...)...)
}

// GetExample 根據ID獲取樣例數據
func (s *ExampleService) GetExample(id string) (*responsevo.ExampleRespVo, error) {
    resp := responsevo.ExampleRespVo{}
    // 調用倉儲層獲取數據
    example, err := s.Repo.GetExampleById(id)
    if err != nil {
        return nil, err
    }
    // 處理數據
    resp.ExamName = example.Name
    resp.ExamAge = example.Age
    resp.Courses = example.Courses
    resp.Profile = example.Profile
    resp.CreatedAt = example.CreatedAt
    resp.UpdatedAt = example.UpdatedAt
    // 返回數據
    return &resp, nil
}
  • 定義樣例倉儲: 見 example_application/module/example-module/repository/example_repository.go
// ExampleRepository Example倉庫,負責Example業務的數據持久化操作,繼承frame.RepositoryLocator倉庫定位器接口,具備獲取上下文、配置、日誌、註冊實例等功能
type ExampleRepository struct {
    frame.RepositoryLocator
    Model *model.ExampleModel
}

func NewExampleRepository(ctx frame.ContextFramer, m *model.ExampleModel) *ExampleRepository {
    return &ExampleRepository{
        RepositoryLocator: frame.NewRepository(ctx).SetName(GetKeyExampleRepository()),
        Model:             m,
    }
}

// GetKeyExampleRepository 獲取 ExampleRepository 註冊鍵名
func GetKeyExampleRepository(ns ...string) string {
    return frame.RegisterKeyName("ExampleRepository", frame.GetNamespace([]string{constant.NameModuleExample}, ns...)...)
}

// RegisterKeyExampleRepository 註冊 ExampleRepository 到容器(延遲初始化)並返回註冊key
func RegisterKeyExampleRepository(ctx frame.ContextFramer, ns ...string) string {
    return frame.RegisterKeyInitializerFunc(GetKeyExampleRepository(ns...), func() (interface{}, error) {
        m := model.NewExampleModel(ctx)
        return NewExampleRepository(ctx, m), nil
    })
}

// GetExampleById 根據ID獲取Example示例數據
func (r *ExampleRepository) GetExampleById(id string) (*entity.Example, error) {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    result, err := r.Model.GetExampleByID(ctx, id)
    if err != nil {
        if errors.Is(err, mongo.ErrNoDocuments) {
            return nil, exception.GetNotFoundDocument() // 返回error
        }
        exception.GetInternalError().RespError(err.Error()).Panic() // 直接panic
    }
    return result, nil
}
  • 定義樣例模型: 見 example_application/module/example-module/model/example_model.go
// ExampleModel Example模型,繼承MongoLocator定位器接口,具備獲取上下文、配置、日誌、註冊實例等功能 以及基本的mongodb操作能力
type ExampleModel struct {
    dbmongo.MongoLocator
    ctx context.Context // 可選屬性
}

func NewExampleModel(ctx frame.ContextFramer) *ExampleModel {
    return &ExampleModel{
        MongoLocator: dbmongo.NewMongoModel(ctx, constant.MongoInstanceKey).SetDbName(constant.DbNameMongo).SetTable(constant.CollExample).
            SetName(GetKeyExampleModel()).(dbmongo.MongoLocator), // 設置當前模型的配置項名(mongodb)和庫名(test)
        ctx: context.Background(),
    }
}

// GetKeyExampleModel 獲取模型註冊key
func GetKeyExampleModel(ns ...string) string {
    return frame.RegisterKeyName("ExampleModel", frame.GetNamespace([]string{constant.NameModuleExample}, ns...)...)
}

// RegisterKeyExampleModel 註冊模型到容器(延遲初始化)並返回註冊key
func RegisterKeyExampleModel(ctx frame.ContextFramer, ns ...string) string {
    return frame.RegisterKeyInitializerFunc(GetKeyExampleModel(ns...), func() (interface{}, error) {
        return NewExampleModel(ctx), nil
    })
}

// GetExampleByID 根據ID獲取樣例文檔
func (m *ExampleModel) GetExampleByID(ctx context.Context, oid string) (*entity.Example, error) {
    _id, err := bson.ObjectIDFromHex(oid)
    if err != nil {
        exception.GetInputError().RespError(err.Error()).Panic()
    }
    filter := bson.D{{"_id", _id}}
    opts := options.FindOne().SetProjection(bson.M{
        "_id":     0,
        "profile": 0,
    })
    var example entity.Example
    err = m.GetCollection(m.GetColl()).FindOne(ctx, filter, opts).Decode(&example)
    if err != nil {
        return nil, err
    }
    return &example, nil
}
  • 調用鏈路總結: 如 獲取樣例數據接口 GET /example/get/:id

    • 路由註冊: RegisterRouteHandlers -> exampleGroup.Get("/get/:id", exampleApi.GetExample)
    • Api處理器: ExampleHandler.GetExample -> h.Service.GetExample
    • 服務層: ExampleService.GetExample -> s.Repo.GetExampleById
    • 倉儲層: ExampleRepository.GetExampleById -> r.Model.GetExampleByID
    • 模型層: ExampleModel.GetExampleByID -> m.GetCollection(m.GetColl()).FindOne(...)
    • 實體層: entity.Example
    • 響應層: e.g. response.RespSuccess(resp).JsonWithCtx(c) -> response.RespInfo

如何添加新的模塊和新的api

  • 參考樣例: example_application/module/example-module
  • 複製樣例模塊目錄:從 example-module 目錄複製一份作為新模塊的起始模板

cp -r example_application/module/example-module example_application/module/mymodule
  • 修改模塊相關文件:

    • 常量定義:修改 constant/constants.go 中的模塊名稱常量
    • 實體類型:修改 entity/types.go 中的實體結構體定義
    • 模型層:修改 model/ 目錄下的模型文件,更新模型名稱和數據庫表名
    • 倉儲層:修改 repository/ 目錄下的倉儲文件,更新倉儲接口和實現
    • 服務層:修改 service/ 目錄下的服務文件,更新業務邏輯
    • API層:修改 api/ 目錄下的API控制器文件,更新接口定義
  • 註冊新模塊API路由:在 module/route_register.go 中添加新模塊路由註冊
// 在 RegisterApiRouters 函數中添加
mymodule.RegisterRouteHandlers(ctx, app)
  • 更新Wire依賴注入:運行 wire 命令重新生成依賴注入代碼

    # 進入新模塊的api目錄
    cd example_application/module/mymodule/api
    
    # 運行wire命令生成依賴注入代碼,指定生成代碼文件的前綴
    wire gen -output_file_prefix api_provider_

task異步任務的使用樣例

  • 定義唯一任務名稱: 見 example_application/module/example-module/task/names.go
package task

// A list of task types. 任務名稱的列表
const (
    // TypeExampleCreate 定義任務名稱,異步創建一個樣例數據
    TypeExampleCreate = "ex:example:create:create-an-example"
)
  • 新建任務: 見 example_application/module/example-module/task/task.go
/*
Task payload list 任務負載列表
*/

// PayloadExampleCreate 樣例創建負載的數據
type PayloadExampleCreate struct {
    frame.PayloadBase // 繼承基礎負載結構體,自動具備獲取json編解碼器的方法
    /**
    負載的數據
    */
    Age int8
}

// NewExampleCreateTask 生成一個 ExampleCreate 任務,從調用處獲取相關參數,並返回任務
func NewExampleCreateTask(ctx frame.IContext, age int8) (*asynq.Task, error) {
    vo := PayloadExampleCreate{
        Age: age,
    }
    // 獲取json編解碼器,將負載數據編碼為json格式的字節切片
    payload, err := vo.GetMustJsonHandler(ctx).Marshal(&vo)
    if err != nil {
        return nil, err
    }
    return asynq.NewTask(TypeExampleCreate, payload, asynq.Retention(24*time.Hour), asynq.MaxRetry(3), asynq.ProcessIn(1*time.Minute)), nil
}
  • 定義任務處理器: 見 example_application/module/example-module/task/handler/handle.go
// HandleExampleCreateTask 樣例任務創建的處理器
func HandleExampleCreateTask(ctx context.Context, t *asynq.Task) error {
    // 從 context 中獲取 appCtx 全局應用上下文,獲取包括配置、日誌、註冊實例等組件
    appCtx, _ := ctx.Value(frame.ContextKeyAppCtx).(frame.ContextFramer)

    // 聲明任務負載對象
    var p task.PayloadExampleCreate

    // 解析任務負載
    if err := p.GetMustJsonHandler(appCtx).Unmarshal(t.Payload(), &p); err != nil {
        appCtx.GetLogger().Error(appCtx.GetConfig().LogOriginWeb()).Str("From", "HandleExampleCreateTask").Err(err).Msg("[Asynq]: Unmarshal error")
        return err
    }

    // 獲取處理任務的實例,注意service.TestService需在任務掛載階段註冊到全局管理器
    // 見 task/handler/mount.go: service.RegisterKeyTestService(ctx)
    instance, err := frame.GetInstance[*service.TestService](service.GetKeyTestService())
    if err != nil {
        return err
    }

    // 將負參數傳入實例的處理函數
    result, err := instance.DoAgeDoubleCreateForTaskHandle(p.Age)
    if err != nil {
        return err
    }

    // 記錄結果
    appCtx.GetLogger().InfoWith(appCtx.GetConfig().LogOriginTask()).Msgf("HandleExampleCreateTask 執行成功,結果 Age double: %d", result)
    return nil
}
  • 任務掛載器: 見 example_application/module/example-module/task/handler/mount.go
package handler

import (
    "github.com/lamxy/fiberhouse/example_application/module/example-module/service"
    "github.com/lamxy/fiberhouse/example_application/module/example-module/task"
    "github.com/lamxy/fiberhouse/frame"
)

// RegisterTaskHandlers 統一註冊任務處理函數和依賴的組件實例初始化器
func RegisterTaskHandlers(tk frame.TaskRegister) {
    // append task handler to global taskHandlerMap
    // 通過RegisterKeyXXX註冊任務處理的實例初始化器,並獲取註冊實例的keyName

    // 統一註冊全局管理實例初始化器,該實例可在任務處理函數中通過tk.GetContext().GetContainer().GetXXXService()獲取,用來執行具體的任務處理邏輯
    service.RegisterKeyTestService(tk.GetContext())

    // 統一追加任務處理函數到Task註冊器對象的任務名稱映射的屬性中
    tk.AddTaskHandlerToMap(task.TypeExampleCreate, HandleExampleCreateTask)
}
  • 將任務推送到隊列: 見 example_application/module/example-module/api/example_api.go
    調用了 example_application/module/example-module/service/example_service.go 的 GetExampleWithTaskDispatcher 方法
// GetExampleWithTaskDispatcher 示例方法,演示如何在服務方法中使用任務調度器異步執行任務
func (s *ExampleService) GetExampleWithTaskDispatcher(id string) (*responsevo.ExampleRespVo, error) {
    resp := responsevo.ExampleRespVo{}
    example, err := s.Repo.GetExampleById(id)
    if err != nil {
        return nil, err
    }

    // 獲取帶任務標記的日誌器,從全局管理器獲取已附加了日誌源標記的日誌器
    log := s.GetContext().GetMustLoggerWithOrigin(s.GetContext().GetConfig().LogOriginTask())

    // 獲取樣例數據成功,推送延遲任務異步執行
    dispatcher, err := s.GetContext().(frame.ContextFramer).GetStarterApp().GetTask().GetTaskDispatcher()
    if err != nil {
        log.Warn().Err(err).Str("Category", "asynq").Msg("GetExampleWithTaskDispatcher GetTaskDispatcher failed")
    }
    // 創建任務對象
    task1, err := task.NewExampleCreateTask(s.GetContext(), int8(example.Age))
    if err != nil {
        log.Warn().Err(err).Str("Category", "asynq").Msg("GetExampleWithTaskDispatcher NewExampleCountTask failed")
    }
    // 將任務對象入隊
    tInfo, err := dispatcher.Enqueue(task1, asynq.MaxRetry(constant.TaskMaxRetryDefault), asynq.ProcessIn(1*time.Minute)) // 任務入隊,並將在1分鐘後執行

    if err != nil {
        log.Warn().Err(err).Msg("GetExampleWithTaskDispatcher Enqueue failed")
    } else if tInfo != nil {
        log.Warn().Msgf("GetExampleWithTaskDispatcher Enqueue task info: %v", tInfo)
    }

    // 正常的業務邏輯
    resp.ExamName = example.Name
    resp.ExamAge = example.Age
    resp.Courses = example.Courses
    resp.Profile = example.Profile
    resp.CreatedAt = example.CreatedAt
    resp.UpdatedAt = example.UpdatedAt
    return &resp, nil
}

緩存組件使用樣例

  • 見獲取樣例列表接口: example_application/module/example-module/api/example_api.go 的 GetExamples 方法
    調用樣例服務的 GetExamplesWithCache 方法: example_application/module/example-module/service/example_service.go

func (s *ExampleService) GetExamples(page, size int) ([]responsevo.ExampleRespVo, error) {
    // 從緩存選項池獲取緩存選項對象
    co := cache.OptionPoolGet(s.GetContext())
    // 使用完的緩存選項對象歸還對象池
    defer cache.OptionPoolPut(co)

    // 設置緩存參數: 二級緩存、啓用本地緩存、設置緩存key、設置本地緩存隨機過期時間(10秒±10%)、設置遠程緩存隨機過期時間(3分鐘±1分鐘)、寫遠程緩存同步策略、設置上下文、啓用緩存全部的保護措施
    co.Level2().EnableCache().SetCacheKey("key:example:list:page:"+strconv.Itoa(page)+":size:"+strconv.Itoa(size)).SetLocalTTLRandomPercent(10*time.Second, 0.1).
        SetRemoteTTLWithRandom(3*time.Minute, 1*time.Minute).SetSyncStrategyWriteRemoteOnly().SetContextCtx(context.TODO()).EnableProtectionAll()

    // 獲取緩存數據,調用緩存包的 GetCached 方法,傳入緩存選項對象和獲取數據的回調函數
    return cache.GetCached[[]responsevo.ExampleRespVo](co, func(ctx context.Context) ([]responsevo.ExampleRespVo, error) {
        list, err := s.Repo.GetExamples(page, size)

        if err != nil {
            return nil, err
        }
        examples := make([]responsevo.ExampleRespVo, 0, len(list))
        for i := range list {
            example := responsevo.ExampleRespVo{
                ID:       list[i].ID.Hex(),
                ExamName: list[i].Name,
                ExamAge:  list[i].Age,
                Courses:  list[i].Courses,
                Profile:  list[i].Profile,
                Timestamps: commonvo.Timestamps{
                    CreatedAt: list[i].CreatedAt,
                    UpdatedAt: list[i].UpdatedAt,
                },
            }
            examples = append(examples, example)
        }
        return examples, nil
    })
}

CMD命令行應用使用樣例

  • 命令行框架應用main入口 : 見 example_application/command/main.go
package main

import (
    "github.com/lamxy/fiberhouse/example_application/command/application"
    "github.com/lamxy/fiberhouse/frame"
    "github.com/lamxy/fiberhouse/frame/bootstrap"
    "github.com/lamxy/fiberhouse/frame/commandstarter"
)

func main() {
    // bootstrap 初始化啓動配置(全局配置、全局日誌器),配置路徑為當前工作目錄下的"./../config"
    cfg := bootstrap.NewConfigOnce("./../../example_config")

    // 全局日誌器,定義日誌目錄為當前工作目錄下的"./logs"
    logger := bootstrap.NewLoggerOnce(cfg, "./logs")

    // 初始化命令全局上下文
    ctx := frame.NewCmdContextOnce(cfg, logger)

    // 初始化應用註冊器對象,注入應用啓動器
    appRegister := application.NewApplication(ctx) // 需實現框架關於命令行應用的 frame.ApplicationCmdRegister接口

        // 實例化命令行應用啓動器
        cmdlineStarter := &commandstarter.CMDLineApplication{
            // 實例化框架命令啓動器對象
            FrameCmdStarter: commandstarter.NewFrameCmdApplication(ctx, option.WithCmdRegister(appRegister)),
            // 實例化核心命令啓動器對象
            CoreCmdStarter: commandstarter.NewCoreCmdCli(ctx),
        }
    // 運行命令行啓動器
    commandstarter.RunCommandStarter(cmdlineStarter)
}
  • 編寫一個命令腳本: 見 example_application/command/application/commands/test_orm_command.go
// TestOrmCMD 測試go-orm庫的CURD操作命令,需實現 frame.CommandGetter 接口,通過 GetCommand 方法返回命令行命令對象
type TestOrmCMD struct {
    Ctx frame.ContextCommander
}

func NewTestOrmCMD(ctx frame.ContextCommander) frame.CommandGetter {
    return &TestOrmCMD{
        Ctx: ctx,
    }
}

// GetCommand 獲取命令行命令對象,實現 frame.CommandGetter 接口的 GetCommand方法
func (m *TestOrmCMD) GetCommand() interface{} {
    return &cli.Command{
        Name:    "test-orm",
        Aliases: []string{"orm"},
        Usage:   "測試go-orm庫CURD操作",
        Flags: []cli.Flag{
            &cli.StringFlag{
                Name:     "method",
                Aliases:  []string{"m"},
                Usage:    "測試類型(ok/orm)",
                Required: true,
            },
            &cli.StringFlag{
                Name:     "operation",
                Aliases:  []string{"o"},
                Usage:    "CURD(c創建|u更新|r讀取|d刪除)",
                Required: false,
            },
            &cli.UintFlag{
                Name:     "id",
                Aliases:  []string{"i"},
                Usage:    "主鍵ID",
                Required: true,
            },
        },
        Action: func(cCtx *cli.Context) error {
            var (
                ems  *service.ExampleMysqlService
                wrap = component.NewWrap[*service.ExampleMysqlService]()
            )

            // 使用dig注入所需依賴,通過provide連綴方法連續注入依賴組件
            dc := m.Ctx.GetDigContainer().
                Provide(func() frame.ContextCommander { return m.Ctx }).
                Provide(model.NewExampleMysqlModel).
                Provide(service.NewExampleMysqlService)

            // 錯誤處理
            if dc.GetErrorCount() > 0 {
                return fmt.Errorf("dig container init error: %v", dc.GetProvideErrs())
            }

            /*
            // 通過Invoke方法獲取依賴組件,在回調函數中使用依賴組件
            err := dc.Invoke(func(ems *service.ExampleMysqlService) error {
                err := ems.AutoMigrate()
                if err != nil {
                    return err
                }
                // 其他操作...
                return nil
            })
            */

            // 另一種方式,使用泛型Invoke方法獲取依賴組件,通過component.Wrap輔助類型來獲取依賴組件
            err := component.Invoke[*service.ExampleMysqlService](wrap)
            if err != nil {
                return err
            }

            // 獲取依賴組件
            ems = wrap.Get()

            // 自動創建一次數據表
            err = ems.AutoMigrate()
            if err != nil {
                return err
            }

            // 獲取命令行參數
            method := cCtx.String("method")

            // 執行測試
            if method == "ok" {
                testOk := ems.TestOk()

                fmt.Println("result: ", testOk, "--from:", method)
            } else if method == "orm" {
                // 獲取更多命令行參數
                op := cCtx.String("operation")
                id := cCtx.Uint("id")

                // 執行測試orm
                err := ems.TestOrm(m.Ctx, op, id)
                if err != nil {
                    return err
                }

                fmt.Println("result: testOrm OK", "--from:", method)
            } else {
                return fmt.Errorf("unknown method: %s", method)
            }

            return nil
        },
    }
}
  • 命令行構建: 見 example_application/command/README_go_build.md
# 構建
cd command/  # command ROOT Directory
go build -o ./target/cmdstarter.exe ./main.go 

# 執行命令幫助
cd command/    ## work dir is ~/command/, configure path base on it
./target/cmdstarter.exe -h
  • 命令行應用使用説明

    • 編譯命令行應用: go build -o ./target/cmdstarter.exe ./main.go
    • 運行命令行應用查看幫助: ./target/cmdstarter.exe -h
    • 運行測試go-orm庫的CURD操作命令: ./target/cmdstarter.exe test-orm --method ok./target/cmdstarter.exe test-orm -m ok
    • 運行測試go-orm庫的CURD操作命令(創建數據): ./target/cmdstarter.exe test-orm --method orm --operation c --id 1./target/cmdstarter.exe test-orm -m orm -o c -i 1
    • 子命令行參數幫助説明: ./target/cmdstarter.exe test-orm -h

🔧 配置説明

應用全局配置

FiberHouse 支持基於環境的多配置文件管理,配置文件位於 example_config/ 目錄。全局配置對象位於框架上下文對象中,可通過 ctx.GetConfig() 方法獲取。

  • 配置文件 README: 見 example_config/README.md
  • 配置文件命名規則
配置文件格式: application_[應用類型]_[環境].yml
應用類型: web | cmd
環境類型: dev | test | prod

示例文件:
- application_web_dev.yml     # Web應用開發環境
- application_web_test.yml    # Web應用測試環境  
- application_web_prod.yml    # Web應用生產環境
- application_cmd_test.yml    # 命令行應用測試環境
  • 環境變量配置
# 引導環境變量 (APP_ENV_ 前綴):
APP_ENV_application_appType=web    # 設置應用類型: web/cmd
APP_ENV_application_env=prod       # 設置運行環境: dev/test/prod

# 配置覆蓋環境變量 (APP_CONF_ 前綴):
APP_CONF_application_appName=MyApp              # 覆蓋應用名稱
APP_CONF_application_server_port=9090           # 覆蓋服務端口
APP_CONF_application_appLog_level=error         # 覆蓋日誌級別
APP_CONF_application_appLog_asyncConf_type=chan # 覆蓋異步日誌類型
核心配置項
  • 應用基礎配置:

    application:
    appName: "FiberHouse"           # 應用名稱
    appType: "web"                  # 應用類型: web/cmd
    env: "dev"                      # 運行環境: dev/test/prod
    
    server:
      host: "127.0.0.1"              # 服務主機
      port: 8080                     # 服務端口
  • 日誌系統配置:

    application:
    appLog:
      level: "info"                # 日誌級別: debug/info/warn/error
      enableConsole: true          # 啓用控制枱輸出
      consoleJSON: false           # 控制枱JSON格式
      enableFile: true             # 啓用文件輸出
      filename: "app.log"          # 日誌文件名
      
      # 異步日誌配置
      asyncConf:
        enable: true              # 啓用異步日誌
        type: "diode"             # 異步類型: chan/diode
        
      # 日誌輪轉配置  
      rotateConf:
        maxSize: 5                             # megabytes
        maxBackups: 5                          # 最大備份文件數
        maxAge: 7                              # days
        compress: false                        # disabled by default
  • 數據庫配置:

    # MySQL 配置
    mysql:
    dsn: "root:root@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local&timeout=10s"
    gorm:
      maxIdleConns: 10                       # 最大空閒連接數
      maxOpenConns: 100                      # 最大打開連接數
      connMaxLifetime: 3600                  # 連接最大生命週期,單位秒
      connMaxIdleTime: 300                   # 連接最大空閒時間,單位秒
      logger:
        level: info                        # 日誌級別: silent、error、warn、info
        slowThreshold: 200 * time.Millisecond # 慢SQL閾值,建議 200 * time.Millisecond,根據實際業務調整
        colorful: false                    # 是否彩色輸出
        enable: true                       # 是否啓用日誌記錄
        skipDefaultFields: true            # 跳過默認字段
    pingTry: false
  • redis配置:

    redis:
    host: "127.0.0.1"
    port: 6379
    password: ""
    database: 0
    poolSize: 100                # 連接池大小
    
    # 集羣配置 (可選)
    cluster:
      addrs: ["127.0.0.1:6379"]
      poolSize: 100
  • 緩存系統配置:

    cache:
    # 本地緩存
    local:                                     # 本地緩存配置
      numCounters: 1000000                     # 100萬個計數器
      maxCost: 134217728                       # 最大緩存128M
      bufferItems: 64                          # 每個緩存分區的緩衝區大小
      metrics: true                            # 是否啓用緩存指標
      IgnoreInternalCost: false                # 是否忽略內部開銷
        
    # 遠程緩存  
    redis:                                     # remote 遠程緩存配置
      host: 127.0.0.1                          # Redis 服務器地址
      port: 6379                               # Redis 服務器端口
      password: ""                             # Redis 服務器密碼
    # 異步池配置
    asyncPool:                               # 啓用二級緩存時的異步goroutine池配置,用於處理緩存更新和同步策略
      ants:                                  # ants異步goroutine池配置
        local:
          size: 248                          # 本地緩存異步goroutine池大小
          expiryDuration: 5                  # 單位秒,空閒goroutine超時時間
          preAlloc: false                    # 不預分配
          maxBlockingTasks: 512              # 最大阻塞任務數
          nonblocking: false                 # 允許阻塞
  • 任務組件配置

    task:
      enableServer: true                       # 是否啓用任務調度服務組件支持
  • 更多配置按需自定義
  • 完整配置示例參考:

    • 測試環境配置: example_config/application_web_test.yml
    • 命令行測試環境配置: application_cmd_test.yml

🤝 貢獻指南

快速開始

  • Fork 倉庫並 Clone
  • 創建分支:git checkout -b feature/your-feature
  • 開發並保持格式:go fmt ./... && golangci-lint run
  • 運行測試:go test ./... -race -cover
  • 提交:feat(module): 描述
  • 推送併發起 PR

分支策略

  • main:穩定發佈
  • develop:集成開發
  • feature/*:功能
  • fix/*:缺陷
  • 其它分類

PR 要求

  • 標題:與提交信息一致
  • 內容:背景 / 方案 / 影響 / 測試 / 關聯 Issue
  • CI 通過

安全

安全漏洞請私信:pytho5170@hotmail.com

📄 許可證

本項目基於 MIT 許可證開源 - 查看 LICENSE 文件瞭解詳情。

🙋‍♂️ 支持與反饋

  • 如果您感興趣,或者支持FiberHouse的持續開發,請在GitHub上點個星GitHub Star
  • 問題反饋: Issues
  • 聯繫郵箱: pytho5170@hotmail.com

🌟 致謝

感謝以下開源項目:

  • gofiber/fiber - 高性能 HTTP 內核
  • rs/zerolog - 高性能結構化日誌
  • knadh/koanf - 靈活的多源配置管理
  • bytedance/sonic - 高性能 JSON 編解碼
  • dgraph-io/ristretto - 高性能本地緩存
  • hibiken/asynq - 基於 Redis 的分佈式任務隊列
  • go.mongodb.org/mongo-driver - MongoDB 官方驅動
  • gorm.io/gorm - ORM 抽象與 MySQL 支撐
  • redis/go-redis - Redis 客户端
  • panjf2000/ants - 高性能 goroutine 池

同時感謝:

  • swaggo/swag 提供 API 文檔生成
  • google/wire、uber-go/dig 支持依賴注入模式
  • 以及所有未逐一列出的優秀項目

最後感謝:GitHub Copilot 提供的資料查閲、文檔整理和編碼輔助能力。

github地址:https://github.com/lamxy/fiberhouse

user avatar
0 用户, 点赞了这篇动态!

发布 评论

Some HTML is okay.