頂級 fakapov 青色

頂級 fakapov 青色

對所有人都好! 

我叫Nikita,是Cian工程團隊的組長。我在公司的職責之一是將與生產基礎設施相關的事故數量減少到零。
以下將要討論的內容給我們帶來了極大的痛苦,而本文的目的是防止其他人重複我們的錯誤或至少盡量減少其影響。 

前言

很久以前,當 Cian 由單體組成時,還沒有微服務的跡象,我們透過檢查 3-5 個頁面來衡量資源的可用性。 

他們回答 - 一切都很好,如果他們很長時間不回答 - 警報。他們需要下班多長時間才能被視為事件,這是由人們在會議上決定的。工程師團隊始終參與事件調查。調查完成後,他們寫了一份事後分析——一種透過電子郵件發送的報告,格式如下:發生了什麼、持續了多長時間、我們當時做了什麼、將來會做什麼。 

網站的主要頁面或我們如何理解我們已經觸底

 
為了以某種方式了解錯誤的優先級,我們已經確定了業務功能最關鍵的網站頁面。使用它們,我們可以計算成功/不成功的請求和超時的數量。這就是我們衡量正常運作時間的方式。 

假設我們發現該網站有許多非常重要的部分負責主要服務 - 搜尋和提交廣告。如果失敗的請求數量超過 1%,則屬於嚴重事件。如果在黃金時段15分鐘內錯誤率超過0,1%,那麼這也被視為嚴重事件。這些標準涵蓋了大多數事件;其餘事件超出了本文的範圍。

頂級 fakapov 青色

最佳最佳事件 青色

所以,我們肯定已經學會了確定事件發生的事實。 

現在,每個事件都被詳細描述並反映在 Jira 史詩中。順便說一句:為此我們啟動了一個單獨的項目,稱之為「失敗」——只能在其中創建史詩。 

如果你收集過去幾年的所有失敗,領導者是: 

  • mssql相關事件;
  • 由外在因素引起的事件;
  • 管理錯誤。

讓我們更詳細地看看管理員的錯誤,以及其他一些有趣的失敗。

第五名——“在 DNS 中把事情整理好”

那是一個風雨交加的星期二。我們決定恢復 DNS 叢集中的秩序。 

我想將內部 DNS 伺服器從 bind 轉移到 powerdns,為此分配完全獨立的伺服器,除了 DNS 之外什麼都沒有。 

我們在 DC 的每個位置放置了一台 DNS 伺服器,現在是將區域從 Bind 移動到 powerdns 並將基礎設施切換到新伺服器的時刻到來了。 

在遷移過程中,在所有伺服器上的本機快取綁定中指定的所有伺服器中,只剩下一台位於聖彼得堡的資料中心。該 DC 最初被聲明為對我們來說不重要,但突然變成了單點故障。
正是在搬遷期間,莫斯科和聖彼得堡之間的運河垮塌了。實際上,我們有五分鐘沒有 DNS 服務,當託管服務商解決了問題後,我們又恢復正常了。 

結論:

如果說以前我們在準備工作時忽略了外部因素,那麼現在它們也被納入了我們正在準備的清單中。現在我們努力確保所有元件都保留n-2,並且在工作過程中我們可以將這個等級降低到n-1。

  • 在製定行動計劃時,標記出服務可能失敗的點,並提前考慮一切「每況愈下」的場景。
  • 將內部 DNS 伺服器分佈在不同的地理位置/資料中心/機架/交換器/輸入上。
  • 在每台伺服器上,安裝本機快取 DNS 伺服器,該伺服器將請求重新導向到主 DNS 伺服器,如果不可用,則會從快取中回應。 

第四名——“在 Nginx 中把事情整理好”

有一天,我們的團隊決定“我們已經受夠了”,重構 nginx 配置的過程開始了。主要目標是將配置引入直覺的結構。以前一切都是“歷史既定”,沒有任何邏輯。現在,每個 server_name 已移至同名文件,並且所有配置已分發到資料夾中。順便說一句,該配置包含 253949 行或 7836520 個字符,佔用近 7 MB 的空間。頂層結構: 

Nginx結構

├── access
│   ├── allow.list
...
│   └── whitelist.conf
├── geobase
│   ├── exclude.conf
...
│   └── geo_ip_to_region_id.conf
├── geodb
│   ├── GeoIP.dat
│   ├── GeoIP2-Country.mmdb
│   └── GeoLiteCity.dat
├── inc
│   ├── error.inc
...
│   └── proxy.inc
├── lists.d
│   ├── bot.conf
...
│   ├── dynamic
│   └── geo.conf
├── lua
│   ├── cookie.lua
│   ├── log
│   │   └── log.lua
│   ├── logics
│   │   ├── include.lua
│   │   ├── ...
│   │   └── utils.lua
│   └── prom
│       ├── stats.lua
│       └── stats_prometheus.lua
├── map.d
│   ├── access.conf
│   ├── .. 
│   └── zones.conf
├── nginx.conf
├── robots.txt
├── server.d
│   ├── cian.ru
│   │   ├── cian.ru.conf
│   │   ├── ...
│   │   └── my.cian.ru.conf
├── service.d
│   ├── ...
│   └── status.conf
└── upstream.d
    ├── cian-mcs.conf
    ├── ...
    └── wafserver.conf

