ELK是什么?
一般來說,為了提高服務可用性,服務器需要部署多個實例,每個實例都是負載均衡轉發的后的,如果還用老辦法登錄服務器去tail -f xxx.log,有很大可能錯誤日志未出現在當前服務器中,還需要重復這個過程直到找到日志才能進行問題定位。兩三台還好,成百上千個實例呢?人力有時窮。此時ELK閃亮登場了,那么ELK是什么?
ELK是全文本分布式日志搜索系統,包含Elasticsearch(索引庫)/Logstash (過濾日志保存到索引庫)/ Kibana (查看日志的前端工具)
本文內容說明
本文選用單體架構,多個組件都是單體形式進行部署,包含的組件有ELK(Elasticsearch
、Logstash
、Kibana
)、Zookeeper
、Kafka
還有一個基於Kafka Client的客戶端(logback接口的實現),通過這些組件的整合完成單體日志系統的搭建,這里使用的是下載的tar.gz
,而不是直接安裝的,配置部分可參考
系統架構圖如下
這里用Kafka做的緩沖層,防止日志寫入量過大,logstash和elasticsearch兩者寫入速率跟不上導致的數據丟失
后續會給大家帶來點docker-compose版的demo級的elk集群,敬請期待!
環境准備
- Ubuntu Server 18.04.2 (可替換為Centos 7, 因為都是Systemd的),請確保有足夠的內存與硬盤空間
- ELK 7.1.1
- Kafka_2.12-2.2.0
- Zookeeper使用Kafka自帶的
- 生成日志的demo,代碼見https://github.com/HellxZ/LogDemo
出現的問題匯總
問題匯總請參考ELK搭建過程中出現的問題與解決方法匯總,基本上我測試過程中的ELK問題均已解決
Kafka外網無法連接的問題請參考
搭建過程
以下的相對位置均為下載文件的目錄,請注意。另文中使用了nohup方式后台,每次執行命令后使用ctrl +c 來結束不會影響進程,使用tail -f xxx.out查看日志
配置Elasticsearch
tar zxvf elasticsearch-7.1.1-linux-x86_64.tar.gz # 解壓
mkdir single-elk # 創建目錄改名移動
mv elasticsearch-7.1.1 single-elk/elasticsearch
cd single-elk/elasticsearch && vim config/elasticsearch.yml # 進入配置文件夾,修改es配置文件
# 要修改的內容有
# 1.放開node.name注釋,節點名可DIY
node.name: node-1
# 2.放開network.host,修改ip為當前服務器ip或0.0.0.0,供外部訪問
network.host: 0.0.0.0
# 3.放開cluster.initial_master_nodes,指定當前node.name名稱即可
cluster.initial_master_nodes: ["node-1"] #與node.name保持一致
bootstrap.memory_lock: true #鎖內存,防止內存占用過大,官方推薦使用系統內存的一半,但不要達到32GB
# 保存退出
ES_JAVA_OPTS="-Xms512m -Xmx512m" bin/elasticsearch -d # 后台啟動es,默認綁定端口號9200和9300,接口訪問9200測試,9300為es集群之間通信
當日志中提示
ERROR: [1] bootstrap checks failed [1]: memory locking requested for elasticsearch process but memory is not locked
如果當前主機可以分配給Es的超過1G,可以不設置
bootstrap.memory_lock: true
,這里自然說的是測試環境;正式環境還是需要限制內存,如上方的-Xmx -Xms等,官方推薦是占用系統內存的50%,但不要超過32G。可以通過ES_JAVA_OPTS進行限制,如果仍未能解決問題,請參考https://www.cnblogs.com/hellxz/p/11009634.html
瀏覽器訪問http://192.168.87.133:9200/ (自行替換ip)
可選用elasticsearch-head查看,github上最新版只到了5,個人維護版有6的,還是沒有7,給官方提issue,官方人員表示暫時沒有意願升級,因為大體可用,除了每個ES的分片等信息匹配不到了。。。看他們興趣缺缺的樣子,就不使用插件安裝到es中了,改用的google-chrome插件,如圖
已經給官方提issue了,官方回應現在在github上最新代碼已經改了,如有需要,可以使用npm啟動,支持es7.x
配置Zookeeper與Kafka
tar -zxvf kafka_2.12-2.2.0.tgz
mv kafka_2.12-2.2.0 single-elk/kafka
cd single-elk/kafka; vim config/zookeeper.properties #修改下data-dir就可以了,保存退出
vim config/server.properties #修改kafka配置
#需要修改內容如下
listeners=PLAINTEXT://kafka:9092
advertised.listeners=PLAINTEXT://kafka:9092
#保存退出
#編輯/etc/hosts,在hosts文件中追加kafka映射,注意是內網ip需要替換
192.168.87.133 kafka #其實寫127.0.0.1也行 ==
nohup bin/zookeeper-server-start.sh config/zookeeper.properties > zookeeper.out & #啟動zookeeper,出現綁定端口號即成功
nohup bin/kafka-server-start.sh config/server.properties > kafka.out & #啟動kafka
#日志中出現started即成功
這里寫kafka是因為外網訪問的時候需要去用域名換ip,注冊到zookeeper中的key包含了域名,所以本文中使用的是修改/etc/hosts的方式,我不知道其他人是怎么解決這個問題的,如果您有更好的方式,歡迎下方評論!
配置Logstash
tar zxvf logstash-7.1.1.tar.gz # 解壓
mv logstash-7.1.1 single-elk/logstash
cd single-elk/logstash
vim config/logstash.conf # 創建配置文件,設置參數可參考logstash.sample.conf,詳情見官網
使用自定義的配置文件需要在啟動時指定。
# logstash.conf
# 本人配置的是使用kafka做了一層緩沖層,這個不用我多說了,請按需配置
input {
kafka {
bootstrap_servers => "192.168.87.133:9092"
topics => ["all_logs"]
group_id => "logstash"
codec => json
}
}
# 過濾器我沒有配置,目前只是先看看效果
filter {
}
output {
elasticsearch {
hosts => ["192.168.87.133:9200"]
index => "all-logs-%{+YYYY.MM.dd}"
#user => "elastic"
#password => "changeme"
}
stdout {
codec => rubydebug
}
}
保存退出
nohup bin/logstash -f config/logstash.conf > logstash.out & #后台啟動Logstash
看到日志中出現Successfully started Logstash API endpoint {:port=>9600}
,即啟動成功
配置Kibana
# Kibana是基於node.js的前端項目,不過我測試服務器沒裝node.js也正常啟動,看來ELK這些都自帶了依賴環境
tar zxvf kibana-7.1.1-linux-x86_64.tar.gz
mv kibana-7.1.1-linux-x86_64 single-elk/kibana
cd single-elk/kibana && vim config/kibana.yml
#kibana.yml 以下配置均為解開注釋,修改而成,使用搜索修改
# 指定kibana占用端口號,如無其它端口需要,可以不開啟,默認5601
server.port: 5601
# 指定kibana綁定的ip地址,這里寫kibana所在的ip即可
server.host: "192.168.87.133"
# es節點的ip地址
elasticsearch.hosts: ["http://192.168.87.133:9200"]
# kibana.index是kibana在es中創建的索引,會保存搜索記錄,無需改變
kibana.index: ".kibana"
# 設置查詢es超時時間,單位為milliseconds必須為整數
elasticsearch.requestTimeout: 30000
# 其余按需配置
# 中文化
i18n.locale: "zh-CN"
#保存退出
nohup bin/kibana > kibana.out & # 后台啟動kibana
出現Server running at http://192.168.87.133:5601"
類似字樣,啟動完成,訪問看看
配置測試代碼
使用代碼的環境需要設置hosts文件,映射到kafka為剛才的ip,我的是192.168.87.133 kafka
項目是springboot的直接啟動DemoApplication就好,還可以通過訪問TestController中的方法來生產日志。
Connection to node -1 could not be established. Broker may not be available.
出現這個問題請參考【Kafka問題解決】Connection to xxx could not be established. Broker may not be available.檢查配置文件。
如需修改kafka的映射名稱,記得修改logback-spring.xml中的<producerConfig>bootstrap.servers=your-kafka-domain:kafka-port</producerConfig>
查看效果
使用Elasticsearch-head
進入google-chrome的Elasticsearch-head插件,連接項目我們可以簡單看到多出了幾個綠色的0
當然了,由於這個插件官方沒有對Elasticsearch 7.X進行優化支持,顯示的圖並不准確,好在我們可以看到索引和數據瀏覽
我的虛擬機沒內存了。。所以集群狀態變成yellow了,僅為只讀狀態,大家可以通過在配置文件中限制es的內存,默認是1G的。官方建議設置內存為系統內存的一半,但不要超過32GB,且最大內存與最小內存最好相等防止經常GC,參考自config/elasticsearch.yml
啟動es的時候就需要指定內存參數, 如
ES_JAVA_OPTS="-Xms512m -Xmx512m" bin/elasticsearch -d
使用kibana
此時我已經修復了內存不夠的問題,配置文件也在上邊更新了,大家可以放心測試
訪問<你的kibana-ip:5601> 我的是<192.168.87.133:5061>
Kibana默認是不會給我們添加展示的索引的,需要我們去匹配,這里我們去添加
下一步,選擇@timestamp或者其它,我這里選擇@timestamp,然后創建索引模式即可
索引創建完成,我們去儀表盤查看下,點這個Discover
結束
最近在做ELK日志系統這塊,還做了個demo級的docker-compose的ELK集群,因為生產環境我們是不會將多個es和多個kafka放在同一台機器上的。稍后我會整理下發上來,供大家借鑒。