{"id":31286890,"url":"https://github.com/lamxy/fiberhouse","last_synced_at":"2025-09-28T14:01:59.920Z","repository":{"id":316246775,"uuid":"1061966247","full_name":"lamxy/fiberhouse","owner":"lamxy","description":"fiberhouse 是基于 Fiber 的高性能、可装配的 Go Web 框架，内置全局管理器、配置器、统一日志器、验证包装器以及数据库、缓存、中间件、统一异常处理等框架组件，开箱即用。","archived":false,"fork":false,"pushed_at":"2025-09-23T13:26:34.000Z","size":245,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-23T15:12:51.060Z","etag":null,"topics":["cmd","cmd-framework","fasthttp","fiber","framework","go","golang","goweb","performance","rest-api","web-framework"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lamxy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-22T16:12:45.000Z","updated_at":"2025-09-23T13:06:51.000Z","dependencies_parsed_at":"2025-09-23T15:24:49.620Z","dependency_job_id":null,"html_url":"https://github.com/lamxy/fiberhouse","commit_stats":null,"previous_names":["lamxy/fiberhouse"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/lamxy/fiberhouse","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lamxy%2Ffiberhouse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lamxy%2Ffiberhouse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lamxy%2Ffiberhouse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lamxy%2Ffiberhouse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lamxy","download_url":"https://codeload.github.com/lamxy/fiberhouse/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lamxy%2Ffiberhouse/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276737503,"owners_count":25695698,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-24T02:00:09.776Z","response_time":97,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cmd","cmd-framework","fasthttp","fiber","framework","go","golang","goweb","performance","rest-api","web-framework"],"created_at":"2025-09-24T10:50:03.607Z","updated_at":"2025-09-24T10:50:04.878Z","avatar_url":"https://github.com/lamxy.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FiberHouse Framework\n\n[![Go Version](https://img.shields.io/badge/go-%3E%3D1.24-blue.svg)](https://golang.org/)\n[![Fiber Version](https://img.shields.io/badge/fiber-v2.x-green.svg)](https://github.com/gofiber/fiber)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\u003cimg src=\"https://img.shields.io/github/issues/lamxy/fiberhouse.svg\" alt=\"GitHub Issues\"\u003e\u003c/img\u003e\n\n\n📖 [中文](README.md) | [English](./frame/docs/README_en.md)\n\n## 🏠 关于 FiberHouse\n\nFiberHouse 是基于 Fiber 的高性能、可装配的 Go Web 框架，内置全局管理器、配置器、统一日志器、验证包装器以及数据库、缓存、中间件、统一异常处理等框架组件，开箱即用。\n\n- 提供了强大的全局管理容器，支持自定义组件一次注册到处使用的能力，方便开发者按需替换和功能扩展，\n- 在框架层面约定了应用启动器、全局上下文、业务分层等接口以及内置默认实现，支持自定义实现和模块化开发，\n- 使得 FiberHouse 像装配\"家具\"的\"房子\"一样可以按需构建灵活的、完整的 Go Web 应用。\n\n### 🏆 开发方向 \n\n提供高性能、可扩展、可定制，开箱即用的 Go Web 框架\n\n## ✨ 功能\n\n- **高性能**: 基于 Fiber 框架，提供极速的 HTTP 性能，支持对象池、goroutine池、缓存、异步等性能优化措施\n- **模块化设计**: 清晰的分层架构设计，定义了标准的接口契约和实现，支持团队协作、扩展和模块化开发\n- **全局管理器**: 全局对象管理容器，无锁设计、即时注册、延迟初始化、单例特性，支持可替代第三方依赖注入工具的依赖解决方案、以及生命周期的统一管理\n- **全局配置管理**: 统一配置文件加载、解析和管理，支持多格式配置、环境变量覆盖，适应不同的应用场景\n- **统一日志管理**:  高性能日志系统，支持结构化日志、同步异步写入器，以及各种日志源标识管理\n- **统一异常处理**: 统一异常定义和处理机制，支持错误码模块化管理、集成参数验证器、错误追踪，以及友好的调试体验\n- **参数验证**: 集成开源验证包装器，支持注册自定义语言验证器、tag标签规则和多语言翻译器\n- **数据库支持**: 集成 MySQL、MongoDB 驱动组件以及对数据库模型基类的支持\n- **缓存组件**: 内置高性能的本地、远程和二级缓存组件的组合使用和管理，以及对缓存模型基类的支持\n- **任务队列**: 集成基于 Redis 的高性能 C/S 架构异步任务队列，支持任务调度、延时执行和失败重试等功能\n- **API 文档**: 集成 swag 文档工具，支持自动生成 API 文档\n- **命令行应用**: 完整的命令行应用框架支持，遵循统一的模块化设计，支持团队协作、功能扩展和模块化开发\n- **样例模板**: 提供完整的Web应用和CMD应用样例模板结构，涵盖了常见场景和最佳实践，开发者稍作修改即可直接套用\n- **更多**: 持续优化和更新中...\n\n## 🏗️ 架构说明\n\n```\nframe/                              # FiberHouse 框架核心\n├── 接口定义层\n│   ├── application_interface.go    # 应用启动器接口定义\n│   ├── command_interface.go        # 命令行应用接口定义  \n│   ├── context_interface.go        # 全局上下文接口定义\n│   ├── json_wraper_interface.go    # JSON 包装器接口定义\n│   ├── locator_interface.go        # 服务定位器接口定义\n│   └── model_interface.go          # 数据模型接口定义\n├── 应用启动层\n│   ├── applicationstarter/         # Web 应用启动器实现\n│   │   └── frame_application.go    # 基于 Fiber 的应用启动器\n│   ├── commandstarter/             # 命令行应用启动器实现\n│   │   └── cmd_application.go      # 命令行应用启动器\n│   └── bootstrap/                  # 应用引导程序\n│       └── bootstrap.go            # 统一引导入口\n├── 配置管理层\n│   └── appconfig/                  # 应用配置管理\n│       └── config.go               # 多格式配置文件加载和管理\n├── 全局管理层\n│   ├── globalmanager/              # 全局对象容器管理\n│   │   ├── interface.go            # 全局管理器接口\n│   │   ├── manager.go              # 全局管理器实现\n│   │   └── types.go                # 全局管理器类型定义\n│   └── global_utility.go           # 全局工具函数\n├── 数据访问层\n│   └── database/                   # 数据库驱动支持\n│       ├── dbmysql/                # MySQL 数据库组件\n│       │   ├── interface.go        # MySQL 接口定义\n│       │   ├── mysql.go            # MySQL 连接实现\n│       │   └── mysql_model.go      # MySQL 模型基类\n│       └── dbmongo/                # MongoDB 数据库组件\n│           ├── interface.go        # MongoDB 接口定义\n│           ├── mongo.go            # MongoDB 连接实现\n│           └── mongo_model.go      # MongoDB 模型基类\n├── 缓存系统层\n│   └── cache/                      # 高性能缓存组件\n│       ├── cache_interface.go      # 缓存接口定义\n│       ├── cache_option.go         # 缓存配置选项\n│       ├── cache_utility.go        # 缓存工具函数\n│       ├── cache_errors.go         # 缓存错误定义\n│       ├── helper.go               # 缓存助手函数\n│       ├── cache2/                 # 二级缓存实现\n│       │   └── level2_cache.go     # 本地+远程二级缓存\n│       ├── cachelocal/             # 本地缓存实现\n│       │   ├── local_cache.go      # 内存缓存实现\n│       │   └── type.go             # 本地缓存类型\n│       └── cacheremote/            # 远程缓存实现\n│           ├── cache_model.go      # 远程缓存模型基类\n│           └── redis_cache.go      # Redis 缓存实现\n├── 组件库层\n│   └── component/                  # 框架核心组件\n│       ├── dig_container.go        # 基于dig依赖注入容器包装\n│       ├── jsoncodec/              # JSON 编解码器\n│       │   └── sonicjson.go        # 基于 Sonic 的高性能 JSON编解码器\n│       ├── jsonconvert/            # JSON 转换工具\n│       │   └── convert.go          # 转换核心实现\n│       ├── mongodecimal/           # MongoDB 十进制处理\n│       │   └── mongo_decimal.go    # MongoDB Decimal128 支持\n│       ├── validate/               # 参数验证组件\n│       │   ├── type_interface.go   # 验证器接口定义\n│       │   ├── validate_wrapper.go # 验证器包装实现\n│       │   ├── en.go               # 英文验证器实现\n│       │   ├── zh_cn.go            # 简体中文验证器实现\n│       │   ├── zh_tw.go            # 繁体中文验证器实现\n│       │   └── example/            # 注册示例\n│       ├── tasklog/                # 任务日志组件\n│       │   └── logger_adapter.go   # 日志适配器\n│       └── writer/                 # 日志写入器\n│           ├── async_channel_writer.go     # 异步通道写入器\n│           ├── async_diode_writer.go       # 异步二极管写入器\n│           ├── async_diode_writer_test.go  # 异步写入器测试\n│           └── sync_lumberjack_writer.go   # 同步滚动日志写入器\n├── 中间件层\n│   └── middleware/                 # HTTP 中间件\n│       └── recover/                # 异常恢复中间件\n│           ├── config.go           # 恢复中间件配置\n│           └── recover.go          # 恢复中间件实现\n├── 响应处理层\n│   └── response/                   # 统一响应处理\n│       └── response.go             # 响应对象池和序列化\n├── 异常处理层\n│   └── exception/                  # 统一异常处理\n│       ├── types.go                # 异常类型定义\n│       └── exception_error.go      # 异常错误实现\n├── 工具层\n│   ├── utils/                      # 通用工具函数\n│   │   └── common.go               # 通用工具实现\n│   └── constant/                   # 框架常量\n│       ├── constant.go             # 全局常量定义\n│       └── exception.go            # 异常常量定义\n├── 业务分层\n│   ├── api.go                      # API 层接口定义\n│   ├── service.go                  # 服务层接口定义\n│   ├── repository.go               # 仓储层接口定义\n│   └── task.go                     # 任务层接口定义\n└── 占位模块\n    ├── mq/                         # 消息队列（待实现）\n    ├── plugins/                    # 插件支持（待实现）\n    └── component/\n        ├── i18n/                   # 国际化（待实现）\n        └── rpc/                    # RPC 支持（待实现）\n        \n```\n\n## 🚀 快速开始\n\n### 环境要求\n\n- Go 1.24 或更高版本，推荐升级到1.25+\n- MySQL 5.7+ 或 MongoDB 4.0+\n- Redis 5.0+\n\n### docker 启动数据库、缓存容器用于框架调式\n\n- docker compose文件，见： [docker-compose.yml](./frame/docs/docker_compose_db_redis_yaml/docker-compose.yml)\n- 启动命令: `docker compose up -d`\n\n```bash\n\ncd  frame/docs/docker_compose_db_redis_yaml/\ndocker compose up -d\n```\n\n### 安装\n\nFiberHouse 运行需要 **Go 1.24 或更高版本**。如果您需要安装或升级 Go，请访问 [Go 官方下载页面](https://go.dev/dl/)。\n要开始创建项目，请创建一个新的项目目录并进入该目录。然后，在终端中执行以下命令，使用 Go Modules 初始化您的项目：\n\n```bash\n\ngo mod init github.com/your/repo\n```\n项目设置完成后，您可以使用`go get`命令安装FiberHouse框架：\n\n```bash\n\ngo get github.com/lamxy/fiberhouse\n```\n### main文件示例\n\n参考样例: [example_main/main.go](./example_main/main.go)\n\n```go\npackage main\n\nimport (\n\t\"github.com/lamxy/fiberhouse/example_application\"\n\t\"github.com/lamxy/fiberhouse/example_application/module\"\n\t\"github.com/lamxy/fiberhouse/frame\"\n\t\"github.com/lamxy/fiberhouse/frame/applicationstarter\"\n\t\"github.com/lamxy/fiberhouse/frame/bootstrap\"\n)\n\nfunc main() {\n\t// bootstrap 初始化启动配置(全局配置、全局日志器)，配置目录默认为当前工作目录\".\"下的`example_config/`\n\t// 可以指定绝对路径或基于工作目录的相对路径\n\tcfg := bootstrap.NewConfigOnce(\"./example_config\")\n\t\n\t// 日志目录默认为当前工作目录\".\"下的`example_main/logs`\n\t// 可以指定绝对路径或基于工作目录的相对路径\n\tlogger := bootstrap.NewLoggerOnce(cfg, \"./example_main/logs\")\n\n\t// 初始化全局应用上下文\n\tappContext := frame.NewAppContextOnce(cfg, logger)\n\n\t// 初始化应用注册器、模块/子系统注册器和任务注册器对象，注入到应用启动器\n\tappRegister := example_application.NewApplication(appContext)  // 需实现应用注册器接口，见frame.ApplicationRegisterer接口定义，参考example_application/application.go样例实现\n\tmoduleRegister := module.NewModule(appContext)  // 需实现模块注册器接口，见样例模块module/module.go的实现\n\ttaskRegister := module.NewTaskAsync(appContext)  // 需实现任务注册器接口，见样例任务module/task.go的实现\n\n\t// 实例化框架应用启动器\n\tstarterApp := applicationstarter.NewFrameApplication(appContext, appRegister, moduleRegister, taskRegister)\n\n\t// 运行框架应用启动器\n\tapplicationstarter.RunApplicationStarter(starterApp)\n}\n```\n\n### 快速体验\n\n- web应用快速体验\n\n```bash\n\n# 克隆框架\ngit clone https://github.com/lamxy/fiberhouse.git\n\n# 进入框架目录\ncd fiberhouse\n\n# 安装依赖\ngo mod tidy\n\n# 进入example_main/\ncd example_main/\n\n# 查看README\ncat README_go_build.md\n\n# 构建应用: windows环境为例，其他环境请参考交叉编译\n# 退回到应用根目录（默认工作目录），在工作目录下执行以下命令，构建应用\n# 当前工作目录为 fiberhouse/，构建产物输出到 example_main/target/ 目录\ncd ..\n# windows环境构建产物保留.exe后缀，linux环境无需保留后缀\ngo build \"-ldflags=-X 'main.Version=v0.0.1'\" -o ./example_main/target/examplewebserver.exe ./example_main/main.go\n\n# 运行应用\n# 退回到应用根目录（默认工作目录），在工作目录下执行以下命令，启动应用\n./example_main/target/examplewebserver.exe\n# or Linux、 MacOS\n./example_main/target/examplewebserver\n```\n\n访问hello world接口： http://127.0.0.1:8080/example/hello/world\n\n您将收到响应: {\"code\":0,\"msg\":\"ok\",\"data\":\"Hello World!\"}\n\n```bash\n\ncurl -sL  \"http://127.0.0.1:8080/example/hello/world\"\n\n# 响应:\n{\n    \"code\": 0,\n    \"msg\": \"ok\",\n    \"data\": \"Hello World!\"\n}\n```\n\n- Cmd应用快速体验\n\n```bash\n\n# mysql数据库准备\nmysqlsh root:root@localhost:3306 \n\n# 创建一个test库\nCREATE DATABASE IF NOT EXISTS test CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;\n\n# 克隆框架\ngit clone https://github.com/lamxy/fiberhouse.git\n\n# 进入框架目录\ncd fiberhouse\n\n# 安装依赖\ngo mod tidy\n\n# 进入example_application/command/\ncd example_application/command/\n\n# 查看README\ncat README_go_build.md\n\n# 当前工作目录： command/\n# windows环境构建产物保留.exe后缀，Linux or MacOS环境无需保留后缀\ngo build -o ./target/cmdstarter.exe ./main.go \n\n# 设置cmd应用的环境变量，windows环境，将读取application_cmd_dev.yml配置文件\nset APP_ENV_application_appType=cmd\nset APP_ENV_application_env=dev\n\n# Linux or MacOS 环境\n# export APP_ENV_application_appType=cmd\n# export APP_ENV_application_env=dev\n\n# 执行cmd命令脚本，查看帮助\n./target/cmdstarter.exe -h \n# or \n./target/cmdstarter -h\n\n# 执行子命令，查看控制台日志输出\n./target/cmdstarter.exe test-orm -m ok\n# or \n./target/cmdstarter test-orm -m ok\n\n# 控制台输出 ok\n# result:  ExampleMysqlService.TestOK: OK --from: ok\n\n```\n\n## 📖 使用指南\n\n- examples样例模板项目结构\n- 依赖注入工具说明和使用\n- 通过框架的全局管理器实现无需依赖注入工具来解决依赖关系\n- 样例 curd API实现\n- 如何添加新的模块和新的api\n- task异步任务的使用样例\n- 缓存组件使用样例\n- cmd命令行应用的使用样例\n\n### examples样例应用模板目录结构\n\n- 架构概览与说明\n\n```\nexample_application/                    # 样例应用根目录\n├── 应用配置层\n│   ├── application.go                  # 应用注册器实现\n│   ├── constant.go                     # 应用级常量定义\n│   └── customizer_interface.go         # 应用定制器接口\n├── API 接口层\n│   └── api-vo/                         # API 值对象定义\n│       ├── commonvo/                   # 通用 VO\n│       │   └── vo.go                   # 通用值对象\n│       └── example/                    # 示例模块 VO\n│           ├── api_interface.go        # API 接口定义\n│           ├── requestvo/              # 请求 VO\n│           │   └── example_reqvo.go    # 示例请求对象\n│           └── responsevo/             # 响应 VO\n│               └── example_respvo.go   # 示例响应对象\n├── 命令行框架应用层\n│   └── command/                        # 命令行程序\n│       ├── main.go                     # 命令行main入口\n│       ├── README_go_build.md          # 构建说明\n│       ├── application/                \n│       │   ├── application.go          # 命令应用配置和逻辑\n│       │   ├── constants.go            # 命令常量\n│       │   ├── functions.go            # 命令工具函数\n│       │   └── commands/               # 具体命令脚本实现\n│       │       ├── test_orm_command.go # ORM 测试命令\n│       │       └── test_other_command.go # 其他更多开发的命令脚本...\n│       ├── component/                  # 命令行组件\n│       │   ├── cron.go                 # 定时任务组件\n│       │   └── readme.md               # 组件说明\n│       └── target/                     # 构建产物\n│           └── cmdstarter.exe          # 命令行可执行文件\n├── 异常处理层\n│   ├── get_exceptions.go               # 异常获取器\n│   └── example-module/                 # 示例模块异常，其他模块异常，每个模块独立目录\n│       └── exceptions.go               # 模块异常汇总\n├── 中间件层\n│   └── middleware/                     # 应用级中间件\n│       └── register_app_middleware.go  # 应用中间件注册器\n├── 模块(子系统)层\n│   └── module/                         # 业务模块\n│       ├── module.go                   # 模块注册器\n│       ├── route_register.go           # 路由注册器\n│       ├── swagger.go                  # Swagger 文档配置\n│       ├── task.go                     # 异步任务注册器\n│       ├── api/                        # 模块级 API 中间件\n│       │   └── register_module_middleware.go\n│       ├── command-module/             # 命令行脚本专用的业务模块\n│       │   ├── entity/                 # 实体定义\n│       │   │   └── mysql_types.go      # MySQL 类型定义\n│       │   ├── model/                  # 数据模型\n│       │   │   ├── mongodb_model.go    # MongoDB 模型\n│       │   │   └── mysql_model.go      # MySQL 模型\n│       │   └── service/                # 业务服务\n│       │       ├── example_mysql_service.go  # MySQL 服务示例\n│       │       └── mongodb_service.go        # MongoDB 服务示例\n│       ├── common-module/           # 通用模块\n│       │   ├── attrs/                  # 属性定义\n│       │   │   └── attr1.go            # 属性示例\n│       │   ├── command/                # 通用命令\n│       │   ├── fields/                 # 通用字段\n│       │   │   └── timestamps.go       # 时间戳字段\n│       │   ├── model/                  # 通用模型\n│       │   ├── repository/             # 通用仓储\n│       │   ├── service/                # 通用服务\n│       │   └── vars/                   # 通用变量\n│       │       └── vars.go             # 变量定义\n│       ├── constant/                # 常量定义\n│       │   └── constants.go            # 模块常量\n│       └── example-module/          # 用于展示的核心样例模块\n│           ├── api/                    # API 控制器层\n│           │   ├── api_provider_wire_gen.go    # Wire 依赖注入生成文件\n│           │   ├── api_provider.go             # API 提供者，提供依赖关系\n│           │   ├── common_api.go               # 通用 API 控制器\n│           │   ├── example_api.go              # 示例 API 控制器\n│           │   ├── health_api.go               # 健康检查 API 控制器\n│           │   ├── README_wire_gen.md          # Wire 生成说明\n│           │   └── register_api_router.go      # API 路由注册\n│           ├── dto/                    # 数据传输对象\n│           ├── entity/                 # 实体层\n│           │   └── types.go            # 类型定义\n│           ├── model/                  # 模型层\n│           │   ├── example_model.go            # 示例模型\n│           │   ├── example_mysql_model.go      # MySQL 示例模型\n│           │   └── model_wireset.go            # 模型 Wire 集合\n│           ├── repository/             # 仓储层\n│           │   ├── example_repository.go       # 示例仓储\n│           │   ├── health_repository.go        # 健康检查仓储\n│           │   └── repository_wireset.go       # 仓储 Wire 集合\n│           ├── service/                # 服务层\n│           │   ├── example_service.go          # 示例服务\n│           │   ├── health_service.go           # 健康检查服务\n│           │   ├── service_wireset.go          # 服务 Wire 集合\n│           │   └── test_service.go             # 测试服务\n│           └── task/                   # 任务层\n│               ├── names.go            # 任务名称定义\n│               ├── task.go             # 任务注册器\n│               └── handler/            # 任务处理器\n│                   ├── handle.go       # 任务处理逻辑\n│                   └── mount.go        # 任务挂载器\n├── 工具层\n│   └── utils/                          # 应用工具\n│       └── common.go                   # 通用工具函数\n└── 自定义验证器层\n    └── validatecustom/                 # 自定义验证器\n        ├── tag_register.go             # 标签注册器\n        ├── validate_initializer.go     # 验证器初始化\n        ├── tags/                       # 自定义标签\n        │   ├── new_tag_hascourses.go   # 课程验证标签\n        │   └── tag_startswith.go       # 前缀验证标签\n        └── validators/                 # 多语言验证器\n            ├── ja.go                   # 日语验证器\n            ├── ko.go                   # 韩语验证器\n            └── langs_const.go          # 语言常量\n```\n\n### 依赖注入工具说明和使用\n\n- 依赖注入工具和库\n  - google wire: 依赖注入代码生成工具，官方地址 [https://github.com/google/wire](https://github.com/google/wire)\n  - uber dig: 依赖注入容器，推荐仅在应用启动阶段使用，官方地址 [https://github.com/uber-go/dig](https://github.com/uber-go/dig)\n- google wire使用说明和示例，参考:\n  - [example_application/module/example-module/api/api_provider.go](./example_application/module/example-module/api/api_provider.go)\n  - [example_application/module/example-module/api/README_wire_gen.md](./example_application/module/example-module/api/README_wire_gen.md)\n- uber dig使用说明和示例，参考:\n  - [frame/component/dig_container.go](./frame/component/dig_container.go)\n\n### 通过框架的全局管理器实现无需依赖注入工具来解决依赖关系\n\n- 见注册路由示例： [example_application/module/example-module/api/register_api_router.go](./example_application/module/example-module/api/register_api_router.go)\n\n```go\nfunc RegisterRouteHandlers(ctx frame.ContextFramer, app fiber.Router) {\n    // 获取exampleApi处理器\n    exampleApi, _ := InjectExampleApi(ctx) // 由wire编译依赖注入生成注入函数获取ExampleApi\n    \n    // 获取CommonApi处理器，直接NewCommonHandler\n\t\n\t// 直接New，无需依赖注入(Wire注入)，内部依赖走全局管理器延迟获取依赖组件，\n\t// 见 common_api.go: api.CommonHandler\n\tcommonApi := NewCommonHandler(ctx) \n\t\n    // 获取注册更多api处理器并注册相应路由...\n    \n    // 注册Example模块的路由\n    exampleGroup := app.Group(\"/example\")\n\t// hello world\n    exampleGroup.Get(\"/hello/world\", exampleApi.HelloWorld).Name(\"ex_get_example_test\")\n}\n```\n\n- 见CommonHandler通过全局管理器实现无需事先依赖注入服务组件: [example_application/module/example-module/api/common_api.go](./example_application/module/example-module/api/common_api.go)\n\n```go\n// CommonHandler 示例公共处理器，继承自 frame.ApiLocator，具备获取上下文、配置、日志、注册实例等功能\ntype CommonHandler struct {\n\tframe.ApiLocator\n\tKeyTestService string // 定义依赖组件的全局管理器的实例key。通过key即可由 h.GetInstance(key) 方法获取实例，或由 frame.GetMustInstance[T](key) 泛型方法获取实例，\n\t                      // 无需wire或其他依赖注入工具\n}\n\n// NewCommonHandler 直接New，无需依赖注入(Wire) TestService对象，内部走全局管理器获取依赖组件\nfunc NewCommonHandler(ctx frame.ContextFramer) *CommonHandler {\n\treturn \u0026CommonHandler{\n\t\tApiLocator:     frame.NewApi(ctx).SetName(GetKeyCommonHandler()),\n\t\t\n        // 注册依赖的TestService实例初始化器并返回注册实例key，通过 h.GetInstance(key) 方法获取TestService实例\n\t\tKeyTestService: service.RegisterKeyTestService(ctx), \n\t}\n}\n\n// TestGetInstance 测试获取注册实例，通过 h.GetInstance(key) 方法获取TestService注册实例，无需编译阶段的wire依赖注入\nfunc (h *CommonHandler) TestGetInstance(c *fiber.Ctx) error {\n    t := c.Query(\"t\", \"test\")\n    \n    // 通过 h.GetInstance(h.KeyTestService) 方法获取注册实例\n    testService, err := h.GetInstance(h.KeyTestService)\n        if err != nil {\n        return err\n    }\n    \n    if ts, ok := testService.(*service.TestService); ok {\n        return response.RespSuccess(t + \":\" + ts.HelloWorld()).JsonWithCtx(c)\n    }\n    \n    return fmt.Errorf(\"类型断言失败\")\n}\n```\n\n### 样例 curd API实现\n\n- 定义实体类型: 见[example_application/module/example-module/entity/types.go](./example_application/module/example-module/entity/types.go)\n\n```go\n// Example\ntype Example struct {\n\tID                bson.ObjectID             `json:\"id\" bson:\"_id,omitempty\"`\n\tName              string                    `json:\"name\" bson:\"name\"`\n\tAge               int                       `json:\"age\" bson:\"age,minsize\"` // minsize 取int32存储数据\n\tCourses           []string                  `json:\"courses\" bson:\"courses,omitempty\"`\n\tProfile           map[string]interface{}    `json:\"profile\" bson:\"profile,omitempty\"`\n\tfields.Timestamps `json:\"-\" bson:\",inline\"` // inline: bson文档序列化自动提升嵌入字段即自动展开继承的公共字段\n}\n```\n\n- 路由注册：见 [example_application/module/example-module/api/register_api_router.go](./example_application/module/example-module/api/register_api_router.go)\n\n```go\nfunc RegisterRouteHandlers(ctx frame.ContextFramer, app fiber.Router) {\n    // 获取exampleApi处理器\n    exampleApi, _ := InjectExampleApi(ctx) // 由wire编译依赖注入获取\n\t\n    // 注册Example模块的路由\n    // Example 路由组\n    exampleGroup := app.Group(\"/example\")\n\t\n\t// hello world 路由\n    exampleGroup.Get(\"/hello/world\", exampleApi.HelloWorld).Name(\"ex_get_example_test\")\n\t\n\t// CURD 路由\n    exampleGroup.Get(\"/get/:id\", exampleApi.GetExample).Name(\"ex_get_example\")\n    exampleGroup.Get(\"/on-async-task/get/:id\", exampleApi.GetExampleWithTaskDispatcher).Name(\"ex_get_example_on_task\")\n    exampleGroup.Post(\"/create\", exampleApi.CreateExample).Name(\"ex_create_example\")\n    exampleGroup.Get(\"/list\", exampleApi.GetExamples).Name(\"ex_get_examples\")\n}\n```\n\n- 定义样例Api处理器: 见 [example_application/module/example-module/api/example_api.go](./example_application/module/example-module/api/example_api.go)\n\n```go\n// ExampleHandler 示例处理器，继承自 frame.ApiLocator，具备获取上下文、配置、日志、注册实例等功能\ntype ExampleHandler struct {\n\tframe.ApiLocator\n\tService        *service.ExampleService \n\tKeyTestService string                  \n}\n\nfunc NewExampleHandler(ctx frame.ContextFramer, es *service.ExampleService) *ExampleHandler {\n\treturn \u0026ExampleHandler{\n\t\tApiLocator:     frame.NewApi(ctx).SetName(GetKeyExampleHandler()),\n\t\tService:        es,\n\t\tKeyTestService: service.RegisterKeyTestService(ctx),\n\t}\n}\n\n// GetKeyExampleHandler 定义和获取 ExampleHandler 注册到全局管理器的实例key\nfunc GetKeyExampleHandler(ns ...string) string {\n\treturn frame.RegisterKeyName(\"ExampleHandler\", frame.GetNamespace([]string{constant.NameModuleExample}, ns...)...)\n}\n\n// GetExample 获取样例数据\nfunc (h *ExampleHandler) GetExample(c *fiber.Ctx) error {\n\t// 获取语言\n\tvar lang = c.Get(constant.XLanguageFlag, \"en\")\n\n\tid := c.Params(\"id\")\n\n\t// 构造需要验证的结构体\n\tvar objId = \u0026requestvo.ObjId{\n\t\tID: id,\n\t}\n\t// 获取验证包装器对象\n\tvw := h.GetContext().GetValidateWrap()\n\n\t// 获取指定语言的验证器，并对结构体进行验证\n\tif errVw := vw.GetValidate(lang).Struct(objId); errVw != nil {\n\t\tvar errs validator.ValidationErrors\n\t\tif errors.As(errVw, \u0026errs) {\n\t\t\treturn vw.Errors(errs, lang, true)\n\t\t}\n\t}\n\n\t// 从服务层获取数据\n\tresp, err := h.Service.GetExample(id)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// 返回成功响应\n\treturn response.RespSuccess(resp).JsonWithCtx(c)\n}\n```\n\n- 定义样例服务: 见 [example_application/module/example-module/service/example_service.go](./example_application/module/example-module/service/example_service.go)\n\n```go\n// ExampleService 样例服务，继承 frame.ServiceLocator 服务定位器接口，具备获取上下文、配置、日志、注册实例等功能\ntype ExampleService struct {\n\tframe.ServiceLocator                               // 继承服务定位器接口\n\tRepo                 *repository.ExampleRepository // 依赖的组件: 样例仓库，构造参数注入。由wire工具依赖注入\n}\n\nfunc NewExampleService(ctx frame.ContextFramer, repo *repository.ExampleRepository) *ExampleService {\n\tname := GetKeyExampleService()\n\treturn \u0026ExampleService{\n\t\tServiceLocator: frame.NewService(ctx).SetName(name),\n\t\tRepo:           repo,\n\t}\n}\n\n// GetKeyExampleService 获取 ExampleService 注册键名\nfunc GetKeyExampleService(ns ...string) string {\n\treturn frame.RegisterKeyName(\"ExampleService\", frame.GetNamespace([]string{constant.NameModuleExample}, ns...)...)\n}\n\n// GetExample 根据ID获取样例数据\nfunc (s *ExampleService) GetExample(id string) (*responsevo.ExampleRespVo, error) {\n    resp := responsevo.ExampleRespVo{}\n\t// 调用仓储层获取数据\n    example, err := s.Repo.GetExampleById(id)\n    if err != nil {\n        return nil, err\n    }\n\t// 处理数据\n    resp.ExamName = example.Name\n    resp.ExamAge = example.Age\n    resp.Courses = example.Courses\n    resp.Profile = example.Profile\n    resp.CreatedAt = example.CreatedAt\n    resp.UpdatedAt = example.UpdatedAt\n\t// 返回数据\n    return \u0026resp, nil\n}\n```\n\n- 定义样例仓储: 见 [example_application/module/example-module/repository/example_repository.go](./example_application/module/example-module/repository/example_repository.go)\n\n```go\n// ExampleRepository Example仓库，负责Example业务的数据持久化操作，继承frame.RepositoryLocator仓库定位器接口，具备获取上下文、配置、日志、注册实例等功能\ntype ExampleRepository struct {\n\tframe.RepositoryLocator\n\tModel *model.ExampleModel\n}\n\nfunc NewExampleRepository(ctx frame.ContextFramer, m *model.ExampleModel) *ExampleRepository {\n\treturn \u0026ExampleRepository{\n\t\tRepositoryLocator: frame.NewRepository(ctx).SetName(GetKeyExampleRepository()),\n\t\tModel:             m,\n\t}\n}\n\n// GetKeyExampleRepository 获取 ExampleRepository 注册键名\nfunc GetKeyExampleRepository(ns ...string) string {\n\treturn frame.RegisterKeyName(\"ExampleRepository\", frame.GetNamespace([]string{constant.NameModuleExample}, ns...)...)\n}\n\n// RegisterKeyExampleRepository 注册 ExampleRepository 到容器（延迟初始化）并返回注册key\nfunc RegisterKeyExampleRepository(ctx frame.ContextFramer, ns ...string) string {\n\treturn frame.RegisterKeyInitializerFunc(GetKeyExampleRepository(ns...), func() (interface{}, error) {\n\t\tm := model.NewExampleModel(ctx)\n\t\treturn NewExampleRepository(ctx, m), nil\n\t})\n}\n\n// GetExampleById 根据ID获取Example示例数据\nfunc (r *ExampleRepository) GetExampleById(id string) (*entity.Example, error) {\n\tctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\n\tdefer cancel()\n\tresult, err := r.Model.GetExampleByID(ctx, id)\n\tif err != nil {\n\t\tif errors.Is(err, mongo.ErrNoDocuments) {\n\t\t\treturn nil, exception.GetNotFoundDocument() // 返回error\n\t\t}\n\t\texception.GetInternalError().RespError(err.Error()).Panic() // 直接panic\n\t}\n\treturn result, nil\n}\n```\n\n- 定义样例模型: 见 [example_application/module/example-module/model/example_model.go](./example_application/module/example-module/model/example_model.go)\n\n```go\n// ExampleModel Example模型，继承MongoLocator定位器接口，具备获取上下文、配置、日志、注册实例等功能 以及基本的mongodb操作能力\ntype ExampleModel struct {\n\tdbmongo.MongoLocator\n\tctx context.Context // 可选属性\n}\n\nfunc NewExampleModel(ctx frame.ContextFramer) *ExampleModel {\n\treturn \u0026ExampleModel{\n\t\tMongoLocator: dbmongo.NewMongoModel(ctx, constant.MongoInstanceKey).SetDbName(constant.DbNameMongo).SetTable(constant.CollExample).\n\t\t\tSetName(GetKeyExampleModel()).(dbmongo.MongoLocator), // 设置当前模型的配置项名(mongodb)和库名(test)\n\t\tctx: context.Background(),\n\t}\n}\n\n// GetKeyExampleModel 获取模型注册key\nfunc GetKeyExampleModel(ns ...string) string {\n\treturn frame.RegisterKeyName(\"ExampleModel\", frame.GetNamespace([]string{constant.NameModuleExample}, ns...)...)\n}\n\n// RegisterKeyExampleModel 注册模型到容器（延迟初始化）并返回注册key\nfunc RegisterKeyExampleModel(ctx frame.ContextFramer, ns ...string) string {\n\treturn frame.RegisterKeyInitializerFunc(GetKeyExampleModel(ns...), func() (interface{}, error) {\n\t\treturn NewExampleModel(ctx), nil\n\t})\n}\n\n// GetExampleByID 根据ID获取样例文档\nfunc (m *ExampleModel) GetExampleByID(ctx context.Context, oid string) (*entity.Example, error) {\n\t_id, err := bson.ObjectIDFromHex(oid)\n\tif err != nil {\n\t\texception.GetInputError().RespError(err.Error()).Panic()\n\t}\n\tfilter := bson.D{{\"_id\", _id}}\n\topts := options.FindOne().SetProjection(bson.M{\n\t\t\"_id\":     0,\n\t\t\"profile\": 0,\n\t})\n\tvar example entity.Example\n\terr = m.GetCollection(m.GetColl()).FindOne(ctx, filter, opts).Decode(\u0026example)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn \u0026example, nil\n}\n```\n- 调用链路总结: 如 获取样例数据接口 GET /example/get/:id\n  - 路由注册: RegisterRouteHandlers -\u003e exampleGroup.Get(\"/get/:id\", exampleApi.GetExample)\n  - Api处理器: ExampleHandler.GetExample -\u003e h.Service.GetExample\n  - 服务层: ExampleService.GetExample -\u003e s.Repo.GetExampleById\n  - 仓储层: ExampleRepository.GetExampleById -\u003e r.Model.GetExampleByID\n  - 模型层: ExampleModel.GetExampleByID -\u003e m.GetCollection(m.GetColl()).FindOne(...)\n  - 实体层: entity.Example\n  - 响应层: e.g. response.RespSuccess(resp).JsonWithCtx(c) -\u003e response.RespInfo\n\n### 如何添加新的模块和新的api\n- 参考样例: [example_application/module/example-module](./example_application/module/example-module)\n\n- 复制样例模块目录：从 `example-module` 目录复制一份作为新模块的起始模板\n\n```bash\n\ncp -r example_application/module/example-module example_application/module/mymodule\n```\n\n- 修改模块相关文件：\n  - **常量定义**：修改 `constant/constants.go` 中的模块名称常量\n  - **实体类型**：修改 `entity/types.go` 中的实体结构体定义\n  - **模型层**：修改 `model/` 目录下的模型文件，更新模型名称和数据库表名\n  - **仓储层**：修改 `repository/` 目录下的仓储文件，更新仓储接口和实现\n  - **服务层**：修改 `service/` 目录下的服务文件，更新业务逻辑\n  - **API层**：修改 `api/` 目录下的API控制器文件，更新接口定义\n\n- 注册新模块API路由：在 `module/route_register.go` 中添加新模块路由注册\n\n```go\n// 在 RegisterApiRouters 函数中添加\nmymodule.RegisterRouteHandlers(ctx, app)\n```\n\n- 更新Wire依赖注入：运行 `wire` 命令重新生成依赖注入代码\n```bash\n# 进入新模块的api目录\ncd example_application/module/mymodule/api\n\n# 运行wire命令生成依赖注入代码，指定生成代码文件的前缀\nwire gen -output_file_prefix api_provider_\n```\n\n### task异步任务的使用样例\n\n- 定义唯一任务名称: 见 [example_application/module/example-module/task/names.go](./example_application/module/example-module/task/names.go)\n\n```go\npackage task\n\n// A list of task types. 任务名称的列表\nconst (\n\t// TypeExampleCreate 定义任务名称，异步创建一个样例数据\n\tTypeExampleCreate = \"ex:example:create:create-an-example\"\n)\n```\n\n- 新建任务: 见 [example_application/module/example-module/task/task.go](./example_application/module/example-module/task/task.go)\n\n```go\n/*\nTask payload list 任务负载列表\n*/\n\n// PayloadExampleCreate 样例创建负载的数据\ntype PayloadExampleCreate struct {\n\tframe.PayloadBase // 继承基础负载结构体，自动具备获取json编解码器的方法\n\t/**\n\t负载的数据\n\t*/\n\tAge int8\n}\n\n// NewExampleCreateTask 生成一个 ExampleCreate 任务，从调用处获取相关参数，并返回任务\nfunc NewExampleCreateTask(ctx frame.IContext, age int8) (*asynq.Task, error) {\n\tvo := PayloadExampleCreate{\n\t\tAge: age,\n\t}\n\t// 获取json编解码器，将负载数据编码为json格式的字节切片\n\tpayload, err := vo.GetMustJsonHandler(ctx).Marshal(\u0026vo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn asynq.NewTask(TypeExampleCreate, payload, asynq.Retention(24*time.Hour), asynq.MaxRetry(3), asynq.ProcessIn(1*time.Minute)), nil\n}\n```\n\n- 定义任务处理器: 见 [example_application/module/example-module/task/handler/handle.go](./example_application/module/example-module/task/handler/handle.go)\n\n```go\n// HandleExampleCreateTask 样例任务创建的处理器\nfunc HandleExampleCreateTask(ctx context.Context, t *asynq.Task) error {\n\t// 从 context 中获取 appCtx 全局应用上下文，获取包括配置、日志、注册实例等组件\n\tappCtx, _ := ctx.Value(frame.ContextKeyAppCtx).(frame.ContextFramer)\n\n\t// 声明任务负载对象\n\tvar p task.PayloadExampleCreate\n\n\t// 解析任务负载\n\tif err := p.GetMustJsonHandler(appCtx).Unmarshal(t.Payload(), \u0026p); err != nil {\n\t\tappCtx.GetLogger().Error(appCtx.GetConfig().LogOriginWeb()).Str(\"From\", \"HandleExampleCreateTask\").Err(err).Msg(\"[Asynq]: Unmarshal error\")\n\t\treturn err\n\t}\n\n\t// 获取处理任务的实例，注意service.TestService需在任务挂载阶段注册到全局管理器\n    // 见 task/handler/mount.go: service.RegisterKeyTestService(ctx)\n\tinstance, err := frame.GetInstance[*service.TestService](service.GetKeyTestService())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// 将负参数传入实例的处理函数\n\tresult, err := instance.DoAgeDoubleCreateForTaskHandle(p.Age)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// 记录结果\n\tappCtx.GetLogger().InfoWith(appCtx.GetConfig().LogOriginTask()).Msgf(\"HandleExampleCreateTask 执行成功，结果 Age double: %d\", result)\n\treturn nil\n}\n\n```\n\n- 任务挂载器: 见 [example_application/module/example-module/task/handler/mount.go](./example_application/module/example-module/task/handler/mount.go)\n\n```go\npackage handler\n\nimport (\n\t\"github.com/lamxy/fiberhouse/example_application/module/example-module/service\"\n\t\"github.com/lamxy/fiberhouse/example_application/module/example-module/task\"\n\t\"github.com/lamxy/fiberhouse/frame\"\n)\n\n// RegisterTaskHandlers 统一注册任务处理函数和依赖的组件实例初始化器\nfunc RegisterTaskHandlers(tk frame.TaskRegister) {\n\t// append task handler to global taskHandlerMap\n\t// 通过RegisterKeyXXX注册任务处理的实例初始化器，并获取注册实例的keyName\n\n\t// 统一注册全局管理实例初始化器，该实例可在任务处理函数中通过tk.GetContext().GetContainer().GetXXXService()获取，用来执行具体的任务处理逻辑\n\tservice.RegisterKeyTestService(tk.GetContext())\n\n\t// 统一追加任务处理函数到Task注册器对象的任务名称映射的属性中\n\ttk.AddTaskHandlerToMap(task.TypeExampleCreate, HandleExampleCreateTask)\n}\n```\n\n- 将任务推送到队列: 见 [example_application/module/example-module/api/example_api.go](./example_application/module/example-module/api/example_api.go) \n  调用了 [example_application/module/example-module/service/example_service.go](./example_application/module/example-module/service/example_service.go) 的 GetExampleWithTaskDispatcher 方法\n\n```go\n// GetExampleWithTaskDispatcher 示例方法，演示如何在服务方法中使用任务调度器异步执行任务\nfunc (s *ExampleService) GetExampleWithTaskDispatcher(id string) (*responsevo.ExampleRespVo, error) {\n\tresp := responsevo.ExampleRespVo{}\n\texample, err := s.Repo.GetExampleById(id)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// 获取带任务标记的日志器，从全局管理器获取已附加了日志源标记的日志器\n\tlog := s.GetContext().GetMustLoggerWithOrigin(s.GetContext().GetConfig().LogOriginTask())\n\n\t// 获取样例数据成功，推送延迟任务异步执行\n\tdispatcher, err := s.GetContext().(frame.ContextFramer).GetStarterApp().GetTask().GetTaskDispatcher()\n\tif err != nil {\n\t\tlog.Warn().Err(err).Str(\"Category\", \"asynq\").Msg(\"GetExampleWithTaskDispatcher GetTaskDispatcher failed\")\n\t}\n\t// 创建任务对象\n\ttask1, err := task.NewExampleCreateTask(s.GetContext(), int8(example.Age))\n\tif err != nil {\n\t\tlog.Warn().Err(err).Str(\"Category\", \"asynq\").Msg(\"GetExampleWithTaskDispatcher NewExampleCountTask failed\")\n\t}\n\t// 将任务对象入队\n\ttInfo, err := dispatcher.Enqueue(task1, asynq.MaxRetry(constant.TaskMaxRetryDefault), asynq.ProcessIn(1*time.Minute)) // 任务入队，并将在1分钟后执行\n\n\tif err != nil {\n\t\tlog.Warn().Err(err).Msg(\"GetExampleWithTaskDispatcher Enqueue failed\")\n\t} else if tInfo != nil {\n\t\tlog.Warn().Msgf(\"GetExampleWithTaskDispatcher Enqueue task info: %v\", tInfo)\n\t}\n\n\t// 正常的业务逻辑\n\tresp.ExamName = example.Name\n\tresp.ExamAge = example.Age\n\tresp.Courses = example.Courses\n\tresp.Profile = example.Profile\n\tresp.CreatedAt = example.CreatedAt\n\tresp.UpdatedAt = example.UpdatedAt\n\treturn \u0026resp, nil\n}\n```\n### 缓存组件使用样例\n\n- 见获取样例列表接口: [example_application/module/example-module/api/example_api.go](./example_application/module/example-module/api/example_api.go) 的 GetExamples 方法\n  调用样例服务的 GetExamplesWithCache 方法: [example_application/module/example-module/service/example_service.go](./example_application/module/example-module/service/example_service.go)\n\n```go\n\nfunc (s *ExampleService) GetExamples(page, size int) ([]responsevo.ExampleRespVo, error) {\n\t// 从缓存选项池获取缓存选项对象\n\tco := cache.OptionPoolGet(s.GetContext())\n\t// 使用完的缓存选项对象归还对象池\n\tdefer cache.OptionPoolPut(co)\n\n\t// 设置缓存参数: 二级缓存、启用本地缓存、设置缓存key、设置本地缓存随机过期时间(10秒±10%)、设置远程缓存随机过期时间(3分钟±1分钟)、写远程缓存同步策略、设置上下文、启用缓存全部的保护措施\n\tco.Level2().EnableCache().SetCacheKey(\"key:example:list:page:\"+strconv.Itoa(page)+\":size:\"+strconv.Itoa(size)).SetLocalTTLRandomPercent(10*time.Second, 0.1).\n\t\tSetRemoteTTLWithRandom(3*time.Minute, 1*time.Minute).SetSyncStrategyWriteRemoteOnly().SetContextCtx(context.TODO()).EnableProtectionAll()\n\n\t// 获取缓存数据，调用缓存包的 GetCached 方法，传入缓存选项对象和获取数据的回调函数\n\treturn cache.GetCached[[]responsevo.ExampleRespVo](co, func(ctx context.Context) ([]responsevo.ExampleRespVo, error) {\n\t\tlist, err := s.Repo.GetExamples(page, size)\n\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\texamples := make([]responsevo.ExampleRespVo, 0, len(list))\n\t\tfor i := range list {\n\t\t\texample := responsevo.ExampleRespVo{\n\t\t\t\tID:       list[i].ID.Hex(),\n\t\t\t\tExamName: list[i].Name,\n\t\t\t\tExamAge:  list[i].Age,\n\t\t\t\tCourses:  list[i].Courses,\n\t\t\t\tProfile:  list[i].Profile,\n\t\t\t\tTimestamps: commonvo.Timestamps{\n\t\t\t\t\tCreatedAt: list[i].CreatedAt,\n\t\t\t\t\tUpdatedAt: list[i].UpdatedAt,\n\t\t\t\t},\n\t\t\t}\n\t\t\texamples = append(examples, example)\n\t\t}\n\t\treturn examples, nil\n\t})\n}\n```\n\n### CMD命令行应用使用样例\n\n- 命令行框架应用main入口 : 见 [example_application/command/main.go](./example_application/command/main.go)\n\n```go\npackage main\n\nimport (\n\t\"github.com/lamxy/fiberhouse/example_application/command/application\"\n\t\"github.com/lamxy/fiberhouse/frame\"\n\t\"github.com/lamxy/fiberhouse/frame/bootstrap\"\n\t\"github.com/lamxy/fiberhouse/frame/commandstarter\"\n)\n\nfunc main() {\n\t// bootstrap 初始化启动配置(全局配置、全局日志器)，配置路径为当前工作目录下的\"./../config\"\n\tcfg := bootstrap.NewConfigOnce(\"./../../example_config\")\n\n\t// 全局日志器，定义日志目录为当前工作目录下的\"./logs\"\n\tlogger := bootstrap.NewLoggerOnce(cfg, \"./logs\")\n\n\t// 初始化命令全局上下文\n\tctx := frame.NewCmdContextOnce(cfg, logger)\n\n\t// 初始化应用注册器对象，注入应用启动器\n\tappRegister := application.NewApplication(ctx) // 需实现框架关于命令行应用的 frame.ApplicationCmdRegister接口\n\n\t// 初始化命令行启动器对象\n\tcmdStarter := commandstarter.NewCmdApplication(ctx, appRegister)\n\n\t// 运行命令行启动器\n\tcommandstarter.RunCommandStarter(cmdStarter)\n}\n```\n- 编写一个命令脚本: 见 [example_application/command/application/commands/test_orm_command.go](./example_application/command/application/commands/test_orm_command.go)\n\n```go\n// TestOrmCMD 测试go-orm库的CURD操作命令，需实现 frame.CommandGetter 接口，通过 GetCommand 方法返回命令行命令对象\ntype TestOrmCMD struct {\n\tCtx frame.ContextCommander\n}\n\nfunc NewTestOrmCMD(ctx frame.ContextCommander) frame.CommandGetter {\n\treturn \u0026TestOrmCMD{\n\t\tCtx: ctx,\n\t}\n}\n\n// GetCommand 获取命令行命令对象，实现 frame.CommandGetter 接口的 GetCommand方法\nfunc (m *TestOrmCMD) GetCommand() interface{} {\n\treturn \u0026cli.Command{\n\t\tName:    \"test-orm\",\n\t\tAliases: []string{\"orm\"},\n\t\tUsage:   \"测试go-orm库CURD操作\",\n\t\tFlags: []cli.Flag{\n\t\t\t\u0026cli.StringFlag{\n\t\t\t\tName:     \"method\",\n\t\t\t\tAliases:  []string{\"m\"},\n\t\t\t\tUsage:    \"测试类型(ok/orm)\",\n\t\t\t\tRequired: true,\n\t\t\t},\n\t\t\t\u0026cli.StringFlag{\n\t\t\t\tName:     \"operation\",\n\t\t\t\tAliases:  []string{\"o\"},\n\t\t\t\tUsage:    \"CURD(c创建|u更新|r读取|d删除)\",\n\t\t\t\tRequired: false,\n\t\t\t},\n\t\t\t\u0026cli.UintFlag{\n\t\t\t\tName:     \"id\",\n\t\t\t\tAliases:  []string{\"i\"},\n\t\t\t\tUsage:    \"主键ID\",\n\t\t\t\tRequired: true,\n\t\t\t},\n\t\t},\n\t\tAction: func(cCtx *cli.Context) error {\n\t\t\tvar (\n\t\t\t\tems  *service.ExampleMysqlService\n                wrap = component.NewWrap[*service.ExampleMysqlService]()\n\t\t\t)\n\n\t\t\t// 使用dig注入所需依赖，通过provide连缀方法连续注入依赖组件\n\t\t\tdc := m.Ctx.GetDigContainer().\n\t\t\t\tProvide(func() frame.ContextCommander { return m.Ctx }).\n\t\t\t\tProvide(model.NewExampleMysqlModel).\n\t\t\t\tProvide(service.NewExampleMysqlService)\n\n\t\t\t// 错误处理\n\t\t\tif dc.GetErrorCount() \u003e 0 {\n\t\t\t\treturn fmt.Errorf(\"dig container init error: %v\", dc.GetProvideErrs())\n\t\t\t}\n\n\t\t\t/*\n\t\t\t// 通过Invoke方法获取依赖组件，在回调函数中使用依赖组件\n\t\t\terr := dc.Invoke(func(ems *service.ExampleMysqlService) error {\n\t\t\t\terr := ems.AutoMigrate()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\t// 其他操作...\n\t\t\t\treturn nil\n\t\t\t})\n\t\t\t*/\n\n\t\t\t// 另一种方式，使用泛型Invoke方法获取依赖组件，通过component.Wrap辅助类型来获取依赖组件\n\t\t\terr := component.Invoke[*service.ExampleMysqlService](wrap)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// 获取依赖组件\n\t\t\tems = wrap.Get()\n\n\t\t\t// 自动创建一次数据表\n\t\t\terr = ems.AutoMigrate()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// 获取命令行参数\n\t\t\tmethod := cCtx.String(\"method\")\n\n\t\t\t// 执行测试\n\t\t\tif method == \"ok\" {\n\t\t\t\ttestOk := ems.TestOk()\n\n\t\t\t\tfmt.Println(\"result: \", testOk, \"--from:\", method)\n\t\t\t} else if method == \"orm\" {\n\t\t\t\t// 获取更多命令行参数\n\t\t\t\top := cCtx.String(\"operation\")\n\t\t\t\tid := cCtx.Uint(\"id\")\n\n\t\t\t\t// 执行测试orm\n\t\t\t\terr := ems.TestOrm(m.Ctx, op, id)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tfmt.Println(\"result: testOrm OK\", \"--from:\", method)\n\t\t\t} else {\n\t\t\t\treturn fmt.Errorf(\"unknown method: %s\", method)\n\t\t\t}\n\n\t\t\treturn nil\n\t\t},\n\t}\n}\n```\n- 命令行构建： 见 [example_application/command/README_go_build.md](./example_application/command/README_go_build.md)\n\n```bash\n# 构建\ncd command/  # command ROOT Directory\ngo build -o ./target/cmdstarter.exe ./main.go \n\n# 执行命令帮助\ncd command/    ## work dir is ~/command/, configure path base on it\n./target/cmdstarter.exe -h\n```\n\n- 命令行应用使用说明\n  - 编译命令行应用: `go build -o ./target/cmdstarter.exe ./main.go `\n  - 运行命令行应用查看帮助: `./target/cmdstarter.exe -h`\n  - 运行测试go-orm库的CURD操作命令: `./target/cmdstarter.exe test-orm --method ok` 或 `./target/cmdstarter.exe test-orm -m ok`\n  - 运行测试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`\n  - 子命令行参数帮助说明: `./target/cmdstarter.exe test-orm -h`\n\n\n## 🔧 配置说明\n\n### 应用全局配置\nFiberHouse 支持基于环境的多配置文件管理，配置文件位于 example_config/ 目录。全局配置对象位于框架上下文对象中，可通过 ctx.GetConfig() 方法获取。\n\n- 配置文件 README： 见 [example_config/README.md](./example_config/README.md)\n\n- 配置文件命名规则\n\n```\n配置文件格式: application_[应用类型]_[环境].yml\n应用类型: web | cmd\n环境类型: dev | test | prod\n\n示例文件:\n- application_web_dev.yml     # Web应用开发环境\n- application_web_test.yml    # Web应用测试环境  \n- application_web_prod.yml    # Web应用生产环境\n- application_cmd_test.yml    # 命令行应用测试环境\n\n```\n- 环境变量配置\n\n```\n# 引导环境变量 (APP_ENV_ 前缀):\nAPP_ENV_application_appType=web    # 设置应用类型: web/cmd\nAPP_ENV_application_env=prod       # 设置运行环境: dev/test/prod\n\n# 配置覆盖环境变量 (APP_CONF_ 前缀):\nAPP_CONF_application_appName=MyApp              # 覆盖应用名称\nAPP_CONF_application_server_port=9090           # 覆盖服务端口\nAPP_CONF_application_appLog_level=error         # 覆盖日志级别\nAPP_CONF_application_appLog_asyncConf_type=chan # 覆盖异步日志类型\n\n```\n#### 核心配置项\n\n- 应用基础配置:\n```yaml\napplication:\n  appName: \"FiberHouse\"           # 应用名称\n  appType: \"web\"                  # 应用类型: web/cmd\n  env: \"dev\"                      # 运行环境: dev/test/prod\n  \n  server:\n    host: \"127.0.0.1\"              # 服务主机\n    port: 8080                     # 服务端口\n```\n- 日志系统配置:\n```yaml\napplication:\n  appLog:\n    level: \"info\"                # 日志级别: debug/info/warn/error\n    enableConsole: true          # 启用控制台输出\n    consoleJSON: false           # 控制台JSON格式\n    enableFile: true             # 启用文件输出\n    filename: \"app.log\"          # 日志文件名\n    \n    # 异步日志配置\n    asyncConf:\n      enable: true              # 启用异步日志\n      type: \"diode\"             # 异步类型: chan/diode\n      \n    # 日志轮转配置  \n    rotateConf:\n      maxSize: 5                             # megabytes\n      maxBackups: 5                          # 最大备份文件数\n      maxAge: 7                              # days\n      compress: false                        # disabled by default\n```\n\n- 数据库配置:\n```yaml\n# MySQL 配置\nmysql:\n  dsn: \"root:root@tcp(127.0.0.1:3306)/test?charset=utf8mb4\u0026parseTime=True\u0026loc=Local\u0026timeout=10s\"\n  gorm:\n    maxIdleConns: 10                       # 最大空闲连接数\n    maxOpenConns: 100                      # 最大打开连接数\n    connMaxLifetime: 3600                  # 连接最大生命周期，单位秒\n    connMaxIdleTime: 300                   # 连接最大空闲时间，单位秒\n    logger:\n      level: info                        # 日志级别: silent、error、warn、info\n      slowThreshold: 200 * time.Millisecond # 慢SQL阈值，建议 200 * time.Millisecond，根据实际业务调整\n      colorful: false                    # 是否彩色输出\n      enable: true                       # 是否启用日志记录\n      skipDefaultFields: true            # 跳过默认字段\n  pingTry: false\n```\n\n- redis配置:\n```yaml\nredis:\n  host: \"127.0.0.1\"\n  port: 6379\n  password: \"\"\n  database: 0\n  poolSize: 100                # 连接池大小\n  \n  # 集群配置 (可选)\n  cluster:\n    addrs: [\"127.0.0.1:6379\"]\n    poolSize: 100\n```\n- 缓存系统配置:\n```yaml\ncache:\n  # 本地缓存\n  local:                                     # 本地缓存配置\n    numCounters: 1000000                     # 100万个计数器\n    maxCost: 134217728                       # 最大缓存128M\n    bufferItems: 64                          # 每个缓存分区的缓冲区大小\n    metrics: true                            # 是否启用缓存指标\n    IgnoreInternalCost: false                # 是否忽略内部开销\n      \n  # 远程缓存  \n  redis:                                     # remote 远程缓存配置\n    host: 127.0.0.1                          # Redis 服务器地址\n    port: 6379                               # Redis 服务器端口\n    password: \"\"                             # Redis 服务器密码\n  # 异步池配置\n  asyncPool:                               # 启用二级缓存时的异步goroutine池配置，用于处理缓存更新和同步策略\n    ants:                                  # ants异步goroutine池配置\n      local:\n        size: 248                          # 本地缓存异步goroutine池大小\n        expiryDuration: 5                  # 单位秒，空闲goroutine超时时间\n        preAlloc: false                    # 不预分配\n        maxBlockingTasks: 512              # 最大阻塞任务数\n        nonblocking: false                 # 允许阻塞\n```\n\n- 任务组件配置\n```yaml\n  task:\n    enableServer: true                       # 是否启用任务调度服务组件支持\n```\n- 更多配置按需自定义\n\n- 完整配置示例参考：\n  - 测试环境配置: [example_config/application_web_test.yml](./example_config/application_web_test.yml)\n  - 命令行测试环境配置: [application_cmd_test.yml](./example_config/application_cmd_test.yml)\n\n\n## 🤝 贡献指南\n\n### 快速开始\n- Fork 仓库并 Clone\n- 创建分支：git checkout -b feature/your-feature\n- 开发并保持格式：go fmt ./... \u0026\u0026 golangci-lint run\n- 运行测试：go test ./... -race -cover\n- 提交：feat(module): 描述\n- 推送并发起 PR\n\n### 分支策略\n- main：稳定发布\n- develop：集成开发\n- feature/*：功能\n- fix/*：缺陷\n- 其它分类\n\n### PR 要求\n- 标题：与提交信息一致\n- 内容：背景 / 方案 / 影响 / 测试 / 关联 Issue\n- CI 通过\n\n### 安全\n安全漏洞请私信：pytho5170@hotmail.com\n\n## 📄 许可证\n\n本项目基于 MIT 许可证开源 - 查看 [LICENSE](LICENSE) 文件了解详情。\n\n## 🙋‍♂️ 支持与反馈\n\n- 如果您感兴趣，或者支持FiberHouse的持续开发，请在GitHub上点个星[GitHub Star](https://github.com/lamxy/fiberhouse/stargazers)\n- 问题反馈: [Issues](https://github.com/lamxy/fiberhouse/issues)\n- 联系邮箱: pytho5170@hotmail.com\n\n## 🌟 致谢\n\n感谢以下开源项目：\n\n- [gofiber/fiber](https://github.com/gofiber/fiber) - 高性能 HTTP 内核\n- [rs/zerolog](https://github.com/rs/zerolog) - 高性能结构化日志\n- [knadh/koanf](https://github.com/knadh/koanf) - 灵活的多源配置管理\n- [bytedance/sonic](https://github.com/bytedance/sonic) - 高性能 JSON 编解码\n- [dgraph-io/ristretto](https://github.com/dgraph-io/ristretto) - 高性能本地缓存\n- [hibiken/asynq](https://github.com/hibiken/asynq) - 基于 Redis 的分布式任务队列\n- [go.mongodb.org/mongo-driver](https://github.com/mongodb/mongo-go-driver) - MongoDB 官方驱动\n- [gorm.io/gorm](https://gorm.io) - ORM 抽象与 MySQL 支撑\n- [redis/go-redis](https://github.com/redis/go-redis) - Redis 客户端\n- [panjf2000/ants](https://github.com/panjf2000/ants) - 高性能 goroutine 池\n\n同时感谢：\n- [swaggo/swag](https://github.com/swaggo/swag) 提供 API 文档生成\n- [google/wire](https://github.com/google/wire)、[uber-go/dig](https://github.com/uber-go/dig) 支持依赖注入模式\n- 以及所有未逐一列出的优秀项目\n\n最后感谢：GitHub Copilot 提供的资料查阅、文档整理和编码辅助能力。","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flamxy%2Ffiberhouse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flamxy%2Ffiberhouse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flamxy%2Ffiberhouse/lists"}