色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

怎么使用Go重構流式日志網關呢?

OSC開源社區 ? 來源:又拍云 ? 2023-06-18 10:42 ? 次閱讀

項目背景

分享之前,先來簡單介紹下該項目在流式日志處理鏈路中所處的位置。

ee017162-0c36-11ee-962d-dac502259ad0.png

流式日志網關的主要功能是提供 HTTP 接口,接收 CDN 邊緣節點上報的各類日志(訪問日志/報錯日志/計費日志等),將日志作預處理并分流到多個的 Kafka 集群和 Topic 中。

越來越多的客戶要求提供實時日志支持,業務量的增加讓機器資源的消耗也與日俱增,最先暴露出了流式日志處理鏈路的一大瓶頸——帶寬資源。 可以通過給集群擴充更多的機器來提升集群總傳輸帶寬,但基于成本考量,重中之重是先優化網關程序。

舊版網關項目

項目代號 Chopper ,其基于另一個內部 OpenResty 項目框架來開發的。其亮點功能有:支持從 Consul 、Redis 等其他外部系統熱加載配置及動態生效;能夠加載 Lua 腳本實現靈活的日志預處理能力。 其 Kafka 生產者客戶端基于 doujiang24/lua-resty-kafka 實現。經過實踐考驗,Chopper 的吞吐量是滿足現階段需求的。

存在的問題

1. 關鍵依賴庫的社區活躍度低 lua-resty-kafka 的社區活躍度較低,至今仍然處在實驗階段;而且它用作 Kafka 生產者客戶端目前沒有支持消息壓縮功能,而這在其他語言實現的 Kafka 客戶端中都是標準的選項。

2. 內存使用不節制 單實例部署配置 4 核 8 G,僅少量請求訪問后,內存占用就穩定在 2G 而沒有釋放。

3. 配置文件可維護性差 實際線上用到 Consul 作為配置中心,采用篇幅很長的 JSON 格式配置文件,不利于運維。另外在 Consul 修改配置沒有回退功能,是一個高風險操作。 好在目前日志網關的功能并不復雜,所以我們決定重構它。

新項目啟動

眾所周知, Go 語言擁有獨特的高并發模型、較低的上手難度和豐富的第三方生態。而且我們小組成員都有 Go 項目的開發經驗,所以我們選擇使用基于 Go 語言的技術棧來重新構建 Chopper 項目,所以新項目命名為 chopper-go 。

需求梳理及概要設計

重新構建一個線上項目的基本原則是,功能上要完全兼容,最好能夠實現線上服務的無縫升級替換。

原版核心模塊的設計

Chopper 的核心功能是將接收到的 HTTP 請求分流到特定 Kafka 集群及其 Topic 中。

一、HTTP 接口部分

只開放了唯一一個對外的 API ,功能很簡單:

請求方式:POST 請求路徑:/log/repo/{repo_name}請求體: 多行日志,滿足 JSONL 格式(即每行一條 JSON ,多行按換行符 分隔)。相應狀態碼:- 200:投遞成功。- 5xx:投遞失敗需要重試。參數解釋: - repo_name: 對應 repo 配置名稱。

二、業務配置部分

每一類業務抽象為一個 repo 配置。Repo 配置由三部分構成:constraint、processor、kafka。 constraint 是一個對象,可以配置對日志字段的一些約束條件,不滿足條件的日志會被丟棄。 processor 是一個列表,可以組合多個處理模塊,程序將按順序依次對請求中的每條日志進行處理。實現了如下幾種 processor 類型:

decoder , 配置原始數據按哪種格式反序列化到 Lua table ,但只實現了 JSON decoder。

splitter,配置分隔日志字段的字符。

assigner,配置一組字段名映射關系,需要與 spliter 配合。

executer, 配置額外的 lua 腳本名稱,通過動態加載其他 lua 腳本實現更靈活的處理邏輯。

kafka 是一個對象,可以配置當前業務相關聯的 Kafka 集群名,默認投遞的 Topic ,以及生產者客戶端的工作模式(同步或者異步)。 新版本的改動 HTTP 接口沿用原先的設計,在業務配置部分做了一些改動:

processor 改名為 executers ,實現幾個通用功能的日志處理模塊,方便組合使用。

kafka 配置中關聯的不再是集群名,而是 Kafka 生產者客戶端的配置標簽

原先保存 kafka 集群連接配置信息的配置塊,改為保存 kafka 生產者客戶端的配置塊,統一在一個配置塊區域初始化所有用到的 kafka 生產者客戶端。

一點妥協(做減法)

為了縮短新項目的開發周期,對原始項目的一些不太重要的特性我們做了一些取舍。

取消動態腳本功能

Go 是靜態語言沒有 Lua 動態語言那么靈活,要加載執行動態腳本有一定的實現難度,且日志處理性能沒有保障。 線上只有極少數業務在 processor 中配置了 executor,且這些 executor 的 Lua 腳本實現相近,完全可以抽取出通用的代碼。

不支持外部配置中心

為了讓發布和回退有記錄可回溯,從 Consul 等配置中心熱加載服務配置的功能我們也去掉了。利用好容器平臺的金絲雀發布功能,就能將服務更新的影響降到最低。

不支持復雜的路由重寫

OpenResty 項目內置 Nginx 可以利用 Nginx 強大的配置實現豐富的路由 rewrite 功能,就具體使用場景而言,我們只需要簡單的路由映射即可。況且更復雜的需求也可以由上一級網關完成。

選擇合適的開源庫

Web 框架的選擇

最終我們選擇了 Gin 。原因是用得多比較熟,而且文檔看著舒服。

Kafka 生產者客戶端的選擇

社區中熱度最高的幾款 Go Kafka 客戶端庫:

segmentio/kafka-go

Shopify/sarama

confluentinc/confluent-kafka-go

實際上三款客戶端庫我們在歷史項目中都使用過,其中 kafka-go 的 API 是三者中最簡潔易用的,我們的多個消費端程序都是基于它實現的。

但是在 chopper-go 中僅需要用到生產者客戶端,我們沒有選擇 kafka-go 。

那是因為我們做了一些基準測試,發現 kafka-go 的生產者客戶端存在性能風險:啟用 async 模式時盡管消息發送特別快,但是內存占用也增長特別快。

最終我們選擇 sarama ,一方面是性能很穩定,另一方面是它開放的 API 較多,但是用起來確實有點費勁。

測試框架的選擇

程序的可靠性,一定需要測試來保證。除了編寫小模塊中編寫單元從測試,我們對整個日志網關服務還要做集成測試。集成測試涉及到一些外部服務依賴,此項目中主要的外部依賴是 Kafka 和 Zookeeper 。

利用 Docker 可以很方便的拉起測試環境,我們注意到了兩款可以用來在 Go test 中編寫集成測試的庫:

ory/dockertest

testcontainers/testcontainers-go

使用下來,我們最終選擇了 testcontainers-go,簡單介紹下原因: 在編寫集成測試時,我們需要有個等待機制來確保依賴服務的容器是否準備就緒,并以此控制測試流程,以及測試結束后需要把測試開啟的臨時容器都清理干凈。 testcontainers-go 的設計要優于 dockertest 。

testcontainers-go 提供一個 wait 子包,可以配置多種等待策略來確保依賴服務就緒,以及測試結束時它會調用一個特殊的名為 Ryuk 的容器來確保測試容器都被關閉。

相對而言,dockertest 要簡陋不少。 需要注意的是,在 CI 環境運行集成測試都需要確保 ci-runner 支持 DinD ,否則運行 go test 會失敗。

項目開發

項目開發過程中基本按照需求來實現沒有太多難點。這里分享踩到的幾個坑。

循環中變量的引用問題

在測試中發現,Kafka 生產者沒有按期望把消息投遞到指定的 Kafka 集群。 經過排查到如下代碼:

func New(cfg Config) (*Manager, error) {
        var newProducers = make(NewProducerFuncs)
        for name, kCfg := range cfg.Mapping {
                newProducers[name] = func() (kafka.Producer, error) { return kafka.New(kCfg) }
        }
        // 略
}
其作用是將配置每個 Kafka 生產者配置先保存為一個函數閉包,待后續初始化 repo 的時候再初始化生產者客戶端。

