(譯)面向性能的微服務

phgo9760 8年前發布 | 21K 次閱讀 微服務 軟件架構

 

摘要:從性能響應延遲的角度解讀微服務帶來的影響,并提出了幾個保證服務低延遲的建議。

概述

微服務是目前的一個熱門詞匯。它是原創的還是基于最佳實踐產生的?雖然在實施微服務的過程中有一些缺點,但這些缺點能被克服么?

組件可測試性和穩定性

一旦你組裝好了一個大系統,那么幾乎不可能監測到系統的最大延遲來自哪里。你可以監測到平均的延遲和吞吐量,但為了達到穩定的延遲,需要去分析系統的關鍵部分。這正是一個由簡單組件構成并且可以獨立運行和測試的系統可以幫到你的地方,它能幫你實現系統端到端的延遲穩定性。

UNIX 哲學

微服務中的許多關鍵概念已經在分布式系統中使用多年了。

它與 Unix哲學 有很多共同之處。

引用 Mike Gancarz 總結的這些原則,如下所示:

  • 小即是美。
  • 一個程序只做好一件事。
  • 盡可能早地創建原型
  • 可移植性比效率更重要。
  • 數據應該保存為文本文件。
  • 盡可能地榨取軟件的全部價值。
  • 使用shell腳本來提高效率和可移植性。
  • 避免使用可定制性低下的用戶界面。
  • 所有程序都是數據的過濾器。

微服務 即是把UNIX哲學應用到分布式系統。

微服務架構哲學與UNIX哲學中“一次做好一件事”本質上是相同的。它描述如下:

  • 服務小且細粒度的,完成單一功能。
  • 企業文化應擁抱部署和測試自動化。這減輕了管理與運維負擔。
  • 文化和設計原則應接受失敗和錯誤,類似于高容錯性系統。
  • 每個服務都是有彈性的,易恢復的,可組合的,最小化且完備的。

使用微服務架構有一些 缺點

  • 服務帶來信息屏障。
  • 該架構引入了額外的復雜性和需要處理的新問題,如網絡延遲、消息格式、負載均衡和容錯,忽略其中任何一點都屬于對“分布式計算的誤解”。
  • 測試和部署變得更復雜了。
  • 單體應用的復雜性僅僅轉移到了服務的網狀分布中,但是依然存在。
  • 過于細粒度的微服務已經被批評是反模式。

我們能得到單體應用和微服務都有的最佳特性嗎?還是只能二選一?難道我們不該使用最適合我們問題的方法么?微服務的關鍵方面之一是控制應用的部署。在哪些情況下,我們應該把一個組件部署為一個單體應用或微服務,這樣做最有意義。

對于超微服務的建議替代方案包括:

  • 將功能打包為一個庫而非服務。
  • 和其他功能組合產生一個更有實質意義和有用的服務。
  • 重構系統,將功能放在其他服務里或者重新設計系統。

我們怎樣才能兩全其美?讓組件可組合

如果你的組件是可組合的,那么其大小就總是合適的。你可以按需把它們組合成一個服務集,或者全部組成一個服務。

這點對于測試和調試特別重要。你需要知道一組組件在隔離基礎設施的情況下如何協同工作。為方便單元測試,你可能想要讓所有組件運行在一個線程里并且可以直接相互調用。這樣的測試不會比測試單體應用組件更復雜,你可以單步調試你的代碼,從一個組件到另一個組件看看到底發生了什么。

一旦你的組件在沒有基礎設施的情況下協作正常,接下來需要測試它們如何和基礎設施協同。

讓你的基礎設施符合應用對性能的需求

低延遲交易系統是一種分布式系統,并且它們也有非常嚴格的延遲需求。大多數交易系統被設計為高度延遲敏感的,它對速度的要求遠超你所能直接看見的。在Java領域,一個交易系統要求99%甚或99.9%的耗時低于100微秒的情況并不少見。這可以使用像Java這樣的高級語言在商用硬件上實現。

實現低延遲的關鍵是:

  • 用于消息和日志的低延遲基礎設施。理想情況下,對于短消息大約1微秒。
  • 最小網絡跳數。
  • 一個高水平的真實生產負載再現能力,這樣你就能研究99%(最差的1%)或99.9%(最差的0.1%)的延遲情況。
  • 將每個CPU核心視為運行一個特定的任務或服務,并使用它自己的緩存數據和代碼。焦點在于應用在CPU核心間的分布(而非計算機之間)。

你的二級高速緩存一致性總線是高性能服務之間的消息通道。

你可以在兩個不同的CPU核上對同樣的數據執行CAS操作,這樣一個線程可以很快感知到由其他線程設置的值,其往返時間在Sandy Bridge的處理器上不超過50納秒,而在新一代型號上會更短。

Java領域中低延遲的基礎設施的例子

  • Aeron 一個可靠的UDP傳輸組件。
  • Chronicle Queue 一個用于消息和日志的持久化隊列。

這些傳輸組件在處理負載均衡和故障轉移方面有各有不同的優勢。

使消息格式可配置

對于消息格式有許多互相矛盾的考量。你想要:

  • 對人友好易讀,以便你可以驗證消息不止表現正常,而且行為符合你的期望。我常常感到驚訝能從導出的存儲文件和消息日志中發現了如此多的問題。
  • 對機器友好的高效二進制格式。
  • schema改變的靈活性。靈活性意味著增加冗余,所以軟件可以應對未來的字段新增、刪除和數據類型變化。如果你不需要這些,這種冗余就是浪費。

理想情況下,你可以在測試或部署時選擇最佳選項。

一些能讓你寫時改變格式并適合你需求的序列化庫的例子有:

  • Jackson Speaming API 支持JSON、XML、CSV、CBOR(一種二進制格式)。
  • Chronicle Wire 支持將對象序列化為YAML,還有許多不同形式的二進制YAML、JSON、CSV、原始數據。

我發現 YAML 相比JSON更好用,它的語法設計更簡潔而且易讀。不像JSON是另一門語言的子集,它對數據類型、注釋、二進制內容和消息分隔符的支持很自然。

總結

我覺得有很多關于如何使用微服務的好想法,而很多圍繞它們的批評是針對該如何去實施落地的,然而我相信這些問題都是可以解決的。

來自: http://mindwind.me/blog/2016/04/18/譯-面向性能的微服務.html

 本文由用戶 phgo9760 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!