簡體   English   中英

Java - 記錄多節點環境中的最佳實踐

[英]Java - Logging best practices in multi-node environment

在我的公司,我在一個多節點基礎設施中管理一個大型應用程序(> 100k用戶),由3個(但可能更多)應用程序服務器組成。 每個應用程序服務器都有5個不同的日志文件,其中幾乎記錄了有關http / s(REST或SOAP)請求和對其他(外部)子系統的響應的每個信息。 我使用Apache Http客戶端來處理REST流,將wsimport生成的客戶端用於SOAP請求,使用Logback作為日志記錄技術。

目前,當我被要求調試某些東西時,我要做的最復雜和最耗時的任務是確定我必須調試的節點。 在那之后,為了發現發生了什么,我必須實際上使用大量的線條。 說實話,我發現它非常無聊和過時,也很復雜。

為了讓我的生活更輕松,讓我的日志變得更有趣,我過去幾天在彈性搜索堆棧(elasticsearch,logstash,kibana)上看了一下,並使用他們的docker圖像進行了游戲。 我發現它們非常有趣,我想在我的應用程序中介紹它們但在此之前我想知道是否有最佳實踐/模式來做類似的事情。

這些是我的疑惑:

  • 是否有一種最佳實踐來記錄Http / s REST和SOAP請求/響應(我需要查看所有內容:url,headers,path,body,cookies,...),格式可以通過logstash / elasticsearch輕松解析?
  • 考慮到我的基礎設施,我應該使用elasticsearch appender進行我的logback實現,還是使用Logstash作為日志處理器(我想每個應用服務器都有一個)?
  • 是否有有效的logback和elasticsearch技術替代方案來滿足我的要求?

我不指望一個簡單易行的答案。 我想了解不同的經驗,以便做出最適合我的解決方案的選擇

謝謝!

這是一個復雜的答案:) ELK堆棧絕對可以讓你的生活在分布式環境中更容易。 但是,為了從中受益,您可以考慮以下做法:

  • 在ElasticSearch的日志消息中,您應該看到以下內容(除了明顯的時間,級別,消息本身):

    • 生成大量消息的服務器
    • 發起請求的用戶
    • 如果您的申請是多租戶 - 請求已經進行的租戶
  • 所有消息應該具有相同的結構(布局)

  • 由於您使用Java,異常可能成為一個潛在的問題(它們是多線的),因此需要特殊處理。 Logstash可以處理它

  • 如果您的流可以分布在不同的服務器上(您說您有3個且可能更多),請考慮為每個請求生成一個特殊的相關ID。 一些可以識別流量的隨機數。

所有這些都有助於應用過濾器並從Elastic Search中獲益更多。

考慮將TTL用於日志。 可能您不需要在超過一周或兩周之前保留創建的日志。

現在關於HTTP請求。 通常只記錄所有內容可能是一個安全問題,因為您無法確定是否會記錄某些“敏感”信息。 所以你要保持這種保護(至少你的安全人員會想:))。 可能記錄URL,服務器,http方法和一些用戶標識符(或者如果需要的話,租戶)就足夠了,但這完全是我的意見。

現在關於appender vs logstash(文件)方法。 這兩種方法都有優點和反差。 例如:如果使用logstash方法,則必須解析日志文件的每一行。 如果您的應用程序生成許多日志,它可能會影響性能,因為解析可以通過CPU costy(特別是如果您在logstash中使用grok過濾器)。 另一方面 - appenders允許完全避免解析(你將在java中的內存中獲得所有信息)。

另一方面,應仔細設置appender。 我沒有使用logback Elasticsearch appender的經驗,但我認為它至少應該是:

  • 異步(否則您的業務流程可能會卡住)
  • 能夠應對失敗(你不會因為當前的ES不可用或其他東西而拋出異常。最終用戶不應該真正感受到這一點)。
  • 可能維護一些隊列/使用干擾器,只是因為你可以產生比你的appender可能發送給ES更多的日志,所以最終日志消息將丟失。 例如,如果您有一個大小為1000的隊列,並且日志中有超過1000條消息,則可以映像FIFO將執行的操作。

還有一件事需要考慮:讓我們想象一下,由於某些原因,其中一個應用服務器存在問題。 所以你可能想要重新啟動它(優雅與否)。 如果你使用im-memory appender這些消息會發生什么? 你想在ElasticSearch中看到它們來分析post mortum嗎? 因此,底線內存中的方法無法處理重啟。

另一方面,logstash進程將很樂意處理存儲在文件中的任何內容。

至於appender與logstash的替代方法,您可能會考慮使用Apache Flume作為傳輸。 如果你采用appender方法,你可以使用嵌入式水槽代理,並在它上面寫一個非常好的appender。 Flume將提供基於磁盤的持久性,像api這樣的事務等等。

話雖如此,據我所知,很多人只是采用了logstash方法。

還有一件事,可能是我想到的最后一件事:

  • 你不應該直接寫ElasticSearch。 而是使用一些中間服務器(在logstash中它可以是Redis或RabbitMQ)。 在水槽方法中,您可以使用其他水槽工藝(開箱即用的擴展選項支持)。

這將允許您在架構方面抽象ElasticSearch並在日志存儲服務器上應用一些額外的處理(它可以從RedM獲取數據/從RabbitMQ獲取接收消息)。 在水槽中,類似的行為也是可以實現的。

