2019獨角獸企業重金招聘Python工程師標準>>>
首先我應該提到,“無服務器”技術肯定有服務器涉及。?我只是使用這個術語來描述這種方法和技術,它將任務處理和調度抽象為與服務器管理無關。?在 2012 年為 ReadWrite 撰寫的有關軟件和應用程序未來的文章中,我將“無服務器”描述如下。
?
短語“無服務器”并不意味著服務器不再涉及。?它只是意味著開發人員不再需要對它們有太多的關注。?計算資源被用作服務,而不必管理物理容量或限制。?服務提供商越來越多地承擔管理服務器,數據存儲和其他基礎設施資源的責任...無服務器架構允許開發人員將重點從服務器級別轉移到任務級別。?無服務器解決方案允許開發人員通過消除后端基礎架構的復雜性來專注于其應用程序或系統需要做什么。
?
在那篇文章的時候,“無服務器”這個術語并沒有受到好評,當時在 Hacker News 的評論中也可以看到。但隨著一些無服務器平臺的誕生和微服務和事件驅動架構發揮越來越重要地位,這些質疑很幸運的逐漸得到了消退。
?
無服務器架構使用場景示例
?
為了更好理解這個技術,最好基于一個實際使用場景的示例來討論,因此假設我們要使用無服務器管道來處理電子郵件以及檢測垃圾郵件。?它是事件驅動的,因為當電子郵件進來時,它將產生一系列的工作或功能,旨在專門操作該電子郵件。
?
在此管道中,您可能具有執行電子郵件中的文本,圖像,鏈接,郵件屬性和其他項目或嵌入對象的解析的任務。?每個項目或元素可能具有不同的處理要求,這又要求一個或多個單獨的任務以及甚至其自己的處理流水線或序列。?例如,可以跨越幾個不同的處理向量來分析圖像鏈接,以確定圖像的內容和真實性。?根據消息評分和結果(是否是垃圾郵件),將采取各種行動,這可能反過來涉及其他無服務器功能。
?
(點擊圖片可縮放)
?
無服務器架構分析
?
無服務器環境中的基本單位是任務或作業,它是圍繞特定工作負載處理的實例化和執行。?任務處理自從編程開始就存在,所以它也不是一個全新的事物。?但是考慮到這些工作負載處理的高度分布的性質和抽象的方式,因此跨過具體的實現層次,并有廣泛的理解是必要的。
?
同步與異步
?
雖然處理任務的性質 - 無論是同步還是異步 - 通常是一個平臺問題,但它也是在任務級別需要考慮的一個重要因素。?傳統的工作和作業處理系統在很大程度上是異步的,這意味著調用進程不保持與執行任務處理組件的持久連接。?作業將排隊,因此,它們可能不會立即運行。?調用函數和處理器之間唯一的特定連接將任務排隊等待運行。?(注意,某些平臺可以允許對任務獲得狀態,但是通過API調用而不是直接/持久連接)。
?
許多新的無服務器平臺允許同步處理,從而保持連接并且客戶端在功能正在處理時等待。?同步處理的優點是可以直接從處理平臺獲得結果,而在異步處理中,獲得結果必須作為獨立的調用來完成。?我將在平臺部分討論更多細節,雖然一般的規則是同步處理適用于輕量級函數(類似于API調用獲得天氣信息),而異步處理更多的涉及處理作業(音頻轉錄或作為小批量處理作業的一組事件的處理),以及啟動處理的應用/組件/功能不是處理結果的應用/組件/功能的地方。
?
無狀態
?
無論處理方法如何,開發微服務和/或無服務器功能的核心原則之一是每個服務或方法應被視為無狀態。(小編:無狀態也反復在在高可用架構群討論及分享中提及)。?無狀態是指每個任務是一個單獨且不同的處理請求,其包含足夠的信息來滿足該請求。?服務和方法不應存儲任何唯一的軟件配置或狀態。?任何配置數據都應來自方法外部,通常作為任務的一部分或通過平臺內的配置服務。?該方法應該僅用于其計算資源,僅用于處理單個工作負載。
?
另外,應當有明顯的開始狀態和結束狀態,并且服務或方法應以相同的方式處理每個任務。?借用一個?principles of clean code, bad code?—?and bad microservices and serverless functions? [1] 一文中的觀點,我們應該聚焦并使用單一責任原則(SRP)[2]?。?思考無服務器函數的一個好方法是每個函數應該有一個且只有一個維度或向量的變化。?換句話說,如果有多種方式可以擴展函數(例如,將檢查多個特征的圖像分析),則對于每個向量應當存在兩個或更多個不同的函數。
?
在我們使用的用例中,每個電子郵件是一個單獨的事件,因此每個電子郵件都有一個單獨的任務序列。?每個任務將承載為相應的任務或方法提供處理的數據。
?
短生命周期
?
無服務器功能也是短暫的 - 意味著它們持續有限的一段時間。?無服務器應用程序的基礎主要圍繞事件處理和為這些事件服務時發生的任務處理。?強大的容器技術的出現使得任務可以在分布式環境中處理,并且決定在運行時在何處運行。
?
換句話說,任務處理基本上變成容器處理,其中容器在任務的基礎上建立和移除。作為示例,電子郵件處理示例中的每個任務僅持續對特定電子郵件執行特定動作。?完成后,任務和容器應該終止。
?
可能存在需要持久或長時間運行的進程的情況,如實現應用服務器或API服務器,這些場景我們通常放在無服務器范例之外。?在大多數情況下,你覺得可能需要長時間運行的任務,很可能有辦法避免這種開銷。?例如,無服務器平臺,消息隊列或其他組件可能能夠適應任何路由需求。?同樣,計劃任務可能能夠提供定期狀態檢查或處理周期。這里的示例是整合和處理來自各種數量的IoT設備的流數據。?如果數據被收集在一個或多個隊列或數據庫中,則調度作業可以在周期性(和頻繁)基礎上運行,查看隊列中或數據庫中的數據,并啟動一個或多個子任務以執行每個數據的合并和處理片。
?
(點擊圖片可縮放)
?
注意,在實際處理場景中,容器可能不會在每個任務之后終止,主要是出于性能原因。?容器可以從任務持續到下一個任務,但是它們的狀態和存儲將被擦除和重置,使得每個任務或事件處理循環被隔離并且短周期的。
?
冪等
?
冪等是構建到微服務和無服務器函數的關鍵屬性(小編:在高可用架構群討論及分享中,這一術語也被反復提及)。?在基本級別,能夠運行重復的任務并獲得相同的結果。它也能夠使多個重復的請求具有與單個請求相同的效果。?這是第二個定義,對于任務以高度并發和異步方式操作時的設計至關重要。?在任何作業處理環境中,任務可能由于多種原因(服務器崩潰,資源限制,第三方服務超時,任務超時等)而無法完成。
?
在其他情況下,任務可以完成,但是可能已經調用了針對相同的重復處理請求。?這樣的一個示例是注冊消息的超時的隊列,因為任務可能仍然在處理請求(并且因此沒有及時刪除或取消保留消息)。?結果,隊列可能觸發對該消息的另一處理請求。
?
(點擊圖片可縮放)
?
如果只是簡單繼續處理這些任務 - 將其放在隊列上或將其寫入數據庫,可能會有不良影響,尤其是在事務情況下。?例如,會產生兩個重復的訂單。?這是最重要的,然后確保只有一個請求處理相同的任務。?正是由于這個原因,在無服務器平臺(如大多數其他處理領域)中,開發人員需要在處理之前和/或在寫入或輸出結果之前,執行重復任務的檢查。
?
(點擊圖片可縮放)
以一個開發者朋友的話來說,另一種思考方式是“想象一下,如果服務器崩潰,而任務正在中間處理并且任務被重試。?或者,如果它只是排隊或安排兩次。?你需要做什么,以確保你不會覆蓋數據,添加重復的事務,因為它可能會多次運行。” 因此在處理周期中,在適當點檢查和驗證,以確保尚未執行工作。
?
多語言編程(Polyglot)
?
Polyglot是指以多種語言編程。?在無服務器編程的情況下,它指的是以多種語言編寫和執行任務的能力。?雖然每個功能可能只是一種語言,正確的無服務器平臺應該能夠處理多種語言。?這意味著它還應該提供一個重要級別的代碼獨立性,使開發人員可以透明地工作,而不必關心操作系統和服務器級依賴關系。
?
多語言的優點是能夠在不同的任務中使用合適的工具。?或者,為對應的團隊使用適合他們使用的工具。?在實際情況中經常發生的是,如果你擁有一把錘子,你看到一切都像釘子。使用單一語言,常常會約束解決問題的方法。?開發人員可能艱難的適應那種語言的代碼包來完成他們的需要,而事實上,其他語言的其他庫也許可以更好地服務于目的。
?
為了計算貝葉斯統計或進行機器學習,您可能希望使用用C,C ++,Python或Java編寫的包。?同樣,與您合作的開發團隊可能精通特定的網絡爬行包,它是為特定語言編寫的(例如以Ruby編寫的Nokogiri)。?能夠利用這種知識和經驗可以消除開發周期,以及降低項目延遲或失敗的風險。
?
請注意,許多較新的無服務器平臺目前僅支持少數幾種語言,但我希望在今年內能夠快速改變。?(例如,IronWorker可以處理大多數常用語言和可執行代碼。)
?
兼容性
?
無服務器任務需要考慮兩個兼容性順序。?第一個是任務之間,第二個是版本之間。?當你分解任務時候,你需要強大的服務契約和組件之間的規范。?規范的API格式可以通過常用的身份驗證和傳輸協議解決部分問題,但是使用自定義函數和服務,開發人員仍然需要定義有意義且易于理解的輸入和輸出模式。
?
?
除了干凈的接口,開發人員需要解決版本控制需求。?例如,假設函數X在平臺內運行,并且它調用函數Y,如果函數Y已經被更新而沒有讓函數X知道并被正確設計,則它可能在處理時失敗或者它可能產生不正確的結果(或者它導致期望原始結果的任務中的下游故障)。
?
與代碼包一樣,無服務器任務中的更改和更新可以通過應用程序發布。?在代碼包的情況下,這些沖突可能會通過打包和編譯工具早期發現。?然而,使用微服務和無服務器編程,它可能只是通過運行服務(最好在測試或仿真環境),問題才會被發現。
?
這意味著,所有這些無狀態性和任務和服務獨立性,團隊需要注意不僅設計良好構建的接口,而且解決向后兼容性的意識。?一個幫助可以是在描述/版本化無服務器任務中使用語義版本[3]?。?它不是萬能的,但隨著這個版本化約定的傳播,它為可能正在使用您創建的任務的其他開發人員提供了一些基礎。
?
?
參考資源
?
-
https://blog.goyello.com/2013/01/21/top-9-principles-clean-code/
-
https://en.wikipedia.org/wiki/Single_responsibility_principle
-
http://semver.org/
-
本文英文原文:http://highscalability.com/blog/2017/1/30/part-1-of-thinking-serverlesshow-new-approaches-address-mode.html
?
https://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=2653548239&idx=1&sn=9202d4d708cfada26d9f9aa1c62aa3c2&chksm=813a7f57b64df6416b9893800a8557405a4505e77ffa5a384fa89e62080a83b131803c7b8a2e&scene=0&key=f813d0a51cab0633f0c54ce756dda54a20169aa6fd606e93640d86a028b100064a448f4d4114cce0cb46e0ac70cc14bf7271069f0f51d79a15ca426f906b70305c53acd8c19801f8c6c052a5a3595d44&ascene=7&uin=MTA4NDY0MzM2MA%3D%3D&devicetype=android-23&version=26050433&nettype=cmnet&abtest_cookie=AQABAAgAAQBGhh4AAAA%3D&pass_ticket=3i02xv%2Bfw9GaA3ePmRRfZAYo1tsLZjJdXU92%2FCpAlqLsmJd9JhrfIuAHQ5c5PDc4&wx_header=1