🔧 索引重建优化: - 当数据库为空时跳过索引重建,避免频繁日志 - 只在有数据的页面时记录详细扫描日志 - 添加记录计数统计,显示重建的记录数量 - 减少 CPU 使用率,提高空数据库性能 💻 系统监控功能: - 添加完整的 CPU 和内存监控 - 实时显示 Goroutine 数量和内存使用情况 - 垃圾回收统计和对象分配监控 - 每10秒显示系统资源状态 📊 自动处理示例增强: - 集成系统资源监控到示例中 - 提供性能分析和资源优化指导 - 完善的监控文档和使用说明 🎯 性能提升: - 解决空数据库时的高 CPU 使用问题 - 优化日志输出频率和级别 - 提供实时性能监控能力
330 lines
10 KiB
Makefile
330 lines
10 KiB
Makefile
# Pipeline Database - Makefile
|
|
# ===================================
|
|
|
|
# 项目信息
|
|
PROJECT_NAME := pipelinedb
|
|
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
|
|
|
|
# Go 工具
|
|
GOCMD := go
|
|
GOTEST := $(GOCMD) test
|
|
GOMOD := $(GOCMD) mod
|
|
GOFMT := gofmt
|
|
GOVET := $(GOCMD) vet
|
|
GOLINT := golangci-lint
|
|
|
|
# 目录定义
|
|
COVERAGE_DIR := coverage
|
|
EXAMPLES_DIR := examples
|
|
|
|
# 默认目标
|
|
.PHONY: all
|
|
all: deps fmt vet test
|
|
|
|
# ==================== 依赖管理 ====================
|
|
|
|
.PHONY: deps
|
|
deps: ## 下载依赖
|
|
@echo "📦 下载依赖..."
|
|
$(GOMOD) download
|
|
$(GOMOD) tidy
|
|
|
|
.PHONY: deps-update
|
|
deps-update: ## 更新依赖
|
|
@echo "🔄 更新依赖..."
|
|
$(GOMOD) get -u ./...
|
|
$(GOMOD) tidy
|
|
|
|
.PHONY: deps-verify
|
|
deps-verify: ## 验证依赖
|
|
@echo "✅ 验证依赖..."
|
|
$(GOMOD) verify
|
|
|
|
# ==================== 代码格式化和检查 ====================
|
|
|
|
.PHONY: fmt
|
|
fmt: ## 格式化代码
|
|
@echo "🎨 格式化代码..."
|
|
$(GOFMT) -s -w .
|
|
$(GOCMD) mod tidy
|
|
|
|
.PHONY: fmt-check
|
|
fmt-check: ## 检查代码格式
|
|
@echo "🔍 检查代码格式..."
|
|
@if [ -n "$$($(GOFMT) -s -l .)" ]; then \
|
|
echo "❌ 以下文件需要格式化:"; \
|
|
$(GOFMT) -s -l .; \
|
|
exit 1; \
|
|
fi
|
|
@echo "✅ 代码格式正确"
|
|
|
|
.PHONY: vet
|
|
vet: ## 静态代码分析
|
|
@echo "🔍 静态代码分析..."
|
|
$(GOVET) ./...
|
|
|
|
.PHONY: lint
|
|
lint: ## 代码质量检查
|
|
@echo "🔍 代码质量检查..."
|
|
@if command -v $(GOLINT) >/dev/null 2>&1; then \
|
|
$(GOLINT) run --timeout=5m; \
|
|
else \
|
|
echo "⚠️ golangci-lint 未安装,跳过 lint 检查"; \
|
|
echo "安装命令: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest"; \
|
|
fi
|
|
|
|
.PHONY: lint-install
|
|
lint-install: ## 安装代码质量检查工具
|
|
@echo "📥 安装 golangci-lint..."
|
|
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
|
|
|
|
|
# ==================== 测试 ====================
|
|
|
|
.PHONY: test
|
|
test: ## 运行测试
|
|
@echo "🧪 运行测试..."
|
|
$(GOTEST) -v -race ./...
|
|
|
|
.PHONY: test-short
|
|
test-short: ## 运行快速测试
|
|
@echo "⚡ 运行快速测试..."
|
|
$(GOTEST) -short -v ./...
|
|
|
|
.PHONY: test-coverage
|
|
test-coverage: ## 生成测试覆盖率报告
|
|
@echo "📊 生成测试覆盖率报告..."
|
|
@mkdir -p $(COVERAGE_DIR)
|
|
$(GOCMD) tool cover -html=$(COVERAGE_DIR)/coverage.out -o $(COVERAGE_DIR)/coverage.html
|
|
$(GOCMD) tool cover -func=$(COVERAGE_DIR)/coverage.out | grep total
|
|
|
|
.PHONY: test-coverage-ci
|
|
test-coverage-ci: ## CI环境的覆盖率测试
|
|
@echo "📊 CI 环境测试覆盖率..."
|
|
$(GOTEST) -v -coverprofile=coverage.out ./...
|
|
@COVERAGE=$$(go tool cover -func=coverage.out | grep total | awk '{print $$3}' | sed 's/%//'); \
|
|
echo "测试覆盖率: $${COVERAGE}%"; \
|
|
if [ "$$(echo "$$COVERAGE < 70" | bc -l)" -eq 1 ]; then \
|
|
echo "❌ 测试覆盖率低于 70%"; \
|
|
exit 1; \
|
|
fi; \
|
|
echo "✅ 测试覆盖率达标"
|
|
|
|
# ==================== 基准测试 ====================
|
|
|
|
.PHONY: bench
|
|
bench: ## 运行基准测试
|
|
@echo "⚡ 运行基准测试..."
|
|
$(GOTEST) -bench=. -benchmem -run=^$$ ./...
|
|
|
|
.PHONY: bench-cpu
|
|
bench-cpu: ## CPU性能分析
|
|
@echo "🔥 CPU 性能分析..."
|
|
@mkdir -p $(COVERAGE_DIR)
|
|
$(GOTEST) -bench=BenchmarkConcurrentAcceptData -cpuprofile=$(COVERAGE_DIR)/cpu.prof -run=^$$ ./...
|
|
$(GOCMD) tool pprof -text $(COVERAGE_DIR)/cpu.prof | head -20
|
|
|
|
.PHONY: bench-mem
|
|
bench-mem: ## 内存性能分析
|
|
@echo "💾 内存性能分析..."
|
|
@mkdir -p $(COVERAGE_DIR)
|
|
$(GOTEST) -bench=BenchmarkConcurrentAcceptData -memprofile=$(COVERAGE_DIR)/mem.prof -run=^$$ ./...
|
|
$(GOCMD) tool pprof -text $(COVERAGE_DIR)/mem.prof | head -20
|
|
|
|
.PHONY: bench-concurrent
|
|
bench-concurrent: ## 并发基准测试
|
|
@echo "🚀 并发基准测试..."
|
|
$(GOTEST) -bench=BenchmarkConcurrent -benchmem -benchtime=2s -run=^$$ ./...
|
|
|
|
.PHONY: bench-all
|
|
bench-all: ## 完整基准测试套件
|
|
@echo "📊 完整基准测试套件..."
|
|
@echo "=== 核心功能基准测试 ==="
|
|
$(GOTEST) -bench=BenchmarkPipelineDB -benchmem -benchtime=1s -run=^$$ ./...
|
|
@echo "=== 并发性能基准测试 ==="
|
|
$(GOTEST) -bench=BenchmarkConcurrent -benchmem -benchtime=1s -run=^$$ ./...
|
|
@echo "=== 存储引擎基准测试 ==="
|
|
$(GOTEST) -bench=BenchmarkStorage -benchmem -benchtime=1s -run=^$$ ./...
|
|
@echo "=== 缓存系统基准测试 ==="
|
|
$(GOTEST) -bench=BenchmarkCache -benchmem -benchtime=1s -run=^$$ ./...
|
|
|
|
# ==================== 示例运行 ====================
|
|
|
|
.PHONY: run-basic
|
|
run-basic: ## 运行基础使用示例
|
|
@echo "🎯 运行基础使用示例..."
|
|
@cd $(EXAMPLES_DIR)/basic-usage && GOWORK=off $(GOCMD) run main.go
|
|
|
|
.PHONY: run-group
|
|
run-group: ## 运行组管理示例
|
|
@echo "🎯 运行组管理示例..."
|
|
@cd $(EXAMPLES_DIR)/group-management && GOWORK=off $(GOCMD) run main.go
|
|
|
|
.PHONY: run-handler
|
|
run-handler: ## 运行处理器示例
|
|
@echo "🎯 运行处理器示例..."
|
|
@cd $(EXAMPLES_DIR)/external-handler && GOWORK=off $(GOCMD) run main.go
|
|
|
|
.PHONY: run-auto
|
|
run-auto: ## 运行自动处理示例
|
|
@echo "🚀 运行自动处理示例..."
|
|
@cd $(EXAMPLES_DIR)/auto-processing && GOWORK=off $(GOCMD) run main.go
|
|
|
|
# ==================== 安全和质量 ====================
|
|
|
|
.PHONY: security
|
|
security: ## 安全扫描
|
|
@echo "🔒 安全扫描..."
|
|
@if command -v gosec >/dev/null 2>&1; then \
|
|
gosec ./...; \
|
|
else \
|
|
echo "⚠️ gosec 未安装,跳过安全扫描"; \
|
|
echo "安装命令: go install github.com/securego/gosec/v2/cmd/gosec@latest"; \
|
|
fi
|
|
|
|
.PHONY: security-install
|
|
security-install: ## 安装安全扫描工具
|
|
@echo "📥 安装 gosec..."
|
|
go install github.com/securego/gosec/v2/cmd/gosec@latest
|
|
|
|
.PHONY: complexity
|
|
complexity: ## 检查代码复杂度
|
|
@echo "🔍 检查代码复杂度..."
|
|
@if command -v gocyclo >/dev/null 2>&1; then \
|
|
gocyclo -over 15 .; \
|
|
else \
|
|
echo "⚠️ gocyclo 未安装,跳过复杂度检查"; \
|
|
echo "安装命令: go install github.com/fzipp/gocyclo/cmd/gocyclo@latest"; \
|
|
fi
|
|
|
|
.PHONY: yaml-check
|
|
yaml-check: ## 检查 YAML 文件语法
|
|
@echo "📋 检查 YAML 文件语法..."
|
|
@if command -v yamllint >/dev/null 2>&1; then \
|
|
yamllint .gitea/workflows/*.yml || true; \
|
|
else \
|
|
echo "⚠️ yamllint 未安装,跳过 YAML 检查"; \
|
|
echo "安装命令: make yamllint-install"; \
|
|
fi
|
|
|
|
.PHONY: yamllint-install
|
|
yamllint-install: ## 安装 YAML 语法检查工具
|
|
@echo "📥 安装 yamllint..."
|
|
@if command -v brew >/dev/null 2>&1; then \
|
|
echo "使用 Homebrew 安装 yamllint..."; \
|
|
brew install yamllint; \
|
|
elif command -v apt-get >/dev/null 2>&1; then \
|
|
echo "使用 apt-get 安装 yamllint..."; \
|
|
sudo apt-get update && sudo apt-get install -y yamllint; \
|
|
elif command -v yum >/dev/null 2>&1; then \
|
|
echo "使用 yum 安装 yamllint..."; \
|
|
sudo yum install -y yamllint; \
|
|
elif command -v dnf >/dev/null 2>&1; then \
|
|
echo "使用 dnf 安装 yamllint..."; \
|
|
sudo dnf install -y yamllint; \
|
|
elif command -v pipx >/dev/null 2>&1; then \
|
|
echo "使用 pipx 安装 yamllint..."; \
|
|
pipx install yamllint; \
|
|
elif command -v pip3 >/dev/null 2>&1; then \
|
|
echo "使用 pip3 安装 yamllint (用户模式)..."; \
|
|
pip3 install --user --break-system-packages yamllint 2>/dev/null || pip3 install --user yamllint; \
|
|
elif command -v pip >/dev/null 2>&1; then \
|
|
echo "使用 pip 安装 yamllint (用户模式)..."; \
|
|
pip install --user --break-system-packages yamllint 2>/dev/null || pip install --user yamllint; \
|
|
else \
|
|
echo "❌ 无法找到包管理器,请手动安装 yamllint"; \
|
|
echo "macOS: brew install yamllint"; \
|
|
echo "Ubuntu/Debian: sudo apt-get install yamllint"; \
|
|
echo "CentOS/RHEL: sudo yum install yamllint"; \
|
|
echo "Python: pipx install yamllint"; \
|
|
exit 1; \
|
|
fi
|
|
|
|
.PHONY: tools-install
|
|
tools-install: lint-install security-install yamllint-install ## 安装所有开发工具
|
|
@echo "📥 安装开发工具..."
|
|
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
|
|
go install honnef.co/go/tools/cmd/staticcheck@latest
|
|
go install github.com/mibk/dupl@latest
|
|
|
|
# ==================== CI/CD 相关 ====================
|
|
|
|
.PHONY: ci
|
|
ci: deps fmt-check vet yaml-check test-coverage-ci ## CI 流水线
|
|
@echo "🤖 CI 流水线完成"
|
|
|
|
.PHONY: pre-commit
|
|
pre-commit: fmt vet test ## 提交前检查
|
|
@echo "✅ 提交前检查完成"
|
|
|
|
# ==================== 发布相关 ====================
|
|
|
|
.PHONY: release
|
|
release: ci ## 创建发布标签
|
|
@echo "🏷️ 准备创建发布标签..."
|
|
@if [ "$(VERSION)" = "dev" ]; then \
|
|
echo "❌ 请先创建 Git 标签,例如: git tag v1.0.0"; \
|
|
exit 1; \
|
|
fi
|
|
@echo "📋 当前版本: $(VERSION)"
|
|
@echo "📊 运行最终检查..."
|
|
@git status --porcelain | grep -q . && echo "❌ 工作目录不干净,请先提交所有更改" && exit 1 || true
|
|
@echo "✅ 工作目录干净"
|
|
@echo "🎉 发布标签 $(VERSION) 已准备就绪"
|
|
@echo ""
|
|
@echo "📦 发布信息:"
|
|
@echo " 版本: $(VERSION)"
|
|
@echo " 提交: $$(git rev-parse HEAD)"
|
|
@echo " 分支: $$(git branch --show-current)"
|
|
@echo " 时间: $$(date)"
|
|
@echo ""
|
|
@echo "🚀 要推送标签到远程仓库,请运行:"
|
|
@echo " git push origin $(VERSION)"
|
|
|
|
.PHONY: tag
|
|
tag: ## 创建新的版本标签
|
|
@echo "🏷️ 创建新版本标签..."
|
|
@read -p "请输入版本号 (例如 v1.0.0): " version; \
|
|
if [ -z "$$version" ]; then \
|
|
echo "❌ 版本号不能为空"; \
|
|
exit 1; \
|
|
fi; \
|
|
echo "📋 创建标签: $$version"; \
|
|
git tag -a "$$version" -m "Release $$version"; \
|
|
echo "✅ 标签 $$version 已创建"; \
|
|
echo "🚀 要推送标签,请运行: git push origin $$version"
|
|
|
|
# ==================== 清理 ====================
|
|
|
|
.PHONY: clean
|
|
clean: ## 清理临时文件
|
|
@echo "🧹 清理临时文件..."
|
|
@rm -rf $(COVERAGE_DIR)
|
|
@rm -f coverage.out *.prof
|
|
@find . -name "*.db" -type f -delete 2>/dev/null || true
|
|
@find . -name "*.log" -type f -delete 2>/dev/null || true
|
|
|
|
# ==================== 开发辅助 ====================
|
|
|
|
.PHONY: dev-setup
|
|
dev-setup: deps tools-install ## 开发环境设置
|
|
@echo "🛠️ 开发环境设置完成"
|
|
|
|
.PHONY: help
|
|
help: ## 显示帮助信息
|
|
@echo "Pipeline Database - Makefile 帮助"
|
|
@echo "======================================"
|
|
@echo ""
|
|
@echo "可用命令:"
|
|
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
|
@echo ""
|
|
@echo "常用命令组合:"
|
|
@echo " make dev-setup # 初始化开发环境"
|
|
@echo " make pre-commit # 提交前检查"
|
|
@echo " make ci # CI 流水线"
|
|
@echo " make tag # 创建版本标签"
|
|
@echo " make release # 发布检查"
|
|
|
|
# 默认显示帮助
|
|
.DEFAULT_GOAL := help
|