經驗豐富的同學可以發現,for 循環的 kCfg 變量其實是指向迭代對象的地址,整個循環下來所有的函數閉包中用到的 kCfg 都指向 cfg.Mapping 的最后一個迭代值。 解決辦法很簡單,先做一遍變量拷貝即可:
func New(cfg Config) (*Manager, error) {
        var newProducers = make(NewProducerFuncs)
        for name, kCfg := range cfg.Mapping {
                newProducers[name] = func() (kafka.Producer, error) { return kafka.New(kCfg) }
        }
        // 略
}

Sarama 客戶端的一點坑

對于重要的日志數據,我們希望在 HTTP 請求返回時明確反饋是否成功寫入 Kafka 。那么最好將 Kafka 生產者客戶端配置為同步模式。

而同步模式的生產者要提高吞吐量,批量發送是必不可少的。 批量發送的配置位于 sarama.Config.Producer.Flush

cfg := sarama.NewConfig()
// 單次請求中消息數量的絕對上限
cfg.Producer.Flush.MaxMessages = batchMaxMsgs
// 能夠觸發請求發出的消息數量閾值
cfg.Producer.Flush.Messages = batchMsgs
// 能夠觸發請求發出的消息字節大小閾值
cfg.Producer.Flush.Bytes = batchBytes
// 批量請求的觸發間隔時間
cfg.Producer.Flush.Frequency = batchTimeout
實踐中發現,如果配置了 Flush.Bytes 而沒有配置Flush.Frequency 就存在問題。如果消息大小始終未達閾值就不會觸發批量請求,故 HTTP 請求就會阻塞直到客戶端請求超時。 所以在配置參數的讀取上,我們把這兩個配置項做了關聯,只有配置了 Flush.Frequency 才能讓 Flush.Bytes 的配置生效。

項目上線

容器平臺上的灰度技巧

原本圖方便我們的路由轉發規則配置的是全部路由直接轉給同一組 Chopper 實例。 前面介紹了,每一個業務對應一個 repo,也就對應一個獨立的請求路徑。如果要灰度新的服務,需要對不同業務單獨灰度,所以我們需要將不同業務的流量去分開。

好在容器平臺的 k8s-ingress 使用的是 APISIX 作為接入網關,其路由匹配的優先級是:絕對匹配 > 前綴匹配。 只需要針對特定業務增加一條絕對匹配規則,就可以分離出特定業務的流量。