啤酒花有幫助

是否有最佳實踐[/]格式[/ protocol]?

我不知道任何已有您想要的字段的日志標准。 所以你需要一種可以存儲自定義元數據的格式。 您可以使用RFC5424格式向syslog消息添加元數據。 我還看到各種日志服務通過套接字連接接受JSON格式的消息。

我應該使用elasticsearch appender嗎?

我建議直接發送到logstash,而不是直接發送到ElasticSearch。

  1. Logstash旨在以各種格式接收和解析消息,因此以logstash理解的格式比以ElasticSearch理解的格式更容易發送消息。
  2. 隨着您的日志記錄需求的發展:您將能夠在一個地方進行更改 - Logstash - 而不是重新配置您的每個應用程序實例。

    • 這包括操作更改,例如更改ElasticSearch集群的地址。
  3. Logstash可以執行諸如審查日志之類的操作(刪除看起來像密碼或地址的內容)

  4. Logstash可以將日志發送到各種下游服務。 例如:如果遇到重要錯誤,它可以觸發PagerDuty通知或Slack消息。
  5. Logstash可以使用其他元數據豐富日志消息(例如,從IP地址解密地理坐標)

也可能存在規模問題。 我不足以對這些進行評論,但這是我的直覺:我希望Logstash能夠很好地處理大量連接(以及優雅地處理連接失敗)。 我不知道這在ElasticSearch集群的設計中是否具有類似的優先級,或者ElasticSearch的搜索性能是否會受到同時連接到它的大量代理的影響。 我更有信心Logstash的設計考慮到了這種用途。

您可能還發現ElasticSearch appender存在局限性。 appender需要對許多事情有很好的支持。 首先想到的是:

  • 協議選擇,加密
  • 選擇壓縮
  • 完全控制日志消息的格式(包括自定義字段)
  • 控制特殊消息(例如異常)被發送

您可以通過堅持一個良好支持的標准(例如syslog appender)來避免技術特定的appender的任何限制。

是否有有效的logback和elasticsearch技術替代方案來滿足我的要求?

你的意思是說logstash (即“是否有替代ELK堆棧”?)如果這是你的意圖,那么我沒有答案。

但就logback的替代方案而言......我使用log4j2。 它提供異步日志記錄,以減輕應用程序的性能負擔。 也許logback也有這個功能。 在log4j2日志消息中發送自定義字段很難(目前很難支持轉義JSON。插件可用,但您的構建需要正確設置才能支持這些)。 對我來說最簡單的方法是使用RFC5424 syslog appender。

考慮設計Java應用程序以調用日志記錄(即SLF4J),而不是直接調用logback。 這使您可以在將來輕松切換到其他日志記錄提供程序。

我和你有同樣的問題,並決定避免任何中間日志收集器(如Logstash / Flume)。

https://github.com/internetitem/logback-elasticsearch-appender目前並不理想但它的配置更具彈性然后https://github.com/logstash/logstash-logback-encoder

例如, logstash-logback-encoder修復了https://logback.qos.ch/apidocs/ch/qos/logback/classic/spi/ILoggingEvent.html標准字段的名稱

如果響鈴已滿並且缺少對可用ES服務器的迭代(目前只能指定一個),則logback-elasticsearch-appender當前缺乏對本地FS存儲的持久性。

請注意,默認情況下,Logstash不是故障安全的,來自https://www.elastic.co/guide/en/logstash/current/persistent-queues.html

默認情況下,Logstash在管道階段(輸入→管道工作者)之間使用內存中有界隊列來緩沖事件。 這些內存中隊列的大小是固定的,不可配置

因此,您需要使用Redis,RabbitMQ或Kafka創建一些模式。 在我看來,ES集群比Logstash(ES安全在Elasic.io廣告中)更安全。

另請注意Logstash在Ruby中實現,因此單線程應用程序 我們不能在這里談論可擴展性。 期望高達10000 req / s(這是我在Internet上找到的性能報告中的典型數字)。

水槽有更好的性能。 我看到它缺乏文檔。 准備好在郵件列表上提問))

有很多商業優惠:

  • Splunk <http://www.splunk.com/en_us/products/splunk-light.html>
  • Scalyr <https://www.scalyr.com/pricing>
  • Graylog <https://www.graylog.org/support-packages/>
  • Loggly <https://www.loggly.com/product/>
  • Motadata <https://www.motadata.com/elk-stack-alternative/>

由於明智的原因,它們每年花費數千美元。

您可以檢查一個日志收集供應商如何設計好的appender: https//logz.io/blog/lessons-learned-writing-new-logback-appender/

使用集中式日志記錄解決方案,您應該更改記錄方式:

  • 將上下文添加到https://www.slf4j.org/api/org/slf4j/MDC.html這可以是客戶電話號碼,IP地址,票號或其他任何內容。 您需要一種快速過濾重要數據的方法

  • 開始使用https://www.slf4j.org/api/org/slf4j/Marker.html進行需要立即反應的意外事件。 不要隱瞞或忽視問題

  • 計划如何命名MDC參數和標記並記錄它們,以便操作團隊知道發生了什么,而不是在午夜打電話給你。

  • 在ES群集中​​設置復制。 這允許您關閉部分ES節點以進行維護。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM