pixiu

module
v0.1.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 10, 2026 License: Apache-2.0

README

貔貅 · Pixiu

面向 Go 服务的分层复用库
独立原语 · 技术能力 · 通用业务流程

Go Reference 许可证 Apache-2.0

貔貅将 Go 服务中反复出现的工程能力沉淀为职责清楚、可按需引入的包:从结构化日志、文件轮转和并发任务,到 HTTP、数据库、缓存、消息通信、JWT 签发验签,以及可复用的分布式锁流程。

你可以只引入一个基础模块,也可以在应用中组合多种能力。资源的创建、业务配置与退出顺序由应用明确掌握。

项目理念 · 安装 · 快速开始 · 模块导航 · 分层架构 · 使用示例 · 使用约定 · 开发与贡献 · 许可证

项目理念

为什么叫貔貅

“貔貅”是中国传统文化中的祥瑞之兽。这个名字寄托了项目的愿望:把值得复用的工程能力积累下来,为不同的 Go 服务提供可靠支撑。

项目使用 Pixiu 作为英文名与 Go module 名。吉祥物以青玉色兽身、暖金瑞角和圆润卷尾呈现貔貅的形象,见 Logo 图片。

设计重点

  • 职责分层:基础模块提供独立原语,infra/ 组合通用技术能力,biz/ 承载跨项目复用的业务流程。
  • 基础模块只使用标准库:顶层基础模块的生产代码彼此独立,不引入第三方包。
  • 性能与正确性一起验证:日志采用同步写入、字段直接编码与缓冲复用;优化保留字段顺序、JSON 转义和完整记录写入等语义。
  • 统一可观测性:围绕 logit 关联请求、下游调用与后台任务的日志,按需汇总调用耗时。
  • 显式生命周期:连接、服务和任务池由调用方创建与关闭;lifecycle 帮助按依赖顺序释放资源。
  • 按需组合:沿用 context.Context、io.Writer、http.Handler 和所封装 SDK 的公开能力,便于接入现有应用。

适用于需要统一日志和下游访问方式的 Go 服务,也适用于只想复用文件轮转、并发编排或资源关闭等单项能力的项目。

安装

当前 go.mod 要求 Go 1.27.3 或更高版本。

在已有 Go module 的项目中安装需要的包:

go get github.com/bpcoder16/pixiu/logit

需要其他能力时,使用对应路径:

go get github.com/bpcoder16/pixiu/rotatefile
go get github.com/bpcoder16/pixiu/infra/httpcall
go get github.com/bpcoder16/pixiu/infra/jwtx
go get github.com/bpcoder16/pixiu/biz/lockx/redislock

各包共享根 Go module,导入路径都以 github.com/bpcoder16/pixiu 开头。只使用基础模块时不会编译 infra/ 的代码,但根 go.mod 仍记录基础功能与业务功能使用的第三方依赖。

使用 infra/sqlitex 时还需要启用 CGO,并准备可用的 C 编译器;该包采用 go-sqlite3 驱动。

快速开始

下面是一个完整的结构化日志示例。保存为 main.go,安装 logit 后执行 go run .:

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/bpcoder16/pixiu/logit"
)

func main() {
	logger := logit.MustNew(
		logit.OptWriter(logit.Stdout()),
		logit.OptEncoder(logit.DefaultJSONEncoder),
		logit.OptMinLevel(logit.InfoLevel),
	)
	logit.SetDefault(logger)
	defer func() {
		if err := logit.Close(logger); err != nil {
			fmt.Fprintln(os.Stderr, err)
		}
	}()

	ctx := logit.WithContextLogID(context.Background())
	ctx = logit.WithStart(ctx)
	logit.AddField(ctx, logit.Str("service", "demo"))

	logit.Info(ctx, "开始处理", logit.Str("action", "hello"))
	logit.InfoDuration(ctx, "处理完成")
}

这个例子会向标准输出写入 JSON 日志,在同一请求中沿用 logId 和 service 字段,并在结束日志中追加自身与总耗时。

默认全局 Logger 为空操作 Logger:未调用 SetDefault 时,日志不输出到 stdout/stderr,所有级别(包括 Fatal)直接返回,Enabled 为 false,Close 返回 nil。仅使用 biz/lockx、infra/elasticsearchx 等能力时,无需初始化 logit。需要日志时,在启动阶段通过 New / MustNew 构造实例并调用 SetDefault;也可直接使用独立实例,或通过 SetNamed 注册命名 Logger。WithContext 的前置约束和 panic 专用接口语义保持不变。

新项目应先完成 bootstrap.MustBaseInit 初始化,再通过 logit.Default()、logit.With(...) 或 logit.Named(...) 创建和保存模块 Logger。不要在先于 bootstrap 执行的包变量初始化或 Go 的 init() 中缓存这些 Logger:初始化前取到的空操作实例不会随后续 SetDefault 或命名注册自动更新。包级 logit.Info(ctx, ...) 等方法每次调用时选择当前 Logger,可在初始化完成后直接使用。默认静默便于老项目引入其他 Pixiu 能力,不影响已完成日志初始化的新项目。

模块导航

以下均为当前仓库已实现的公开包。链接指向各包的 doc.go,其中包含用途、调用样例和具体边界。

基础模块

包 能力 典型用途
logit 文本 / 有序 JSON 日志、类型化字段、context 字段、命名 Logger、耗时与 panic 记录 服务日志与调用链关联
rotatefile 按本地小时或天轮转、稳定软链、旧文件清理 日志或其他持续追加文件
lifecycle 实例式资源关闭栈,逆序执行并汇总错误 按依赖顺序关闭资源
conc 单次调用的命名并发任务、结果汇总、限流或整体超时 并行查询与结果聚合
jsonx JSON 首值解码,保留解码期间观察到的读取错误 解析流中的一个 JSON 值
cryptox HMAC-SHA256、AES-GCM、用途绑定的分享 token、安全随机数 内部接口参数签名、分享凭证加解密;设计与安全约束
netx 本机 IPv4 / IPv6 地址查询 获取符合筛选规则的网卡地址
validx 手机号、邮箱、HTTP URL、IP、数字串与 rune 长度验证 请求参数的无状态格式检查
moneyx 元字符串与 int64 分金额精确转换,支持负数、格式及溢出错误 金额输入解析与固定两位小数输出

以上基础模块的生产代码仅依赖 Go 标准库,彼此不互相导入。

基础功能 · infra

导入时在下表路径前加上 github.com/bpcoder16/pixiu/。

包 能力 主要依赖
infra/apprun 常驻服务监督、统一停收和限时排空、显式 SIGINT/SIGTERM 接入 标准库、logit
infra/cronx 六字段 Cron、固定/随机间隔、防重入、任务日志与两阶段关闭 gocron v2、robfig/cron v3、logit;可注入 gocron.Locker
infra/configx YAML / TOML / JSON 结构体配置加载、全局命名获取与零值兜底 Viper
infra/env 通用应用环境、IP 校验与补齐、一次初始化与全局读取 标准库、netx
infra/httpcall 可复用 HTTP 下游客户端、结果日志、请求级耗时 Resty v2、logit
infra/httpserver 标准 http.Handler 服务端、监听、限时关闭 标准库
infra/websocketx 标准 Handler、认证与心跳、有界收发、不可变预制帧、独立连接生命周期 Gorilla WebSocket、logit
infra/ginx 独立 Gin Engine、请求日志作用域、访问日志、Recovery 与 OpenAPI / Elements 文档 Gin、Swag、logit
infra/jwtx HS256 / RS256 / ES256 / PS256 JWT 签发、验签与声明校验 golang-jwt/jwt v5
infra/taskpool 本地异步任务、有界队列、worker 扩缩容、重试与排空 logit
infra/lrucache 泛型有界 LRU、默认 / 单条目 TTL、独立及命名实例 ttlcache v3
infra/mysqlx MySQL 连接池、显式主从选择、查询日志 GORM、MySQL 驱动、logit
infra/gormx Repository 主、从库会话依赖 Sessions,按关键词原文进行 LIKE 包含匹配 GORM
infra/schemamigrate AutoMigrate、物理分表、MySQL / PostgreSQL 表注释及按数量校准 SQL 种子 GORM
infra/postgresqlx PostgreSQL 连接池、显式主从选择、查询日志 GORM、pgx、logit
infra/clickhousex ClickHouse 连接池、显式主从选择、查询日志 GORM、ClickHouse 驱动、logit
infra/sqlitex SQLite 单库连接池、常用参数配置、查询日志 GORM、go-sqlite3、logit
infra/redisx 单机 Redis 客户端、初始化验活、命令结果日志 go-redis v9、logit
infra/natsx Core / JetStream 消息收发、启动期批量消费注册、Handler 注册表、命名空间与统一日志 nats.go、logit
infra/elasticsearchx Elasticsearch 通用操作、Bulk、默认及命名实例、结果日志与版本适配 官方 Elasticsearch SDK、logit
infra/estextsearch Elasticsearch 短文本查询 DSL、基础召回与混合输入扩展召回 标准库
infra/aliyun/ossx OSS 固定 Bucket 的上传、对象查询、下载签名与生命周期 阿里云 OSS SDK V2、credentials-go、logit
infra/aliyun/stsx STS AssumeRole、临时凭据与独立生命周期 阿里云 STS SDK、credentials-go、logit
infra/aliyun/esx 阿里云 ES 固定 InstanceID 的同义词清单、完整清单更新、实例查询 阿里云 Elasticsearch 管理 SDK、credentials-go、logit

Elasticsearch 连接按服务端主版本选择 v7、v8 或 v9 适配包;共用操作位于 infra/elasticsearchx。各版本的 NewDefault / NewNamed 共用注册表,通过 elasticsearchx.Default() / Named(name) 获取实例,应用统一调用 CloseAll() 关闭;独立 New 创建的实例仍需自行关闭。

独立 Elasticsearch 客户端默认关闭请求结果日志,通过 OptLogRequests(true) 开启;请求体和响应详情还需开启 OptLogDetails(true)。context 已调用 logit.WithStart 时,关闭结果日志仍会记录请求级下游耗时。Search 超时或分片失败会保留已有结果并返回 PartialSearchError;Bulk 动作失败返回 BulkError 并保留成功数与失败项,调用方应检查错误后再决定是否接受结果或重试。

infra/estextsearch 独立构建查询子句,不执行网络请求:Query(field, text) 提供基础召回,QueryExpanded(field, text) 扩展跨词同义词与编号等符号片段的组合召回,可能增加查询成本并改变评分或排名。调用方须准备主字段及 .contains、.contains_unigram 子字段,索引配置见 模板说明;空输入返回 nil, nil,合并请求时应省略该条件。

infra/aliyun/ossx、infra/aliyun/stsx 和 infra/aliyun/esx 独立持有配置、凭据、连接池和命名注册表,可使用不同账号。三者均支持成对配置 AccessKeyID / AccessKeySecret,或注入与其互斥的 Credential;New 只构造,不联网验活,结果日志默认关闭。共享实例使用 NewNamed / NewDefault 创建并统一 CloseAll;独立 New 创建的实例自行关闭。

OSS 每个实例固定一个 Config.Bucket,阿里云 ES 管理端每个实例固定一个 Config.InstanceID。UpdateSynonymsDicts 提交完整目标清单,遗漏已有文件会删除它;API 成功不代表分发或索引加载完成。凭据、上传及词典更新的完整边界见对应包文档。

通用业务功能 · biz

包 能力 典型用途
biz/common 按应用时区生成 ID、格式化时间,int64 万分之一整数与百分比精确互转,名称脱敏 常规业务工具;ID 与时间依赖 env,百分比支持负数,MaskName 支持自定义符号
biz/httpauth / ginauth 命名认证方案、统一身份、标准 Context 与 Gin 中间件 支持多平台认证,按平台注册认证实现,由路由显式选择认证方案
biz/bootstrap 应用时区、日志及多实例初始化,Gin / HTTP / WebSocket / Cron 服务构造、NATS 消费配置装配与显式 MySQL / PostgreSQL 迁移入口 声明实例、登记关闭栈;通过 Start 或自持 Manager 运行服务,日志最后关闭
biz/realtime WebSocket 身份、独立业务状态、scene/action 路由、ProtoJSON/PB 编解码、响应与主动事件 通过 bootstrap.NewWebSocketService 使用具名独立端口,或挂载到已有 HTTP 并显式管理生命周期
biz/ossservice multipart 上传、指定对象的 STS 凭据签发、URL 内容 MD5 上传需要 OSS,签发另需 STS;MD5FromURL 为独立包函数,无需客户端
biz/elasticsearchservice 固定 standard → lowercase → synonym_graph,创建临时索引严格验证并清理 通过 ValidateSynonyms 验证 synonyms_path,保留 ES 错误原因与清理状态
biz/appconfig 直接定义 env/log,严格解析应用配置、返回配置指针并初始化环境 从 app.yaml 模板 加载配置,不在 configx 注册全局配置
biz/lockx 阻塞 / 非阻塞锁契约,默认及命名执行器,Do / TryDo 协调获取、执行与释放 受锁保护的业务流程
biz/lockx/redislock 基于单机 Redis 的固定租期锁,原子校验身份并释放 同一协议下的多实例协调
biz/outbox MySQL/PostgreSQL 自增任务 ID、同事务入表、行锁并发发送、外部 cron 补偿与过期失败 数据库提交后的可靠发送意图
biz/outbox/natsoutbox 复用 natsx JetStream,固定消息 ID 并等待 PubAck 事务消息发布与失败补偿

分层架构

项目按基础模块、基础功能(infra/)和通用业务功能(biz/)分层:

  1. 顶层基础模块的生产代码只使用标准库,不依赖其他基础模块、infra/ 或 biz/。
  2. infra/ 可依赖基础模块、第三方包和 infra/internal/,不依赖其他公开 infra 包或 biz/。infra/internal/ 不反向依赖公开包。既有 Elasticsearch 版本适配子包对父包的依赖保留为迁移边界。
  3. biz/ 可依赖两个下层,同层保持无环依赖。项目特有业务逻辑由业务仓库承载。

应用可以直接使用任意一层。例如,ginx 创建的路由器实现 http.Handler,应用可把它传给 httpserver.New;日志轮转则由应用把 rotatefile 接入 logit.NewWriter。

使用示例

下面的完整示例可分别保存为独立程序,安装相应包后运行。完整配置与边界请阅读对应包文档;应用组合示例可参考 pixiu-demo。

最小 HTTP 应用

这个示例无需数据库等外部服务,使用标准 http.Handler 提供健康检查,并通过管理器接收停机信号、等待 HTTP 排空,最后关闭共享资源与日志。