舉個例子: 原本的轉發規則是:/* -> workers-0 我們新建一條轉發規則:/log/repo/cdn-access -> workers-1 workers-0 和 workers-1 兩組服務的配置完全相同。 然后我們對 workers-1 這組服務灰度發布新版程序。

逐步擴大

每灰度一條路由,我們可以從監控 Dashboard 上觀察 HTTP 請求是否有異常,觀察 Kafka 對應的 topic 的寫入速率是否有異常抖動。

一旦觀測到異常,立即停止灰度,然后檢查程序運行日志,修正問題后重新開始灰度。 如果無異常,則逐步擴大灰度比例,直到完成服務更新。

總結起來就是灰度、觀測、回退、修改循環推進,確保升級對每個業務都無感知。

完成發布

對比服務端資源占用情況

舊版 chopper (4C8G x 20) 灰度比例 10% -> 50%

ee241b5e-0c36-11ee-962d-dac502259ad0.png

chopper-go (4C4G x 20) 10% -> 50%

ee46526e-0c36-11ee-962d-dac502259ad0.png

50% -> 100%

ee5d7f70-0c36-11ee-962d-dac502259ad0.png

結論:新版日志網關的內存和 CPU 的資源使用都有顯著降低。

服務端程序的資源占用情況

舊版 chopper 的 Kafka 客戶端不支持消息壓縮,chopper-go 發布中就配置了 Kafka 生產者消息的功能。 壓縮算法選擇 lz4 ,觀察兩組消費服務的資源實用率的變化: 消費服務0

內存使用率 27% -> 40%

網絡流入 253Mbps -> 180Mbps

消費服務1

內存使用率 28% -> 39%

網絡流入 380Mbps -> 267Mbps

結論:開啟消息壓縮功能后,消費實例的內存使用率普遍有增長,但內網傳輸帶寬占用降低約 30% 。

更新計劃

重構后的流式日志網關,尚有許多可優化空間,例如:

采用更節省帶寬的日志傳輸格式;

進一步細化 Kafka topic 的分流粒度;

日志消息處理階段多級處理執行器之間增加緩存提高字段訪問速度等等。

在豐富開源生態的加持下,該項目的優化迭代也將有條不紊地進行。





審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • CDN網絡
    +關注

    關注

    0

    文章

    11

    瀏覽量

    6800
  • JSON
    +關注

    關注

    0

    文章

    119

    瀏覽量

    6999
  • HTTP接口
    +關注

    關注

    0

    文章

    21

    瀏覽量

    1823
  • go語言
    +關注

    關注

    1

    文章

    158

    瀏覽量

    9070

原文標題:使用Go重構流式日志網關

文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Go語言開發有什么優勢?怎么學?

    帶來的各種問題。  3. 性能優異。Go的性能只比C/C++減少了10%左右。相對其他腳本(python/php),性能具有巨大的優勢。  那么,Go語言都有哪些公司在用?比如google
    發表于 12-19 16:08

    API信息全掌控,方便你的日志管理——阿里云推出API網關打通日志服務

    摘要: 近日,阿里云API網關對接了日志服務,可以輸出用戶在API網關產生的API調用日志,目前支持將 API 接入 API 網關的用戶查看
    發表于 02-06 15:24

    go語言能做什么工作?

    讓程序員更容易地進行維護和修改。它融合了傳統編譯型語言的高效性和腳本語言的易用性和富于表達性。Go語言作為服務器編程語言,很適合處理日志、數據打包、虛擬機處理、文件系統、分布式系統、數據庫代理等;網絡
    發表于 03-22 15:03

    如何利用ARM與FPGA設計重構控制器?

    重構技術是指利用可重用的軟硬件資源,根據不同的應用需求,靈活地改變自身體系結構的設計方法。常規SRAM工藝的FPGA都可以實現重構,那我們具體該怎么做
    發表于 08-09 07:35

    有沒有辦法同時流式傳輸 A55 的 uart 日志并使用 MCUXpresso 使用 iMX93 evk 調試 M33?

    有沒有辦法同時流式傳輸 A55 的 uart 日志并使用 MCUXpresso 使用 iMX93 evk 調試 M33。
    發表于 05-18 08:21

    網絡取證日志分布式安全管理

    提出了一種網絡取證日志分布式安全管理方法,通過日志代理和管理網關將分散的異構的日志收集并存儲到多個管理節點。該管理節點采用信息分配算法IDA將日志
    發表于 05-11 20:12 ?10次下載

    對于大規模系統日志日志模式提煉算法的優化

    LARGE框架是部署在中國科學院超級計算環境中的日志分析系統,通過日志收集、集中分析、結果反饋等步驟對環境中的各種日志文件進行監控和分析。在對環境中系統日志的監控過程中,系統維護人員需
    發表于 11-21 14:54 ?7次下載
    對于大規模系統<b class='flag-5'>日志</b>的<b class='flag-5'>日志</b>模式提煉算法的優化

    小米流式平臺架構演進與實踐

    ,實時同步任務 1.5 萬,實時計算的數據 1 萬億條。 伴隨著小米業務的發展,流式平臺也經歷三次大升級改造,滿足了眾多業務的各種需求。最新的一次迭代基于 Apache Flink,對于流式平臺內部模塊進行了徹底的重構,同時小米
    發表于 03-15 16:48 ?871次閱讀
    小米<b class='flag-5'>流式</b>平臺架構演進與實踐

    PLC網關主要可以支持哪些品牌型號的PLC協議

    PLC網關主要可以支持哪些品牌型號的PLC協議
    發表于 11-06 15:58 ?1025次閱讀
    PLC<b class='flag-5'>網關</b>主要可以支持哪些品牌型號的PLC協議<b class='flag-5'>呢</b>?

    詳解MySQL三大日志的作用

    MySQL日志 主要包括錯誤日志、查詢日志、慢查詢日志、事務日志、二進制日志幾大類。其中,比較重
    的頭像 發表于 07-22 14:44 ?1376次閱讀

    工業智能網關日志有哪些?如何輸出和導出網關日志查看

    日志主要看網關與平臺交互情況,判斷平臺數據是否正常,通道是否正常系統日志主要用于判斷網站和系統的異常如何輸出和導出工業智能網關日志
    的頭像 發表于 10-26 17:33 ?807次閱讀
    工業智能<b class='flag-5'>網關</b><b class='flag-5'>日志</b>有哪些?如何輸出和導出<b class='flag-5'>網關</b><b class='flag-5'>日志</b>查看<b class='flag-5'>呢</b>?

    流式圖計算TuGraph-Analytics技術背后的故事和技術特性

    流式計算針對流式動態變化的數據流,一般動態的數據流有實時的日志流,或者數據庫的變化日志,主要是為了場景中的實時應用需求。
    的頭像 發表于 06-28 11:34 ?1091次閱讀
    <b class='flag-5'>流式</b>圖計算TuGraph-Analytics技術背后的故事和技術特性

    FTTR主網關開通后實現主從網關組網

    FTTR主網關開通后,如何開通從網關,實現主從網關組網
    的頭像 發表于 07-19 09:09 ?5151次閱讀
    FTTR主<b class='flag-5'>網關</b>開通后實現主從<b class='flag-5'>網關</b>組網<b class='flag-5'>呢</b>?

    奇怪!應用的日志??

    1. 問題回顧 問題背景 是在進行中臺應用中間件遷移過程中,發現存在 項目啟動失敗 或者 項目正常啟動 (jsf正常掛載并正常運行,mq正常發送和消費)但是 無任何日志打印 現象。 更奇怪 的是不打
    的頭像 發表于 06-11 10:48 ?348次閱讀
    奇怪!應用的<b class='flag-5'>日志</b><b class='flag-5'>呢</b>??

    日志篇:模組日志總體介紹

    ?今天我們學習合宙模組日志總體介紹,以下進入正文。 一、本文討論的邊界 本文是對合宙 4G 模組, 以及 4G+GNSS 模組的日志功能的總體介紹。通過日志,可以對研發過程中,以及模組運行過程中
    的頭像 發表于 10-24 07:16 ?232次閱讀
    <b class='flag-5'>日志</b>篇:模組<b class='flag-5'>日志</b>總體介紹
    主站蜘蛛池模板: 日本久久久WWW成人免费毛片丨 | 国产色情短视频在线网站 | 亚洲青青草原 | 三级黄色在线看 | 精品国产国产综合精品 | 好大的太粗好深BL | 国产精品资源在线观看网站 | 伊人久久天堂 | 中文中幕无码亚洲视频 | 永久免费精品精品永久-夜色 | 国产一区私人高清影院 | 亚洲狠狠网站色噜噜 | 蜜桃传媒一区二区亚洲AV | 国产欧美一区二区精品性色tv | 午夜伦理伦理片在线观 | jizz国产丝袜18老师美女 | 国产激情视频在线 | 国产精品无码亚洲区艳妇 | 大香伊人中文字幕精品 | 国产在线一区观看 | 金发欧美一区在线观看 | 亚洲精品在线免费 | 国产人妻麻豆蜜桃色69 | MD传媒在线观看佳片 | 国内精品一级毛片免费看 | 恋孩癖网站大全在线观看 | 国产精品女上位好爽在线短片 | 欧美一区二区三区久久综 | 国产在线一区二区三区四区 | 亚洲 欧美 日本 国产 高清 | 久久婷五月综合色啪网 | 亚洲国产欧美在线人成aaaa20 | 中文字幕视频在线免费观看 | 欧美牲交视频免费观看K8经典 | 亚洲国产成人精品不卡青青草原 | 久久毛片视频 | 脱女学小内内摸出水网站免费 | 天天看学生视频 | 妹妹好色网 | 国产97精品久久久天天A片 | 亚洲国产剧情中文视频在线 |