今天介绍微服务架构中的日志收集方案 ELK(ELK 是 Elasticsearch、Logstash、Kibana 的简称),准确的说是 ELKB,即 ELK + Filebeat,其中 Filebeat 是用于转发和集中日志数据的轻量级传送工具。

ELK虽然也可以用在很多其它领域,但典型的用法就是收集分析处理日志的组合工具。

日志系统

在以前的项目中,如果想要在生产环境需要通过日志定位业务服务的 bug 或者性能问题,则需要运维人员使用命令挨个服务实例去查询日志文件,导致的结果是排查问题的效率非常低。

微服务架构下,服务多实例部署在不同的物理机上,各个微服务的日志被分散储存不同的物理机。集群足够大的话,使用上述传统的方式查阅日志变得非常不合适。因此需要集中化管理分布式系统中的日志,其中有开源的组件如 syslog,用于将所有服务器上的日志收集汇总。

然而集中化日志文件之后,我们面临的是对这些日志文件进行统计和检索,哪些服务有报警和异常,这些需要有详细的统计。所以在之前出现线上故障时,经常会看到开发和运维人员下载了服务的日志,基于 Linux 下的一些命令,如 grep、awk 和 wc 等,进行检索和统计。这样的方式效率低,工作量大,且对于要求更高的查询、排序和统计等要求和庞大的机器数量依然使用这样的方法难免有点力不从心。

ELKB

ELKB 是一个完整的分布式日志收集系统,很好地解决了上述提到的日志收集难,检索和分析难的问题。ELKB 分别是指 Elasticsearch、Logstash、Kibana 和 Filebeat。elastic 提供的一整套组件可以看作为 MVC 模型,logstash 对应逻辑控制 controller 层,Elasticsearch 是一个数据模型 model 层,而 Kibana 则是视图 view 层。logstash 和 Elasticsearch 基于 Java 编写实现,Kibana 则使用的是 Node.js 框架。

ELKB典型的部署架构(绝不是必须这么干)如下:

image-20210201002834542

Elasticsearch

Elasticsearch 是一个实时的分布式搜索分析引擎,它被用作全文检索、结构化搜索、分析以及这三个功能的组合,它是面向文档 的,意味着它存储整个对象或 文档。Elasticsearch 不仅存储文档,而且 索引每个文档的内容使之可以被检索。在 Elasticsearch 中,你 对文档进行索引、检索、排序和过滤–而不是对行列数据。

下面我们直接使用使用 docker 安装 Elasticsearch:

$ docker run -d --name elasticsearch  docker.elastic.co/elasticsearch/elasticsearch:5.4.0
$ docker pull elasticsearch
docker run -itd --name esTest -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch

docker pull elasticsearch:6.8.13
docker run -d --name esTest elasticsearch:6.8.13

Logstash

docker pull logstash:6.8.13
docker run -itd -p 5044:5044 --name logstash --net somenetwork
-v /home/mqs/elk/logstash/logstash.yml:/usr/share/logstash/config/logstash.yml
-v /home/mqs/elk/logstash/conf.d/:/usr/share/logstash/conf.d/ logstash:6.8.13

Kibana

docker pull kibana:6.8.13
docker run --name kibana -e ELASTICSEARCH_URL=http://127.0.0.1:9200 -p 5601:5601 -d kibana:6.8.13

Filebeat

docker pull elastic/filebeat:6.8.13

安装启动过程非常麻烦,容易出错。这里不做介绍了。下面介绍一个更快的方式。

全家桶sebp/elk

用docker可以更快的一次性安装这些打包后的组件:

docker run -d -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -p 5601:5601 -p 5044:5044 
	-p 9200:9200 -p 9300:9300 -it --restart=always --name elkTool sebp/elk:7.10.0

最新版本可以自己查询https://hub.docker.com/

期间可能会出错,记得修改/etc/sysctl.conf

vm.max_map_count=262144

之后执行:sysctl -w vm.max_map_count=262144

修改配置

1
2
3
4
# 进入容器
docker exec -it elkTool bash
# 编辑配置文件
vim /etc/logstash/conf.d/02-beats-input.conf 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
input {
    tcp {
        port => 5044
        codec => json_lines
    }
}
output{
    elasticsearch {
    	hosts => ["localhost:9200"]
    	index => "xxx.log.-%{+YYYY.MM.dd}"
    }
}

退出后,重启elk容器docker restart elkTool,访问9200和5601看是否能看到页面。

设置语言:如果希望将页面设置为中文,则在docker中设置kibana.yml中的语言即可:

1
2
3
4
5
6
7
# 进入elk
docker exec -it elkTool bash
# 找到kibana.yml(可以用whereis kibana.yml查询)
cd /opt/kibana/config
# 在yml中加上以下配置:
i18n.locale: "zh-CN"
# 重启即可。

很快你就会看到如下的页面,恭喜你配置成功了。之后就是接入数据源了。

image-20210201145204397

(完)