将 app.yaml 和 http.yaml 复制到应用的 conf/ 目录,修改应用名称。保存以下代码为 main.go,安装 biz/bootstrap 后执行 go run .,再访问 http://127.0.0.1:8888/healthz,应返回 HTTP 204;在终端按 Ctrl+C 关闭。

展开完整示例(无需外部服务)
package main

import (
	"errors"
	"log"
	"net/http"
	"os"

	"github.com/bpcoder16/pixiu/biz/appconfig"
	"github.com/bpcoder16/pixiu/biz/bootstrap"
	"github.com/bpcoder16/pixiu/infra/apprun"
	"github.com/bpcoder16/pixiu/lifecycle"
)

func main() {
	if run() != nil {
		os.Exit(1)
	}
}

func run() (runErr error) {
	cfg := appconfig.MustLoadAppConfig("./conf/app.yaml")
	var resources lifecycle.Stack
	defer func() {
		if runErr != nil {
			failure := runErr
			_ = resources.Register(func() error {
				log.Printf("server exit: %v", failure)
				return nil
			})
		}
		runErr = errors.Join(runErr, resources.Close())
	}()
	bootstrap.MustBaseInit(cfg, &resources)

	mux := http.NewServeMux()
	mux.HandleFunc("GET /healthz", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusNoContent)
	})
	return bootstrap.Start(func() (apprun.Service, error) {
		return bootstrap.NewHTTPService(mux)
	})
}

NewHTTPService 构造不监听,Start 接管服务与信号;Stop 统一封闭入口,Wait 共享 30 秒,超时 Cancel。返回后无论是否排空超时都执行资源栈 Close,默认整体最多等待 20 秒。库不退出进程,应用 main 在有界收尾后退出。

通过 bootstrap 初始化后,业务日志默认写入 <dir>/<appName>/biz/ 下的 debug.log、info.log、wf.log,分别对应 Debug、Info 和 Warn / Error / Fatal;命名 Logger 增加 <name>. 文件前缀。dir 默认 ./log,相对应用启动目录解析;release 输出 Info 及以上,debug/test 输出 Debug 及以上。

log.hookStd 省略时默认开启,模板也显式开启:stdout / stderr 原始输出分别追加到 <dir>/<appName>/std/stdout.log 和 stderr.log,文件不轮转,重定向持续至进程退出。该能力仅支持 Linux/macOS;其他平台或需要保留终端标准输出时,在 app.yaml 的 log 段显式设置 hookStd: false。业务日志仍按上述文件分流。

Gin 与 OpenAPI 文档

使用 Gin 时,在初始化环境后显式调用 gin.SetMode(env.RunMode()),通过 bootstrap.NewGinEngine() 构造 Engine,注册业务路由,再将 Engine 传给 bootstrap.NewHTTPService。需额外导入 Gin 和 infra/env;将 gin.yaml 放在同一配置目录。文件必须存在,内容为 {} 时沿用默认值。

也可在 Start 的服务构造函数中调用 bootstrap.NewGinHTTPService(registerRoutes, modules...):它设置 Gin 模式、读取 gin.yaml 和 http.yaml,在 Engine 与文档路由创建成功后调用业务路由注册回调,并返回 apprun.Service。构造仍不监听端口,须在启动阶段串行调用;完整装配示例见 bootstrap 文档。

NewGinEngine 根据应用环境决定文档路由:

  • debug/test:自动注册 OpenAPI 与内嵌的 Stoplight Elements。应用须先使用 Swag CLI 生成文档(例如 swag init -o ./openapi),并在入口 blank import 生成包;未注册文档时构造返回错误。默认页面为 /docs,文档为 /openapi/doc.json。
  • release:不自动注册文档路由,也不要求生成文档。

多模块应用可向 NewGinEngine 传入 ginx.OpenAPIModule,以 Name 对应 Swag 的命名文档实例,Title 作为导航标题。每个模块提供 /openapi/<Name>.json 和 /docs/<Name>,/docs 展示首个模块;静态资源位于 /docs/assets/。生成参数、Bearer 前缀补齐等用法见 ginx 包文档。

文档路由在 Engine 构造时注册,之后添加的业务中间件不会作用于它们,也不会自动增加认证。需要控制文档访问时,可使用 ginx.New,在带认证中间件的路由组调用 ginx.RegisterOpenAPI。

文档页面、JSON 端点和内嵌静态资源的 GET 路由会自动跳过 ginx 访问日志、请求和响应详情采集及 Observe,仍保留请求作用域、组中间件与 Recovery。gin.yaml 模板默认保留普通访问日志,关闭请求和响应详情。已复制旧模板的服务需自行将 logRequestInfo、logResponseInfo 改为 false。其他需要跳过观察的路由可通过 ginx.RegisterIgnoredRoute 显式登记。

应用配置与多实例初始化

将 app.yaml 复制到应用的 conf/app.yaml。按下表选择组件并复制模板到同一配置目录,填写实际连接信息;完整示例使用其中七个组件:

声明 配置文件 模板
MustRegisterMySQL("orders", true) conf/mysql.orders.yaml MySQL
MustRegisterPostgreSQL("orders", true) conf/postgresql.orders.yaml PostgreSQL
MustRegisterRedis("cache", true) conf/redis.cache.yaml Redis
MustRegisterElasticsearch("search", true) conf/elasticsearch.search.yaml Elasticsearch
MustRegisterAliyunOSS("assets", true) conf/aliyunossx.assets.yaml 阿里云 OSS
MustRegisterAliyunSTS("upload", true) conf/aliyunstsx.upload.yaml 阿里云 STS
MustRegisterAliyunES("search-control", true) conf/aliyunesx.search-control.yaml 阿里云 ES 管理端
MustRegisterNATS("events", true) conf/nats.events.yaml NATS

实例名与默认标记只在代码中声明,实例文件不接受 name / isDefault。Elasticsearch 文件的 version 必须与部署主版本一致,支持 7 / 8 / 9;caCertFile 相对路径基于配置目录。只需某个组件时,保留对应声明与配置文件即可;未声明的实例不会加载。

NATS 操作日志默认记录概要和消息正文字节数;完整正文、Header 和编码字段需将 natsx.Config.LogDetails 显式设为 true,或在 nats.<name>.yaml 中配置 logDetails: true。该开关按实例固定,不影响追踪、耗时、原始错误文本和连接状态日志;已有依赖完整消息日志的应用需显式开启。

展开完整示例(需要实际下游服务)
package main

import (
	"context"
	"fmt"
	"os"

	"github.com/bpcoder16/pixiu/biz/appconfig"
	"github.com/bpcoder16/pixiu/biz/bootstrap"
	"github.com/bpcoder16/pixiu/lifecycle"
	"github.com/bpcoder16/pixiu/logit"
)

func main() {
	cfg := appconfig.MustLoadAppConfig("./conf/app.yaml")
	var resources lifecycle.Stack
	defer func() {
		if err := resources.Close(); err != nil {
			fmt.Fprintln(os.Stderr, "close resources:", err)
		}
	}()

	bootstrap.MustRegisterMySQL("orders", true)
	bootstrap.MustRegisterRedis("cache", true)
	bootstrap.MustRegisterElasticsearch("search", true)
	bootstrap.MustRegisterAliyunOSS("assets", true)
	bootstrap.MustRegisterAliyunSTS("upload", true)
	bootstrap.MustRegisterAliyunES("search-control", true)
	bootstrap.MustRegisterNATS("events", true)
	bootstrap.MustBaseInit(cfg, &resources)
	logit.Info(context.Background(), "应用初始化完成")
}

