無服務器架構下的運維實踐
前言
在介紹運維之前,大家先來快速了解一下無服務器(serverless)的概念。由于筆者的實戰(zhàn)經(jīng)驗是在AWS平臺上,本文中出現(xiàn)的無服務器均指使用AWS Lambda構建的serverless應用。Serverless的特點是用戶無需預配置或管理服務器,只需要部署功能代碼,服務會在需要的時候執(zhí)行代碼并自動伸縮,從每天幾個請求到每秒數(shù)千個請求,輕松地實現(xiàn)FaaS(Function as a Service)。如下圖所示:
(圖片來自網(wǎng)絡)
在傳統(tǒng)的應用中,開發(fā)團隊除了需要編寫功能代碼,還要監(jiān)控實時負載,并相應地對應用進行伸縮,還要處理一些因非功能性故障導致的停機(硬盤、內(nèi)存等)。而無服務器架構則將開發(fā)團隊從服務器維護的工作中解放出來,繼而能更專注在功能代碼上(圖中的Function)。在實際的項目里,開發(fā)者只需將功能代碼打包上傳到AWS Lambda,再進行少量配置(環(huán)境變量,觸發(fā)條件,內(nèi)存,超時時間等)即可將應用/服務上線。
以上是無服務器架構的基本概念。接下來,筆者將從日志,指標,監(jiān)控及報警,災備這四個維度來介紹無服務器架構下的運維。
日志
默認情況下,應用運行時產(chǎn)生的日志會保存在應用服務器本機,在需要查看日志的時候,需要運維人員遠程登錄到這臺服務器獲取日志信息。這種方式操作起來稍顯繁瑣,而且當應用服務器的數(shù)量增多后,由于需要先找出產(chǎn)生錯誤信息的那臺服務器,會嚴重降低查找日志的效率。
一種解決辦法是ELK(ElasticSearch, Logstash, Kibana),這三個開源工具各司其職,Logstash負責日志的推送和轉換,ElasticSearch作為數(shù)據(jù)庫與搜索引擎,Kibana作為圖形界面。好處是搭建容易,良好的伸縮性,以及免費。但帶來的額外成本是,獨立出來的日志服務也需要做好全方位的監(jiān)控(應用狀態(tài),硬盤,網(wǎng)絡等),避免因為基礎服務的問題導致系統(tǒng)全面故障。
AWS無服務器架構中的日志是一個開箱即用的服務,所有日志自動采集到AWS CloudWatch Logs中,只要根據(jù)服務名稱找到對應的日志組,即可進行查詢搜索,不需要任何配置,也沒有任何維護成本。
指標
通常情況下,運維工作會包含采集線上應用的運行指標,來反映應用的健康狀況,故障率,性能,訪問量,訪問頻率等。這里以一個使用Spring Boot構建的API服務來舉例,Spring Boot中的Actuator扮演了采集指標的角色。默認配置下,對于每個API,Actuator會自動采集以下幾個指標:
- uri,例如/api/person/{id}
- method,例如GET或POST
- status,例如200或500
當然我們可以通過實現(xiàn)一些接口來擴展/自定義采集指標,這里就不展開了。有了指標數(shù)據(jù),還需要對應的報表或儀表盤工具,以便更好地查詢和展示,可以選擇像Prometheus,Grafana這樣的工具。
那么AWS無服務器架構是否提供了類似的指標采集呢?答案是肯定的,AWS CloudWatch Metrics自動采集了Lambda function的以下四個指標:
- Invocations(實際調用量)
- Errors
- Duration(執(zhí)行時間)
- Throttles(超過并行限制而被阻止的調用的數(shù)量)
Invocations和Errors取一段時間的總數(shù),結合二者可以得出應用的錯誤率,如下
Duration則通過取平均數(shù)來反映一段時間的性能表現(xiàn),在筆者的項目中Lambda function的耗時主要集中在SQL的查詢上,這個數(shù)字可以相應地反映技術人員對查詢優(yōu)化的效果。當然,在實際情況中,這些檢驗都可以在預發(fā)布環(huán)境下進行,這個例子只是為了方便理解。
在筆者目前的項目中,Throttle并未被使用到,默認的并發(fā)限制是1000/秒,而用量***的Lambda function的調用頻率也不過每分鐘150次,距離超限差得很遠,不過這一數(shù)據(jù)對于并發(fā)高的應用有很重要的意義。
除了開箱即用的幾個指標以外,還可以結合CloudWatch metrics的API,在相應的功能代碼中埋點,定制化采集指標。例如,對于一個Lambda function,代碼里三個子task,默認提供的Duration只能反映總體的運行效率,如果需要統(tǒng)計每個task的消耗,就需要用到AWS CloudWatch metrics API。
監(jiān)控&報警
監(jiān)控的意義在于全面了解應用的資源使用率,性能和運行情況,這些數(shù)據(jù)可以用來幫助團隊及時作出調整,保證應用程序順暢運行。這通常包括CPU使用率,數(shù)據(jù)傳輸,磁盤使用等。在突發(fā)狀況導致系統(tǒng)不可用的時候,團隊的響應速度,往往取決于監(jiān)控和報警的及時性,全面性和準確度。如果能在對歷史數(shù)據(jù)的分析之上對監(jiān)控系統(tǒng)進行合理的配置,團隊甚至能預測不好的事情將要發(fā)生,提前做好防范,未雨綢繆。
同上,這里還是以一個Spring Boot應用為例,在上一小節(jié)指標數(shù)據(jù)的采集中提到過Actuator,事實上Actuator除了可以記錄上面提到的指標,還可以用來收集監(jiān)控數(shù)據(jù)。這里我們只需要設置一個Spring Boot Admin應用,給需要進行監(jiān)控的應用加上Spring Boot Admin client配置,監(jiān)控數(shù)據(jù)就會通過Actuator暴露的API傳遞給Spring Boot Admin。
報警功能一般則要根據(jù)實際情況自行實現(xiàn)。Spring Boot Admin中實現(xiàn)了對Pagerduty,Slack等第三方工具的集成,如果只是需要簡單的郵件提醒,實現(xiàn)起來也不復雜,這里就不展開了。
隨著云上基礎設施的普及,上面提到的監(jiān)控和報警早已是各個平臺的標準配置,根本輪不到開發(fā)者去操心如何實現(xiàn)及維護,運營團隊可以把更多的精力放在配置優(yōu)化的工作中去。
AWS默認提供了非常完備的監(jiān)控數(shù)據(jù),也允許自定義監(jiān)控dashboard,通過把一系列重要的指標添加到創(chuàng)建好的dashboard中,應用的運行狀況一目了然。
前面已經(jīng)提到過,在出現(xiàn)錯誤,或性能底下時,根據(jù)某些關鍵指標的變動情況發(fā)送警告通知非常必要。筆者所在的項目的做法是使用AWS CloudWatch和AWS SNS提供的告警通知功能,只需要先選擇指標然后設定觸發(fā)閾值和檢查間隔時間即可,AWS SNS支持HTTP、SMS、Email等多種訂閱方式。下圖展示了如何設定當某個Lambda在過去5分鐘內(nèi)發(fā)生了5次以上錯誤的時候發(fā)送通知。
災難備份&恢復
在系統(tǒng)鏡像,構建工具還有容器技術越來越普及的今天,災難備份的意義很大程度上是為了有效保護重要數(shù)據(jù)。通常的做法是設定一些定期任務,將數(shù)據(jù)傳輸?shù)竭h端的災備中心,從物理上抵御不可抗災難。如果數(shù)據(jù)量過大,出現(xiàn)網(wǎng)絡傳輸效率跟不上的情況,可以參考AWS用卡車拉數(shù)據(jù)的解決辦法。
真正需要用到災難備份的情況在筆者有限的經(jīng)歷中還沒有發(fā)生過,但是如果不未雨綢繆,真正發(fā)生時的后果將難以設想。筆者項目中用到的AWS RDS默認啟用了以7天為周期的自動備份,這個配置可以手動調整也可以將配置寫入構建基礎設施的腳本中去。 如果災難真的發(fā)生,光有數(shù)據(jù)備份是不夠的,還需要能夠快速重建應用運行時的基礎設施。筆者所在的團隊(下文簡稱團隊)分別使用了AWS CloudFormation和Serverless framework,CloudFormation用來重建數(shù)據(jù)庫、網(wǎng)絡等基礎設施,Serverless framework用來重建Lambda function,在重建數(shù)據(jù)庫的時候,通過持續(xù)集成流水線,以環(huán)境變量的方式傳入最近一次數(shù)據(jù)備份快照的Id,15分鐘以內(nèi)即可重建一套產(chǎn)品環(huán)境。
總結
筆者所在的團隊是10個人左右的配置,采用結對編程的方式,3對pair,包含web端、業(yè)務層、數(shù)據(jù)層。從產(chǎn)品原型確定到***次上線(MVP)耗時30天,每周至少發(fā)布一次新版本,story的平均交付時間(cycle time,從需求確定到上線)為8天。這樣的速度也許不能算快,但是如果沒有Serverless架構在運維端提供的支持,我們想要在交付速度上有更高的突破會困難得多。
***來談一下成本,俗話說拋開商業(yè)化談技術都是耍流氓,大部分人看到一個強大易用的工具都會下意識里覺得開銷會很大。實際上并不是這樣,我們做了一個粗算,選用雙核CPU,8G內(nèi)存的M4型服務器,開銷是$72每月。dev,staging,prod三個環(huán)境都用同樣的配置就是$216每月,而實際上Lambda每個月的開銷包含所有環(huán)境在$20左右,需要注意的是Lambda的計費是根據(jù)使用量來的,我們的API訪問大約在150萬每月的量級??梢灶A見到當訪問達到一定數(shù)量的時候Lambda的開銷會和使用服務器的方案持平甚至更大,但是在量小的時候優(yōu)勢明顯。
得益于強大的AWS生態(tài),利用Lambda構建的無服務器應用經(jīng)過少量甚至無需任何配置,即可以極低的價格獲得完整的運維功能和體驗。與自己利用開源工具進行搭建的方式相比,研發(fā)團隊可以從繁瑣的運維工作——特別是基礎工程搭建——中解脫出來,更加專注于產(chǎn)品本身,極大的提高軟件交付速度,可用性、可靠性和可擴展性也相當有保障。換來的代價是更高的遷移成本,某些功能的不可定制化可能成為瓶頸,以及對底層實現(xiàn)原理的屏蔽也可能對開發(fā)者的學習和成長有影響。
【本文是51CTO專欄作者“ThoughtWorks”的原創(chuàng)稿件,微信公眾號:思特沃克,轉載請聯(lián)系原作者】