1. 项目背景与核心需求
在RockyLinux 9.6环境下,我们需要为采用Docker Compose部署的SpringBoot2+Vue3全栈应用搭建一套完整的日志收集分析系统。ELK Stack(Elasticsearch + Logstash + Kibana)7.17.10版本作为当前稳定的日志解决方案,能够有效解决以下痛点:
- 容器化环境下日志分散存储,难以统一查看
- 前后端日志格式不统一,缺乏标准化分析
- 传统文件日志检索效率低下,故障排查耗时
特别提示:选择7.17.10版本是因为它既包含新版本特性(如ECS日志格式支持),又经过长期生产验证,比最新版更稳定。RockyLinux作为RHEL替代品,其SELinux策略需要特别注意。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与组件规划
2.1 基础架构设计
采用三节点分离部署模式:
code复制┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Logstash │───▶│ Elasticsearch│───▶│ Kibana │
└─────────────┘ └─────────────┘ └─────────────┘
▲
│
┌─────────────────────────┐
│ Docker Compose Services │
│ - SpringBoot2 (3节点) │
│ - Vue3 Nginx (2节点) │
└─────────────────────────┘
2.2 关键配置参数
在RockyLinux 9.6上需要预先配置的系统参数:
bash复制# 调整系统最大映射内存区域
echo "vm.max_map_count=262144" >> /etc/sysctl.conf
sysctl -p
# 创建专用数据目录(避免SELinux权限问题)
mkdir -p /data/elk/{es-data,logstash,kibana}
semanage fcontext -a -t container_file_t "/data/elk(/.*)?"
restorecon -Rv /data/elk
3. Docker Compose核心配置
3.1 编排文件结构设计
采用多文件分模块管理:
code复制docker-compose.yml # 主入口文件
├── docker-compose.elastic.yml
├── docker-compose.logstash.yml
├── docker-compose.kibana.yml
└── docker-compose.app.yml
3.2 关键服务配置示例
Elasticsearch服务片段(注意RockyLinux特有配置):
yaml复制services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.10
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms2g -Xmx2g"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- /data/elk/es-data:/usr/share/elasticsearch/data
ports:
- "9200:9200"
healthcheck:
test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
经验之谈:RockyLinux的firewalld默认会阻止Docker网络,需要执行
firewall-cmd --add-rich-rule='rule family="ipv4" source address="172.18.0.0/16" accept'开放Docker子网。
4. 日志采集方案实现
4.1 SpringBoot日志处理
采用JSON日志格式 + Logback直接输出到Logstash:
xml复制<!-- logback-spring.xml -->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>logstash:5044</destination>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp/>
<version/>
<logLevel/>
<loggerName/>
<threadName/>
<message/>
<stackTrace/>
<context/>
<mdc/>
</providers>
</encoder>
</appender>
4.2 Vue前端日志方案
Nginx容器日志配置优化:
nginx复制log_format json_escape escape=json
'{'
'"time":"$time_iso8601",'
'"host":"$host",'
'"remote_addr":"$remote_addr",'
'"request":"$request",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"request_time":$request_time,'
'"upstream_response_time":"$upstream_response_time"'
'}';
access_log /var/log/nginx/access.log json_escape;
5. Logstash管道配置精要
5.1 多输入源处理
ruby复制input {
tcp {
port => 5044
codec => json_lines
type => "springboot"
}
file {
path => "/var/log/nginx/access.log"
start_position => "beginning"
sincedb_path => "/dev/null"
type => "vue-nginx"
}
}
5.2 Grok模式匹配优化
针对SpringBoot异常堆栈的特殊处理:
ruby复制filter {
if [type] == "springboot" and [stackTrace] {
mutate {
gsub => [
"stackTrace", "\n", "<br>",
"stackTrace", "\t", " "
]
}
}
if [type] == "vue-nginx" {
json {
source => "message"
remove_field => ["message"]
}
date {
match => ["time", "ISO8601"]
target => "@timestamp"
}
}
}
6. Kibana可视化实战技巧
6.1 前后端关联分析
创建关联仪表盘的技巧:
- 使用
traceId作为前后端日志关联字段 - 在SpringBoot中通过MDC注入:
java复制@RestController
public class DemoController {
@GetMapping("/api")
public ResponseEntity<?> demo() {
MDC.put("traceId", UUID.randomUUID().toString());
// ...
}
}
- 在Vue前端通过axios拦截器注入:
javascript复制axios.interceptors.request.use(config => {
config.headers['X-Trace-Id'] = uuidv4();
return config;
});
6.2 关键性能指标看板
推荐监控的核心指标:
- 应用层:
统计status>=400的请求占比 - 性能层:
按百分位统计request_time - 业务层:
高频接口调用TOP10 - 异常层:
ERROR日志趋势图
7. 性能调优与问题排查
7.1 典型性能瓶颈解决
场景1:Logstash管道延迟高
- 方案:增加
pipeline.workers数量(建议CPU核数的1.5倍) - 验证:
GET _node/stats/pipeline
场景2:Elasticsearch索引速度慢
- 优化:调整refresh_interval为30s
json复制PUT /logstash-*/_settings
{
"index" : {
"refresh_interval" : "30s"
}
}
7.2 常见错误排查指南
| 现象 | 检查点 | 解决方案 |
|---|---|---|
| Logstash无法连接ES | 检查ES健康状态curl -XGET 'http://elasticsearch:9200/_cluster/health?pretty' |
调整ES的network.host配置 |
| Nginx日志未采集 | 确认容器volume挂载正确docker inspect <container_id> |
在docker-compose中添加volumes: - "./nginx/logs:/var/log/nginx" |
| Kibana无法显示日志 | 检查索引模式是否创建GET _cat/indices?v |
在Kibana的Stack Management中创建匹配logstash-*的索引模式 |
8. 安全加固建议
- 基础认证配置(在docker-compose中):
yaml复制environment:
- ELASTIC_USERNAME=admin
- ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
- xpack.security.enabled=true
- 网络层隔离:
bash复制# 创建专用Docker网络
docker network create --driver bridge --subnet 172.18.0.0/24 elk-network
# 在compose文件中指定
networks:
default:
external:
name: elk-network
- 定期维护任务:
bash复制# 日志索引生命周期管理(ILM)
PUT _ilm/policy/logs_policy
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_size": "50GB",
"max_age": "7d"
}
}
},
"delete": {
"min_age": "30d",
"actions": {
"delete": {}
}
}
}
}
}
9. 扩展优化方向
- 引入Filebeat作为日志中转(降低Logstash负载):
yaml复制filebeat.inputs:
- type: container
paths:
- '/var/lib/docker/containers/*/*.log'
processors:
- add_docker_metadata: ~
output.logstash:
hosts: ["logstash:5044"]
- 添加APM监控实现全栈追踪:
dockerfile复制services:
apm-server:
image: docker.elastic.co/apm/apm-server:7.17.10
ports: ["8200:8200"]
environment:
- output.elasticsearch.hosts=["elasticsearch:9200"]
- 日志告警配置示例(通过Kibana Alerting):
json复制{
"name": "Error Rate Alert",
"trigger": {
"threshold": {
"value": 5,
"comparator": ">"
}
},
"conditions": [{
"query": {
"query_string": {
"query": "level:ERROR"
}
}
}]
}
10. 维护与升级策略
- 版本升级路线图:
- 小版本升级(7.17.x):直接替换镜像标签
- 大版本升级(7.x→8.x):使用官方迁移工具
bash复制
elasticsearch-upgrade prepare -v 8.12.0
- 日常维护命令速查:
bash复制# 查看ES集群状态
curl -XGET 'http://localhost:9200/_cluster/health?pretty'
# 清理旧日志索引
curl -XDELETE 'http://localhost:9200/logstash-2023.11.*'
# 重置Kibana配置(开发环境)
docker-compose exec kibana kibana --reset
- 备份恢复方案:
bash复制# 创建快照仓库
PUT _snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/data/elk/backups"
}
}
# 手动执行快照
PUT _snapshot/my_backup/snapshot_1?wait_for_completion=true
