實時和接近實時應用開發之間的差異是微乎其微的,但每個人都會遭遇應用程序在構建和運行上的延遲。
隨著微服務的出現,構建云應用的最常見方法包括拆分每個組件,使其在單獨的環境中運行。這種方法從維護,可擴展性和開發的角度來看是理想的,但卻會降低單個事務的處理速度。
開發人員可以為那些需要快速處理的工作負載構建延遲在100毫秒內的實時應用,和幾秒鐘內的接近實時應用程序。接近實時對于許多應用來說已經足夠快了,但對于金融機構或媒體公司中運行的應用來說則可能太慢。在本文中,我們將探討如何對一個在AWS上運行的博客平臺進行實時應用的開發。
從用戶獲取輸入
當一個用戶創建一個新的帖子時,會通過一個HTML表單提交,然后通知后端應用有新的內容要處理和顯示。該應用程序可能還需要做一些文本分析,識別出與帖子關聯的圖片類型,然后自動發布到社交媒體。
將應用劃分為單獨的幾個部分以使其可網絡擴展,以便數百萬用戶可以同時發帖。當用戶點擊Submit時,平臺立即保存內容并通知多個服務。在實時應用開發中,這被稱為一個event。
監聽者或事件模式
事件驅動應用程序的使用正變得越來越普遍。隨著Node.js的普及,更多的開發人員正在學習event emitters的概念。在Node.js中,許多對象在完成任務后會立即通知一部分代碼。這些代碼塊就是所謂的listeners;開發人員使用監聽器的這種模式與使用Amazon Simple Queue Service(SQS),Amazon Simple Notification Service(SNS)或Amazon Kinesis的應用程序非常相似。
event.on('ready', postToTwitter);
event.on('ready', postToFacebook);
event.on('ready', postToSnapchat);
event.on('ready', addImage); event.trigger('ready', articleData);
Batch processing with Amazon SQS
使用亞馬遜SQS進行批處理
大多數開發人員都是用異步的方式來處理事件,這有助于應用的可擴展,但卻制造了額外的管理上的挑戰。在該博客平臺上,如果設置了異步過程來閱讀和發布故事,整個過程需要幾乎立即發生。撰寫和提交帖子的博主不想等著看到自己的帖子發布。在瀏覽器重新加載時,有一定的延遲空間,但是許多用戶不能容忍任何超過500毫秒(ms)響應的操作。
IT團隊可能會遇到實時應用開發延遲。例如,如果一個事件傳遞到SQS,在讀取之前會有一個自動延遲——從100毫秒到幾秒鐘。SQS專為批處理而設計,這有助于異步操作的處理,但卻難以處理實時事件。更糟糕的是,如果后端系統沒有跟上SQS請求,則可能在處理消息前可能有一個延遲的延遲。
使用Amazon SNS來觸發多操作
與Amazon Kinesis類似,Amazon SNS專為近實時事件處理而設計。它將輸入與各個處理節點分離。但是,與Kinesis不同,SNS被設計為基于一個事件觸發多個操作。在該博客平臺,一個開發人員可以擁有一個SNS Topic,即Post Created。多個AWS Lambda函數可以訂閱該主題,一個發布到Twitter,一個發送到Facebook,另一個處理文檔以自動識別與其關聯的正確圖片。解耦發生在SNS內,因此當應用程序還需要發布到Snapchat時,在發布方面不需要更改任何代碼。另一個監聽器會附加到該SNS主題,以便在發生事件時通知Snapchat微服務。
SNS不構建一個隊列,它并行執行所有的事件。因此,Twitter,Facebook,Snapchat和圖像微服務都會同時接收通知。例如,SNS無需等待Twitter發布后再發到Facebook。
SNS還允許開發人員配置應用端點,以立即和定期重試,直到事件處理成功——或達到指定的嘗試次數。但是SNS的初始延遲可能會超過幾秒鐘,因此它不是完全實時的。
隊列vs.管道
Amazon SQS和Amazon Simple Workflow Service都提供隊列來解耦請求和處理服務。這個模式構建起來簡單,并且非常的可擴展。不幸的是,這也是一種最延遲管道的方式。隊列不是為提高速度而建;它們被構建為用于擴展——增加了至少100ms的延遲 - 即使這些隊列是空的,并且它們擴展的速度也不快。隊列具有等待資源變得可用的事件的積壓。如果應用不需要實時運行,尤其是與競價型實例相結合時,這可能非常有用。
但對于實時應用開發,像Amazon Kinesis這樣的管道更合適。與隊列不同,管道設計用于實時流處理。不是將項目添加到一個列表中,而是以流的形式發送。雖然項目仍可在流中積壓,但只有在出現問題時才會發生。隊列和管道都支持容錯和重試,但管道立即運行。
與SQS不同,消息的延遲可以達到幾百毫秒,Kinesis延遲只有幾十毫秒。使用Kinesis這樣的管道服務的最重要的原因是它直接與AWS Lambda集成。這不只是一個更快的隊列服務,它還是一個不同的設計模式。
使用Amazon Kinesis進行實時處理
Amazon Kinesis為實時處理提供了更好的選擇。雖然Kinesis類似于SQS,它不直接排隊,更像一個管道,允許開發人員將請求定向到一個或多個處理服務。雖然這些管道可以有積壓,但啟動延遲通常明顯小于隊列服務,并且事件可以在10ms內接收并準備就緒。
此外,Kinesis直接與Lambda連接,這允許服務實時動態擴展。當Auto Scaling組識別到一個SQS的待辦事項時,最多可能需要一個小時才能等到其他可用的資源,以減少延遲。使用Kinesis和Lambda,管道只是對每一個輸入到管道的事件觸發一個Lambda函數;不需要對資源進行配置,這意味著不會把時間浪費在啟動額外的彈性計算云實例。
其他事件也可以觸發Kinesis流,例如Amazon DynamoDB寫操作。在博客這個示例中,當最終用戶添加一個新帖子時,會直接添加到DynamoDB中,之后通過Kinesis Stream觸發一個Lambda函數。
將各種服務功能連接起來
事件和工作程序之間的連接可以造成10毫秒或10分鐘的延遲之差。對于計算密集型任務,SQS允許應用處理更長時間,正確處理超時事件并構建可能具有長啟動時間的自定義工作程序。這些任務需要一段時間來處理,因此來自SQS的額外的一兩秒延遲是可以容忍的。這些任務也可能運行起來很昂貴,因此如果這些類型的事件的延遲可以接受,開發人員應該考慮為工作進程選擇競價型實例。
開發人員可以將SNS與SQS結合使用,用于需要處理多個事件的進程。 SNS可以發送其他不需要實時發生的通知(電子郵件或短信)。請記住,運營商或電子郵件提供商的延遲總是會比SNS強加的延遲更長。
對于博客,開發人員將使用Amazon Kinesis來實時傳送到博客平臺。對于Twitter,Facebook和Snapchat消息,SNS將交付給Lambda函數。對于可能需要大量計算的圖像處理系統,開發人員可以添加另一個SNS監聽器,但將其傳遞給SQS隊列,以使用定制的長時間運行的進程來處理圖像處理相關的計算密集型工作負載。如果其他客戶端需要通過自定義的渠道接受通知,請設置額外的Kinesis流,以便這些可以實時發生,或添加監聽器到用于電子郵件,短信或其他近實時通知的SNS主題。
在所有情況下,傳輸介質都必須是實時處理或接近實時處理。這只取決于IT團隊需要多快來傳輸信息。