PostgreSQL 项目将示例中的 MySQL 声明替换为 bootstrap.MustRegisterPostgreSQL("orders", true),使用 postgresql.orders.yaml,初始化后通过 postgresqlx.Default() 或 postgresqlx.Named("orders") 获取客户端。以 PostgreSQL 18 为验证基准;配置、TLS、时区和缓存开关见模板。

各组件独立选择默认实例,Default() 与 Named(默认名称) 返回同一客户端。共享组件由 bootstrap 各登记一次 CloseAll,业务无需重复登记单个客户端关闭。初始化失败会 panic,提前登记的 defer 负责回收已创建资源;初始化只在启动阶段串行执行,失败后不支持重试。

此示例只展示初始化;常驻 HTTP 应用还需接入上面的服务管理器。MustRegisterNATS 声明实例,MustBaseInit 只完成连接初始化,不会自动准备 Stream 或启动消费。

需要消费时,通过 natsx.MustNewJetStreamHandlerRegistry / MustNewCoreHandlerRegistry 登记 Handler,在 Start 工厂中返回 bootstrap.NewNATSConsumerService(instanceName, jetStreamHandlers, coreHandlers)。消费清单见 NATS 消费配置;消费者在服务运行时注册,与 HTTP/Cron 共用停机预算。JetStream 按 Handler 返回结果确认或重投,业务应保证幂等,不自行 ACK / NAK / Term;注册失败应中止启动。

NATS 连接文件可配置 namespace 和 loggerName。配置装配、注册限制及各组件日志默认值见 bootstrap 包文档,主题映射与消息处理契约见 natsx 包文档。

OSS 上传与临时凭据签发可通过 biz/ossservice 组合已有 OSS、STS 客户端,应用负责文件校验、Key 生成和记录保存。各阿里云组件的连接参数与默认值见上方配置模板及模块导航中的包文档。

按需裁剪 bootstrap 编译依赖

默认构建保留全部组件,只有通过 MustRegisterXxx 声明的实例才会初始化。构建标签用于进一步排除不需要的组件编译依赖,与 app.yaml 的运行时配置无关;省略标签不改变现有行为。

不使用的组件 构建标签
Elasticsearch 7/8/9 pixiu_bootstrap_no_es
阿里云 OSS pixiu_bootstrap_no_aliyun_oss
阿里云 STS pixiu_bootstrap_no_aliyun_sts
阿里云 ES 管理端 pixiu_bootstrap_no_aliyun_es
MySQL pixiu_bootstrap_no_mysql
PostgreSQL pixiu_bootstrap_no_postgresql
Redis pixiu_bootstrap_no_redis
NATS pixiu_bootstrap_no_nats

在业务应用包含 main 包的入口目录执行,多个标签用逗号分隔:

# 不使用 Elasticsearch 数据面,阿里云 ES 管理端仍可单独使用。
go build -tags=pixiu_bootstrap_no_es -o app .

# 不使用 MySQL。
go build -tags=pixiu_bootstrap_no_mysql -o app .

# 不使用 Redis 和 NATS。
go build -tags=pixiu_bootstrap_no_redis,pixiu_bootstrap_no_nats -o app .

# 不使用三个阿里云组件。
go build -tags=pixiu_bootstrap_no_aliyun_oss,pixiu_bootstrap_no_aliyun_sts,pixiu_bootstrap_no_aliyun_es -o app .

# 排除全部八个组件;构建、运行和测试使用同一组标签。
BOOTSTRAP_TAGS='pixiu_bootstrap_no_es,pixiu_bootstrap_no_aliyun_oss,pixiu_bootstrap_no_aliyun_sts,pixiu_bootstrap_no_aliyun_es,pixiu_bootstrap_no_mysql,pixiu_bootstrap_no_postgresql,pixiu_bootstrap_no_redis,pixiu_bootstrap_no_nats'
go build -tags="$BOOTSTRAP_TAGS" -o app .
go run -tags="$BOOTSTRAP_TAGS" .
go test -tags="$BOOTSTRAP_TAGS" ./...

禁用后,基础 MustRegisterXxx(name, isDefault) 方法仍保留,显式调用立即 panic 并指出对应标签;基础初始化跳过该模块,不读取其配置或登记关闭。

涉及 SDK 类型的专用 API 随模块排除:禁用 MySQL 时没有 RunMySQLInitialization;禁用 PostgreSQL 时没有 RunPostgreSQLInitialization;只有两者都禁用才排除共享的 SeedOptions 和迁移核心依赖;禁用 Redis 时没有 MustRegisterRedisLock;禁用 NATS 时没有 NewNATSConsumerService。应用仍调用这些入口时会编译失败,应一并移除或用对应构建约束隔离相关业务文件。

日志、时区、HTTP/Gin、WebSocket 和普通 Cron 保留。禁用 Redis 后,Cron 配置中出现非空 lock(包括 {})会明确返回标签错误,不会降级为无锁执行;省略 lock 或配置 lock: null 不受影响。

标签只排除 bootstrap 引入的依赖,不删除 go.mod 中的模块;其他已启用组件共享的依赖、应用自身直接导入的 SDK 或适配包仍会参与编译。在 Pixiu 库仓库执行 go build -tags=... ./... 仍会构建独立的 infra 适配包;裁剪应用应针对业务入口构建。

显式执行 MySQL / PostgreSQL 表结构迁移

项目维护 []schemamigrate.Table 模型清单,在 MustBaseInit 完成后、业务服务启动前调用 bootstrap.RunMySQLInitialization("orders", tables, bootstrap.SeedOptions{}),并检查返回的报告与错误。空 SeedOptions 表示只迁移结构。名称对应已声明的 MySQL 实例,迁移在其主库执行;失败时停止启动,不忽略错误后开放业务入口。

PostgreSQL 使用 bootstrap.RunPostgreSQLInitialization("orders", tables, bootstrap.SeedOptions{});需要同时校准种子时,在 SeedOptions 中填写种子配置,参数与下方 MySQL 示例相同。PostgreSQL 支持 Table.Comment,仅注释变化时执行 COMMENT ON TABLE,空值不管理已有注释;Charset、Collation 仍仅支持 MySQL,PostgreSQL 显式配置会在整批 DDL 前报错。两个数据库入口均读取 migrate.<name>.yaml,同名实例共享迁移开关,需要独立控制时使用不同实例名。

将 migrate.example.yaml 复制为 conf/migrate.orders.yaml。调用初始化入口时文件必须存在,enabled 默认 false,显式开启后执行;timeout 默认 5 分钟。迁移不会自动挂到 MustBaseInit 或连接构造中,关闭或表与种子清单均为空时不获取数据库。

每张表通过 Model 登记,可选 Name 指定物理表名、Comment 管理 MySQL / PostgreSQL 表注释。只迁移显式登记的表,关联表和多对多中间表须单独登记,不自动创建关联外键。没有跨实例迁移锁,发布时应避免多实例同时执行;DDL 失败或超时可能已部分生效,不能保证整批回滚。完整样例与报告语义见 schemamigrate 包文档。

需要同时初始化 SQL 种子时使用组合入口:

report, err := bootstrap.RunMySQLInitialization("orders", tables, bootstrap.SeedOptions{
    Files: seedFiles, // 项目内嵌的 embed.FS。
    Seeds: []schemamigrate.Seed{
        {Model: &OrderStatus{}, Where: map[string]any{"category": "default"}, File: "seeds/statuses.sql"},
    },
    Timeout: 3 * time.Minute,
})

项目保留 Model、表清单、种子声明和 SQL 文件。enabled 同时控制迁移与 seeds;关闭时不访问数据库或读取 SQL,迁移失败不会执行 seeds。表清单为空仍可对已有表执行种子。YAML 的 timeout 仅限制表结构迁移;SeedOptions.Timeout 从种子阶段开始独立计时,限制整批 seeds,零值默认 2 分钟、负值非法。返回的报告仅记录结构迁移结果,调用方必须处理任一阶段的错误。

种子 SQL 每个有效行必须是一条以分号结束、插入一行的 INSERT INTO;关键字不区分大小写,空行与 -- 整行注释不计数。空文件、跨行 SQL 及其他语句报错。有效行数与 Where 范围内的物理记录数(含软删除记录)相同则保留内容;不同则事务 DELETE 该范围并重建,空 Where 明确作用于整表。每条 INSERT 必须影响一行,完成后再次核对范围内数量;失败回滚当前项的删除与插入并停止,之前完成的项保留。

SQL 是可信部署代码,调用方负责其目标表及条件正确,并使用支持事务的表;本组件不解析 SQL 或隔离权限。不重置自增序列,重建可能改变 ID 和覆盖自定义数据,只适用于可整体重建的受管数据。数量相同不会发现内容差异。底层可直接调用 schemamigrate.ApplySeeds(ctx, masterDB, files, seeds),由调用方提供带期限的 Context;没有跨实例锁,须由单个实例在业务流量进入前执行。

PostgreSQL 的 serial / bigserial 或允许显式值的 identity 列插入固定 ID 时,不会自动推进对应序列,后续默认生成 ID 可能发生主键冲突。优先省略自增 ID 或填写 DEFAULT;必须混用固定 ID 和自动生成 ID 时,由项目在单实例初始化期间显式校准对应序列,组件不自动处理。序列取号或 setval 不随事务回滚,不属于种子删除与插入的回滚保证。参见 PostgreSQL 18 serial 说明及序列函数。

日志写入轮转文件

按小时轮转,当前轮转维度的保留上限设为 48 个实际文件(包含当前时段);每小时整点清理,清理完成前可能暂时超过上限。通过稳定的 app.log 软链访问当前文件。示例使用临时目录,结束后保留文件以便查看。

展开完整示例
package main

import (
	"context"
	"fmt"
	"os"
	"path/filepath"
	"time"

	"github.com/bpcoder16/pixiu/logit"
	"github.com/bpcoder16/pixiu/rotatefile"
)

func main() {
	if run() != nil {
		os.Exit(1)
	}
}

func run() error {
	dir, err := os.MkdirTemp("", "pixiu-logs-")
	if err != nil {
		return err
	}
	path := filepath.Join(dir, "app.log")
	file, err := rotatefile.New(path,
		rotatefile.OptEvery(time.Hour),
		rotatefile.OptMaxFiles(48),
	)
	if err != nil {
		return err
	}
	logger := logit.MustNew(logit.OptWriter(logit.NewWriter(file)))
	ctx := logit.WithContextLogID(context.Background())
	logger.Info(ctx, "日志已写入")
	fmt.Println("日志路径:", path)
	return logit.Close(logger)
}

生产环境请使用应用有权限写入的绝对路径,并在其他资源收尾之后关闭 Logger。按天轮转使用 rotatefile.OptEvery(24 * time.Hour)。

一次请求中的并发任务

conc 汇总命名任务的结果、错误和耗时。下面同时执行两个任务,并设置整组超时。

展开完整示例
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/bpcoder16/pixiu/conc"
)

func main() {
	tasks := map[string]conc.Task{
		"profile": func(ctx context.Context) (any, error) {
			return "alice", ctx.Err()
		},
		"orders": func(ctx context.Context) (any, error) {
			return 3, ctx.Err()
		},
	}
	report, err := conc.RunNamed(context.Background(), tasks,
		conc.WithTimeout(500*time.Millisecond),
		conc.WithCancelOnError(),
	)
	for name, result := range report.Results {
		fmt.Printf("%s: value=%v err=%v timedOut=%t\n",
			name, result.Value, result.Err, result.TimedOut,
		)
	}
	fmt.Println("整组耗时:", report.Duration)
	if err != nil {
		fmt.Println("整组错误:", err)
	}
}

需要限制并发数时使用 WithLimit(n);它不能与 WithTimeout 同时使用。超时返回结果快照,忽略 context 取消的已启动任务仍可能继续运行。

HTTP 下游调用与耗时汇总

httpcall 复用客户端与连接池,每次调用创建新 Request。这个例子在本地启动一个演示下游,无需外部服务;生产环境将 BaseURL 换成实际下游地址。

展开完整示例
package main

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"
	"os"
	"time"

	"github.com/bpcoder16/pixiu/infra/httpcall"
	"github.com/bpcoder16/pixiu/logit"
	"github.com/go-resty/resty/v2"
)

func main() {
	logger := logit.MustNew(
		logit.OptWriter(logit.Stdout()),
		logit.OptEncoder(logit.DefaultJSONEncoder),
	)
	logit.SetDefault(logger)
	defer func() {
		if err := logit.Close(logger); err != nil {
			fmt.Fprintln(os.Stderr, err)
		}
	}()

	downstream := httptest.NewServer(http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			w.WriteHeader(http.StatusNoContent)
		},
	))
	defer downstream.Close()

	client := httpcall.New("demo",
		httpcall.OptResty(func(r *resty.Client) {
			r.SetBaseURL(downstream.URL)
			r.SetTimeout(3 * time.Second)
		}),
	)
	ctx := logit.WithContextLogID(context.Background())
	ctx = logit.WithStart(ctx)
	ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
	defer cancel()

	resp, err := client.Request(ctx).Get("/health")
	if err != nil {
		logit.Error(ctx, "下游调用失败", logit.Err(err))
	} else if resp.IsError() {
		logit.Error(ctx, "下游返回错误状态", logit.Int("status", resp.StatusCode()))
	} else {
		fmt.Println("HTTP 状态:", resp.StatusCode())
	}
	logit.InfoDuration(ctx, "请求结束")
}

HTTP 4xx / 5xx 不会自动成为 Go error,需要检查响应状态。默认不自动重试;通过 OptResty 配置重试时,应结合下游的幂等语义决定哪些请求允许重试。

请求结束后的本地异步任务

taskpool 为每个任务创建独立日志作用域,并沿用入口的 logId。任务 context 不继承入口的取消和截止时间,执行期限在回调内设置。

展开完整示例
package main

import (
	"context"
	"errors"
	"os"
	"time"

	"github.com/bpcoder16/pixiu/infra/taskpool"
	"github.com/bpcoder16/pixiu/logit"
)

func main() {
	if run() != nil {
		os.Exit(1)
	}
}

