gitea workflow

This commit is contained in:
2025-12-15 22:50:03 +08:00
parent 5f90c88c63
commit c62aa4b120
56 changed files with 6900 additions and 162 deletions
Vendored
BIN
View File
Binary file not shown.
+52 -156
View File
@@ -1,177 +1,73 @@
# ============================================
# LJWX 统一配置文件 v2.0
# ============================================
# 此文件统一管理所有构建、推送、部署配置
# 使用方法: cp .env.unified .env
# ============================================
# ==============================================
# P0 监控完整环境配置文件
# 用于 docker-compose-p0.yml
# ==============================================
# --------------------------------------------
# 版本配置
# --------------------------------------------
# 应用版本(统一版本号)
LJWX_VERSION=2.0.4
# ----------------------------------------------
# 基础设施端口配置
# ----------------------------------------------
MYSQL_PORT=3306
REDIS_PORT=6379
REDIS_EXPORTER_PORT=9121
# 组件独立版本(如需单独升级某个组件)
LJWX_MYSQL_VERSION=${LJWX_VERSION}
LJWX_REDIS_VERSION=${LJWX_VERSION}
LJWX_BOOT_VERSION=${LJWX_VERSION}
LJWX_BIGSCREEN_VERSION=${LJWX_VERSION}
LJWX_ADMIN_VERSION=${LJWX_VERSION}
# ----------------------------------------------
# 业务应用端口配置
# ----------------------------------------------
LJWX_BOOT_PORT=9998
LJWX_ADMIN_PORT=5173
# 监控组件版本
LJWX_GRAFANA_VERSION=1.2.6
LJWX_PROMETHEUS_VERSION=1.2.6
LJWX_LOKI_VERSION=1.2.6
LJWX_PROMTAIL_VERSION=1.2.6
LJWX_ALERTMANAGER_VERSION=1.2.6
# ----------------------------------------------
# 监控系统端口配置
# ----------------------------------------------
PROMETHEUS_PORT=9090
GRAFANA_PORT=3000
# 数据库版本(用于迁移管理)
DB_MIGRATION_VERSION=2.0.3
# --------------------------------------------
# 镜像仓库配置
# --------------------------------------------
# Harbor 配置(主要推送目标)
HARBOR_HOST=harbor.omniverseai.net
HARBOR_PROJECT=health
HARBOR_USERNAME=admin
HARBOR_PASSWORD=admin123
HARBOR_INSECURE=false
# 镜像仓库地址(使用 Harbor)
REGISTRY=${HARBOR_HOST}/${HARBOR_PROJECT}
PRIVATE_REGISTRY_HOST=${HARBOR_HOST}
PRIVATE_REGISTRY_ENABLED=true
# 本地缓存 Registry(拉取加速 - 可选)
CACHE_REGISTRY_HOST=localhost:15001
CACHE_REGISTRY_ENABLED=false
# --------------------------------------------
# 构建配置
# --------------------------------------------
# 构建平台
PLATFORMS=linux/amd64
# 构建模式
LOCAL_BUILD=true
PUSH_TO_REGISTRY=true
DOCKER_BUILDKIT=1
COMPOSE_DOCKER_CLI_BUILD=1
# 代理配置(如需要)
HTTP_PROXY=
HTTPS_PROXY=
NO_PROXY=localhost,127.0.0.1,*.local
# --------------------------------------------
# ----------------------------------------------
# MySQL 数据库配置
# --------------------------------------------
# 容器内数据库配置
# ----------------------------------------------
MYSQL_ROOT_PASSWORD=123456
MYSQL_DATABASE=test
MYSQL_USER=root
MYSQL_PASSWORD=123456
MYSQL_PORT=3307
# 宿主机数据库配置(用于数据导出)
HOST_MYSQL_HOST=127.0.0.1
HOST_MYSQL_PORT=3306
HOST_MYSQL_USER=root
HOST_MYSQL_PASSWORD=123456
HOST_MYSQL_DATABASE=test
# 数据库迁移配置
DB_MIGRATION_ENABLED=true
DB_MIGRATION_AUTO_APPLY=true
DB_MIGRATION_DIR=./docker/mysql/migrations
# --------------------------------------------
# Redis 缓存配置
# --------------------------------------------
REDIS_HOST=ljwx-redis
REDIS_PORT=6379
# ----------------------------------------------
# Redis 配置
# ----------------------------------------------
REDIS_PASSWORD=123456
REDIS_DB=0
REDIS_DATABASE=1
REDIS_MAXMEMORY=2gb
# --------------------------------------------
# 应用配置
# --------------------------------------------
# Spring Boot 环境
# ----------------------------------------------
# ljwx-boot 应用配置
# ----------------------------------------------
SPRING_PROFILES_ACTIVE=prod
# 后端服务配置
BOOT_PORT=9998
BOOT_JVM_OPTS="-Xms512m -Xmx1g -XX:+UseG1GC"
# P0-3 Redis去重配置
HEALTH_DEDUP_USE_REDIS=true
HEALTH_DEDUP_TTL_HOURS=24
HEALTH_DEDUP_USE_CONTENT_HASH=true
# 大屏服务配置
BIGSCREEN_PORT=5225
BIGSCREEN_EXTERNAL_PORT=8000
# P0-4 缓存失效配置
HEALTH_CACHE_AUTO_INVALIDATION=true
HEALTH_CACHE_INVALIDATION_DELAY_MS=1000
# 管理界面配置
ADMIN_PORT=80
ADMIN_EXTERNAL_PORT=8080
# Prometheus Metrics
MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE=*
MANAGEMENT_METRICS_EXPORT_PROMETHEUS_ENABLED=true
# --------------------------------------------
# 部署配置
# --------------------------------------------
# Docker Compose 文件
COMPOSE_FILE=docker-compose.prod.yml
# ----------------------------------------------
# ljwx-admin 前端配置
# ----------------------------------------------
NODE_ENV=production
VITE_USER_NODE_ENV=production
# 网络配置
NETWORK_NAME=ljwx-network
# 数据卷配置
MYSQL_VOLUME=mysql_data
REDIS_VOLUME=redis_data
# ----------------------------------------------
# Grafana 配置
# ----------------------------------------------
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=admin123
# ----------------------------------------------
# 时区配置
# ----------------------------------------------
TZ=Asia/Shanghai
# --------------------------------------------
# 监控配置
# --------------------------------------------
# Grafana
GF_SECURITY_ADMIN_PASSWORD=admin123
GRAFANA_PORT=3001
# Prometheus
PROMETHEUS_PORT=9091
# 功能特性
FEATURES_ENABLED=grafana-dashboard,prometheus-config,loki-logs,promtail-collect,alertmanager-rules
MONITORING_TIER=enterprise
# --------------------------------------------
# 构建元数据
# --------------------------------------------
BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
# --------------------------------------------
# 使用说明
# --------------------------------------------
# 1. 复制配置: cp .env.unified .env
# 2. 修改配置: 根据实际环境调整密码、端口等
# 3. 构建镜像: ./build-and-push.sh -b
# 4. 推送镜像: ./build-and-push.sh -p
# 5. 部署服务: ./build-and-push.sh -d
# 6. 一键部署: ./build-and-push.sh -a
# ============================================
# v2.0 配置总结
# ============================================
# Harbor 推送目标: ${HARBOR_HOST}/${HARBOR_PROJECT}
# 完整镜像格式: localhost:80/health/ljwx-boot:2.0.4
# Harbor 管理界面: http://localhost:80
#
# Docker insecure registry 配置(HTTP Harbor 必需):
# macOS: Docker Desktop -> Preferences -> Docker Engine
# {
# "insecure-registries": ["localhost:80"]
# }
#
# 使用示例:
# 1. 构建并推送到 Harbor: ./build-and-push-v2.sh -b -p
# 2. 查看镜像: http://localhost:80/harbor/projects/20/repositories
# ============================================
+326
View File
@@ -0,0 +1,326 @@
# Gitea CI/CD 配置指南
本文档说明如何配置 LJWX Health 项目的 Gitea Actions CI/CD 流水线。
## 架构概述
```
Gitea 代码推送
↓
Gitea Actions Runner (本机 K8s 部署)
↓
构建 Docker 镜像 → 推送到 Harbor
↓
部署到本机 K8s ljwx-health namespace
```
## 前置要求
### 1. Gitea Actions Runner
确保你的 K8s 集群中已部署 Gitea Actions Runner:
```bash
# 检查 runner 状态
kubectl get pods -n gitea-runner
# 查看 runner 日志
kubectl logs -n gitea-runner -l app=gitea-runner -f
```
### 2. Gitea 仓库 Secrets 配置
在 Gitea 仓库设置中配置以下 Secrets:
**路径**: `http://192.168.1.83:33000/gao/ljwx-health/settings/secrets`
| Secret 名称 | 说明 | 示例值 |
|------------|------|-------|
| `HARBOR_USERNAME` | Harbor 镜像仓库用户名 | `admin` |
| `HARBOR_PASSWORD` | Harbor 镜像仓库密码 | `your_harbor_password` |
**配置步骤**:
1. 进入仓库 Settings → Secrets
2. 点击 "Add Secret"
3. 输入 Name 和 Value
4. 点击 "Add Secret" 保存
### 3. K8s 配置
#### 3.1 创建 ljwx-health namespace
```bash
kubectl create namespace ljwx-health
```
#### 3.2 配置 Harbor 拉取密钥(可选)
如果你的 K8s 集群还没有 Harbor 拉取密钥,可以手动创建:
```bash
kubectl create secret docker-registry harbor-secret \
--docker-server=harbor.omniverseai.net \
--docker-username=YOUR_HARBOR_USERNAME \
--docker-password=YOUR_HARBOR_PASSWORD \
--namespace=ljwx-health
```
**注意**: CI/CD workflow 会自动创建/更新这个 secret,所以这一步是可选的。
#### 3.3 配置 ConfigMap 和 Secret
确保 K8s 配置文件中的 ConfigMap 和 Secret 已创建:
```bash
# 应用 ljwx-boot 配置
cd ljwx-boot/k8s
kubectl apply -f configmap.yml -n ljwx-health
# 创建数据库 Secret(示例,请根据实际情况修改)
kubectl create secret generic ljwx-boot-secret \
--from-literal=database.username=root \
--from-literal=database.password=123456 \
--from-literal=redis.password=123456 \
--namespace=ljwx-health
```
## Workflow 功能说明
### 触发条件
1. **自动触发**:推送到 `main` 或 `develop` 分支时
- 仅构建修改过的组件
- 例如:修改 `ljwx-boot/` 下的文件,只会构建 ljwx-boot
2. **手动触发**:通过 Gitea Actions UI 手动运行
- 可以选择构建特定组件:`all`、`boot`、`admin`、`bigscreen`
- 路径:`Actions` → 选择 workflow → `Run workflow`
### 构建流程
#### 阶段 1: 构建镜像(并行)
- **build-boot**: 构建 ljwx-boot 后端镜像
- **build-admin**: 构建 ljwx-admin 前端镜像
- **build-bigscreen**: 构建 ljwx-bigscreen 监控面板镜像
每个镜像会推送到 Harbor:
```
harbor.omniverseai.net/ljwx-health/ljwx-boot:main-abc1234
harbor.omniverseai.net/ljwx-health/ljwx-boot:latest
```
#### 阶段 2: 部署到 K8s
- 自动更新 K8s deployment 镜像
- 执行滚动更新(零停机)
- 等待部署完成并验证状态
### 镜像标签策略
- `latest`: 最新版本(每次推送都会更新)
- `{branch}-{sha}`: 分支名 + Git commit SHA(用于追溯)
- 示例:`main-5f90c88`, `develop-1a42f93`
## 使用方法
### 方法 1: 推送代码自动触发
```bash
# 修改代码
git add .
git commit -m "feat: add new feature"
git push origin main
# 自动触发 CI/CD,构建修改的组件
```
### 方法 2: 手动触发
1. 进入 Gitea Actions 页面
2. 选择 "LJWX Health CI/CD Pipeline" workflow
3. 点击 "Run workflow"
4. 选择要构建的组件:
- `all`: 构建所有组件
- `boot`: 仅构建 ljwx-boot
- `admin`: 仅构建 ljwx-admin
- `bigscreen`: 仅构建 ljwx-bigscreen
5. 点击确认
### 查看构建状态
```bash
# 查看 workflow 执行状态
# 访问: http://192.168.1.83:33000/gao/ljwx-health/actions
# 查看 K8s 部署状态
kubectl get deployments -n ljwx-health
kubectl get pods -n ljwx-health
kubectl logs -n ljwx-health -l app=ljwx-boot -f
```
## 故障排查
### 问题 1: Workflow 没有触发
**可能原因**:
- Gitea Runner 未运行
- Workflow 文件语法错误
**解决方法**:
```bash
# 检查 runner 状态
kubectl get pods -n gitea-runner
# 检查 workflow 语法
cat .gitea/workflows/ci-cd.yml
```
### 问题 2: Docker 构建失败
**可能原因**:
- Dockerfile 路径错误
- 构建依赖缺失
**解决方法**:
```bash
# 手动测试构建
cd ljwx-boot
docker build -f ljwx-boot-admin/Dockerfile .
# 查看构建日志
# Gitea Actions UI 中查看详细日志
```
### 问题 3: Harbor 推送失败
**可能原因**:
- Secrets 未配置或配置错误
- Harbor 连接失败
**解决方法**:
```bash
# 测试 Harbor 登录
docker login harbor.omniverseai.net
# 检查 Gitea Secrets 配置
# Settings → Secrets
```
### 问题 4: K8s 部署失败
**可能原因**:
- kubectl 权限不足
- ConfigMap/Secret 未创建
- 镜像拉取失败
**解决方法**:
```bash
# 检查 kubectl 权限
kubectl auth can-i get pods -n ljwx-health
# 检查 harbor-secret
kubectl get secret harbor-secret -n ljwx-health
# 查看 Pod 事件
kubectl describe pod -n ljwx-health -l app=ljwx-boot
```
### 问题 5: 回滚机制
如果部署失败,workflow 会自动回滚到上一个版本:
```bash
# 手动回滚
kubectl rollout undo deployment/ljwx-boot -n ljwx-health
# 查看回滚历史
kubectl rollout history deployment/ljwx-boot -n ljwx-health
```
## 高级配置
### 多环境部署
如需支持多环境(dev/staging/prod),可以:
1. 修改 workflow 添加环境参数
2. 为每个环境创建独立的 namespace
3. 使用不同的 Harbor project
示例:
```yaml
env:
K8S_NAMESPACE: ljwx-health-${{ github.event.inputs.environment }}
```
### 构建优化
1. **使用 BuildKit**:
```yaml
env:
DOCKER_BUILDKIT: 1
```
2. **多阶段构建缓存**:
```yaml
docker build --cache-from harbor.omniverseai.net/ljwx-health/ljwx-boot:latest ...
```
3. **并行构建**:
workflow 已配置为并行构建三个组件,无需额外配置。
## 监控和通知
### 构建通知(可选)
可以添加构建通知到企业微信/钉钉:
```yaml
- name: 通知部署成功
if: success()
run: |
curl -X POST 'YOUR_WEBHOOK_URL' \
-d '{"msgtype":"text","text":{"content":"✅ 部署成功"}}'
```
### Prometheus 监控
ljwx-boot 已集成 Prometheus metrics:
- 访问: `http://<ljwx-boot-service>:9998/actuator/prometheus`
- ServiceMonitor 已配置在 `ljwx-boot/k8s/servicemonitor.yml`
## 文件结构
```
ljwx-health/
├── .gitea/
│ └── workflows/
│ ├── ci-cd.yml # 主 CI/CD 流水线 ✅
│ ├── openapi-contract.yml # API 契约检查
│ └── GITEA_CI_CD_SETUP.md # 本文档
├── ljwx-boot/
│ ├── ljwx-boot-admin/Dockerfile # Boot Dockerfile
│ └── k8s/ # K8s 配置文件
│ ├── deployment.yml
│ ├── service.yml
│ ├── configmap.yml
│ └── ...
├── ljwx-admin/
│ └── Dockerfile.prod # Admin Dockerfile
└── ljwx-bigscreen/
└── bigscreen/Dockerfile.prod # BigScreen Dockerfile
```
## 下一步
1. ✅ 配置 Gitea Secrets
2. ✅ 验证 Gitea Runner 运行状态
3. ✅ 测试手动触发 workflow
4. ✅ 推送代码触发自动构建
5. ⬜ 配置构建通知(可选)
6. ⬜ 集成自动化测试(可选)
## 参考资料
- [Gitea Actions 文档](https://docs.gitea.com/usage/actions/overview)
- [Harbor 文档](https://goharbor.io/docs/)
- [Kubernetes 部署最佳实践](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)
+178
View File
@@ -0,0 +1,178 @@
# Gitea CI/CD 快速启动指南
## 5 分钟配置清单
### ✅ 第 1 步:配置 Gitea Secrets(2 分钟)
访问: http://192.168.1.83:33000/gao/ljwx-health/settings/secrets
添加以下 Secrets:
- [ ] `HARBOR_USERNAME`: Harbor 用户名
- [ ] `HARBOR_PASSWORD`: Harbor 密码
### ✅ 第 2 步:验证 Gitea Runner(1 分钟)
```bash
# 检查 runner 是否运行
kubectl get pods -n gitea-runner
# 期望输出:至少一个 Running 的 pod
# NAME READY STATUS RESTARTS AGE
# gitea-runner-xxxxxxxxx-xxxxx 1/1 Running 0 1h
```
如果 runner 未运行,需要先部署 runner。
### ✅ 第 3 步:创建 K8s namespace(30 秒)
```bash
kubectl create namespace ljwx-health
```
### ✅ 第 4 步:手动测试 workflow(1 分钟)
1. 访问: http://192.168.1.83:33000/gao/ljwx-health/actions
2. 选择 "LJWX Health CI/CD Pipeline"
3. 点击 "Run workflow"
4. 选择组件: `boot` (测试最小组件)
5. 点击确认
### ✅ 第 5 步:监控执行(1 分钟)
在 Actions 页面查看执行状态:
- ⏳ **黄色**:正在运行
- ✅ **绿色**:执行成功
- ❌ **红色**:执行失败(点击查看日志)
## 预期结果
### 成功标志
构建成功后,你应该看到:
1. **Harbor 镜像**:
```bash
# 访问 Harbor Web UI
https://harbor.omniverseai.net/harbor/projects/14/repositories/ljwx-boot
# 或使用 docker 命令检查
docker pull harbor.omniverseai.net/ljwx-health/ljwx-boot:latest
```
2. **K8s 部署**:
```bash
kubectl get deployments -n ljwx-health
# 期望输出:
# NAME READY UP-TO-DATE AVAILABLE AGE
# ljwx-boot 2/2 2 2 5m
kubectl get pods -n ljwx-health
# 期望输出:
# NAME READY STATUS RESTARTS AGE
# ljwx-boot-xxxxxxxxx-xxxxx 1/1 Running 0 5m
# ljwx-boot-xxxxxxxxx-xxxxx 1/1 Running 0 5m
```
3. **服务访问**:
```bash
kubectl get svc -n ljwx-health
# 获取服务地址
# 测试健康检查
kubectl port-forward -n ljwx-health svc/ljwx-boot 9998:9998
curl http://localhost:9998/actuator/health
```
## 常见问题速查
### ❌ Runner 未运行
**错误**: workflow 显示 "Waiting for runner"
**解决**:
```bash
# 检查 runner
kubectl get pods -n gitea-runner -o wide
# 如果没有 runner,需要先部署
# 参考: https://docs.gitea.com/usage/actions/quickstart
```
### ❌ Secrets 未配置
**错误**: `Error: Cannot perform an interactive login from a non TTY device`
**解决**: 检查 Gitea Secrets 是否正确配置
### ❌ Harbor 登录失败
**错误**: `unauthorized: authentication required`
**解决**:
```bash
# 手动测试 Harbor 登录
docker login harbor.omniverseai.net
# 使用与 Secrets 相同的用户名密码
```
### ❌ K8s 部署失败
**错误**: `error: failed to create deployment`
**解决**:
```bash
# 检查 ConfigMap 和 Secret
kubectl get configmap -n ljwx-health
kubectl get secret -n ljwx-health
# 如果缺失,手动创建
kubectl apply -f ljwx-boot/k8s/configmap.yml -n ljwx-health
```
## 下一步
### 推送代码触发自动构建
```bash
# 修改任意文件
echo "# Test" >> ljwx-boot/README.md
# 提交并推送
git add .
git commit -m "test: trigger ci/cd"
git push origin main
# 自动触发构建
```
### 查看详细日志
```bash
# Workflow 日志
# 访问: http://192.168.1.83:33000/gao/ljwx-health/actions
# 点击具体的 workflow run → 查看每个 step 的日志
# K8s Pod 日志
kubectl logs -n ljwx-health -l app=ljwx-boot -f
# Runner 日志
kubectl logs -n gitea-runner -l app=gitea-runner -f
```
## 完整配置文档
详细配置请参考: [GITEA_CI_CD_SETUP.md](./GITEA_CI_CD_SETUP.md)
## 技术支持
如遇问题,请检查:
1. ✅ Gitea Secrets 是否正确配置
2. ✅ Runner 是否正常运行
3. ✅ Harbor 是否可访问
4. ✅ K8s 集群是否正常
5. ✅ Workflow 语法是否正确
查看 Workflow 文件: `.gitea/workflows/ci-cd.yml`
+57
View File
@@ -0,0 +1,57 @@
# Workflow 备份文件
这个目录包含了旧的 workflow 配置文件,已被新的统一 CI/CD workflow 替代。
## 备份文件说明
| 文件 | 原位置 | 说明 | 状态 |
|------|-------|------|------|
| `build-and-deploy.yml` | `ljwx-boot/.gitea/workflows/` | ljwx-boot 单独的构建部署 | ❌ 已废弃 |
| `ci-test.yml` | `ljwx-boot/.gitea/workflows/` | ljwx-boot 测试流程 | ❌ 已废弃 |
| `ci-cd.yml` | `ljwx-bigscreen/.gitea/workflows/` | ljwx-bigscreen CI/CD | ❌ 已废弃 |
## 为什么废弃?
这些 workflow 文件存在以下问题:
1. **GitHub Actions 语法**:使用了 GitHub Actions 的语法,不完全兼容 Gitea
2. **分散配置**:每个组件有独立的 workflow,难以统一管理
3. **runner 标签问题**:使用了 `ubuntu-latest` 等 GitHub 特定标签
## 新的统一 Workflow
现在使用统一的 CI/CD workflow:
**位置**: `.gitea/workflows/ci-cd.yml`
**特性**:
- ✅ 完全兼容 Gitea Actions
- ✅ 统一管理三个组件(boot/admin/bigscreen)
- ✅ 智能检测修改,仅构建变更的组件
- ✅ 支持手动触发和选择组件
- ✅ 使用 self-hosted runner
- ✅ 自动部署到本地 K8s
**文档**: `.gitea/GITEA_CI_CD_SETUP.md`
## 如何恢复旧配置?
如果需要恢复旧的 workflow(不推荐):
```bash
# 恢复 ljwx-boot 的 workflow
cp .gitea/workflows-backup/build-and-deploy.yml ljwx-boot/.gitea/workflows/
# 恢复 ljwx-bigscreen 的 workflow
cp .gitea/workflows-backup/ci-cd.yml ljwx-bigscreen/.gitea/workflows/
```
**注意**: 恢复后需要修改语法以兼容 Gitea Actions。
## 清理建议
如果新的 CI/CD workflow 运行正常超过 1 个月,可以安全删除这个备份目录:
```bash
rm -rf .gitea/workflows-backup
```
+290
View File
@@ -0,0 +1,290 @@
name: LJWX Health CI/CD Pipeline
on:
push:
branches:
- main
- develop
paths:
- 'ljwx-boot/**'
- 'ljwx-admin/**'
- 'ljwx-bigscreen/**'
- '.gitea/workflows/ci-cd.yml'
pull_request:
branches:
- main
- develop
workflow_dispatch:
inputs:
component:
description: '选择构建组件 (all/boot/admin/bigscreen)'
required: false
default: 'all'
env:
HARBOR_REGISTRY: harbor.omniverseai.net
HARBOR_PROJECT: ljwx-health
K8S_NAMESPACE: ljwx-health
IMAGE_TAG: ${{ github.ref_name }}-${{ github.sha }}
jobs:
# ==================== Job 1: 构建并推送 ljwx-boot 镜像 ====================
build-boot:
name: 构建 ljwx-boot 镜像
runs-on: self-hosted
if: |
github.event_name == 'workflow_dispatch' && (github.event.inputs.component == 'all' || github.event.inputs.component == 'boot') ||
github.event_name != 'workflow_dispatch' && (
contains(github.event.head_commit.modified, 'ljwx-boot/') ||
contains(github.event.head_commit.added, 'ljwx-boot/') ||
contains(github.event.head_commit.removed, 'ljwx-boot/')
)
timeout-minutes: 30
steps:
- name: 检出代码
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 登录 Harbor
run: |
echo "${{ secrets.HARBOR_PASSWORD }}" | docker login ${{ env.HARBOR_REGISTRY }} \
--username "${{ secrets.HARBOR_USERNAME }}" \
--password-stdin
- name: 构建并推送 ljwx-boot 镜像
working-directory: ljwx-boot
run: |
IMAGE_NAME="${{ env.HARBOR_REGISTRY }}/${{ env.HARBOR_PROJECT }}/ljwx-boot"
# 构建镜像
docker build \
-t ${IMAGE_NAME}:${{ env.IMAGE_TAG }} \
-t ${IMAGE_NAME}:latest \
-f ljwx-boot-admin/Dockerfile \
.
# 推送镜像
docker push ${IMAGE_NAME}:${{ env.IMAGE_TAG }}
docker push ${IMAGE_NAME}:latest
echo "✅ ljwx-boot 镜像构建并推送成功"
echo "📦 镜像地址: ${IMAGE_NAME}:${{ env.IMAGE_TAG }}"
# ==================== Job 2: 构建并推送 ljwx-admin 镜像 ====================
build-admin:
name: 构建 ljwx-admin 镜像
runs-on: self-hosted
if: |
github.event_name == 'workflow_dispatch' && (github.event.inputs.component == 'all' || github.event.inputs.component == 'admin') ||
github.event_name != 'workflow_dispatch' && (
contains(github.event.head_commit.modified, 'ljwx-admin/') ||
contains(github.event.head_commit.added, 'ljwx-admin/') ||
contains(github.event.head_commit.removed, 'ljwx-admin/')
)
timeout-minutes: 30
steps:
- name: 检出代码
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 登录 Harbor
run: |
echo "${{ secrets.HARBOR_PASSWORD }}" | docker login ${{ env.HARBOR_REGISTRY }} \
--username "${{ secrets.HARBOR_USERNAME }}" \
--password-stdin
- name: 构建并推送 ljwx-admin 镜像
working-directory: ljwx-admin
run: |
IMAGE_NAME="${{ env.HARBOR_REGISTRY }}/${{ env.HARBOR_PROJECT }}/ljwx-admin"
# 构建镜像
docker build \
-t ${IMAGE_NAME}:${{ env.IMAGE_TAG }} \
-t ${IMAGE_NAME}:latest \
-f Dockerfile.prod \
.
# 推送镜像
docker push ${IMAGE_NAME}:${{ env.IMAGE_TAG }}
docker push ${IMAGE_NAME}:latest
echo "✅ ljwx-admin 镜像构建并推送成功"
echo "📦 镜像地址: ${IMAGE_NAME}:${{ env.IMAGE_TAG }}"
# ==================== Job 3: 构建并推送 ljwx-bigscreen 镜像 ====================
build-bigscreen:
name: 构建 ljwx-bigscreen 镜像
runs-on: self-hosted
if: |
github.event_name == 'workflow_dispatch' && (github.event.inputs.component == 'all' || github.event.inputs.component == 'bigscreen') ||
github.event_name != 'workflow_dispatch' && (
contains(github.event.head_commit.modified, 'ljwx-bigscreen/') ||
contains(github.event.head_commit.added, 'ljwx-bigscreen/') ||
contains(github.event.head_commit.removed, 'ljwx-bigscreen/')
)
timeout-minutes: 30
steps:
- name: 检出代码
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 登录 Harbor
run: |
echo "${{ secrets.HARBOR_PASSWORD }}" | docker login ${{ env.HARBOR_REGISTRY }} \
--username "${{ secrets.HARBOR_USERNAME }}" \
--password-stdin
- name: 构建并推送 ljwx-bigscreen 镜像
working-directory: ljwx-bigscreen/bigscreen
run: |
IMAGE_NAME="${{ env.HARBOR_REGISTRY }}/${{ env.HARBOR_PROJECT }}/ljwx-bigscreen"
# 构建镜像
docker build \
-t ${IMAGE_NAME}:${{ env.IMAGE_TAG }} \
-t ${IMAGE_NAME}:latest \
-f Dockerfile.prod \
.
# 推送镜像
docker push ${IMAGE_NAME}:${{ env.IMAGE_TAG }}
docker push ${IMAGE_NAME}:latest
echo "✅ ljwx-bigscreen 镜像构建并推送成功"
echo "📦 镜像地址: ${IMAGE_NAME}:${{ env.IMAGE_TAG }}"
# ==================== Job 4: 部署到 K8s ====================
deploy-to-k8s:
name: 部署到 K8s 集群
runs-on: self-hosted
needs: [build-boot, build-admin, build-bigscreen]
if: |
always() &&
(needs.build-boot.result == 'success' || needs.build-boot.result == 'skipped') &&
(needs.build-admin.result == 'success' || needs.build-admin.result == 'skipped') &&
(needs.build-bigscreen.result == 'success' || needs.build-bigscreen.result == 'skipped') &&
(needs.build-boot.result == 'success' || needs.build-admin.result == 'success' || needs.build-bigscreen.result == 'success')
timeout-minutes: 10
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 验证 kubectl 连接
run: |
kubectl cluster-info
kubectl get nodes
echo "✅ K8s 集群连接正常"
- name: 创建命名空间(如不存在)
run: |
if ! kubectl get namespace ${{ env.K8S_NAMESPACE }} > /dev/null 2>&1; then
kubectl create namespace ${{ env.K8S_NAMESPACE }}
echo "✅ 命名空间 ${{ env.K8S_NAMESPACE }} 已创建"
else
echo "ℹ️ 命名空间 ${{ env.K8S_NAMESPACE }} 已存在"
fi
- name: 创建 Harbor 拉取密钥
run: |
kubectl create secret docker-registry harbor-secret \
--docker-server=${{ env.HARBOR_REGISTRY }} \
--docker-username=${{ secrets.HARBOR_USERNAME }} \
--docker-password=${{ secrets.HARBOR_PASSWORD }} \
--namespace=${{ env.K8S_NAMESPACE }} \
--dry-run=client -o yaml | kubectl apply -f -
echo "✅ Harbor 拉取密钥已配置"
- name: 部署 ljwx-boot
if: needs.build-boot.result == 'success'
run: |
cd ljwx-boot/k8s
# 应用 ConfigMap 和 Secret(如果存在)
if [ -f configmap.yml ]; then
kubectl apply -f configmap.yml -n ${{ env.K8S_NAMESPACE }}
fi
# 应用部署配置
kubectl apply -f deployment.yml -n ${{ env.K8S_NAMESPACE }}
kubectl apply -f service.yml -n ${{ env.K8S_NAMESPACE }}
# 更新镜像
kubectl set image deployment/ljwx-boot \
ljwx-boot=${{ env.HARBOR_REGISTRY }}/${{ env.HARBOR_PROJECT }}/ljwx-boot:${{ env.IMAGE_TAG }} \
-n ${{ env.K8S_NAMESPACE }} \
--record
# 等待部署完成
kubectl rollout status deployment/ljwx-boot -n ${{ env.K8S_NAMESPACE }} --timeout=300s
echo "✅ ljwx-boot 部署成功"
- name: 部署 ljwx-admin
if: needs.build-admin.result == 'success'
run: |
# 检查是否存在 K8s 配置文件
if [ -d ljwx-admin/k8s ]; then
cd ljwx-admin/k8s
kubectl apply -f . -n ${{ env.K8S_NAMESPACE }}
kubectl set image deployment/ljwx-admin \
ljwx-admin=${{ env.HARBOR_REGISTRY }}/${{ env.HARBOR_PROJECT }}/ljwx-admin:${{ env.IMAGE_TAG }} \
-n ${{ env.K8S_NAMESPACE }} \
--record || echo "⚠️ ljwx-admin deployment 不存在,跳过"
kubectl rollout status deployment/ljwx-admin -n ${{ env.K8S_NAMESPACE }} --timeout=300s || echo "⚠️ ljwx-admin 部署状态检查失败"
else
echo "⚠️ ljwx-admin K8s 配置不存在,跳过部署"
fi
- name: 部署 ljwx-bigscreen
if: needs.build-bigscreen.result == 'success'
run: |
# 检查是否存在 K8s 配置文件
if [ -d ljwx-bigscreen/k8s ]; then
cd ljwx-bigscreen/k8s
kubectl apply -f . -n ${{ env.K8S_NAMESPACE }}
kubectl set image deployment/ljwx-bigscreen \
ljwx-bigscreen=${{ env.HARBOR_REGISTRY }}/${{ env.HARBOR_PROJECT }}/ljwx-bigscreen:${{ env.IMAGE_TAG }} \
-n ${{ env.K8S_NAMESPACE }} \
--record || echo "⚠️ ljwx-bigscreen deployment 不存在,跳过"
kubectl rollout status deployment/ljwx-bigscreen -n ${{ env.K8S_NAMESPACE }} --timeout=300s || echo "⚠️ ljwx-bigscreen 部署状态检查失败"
else
echo "⚠️ ljwx-bigscreen K8s 配置不存在,跳过部署"
fi
- name: 验证部署状态
run: |
echo "========================================="
echo "📊 部署状态汇总"
echo "========================================="
kubectl get deployments -n ${{ env.K8S_NAMESPACE }}
echo ""
echo "📦 Pod 状态:"
kubectl get pods -n ${{ env.K8S_NAMESPACE }}
echo ""
echo "🔗 服务状态:"
kubectl get svc -n ${{ env.K8S_NAMESPACE }}
echo ""
echo "✅ 部署验证完成"
- name: 回滚处理
if: failure()
run: |
echo "❌ 部署失败,执行回滚..."
# 回滚所有部署
kubectl rollout undo deployment/ljwx-boot -n ${{ env.K8S_NAMESPACE }} || echo "⚠️ ljwx-boot 回滚失败"
kubectl rollout undo deployment/ljwx-admin -n ${{ env.K8S_NAMESPACE }} || echo "⚠️ ljwx-admin 回滚失败"
kubectl rollout undo deployment/ljwx-bigscreen -n ${{ env.K8S_NAMESPACE }} || echo "⚠️ ljwx-bigscreen 回滚失败"
# 等待回滚完成
kubectl rollout status deployment/ljwx-boot -n ${{ env.K8S_NAMESPACE }} --timeout=180s || true
echo "⚠️ 已回滚到上一个版本,请检查错误日志"
exit 1
Binary file not shown.
+71
View File
@@ -0,0 +1,71 @@
# ==============================================
# P0 监控环境配置文件
# 用于 docker-compose-p0-monitoring.yml
# ==============================================
# ----------------------------------------------
# 基础设施端口配置
# ----------------------------------------------
# MySQL
MYSQL_PORT=3306
# Redis
REDIS_PORT=6379
# Prometheus
PROMETHEUS_PORT=9090
# Grafana
GRAFANA_PORT=3000
# Redis Exporter
REDIS_EXPORTER_PORT=9121
# ----------------------------------------------
# 业务应用端口配置
# ----------------------------------------------
# ljwx-boot 后端服务
LJWX_BOOT_PORT=9998
# ljwx-admin 前端服务
LJWX_ADMIN_PORT=5173
# ----------------------------------------------
# 数据库配置
# ----------------------------------------------
# MySQL
MYSQL_ROOT_PASSWORD=123456
MYSQL_DATABASE=test
MYSQL_USER=root
MYSQL_PASSWORD=123456
# Redis
REDIS_PASSWORD=123456
REDIS_DATABASE=1
REDIS_MAXMEMORY=2gb
# ----------------------------------------------
# 应用配置
# ----------------------------------------------
# ljwx-boot
SPRING_PROFILES_ACTIVE=prod
HEALTH_DEDUP_USE_REDIS=true
HEALTH_DEDUP_TTL_HOURS=24
HEALTH_DEDUP_USE_CONTENT_HASH=true
HEALTH_CACHE_AUTO_INVALIDATION=true
HEALTH_CACHE_INVALIDATION_DELAY_MS=1000
# ljwx-admin
NODE_ENV=production
VITE_USER_NODE_ENV=production
# ----------------------------------------------
# Grafana配置
# ----------------------------------------------
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=admin123
# ----------------------------------------------
# 时区配置
# ----------------------------------------------
TZ=Asia/Shanghai
+71
View File
@@ -0,0 +1,71 @@
# ==============================================
# P0 监控环境配置文件
# 用于 docker-compose-p0-monitoring.yml
# ==============================================
# ----------------------------------------------
# 基础设施端口配置
# ----------------------------------------------
# MySQL
MYSQL_PORT=3306
# Redis
REDIS_PORT=6379
# Prometheus
PROMETHEUS_PORT=9090
# Grafana
GRAFANA_PORT=3000
# Redis Exporter
REDIS_EXPORTER_PORT=9121
# ----------------------------------------------
# 业务应用端口配置
# ----------------------------------------------
# ljwx-boot 后端服务
LJWX_BOOT_PORT=9998
# ljwx-admin 前端服务
LJWX_ADMIN_PORT=5173
# ----------------------------------------------
# 数据库配置
# ----------------------------------------------
# MySQL
MYSQL_ROOT_PASSWORD=123456
MYSQL_DATABASE=test
MYSQL_USER=root
MYSQL_PASSWORD=123456
# Redis
REDIS_PASSWORD=123456
REDIS_DATABASE=1
REDIS_MAXMEMORY=2gb
# ----------------------------------------------
# 应用配置
# ----------------------------------------------
# ljwx-boot
SPRING_PROFILES_ACTIVE=prod
HEALTH_DEDUP_USE_REDIS=true
HEALTH_DEDUP_TTL_HOURS=24
HEALTH_DEDUP_USE_CONTENT_HASH=true
HEALTH_CACHE_AUTO_INVALIDATION=true
HEALTH_CACHE_INVALIDATION_DELAY_MS=1000
# ljwx-admin
NODE_ENV=production
VITE_USER_NODE_ENV=production
# ----------------------------------------------
# Grafana配置
# ----------------------------------------------
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=admin123
# ----------------------------------------------
# 时区配置
# ----------------------------------------------
TZ=Asia/Shanghai
+68 -6
View File
@@ -1,15 +1,77 @@
# 使用eclipse-temurin官方Alpine Linux带JRE的轻量级镜像
FROM eclipse-temurin:21-jre-alpine
# 指定维护者信息(可选)
# ============================================================================
# 多阶段构建Dockerfile - 用于客户交付
# 阶段1: Maven构建
# 阶段2: 运行时镜像
# ============================================================================
# ============================================================================
# 阶段1: 构建阶段
# ============================================================================
FROM eclipse-temurin:21-jdk-alpine AS builder
LABEL maintainer="gaojunivas@gmail.com"
LABEL stage="builder"
# 安装Maven
RUN apk add --no-cache maven
# 设置工作目录
WORKDIR /build
# 复制Maven配置和父POM
COPY pom.xml ./
COPY ljwx-boot-common/pom.xml ./ljwx-boot-common/
COPY ljwx-boot-modules/pom.xml ./ljwx-boot-modules/
COPY ljwx-boot-admin/pom.xml ./ljwx-boot-admin/
# 下载依赖(利用Docker缓存层)
RUN mvn dependency:go-offline -B || true
# 复制源代码
COPY ljwx-boot-common ./ljwx-boot-common
COPY ljwx-boot-modules ./ljwx-boot-modules
COPY ljwx-boot-admin ./ljwx-boot-admin
# 构建应用(跳过测试以加快构建)
RUN mvn clean package -DskipTests -pl ljwx-boot-admin -am
# ============================================================================
# 阶段2: 运行时镜像
# ============================================================================
FROM eclipse-temurin:21-jre-alpine
LABEL maintainer="gaojunivas@gmail.com"
LABEL description="LJWX Health Boot Application"
LABEL version="1.0.6-SNAPSHOT"
# 设置时区
ENV TZ='Asia/Shanghai'
RUN ln -snf /usr/share/zoneinfo/"$TZ" /etc/localtime && echo "$TZ" > /etc/timezone
# 创建应用用户(安全最佳实践)
RUN addgroup -S ljwx && adduser -S ljwx -G ljwx
# 设置工作目录
WORKDIR /app
# 将构建的jar文件复制到镜像中
COPY target/ljwx-boot-admin-1.0.6-SNAPSHOT.jar app.jar
# 从构建阶段复制JAR文件
COPY --from=builder /build/ljwx-boot-admin/target/ljwx-boot-admin-*.jar app.jar
# 更改所有权
RUN chown ljwx:ljwx /app/app.jar
# 切换到非root用户
USER ljwx
# 允许外界访问容器的9998端口
EXPOSE 9998
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \
CMD wget -q --spider http://localhost:9998/actuator/health || exit 1
# JVM优化参数
ENV JAVA_OPTS="-Xms512m -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
# 配置容器启动后执行的命令
ENTRYPOINT ["java", "-jar", "app.jar"]
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
+269
View File
@@ -0,0 +1,269 @@
200,30
200,30
200,30
200,31
200,28
200,30
200,28
200,31
200,29
200,29
200,31
200,30
200,30
200,30
200,30
200,31
200,32
200,31
200,29
200,34
200,32
200,31
200,30
200,35
200,30
200,33
200,31
200,35
200,31
200,31
200,31
200,30
200,35
200,35
200,35
200,31
200,35
200,37
200,34
200,36
200,37
200,36
200,32
200,34
200,33
200,40
200,38
200,38
200,43
200,37
200,45
200,35
200,38
200,36
200,35
200,34
200,35
200,34
200,35
200,37
200,37
200,38
200,43
200,39
200,40
200,32
200,36
200,37
200,36
200,40
200,39
200,36
200,36
200,41
200,38
200,38
200,35
200,32
200,39
200,38
200,42
200,35
200,34
200,34
200,34
200,39
200,42
200,42
200,37
200,42
200,42
200,36
200,33
200,35
200,44
200,43
200,41
200,41
200,44
200,36
200,43
200,44
200,39
200,41
200,40
200,40
200,37
200,36
200,38
200,38
200,37
200,38
200,34
200,32
200,32
200,30
200,30
200,33
200,30
200,30
200,34
200,34
200,34
200,32
200,31
200,31
200,36
200,38
200,40
200,36
200,40
200,39
200,40
200,42
200,43
200,45
200,42
200,37
200,45
200,35
200,37
200,36
200,38
200,38
200,38
200,37
200,34
200,34
200,30
200,36
200,33
200,31
200,36
200,31
200,36
200,35
200,44
200,42
200,47
200,47
200,47
200,52
200,49
200,46
200,46
200,42
200,39
200,39
200,30
200,26
200,29
200,34
200,39
200,36
200,37
200,48
200,47
200,58
200,46
200,47
200,42
200,41
200,40
200,35
200,32
200,32
200,34
200,36
200,32
200,36
200,37
200,43
200,36
200,39
200,38
200,42
200,39
200,45
200,39
200,36
200,33
200,38
200,36
200,39
200,46
200,46
200,48
200,41
200,45
200,43
200,43
200,47
200,46
200,38
200,41
200,45
200,40
200,35
200,41
200,37
200,41
200,42
200,38
200,38
200,42
200,44
200,46
200,46
200,43
200,38
200,39
200,40
200,40
200,39
200,44
200,43
200,43
200,39
200,40
200,42
200,43
200,38
200,44
200,42
200,41
200,41
200,41
200,39
200,43
200,45
200,45
200,44
200,45
200,51
200,50
200,46
200,49
200,43
200,47
200,42
200,45
200,48
200,49
200,48
200,53
200,52
200,44
200,79
200,93
+205
View File
@@ -0,0 +1,205 @@
200,30
200,28
200,30
200,31
200,31
200,32
200,39
200,39
200,38
200,35
200,40
200,41
200,36
200,35
200,38
200,39
200,36
200,41
200,36
200,34
200,34
200,36
200,40
200,42
200,42
200,40
200,42
200,43
200,37
200,36
200,35
200,39
200,36
200,39
200,42
200,44
200,37
200,39
200,41
200,38
200,36
200,33
200,37
200,41
200,40
200,42
200,39
200,38
200,42
200,37
200,38
200,36
200,38
200,39
200,38
200,43
200,44
200,37
200,38
200,38
200,38
200,39
200,40
200,39
200,39
200,40
200,37
200,46
200,38
200,44
200,47
200,45
200,40
200,39
200,37
200,30
200,31
200,34
200,34
200,36
200,42
200,35
200,47
200,33
200,38
200,37
200,35
200,33
200,34
200,47
200,41
200,36
200,45
200,41
200,48
200,47
200,39
200,42
200,38
200,34
200,28
200,29
200,30
200,31
200,38
200,40
200,39
200,39
200,39
200,43
200,40
200,37
200,44
200,39
200,32
200,29
200,30
200,34
200,34
200,43
200,39
200,41
200,41
200,42
200,38
200,42
200,42
200,40
200,37
200,38
200,33
200,32
200,34
200,33
200,33
200,37
200,37
200,49
200,41
200,38
200,42
200,40
200,36
200,34
200,32
200,40
200,35
200,39
200,39
200,39
200,45
200,38
200,40
200,40
200,42
200,39
200,38
200,44
200,44
200,39
200,36
200,34
200,36
200,36
200,37
200,47
200,47
200,42
200,38
200,39
200,36
200,43
200,42
200,47
200,45
200,40
200,38
200,40
200,39
200,45
200,48
200,52
200,49
200,49
200,48
200,49
200,45
200,47
200,42
200,42
200,41
200,44
200,58
200,43
200,41
200,38
200,44
200,49
200,52
200,49
200,50
200,52
200,42
200,58
200,85
+199
View File
@@ -0,0 +1,199 @@
200,35
200,36
200,35
200,42
200,40
200,38
200,35
200,34
200,37
200,38
200,37
200,34
200,35
200,34
200,34
200,34
200,35
200,35
200,35
200,34
200,33
200,32
200,29
200,30
200,30
200,30
200,32
200,31
200,34
200,40
200,36
200,36
200,40
200,38
200,37
200,35
200,36
200,40
200,40
200,41
200,41
200,38
200,38
200,38
200,37
200,37
200,36
200,34
200,31
200,33
200,37
200,36
200,35
200,34
200,34
200,34
200,36
200,36
200,35
200,39
200,36
200,45
200,38
200,43
200,46
200,41
200,37
200,34
200,33
200,34
200,34
200,34
200,37
200,34
200,40
200,35
200,46
200,34
200,33
200,32
200,34
200,34
200,36
200,41
200,38
200,36
200,35
200,39
200,32
200,30
200,29
200,32
200,32
200,36
200,35
200,38
200,44
200,46
200,47
200,51
200,47
200,48
200,47
200,41
200,39
200,40
200,45
200,40
200,33
200,30
200,31
200,35
200,35
200,40
200,41
200,44
200,41
200,38
200,37
200,41
200,42
200,37
200,33
200,33
200,35
200,40
200,36
200,36
200,38
200,37
200,41
200,53
200,52
200,49
200,60
200,45
200,43
200,36
200,36
200,40
200,38
200,36
200,37
200,36
200,36
200,37
200,42
200,41
200,42
200,35
200,37
200,44
200,42
200,46
200,37
200,40
200,36
200,41
200,40
200,43
200,44
200,40
200,43
200,42
200,37
200,38
200,43
200,43
200,48
200,51
200,38
200,40
200,40
200,40
200,42
200,39
200,47
200,44
200,46
200,46
200,42
200,45
200,47
200,48
200,41
200,45
200,53
200,50
200,40
200,40
200,40
200,58
200,45
200,47
200,49
200,46
200,42
200,58
200,61
+194
View File
@@ -0,0 +1,194 @@
200,30
200,29
200,27
200,27
200,29
200,27
200,30
200,31
200,30
200,32
200,32
200,38
200,37
200,36
200,38
200,38
200,38
200,41
200,53
200,45
200,42
200,40
200,44
200,37
200,42
200,41
200,40
200,40
200,41
200,41
200,41
200,42
200,38
200,35
200,43
200,43
200,37
200,37
200,34
200,37
200,34
200,35
200,33
200,35
200,36
200,30
200,31
200,31
200,32
200,32
200,36
200,35
200,32
200,32
200,34
200,40
200,36
200,36
200,35
200,37
200,35
200,38
200,47
200,41
200,34
200,33
200,39
200,35
200,40
200,35
200,41
200,43
200,40
200,38
200,36
200,34
200,39
200,38
200,34
200,34
200,31
200,32
200,38
200,41
200,39
200,43
200,49
200,47
200,49
200,45
200,47
200,47
200,49
200,52
200,45
200,38
200,33
200,33
200,34
200,31
200,31
200,47
200,42
200,44
200,45
200,46
200,42
200,40
200,38
200,34
200,31
200,32
200,32
200,35
200,37
200,42
200,36
200,37
200,37
200,44
200,43
200,40
200,41
200,37
200,34
200,39
200,35
200,41
200,52
200,46
200,44
200,42
200,41
200,38
200,37
200,41
200,41
200,34
200,39
200,35
200,39
200,39
200,42
200,42
200,38
200,35
200,35
200,38
200,42
200,42
200,38
200,36
200,36
200,40
200,42
200,44
200,43
200,38
200,40
200,37
200,40
200,43
200,41
200,38
200,38
200,41
200,40
200,44
200,46
200,46
200,45
200,43
200,47
200,43
200,40
200,40
200,43
200,45
200,42
200,45
200,69
200,53
200,40
200,42
200,46
200,48
200,55
200,51
200,51
200,51
200,52
200,52
200,68
200,80
+185
View File
@@ -0,0 +1,185 @@
200,28
200,28
200,26
200,26
200,31
200,31
200,37
200,43
200,36
200,35
200,38
200,36
200,36
200,39
200,38
200,44
200,38
200,38
200,33
200,34
200,37
200,35
200,39
200,40
200,38
200,38
200,40
200,39
200,38
200,38
200,35
200,35
200,37
200,35
200,33
200,36
200,41
200,38
200,35
200,35
200,33
200,34
200,36
200,35
200,33
200,34
200,39
200,43
200,37
200,44
200,46
200,43
200,38
200,32
200,36
200,33
200,34
200,35
200,34
200,37
200,40
200,35
200,48
200,34
200,36
200,39
200,37
200,36
200,35
200,42
200,39
200,38
200,45
200,43
200,36
200,36
200,36
200,35
200,31
200,29
200,29
200,36
200,34
200,42
200,42
200,49
200,51
200,47
200,45
200,45
200,46
200,48
200,46
200,53
200,42
200,39
200,38
200,33
200,31
200,31
200,31
200,33
200,39
200,41
200,39
200,42
200,43
200,48
200,46
200,44
200,42
200,45
200,36
200,38
200,37
200,36
200,33
200,43
200,43
200,43
200,49
200,48
200,43
200,38
200,38
200,37
200,37
200,38
200,35
200,39
200,38
200,42
200,38
200,41
200,38
200,35
200,38
200,34
200,42
200,48
200,38
200,38
200,40
200,39
200,38
200,43
200,44
200,43
200,43
200,41
200,40
200,38
200,41
200,42
200,43
200,42
200,38
200,45
200,41
200,44
200,42
200,46
200,48
200,47
200,41
200,43
200,44
200,46
200,44
200,40
200,43
200,48
200,68
200,45
200,40
200,43
200,45
200,44
200,45
200,46
200,43
200,48
200,47
200,59
200,83
+178
View File
@@ -0,0 +1,178 @@
200,31
200,31
200,32
200,32
200,36
200,40
200,32
200,38
200,41
200,38
200,38
200,34
200,36
200,38
200,35
200,37
200,36
200,38
200,42
200,41
200,40
200,38
200,36
200,34
200,32
200,35
200,34
200,35
200,40
200,41
200,37
200,35
200,36
200,35
200,34
200,34
200,35
200,31
200,27
200,28
200,27
200,34
200,30
200,36
200,34
200,35
200,35
200,39
200,46
200,40
200,38
200,35
200,33
200,39
200,39
200,35
200,41
200,41
200,42
200,39
200,35
200,34
200,39
200,37
200,35
200,33
200,30
200,31
200,35
200,42
200,45
200,42
200,41
200,41
200,44
200,45
200,48
200,48
200,52
200,49
200,42
200,38
200,38
200,33
200,33
200,31
200,34
200,49
200,41
200,43
200,38
200,39
200,36
200,38
200,36
200,32
200,31
200,32
200,35
200,35
200,39
200,40
200,41
200,43
200,40
200,43
200,36
200,38
200,36
200,33
200,33
200,43
200,46
200,42
200,51
200,55
200,50
200,42
200,39
200,37
200,35
200,43
200,44
200,42
200,38
200,37
200,38
200,43
200,42
200,44
200,47
200,45
200,39
200,50
200,41
200,47
200,46
200,44
200,44
200,39
200,37
200,40
200,43
200,43
200,41
200,39
200,41
200,41
200,39
200,40
200,40
200,39
200,41
200,40
200,49
200,43
200,40
200,38
200,39
200,46
200,42
200,42
200,43
200,56
200,51
200,44
200,43
200,47
200,43
200,43
200,40
200,47
200,47
200,51
200,49
200,54
200,54
200,79
+173
View File
@@ -0,0 +1,173 @@
200,37
200,36
200,33
200,33
200,33
200,33
200,30
200,33
200,30
200,33
200,31
200,31
200,34
200,31
200,32
200,38
200,38
200,38
200,35
200,37
200,35
200,35
200,37
200,38
200,36
200,36
200,35
200,32
200,32
200,36
200,41
200,37
200,40
200,38
200,39
200,37
200,43
200,47
200,43
200,38
200,38
200,37
200,31
200,34
200,35
200,33
200,37
200,41
200,38
200,44
200,34
200,37
200,39
200,37
200,36
200,35
200,43
200,39
200,37
200,41
200,43
200,38
200,34
200,35
200,35
200,32
200,27
200,30
200,36
200,37
200,44
200,44
200,49
200,48
200,47
200,43
200,42
200,45
200,44
200,35
200,31
200,33
200,33
200,32
200,36
200,36
200,46
200,41
200,40
200,42
200,39
200,35
200,33
200,30
200,32
200,32
200,35
200,40
200,37
200,38
200,38
200,44
200,41
200,44
200,55
200,46
200,41
200,42
200,41
200,40
200,41
200,41
200,42
200,39
200,41
200,43
200,42
200,42
200,41
200,40
200,38
200,36
200,38
200,34
200,38
200,43
200,35
200,37
200,38
200,40
200,42
200,37
200,43
200,37
200,39
200,40
200,44
200,41
200,39
200,41
200,46
200,38
200,40
200,41
200,39
200,39
200,44
200,38
200,49
200,42
200,40
200,37
200,42
200,41
200,44
200,41
200,40
200,58
200,52
200,42
200,43
200,49
200,47
200,48
200,38
200,42
200,49
200,49
200,52
200,55
200,45
200,88
200,123
+165
View File
@@ -0,0 +1,165 @@
200,31
200,28
200,33
200,32
200,33
200,33
200,32
200,33
200,37
200,38
200,37
200,36
200,39
200,33
200,32
200,36
200,38
200,36
200,34
200,34
200,35
200,37
200,38
200,43
200,40
200,40
200,39
200,40
200,37
200,44
200,46
200,44
200,37
200,34
200,37
200,32
200,34
200,30
200,36
200,37
200,41
200,36
200,36
200,32
200,32
200,32
200,35
200,36
200,40
200,40
200,38
200,38
200,35
200,38
200,34
200,32
200,28
200,29
200,30
200,37
200,32
200,38
200,45
200,47
200,48
200,49
200,46
200,46
200,47
200,44
200,41
200,45
200,42
200,48
200,40
200,39
200,33
200,31
200,33
200,36
200,33
200,34
200,37
200,43
200,43
200,44
200,46
200,42
200,40
200,39
200,35
200,39
200,33
200,33
200,34
200,35
200,38
200,43
200,43
200,48
200,65
200,49
200,48
200,40
200,42
200,38
200,39
200,45
200,38
200,43
200,38
200,38
200,37
200,39
200,42
200,43
200,46
200,48
200,38
200,49
200,42
200,46
200,48
200,44
200,50
200,37
200,36
200,39
200,41
200,42
200,43
200,39
200,44
200,43
200,41
200,39
200,40
200,38
200,42
200,38
200,41
200,41
200,38
200,40
200,40
200,42
200,42
200,38
200,43
200,55
200,53
200,44
200,49
200,45
200,44
200,44
200,45
200,48
200,46
200,50
200,55
200,49
200,46
200,99
200,168
+157
View File
@@ -0,0 +1,157 @@
200,32
200,38
200,35
200,35
200,36
200,35
200,37
200,33
200,34
200,39
200,38
200,36
200,36
200,34
200,36
200,34
200,35
200,34
200,34
200,41
200,38
200,39
200,41
200,42
200,46
200,43
200,39
200,49
200,40
200,37
200,35
200,33
200,35
200,36
200,32
200,35
200,32
200,31
200,35
200,33
200,30
200,35
200,33
200,37
200,35
200,37
200,42
200,45
200,47
200,37
200,41
200,40
200,34
200,33
200,28
200,30
200,33
200,36
200,37
200,38
200,37
200,38
200,43
200,39
200,44
200,43
200,42
200,38
200,32
200,30
200,30
200,34
200,35
200,35
200,42
200,42
200,42
200,38
200,37
200,39
200,38
200,34
200,33
200,36
200,38
200,37
200,37
200,39
200,41
200,40
200,52
200,44
200,38
200,48
200,39
200,38
200,34
200,34
200,36
200,40
200,40
200,42
200,48
200,39
200,41
200,46
200,41
200,40
200,38
200,42
200,46
200,44
200,48
200,37
200,37
200,39
200,41
200,37
200,44
200,46
200,42
200,42
200,39
200,42
200,40
200,39
200,47
200,47
200,45
200,41
200,39
200,40
200,41
200,47
200,42
200,49
200,42
200,44
200,45
200,40
200,44
200,48
200,54
200,40
200,39
200,52
200,50
200,45
200,40
200,37
200,56
200,47
200,50
200,54
200,64
200,44
200,216
+151
View File
@@ -0,0 +1,151 @@
200,33
200,35
200,35
200,33
200,29
200,31
200,30
200,30
200,31
200,38
200,35
200,33
200,30
200,34
200,43
200,34
200,36
200,39
200,37
200,35
200,40
200,51
200,37
200,36
200,34
200,33
200,36
200,34
200,37
200,35
200,33
200,31
200,36
200,33
200,31
200,34
200,34
200,37
200,36
200,36
200,41
200,45
200,44
200,39
200,39
200,38
200,35
200,33
200,30
200,29
200,33
200,39
200,39
200,42
200,35
200,47
200,45
200,37
200,48
200,45
200,58
200,47
200,44
200,47
200,50
200,43
200,44
200,44
200,41
200,37
200,38
200,36
200,34
200,32
200,33
200,34
200,37
200,36
200,37
200,38
200,48
200,42
200,40
200,49
200,47
200,39
200,42
200,40
200,39
200,38
200,35
200,42
200,42
200,46
200,44
200,45
200,41
200,39
200,39
200,38
200,36
200,44
200,39
200,43
200,44
200,40
200,33
200,36
200,42
200,45
200,43
200,44
200,39
200,36
200,35
200,37
200,37
200,43
200,44
200,50
200,37
200,39
200,41
200,43
200,42
200,48
200,39
200,43
200,40
200,40
200,36
200,47
200,56
200,47
200,39
200,36
200,50
200,54
200,49
200,40
200,48
200,48
200,49
200,44
200,49
200,44
200,52
200,58
200,51
200,51
200,128
+144
View File
@@ -0,0 +1,144 @@
200,28
200,28
200,32
200,31
200,29
200,33
200,34
200,40
200,32
200,36
200,36
200,36
200,34
200,39
200,46
200,40
200,38
200,35
200,32
200,40
200,37
200,36
200,39
200,41
200,40
200,39
200,40
200,44
200,42
200,39
200,43
200,32
200,30
200,33
200,32
200,32
200,34
200,35
200,41
200,38
200,45
200,45
200,48
200,49
200,48
200,47
200,47
200,49
200,49
200,45
200,40
200,36
200,36
200,31
200,36
200,35
200,36
200,39
200,46
200,45
200,44
200,42
200,39
200,38
200,42
200,41
200,38
200,34
200,33
200,38
200,41
200,38
200,35
200,43
200,38
200,39
200,52
200,48
200,51
200,61
200,51
200,47
200,46
200,39
200,37
200,40
200,43
200,43
200,37
200,37
200,35
200,40
200,43
200,38
200,36
200,40
200,37
200,38
200,44
200,42
200,40
200,39
200,37
200,39
200,42
200,43
200,45
200,44
200,39
200,40
200,37
200,38
200,47
200,45
200,44
200,36
200,42
200,41
200,44
200,45
200,43
200,44
200,45
200,49
200,47
200,42
200,44
200,41
200,43
200,41
200,47
200,51
200,47
200,42
200,41
200,43
200,45
200,49
200,45
200,48
200,52
200,48
200,57
200,71
+262
View File
@@ -0,0 +1,262 @@
200,29
200,29
200,30
200,29
200,29
200,28
200,28
200,27
200,31
200,32
200,31
200,31
200,34
200,33
200,31
200,31
200,34
200,31
200,34
200,31
200,35
200,31
200,31
200,29
200,32
200,36
200,33
200,34
200,31
200,33
200,37
200,34
200,36
200,35
200,36
200,35
200,36
200,33
200,39
200,37
200,39
200,43
200,38
200,41
200,37
200,38
200,35
200,35
200,35
200,36
200,34
200,33
200,38
200,37
200,38
200,44
200,37
200,38
200,37
200,36
200,35
200,36
200,40
200,36
200,36
200,36
200,40
200,41
200,39
200,35
200,31
200,39
200,39
200,43
200,38
200,33
200,36
200,36
200,35
200,39
200,42
200,39
200,42
200,44
200,36
200,34
200,38
200,38
200,42
200,38
200,40
200,42
200,37
200,36
200,37
200,35
200,35
200,34
200,37
200,38
200,40
200,37
200,38
200,38
200,47
200,41
200,38
200,38
200,38
200,38
200,37
200,44
200,38
200,33
200,36
200,38
200,40
200,38
200,34
200,34
200,35
200,31
200,31
200,27
200,29
200,29
200,32
200,32
200,35
200,35
200,36
200,46
200,42
200,37
200,35
200,33
200,38
200,38
200,35
200,37
200,36
200,35
200,33
200,33
200,32
200,29
200,29
200,31
200,32
200,33
200,42
200,44
200,50
200,48
200,48
200,47
200,40
200,42
200,39
200,33
200,28
200,29
200,29
200,33
200,34
200,37
200,45
200,42
200,49
200,47
200,59
200,46
200,41
200,38
200,40
200,39
200,39
200,36
200,34
200,33
200,37
200,34
200,38
200,39
200,42
200,36
200,39
200,40
200,44
200,39
200,46
200,36
200,35
200,35
200,33
200,37
200,41
200,53
200,54
200,45
200,44
200,43
200,42
200,42
200,43
200,41
200,42
200,39
200,43
200,38
200,35
200,37
200,39
200,42
200,42
200,36
200,50
200,41
200,44
200,41
200,42
200,36
200,36
200,38
200,38
200,41
200,46
200,46
200,45
200,47
200,45
200,46
200,43
200,44
200,40
200,46
200,43
200,44
200,41
200,44
200,45
200,42
200,44
200,40
200,40
200,46
200,54
200,43
200,47
200,46
200,53
200,44
200,44
200,37
200,44
200,51
200,56
200,54
200,56
200,45
200,141
200,140
+137
View File
@@ -0,0 +1,137 @@
200,40
200,34
200,37
200,37
200,37
200,33
200,36
200,46
200,41
200,36
200,35
200,33
200,39
200,36
200,35
200,41
200,40
200,39
200,38
200,40
200,43
200,42
200,37
200,40
200,34
200,31
200,31
200,31
200,33
200,36
200,36
200,39
200,41
200,47
200,45
200,48
200,49
200,48
200,49
200,49
200,44
200,42
200,48
200,47
200,42
200,43
200,40
200,39
200,33
200,32
200,34
200,35
200,33
200,35
200,40
200,43
200,42
200,42
200,43
200,44
200,39
200,37
200,36
200,35
200,33
200,32
200,32
200,34
200,36
200,42
200,51
200,51
200,56
200,49
200,43
200,34
200,35
200,38
200,40
200,36
200,38
200,40
200,37
200,41
200,40
200,46
200,40
200,36
200,36
200,34
200,42
200,47
200,35
200,34
200,35
200,36
200,43
200,42
200,45
200,45
200,44
200,42
200,40
200,42
200,41
200,47
200,48
200,50
200,40
200,41
200,39
200,39
200,40
200,42
200,50
200,46
200,43
200,44
200,43
200,44
200,48
200,47
200,41
200,42
200,52
200,46
200,43
200,41
200,41
200,49
200,52
200,51
200,45
200,49
200,49
200,56
200,70
+131
View File
@@ -0,0 +1,131 @@
200,37
200,35
200,34
200,32
200,38
200,37
200,40
200,35
200,35
200,34
200,33
200,33
200,34
200,35
200,40
200,38
200,40
200,42
200,38
200,36
200,30
200,30
200,31
200,31
200,31
200,37
200,38
200,39
200,42
200,44
200,50
200,47
200,50
200,50
200,56
200,48
200,45
200,38
200,37
200,35
200,34
200,33
200,39
200,36
200,40
200,46
200,45
200,46
200,42
200,39
200,37
200,40
200,41
200,36
200,34
200,36
200,37
200,40
200,38
200,37
200,40
200,38
200,37
200,49
200,44
200,38
200,50
200,35
200,37
200,32
200,34
200,44
200,32
200,41
200,39
200,43
200,44
200,39
200,39
200,37
200,41
200,41
200,41
200,45
200,45
200,45
200,38
200,38
200,38
200,41
200,38
200,39
200,43
200,48
200,45
200,37
200,47
200,40
200,39
200,41
200,43
200,43
200,43
200,42
200,40
200,46
200,47
200,48
200,48
200,45
200,50
200,48
200,52
200,49
200,46
200,47
200,42
200,46
200,57
200,51
200,44
200,41
200,40
200,53
200,45
200,51
200,48
200,50
200,48
200,76
200,86
+125
View File
@@ -0,0 +1,125 @@
200,33
200,35
200,36
200,36
200,36
200,37
200,35
200,34
200,40
200,35
200,35
200,32
200,31
200,32
200,32
200,32
200,40
200,42
200,42
200,45
200,43
200,41
200,47
200,50
200,47
200,48
200,43
200,40
200,36
200,33
200,36
200,30
200,36
200,46
200,41
200,43
200,42
200,49
200,42
200,43
200,46
200,40
200,38
200,40
200,34
200,33
200,33
200,33
200,37
200,41
200,37
200,38
200,39
200,45
200,44
200,40
200,39
200,36
200,34
200,35
200,40
200,40
200,40
200,43
200,40
200,40
200,41
200,49
200,46
200,39
200,41
200,36
200,34
200,37
200,41
200,40
200,43
200,44
200,39
200,39
200,43
200,41
200,40
200,42
200,35
200,37
200,35
200,43
200,44
200,44
200,46
200,39
200,41
200,39
200,45
200,40
200,39
200,38
200,40
200,38
200,40
200,41
200,43
200,45
200,46
200,42
200,37
200,39
200,48
200,50
200,40
200,42
200,55
200,48
200,45
200,40
200,38
200,53
200,47
200,47
200,45
200,48
200,42
200,62
200,74
+118
View File
@@ -0,0 +1,118 @@
200,32
200,33
200,31
200,32
200,30
200,32
200,33
200,37
200,48
200,47
200,45
200,41
200,39
200,35
200,28
200,28
200,29
200,32
200,33
200,38
200,37
200,48
200,43
200,48
200,48
200,45
200,53
200,42
200,38
200,36
200,31
200,32
200,33
200,31
200,35
200,37
200,42
200,38
200,40
200,43
200,46
200,44
200,45
200,41
200,42
200,38
200,37
200,38
200,36
200,34
200,40
200,44
200,41
200,51
200,54
200,48
200,43
200,40
200,37
200,41
200,43
200,42
200,41
200,35
200,36
200,39
200,44
200,43
200,42
200,46
200,36
200,39
200,38
200,41
200,48
200,45
200,40
200,35
200,37
200,36
200,40
200,43
200,38
200,37
200,39
200,39
200,41
200,41
200,48
200,40
200,40
200,39
200,41
200,47
200,41
200,48
200,45
200,43
200,46
200,43
200,45
200,45
200,45
200,41
200,48
200,53
200,51
200,46
200,43
200,41
200,56
200,46
200,49
200,51
200,51
200,42
200,70
200,94
+111
View File
@@ -0,0 +1,111 @@
200,36
200,43
200,47
200,50
200,47
200,41
200,40
200,36
200,29
200,30
200,31
200,31
200,33
200,38
200,45
200,41
200,40
200,38
200,38
200,35
200,32
200,31
200,32
200,32
200,40
200,41
200,38
200,41
200,41
200,42
200,40
200,43
200,43
200,42
200,40
200,38
200,36
200,37
200,33
200,31
200,33
200,35
200,36
200,41
200,55
200,48
200,47
200,44
200,39
200,34
200,35
200,39
200,33
200,37
200,38
200,37
200,42
200,39
200,39
200,40
200,40
200,37
200,43
200,44
200,44
200,41
200,35
200,37
200,40
200,36
200,42
200,38
200,41
200,45
200,37
200,37
200,36
200,37
200,40
200,48
200,48
200,41
200,38
200,41
200,40
200,43
200,49
200,51
200,51
200,47
200,43
200,41
200,44
200,44
200,41
200,44
200,43
200,51
200,67
200,43
200,42
200,44
200,46
200,50
200,47
200,42
200,45
200,50
200,49
200,64
200,91
+104
View File
@@ -0,0 +1,104 @@
200,30
200,31
200,36
200,39
200,36
200,40
200,37
200,46
200,42
200,47
200,48
200,44
200,57
200,47
200,47
200,46
200,50
200,44
200,44
200,42
200,38
200,34
200,32
200,31
200,32
200,34
200,36
200,37
200,38
200,40
200,45
200,42
200,48
200,42
200,43
200,51
200,50
200,40
200,43
200,41
200,40
200,41
200,37
200,37
200,37
200,43
200,44
200,46
200,41
200,42
200,41
200,38
200,36
200,39
200,37
200,40
200,40
200,42
200,40
200,40
200,38
200,41
200,44
200,46
200,41
200,39
200,36
200,35
200,36
200,36
200,39
200,41
200,43
200,40
200,41
200,42
200,42
200,47
200,39
200,40
200,39
200,38
200,36
200,49
200,50
200,41
200,39
200,39
200,47
200,48
200,49
200,43
200,45
200,44
200,45
200,46
200,45
200,43
200,48
200,47
200,55
200,48
200,91
200,87
+98
View File
@@ -0,0 +1,98 @@
200,26
200,29
200,33
200,37
200,43
200,48
200,60
200,45
200,39
200,38
200,38
200,33
200,31
200,31
200,34
200,37
200,37
200,36
200,42
200,43
200,47
200,45
200,44
200,42
200,45
200,38
200,39
200,36
200,37
200,32
200,33
200,42
200,43
200,55
200,50
200,46
200,44
200,39
200,37
200,39
200,46
200,40
200,38
200,37
200,36
200,39
200,44
200,44
200,42
200,49
200,41
200,41
200,38
200,41
200,45
200,43
200,40
200,38
200,35
200,38
200,41
200,41
200,40
200,38
200,34
200,38
200,43
200,42
200,42
200,37
200,39
200,34
200,36
200,40
200,40
200,47
200,44
200,42
200,41
200,43
200,43
200,40
200,47
200,39
200,43
200,50
200,48
200,44
200,39
200,45
200,46
200,48
200,48
200,53
200,51
200,51
200,70
200,284
+92
View File
@@ -0,0 +1,92 @@
200,33
200,31
200,32
200,34
200,37
200,43
200,37
200,41
200,42
200,43
200,38
200,40
200,43
200,41
200,36
200,38
200,33
200,33
200,33
200,32
200,33
200,37
200,37
200,50
200,42
200,39
200,47
200,39
200,36
200,34
200,32
200,37
200,38
200,39
200,37
200,45
200,41
200,36
200,39
200,39
200,38
200,38
200,40
200,42
200,42
200,41
200,41
200,40
200,41
200,40
200,47
200,48
200,44
200,39
200,36
200,37
200,36
200,36
200,38
200,41
200,42
200,41
200,37
200,42
200,38
200,42
200,39
200,42
200,42
200,39
200,44
200,47
200,53
200,42
200,37
200,42
200,47
200,46
200,43
200,44
200,43
200,45
200,48
200,41
200,48
200,46
200,49
200,50
200,52
200,50
200,66
200,133
+85
View File
@@ -0,0 +1,85 @@
200,34
200,34
200,32
200,36
200,33
200,38
200,38
200,39
200,42
200,41
200,40
200,44
200,39
200,42
200,34
200,39
200,32
200,36
200,46
200,43
200,46
200,52
200,47
200,43
200,43
200,36
200,40
200,43
200,41
200,42
200,40
200,38
200,37
200,40
200,39
200,36
200,40
200,38
200,36
200,38
200,43
200,40
200,38
200,36
200,37
200,42
200,41
200,46
200,41
200,42
200,39
200,36
200,39
200,49
200,49
200,45
200,39
200,37
200,39
200,43
200,47
200,42
200,46
200,43
200,46
200,47
200,47
200,40
200,44
200,45
200,39
200,47
200,58
200,48
200,40
200,40
200,46
200,47
200,45
200,46
200,49
200,51
200,50
200,63
200,101
+78
View File
@@ -0,0 +1,78 @@
200,37
200,36
200,32
200,36
200,35
200,35
200,34
200,42
200,42
200,41
200,53
200,54
200,48
200,64
200,46
200,46
200,40
200,38
200,35
200,35
200,38
200,36
200,41
200,37
200,39
200,39
200,42
200,41
200,40
200,39
200,35
200,40
200,43
200,38
200,38
200,34
200,36
200,39
200,42
200,45
200,43
200,37
200,37
200,37
200,36
200,38
200,47
200,44
200,42
200,38
200,42
200,41
200,41
200,46
200,49
200,49
200,47
200,50
200,40
200,43
200,43
200,42
200,45
200,45
200,50
200,57
200,44
200,39
200,46
200,51
200,48
200,45
200,43
200,45
200,50
200,66
200,47
200,94
+255
View File
@@ -0,0 +1,255 @@
200,27
200,31
200,27
200,29
200,30
200,30
200,29
200,28
200,29
200,30
200,29
200,30
200,29
200,30
200,31
200,31
200,28
200,31
200,33
200,35
200,32
200,31
200,32
200,31
200,31
200,30
200,31
200,33
200,31
200,33
200,34
200,34
200,38
200,40
200,44
200,39
200,43
200,37
200,36
200,34
200,38
200,37
200,36
200,37
200,34
200,33
200,37
200,38
200,42
200,35
200,36
200,40
200,33
200,37
200,35
200,41
200,40
200,35
200,34
200,39
200,41
200,37
200,34
200,39
200,38
200,37
200,40
200,35
200,35
200,34
200,36
200,37
200,42
200,43
200,39
200,43
200,40
200,35
200,36
200,37
200,39
200,42
200,34
200,40
200,42
200,38
200,38
200,33
200,36
200,37
200,35
200,39
200,38
200,37
200,37
200,42
200,39
200,37
200,31
200,33
200,32
200,32
200,34
200,38
200,42
200,41
200,36
200,37
200,36
200,37
200,39
200,39
200,40
200,35
200,33
200,32
200,31
200,30
200,26
200,27
200,29
200,31
200,34
200,36
200,45
200,37
200,34
200,38
200,39
200,35
200,41
200,35
200,39
200,41
200,40
200,36
200,34
200,32
200,32
200,29
200,30
200,32
200,33
200,34
200,41
200,49
200,45
200,50
200,48
200,49
200,50
200,44
200,45
200,45
200,39
200,37
200,27
200,29
200,34
200,35
200,35
200,46
200,43
200,45
200,42
200,39
200,34
200,33
200,33
200,34
200,34
200,36
200,40
200,43
200,41
200,40
200,43
200,40
200,39
200,39
200,36
200,37
200,34
200,34
200,33
200,34
200,38
200,39
200,52
200,51
200,60
200,47
200,40
200,36
200,40
200,39
200,38
200,38
200,37
200,39
200,38
200,39
200,42
200,43
200,40
200,40
200,41
200,35
200,40
200,47
200,38
200,37
200,36
200,40
200,37
200,41
200,44
200,43
200,44
200,42
200,40
200,42
200,39
200,48
200,48
200,37
200,37
200,40
200,42
200,46
200,46
200,45
200,43
200,49
200,53
200,44
200,47
200,48
200,43
200,50
200,45
200,42
200,55
200,48
200,48
200,40
200,42
200,55
200,48
200,50
200,46
200,54
200,47
200,84
200,93
+72
View File
@@ -0,0 +1,72 @@
200,49
200,45
200,42
200,52
200,46
200,41
200,43
200,39
200,40
200,40
200,40
200,40
200,40
200,36
200,40
200,44
200,43
200,44
200,42
200,39
200,36
200,39
200,34
200,39
200,43
200,34
200,37
200,35
200,42
200,41
200,41
200,49
200,39
200,35
200,41
200,39
200,39
200,45
200,44
200,51
200,42
200,40
200,39
200,41
200,44
200,45
200,40
200,42
200,38
200,39
200,41
200,53
200,51
200,46
200,40
200,38
200,44
200,52
200,49
200,39
200,44
200,46
200,47
200,40
200,45
200,41
200,48
200,53
200,65
200,50
200,74
200,127
+65
View File
@@ -0,0 +1,65 @@
200,62
200,47
200,44
200,39
200,38
200,35
200,38
200,38
200,35
200,39
200,38
200,43
200,40
200,43
200,42
200,38
200,38
200,36
200,40
200,44
200,39
200,37
200,37
200,41
200,40
200,40
200,45
200,47
200,47
200,39
200,41
200,41
200,37
200,46
200,41
200,41
200,41
200,44
200,42
200,45
200,41
200,46
200,49
200,40
200,37
200,39
200,45
200,43
200,44
200,41
200,44
200,59
200,50
200,43
200,41
200,44
200,57
200,41
200,43
200,46
200,48
200,53
200,49
200,51
200,87
+59
View File
@@ -0,0 +1,59 @@
200,39
200,42
200,38
200,36
200,35
200,34
200,37
200,39
200,44
200,42
200,48
200,38
200,38
200,42
200,44
200,46
200,43
200,40
200,39
200,36
200,38
200,46
200,45
200,46
200,46
200,45
200,44
200,44
200,45
200,41
200,43
200,41
200,50
200,42
200,46
200,39
200,44
200,44
200,43
200,48
200,43
200,39
200,44
200,46
200,43
200,42
200,53
200,50
200,46
200,49
200,41
200,45
200,55
200,52
200,53
200,62
200,45
200,140
200,127
+52
View File
@@ -0,0 +1,52 @@
200,40
200,37
200,38
200,43
200,42
200,44
200,43
200,36
200,33
200,40
200,36
200,42
200,43
200,45
200,44
200,41
200,40
200,44
200,40
200,39
200,41
200,44
200,42
200,40
200,43
200,39
200,44
200,44
200,44
200,50
200,49
200,49
200,46
200,44
200,44
200,43
200,42
200,40
200,45
200,53
200,46
200,43
200,40
200,44
200,49
200,52
200,45
200,46
200,46
200,47
200,54
200,98
+45
View File
@@ -0,0 +1,45 @@
200,43
200,38
200,43
200,43
200,40
200,37
200,38
200,35
200,39
200,44
200,44
200,39
200,40
200,39
200,39
200,40
200,44
200,40
200,36
200,37
200,37
200,42
200,43
200,44
200,40
200,45
200,48
200,40
200,43
200,45
200,49
200,40
200,42
200,55
200,56
200,44
200,41
200,44
200,60
200,49
200,48
200,50
200,49
200,40
200,251
+39
View File
@@ -0,0 +1,39 @@
200,39
200,41
200,36
200,40
200,35
200,37
200,39
200,47
200,38
200,40
200,37
200,41
200,37
200,46
200,42
200,41
200,39
200,40
200,43
200,49
200,52
200,42
200,37
200,40
200,47
200,50
200,47
200,45
200,45
200,48
200,48
200,42
200,46
200,44
200,50
200,48
200,68
200,50
200,81
+33
View File
@@ -0,0 +1,33 @@
200,32
200,41
200,45
200,39
200,37
200,37
200,36
200,37
200,39
200,42
200,48
200,46
200,50
200,49
200,39
200,50
200,49
200,52
200,45
200,44
200,51
200,51
200,47
200,41
200,40
200,49
200,47
200,48
200,49
200,52
200,44
200,76
200,88
+26
View File
@@ -0,0 +1,26 @@
200,42
200,43
200,44
200,39
200,38
200,40
200,48
200,41
200,39
200,41
200,41
200,48
200,47
200,44
200,49
200,45
200,48
200,42
200,41
200,41
200,47
200,48
200,50
200,52
200,45
200,157
+20
View File
@@ -0,0 +1,20 @@
200,38
200,44
200,44
200,43
200,42
200,43
200,46
200,47
200,45
200,46
200,50
200,60
200,43
200,45
200,47
200,48
200,53
200,57
200,56
200,87
+14
View File
@@ -0,0 +1,14 @@
200,46
200,52
200,47
200,42
200,43
200,41
200,49
200,50
200,49
200,48
200,49
200,45
200,61
200,83
+247
View File
@@ -0,0 +1,247 @@
200,31
200,32
200,28
200,28
200,29
200,33
200,28
200,28
200,28
200,29
200,30
200,35
200,31
200,34
200,32
200,32
200,31
200,31
200,29
200,30
200,32
200,30
200,32
200,34
200,32
200,37
200,40
200,42
200,38
200,43
200,37
200,34
200,32
200,34
200,35
200,37
200,37
200,33
200,35
200,37
200,40
200,42
200,38
200,35
200,41
200,33
200,38
200,38
200,40
200,40
200,39
200,34
200,42
200,39
200,32
200,37
200,39
200,37
200,40
200,40
200,38
200,36
200,36
200,37
200,36
200,36
200,42
200,37
200,45
200,44
200,37
200,35
200,39
200,33
200,40
200,37
200,39
200,43
200,37
200,36
200,36
200,35
200,35
200,35
200,38
200,39
200,40
200,37
200,37
200,41
200,40
200,37
200,35
200,33
200,33
200,31
200,30
200,32
200,32
200,34
200,33
200,33
200,32
200,33
200,33
200,50
200,33
200,33
200,33
200,34
200,44
200,36
200,36
200,41
200,36
200,37
200,41
200,48
200,42
200,36
200,39
200,37
200,37
200,37
200,37
200,42
200,40
200,40
200,39
200,38
200,44
200,42
200,39
200,41
200,32
200,31
200,32
200,33
200,34
200,32
200,39
200,37
200,43
200,41
200,43
200,49
200,49
200,51
200,51
200,51
200,52
200,46
200,43
200,40
200,36
200,35
200,33
200,34
200,38
200,33
200,39
200,45
200,45
200,44
200,40
200,35
200,39
200,43
200,38
200,36
200,31
200,31
200,32
200,35
200,36
200,37
200,41
200,44
200,43
200,46
200,42
200,38
200,37
200,41
200,41
200,42
200,39
200,40
200,38
200,40
200,38
200,45
200,41
200,40
200,41
200,37
200,37
200,36
200,40
200,43
200,42
200,40
200,39
200,37
200,38
200,42
200,40
200,48
200,46
200,41
200,38
200,39
200,37
200,43
200,42
200,47
200,48
200,39
200,37
200,42
200,41
200,41
200,48
200,44
200,40
200,37
200,36
200,43
200,45
200,45
200,39
200,41
200,42
200,51
200,53
200,45
200,41
200,44
200,55
200,46
200,51
200,46
200,51
200,52
200,56
200,54
200,77
+8
View File
@@ -0,0 +1,8 @@
200,51
200,49
200,46
200,50
200,46
200,49
200,56
200,71
+2
View File
@@ -0,0 +1,2 @@
200,61
200,72
+240
View File
@@ -0,0 +1,240 @@
200,30
200,30
200,31
200,35
200,36
200,34
200,34
200,36
200,37
200,33
200,36
200,37
200,37
200,33
200,34
200,33
200,40
200,36
200,41
200,43
200,36
200,43
200,37
200,36
200,34
200,34
200,34
200,33
200,34
200,31
200,35
200,38
200,38
200,44
200,39
200,39
200,37
200,34
200,35
200,36
200,39
200,38
200,38
200,34
200,41
200,36
200,35
200,37
200,39
200,36
200,40
200,41
200,35
200,34
200,35
200,33
200,40
200,42
200,38
200,38
200,37
200,39
200,39
200,37
200,41
200,53
200,47
200,39
200,43
200,41
200,38
200,41
200,46
200,38
200,39
200,42
200,41
200,42
200,40
200,37
200,36
200,42
200,44
200,40
200,34
200,34
200,36
200,34
200,34
200,33
200,35
200,33
200,30
200,31
200,33
200,32
200,32
200,46
200,33
200,33
200,32
200,33
200,44
200,34
200,35
200,40
200,37
200,38
200,42
200,42
200,33
200,37
200,36
200,37
200,37
200,39
200,31
200,32
200,30
200,33
200,32
200,31
200,32
200,33
200,42
200,38
200,37
200,44
200,45
200,44
200,51
200,46
200,50
200,48
200,49
200,48
200,46
200,46
200,48
200,52
200,51
200,52
200,38
200,32
200,33
200,33
200,29
200,37
200,45
200,43
200,46
200,43
200,46
200,43
200,43
200,46
200,37
200,32
200,32
200,29
200,32
200,34
200,36
200,37
200,40
200,39
200,43
200,43
200,44
200,46
200,41
200,39
200,39
200,35
200,38
200,37
200,38
200,40
200,42
200,43
200,42
200,42
200,49
200,48
200,38
200,39
200,45
200,37
200,36
200,41
200,36
200,41
200,41
200,33
200,38
200,36
200,39
200,40
200,40
200,43
200,39
200,36
200,39
200,42
200,39
200,39
200,45
200,40
200,38
200,41
200,42
200,42
200,38
200,42
200,42
200,43
200,41
200,42
200,41
200,48
200,51
200,45
200,38
200,39
200,51
200,47
200,50
200,44
200,44
200,48
200,49
200,41
200,44
200,42
200,48
200,47
200,50
200,48
200,77
200,119
+234
View File
@@ -0,0 +1,234 @@
200,32
200,34
200,34
200,36
200,36
200,36
200,32
200,35
200,34
200,40
200,35
200,41
200,43
200,38
200,44
200,37
200,36
200,35
200,36
200,37
200,37
200,33
200,35
200,34
200,38
200,39
200,43
200,40
200,37
200,35
200,35
200,33
200,33
200,33
200,33
200,35
200,35
200,33
200,29
200,26
200,27
200,26
200,27
200,28
200,32
200,33
200,33
200,35
200,38
200,37
200,33
200,39
200,44
200,38
200,42
200,43
200,35
200,35
200,38
200,36
200,41
200,35
200,37
200,41
200,38
200,36
200,38
200,37
200,33
200,35
200,34
200,38
200,40
200,38
200,37
200,40
200,42
200,35
200,36
200,39
200,35
200,37
200,35
200,36
200,34
200,36
200,34
200,34
200,33
200,30
200,27
200,30
200,29
200,30
200,30
200,30
200,40
200,34
200,36
200,35
200,38
200,35
200,36
200,46
200,35
200,36
200,39
200,38
200,40
200,35
200,36
200,39
200,42
200,42
200,38
200,40
200,43
200,37
200,34
200,33
200,31
200,32
200,32
200,34
200,40
200,42
200,39
200,41
200,43
200,50
200,47
200,49
200,51
200,46
200,54
200,46
200,52
200,45
200,39
200,33
200,31
200,33
200,41
200,39
200,43
200,40
200,41
200,39
200,42
200,45
200,40
200,37
200,39
200,35
200,34
200,31
200,35
200,37
200,40
200,39
200,40
200,42
200,46
200,44
200,39
200,38
200,38
200,35
200,37
200,39
200,41
200,42
200,40
200,44
200,41
200,43
200,48
200,45
200,44
200,38
200,39
200,37
200,34
200,39
200,40
200,43
200,43
200,39
200,46
200,39
200,44
200,42
200,42
200,37
200,37
200,38
200,44
200,43
200,45
200,41
200,40
200,41
200,36
200,46
200,41
200,41
200,38
200,40
200,41
200,45
200,41
200,44
200,47
200,45
200,44
200,39
200,37
200,38
200,50
200,45
200,42
200,54
200,47
200,46
200,44
200,37
200,52
200,55
200,48
200,55
200,56
200,50
200,91
200,159
+226
View File
@@ -0,0 +1,226 @@
200,33
200,35
200,41
200,37
200,38
200,43
200,37
200,44
200,36
200,36
200,31
200,33
200,36
200,36
200,36
200,31
200,35
200,37
200,39
200,42
200,38
200,37
200,37
200,34
200,36
200,36
200,38
200,38
200,33
200,38
200,42
200,40
200,39
200,33
200,34
200,39
200,40
200,39
200,39
200,35
200,37
200,37
200,35
200,35
200,41
200,37
200,36
200,39
200,37
200,38
200,41
200,52
200,44
200,42
200,43
200,42
200,36
200,43
200,42
200,40
200,41
200,41
200,42
200,42
200,41
200,37
200,37
200,38
200,46
200,39
200,35
200,33
200,33
200,32
200,32
200,31
200,34
200,33
200,31
200,31
200,33
200,31
200,33
200,36
200,34
200,33
200,32
200,33
200,42
200,34
200,33
200,42
200,36
200,36
200,40
200,48
200,37
200,36
200,41
200,38
200,34
200,34
200,36
200,37
200,36
200,35
200,30
200,29
200,31
200,30
200,31
200,37
200,34
200,42
200,43
200,46
200,49
200,45
200,48
200,43
200,41
200,40
200,37
200,28
200,28
200,30
200,31
200,34
200,34
200,37
200,43
200,47
200,46
200,47
200,58
200,45
200,45
200,44
200,49
200,40
200,40
200,34
200,34
200,33
200,34
200,32
200,35
200,36
200,38
200,37
200,39
200,40
200,46
200,41
200,47
200,44
200,36
200,36
200,36
200,36
200,41
200,43
200,46
200,46
200,42
200,40
200,43
200,40
200,45
200,45
200,43
200,39
200,42
200,35
200,34
200,38
200,35
200,42
200,41
200,39
200,48
200,45
200,41
200,48
200,43
200,43
200,36
200,35
200,35
200,39
200,44
200,42
200,42
200,45
200,44
200,44
200,43
200,44
200,42
200,40
200,41
200,45
200,38
200,45
200,45
200,47
200,47
200,40
200,40
200,39
200,46
200,42
200,41
200,53
200,51
200,50
200,47
200,42
200,47
200,49
200,53
200,57
200,56
200,42
200,92
200,182
+221
View File
@@ -0,0 +1,221 @@
200,32
200,32
200,30
200,30
200,31
200,34
200,31
200,31
200,30
200,30
200,32
200,32
200,34
200,33
200,39
200,39
200,37
200,35
200,35
200,36
200,38
200,40
200,36
200,33
200,40
200,35
200,33
200,32
200,32
200,35
200,32
200,35
200,29
200,27
200,26
200,29
200,27
200,28
200,32
200,33
200,36
200,41
200,39
200,37
200,36
200,39
200,35
200,36
200,37
200,41
200,39
200,37
200,38
200,37
200,34
200,32
200,32
200,28
200,28
200,32
200,30
200,31
200,31
200,31
200,36
200,37
200,35
200,35
200,38
200,35
200,31
200,31
200,37
200,39
200,34
200,37
200,34
200,36
200,35
200,36
200,39
200,38
200,41
200,39
200,39
200,40
200,43
200,45
200,44
200,39
200,49
200,42
200,37
200,40
200,38
200,36
200,38
200,35
200,41
200,40
200,41
200,39
200,38
200,43
200,42
200,35
200,41
200,32
200,32
200,31
200,32
200,32
200,37
200,41
200,38
200,42
200,47
200,45
200,41
200,49
200,49
200,52
200,52
200,41
200,33
200,33
200,33
200,30
200,35
200,48
200,43
200,42
200,39
200,38
200,40
200,38
200,37
200,35
200,32
200,37
200,33
200,36
200,39
200,45
200,38
200,40
200,40
200,44
200,39
200,46
200,43
200,36
200,34
200,38
200,34
200,44
200,44
200,51
200,48
200,40
200,43
200,41
200,40
200,48
200,47
200,41
200,37
200,39
200,36
200,36
200,41
200,37
200,42
200,39
200,37
200,39
200,42
200,42
200,45
200,45
200,36
200,36
200,36
200,38
200,41
200,43
200,43
200,38
200,45
200,45
200,45
200,41
200,44
200,40
200,46
200,42
200,48
200,40
200,45
200,42
200,43
200,45
200,42
200,41
200,43
200,57
200,48
200,41
200,53
200,50
200,50
200,46
200,39
200,46
200,47
200,51
200,51
200,51
200,49
200,88
200,86
+212
View File
@@ -0,0 +1,212 @@
200,31
200,29
200,31
200,29
200,30
200,30
200,33
200,35
200,33
200,32
200,36
200,36
200,38
200,38
200,39
200,35
200,33
200,40
200,40
200,39
200,35
200,31
200,37
200,38
200,41
200,37
200,35
200,37
200,37
200,33
200,38
200,42
200,37
200,41
200,40
200,37
200,35
200,34
200,39
200,41
200,36
200,42
200,43
200,38
200,34
200,34
200,36
200,38
200,34
200,38
200,37
200,38
200,38
200,43
200,38
200,35
200,36
200,32
200,32
200,33
200,35
200,37
200,42
200,39
200,40
200,37
200,36
200,37
200,40
200,39
200,43
200,39
200,40
200,34
200,44
200,38
200,43
200,44
200,45
200,38
200,34
200,35
200,35
200,31
200,35
200,37
200,34
200,41
200,37
200,46
200,35
200,33
200,38
200,37
200,34
200,34
200,46
200,39
200,38
200,36
200,35
200,36
200,34
200,30
200,30
200,30
200,35
200,34
200,40
200,45
200,47
200,50
200,42
200,50
200,47
200,49
200,50
200,41
200,40
200,37
200,36
200,34
200,35
200,39
200,35
200,38
200,44
200,46
200,41
200,41
200,38
200,40
200,45
200,35
200,33
200,31
200,33
200,33
200,36
200,37
200,36
200,41
200,42
200,42
200,46
200,42
200,37
200,39
200,40
200,38
200,40
200,39
200,41
200,40
200,44
200,43
200,43
200,42
200,41
200,41
200,37
200,35
200,39
200,41
200,42
200,45
200,41
200,34
200,36
200,41
200,44
200,44
200,45
200,40
200,36
200,35
200,36
200,38
200,43
200,38
200,41
200,42
200,40
200,36
200,42
200,37
200,39
200,41
200,44
200,43
200,41
200,44
200,48
200,55
200,45
200,42
200,38
200,42
200,50
200,51
200,42
200,47
200,44
200,51
200,46
200,47
200,48
200,49
200,51
200,56
200,58
200,83
+215
View File
@@ -0,0 +1,215 @@
#!/bin/bash
###############################################################################
# P0性能压测脚本 - Docker网络版本
# 功能: 模拟并发用户上传健康数据,验证Redis去重和缓存失效性能
###############################################################################
set -e
# ========== 配置参数 ==========
HOST=${HOST:-ljwx-boot}
PORT=${PORT:-9998}
CONCURRENT_USERS=${CONCURRENT_USERS:-100}
TEST_DURATION=${TEST_DURATION:-60}
OUTPUT_DIR="./results"
# ========== 参数解析 ==========
for arg in "$@"; do
case $arg in
--users=*)
CONCURRENT_USERS="${arg#*=}"
;;
--duration=*)
TEST_DURATION="${arg#*=}"
;;
--help|-h)
echo "用法: $0 [选项]"
echo ""
echo "选项:"
echo " --users=<n> 并发用户数 (默认: 100)"
echo " --duration=<n> 测试持续时间(秒)(默认: 60)"
echo " --help 显示帮助信息"
echo ""
echo "示例:"
echo " $0 --users=100 --duration=60"
exit 0
;;
esac
done
mkdir -p "$OUTPUT_DIR"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
RESULT_FILE="$OUTPUT_DIR/test_${TIMESTAMP}.txt"
echo "==========================================" | tee "$RESULT_FILE"
echo "P0性能压测 - Docker环境" | tee -a "$RESULT_FILE"
echo "==========================================" | tee -a "$RESULT_FILE"
echo "并发用户: $CONCURRENT_USERS" | tee -a "$RESULT_FILE"
echo "持续时间: $TEST_DURATION秒" | tee -a "$RESULT_FILE"
echo "==========================================" | tee -a "$RESULT_FILE"
echo "" | tee -a "$RESULT_FILE"
# ========== 单次请求函数 ==========
single_request() {
local start_time=$(date +%s%3N)
docker exec ljwx-boot wget -q -O- \
--post-data="{
\"userId\": $((RANDOM % 1000 + 1000)),
\"customerId\": $((RANDOM % 10 + 1)),
\"deviceSn\": \"PERF-$((RANDOM % 900 + 100))\",
\"heartRate\": $((RANDOM % 40 + 60)),
\"bloodOxygen\": $((RANDOM % 5 + 95)),
\"temperature\": 36.$((RANDOM % 10)),
\"pressureHigh\": 120,
\"pressureLow\": 80,
\"createTime\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\"
}" \
--header="Content-Type: application/json" \
http://localhost:9998/api/health/data/upload 2>/dev/null
local end_time=$(date +%s%3N)
local response_time=$((end_time - start_time))
if [ $? -eq 0 ]; then
echo "200,$response_time"
else
echo "000,$response_time"
fi
}
# ========== 执行压测 ==========
echo "🚀 开始压测..." | tee -a "$RESULT_FILE"
START_TIME=$(date +%s)
END_TIME=$((START_TIME + TEST_DURATION))
TEMP_RESULTS="/tmp/perf_results_$$.txt"
> "$TEMP_RESULTS"
REQUEST_COUNT=0
while [ $(date +%s) -lt $END_TIME ]; do
# 并发执行多个请求
for ((i=0; i<CONCURRENT_USERS; i++)); do
single_request >> "$TEMP_RESULTS" &
done
wait
REQUEST_COUNT=$((REQUEST_COUNT + CONCURRENT_USERS))
ELAPSED=$(($(date +%s) - START_TIME))
PROGRESS=$((ELAPSED * 100 / TEST_DURATION))
echo "⏱️ 进度: $PROGRESS% (已发送 $REQUEST_COUNT 请求)" | tee -a "$RESULT_FILE"
sleep 1
done
echo "" | tee -a "$RESULT_FILE"
echo "✅ 压测完成" | tee -a "$RESULT_FILE"
echo "" | tee -a "$RESULT_FILE"
# ========== 分析结果 ==========
echo "📊 分析结果..." | tee -a "$RESULT_FILE"
echo "" | tee -a "$RESULT_FILE"
TOTAL_REQUESTS=$(wc -l < "$TEMP_RESULTS")
SUCCESS_COUNT=$(grep -c "^200," "$TEMP_RESULTS" || echo "0")
FAIL_COUNT=$((TOTAL_REQUESTS - SUCCESS_COUNT))
SUCCESS_RATE=$(echo "scale=2; $SUCCESS_COUNT * 100 / $TOTAL_REQUESTS" | bc)
# 响应时间统计
awk -F',' '{print $2}' "$TEMP_RESULTS" | sort -n > /tmp/response_times.txt
mapfile -t RESPONSE_TIMES < /tmp/response_times.txt
TOTAL_TIME=0
for time in "${RESPONSE_TIMES[@]}"; do
TOTAL_TIME=$((TOTAL_TIME + time))
done
AVG_TIME=$((TOTAL_TIME / ${#RESPONSE_TIMES[@]}))
P50_INDEX=$((${#RESPONSE_TIMES[@]} * 50 / 100))
P95_INDEX=$((${#RESPONSE_TIMES[@]} * 95 / 100))
P99_INDEX=$((${#RESPONSE_TIMES[@]} * 99 / 100))
P50=${RESPONSE_TIMES[$P50_INDEX]}
P95=${RESPONSE_TIMES[$P95_INDEX]}
P99=${RESPONSE_TIMES[$P99_INDEX]}
MAX=${RESPONSE_TIMES[-1]}
QPS=$(echo "scale=2; $TOTAL_REQUESTS / $TEST_DURATION" | bc)
# ========== 输出结果 ==========
{
echo "==========================================="
echo "测试结果"
echo "==========================================="
echo ""
echo "请求统计:"
echo " 总请求数: $TOTAL_REQUESTS"
echo " 成功: $SUCCESS_COUNT ($SUCCESS_RATE%)"
echo " 失败: $FAIL_COUNT"
echo " QPS: $QPS"
echo ""
echo "响应时间 (ms):"
echo " 平均: $AVG_TIME"
echo " P50: $P50"
echo " P95: $P95"
echo " P99: $P99"
echo " 最大: $MAX"
echo ""
echo "==========================================="
echo ""
echo "SLA检查:"
} | tee -a "$RESULT_FILE"
# SLA检查
SLA_PASS=true
if [ $P50 -lt 50 ]; then
echo " ✅ P50响应时间: ${P50}ms < 50ms" | tee -a "$RESULT_FILE"
else
echo " ❌ P50响应时间: ${P50}ms >= 50ms" | tee -a "$RESULT_FILE"
SLA_PASS=false
fi
if [ $P95 -lt 100 ]; then
echo " ✅ P95响应时间: ${P95}ms < 100ms" | tee -a "$RESULT_FILE"
else
echo " ❌ P95响应时间: ${P95}ms >= 100ms" | tee -a "$RESULT_FILE"
SLA_PASS=false
fi
if [ $P99 -lt 200 ]; then
echo " ✅ P99响应时间: ${P99}ms < 200ms" | tee -a "$RESULT_FILE"
else
echo " ❌ P99响应时间: ${P99}ms >= 200ms" | tee -a "$RESULT_FILE"
SLA_PASS=false
fi
QPS_INT=$(echo "$QPS" | cut -d. -f1)
if [ "$QPS_INT" -ge 100 ]; then
echo " ✅ QPS: $QPS >= 100" | tee -a "$RESULT_FILE"
else
echo " ⚠️ QPS: $QPS < 100 (目标: 100)" | tee -a "$RESULT_FILE"
SLA_PASS=false
fi
SUCCESS_RATE_INT=$(echo "$SUCCESS_RATE" | cut -d. -f1)
if [ "$SUCCESS_RATE_INT" -ge 99 ]; then
echo " ✅ 成功率: $SUCCESS_RATE% >= 99%" | tee -a "$RESULT_FILE"
else
echo " ❌ 成功率: $SUCCESS_RATE% < 99%" | tee -a "$RESULT_FILE"
SLA_PASS=false
fi
echo "" | tee -a "$RESULT_FILE"
if [ "$SLA_PASS" = true ]; then
echo "🎉 SLA检查通过!" | tee -a "$RESULT_FILE"
else
echo "⚠️ SLA检查未通过" | tee -a "$RESULT_FILE"
fi
echo "" | tee -a "$RESULT_FILE"
echo "📄 结果已保存: $RESULT_FILE" | tee -a "$RESULT_FILE"
# 清理临时文件
rm -f "$TEMP_RESULTS" /tmp/response_times.txt
+141
View File
@@ -0,0 +1,141 @@
#!/bin/bash
###############################################################################
# P0完整环境验证脚本 - Docker网络版本
# 功能: 在Docker容器内验证Redis去重、缓存失效和监控指标
###############################################################################
set -e
echo "=========================================="
echo "P0监控体系完整环境验证"
echo "=========================================="
echo ""
# 检查所有服务是否运行
echo "1️⃣ 检查服务运行状态..."
SERVICES="ljwx-mysql ljwx-redis redis-exporter ljwx-boot ljwx-admin prometheus grafana"
for service in $SERVICES; do
if docker ps --format '{{.Names}}' | grep -q "^${service}$"; then
echo " ✅ $service 运行中"
else
echo " ❌ $service 未运行"
exit 1
fi
done
echo ""
echo "2️⃣ 等待ljwx-boot启动完成..."
for i in {1..30}; do
if docker exec ljwx-boot wget -q -O- http://localhost:9998/actuator/health 2>/dev/null | grep -q '"status":"UP"'; then
echo " ✅ ljwx-boot 已就绪"
break
fi
echo " ⏳ 等待中... ($i/30)"
sleep 5
done
# 上传测试数据
echo ""
echo "3️⃣ 上传健康数据测试 (通过容器网络)..."
for i in {1..10}; do
RESPONSE=$(docker exec ljwx-boot wget -q -O- \
--post-data="{
\"userId\": $((1000 + i)),
\"customerId\": 100,
\"deviceSn\": \"TEST-$((100 + i))\",
\"heartRate\": $((60 + RANDOM % 40)),
\"bloodOxygen\": $((95 + RANDOM % 5)),
\"temperature\": 36.$((RANDOM % 10)),
\"pressureHigh\": 120,
\"pressureLow\": 80,
\"createTime\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\"
}" \
--header="Content-Type: application/json" \
http://localhost:9998/api/health/data/upload 2>&1)
if echo "$RESPONSE" | grep -q '"success":true'; then
echo " ✅ 第${i}条数据上传成功"
else
echo " ⚠️ 第${i}条数据上传失败"
fi
sleep 0.5
done
echo ""
echo "4️⃣ 等待事件处理..."
sleep 5
# 检查Redis去重Key
echo ""
echo "5️⃣ 检查Redis去重Key..."
REDIS_KEY_COUNT=$(docker exec ljwx-redis redis-cli -a 123456 --no-auth-warning \
KEYS "health:dedup:*" 2>/dev/null | wc -l)
echo " Redis去重Key总数: $REDIS_KEY_COUNT"
if [ "$REDIS_KEY_COUNT" -gt 0 ]; then
echo " ✅ Redis去重功能正常"
# 显示前3个Key
echo " 前3个Key示例:"
docker exec ljwx-redis redis-cli -a 123456 --no-auth-warning \
KEYS "health:dedup:*" 2>/dev/null | head -3 | sed 's/^/ /'
else
echo " ⚠️ 未找到去重Key,可能P0-3未激活"
fi
# 检查Prometheus指标
echo ""
echo "6️⃣ 检查Prometheus指标..."
CACHE_METRICS=$(docker exec ljwx-boot wget -q -O- http://localhost:9998/actuator/prometheus 2>/dev/null | grep "health_cache_invalidation")
if [ -n "$CACHE_METRICS" ]; then
echo " ✅ 缓存失效指标已暴露"
echo "$CACHE_METRICS" | head -5 | sed 's/^/ /'
else
echo " ⚠️ 未找到缓存失效指标,可能P0-4未激活"
fi
# 检查Prometheus Targets
echo ""
echo "7️⃣ 检查Prometheus Targets..."
TARGETS_UP=$(docker exec prometheus wget -q -O- http://localhost:9090/api/v1/targets 2>/dev/null | grep -o '"health":"up"' | wc -l)
echo " 活跃Targets数量: $TARGETS_UP"
# 服务访问信息
echo ""
echo "8️⃣ 服务访问地址:"
echo " =========================================="
echo " 业务应用:"
echo " 📱 ljwx-admin 前端: http://localhost:5173"
echo " 🔧 ljwx-boot API: http://localhost:9998"
echo " 📚 API文档: http://localhost:9998/doc.html"
echo " 💓 健康检查: http://localhost:9998/actuator/health"
echo " 📈 Metrics: http://localhost:9998/actuator/prometheus"
echo ""
echo " 监控系统:"
echo " 📊 Grafana: http://localhost:3000 (admin/admin123)"
echo " 📈 Prometheus: http://localhost:9090"
echo " 🎯 Targets: http://localhost:9090/targets"
echo " 🔔 Alerts: http://localhost:9090/alerts"
echo ""
echo " 基础设施:"
echo " 🗄️ MySQL: localhost:3306 (root/123456)"
echo " 💾 Redis: localhost:6379 (password: 123456)"
echo " 📊 Redis Exporter: http://localhost:9121/metrics"
echo " =========================================="
echo ""
echo "=========================================="
echo "✅ 验证完成!"
echo "=========================================="
echo ""
echo "下一步:"
echo " 1. 导入Grafana Dashboard:"
echo " 访问 http://localhost:3000"
echo " Dashboards → Import → 上传 ljwx-boot/monitoring/grafana-dashboard-p0.json"
echo ""
echo " 2. 查看Prometheus Targets:"
echo " 访问 http://localhost:9090/targets"
echo " 验证 ljwx-boot 和 redis 状态为 UP"
echo ""
echo " 3. 运行性能压测:"
echo " ./ljwx-boot/scripts/performance-test-docker.sh"
echo ""