前言
我們為啥需要全文搜索
首先,我們來列舉一下關系型數據庫中的幾種模糊查詢
MySql :
- 一般情況下LIKE 模糊查詢 SELECT * FROM `LhzxUsers` WHERE UserName LIKE '%o%'
- 模糊查詢高效的方法
LOCATE('substr',str,pos)方法 SELECT * FROM `LhzxUsers` WHERE LOCATE('O',UserName) >0
解釋:返回 substr 在 str 中第一次出現的位置,如果 substr 在 str 中不存在,返回值為 0 。如果pos存在,返回 substr 在 str 第pos個位置后第一次出現的位置,如果 substr 在 str 中不存在,返回值為0
POSITION('substr' IN `field`)方法 SELECT * FROM `LhzxUsers` WHERE POSITION('O' IN UserName)
解釋:其實我們就可以把這個方法當做是locate()方法的別名,因為它和locate()方法的作用是一樣的。
INSTR(`str`,'substr')方法 SELECT * FROM `LhzxUsers` WHERE INSTR(UserName,'O')>0
解釋:這個函數返回字符串在某一個字段的內容中的位置, 沒有找到字符串返回0,否則返回位置(從1開始)
除了上述的方法外,還有一個函數FIND_IN_SET,這個方法比較特殊,他所查詢的必須要是以“,”分隔開。
FIND_IN_SET(str1,str2) SELECT * FROM LhzxUsers WHERE FIND_IN_SET('杭州',Address)
SqlServer 也有類似的函數提供模糊查詢,不重復說明
思考:使用關系型數據庫我們如何實現類似,淘寶、京東、的搜索框
有同學就舉例了,分詞,sql 拼接,多線程異步執行 ,當你看到這樣的產品屬性時,你還有欲望sql拼接嗎?
可以想象一下公司的業務場景,汽車金融領域,是不是也可以做一個這樣的搜索,供我們的業務部門使用,而不是僅僅從特定的幾個字段來進行搜索
------華麗分割---------
從搜索在談到日志,我們有 log4j、Log4j2、nlog、等等系列開源日志軟件,初期我們寫入txt,后期,每月要清理高達幾百G的日志文件。
我們運行的服務器集群出現 CPU100%,內存溢出等異常,需要查看 IIS、nginx、Apache、tomcat、等服務軟件的運行日志時,需要一台一台的去服務器各個軟件日志目錄去查看,這個時候就有工程師想到了分布式日志服務架構。很優秀!!
基礎軟件環境搭建
ELK由ElasticSearch(ES)、Logstash和Kiabana三個開源工具組成。
- elasticsearch-6.3.2
- kibana-6.3.2-windows-x86_64
- logstash-6.3.2
nssm工具可以將各種應用添加到Windows服務,以服務的形式運行上訴軟件 官網 http://nssm.cc/- ES是個開源分布式搜索引擎,它的特點有:分布式,零配置,自動發現,索引自動分片,索引副本機制,restful風格接口,多數據源,自動搜索負載等。 這里有權威指南 https://es.xiaoleilu.com
- Logstash是一個完全開源的工具,可以對日志進行收集、分析、並將其存儲供以后使用。
Filebeat隸屬於Beats。目前Beats包含四種工具:(此文只會談及)
- Packetbeat(搜集網絡流量數據)
- Topbeat(搜集系統、進程和文件系統級別的 CPU 和內存使用情況等數據)
- Filebeat(搜集文件數據)
- Winlogbeat(搜集 Windows 事件日志數據)
- kibana也是一個開源和免費的工具,他Kibana可以為Logstash和ES提供的日志分析友好的Web界面,可以幫助您匯總、分析和搜索重要數據日志。
1:安裝JAVA-JDK(需要1.8),官方自行下載,不做介紹
2:安裝ES服務
- 進入目錄C:\ELK\elasticsearch-6.5.3\bin, 雙擊執行 elasticsearch.bat,該腳本文件執行 ElasticSearch 安裝程序,稍等片刻,打開瀏覽器,輸入 http://localhost:9200 ,顯式以下畫面,說明ES安裝成功。
- 關閉命令提示符窗口,服務也停止了,我們使用nssm工具將其安裝為服務運行,cmd 進入nssm.exe 目錄 輸入nssm.exe install 回車,此時會彈出nssm工具的ui界面
- 選擇 C:\ELK\elasticsearch-6.5.3\bin\elasticsearch.bat 輸入服務名稱 elasticsearch-6.5.3 點擊install service
- 天公不作美,安裝時出現了意外,百度半天,發現是360 安全防護在作怪
- 如果所示,被360 防護中心攔截,隨手就卸載了360
- 果然再次點擊安裝,成功
- 由於我們在安裝服務時,將DisplayName 隨手寫成了AAA
- 所以在安裝好的服務列表中顯示的是AAA ,描述為BBB
- 啟動服務,然后再瀏覽器里面輸入 http://localhost:9200/
- 看到這個界面,說明elasticsearch啟動成功
- 現在我們來配置下elasticsearch 讓它可以用IPV4 來訪問
- 進入 根目錄 C:\ELK\elasticsearch-6.5.3\config 找到 elasticsearch.yml 配置文件
- 有關 elasticsearch.yml 的詳細配置參考園友的詳細介紹: https://www.cnblogs.com/hanyouchun/p/5163183.html
- 找到 Network 配置位置
- 取消這兩行的注釋 刪除最前面的 #
- 把 network.host 換成安裝elasticsearch本機的IP ,端口號可以默認,然后保存,重啟服務
- 隨即我們在 瀏覽器中 就可以使用 IP 來訪問
- 在這里 elasticsearch 的單機簡易安裝服務我們完成了 ,關於elasticsearch的集群服務安裝可以后續繼續研究。
3:安裝Logstash服務
Logstash 它的五種替代方案(Filebeat、Fluentd、rsyslog、syslog-ng 以及 Logagent)
Logstash工作原理:
Logstash事件處理有三個階段:inputs → filters → outputs。是一個接收,處理,轉發日志的工具。支持系統日志,webserver日志,錯誤日志,應用日志,總之包括所有可以拋出來的日志類型。
這里我不去分析這五種日志收集傳輸工具的優缺點,有興趣的同學可以自行去研究他們的優劣勢以及使用場景。
- 在根目錄新增 logstash.conf 配置文件
input {
stdin{
}
udp{
host=>"192.168.100.48"
port=>4561
codec=>"json"
}
}
filter {
}
output {
elasticsearch {
hosts => ["192.168.100.48:9200"]
index => "logstash-%{+YYYY.MM.dd}"
document_type => "logs"
}
stdout {}
}
- 同理,使用NSSM 安裝 Logstash
- 注意,安裝Logstash 時需要選擇配置文件安裝 添加啟動參數 agent -f C:\ELK\logstash-6.3.2\bin\logstash.conf
- 如圖,安裝服務后 啟動服務
- 在啟動的時候如果報錯或者閃退 未能加載主程序XXXXXX
- bin 文件夾下找到 logstash.bat 文件,打開
在這一行的這兩個位置加上雙引號
- 再次運行,OK
4:安裝 kibana-6.3.2
- 進入跟目錄 C:\ELK\kibana-6.3.2-windows-x86_64\kibana-6.3.2-windows-x86_64\config
- 編輯 kibana.yml
- 使用NSSM 安裝 kibana 為服務
- 右鍵啟用,瀏覽器訪問 http://192.168.100.48:5601 就可以打開 kibana 界面了
這ELK樣服務安裝完成后,我們就可以開始往里面寫入各種數據了
首先來看下在Net Core 中使用 Nlog 向搭建好的 ELK 輸入日志
- 創建一個netcore api 項目
- 打開NuGet包管理器 搜索 NLog.Web.AspNetCore
- 安裝如圖中的兩個包
- 在 Startup.cs 中 配置使用 Nlog
- 新增 nlog.config 文件
<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogLevel="Warn" internalLogFile="internal-nlog.txt"> <!--define various log targets--> <targets> <target name="network" xsi:type="Network" address="udp://192.168.100.48:4561" layout="${message}"/> </targets> <rules> <logger name="*" level="Info" writeTo="network" /> </rules> </nlog>- 新增 JsonLogMessage 類
public class JsonLogMessage { public string A_Message { get; set; } public int A_AddUser { get; set; } public string A_AddUserName { get; set; } public int A_ObjId { get; set; } public string A_ObjName { get; set; } public string A_OperationName { get; set; } public string A_ActionName { get; set; } public string A_Host { get; set; } public string S_LoggerName { get; set; } public string S_Level { get; set; } public string S_Thread { get; set; } public string S_Application { get; set; } public DateTime S_Timestamp { get=> System.DateTime.Now;} }- 在控制器中使用 Nlog 向ELK 輸出 日志
[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { private readonly ILogger _Logger = LogManager.GetCurrentClassLogger(); // GET api/values [HttpGet] public ActionResult<IEnumerable<string>> Get() { for (int i = 0; i < 100; i++) { JsonLogMessage jsonLogMessage = new JsonLogMessage() { A_ActionName = "Get", A_AddUser = 1, A_AddUserName = "張三", A_Host = "192.168.100.48", A_Message = string.Format("測試Logstash日志請求,請求id:{0}", i), A_ObjId = 2, A_ObjName = "操作對象", A_OperationName = "獲取對象", S_Application = "S_Application" }; _Logger.Info(Newtonsoft.Json.JsonConvert.SerializeObject(jsonLogMessage)); } return new string[] { "value1", "value2" }; } }- 打開 Kibana 創建 索引庫
- 創建完畢后,你就能在 Discover 看到 我們輸入的日志了
到這里 一個 以Nlog + ELK 的分布式日志系統就搭建完成了,有同學問,這樣就好了么?,我在這里給大家一張拓撲圖,大家看了就明白了,這上面做的只是入門的基礎單元
網絡截圖
網絡截圖
網絡截圖
拓展:也有nlog 直接寫入 參考園友文章,有興趣的同學可以試一下
https://www.cnblogs.com/focus-lei/p/9154867.html
如果只是為了寫日志,這樣也不失為一個簡便的方法,但你如果需要對收集到的各種日志進行格式化,過濾,此方式就不通了。