feat(架构): 完善基础架构设计

This commit is contained in:
2025-07-02 16:17:59 +08:00
parent 03e615a8fd
commit 5b4392894f
89 changed files with 18555 additions and 3521 deletions

255
scripts/deploy.ps1 Normal file
View File

@@ -0,0 +1,255 @@
# TYAPI 生产环境部署脚本 (PowerShell版本)
# 使用方法: .\scripts\deploy.ps1 [版本号]
param(
[string]$Version = "latest"
)
# 配置
$REGISTRY_URL = "docker-registry.tianyuanapi.com"
$IMAGE_NAME = "tyapi-server"
$APP_VERSION = $Version
$BUILD_TIME = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ")
try {
$GIT_COMMIT = git rev-parse --short HEAD 2>$null
if (-not $GIT_COMMIT) { $GIT_COMMIT = "dev" }
}
catch {
$GIT_COMMIT = "dev"
}
# 颜色输出函数
function Write-Info($message) {
Write-Host "[INFO] $message" -ForegroundColor Blue
}
function Write-Success($message) {
Write-Host "[SUCCESS] $message" -ForegroundColor Green
}
function Write-Warning($message) {
Write-Host "[WARNING] $message" -ForegroundColor Yellow
}
function Write-Error($message) {
Write-Host "[ERROR] $message" -ForegroundColor Red
}
# 检查必要工具
function Test-Requirements {
Write-Info "检查部署环境..."
if (-not (Get-Command docker -ErrorAction SilentlyContinue)) {
Write-Error "Docker 未安装或不在 PATH 中"
exit 1
}
if (-not (Get-Command docker-compose -ErrorAction SilentlyContinue)) {
Write-Error "docker-compose 未安装或不在 PATH 中"
exit 1
}
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
Write-Warning "Git 未安装,将使用默认提交哈希"
}
Write-Success "环境检查通过"
}
# 构建 Docker 镜像
function Build-Image {
Write-Info "开始构建 Docker 镜像..."
docker build `
--build-arg VERSION="$APP_VERSION" `
--build-arg COMMIT="$GIT_COMMIT" `
--build-arg BUILD_TIME="$BUILD_TIME" `
-t "$REGISTRY_URL/$IMAGE_NAME`:$APP_VERSION" `
-t "$REGISTRY_URL/$IMAGE_NAME`:latest" `
.
if ($LASTEXITCODE -ne 0) {
Write-Error "Docker 镜像构建失败"
exit 1
}
Write-Success "Docker 镜像构建完成"
}
# 推送镜像到私有仓库
function Push-Image {
Write-Info "推送镜像到私有仓库..."
# 推送版本标签
docker push "$REGISTRY_URL/$IMAGE_NAME`:$APP_VERSION"
if ($LASTEXITCODE -eq 0) {
Write-Success "已推送版本标签: $APP_VERSION"
}
else {
Write-Error "推送版本标签失败"
exit 1
}
# 推送latest标签
docker push "$REGISTRY_URL/$IMAGE_NAME`:latest"
if ($LASTEXITCODE -eq 0) {
Write-Success "已推送latest标签"
}
else {
Write-Error "推送latest标签失败"
exit 1
}
}
# 准备生产环境配置
function Test-Config {
Write-Info "准备生产环境配置..."
# 检查.env文件是否存在
if (-not (Test-Path ".env")) {
if (Test-Path ".env.production") {
Write-Warning ".env文件不存在正在复制模板..."
Copy-Item ".env.production" ".env"
Write-Warning "请编辑 .env 文件并设置正确的配置值"
exit 1
}
else {
Write-Error "配置文件 .env 和 .env.production 都不存在"
exit 1
}
}
# 验证关键配置
$envContent = Get-Content ".env" -Raw
if (-not ($envContent -match "^DB_PASSWORD=" -and -not ($envContent -match "your_secure_database_password_here"))) {
Write-Error "请在 .env 文件中设置安全的数据库密码"
exit 1
}
if (-not ($envContent -match "^JWT_SECRET=" -and -not ($envContent -match "your_super_secure_jwt_secret"))) {
Write-Error "请在 .env 文件中设置安全的JWT密钥"
exit 1
}
Write-Success "配置检查通过"
}
# 部署到生产环境
function Start-Deploy {
Write-Info "开始部署到生产环境..."
# 设置版本环境变量
$env:APP_VERSION = $APP_VERSION
# 停止现有服务
Write-Info "停止现有服务..."
docker-compose -f docker-compose.prod.yml down --remove-orphans
# 清理未使用的镜像
Write-Info "清理未使用的Docker资源..."
docker image prune -f
# 拉取最新镜像
Write-Info "拉取最新镜像..."
docker-compose -f docker-compose.prod.yml pull
# 启动服务
Write-Info "启动生产环境服务..."
docker-compose -f docker-compose.prod.yml up -d
if ($LASTEXITCODE -ne 0) {
Write-Error "服务启动失败"
exit 1
}
# 等待服务启动
Write-Info "等待服务启动..."
Start-Sleep -Seconds 30
# 检查服务状态
Write-Info "检查服务状态..."
docker-compose -f docker-compose.prod.yml ps
# 健康检查
Write-Info "执行健康检查..."
$maxAttempts = 10
$attempt = 0
while ($attempt -lt $maxAttempts) {
try {
$response = Invoke-WebRequest -Uri "http://localhost:8080/health" -TimeoutSec 5 -ErrorAction Stop
if ($response.StatusCode -eq 200) {
Write-Success "应用健康检查通过"
break
}
}
catch {
$attempt++
Write-Info "健康检查失败,重试 $attempt/$maxAttempts..."
Start-Sleep -Seconds 10
}
}
if ($attempt -eq $maxAttempts) {
Write-Error "应用健康检查失败,请检查日志"
docker-compose -f docker-compose.prod.yml logs tyapi-app
exit 1
}
Write-Success "部署完成!"
}
# 显示部署信息
function Show-Info {
Write-Info "部署信息:"
Write-Host " 版本: $APP_VERSION"
Write-Host " 提交: $GIT_COMMIT"
Write-Host " 构建时间: $BUILD_TIME"
Write-Host " 镜像: $REGISTRY_URL/$IMAGE_NAME`:$APP_VERSION"
Write-Host ""
Write-Host "🌐 服务访问地址:"
Write-Host " 📱 API服务: http://localhost:8080"
Write-Host " 📚 API文档: http://localhost:8080/swagger/index.html"
Write-Host " 💚 健康检查: http://localhost:8080/health"
Write-Host ""
Write-Host "📊 监控和追踪:"
Write-Host " 📈 Grafana仪表盘: http://localhost:3000"
Write-Host " 🔍 Prometheus监控: http://localhost:9090"
Write-Host " 🔗 Jaeger链路追踪: http://localhost:16686"
Write-Host ""
Write-Host "🛠 管理工具:"
Write-Host " 🗄️ pgAdmin数据库: http://localhost:5050"
Write-Host " 📦 MinIO对象存储: http://localhost:9000"
Write-Host " 🎛️ MinIO控制台: http://localhost:9001"
Write-Host ""
Write-Host "🔧 管理命令:"
Write-Host " 查看日志: docker-compose -f docker-compose.prod.yml logs -f"
Write-Host " 停止服务: docker-compose -f docker-compose.prod.yml down"
Write-Host " 查看状态: docker-compose -f docker-compose.prod.yml ps"
Write-Host " 重启应用: docker-compose -f docker-compose.prod.yml restart tyapi-app"
}
# 主函数
function Main {
Write-Info "开始 TYAPI 生产环境部署..."
Write-Info "版本: $APP_VERSION"
Test-Requirements
Test-Config
Build-Image
Push-Image
Start-Deploy
Show-Info
Write-Success "🎉 部署成功!"
}
# 运行主函数
try {
Main
}
catch {
Write-Error "部署过程中发生错误: $($_.Exception.Message)"
exit 1
}

221
scripts/deploy.sh Normal file
View File

@@ -0,0 +1,221 @@
#!/bin/bash
# TYAPI 生产环境部署脚本
# 使用方法: ./scripts/deploy.sh [version]
set -e
# 配置
REGISTRY_URL="docker-registry.tianyuanapi.com"
IMAGE_NAME="tyapi-server"
APP_VERSION=${1:-latest}
BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo 'dev')
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查必要工具
check_requirements() {
log_info "检查部署环境..."
if ! command -v docker &> /dev/null; then
log_error "Docker 未安装或不在 PATH 中"
exit 1
fi
if ! command -v docker-compose &> /dev/null; then
log_error "docker-compose 未安装或不在 PATH 中"
exit 1
fi
if ! command -v git &> /dev/null; then
log_warning "Git 未安装,将使用默认提交哈希"
fi
log_success "环境检查通过"
}
# 构建 Docker 镜像
build_image() {
log_info "开始构建 Docker 镜像..."
docker build \
--build-arg VERSION="$APP_VERSION" \
--build-arg COMMIT="$GIT_COMMIT" \
--build-arg BUILD_TIME="$BUILD_TIME" \
-t "$REGISTRY_URL/$IMAGE_NAME:$APP_VERSION" \
-t "$REGISTRY_URL/$IMAGE_NAME:latest" \
.
log_success "Docker 镜像构建完成"
}
# 推送镜像到私有仓库
push_image() {
log_info "推送镜像到私有仓库..."
# 推送版本标签
docker push "$REGISTRY_URL/$IMAGE_NAME:$APP_VERSION"
log_success "已推送版本标签: $APP_VERSION"
# 推送latest标签
docker push "$REGISTRY_URL/$IMAGE_NAME:latest"
log_success "已推送latest标签"
}
# 准备生产环境配置
prepare_config() {
log_info "准备生产环境配置..."
# 检查.env文件是否存在
if [ ! -f ".env" ]; then
if [ -f ".env.production" ]; then
log_warning ".env文件不存在正在复制模板..."
cp .env.production .env
log_warning "请编辑 .env 文件并设置正确的配置值"
exit 1
else
log_error "配置文件 .env 和 .env.production 都不存在"
exit 1
fi
fi
# 验证关键配置
if ! grep -q "^DB_PASSWORD=" .env || grep -q "your_secure_database_password_here" .env; then
log_error "请在 .env 文件中设置安全的数据库密码"
exit 1
fi
if ! grep -q "^JWT_SECRET=" .env || grep -q "your_super_secure_jwt_secret" .env; then
log_error "请在 .env 文件中设置安全的JWT密钥"
exit 1
fi
log_success "配置检查通过"
}
# 部署到生产环境
deploy() {
log_info "开始部署到生产环境..."
# 设置版本环境变量
export APP_VERSION="$APP_VERSION"
# 停止现有服务
log_info "停止现有服务..."
docker-compose -f docker-compose.prod.yml down --remove-orphans
# 清理未使用的镜像
log_info "清理未使用的Docker资源..."
docker image prune -f
# 拉取最新镜像
log_info "拉取最新镜像..."
docker-compose -f docker-compose.prod.yml pull
# 启动服务
log_info "启动生产环境服务..."
docker-compose -f docker-compose.prod.yml up -d
# 等待服务启动
log_info "等待服务启动..."
sleep 30
# 检查服务状态
log_info "检查服务状态..."
docker-compose -f docker-compose.prod.yml ps
# 健康检查
log_info "执行健康检查..."
max_attempts=10
attempt=0
while [ $attempt -lt $max_attempts ]; do
if curl -f http://localhost:8080/health > /dev/null 2>&1; then
log_success "应用健康检查通过"
break
else
attempt=$((attempt + 1))
log_info "健康检查失败,重试 $attempt/$max_attempts..."
sleep 10
fi
done
if [ $attempt -eq $max_attempts ]; then
log_error "应用健康检查失败,请检查日志"
docker-compose -f docker-compose.prod.yml logs tyapi-app
exit 1
fi
log_success "部署完成!"
}
# 显示部署信息
show_info() {
log_info "部署信息:"
echo " 版本: $APP_VERSION"
echo " 提交: $GIT_COMMIT"
echo " 构建时间: $BUILD_TIME"
echo " 镜像: $REGISTRY_URL/$IMAGE_NAME:$APP_VERSION"
echo ""
echo "🌐 服务访问地址:"
echo " 📱 API服务: http://localhost:8080"
echo " 📚 API文档: http://localhost:8080/swagger/index.html"
echo " 💚 健康检查: http://localhost:8080/health"
echo ""
echo "📊 监控和追踪:"
echo " 📈 Grafana仪表盘: http://localhost:3000"
echo " 🔍 Prometheus监控: http://localhost:9090"
echo " 🔗 Jaeger链路追踪: http://localhost:16686"
echo ""
echo "🛠 管理工具:"
echo " 🗄️ pgAdmin数据库: http://localhost:5050"
echo " 📦 MinIO对象存储: http://localhost:9000"
echo " 🎛️ MinIO控制台: http://localhost:9001"
echo ""
echo "🔧 管理命令:"
echo " 查看日志: docker-compose -f docker-compose.prod.yml logs -f"
echo " 停止服务: docker-compose -f docker-compose.prod.yml down"
echo " 查看状态: docker-compose -f docker-compose.prod.yml ps"
echo " 重启应用: docker-compose -f docker-compose.prod.yml restart tyapi-app"
}
# 主函数
main() {
log_info "开始 TYAPI 生产环境部署..."
log_info "版本: $APP_VERSION"
check_requirements
prepare_config
build_image
push_image
deploy
show_info
log_success "🎉 部署成功!"
}
# 运行主函数
main "$@"

