Maintenance

监控与维护

Tagtag Starter 监控与维护指南,包括日志管理和系统监控方案。

监控与维护是确保系统稳定运行的重要环节,本文档将详细介绍 Tagtag Starter 项目的监控系统、日志管理、性能优化和系统维护方案。

1. 监控系统架构

1.1 监控目标

  • 可用性监控:确保系统服务正常运行
  • 性能监控:监控系统性能指标,如 CPU、内存、磁盘、网络等
  • 业务监控:监控核心业务指标,如用户访问量、接口响应时间、错误率等
  • 安全监控:监控系统安全事件,如入侵尝试、异常登录等

1.2 技术栈

技术用途
Prometheus时间序列数据采集和存储
Grafana监控数据可视化
Node Exporter服务器指标监控
JMX ExporterJava 应用性能监控
MySQL ExporterMySQL 数据库监控
Redis ExporterRedis 缓存监控
Loki日志聚合和查询
Promtail日志采集
Alertmanager告警管理
ELK Stack日志分析和可视化(可选)
Jaeger分布式链路追踪

1.3 监控架构图

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  应用服务       │     │  数据库服务     │     │  缓存服务       │
│  (Spring Boot)  │     │  (MySQL)        │     │  (Redis)        │
└──────┬──────────┘     └──────┬──────────┘     └──────┬──────────┘
       │                       │                       │
       ▼                       ▼                       ▼
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  JMX Exporter   │     │ MySQL Exporter  │     │ Redis Exporter  │
└──────┬──────────┘     └──────┬──────────┘     └──────┬──────────┘
       │                       │                       │
       └───────────┬───────────┴───────────┬───────────┘
                   │                       │
                   ▼                       ▼
┌─────────────────────────────────────────────────────────┐
│                       Prometheus                        │
└───────────────────┬─────────────────────────────────────┘
                   │
                   ├─────────────────────────────┐
                   ▼                             ▼
┌─────────────────────────┐     ┌─────────────────────────┐
│       Alertmanager      │     │        Grafana          │
└─────────────────────────┘     └─────────────────────────┘

2. 日志管理

2.1 日志类型

  • 应用日志:应用程序运行时产生的日志,包括业务日志、错误日志等
  • 系统日志:操作系统产生的日志,如 CPU、内存、磁盘等系统指标
  • 访问日志:Web 服务器产生的访问日志,记录 HTTP 请求和响应
  • 数据库日志:数据库产生的日志,如慢查询日志、错误日志等

2.2 日志格式

2.2.1 应用日志格式

采用 JSON 格式记录应用日志,便于日志收集和分析:

{
  "timestamp": "2023-01-01T12:00:00.123Z",
  "level": "INFO",
  "thread": "http-nio-8080-exec-1",
  "logger": "com.tagtag.controller.UserController",
  "message": "用户登录成功",
  "traceId": "1234567890abcdef",
  "spanId": "abcdef1234567890",
  "userId": 1,
  "ip": "192.168.1.100",
  "method": "POST",
  "path": "/api/auth/login",
  "status": 200,
  "duration": 123
}

2.2.2 访问日志格式

Nginx 访问日志格式:

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for" '
                '$request_time $upstream_response_time';

2.3 日志收集

2.3.1 使用 Loki + Promtail

Promtail 配置

server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://loki:3100/loki/api/v1/push

scrape_configs:
  - job_name: system
    static_configs:
    - targets:
        - localhost
      labels:
        job: varlogs
        __path__: /var/log/*log

  - job_name: nginx
    static_configs:
    - targets:
        - localhost
      labels:
        job: nginx
        __path__: /var/log/nginx/*.log

  - job_name: application
    static_configs:
    - targets:
        - localhost
      labels:
        job: application
        __path__: /opt/tagtag/logs/*.log

2.3.2 使用 ELK Stack

Filebeat 配置

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /opt/tagtag/logs/*.log
  fields:
    application: tagtag
  fields_under_root: true

output.elasticsearch:
  hosts: ["elasticsearch:9200"]
  index: "tagtag-%{+yyyy.MM.dd}"

setup.ilm.enabled: true
setup.ilm.rollover_alias: "tagtag"
setup.ilm.pattern: "000001"

2.4 日志查询

2.4.1 使用 Grafana + Loki

Grafana 支持通过 Loki 数据源查询日志,支持以下查询语法:

# 查询所有日志
{job="application"}

# 按日志级别查询
{job="application"} |= "ERROR"

# 按时间范围查询
{job="application"} |= "ERROR" | __time > 1609459200000ms and __time < 1609545600000ms

# 按字段查询
{job="application"} | json | level="ERROR" and status=500

2.4.2 使用 Kibana

Kibana 提供了强大的日志查询和可视化功能,支持以下查询语法:

# 查询所有日志
application:tagtag

# 按日志级别查询
application:tagtag AND level:ERROR

# 按时间范围查询
application:tagtag AND @timestamp:[2023-01-01T00:00:00.000Z TO 2023-01-02T00:00:00.000Z]

# 按字段查询
application:tagtag AND level:ERROR AND status:500

2.5 日志轮换

Logback 配置

<configuration>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/opt/tagtag/logs/tagtag.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 每天生成一个日志文件,保留30天 -->
            <fileNamePattern>/opt/tagtag/logs/tagtag.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
            <!-- 每个日志文件最大100MB -->
            <maxFileSize>100MB</maxFileSize>
            <!-- 保留30天 -->
            <maxHistory>30</maxHistory>
            <!-- 总大小限制10GB -->
            <totalSizeCap>10GB</totalSizeCap>
        </rollingPolicy>
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="net.logstash.logback.layout.LogstashLayout">
                <jsonGeneratorDecorator class="net.logstash.logback.decorate.ContextJsonGeneratorDecorator" />
            </layout>
        </encoder>
    </appender>
    
    <root level="INFO">
        <appender-ref ref="FILE" />
    </root>
</configuration>

3. 性能监控

3.1 服务器监控

3.1.1 核心指标

  • CPU 使用率:监控 CPU 使用率,阈值建议 80%
  • 内存使用率:监控内存使用率,阈值建议 85%
  • 磁盘使用率:监控磁盘使用率,阈值建议 90%
  • 磁盘 I/O:监控磁盘读写速率和 IOPS
  • 网络流量:监控网络流入流出速率
  • 负载平均值:监控系统负载,建议不超过 CPU 核心数

3.1.2 监控配置

Node Exporter 安装

# 下载 Node Exporter
wget https://github.com/prometheus/node_exporter/releases/download/v1.6.0/node_exporter-1.6.0.linux-amd64.tar.gz

# 解压安装
tar xvfz node_exporter-1.6.0.linux-amd64.tar.gz
mv node_exporter-1.6.0.linux-amd64/node_exporter /usr/local/bin/

# 创建系统服务
cat > /etc/systemd/system/node_exporter.service << EOF
[Unit]
Description=Node Exporter
After=network.target

[Service]
User=root
ExecStart=/usr/local/bin/node_exporter
Restart=always

[Install]
WantedBy=multi-user.target
EOF

# 启动服务
systemctl daemon-reload
systemctl start node_exporter
systemctl enable node_exporter

Prometheus 配置

global:
  scrape_interval:     15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'node'
    static_configs:
    - targets: ['localhost:9100']

3.2 Java 应用监控

3.2.1 核心指标

  • JVM 内存使用:堆内存、非堆内存使用率
  • 垃圾回收:GC 次数、GC 耗时
  • 线程状态:活跃线程数、阻塞线程数、死锁线程数
  • 类加载:已加载类数量
  • Tomcat 连接数:当前连接数、最大连接数
  • 接口响应时间:平均响应时间、P95/P99 响应时间
  • 错误率:接口错误率

3.2.2 监控配置

JMX Exporter 配置

  1. 下载 JMX Exporter JAR 文件
  2. 创建配置文件 jmx_exporter.yaml
  3. 修改应用启动脚本,添加 JMX Exporter 参数

配置文件示例

startDelaySeconds: 0
ssl: false
lowercaseOutputName: false
lowercaseOutputLabelNames: false
rules:
  - pattern: "java.lang<type=Memory><HeapMemoryUsage>(.+)":
      name: jvm_memory_heap_usage_$1
      type: GAUGE
  - pattern: "java.lang<type=Memory><NonHeapMemoryUsage>(.+)":
      name: jvm_memory_nonheap_usage_$1
      type: GAUGE
  - pattern: "java.lang<type=GarbageCollector,name=(.+)><(.+)>(.+)":
      name: jvm_gc_$2_$3
      labels:
        gc: $1
      type: GAUGE
  - pattern: "java.lang<type=Threading><(.+)>":
      name: jvm_threading_$1
      type: GAUGE

启动脚本修改

java -javaagent:jmx_prometheus_javaagent-0.19.0.jar=9404:jmx_exporter.yaml -jar tagtag-backend.jar

3.3 数据库监控

3.3.1 核心指标

  • 连接数:当前连接数、最大连接数
  • 查询性能:QPS、慢查询数
  • 缓存命中率:查询缓存命中率
  • InnoDB 指标:缓冲池命中率、日志写入速率
  • 复制状态:主从复制延迟

3.3.2 监控配置

MySQL Exporter 安装

# 下载 MySQL Exporter
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.15.0/mysqld_exporter-0.15.0.linux-amd64.tar.gz

# 解压安装
tar xvfz mysqld_exporter-0.15.0.linux-amd64.tar.gz
mv mysqld_exporter-0.15.0.linux-amd64/mysqld_exporter /usr/local/bin/

# 创建 MySQL 用户
mysql -u root -p -e "CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'password' WITH MAX_USER_CONNECTIONS 3;"
mysql -u root -p -e "GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';"

# 创建配置文件
cat > /etc/.mysqld_exporter.cnf << EOF
[client]
user=exporter
password=password
EOF

# 创建系统服务
cat > /etc/systemd/system/mysqld_exporter.service << EOF
[Unit]
Description=MySQL Exporter
After=network.target

[Service]
User=root
Environment="DATA_SOURCE_NAME=exporter:password@(localhost:3306)/"
ExecStart=/usr/local/bin/mysqld_exporter --config.my-cnf=/etc/.mysqld_exporter.cnf
Restart=always

[Install]
WantedBy=multi-user.target
EOF

# 启动服务
systemctl daemon-reload
systemctl start mysqld_exporter
systemctl enable mysqld_exporter

3.4 缓存监控

3.4.1 核心指标

  • 内存使用率:Redis 内存使用率
  • 命中率:键命中率
  • 连接数:当前连接数、最大连接数
  • 命令执行:命令执行速率
  • 过期键:过期键数量
  • 网络流量:网络流入流出速率

3.4.2 监控配置

Redis Exporter 安装

# 下载 Redis Exporter
wget https://github.com/oliver006/redis_exporter/releases/download/v1.53.0/redis_exporter-v1.53.0.linux-amd64.tar.gz

# 解压安装
tar xvfz redis_exporter-v1.53.0.linux-amd64.tar.gz
mv redis_exporter-v1.53.0.linux-amd64/redis_exporter /usr/local/bin/

# 创建系统服务
cat > /etc/systemd/system/redis_exporter.service << EOF
[Unit]
Description=Redis Exporter
After=network.target

[Service]
User=root
ExecStart=/usr/local/bin/redis_exporter --redis.addr redis://localhost:6379 --redis.password password
Restart=always

[Install]
WantedBy=multi-user.target
EOF

# 启动服务
systemctl daemon-reload
systemctl start redis_exporter
systemctl enable redis_exporter

4. 告警配置

4.1 告警规则

4.1.1 服务器告警

groups:
- name: node-alerts
  rules:
  - alert: HighCpuUsage
    expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100 > 80
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High CPU usage on {{ $labels.instance }}"
      description: "CPU usage is {{ $value }}% for 5 minutes"
  
  - alert: HighMemoryUsage
    expr: 100 - ((node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100) > 85
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High memory usage on {{ $labels.instance }}"
      description: "Memory usage is {{ $value }}% for 5 minutes"
  
  - alert: HighDiskUsage
    expr: 100 - ((node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100) > 90
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High disk usage on {{ $labels.instance }}"
      description: "Disk usage is {{ $value }}% for 5 minutes"

4.1.2 应用告警

groups:
- name: application-alerts
  rules:
  - alert: HighErrorRate
    expr: sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m])) / sum(rate(http_server_requests_seconds_count[5m])) > 0.05
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High error rate on {{ $labels.instance }}"
      description: "Error rate is {{ $value }}% for 5 minutes"
  
  - alert: SlowResponseTime
    expr: histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket[5m])) by (le, endpoint)) > 2
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "Slow response time on {{ $labels.endpoint }}"
      description: "95th percentile response time is {{ $value }}s for 5 minutes"
  
  - alert: HighJvmMemoryUsage
    expr: sum(jvm_memory_used_bytes{area="heap"}) / sum(jvm_memory_max_bytes{area="heap"}) > 0.85
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High JVM memory usage on {{ $labels.instance }}"
      description: "JVM heap memory usage is {{ $value }}% for 5 minutes"

4.2 告警渠道

  • 邮件告警:发送告警邮件
  • 短信告警:发送告警短信
  • 即时通讯:通过 Slack、DingTalk、WeChat 发送告警
  • 电话告警:严重告警时进行电话通知
  • PagerDuty:专业告警管理平台

4.3 Alertmanager 配置

global:
  resolve_timeout: 5m
  smtp_smarthost: 'smtp.example.com:587'
  smtp_from: 'alertmanager@example.com'
  smtp_auth_username: 'alertmanager@example.com'
  smtp_auth_password: 'password'
  smtp_require_tls: true

route:
  group_by: ['alertname', 'cluster', 'service']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: 'email'
  routes:
  - match:
      severity: critical
    receiver: 'sms'

receivers:
- name: 'email'
  email_configs:
  - to: 'admin@example.com'
    send_resolved: true

- name: 'sms'
  webhook_configs:
  - url: 'https://sms-gateway.example.com/send'
    send_resolved: true

5. 分布式链路追踪

5.1 Jaeger 安装

# 启动 Jaeger 容器
docker run -d --name jaeger \
  -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14268:14268 \
  -p 14250:14250 \
  -p 9411:9411 \
  jaegertracing/all-in-one:1.48

5.2 Spring Boot 集成

添加依赖

<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-spring-jaeger-cloud-starter</artifactId>
    <version>3.3.1</version>
</dependency>

配置文件

opentracing:
  jaeger:
    enabled: true
    udp-sender:
      host: jaeger
      port: 6831
    log-spans: true
    service-name: tagtag-backend

5.3 查看链路追踪

访问 Jaeger UI:http://localhost:16686,可以查看:

  • 服务拓扑图
  • 调用链路详情
  • 每个节点的响应时间
  • 错误链路追踪

6. 系统维护

6.1 定期维护任务

任务频率负责人描述
系统更新每月运维工程师更新系统和软件包
数据库备份每日数据库管理员备份数据库,保留 30 天
日志清理每周运维工程师清理过期日志
性能优化每月运维工程师分析系统性能,进行优化
安全审计每月安全工程师进行安全扫描和审计
备份验证每月运维工程师验证备份的完整性和可恢复性
容量规划每季度架构师评估系统容量,进行扩容规划

6.2 系统备份

6.2.1 数据库备份

全量备份

# 使用 mysqldump 备份
mysqldump -u root -p --all-databases --single-transaction --routines --triggers > /backup/mysql/full_backup_$(date +%Y%m%d_%H%M%S).sql

# 使用 xtrabackup 备份
xtrabackup --backup --target-dir=/backup/mysql/full_backup_$(date +%Y%m%d_%H%M%S)

增量备份

xtrabackup --backup --target-dir=/backup/mysql/incremental_$(date +%Y%m%d_%H%M%S) --incremental-basedir=/backup/mysql/full_backup_20230101_000000

6.2.2 应用备份

# 备份应用配置和数据
BACKUP_DIR="/backup/app"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR/$DATE

# 备份配置文件
cp -r /opt/tagtag/backend/config $BACKUP_DIR/$DATE/

# 备份日志(可选)
cp -r /opt/tagtag/backend/logs $BACKUP_DIR/$DATE/

# 备份静态资源
cp -r /usr/share/nginx/html/tagtag $BACKUP_DIR/$DATE/

# 压缩备份文件
tar -czf $BACKUP_DIR/app_backup_$DATE.tar.gz -C $BACKUP_DIR $DATE

# 删除临时目录
rm -rf $BACKUP_DIR/$DATE

# 删除 7 天前的备份
find $BACKUP_DIR -name "app_backup_*.tar.gz" -mtime +7 -delete

6.3 故障排查

6.3.1 常见故障

应用无法启动

  • 查看应用日志:tail -f /opt/tagtag/logs/tagtag.log
  • 检查端口占用:netstat -tlnp | grep 8080
  • 检查数据库连接:mysql -u root -p -h localhost
  • 检查 Redis 连接:redis-cli -h localhost -p 6379 -a password ping

接口响应缓慢

  • 查看应用日志,检查慢查询
  • 使用 Prometheus 查看性能指标
  • 使用 Jaeger 查看分布式链路
  • 检查数据库慢查询日志

数据库连接失败

  • 检查数据库服务状态:systemctl status mysqld
  • 检查数据库连接数:show processlist;
  • 检查数据库日志:tail -f /var/log/mysql/error.log

6.3.2 故障恢复

数据库恢复

# 使用 mysqldump 恢复
mysql -u root -p < /backup/mysql/full_backup_20230101_000000.sql

# 使用 xtrabackup 恢复
xtrabackup --prepare --target-dir=/backup/mysql/full_backup_20230101_000000
xtrabackup --copy-back --target-dir=/backup/mysql/full_backup_20230101_000000
chown -R mysql:mysql /var/lib/mysql

应用恢复

# 停止当前应用
systemctl stop tagtag-backend

# 恢复备份
cp -r /backup/app/app_backup_20230101_000000/config /opt/tagtag/backend/

# 启动应用
systemctl start tagtag-backend

7. 最佳实践

7.1 监控最佳实践

  • 建立监控基线:确定正常的性能指标范围
  • 设置合理阈值:根据业务需求设置告警阈值
  • 分级告警:根据告警严重程度进行分级
  • 告警收敛:避免告警风暴
  • 定期review告警:定期检查告警规则,优化告警策略
  • 自动化处理:对于常见告警,实现自动化处理

7.2 日志管理最佳实践

  • 统一日志格式:使用 JSON 格式,便于日志收集和分析
  • 添加上下文信息:如 traceId、spanId、userId 等
  • 合理设置日志级别:避免过多的 DEBUG 日志
  • 定期清理日志:避免日志占用过多磁盘空间
  • 日志脱敏:对敏感信息进行脱敏处理
  • 日志备份:重要日志进行异地备份

7.3 性能优化最佳实践

  • 优化数据库查询:添加索引,优化 SQL 语句
  • 使用缓存:合理使用 Redis 缓存热点数据
  • 异步处理:将耗时操作异步化
  • 代码优化:优化算法和数据结构
  • 垂直拆分:将大表拆分为小表
  • 水平扩展:增加服务器节点,实现负载均衡

7.4 安全最佳实践

  • 定期安全扫描:使用工具进行安全扫描
  • 及时更新补丁:修复已知漏洞
  • 使用 HTTPS:加密数据传输
  • 设置防火墙:限制访问端口
  • 启用审计日志:记录重要操作
  • 定期安全培训:提高团队安全意识

8. 总结

监控与维护是确保系统稳定运行的重要环节,通过建立完善的监控体系、日志管理机制、性能优化策略和系统维护流程,可以有效提高系统的可用性、可靠性和安全性。

本文档详细介绍了 Tagtag Starter 项目的监控系统架构、日志管理、性能监控、告警配置、分布式链路追踪和系统维护方案,希望能帮助您建立和完善系统的监控与维护体系。

在实际运营过程中,建议根据业务需求和系统特点,灵活调整监控策略和维护流程,持续优化系统性能和可靠性。