文章目录
- 业务场景
- 问题排查
- 彻底解决
业务场景
-
我们公司做交通相关业务,我们部门主要负责信控服务,卖信号机的硬件产品和配套的信控平台
-
由于有部分小项目,可能只有几十个路口,客户预算有限,只给我们老旧的Windows server服务器,我们平台需要Linux环境,就在里面部署虚拟机
-
我们使用CentOS7虚拟机部署信控平台,我们建立的虚拟机,系统目录root默认分配了50G内存,一般情况下是够用的
-
为了保持环境统一,我们使用docker部署平台服务,使用docker-compose管理配置文件
-
docker服务,默认目录在
/var/lib/docker
,属于/dev/mapper/centos-root
文件系统,docker服务的镜像、容器、卷等都在这个目录下
-
早上九点部署测试环境服务时,顺手使用
df -hl
检查磁盘占用情况,发现centos-root
目录已使用93%(46.5G),磁盘空间即将不足 -
正常情况下,我们的
centos-root
目录一般空间占用在17-20G左右,肯定是有哪个服务有问题
问题排查
- 磁盘使用问题,出现异常占用,首先就要看看有没有大文件
- 使用find命令,查找大文件
find / -type f -size +500M -exec ls -lh {} \; | awk '{ print $9 ":" $5 }';
- 结果发现一个服务的日志
/var/lib/docker/containers/25f900b388614288704640a1fe2e556a95c5440b4dcc1b8bf227926400c006f4/25f900b388614288704640a1fe2e556a95c5440b4dcc1b8bf227926400c006f4-json.log
大小为28G(刚好是多出来的部分,46.5-28=18.5) - 通过路径
/var/lib/docker/containers
,就可以知道,这个一个docker容器,后面的容器id - 使用命令
docker ps -a
,查看所有的服务和容器id - 根据容器id,找到对应的服务为
data-collection
,我们的雷达采集服务
- 我们的docker服务日志,会使用脚本每天凌晨0点压缩存储,循环存储最近七天日志。有兴趣的可以参考这篇博客:定时压缩存储和清理docker容器的日志
- 由于我们每天定时处理,按理说不会有这么大的日志文件
- 查看了这个日志内容,全是数据库连接报错,看了下,测试环境ck数据库未启动,而这个服务一直接收雷达数据进行写库操作
- 数据写入很频繁,写入就会抛出报错堆栈,日志累计很快,9个小时就累计了28G
- 先将服务暂停,日志清空。将ck数据库启动后,重新启动
data-collection
服务,没有报错了 - 临时解决很简单,清空容器日志,再将clickhouse正常启动起来,重启容器服务就行,但这是治标不治本的做法
- 虽然做了定时任务每天凌晨处理容器日志,但是当某个日志在一天内就能撑爆服务器磁盘时,就起不到作用了
彻底解决
- 这次报错场景,在生产环境几乎不会遇到,但也不排除clickhouse异常宕机
- 如异常断电,断电恢复后,服务器重启,其他服务正常,clickhouse无法启动,有兴趣的参考
- 服务器异常断电导致文件损坏,clickhouse启动报错:filesystem error Structure needs cleaning
- 服务器强制关闭、异常断电等导致clickhouse数据损坏Suspiciously many broken parts to remove
- 要通过修改配置,在容器配置里,通过设置参数
log-opt
限制最大日志大小,彻底解决这个问题
docker run --log-driver=json-file --log-opt max-size=<max_size> --log-opt max-file=<max_file_count> <image_name>
- 如果是使用docker-compose,在yml配置文件里,对需要配置的容器配置即可
data-collection-app:
image: data-collection
container_name: data-collection
volumes:
- /etc/localtime:/etc/localtime
ports:
- 7854:7854
depends_on:
- postgresql
- kafka
- redis
- clickhouse
environment:
- _JAVA_OPTIONS=-Xmx512m -Xms256m
- SERVER_PORT=8484
- SPRING_PROFILES_ACTIVE=prod,api-docs,no-liquibase
- SPRING_DATASOURCE_URL=jdbc:postgresql://postgresql:5432/core
- SPRING_DATASOURCE_USERNAME=xx
- SPRING_DATASOURCE_PASSWORD=xxxx
- radar_clickhouse_url=jdbc:clickhouse://clickhouse:8123/radar
- radar_clickhouse_username=xxxx
- radar_clickhouse_password=xxxxxx
- spring_kafka_bootstrapServers=kafka:9092
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PASSWORD=xxxxxxx
- SOCKETIO_PORT=7854
logging:
driver: "json-file" #默认的文件日志驱动
options:
max-size: "500m" # 单个日志文件大小限制
max-file: "3" # 保留的日志数量
- 其实docker支持全局配置,设置下就可以了,所有容器都生效,文件为:/etc/docker/daemon.json,没有创建一个即可
{
"log-driver": "json-file",
"log-opts": {
"max-size": "500m",
"max-file": "3"
}
}
- 当然,如果单个服务业配置了,会以单个服务的私有配置为准