View File

@@ -2,10 +2,10 @@
-- This script runs when PostgreSQL container starts for the first time
-- Create development database if it doesn't exist
CREATE DATABASE tyapi_dev;
-- Note: tyapi_dev is already created by POSTGRES_DB environment variable
-- Create test database for running tests
CREATE DATABASE tyapi_test;
-- Note: Skip database creation in init script, handle in application if needed
-- Create production database (for reference)
-- CREATE DATABASE tyapi_prod;
@@ -30,25 +30,11 @@ CREATE SCHEMA IF NOT EXISTS metrics;
-- Set search path
SET search_path TO public, logs, metrics;
-- Connect to test database and setup extensions
\c tyapi_test;
-- Test database setup will be handled by application migrations
-- when needed, since we don't create it in this init script
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
CREATE EXTENSION IF NOT EXISTS "btree_gin";
CREATE SCHEMA IF NOT EXISTS public;
CREATE SCHEMA IF NOT EXISTS logs;
CREATE SCHEMA IF NOT EXISTS metrics;
SET search_path TO public, logs, metrics;
-- Switch back to development database
\c tyapi_dev;
-- Continue with development database setup
-- (already connected to tyapi_dev)
-- Create application-specific roles (optional)
-- CREATE ROLE tyapi_app WITH LOGIN PASSWORD 'app_password';
@@ -63,9 +49,7 @@ SET search_path TO public, logs, metrics;
-- This will be replaced by proper migrations in the application
-- Log the initialization
INSERT INTO
pg_stat_statements_info (dealloc)
VALUES (0) ON CONFLICT DO NOTHING;
-- Note: pg_stat_statements extension may not be available, skip this insert
-- Create a simple health check function
CREATE OR REPLACE FUNCTION health_check()