func run() (runErr error) {
	logger := logit.MustNew(
		logit.OptWriter(logit.Stdout()),
		logit.OptEncoder(logit.DefaultJSONEncoder),
	)
	logit.SetDefault(logger)
	defer func() {
		runErr = errors.Join(runErr, logit.Close(logger))
	}()

	pool, err := taskpool.New(taskpool.Config{
		MinWorkers:   1,
		MaxWorkers:   4,
		QueueSize:    64,
		DrainTimeout: 5 * time.Second,
	})
	if err != nil {
		return err
	}
	requestCtx := logit.WithContextLogID(context.Background())
	submitErr := pool.Submit(requestCtx, "send-notice",
		func(taskCtx context.Context) error {
			workCtx, cancel := context.WithTimeout(taskCtx, time.Second)
			defer cancel()
			logit.Info(workCtx, "后台任务执行")
			return workCtx.Err()
		},
	)

	shutdownErr := pool.Shutdown()
	waitErr := pool.Wait()
	return errors.Join(submitErr, shutdownErr, waitErr)
}

Submit 成功只表示任务已接收。任务保存在内存中;需要进程异常退出后的可靠恢复时,应用应选择持久化消息队列。示例显式启用标准输出 JSON 日志,通过 Shutdown 发起排空,再用 Wait 确认 worker 退出,最后关闭 Logger;Wait 没有等待上限。

JWT 签发与验签

jwtx 提供独立的签发器与验签器,可在初始化后并发复用。下面用 HS256 演示签发与验证,并校验签发者 iss、接收方 aud 和签发时间 iat。示例临时生成 32 字节随机密钥;生产环境应从安全配置读取持久密钥。

展开完整示例
package main

import (
	"crypto/rand"
	"fmt"
	"os"
	"time"

	"github.com/bpcoder16/pixiu/infra/jwtx"
	"github.com/golang-jwt/jwt/v5"
)

func main() {
	if run() != nil {
		os.Exit(1)
	}
}

func run() error {
	secret := make([]byte, 32)
	if _, err := rand.Read(secret); err != nil {
		return err
	}
	signer, err := jwtx.NewSigner(jwtx.SignConfig{
		Algorithm: jwtx.HS256,
		Secret:    secret,
	})
	if err != nil {
		return err
	}
	verifier, err := jwtx.NewVerifier(jwtx.VerifyConfig{
		Algorithm:     jwtx.HS256,
		Secret:        secret,
		Issuer:        "example",
		Audience:      []string{"api"},
		CheckIssuedAt: true,
	})
	if err != nil {
		return err
	}
	now := time.Now()
	raw, err := signer.Sign(jwt.RegisteredClaims{
		Issuer:    "example",
		Subject:   "user-42",
		Audience:  jwt.ClaimStrings{"api"},
		IssuedAt:  jwt.NewNumericDate(now),
		ExpiresAt: jwt.NewNumericDate(now.Add(15 * time.Minute)),
	})
	if err != nil {
		return err
	}
	var claims jwt.RegisteredClaims
	if err := verifier.Verify(raw, &claims); err != nil {
		return err
	}
	fmt.Println("已验证用户:", claims.Subject)
	return nil
}

Sign 要求提供 exp,原样签名,不补写声明或检查时间;Verify 验证签名并要求 exp 存在、校验过期时间,存在 nbf 时校验生效时间;时间校验可通过 Leeway 配置容差。RS256 / PS256 使用至少 2048 位的 RSA 密钥,ES256 使用 P-256;非对称签发通过 PrivateKeyPEM 配置私钥,验签通过 PublicKeyPEM 配置公钥,不传 Secret。自定义 claims 与完整密钥格式见 jwtx 包文档。

接入 HTTP 认证时,应用实现 httpauth.Authenticator,通过 httpauth.BearerToken 提取凭证,再调用 jwtx 验签器的 Verify,成功后返回 Principal。按名称注册认证方案,再用 ginauth 的 Require(name) 绑定路由;业务从请求 Context 读取身份。刷新、撤销和授权规则由应用实现,认证成功不自动代表具备业务权限。

更多示例:ginx 请求处理、httpserver 启停、lrucache 缓存、mysqlx 主从查询、natsx 消息通信、redislock 锁流程。

使用约定

这些约定决定了模块组合后的行为,接入时建议先阅读:

场景 约定
请求日志字段 先调用 WithContext 或 WithContextLogID,再使用 AddField / AddMeta;未初始化时会 panic。入口初始化一次,后续传递同一个 context。
字段输出 顺序为 With 预埋字段 → meta 字段 → ctx 普通字段 → 调用点字段。同名 key 保留全部出现顺序,不去重;logId 是可选关联字段,不承诺唯一性。
并行日志作用域 派生 context 默认共享已初始化的字段存储;需要隔离字段时使用 NewContextScope,需要独立耗时表时使用 NewDurationScope。
日志写入 日志调用返回时,选中的 Writer 已完成 Write;不代表每条日志都已 fsync。写入错误通过统计和可选回调观察,业务日志调用不返回该错误。
文件轮转 路径必须为绝对路径,同一路径由一个 Writer 管理。进入新时段后的首次 Write 触发轮转,每小时整点清理旧文件,清理完成前文件数可能暂时超过保留上限;旧文件异步 Sync / Close,Writer 的 Sync / Close 等待收尾。
日志详情 各适配包的日志开关与默认值见包文档。开启 Header / Body / SQL / 命令参数等详情时,按包契约保留完整内容,应用需决定记录范围及敏感数据策略。
数据库读写 事务与要求读己之写的查询显式使用主库;可接受延迟的读取可选择从库。模型迁移由应用决定。
Redis 锁 biz/lockx/redislock 使用固定租期;Cron 通过 bootstrap 组合 gocron-redis-lock 的自动续租。同一资源的竞争者使用相同实现与协议,业务自行响应取消,并结合幂等、事务或数据端版本约束保护结果。
JWT 验签 实例固定算法与密钥。每次验签使用新的空 claims 对象,仅在 Verify 返回 nil 后使用身份字段;失败时丢弃可能已解码的不可信内容。HTTP 认证可组合 httpauth / ginauth,会话刷新、撤销与授权规则由应用处理。
应用退出 先停止入口与生产者,等待任务结束,再关闭下游资源,最后关闭日志。lifecycle.Stack 逆序关闭资源,所以日志关闭函数应先登记。

文件轮转当前不提供 gzip 压缩;系统时间变化和目录中的未来时段文件不在轮转正确性保证范围。

开发与贡献

欢迎通过 Issues 报告问题或讨论新的通用能力,也欢迎提交 Pull Request。

克隆仓库并验证:

git clone https://github.com/bpcoder16/pixiu.git
cd pixiu
go build ./...
make test
make test-race

make test 和 make test-race 是完整测试入口,依次运行默认构建、NATS 配置注册集成测试和 bootstrap 构建标签矩阵。矩阵覆盖八个单独禁用、全部禁用及 Redis/NATS 组合,检查注册错误、生产依赖和 HTTP/Cron 基础行为,并验证仅保留 PostgreSQL 时的数据库装配。CI 可直接使用这两个入口,等价命令如下:

go test ./...
go test -tags=natsintegration ./biz/bootstrap -run '^TestNATSFromConfig$'
make test-bootstrap-tags

go test -race ./...
go test -race -tags=natsintegration ./biz/bootstrap -run '^TestNATSFromConfig$'
make test-bootstrap-tags BOOTSTRAP_TEST_FLAGS=-race

