背景
是否遇到过服务器cpu温度高导致降频,磁盘只读等服务器问题。如果你遇到的问题不多或者你只用云服务,那恭喜你,可以跳过这篇文章。如果你被各种辣鸡服务器困扰,还被半死不活的服务器拖后腿导致集群性能短板,那么摆脱人肉智能,需要针对系统日志进行分析。
怎么判断服务器是否有问题
简单点的通过观察系统日志来判断是否有问题1
/var/log/messages
该日志可以反馈很多问题。
例如
- Temperature above threshold, cpu clock throttled(cpu温度高导致的降频)
- I/O error,dev sdh (磁盘有问题)
- memory 有问题等等
采集文件
针对系统日志的读取和采集,需要针对一个不断生成数据的文件不停的采集,市面上现在有很多开源的组件可以完成,例如filebeat、logstash、flume等等。如果要自己手动开发呢,需要怎么办呢。
java版本的可以采用apace的common io来完成。
他采用的是线程方式来监控文件内容的变化
1、Tailer类(采用线程的方式进行文件的内容变法)
2、TailerListener类
3、TailerListenerAdapter类,该类是集成了TailerListener的实现空的接口方式
实例代码如下
1 | import org.apache.commons.io.FileUtils; |
文件的路径最好是通过参数传递进去。这样可以做到可变。
如何部署以及该程序的可用性
- 需要的是每个服务器都部署一个而且只部署一个。
- 一个监控服务器的程序,势必需要另一个程序去监控这个程序,为了形成闭环,那么最近需要通过环境去监控上一个程序。
因此采用的是在kubernetes上部署,通过DaemonSet的形式,做到第一点。然后基于kubernetes可以做到程序挂了自动拉起的高可用形式,解决第二点。
容器化引来的新问题
- 如何获取容器外,宿主机的文件
- 如果获取宿主机的ip
针对第一点,通过将宿主机的文件挂载到容器内部即可,如下配置可以将宿主机的文件映射到在容器内的/log/messages
1 | volumeMounts: |
如何将文件的路径传递进去呢,采用command指令
1 | command: ["java"] |
第二点,目前没有办法拿到宿主机的ip(有谁知道的求告知),可以通过获取容器的名称然后去找对应服务器。如何在java程序中获取呢。这里要用到kubernetes的环境变量。
每个容器都自带了这个一个系统变量HOSTNAME。java中获取方式如下
1 | Map<String, String> map = System.getenv(); |
Reference
https://blog.csdn.net/nickDaDa/article/details/89357667
https://kubernetes.io/zh/docs/tasks/inject-data-application/define-environment-variable-container/