它變得好多了,但在重命名和分發配置的過程中,其中一些配置的擴展名錯誤,並且沒有包含在 include *.conf 指令中。導致部分主機無法使用,返回301返回主頁。由於回應代碼不是 5xx/4xx,所以沒有立即註意到這一點,而是在早上才注意到。之後,我們開始編寫測試來檢查基礎設施元件。

結論: 

  • 正確建立您的配置(不僅僅是 nginx)並在專案的早期階段仔細考慮結構。透過這種方式,您將使團隊更容易理解它們,從而減少 TTM。
  • 為一些基礎設施元件編寫測試。例如:檢查所有關鍵伺服器名稱是否給予正確的狀態+回應正文。手邊只要有幾個腳本來檢查組件的基本功能就足夠了,這樣就不用在凌晨 3 點瘋狂地記住還需要檢查什麼。 

第三名——“卡桑德拉突然空間不足”

資料穩定成長,一切都很好,直到 Cassandra 叢集中大型案例空間的修復開始失敗的那一刻,因為壓縮無法對它們起作用。 

在一個暴風雨天,該簇幾乎變成了一個南瓜,即:

  • 集群中大約剩下總空間的 20%;
  • 無法完全新增節點,因為新增節點後因分區空間不足而無法進行清理;
  • 由於壓實不起作用,生產率逐漸下降; 
  • 集群處於緊急模式。

頂級 fakapov 青色

退出 - 我們在沒有清理的情況下又添加了 5 個節點,之後我們開始系統地從叢集中刪除它們並重新進入它們,就像空間不足的空節點一樣。花費的時間比我們想要的要多得多。存在集群部分或完全不可用的風險。 

結論:

  • 在所有 cassandra 伺服器上,每個分割區上的空間佔用量不得超過 60%。 
  • 它們的負載不應超過 50% cpu。
  • 您不應忘記容量規劃,並且需要根據每個組件的具體情況對其進行仔細考慮。
  • 叢集中的節點越多越好。包含少量資料的伺服器過載速度更快,這樣的叢集更容易復活。 

第二名—“資料從consul鍵值儲存中消失”

對於服務發現,我們像許多人一樣使用 consul。但我們也將其鍵值用於整體的藍綠色佈局。它儲存有關活動和非活動上游的信息,這些資訊在部署期間會改變位置。為此,編寫了與 KV 互動的部署服務。某個時刻,KV 的數據消失了。從記憶中恢復,但有一些錯誤。結果,在上傳過程中,上游負載分配不均,並且由於後端CPU過載而導致我們收到許多502錯誤。因此,我們從 consul KV 遷移到 postgres,從那裡刪除它們不再那麼容易。  

結論:

  • 未經任何授權的服務不應包含對網站運作至關重要的資料。例如,如果您在 ES 中沒有授權,那麼最好在不需要的地方拒絕網路層級的訪問,只保留必要的,並設定 action.delta_requires_name: true。
  • 提前練習您的備份和復原機制。例如,提前製作一個可以備份和還原的腳本(例如Python)。

第一名-《不明顯的船長》 

在某些時候,我們注意到在後端有 10 多台伺服器的情況下,nginx 上游的負載分佈不均勻。由於輪詢方式是按順序從第一個上游發送請求到最後一個上游,並且每次nginx 重新加載都會重新開始,所以第一個上游總是比其他上游收到更多的請求,導致它們的工作速度變慢,整個站點受到影響。隨著流量的增加,這一點變得越來越明顯。簡單地更新 nginx 來啟用隨機是行不通的——我們需要重做一堆在 1 版本上沒有成功的 lua 程式碼(當時)。我們必須修補 nginx 1.15,引入隨機支援。這解決了問題。該錯誤贏得了“非顯而易見性隊長”類別。

結論:

探索這個錯誤是非常有趣和令人興奮的)。 

  • 組織您的監控,以便幫助您快速發現此類波動。例如,您可以使用ELK來監控每個upstream的每個後端的rps,從nginx的角度監控它們的回應時間。在本例中,這幫助我們識別了問題。 

因此,透過更謹慎地對待所做的事情,大多數失敗都是可以避免的。我們必須永遠記住墨菲定律: 任何可能出錯的事情都會出錯 並基於它構建組件。 

來源: www.habr.com

添加評論