NATS 集成测试与被测代码保持同目录,通过 natsintegration build tag 编入内嵌服务端,无需预先安装服务端或在测试中另行构建可执行文件。常规测试不编入该组用例;带标签的第二轮仅运行 TestNATSFromConfig,其中不调用会修改 time.Local 的 MustBaseInit。不要使用 go test -tags=natsintegration ./... 混跑全部用例,否则 macOS 上服务端初始化的后台采样可能与时区初始化测试发生竞争。直接执行 go test ./... 或 go test -race ./... 只完成第一轮。

开发时遵循以下约定:

  1. 先确认能力所属层次和职责边界,复用既有实现,保持变更聚焦。
  2. 功能变更先用测试定义预期行为;修复问题时提供可复现的输入或场景。
  3. 新增公开包时补充中文 doc.go 和调用示例;公开 API 变化同步更新文档。
  4. 提交前运行 make test 与 make test-race,并使用 gofmt 格式化本次修改的 Go 文件。
  5. 日志或轮转热路径变更需运行与功能等价的性能基准,保留正确性门禁和原始结果。

数据库、Redis 和 Elasticsearch 的真实服务验证需要相应环境;具体条件与跳过行为以各包测试为准。全量构建包含 SQLite 驱动,需要 CGO 与 C 编译器。

Cron 的真实 Redis 验收通过 PIXIU_CRON_REDIS_ADDR 指定独立测试实例的 host:port,然后执行 go test ./biz/bootstrap -run TestCronRedisLeaseAndDrain(也支持 -race)。测试使用随机 key 前缀,验证两个调度器互斥、跨 TTL 续租及停机解锁;未设置地址时跳过该项。

文档入口

  • 使用与 API:从上方模块导航进入各包的 doc.go,或查看 Go Reference。
  • 品牌资源:assets/pixiu-logo.png。
  • 本地设计约定:维护工作区的 docs/ 保存设计与规划,作为项目约定的权威来源;该目录当前被 Git 忽略,不作为 GitHub 阅读入口。

许可证

貔貅采用 Apache License 2.0,允许商业使用、修改和分发,也允许集成到闭源项目。分发时须遵守许可证中的版权、修改声明及适用的 NOTICE 要求。

我们欢迎使用者将通用改进和问题修复贡献回社区;公开修改和提交贡献是自愿的,不是本许可证的强制要求。

第三方依赖保留各自的许可证,貔貅的授权不替代它们的许可条件。依赖版本见 go.mod,使用与分发说明见 第三方声明;具体许可条款以各上游项目的许可证和相关声明为准。

Directories

Path Synopsis
biz
appconfig
Package appconfig 直接定义应用共用的 env/log 配置,组合 configx 和 env 加载配置并初始化环境。
Package appconfig 直接定义应用共用的 env/log 配置,组合 configx 和 env 加载配置并初始化环境。
bootstrap
Package bootstrap 提供日志、MySQL、PostgreSQL、Redis、Elasticsearch、OSS、STS、阿里云 ES 和 NATS 多实例的通用初始化入口, 以及应用运行管理器、Gin Engine、HTTP、realtime 和 Cron 服务的构造方法,供项目自己的 bootstrap 组装。
Package bootstrap 提供日志、MySQL、PostgreSQL、Redis、Elasticsearch、OSS、STS、阿里云 ES 和 NATS 多实例的通用初始化入口, 以及应用运行管理器、Gin Engine、HTTP、realtime 和 Cron 服务的构造方法,供项目自己的 bootstrap 组装。
common
Package common 提供常规业务通用工具:按应用时区生成 ID、格式化时间、精确转换百分比及名称脱敏。
Package common 提供常规业务通用工具:按应用时区生成 ID、格式化时间、精确转换百分比及名称脱敏。
elasticsearchservice
Package elasticsearchservice 组织 Elasticsearch 的通用业务流程。
Package elasticsearchservice 组织 Elasticsearch 的通用业务流程。
httpauth
Package httpauth 提供命名 HTTP 认证方案、统一用户身份和标准 Context 传递。
Package httpauth 提供命名 HTTP 认证方案、统一用户身份和标准 Context 传递。
httpauth/ginauth
Package ginauth 将命名认证方案接入 Gin,负责身份传递和失败请求的中止。
Package ginauth 将命名认证方案接入 Gin,负责身份传递和失败请求的中止。
lockx
Package lockx 定义分布式阻塞与非阻塞锁契约,提供获取、执行和释放的通用流程。
Package lockx 定义分布式阻塞与非阻塞锁契约,提供获取、执行和释放的通用流程。
lockx/internal/lockctx
Package lockctx 为 lockx 公共流程及其后端统一检查 context 取消与期限。
Package lockctx 为 lockx 公共流程及其后端统一检查 context 取消与期限。
lockx/redislock
Package redislock 通过 infra/redisx 实现单机 Redis 上的阻塞与非阻塞锁。
Package redislock 通过 infra/redisx 实现单机 Redis 上的阻塞与非阻塞锁。
ossservice
Package ossservice 提供 multipart 文件上传、限定 OSS 对象的 STS 凭据签发及 URL 内容摘要。
Package ossservice 提供 multipart 文件上传、限定 OSS 对象的 STS 凭据签发及 URL 内容摘要。
outbox
Package outbox 提供事务发件箱:同事务登记,提交后主动发送,失败由项目 cron 补偿。
Package outbox 提供事务发件箱:同事务登记,提交后主动发送,失败由项目 cron 补偿。
outbox/natsoutbox
Package natsoutbox 将 JetStream 发布接入 outbox,发送成功以有效 PubAck 为准。
Package natsoutbox 将 JetStream 发布接入 outbox,发送成功以有效 PubAck 为准。
realtime
Package realtime 基于 websocketx 提供连接身份、独立业务状态和 JSON/PB 双向消息。
Package realtime 基于 websocketx 提供连接身份、独立业务状态和 JSON/PB 双向消息。
realtime/protocol
Package protocol 保存 realtime.v1 的公共 protobuf 信封,不包含业务消息类型。
Package protocol 保存 realtime.v1 的公共 protobuf 信封,不包含业务消息类型。
Package conc 编排单次调用中的并发任务。
Package conc 编排单次调用中的并发任务。
Package cryptox 提供独立的 HMAC-SHA256、AES-GCM 和密码学安全随机数,只使用标准库。
Package cryptox 提供独立的 HMAC-SHA256、AES-GCM 和密码学安全随机数,只使用标准库。
infra
aliyun/esx
Package esx 封装阿里云 Elasticsearch 管理 SDK 的词典清单、词典更新和实例查询。
Package esx 封装阿里云 Elasticsearch 管理 SDK 的词典清单、词典更新和实例查询。
aliyun/ossx
Package ossx 封装官方 SDK 的对象上传、元数据查询和下载签名。
Package ossx 封装官方 SDK 的对象上传、元数据查询和下载签名。
aliyun/stsx
Package stsx 封装阿里云 STS AssumeRole,与 ossx、esx 平行。
Package stsx 封装阿里云 STS AssumeRole,与 ossx、esx 平行。
apprun
Package apprun 提供实例式常驻服务监督、统一停收和并行排空,依赖标准库与 logit。
Package apprun 提供实例式常驻服务监督、统一停收和并行排空,依赖标准库与 logit。
clickhousex
Package clickhousex 提供基于 GORM 的 ClickHouse 连接池、显式主从选择和统一查询日志。
Package clickhousex 提供基于 GORM 的 ClickHouse 连接池、显式主从选择和统一查询日志。
configx
Package configx 提供 YAML、TOML、JSON 文件的结构体解析与全局命名配置。
Package configx 提供 YAML、TOML、JSON 文件的结构体解析与全局命名配置。
cronx
Package cronx 组合 gocron v2 与 logit,提供实例式 Cron、固定和随机间隔调度。
Package cronx 组合 gocron v2 与 logit,提供实例式 Cron、固定和随机间隔调度。
elasticsearchx
Package elasticsearchx 提供 Elasticsearch 7、8、9 共用的结果日志和基础操作。
Package elasticsearchx 提供 Elasticsearch 7、8、9 共用的结果日志和基础操作。
elasticsearchx/v7
Package v7 创建 Elasticsearch 7 官方客户端并接入 elasticsearchx 的统一日志与操作。
Package v7 创建 Elasticsearch 7 官方客户端并接入 elasticsearchx 的统一日志与操作。
elasticsearchx/v8
Package v8 创建 Elasticsearch 8 官方客户端并接入 elasticsearchx 的统一日志与操作。
Package v8 创建 Elasticsearch 8 官方客户端并接入 elasticsearchx 的统一日志与操作。
elasticsearchx/v9
Package v9 创建 Elasticsearch 9 官方客户端并接入 elasticsearchx 的统一日志与操作。
Package v9 创建 Elasticsearch 9 官方客户端并接入 elasticsearchx 的统一日志与操作。
env
Package env 提供独立于启动方式的应用运行环境,供 HTTP、命令行等应用复用。
Package env 提供独立于启动方式的应用运行环境,供 HTTP、命令行等应用复用。
estextsearch
Package estextsearch 构建短文本检索的 Elasticsearch 查询子句,仅依赖标准库。
Package estextsearch 构建短文本检索的 Elasticsearch 查询子句,仅依赖标准库。
ginx
Package ginx 提供独立 Gin Engine、请求日志和 Recovery。
Package ginx 提供独立 Gin Engine、请求日志和 Recovery。
gormx
Package gormx 为 Repository 提供统一的主、从库会话依赖 Sessions 和通用查询辅助方法。
Package gormx 为 Repository 提供统一的主、从库会话依赖 Sessions 和通用查询辅助方法。
httpcall
Package httpcall 提供可复用的 HTTP 下游客户端,统一记录调用日志与耗时。
Package httpcall 提供可复用的 HTTP 下游客户端,统一记录调用日志与耗时。
httpserver
Package httpserver 提供独立 HTTP 服务端、普通请求停收和实际排空,不管理 WebSocket 等已接管连接。
Package httpserver 提供独立 HTTP 服务端、普通请求停收和实际排空,不管理 WebSocket 等已接管连接。
internal/aliyun
Package aliyun 提供阿里云 SDK 适配包内部共用的配置校验、凭据解析、HTTP 客户端构造和 Tea 结果日志分类。
Package aliyun 提供阿里云 SDK 适配包内部共用的配置校验、凭据解析、HTTP 客户端构造和 Tea 结果日志分类。
internal/gorm
Package gorm 提供 infra 内部共用的 GORM 日志、连接池初始化和主从路由能力。
Package gorm 提供 infra 内部共用的 GORM 日志、连接池初始化和主从路由能力。
internal/handlerregistry
Package handlerregistry 为 infra 内的强类型 Handler 注册表共用登记、命名和快照逻辑。
Package handlerregistry 为 infra 内的强类型 Handler 注册表共用登记、命名和快照逻辑。
internal/named
Package named 提供 infra 内部共用的可关闭客户端命名与默认注册表。
Package named 提供 infra 内部共用的可关闭客户端命名与默认注册表。
jwtx
Package jwtx 提供独立的 HS256、RS256、ES256、PS256 JWT 签发器与验签器,复用 golang-jwt/jwt v5。
Package jwtx 提供独立的 HS256、RS256、ES256、PS256 JWT 签发器与验签器,复用 golang-jwt/jwt v5。
lrucache
Package lrucache 提供有界 LRU 缓存,支持独立实例和命名共享实例,可设置实例默认 TTL 和单条目 TTL。
Package lrucache 提供有界 LRU 缓存,支持独立实例和命名共享实例,可设置实例默认 TTL 和单条目 TTL。
mysqlx
Package mysqlx 提供基于 GORM 的 MySQL 连接池、显式主从选择和统一查询日志。
Package mysqlx 提供基于 GORM 的 MySQL 连接池、显式主从选择和统一查询日志。
natsx
Package natsx 提供实例式 NATS 连接、启动期消费注册、通用消息操作和 logit 结果日志。
Package natsx 提供实例式 NATS 连接、启动期消费注册、通用消息操作和 logit 结果日志。
postgresqlx
Package postgresqlx 提供基于 GORM 的 PostgreSQL 连接池、显式主从选择和统一查询日志。
Package postgresqlx 提供基于 GORM 的 PostgreSQL 连接池、显式主从选择和统一查询日志。
redisx
Package redisx 管理单机 Redis 客户端的创建、验活、关闭和可配置的命令结果日志。
Package redisx 管理单机 Redis 客户端的创建、验活、关闭和可配置的命令结果日志。
schemamigrate
Package schemamigrate 封装 GORM AutoMigrate 和 SQL 种子校准,提供项目可复用的数据库初始化能力。
Package schemamigrate 封装 GORM AutoMigrate 和 SQL 种子校准,提供项目可复用的数据库初始化能力。
sqlitex
Package sqlitex 提供基于 GORM 的 SQLite 单库连接池和统一查询日志。
Package sqlitex 提供基于 GORM 的 SQLite 单库连接池和统一查询日志。
taskpool
Package taskpool 提供本地异步任务池,依赖 logit 创建独立日志作用域并关联 logId。
Package taskpool 提供本地异步任务池,依赖 logit 创建独立日志作用域并关联 logId。
websocketx
Package websocketx 提供独立的标准 http.Handler WebSocket 传输,不依赖 Gin 或消息中间件。
Package websocketx 提供独立的标准 http.Handler WebSocket 传输,不依赖 Gin 或消息中间件。
Package jsonx 提供独立于传输协议的 JSON 首值解码,保留解码期间观察到的底层读取错误。
Package jsonx 提供独立于传输协议的 JSON 首值解码,保留解码期间观察到的底层读取错误。
Package lifecycle 提供实例式资源关闭栈,零第三方依赖且没有进程级全局状态。
Package lifecycle 提供实例式资源关闭栈,零第三方依赖且没有进程级全局状态。
Package logit 是 pixiu 的日志模块:门面与核心同包,零第三方依赖,性能优先。
Package logit 是 pixiu 的日志模块:门面与核心同包,零第三方依赖,性能优先。
Package moneyx 提供无状态、仅依赖标准库的元字符串与 int64 分金额转换,支持正数、负数和零。
Package moneyx 提供无状态、仅依赖标准库的元字符串与 int64 分金额转换,支持正数、负数和零。
Package netx 提供小型、可复用的网络技术功能,当前支持查询本机 IPv4 和 IPv6 地址。
Package netx 提供小型、可复用的网络技术功能,当前支持查询本机 IPv4 和 IPv6 地址。
Package rotatefile 提供独立于日志模块的按本地小时或天轮转的文件写入器。
Package rotatefile 提供独立于日志模块的按本地小时或天轮转的文件写入器。
Package validx 提供无状态、仅依赖标准库的参数格式验证函数。
Package validx 提供无状态、仅依赖标准库的参数格式验证函数。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL