# Probot 的體系結構-我的 Slack 和 Messenger Bot 用于回答問題
> 原文: [http://highscalability.com/blog/2017/3/15/architecture-of-probot-my-slack-and-messenger-bot-for-answer.html](http://highscalability.com/blog/2017/3/15/architecture-of-probot-my-slack-and-messenger-bot-for-answer.html)

我編寫了一個東西。 稱為 [Probot](https://probot.us/) 。 Probot 是一種快速簡便的方法,可為您的會計和稅務問題提供高質量的答案。 Probot 將找到一位真正的現場專家來回答您的問題并處理所有細節。 您可以通過 Facebook Messenger,Slack 或 Web 回答問題。 答案最低為 10 美元。 那就是球場。
在這種新的機器人時代似乎很自然,不是嗎? 我還是這么想。 沒有那么多(到目前為止),但是稍后會更多。
我認為 Probot 足夠有趣,因為它是一個程序員(我)如何使用當今的基礎架構可以完成很多工作的一個很好的例子。
所有這些新穎的云/無服務器/服務內容實際上都可以工作。 我能夠以相對可擴展,可用和負擔得起的方式對跨越 Messenger,Slack 和 Web 的系統進行編程,同時只需最少的開發。
過去,擔心 VPS 限制,開車前往 Colo 站點檢查有問題的服務器,甚至擔心容器/虛擬機群集自動擴展的日子已經一去不復返了。 至少對于許多用例而言。
多年的編程經驗和撰寫此博客無法避免犯錯誤。 在此過程中,我犯了很多愚蠢的愚蠢錯誤,但是我對最終的想法感到滿意。
這是 Probot 的工作方式。...
## 平臺
* 無服務器:AWS Lambda
* Web 主機:S3 上的靜態站點,單頁應用程序
* 語言:Javascript /節點
* API:API 網關
* DNS:Route53
* CDN:CloudFront
* 用戶登錄名: [Cognito](https://github.com/aws/amazon-cognito-identity-js)
* SSL 證書:讓我們加密
* 服務器:EC2,t2.small,Ubuntu
* 信息庫:GitHub
* 源代碼控制:Git
* 付款:貝寶
* Slackbot: [Botkit](https://github.com/howdyai/botkit)
* 隊列:SQS
* 備份:AWS Data Pipeline,每周將生產數據保存到 S3
* 數據庫:DynamoDB
* 節點進程管理器: [PM2](http://pm2.keymetrics.io/)
* SSL 終止:Nginx
* Web 框架:jQuery,Bootstrap
* 開發平臺:MacBook Air
* 本地測試 Web 服務器: [http 服務器](https://www.npmjs.com/package/http-server)
* 測試隧道: [Ngrok](https://ngrok.com/)
* SQS 輪詢: [平方消費](https://www.npmjs.com/package/sqs-consumer)
* 日志記錄:CloudWatch
## 起源故事
我的妻子 [琳達·科爾曼](http://www.possibility.com/Lgc/AcctRes.html) 是一名注冊代理,這意味著她是一位了不起的稅務會計師,并且在會計專家中都很有經驗。 她有一個網站 [BizTaxTalk](http://biztaxtalk.com/) ,在這里她為人們的稅收問題提供了很好的答案:免費。 她有很多問題。 有真正問題的人需要幫助,很難找到可以回答這類問題的人。
您可能會想像它變得勢不可擋。 她最終不得不放棄 BizTaxTalk,因為它占用了她太多的時間。
我想為什么不通過它獲利? 琳達可以回答人們的問題并獲得報酬。 雙贏。 我知道這種類型的質量檢查網站不是新手,但機器人程序是解決此問題的新方式,應該是處理此類信息交換的一種很好的方式。 使用文本可以非常方便地異步處理問答流程。
因此,Probot 建立了一個雙面市場。 有問題的用戶(例如約會服務)與能夠回答其問題的主題專家(稱為 Pro)相匹配。 Probot 處理消息的匹配,計費和協調。
盡管我顯然會從稅務和會計問題入手,但最終可以吸引更多的主題專家,并且話題數目也有所增加。 這就是我編寫代碼的方式。 它可以輕松擴展以處理新主題和問題樹。
這就是我要建立的。
## 架構
*繼續閱讀* 。 這是一遍又一遍關于 HS 的建議。 那就是我所做的。 我有在 Node 上使用最出色的 [Botkit](https://github.com/howdyai/botkit) 制作 Slackbots 的經驗,因此我就從這里開始。
我也有使用 AWS Lambda 來開發 Alexa 技能的經驗,并且不想管理任何東西-多年玩 sysadmin 就足夠了-所以我選擇了 AWS。 如果 Google Cloud Functions 是 GA,那么我可能會選擇使用 Google Cloud。
以下是我們將介紹的所有主題:
* ProbotService Lambda 函數
* Slackbot
* Messengerbot
* 網站
* PayPal 集成
* 測試
* 采納
* 獲得的經驗教訓
## ProbotService Lambda 函數
這是實現 Probot Service 后端的 AWS Lambda 函數。 大多。 這也是我許多愚蠢錯誤的根源。 讓我解釋。
我為 Slack 編寫的第一個 Probot 機器人用于 Slack,并且取得了一些進步,但是 Slackbot 在 EC2 實例上的 Ubuntu 進程中運行。
我犯的一個大錯誤是不首先使用 API??。 我的大部分職業生涯都是建立另一種消息傳遞協議。 是我做的嗎? 當然不是。
我對所有機器人邏輯進行了編程,因此可以直接在 Slackbot 流程中執行。 這是可能的,因為 AWS 有一個漂亮的 Node API,可以訪問 DynamoDB,SQS,Lambda 和其他 AWS 服務。 因此,所有 AWS 訪問都直接用 javascript 編碼。 效果很好。 沒問題
當我需要制作 Web 客戶端時出現了問題。 嗯,在相同的代碼也幾乎可以在 Web 客戶端中正常工作的意義上,這并不是問題。 真酷。 因此,我浪費了很多時間來建立 Slack 和 Web 客戶端可以共享的通用庫。 但是我對我的數據庫訪問代碼可以在 Web 上看到的想法感到非常不舒服。 對于 Intranet 服務,我不會擔心,但按我的喜好顯示數據結構的攻擊面太大了。
我犯的另一個大錯誤,也與不首先創建 API 有關,是因為人們對 DynamoDB 在數據庫更改時將新值和舊值傳遞給 Lambda 函數的能力深感興趣。 我所做的是像狀態機一樣觸發邏輯。 例如,如果舊記錄說狀態為 PENDING,而新狀態為 ASSIGNED,則觸發 PENDING 到 ASSIGNED 的轉換。 它有效,我認為它真的很聰明。 問題在于,面對許多無法移動狀態但仍觸發 Lambda 函數的操作,它過于脆弱。
解決這兩個問題的方法是構建一個 API,我使用 Lambda 做到了。 我選擇不使用 API??網關,因為直接從 Node 調用 Lambda 函數非常容易。 API 網關會增加延遲,復雜性和成本。 也很難使用。 從 HTTP 請求轉換參數并將其映射到 Lambda 調用對于任何復雜的事情來說都是非常接近魔術的過程。 回復相同(反方向)。 如果將來需要使用公共 API,則可以重新考慮該決定,但是直接使用 Lambda 是很簡單的。 必須更改所有 Slack 和 Web 代碼才能使用新的 API。 真痛苦
### 如何構建無服務器 API?
下一個決定是如何構建 API? 每個 API 調用都映射到一個單獨的函數嗎? 還是將功能歸為一個入口? 還是可能有多個入口點?
我選擇了一個入口點。 之所以采用這種方法,是因為我不想使用框架來管理 Lambda。 我想知道所有東西如何連接在一起,框架包含很多魔術。 因此,我創建了一個 zip 文件,并使用 AWS 控制臺將其上傳到 Production 或 Test。 將來,我將使其自動化,但現在可以正常使用。
使用單個入口點時的一個問題是如何復用函數調用? 我選擇模仿 [JSON-RPC](http://www.jsonrpc.org/specification) ,這些在過去我已成功用于服務器應用程序。
請求包裝在 JSON-RPC 負載中。 使用“ method”屬性指定要調用的方法,并使用“ params”屬性傳遞任何參數。 ProbotService index.js 文件解壓縮 JSON-RPC 請求并調用正確的方法。 看起來像:
> 如果(request.method ===“ giveAnswerToUser”){
>
> var op = new QuestionImpl(appcfg);
>
> op.giveAnswerToUser(request.params,function(error,data){
>
> 返回 sendResponse(錯誤,數據,請求,回調);
>
> })
>
> }
我以標準的 RPC 方式創建了一個名為 ProbotService 的存根對象,該對象使從客戶端代碼調用 Lambda 函數變得更加容易。 例如: *service.getQuestion(id,callback)*格式化正確的 JSON-RPC 結構,調用正確的 Lambda 函數,并在返回回復時調用回調。
### 共享代碼
我選擇不在 Facebook Messenger 機器人代碼中調用 ProbotService Lambda。 而是,服務庫代碼與 Messenger 代碼打包在一起并直接調用。 這是一種代碼共享方法。 在 ProbotService 和 Facebook Messenger 之間共享相同的基礎代碼。
原因是 Facebook Messenger Webhook 調用通過 API 網關調用,該 API 網關調用 Lambda 函數。 使用 ProbotService 還會調用 Lambda 函數。 因此,將在另一個 Lambda 函數中調用 Lambda 函數。 這可以正常工作,但最壞的情況是延遲比我希望用戶體驗到的要高,因此我選擇通過共享代碼來刪除躍點。 我仍然不確定這是否是最好的決定,但是它確實有效,并且 Messenger 機器人的響應時間讓人感覺很快。
由于 Slackbot 是在自己的進程中運行,因此沒有多余的躍點,因此使用 ProbotService 是正確的選擇。 Web 客戶端代碼中也使用了 ProbotService,因此不會泄漏任何內部詳細信息。
### ProbotService API
以下是 Probot API 中的一些功能。 我不會使用 Swagger 之類的文檔。
* updateFromPaypalWebhook
* getQuestion
* GiveAnswerToUser
* GiveAnswerToPro
* askQuestionOfUser
* cancelQuestion
* acceptProAnswer
## Slackbot

### 機器人樣式
對機器人進行編程時,您必須做出的決定之一是:您想要對話式 AI 風格機器人還是結構化命令驅動風格機器人。
我采用了結構化的命令驅動方法。 用戶選擇一個問題主題,然后機器人將引導他們通過問題樹收集 Pro 回答此類問題所需的數據。 例如,對于納稅申報表,您需要知道它是哪一年,是個人還是公司,是否是公司的實體類型(合伙企業,C-Corp 等),等等。
AI 風格很性感,但如果那不是您的事,那真的很難做得很好。 因此,我想出了一種描述與用戶的對話的方法,該對話可以針對每個問題進行定制。 實際上,我提出了幾種不同的對話描述符解決方案,但我對其中任何一個都不滿意。 這是 Slack 的樣子:
> probot.machine.add(“ ask-return-type”,{
>
> 操作:probot.machine.askFromOptions,
>
> 選項:[“個人”,“業務”],
>
> 顯示:[“個人”,“業務”],
>
> 問題:“在回答稅收問題時,幫助您的專家了解報稅種類會很有幫助。”,
>
> sayOnAccept:“知道了。您選擇了 _ {response} _ 選項。”,
>
> 答案:功能(機器,cmd,答案,下一個){
>
> console.log(“ ask-return-type:answer:” + answer);
>
> probot.dto.setReturnType(answer);
>
> if(answer ===“ individual”)
>
> 的 cmd.next =“詢問稅年”;
>
> 其他
>
> cmd.next =“詢問實體類型”;
>
> next(null);
>
> },
>
> ???})
我對 Messenger 采取了完全不同的方向。 我也很討厭這種方式。
### 松弛主機
使用 Slack 時,webhooks 可以用于實現 Slack 命令,但是對話風格要求代碼在流程上下文中運行。 因此,我建立了一個沒有任何冗余的小型 EC2 實例。 由于我不希望用戶在 Slack 上不斷與 Probot 互動,因此我認為停工時間不會造成任何傷害。 所有狀態都將在 DynamoDB 中,因此不會丟失任何內容。 彈性 IP 用于訪問主機。
*保持簡單,不要使事情復雜化* 。 關于 HS 的另一個很長的課程。 如果有人最終使用您的系統,則可以稍后再做所有花哨的工作。
[PM2](http://pm2.keymetrics.io/) 是出色的 Node 進程管理器,用于在 Slack 進程死后重新啟動它。 PM2 還管理日志并執行其他一些精美的操作。 Route53 會 ping 通該過程,并在出現任何問題時向我發送電子郵件。 夠好了。
Botkit 完成了許多繁重的工作。 它處理程序和 Slack 之間的所有協議工作,同時為身份驗證,進行對話之類的事情提供了許多方便的抽象方法。
### 互動消息
在我完全完成 Slackbot 實現之后,Slack 引入了用戶使用按鈕而不是輸入文本進行選擇的功能。 由于我還沒有發布任何東西,所以是時候進行更改了。 這些按鈕確實使用戶更容易。 問題在于按鈕需要您的進程實現 HTTPS Webhook,以便 Slack 可以通過按下哪個按鈕的信息回調到您的進程中。 這是開發流程的重大變化。 松弛的開發是很好的,以前也包含在內。 現在,您的機器人程序必須可以通過 URL 從外部進行訪問。
在 EC2 中的生產機器上還不錯。 我使用 Nginx 終止 SSL,并將請求傳遞給 Slackbot 進程。 這需要使用我使用“加密”的 SSL 證書。 由于必須定期更新,這是維護上的麻煩,但它們是免費的,因此請選擇毒藥。
讓 Slack 通過 Comcast 路由器訪問在筆記本電腦上運行的進程并不容易。 我在各種解決方案上浪費了很多時間。 很多時間。 我最終屈服了,并向 Ngrok 支付了他們的隧道服務。 像魅力一樣工作。 花錢。 Slack 應該考慮能夠完全在無服務器上工作。 那將是一個更清潔的解決方案。
### 身份和驗證
Probot 沒有嘗試創建 Slack,Messenger 和網絡上常見的用戶。 每個都使用其環境固有的身份機制。 對于 Slack,這意味著使用 Slack 分配的團隊 ID 和用戶 ID。 Probot 詢問用戶的姓名和電子郵件地址,但不打擾身份和身份驗證。 Slack 處理所有這些。
### 數據庫
Slack 提供了自己的數據庫抽象,用于存儲團隊,用戶和渠道。 當 Probot 使用 DynamoDB 時,我創建了一個簡單的 [適配器](https://github.com/ToddHoff/botkit-storage-dynamodb) ,該適配器允許 Slack 將其數據存儲在 DynamoDB 中。
通常的做法是在 Slack 的數據結構中插入自己的屬性。 因此,用戶數據存儲在 Slack 的用戶對象中。
### 從 Pro 向用戶發送消息
與用戶對話時,使用 Botkit 發送消息就像 *bot.say(“某些字符串”)* 一樣容易。 在以后的某個時間以異步方式向用戶發送消息并非易事。 例如,當專業人士為用戶提供答案或想要提出問題時,必須向用戶提供消息。
我可以弄清楚如何使異步消息傳遞起作用的唯一方法:
* 當團隊連接到 Probot 時,將 Botkit 機器人 對象存儲在內存中。 需要機器人對象才能向用戶發送消息。
* 每個用戶都與一個團隊相關聯,因此當出現消息時,可以找到正確的機器人對象。
* 來自 Pro 的所有消息都排隊到 AWS SQS。
* Slackbot 進程使用一個名為 sqs-consumer 的漂亮軟件包來輪詢 SQS 以獲取消息。
* 使用 bot 對象將消息發送給用戶。
* 用戶調用@probot 進行對話以處理消息。 該消息可能是答案,問題或狀態更新。 用戶可以對答案進行評分并發表評論。 他們還可以拒絕答案,這意味著用戶無需付費。 我不希望別人覺得自己被人扯了。 這是 Pro 承擔的風險。 盡管我不這樣做,但匹配算法可以在進行匹配時利用評分數據。
Sqs 消費者是為什么 Node 對開發人員如此高效的一個示例。 是的,javascript 很爛。 是的,回調編程有點糟。 但是從字面上來看,我需要花五分鐘的時間思考*,我需要輪詢 SQS* 來找到一個好的 npm 可安裝軟件包并擁有有效的代碼。 Node 一直在發生這種情況。
## Messengerbot

Messenger 是與 Slack 完全不同的野獸。 盡管 Botkit 支持 Messenger,但我還是決定直接向 [Messenger API](https://developers.facebook.com/docs/messenger-platform/) 進行編碼,因為它比 Slack 簡單得多。 這是因為作為團隊協作工具,Slack 具有很多功能。 Slack 具有用于與團隊,渠道,用戶,組,權限,功能等一起使用的各種 API。
使用 Facebook Messenger 時,將通過 Webhook 接收消息,并使用 HTTP 調用發送格式化的消息。 那幾乎就是您所能做的。 因此,Messenger 機器人可以完全在 Lambda 函數上運行。 如果您不關心團隊的所有方面,那么 Messenger 可能是一個更好的起點。
回顧一下,這是 和您所知道的 咬住我的地方。 Probot 不是團隊工具。 它與用戶進行一對一的交互,因此所有開銷都沒有任何好處,并且需要很長時間才能解決。 另一方面,Slack 的員工非常樂于與他們合作。 如果您有問題,那么有技術印章的真實人將為您提供一個很好的答案。 你可以想象?
實際上,我一直在考慮取消對 Slack 的支持,因為沒有人在使用它,而且 EC2 實例每月都要花我很多錢。 無服務器可為此類工作量贏得大量時間。 使用 Lambda,我只在人們實際使用 Probot 時付款。
### 簡化 Messenger
一件事立即變得很清楚,那就是必須簡化 Probot 才能在 Messenger 上正常工作。 使用 Slack 時,復雜的用戶交互變得自然。 在 Messenger 上,復雜的問題樹根本不起作用。
我所做的一個簡化是減少用戶可以從 Pro 請求的答案類型。 在 Slack 上,用戶可以要求以不同的價格快速,完整或深入地回答問題。 添加這一額外的交互層會使整個過程陷入困境,因此,使用 Messenger 時,Pro 可以提供的唯一可能的答案類型是 Quick 類型。
無法將簡短的文本字符串發送到 Messenger 進一步增強了簡短和簡單的需求。 松弛搭配文字很棒。 您可以吐出文本頁面沒問題。 有了 Messenger,您可以發送的最大尺寸。 長字符串必須分成大塊,而不是美觀。
另一個簡化是 Messenger 上,用戶一次只能回答一個未解決的問題。 在網絡和 Slack 上,用戶可以一次打開多個問題。 回想起來,這可能也是我應該構建 Slack 的方式。 通過聊天界面管理多個懸而未決的問題很復雜。
這是關于 HS 的又一個很長的課程: 保持簡單愚蠢 。 說起來容易做起來難。
### Facebook Messenger Webhook
在 Messenger 機器人配置中,指定了一個 Webhook,Facebook 會使用用戶相關事件進行調用。 Webhook 使用綁定到 Lambda 函數的 API 網關實現。 Lambda 函數是使用共享代碼方法實現的。 它包含了所需的所有源代碼,而不是調用其他服務。
Lambda index.js 文件中的啟動代碼負責解析來自 Facebook 的消息并正確分發。 在處理每條消息之前, startSession 被稱為發送者 ID,它被用作用戶 ID。 startSession 獲取用戶記錄(如果存在),如果不存在,則請求該用戶的配置文件并創建用戶記錄。 如果用戶記錄中已有問題 ID,則會從數據庫中檢索該問題,并創建該問題的狀態機對象。 傳入消息是狀態機上的一個事件,它驅動消息的處理方式。
使用 startSession 來處理用戶消息所需的所有數據均已就緒,因此無需任何較低級別的代碼。 同樣,在處理完一條消息后,將檢查臟標志,并且如果更改了對象,則會在數據庫中自動對其進行更新。 我發現這種風格使使用 Lambda 函數更加簡潔。 較低級別的代碼永遠不必擔心狀態管理。
這是 Slack 比 Facebook 更具優勢的領域。 Lambda 函數無法存儲狀態,因此必須激活每個狀態并隨每個請求將其鈍化。 使用 Slack 的狀態可以存儲在 Slackbot 進程中,盡管如果我要重做一遍,則可能不會將狀態保持在 Slack 中。 轉到數據庫并編輯記錄并在下一個請求中提取更改非常方便。 為了使這些更改在 Slackbot 中可見,必須重新啟動該過程。
Messenger 具有許多不同類型的消息:消息,回發,身份驗證,傳遞確認,消息讀取,帳戶鏈接等。 消息類型有幾種子類型:快速答復,文本,回聲,回執,已讀回執,鍵入,鍵入,等等。
通常,我唯一要注意的消息是與用戶的交互。 所有命令源均映射為通用請求格式,并饋入 Question 狀態機。 例如,當用戶點擊“回發”按鈕,“入門”按鈕,“持久”菜單或“結構化消息”時,發生回發事件。 我認為來自用戶的任何純文本輸入都是為了響應我之前提出的問題。 快速回復 只是用戶可點擊按鈕的另一種類型。
### Facebook 問題狀態機
所有問題都存儲在 DynamoDB 中。 每個問題都有一個屬性,用于指定問題所在的當前狀態。將消息標準化為通用請求格式后,將其應用于“問題”狀態機,該狀態機看起來像:
> var QuestionDto = require("./QuestionDto");function FacebookQuestionSm(appcfg, startState) {? console.log("FacebookQuestionSm:startState:" + startState);? this.startState = startState;? var self = this;? this.any = {? ? help: {? ? ? action: FacebookQuestionSm.sendHelp,? ? },? ? getstarted: {? ? ? action: FacebookQuestionSm.sendGetStarted,? ? },? ? settings: {? ? ? action: FacebookQuestionSm.sendSettings,? ? },? ? status: {? ? ? action: FacebookQuestionSm.sendStatus,? ? },? ...? this.states = {? ? start : {? ? ? on : {? ? ? ? accounting: {? ? ? ? ? forward: "ask_accounting_question"? ? ? ? },? ? ? ? ask_accounting_question: {? ? ? ? ? action: FacebookQuestionSm.createQuestion,? ? ? ? ? next: "ask_question",? ? ? ? ? data: { type: "accounting", msg: "Great choice, I see you want to ask an accounting question." }? ? ? ? },? ? ? ? ask_individual_tax_question: {? ? ? ? ? action: FacebookQuestionSm.createQuestion,? ? ? ? ? next: "ask_tax_year",? ? ? ? ? data: { type: "tax", returnType: "individual",?? ? ? ? ? ? ? ? ? msg: "Great choice, I see you want to ask a tax question for an individual."?? ? ? ? ? }? ? ? ? },? ? ? ? ask_business_tax_question: {? ? ? ? ? action: FacebookQuestionSm.createQuestion,? ? ? ? ? next: "ask_entity_type",? ? ? ? ? data: { type: "tax", returnType: "business",?? ? ? ? ? ? msg: "Great choice, I see you want to ask a business related tax question."?? ? ? ? ? }? ? ? ? }? ? ? }? ? },? ? ask_tax_year : {? ? ? action: FacebookQuestionSm.sendTaxYearQuestion,? ? ? on : {? ? ? ? text: {? ? ? ? ? verify: FacebookQuestionSm.verifyTaxYear,? ? ? ? ? action: FacebookQuestionSm.saveTaxYear,? ? ? ? ? next: "ask_question"? ? ? ? }? ? ? }? ? },
>
> ? ? ...
>
> }
>
> this.on = function(appcfg,userid,request,next){
>
> console.log(“ on:userid:” + userid +``“ request:” + JSON.stringify(request));
>
> }
上的 *方法接受請求并將其應用于狀態定義。 這可以正常工作,但是處理用戶可以與機器人進行交互的所有方式都會使代碼看起來有些駭人。*
### Identity and Authentication
與 Slack 一樣,Facebook 提供了專門用于 Messenger 的用戶 ID,而我只是使用該 ID。 它不是真實的 Facebook 用戶 ID,因此您不能使用 graph API 來獲取大量用戶信息。 該 ID 與問題一起存儲,因此可以將答復直接發送給用戶。
### Database
與 Slack 的 Facebook 數據庫 API 等效,因此用戶數據存儲在 DynamoDB 中 Facebook 特定的用戶表中。
## 網站

[Probot.us](https://probot.us/) 是 S3 上托管的單頁應用程序。 作為單頁應用程序,所有操作均使用 Slack 使用的相同 ProbotService API 完成。 使用 S3 的優點是我無需管理任何事情。 它是一個與其他網站非常相似的網站,因此我不會在此進行過多介紹,但有一些主題值得注意。
### 電子郵件崩潰
您是否曾經做過一些您最終不會做的事情,但還是成功了? 這是另一個浪費時間的大錯誤。 毫無疑問,我不太擅長制作網站。 我希望這可以解釋為什么我真正嘗試完全避免制造一個。
我所做的是通過電子郵件使所有 Pro 交互工作。 問題將通過電子郵件發送給專業人士。 專業人士會通過電子郵件答復并回答問題。 電子郵件中的關鍵字使它可以解析和提取數據。 用戶沒有注意到差異,因為他們仍然會使用 Slack 或 Messenger。
這是流程:Probot 向 Pro 發送了電子郵件。 例如,將問題分配給專業人士時,他們將收到一封包含該問題的電子郵件,有關用戶的信息以及將電子郵件映射回該問題所需的一些簿記屬性。 專業人士會回覆他們的回應,并確保將文字插入正確的位置,以便可以正確解析。 AWS 收到了 Pro 的回復并將其保存到 S3 中。 這導致了 Lambda 函數被調用。 該功能將解析電子郵件,提取所有數據,并相應地更新用戶。
盡管配置很麻煩,但實際上確實有效,并且編寫代碼很有趣。 只有我的測試專家討厭它。 只是討厭它。 當然,他們做到了,這對他們來說很糟糕。 因此,我最終制作了 Pro 儀表板,以管理我一直知道自己必須解決的所有 Pro 問題。 我還添加了一個收件箱,以便用戶可以在網絡上提問和管理問題。 同一網站還為 Slack 用戶充當著陸頁,以便他們可以將 bot 安裝到他們的團隊中。
### [HTG0 BC]
盡管我已經在 Golang 中使用了完整的用戶注冊系統,但我希望將所有內容保留在 Node 中。 我決定重試一下,而不是重新發明輪子。 我不想對用戶密碼的安全性負責,Cognito 可以處理所有這些。 使用起來很棘手,這里的有一些奇怪的問題要弄清楚。 示例代碼和文檔可能會更好。 但是我最終得到了所有典型的流程-注冊,忘記密碼,更改密碼,重新發送驗證碼,輸入驗證碼等。 這并不容易,但是似乎可以可靠地工作。
### 節點和瀏覽器之間共享代碼
這是我犯的另一個錯誤:我不打算在 Node 和瀏覽器之間共享代碼。 到我意識到可以共享很多代碼的時候,采用另一種模塊哲學已經太費力了。 我確實共享代碼,但是在包含導致在兩種情況下都不起作用的依賴項的代碼時,我必須非常小心。
## PayPal 集成
我選擇 PayPal 是因為我發現它們的 API 是可以理解的,其儀表板是可以使用的,并且其文檔是可以使用的。 支持速度很慢,但通常會有所幫助。
當用戶接受專業人士對其問題的回答時,付款狀態機將啟動。在 ProbotService 中,PayPal API 用于創建發票,該發票由 PayPal 發送到用戶的電子郵件地址。 通過 PayPal,您可以配置一個 Webhook 來使用發票相關事件。 Webhook 使用綁定到 Lambda 函數的 API 網關。
當 Lambda 函數接收發票事件時,它將在事情發生時通知用戶和 Pro。
* 松弛:通過前面描述的 SQS 機制通知用戶。 專業人士會收到一封電子郵件,告知他們應該前往儀表板了解詳細信息。 絕不會通過電子郵件發送任何敏感信息。
* Messenger:發短信給用戶。 請注意,要在上次聯系后 24 小時向用戶發送消息,您必須對機器人具有特殊權限。 這并不總是容易獲得的。 因此,如果您的機器人需要提前進行此類功能計劃。
* Web:向用戶發送電子郵件,并要求用戶登錄 Probot 以獲得其儀表板上的更多信息。
這花了一些時間才能開始工作。 如果未調用與 Webhook 關聯的 Lambda 函數,則很難理解問題所在。 絕對打開 A??PI 網關日志記錄。 您將需要它。
PayPal Lambda 函數使用與前面所述相同的代碼共享方法。 無需進行遠程 ProbotService 調用,而是直接調用代碼。
## 測試
這里沒什么好想的。
對于 API 網關,Lambda 和 DynamoDB,有所有版本的測試和生產版本。 根據配置在運行時選擇使用哪個。
該網站有測試和生產版本。 為了測試它們,我只使用所有功能。 使用 *aws s3* 命令行將文件從開發環境復制到 S3。 對于本地開發,將 http-server 用作 Web 服務器,并且可以通過 localhost 測試所有功能。
PayPal 具有測試和生產配置選項。 每個都分別指向測試和生產網絡掛鉤。 PayPal 具有在調用 Webhooks 時記錄的日志,這在調試時很有用。 不幸的是,事件不是實時發送的,因此您必須等待事件發送和日志出現。
對于 Slack,有一個單獨的機器人,用于測試和生產。 每個都分別指向測試和生產網絡掛鉤。 Messenger 也是一樣。 除了將測試版本和生產版本視為完全不同的漫游器之外,我沒有其他更清潔的方法。
對于本地開發,Slackbot 在開發計算機上運行。 Ngrok 用作隧道,因此 Slack 可以向該進程發送交互式消息。 使用網站的測試版本將測試機器人安裝到團隊中。 它具有正確的應用程序令牌,可以識別機器人的測試版本。 安裝測試機器人后,您可以通過 Slack 與該機器人對話。
對于本地開發測試,通過共享代碼使 Lambda 代碼變得更加容易。 唯一可以調用的外部服務是其他人的服務,而不是您自己的服務。 因此,要進行測試,根本不需要將代碼上傳到 Lambda。 Lambda 函數中使用的相同代碼可從可從命令行執行的腳本中調用。 為您 API 中的每個函數創建一個相應的腳本,并且可以在本地對其進行完全調試。
Messengerbot 的本地開發測試比較棘手,因為將消息發送到 bot 時,消息會顯示在 Messenger 中。 當您點擊按鈕時,回復將返回到您的測試網絡掛鉤。 據我所知,尚無干凈的方法可以以可單元測試的方式進行此操作。 我所做的是將 Bot 的測試版本安裝到 Messenger 中并記錄了用戶 ID。 在為每個方案制作測試腳本時,在運行時選擇要使用的用戶 ID,測試版本或生產版本。 如果方案涉及要求用戶回答問題,則將從腳本中發送問題。 然后,您轉到手機上,然后使用測試機器人進行回復。 答復將轉到您的測試網絡掛鉤,以便代碼可以正常運行。 我對這種方法不是很滿意,但是這種方法行之有效,而且比通過 Messenger 進行的所有測試都更快。
總有一天應該從 GitHub 安裝所有內容,但是今天不是那天。
## 采納
吸收不好。 我希望隨著稅收季節臨近活動的到來。 問題的一部分在于,作為一名程序員,我幾乎迷上了營銷。 我正在嘗試 Messenger Bot 廣告,但是這些廣告無效。
使用嘗試使漫游器不轉化的渠道隱喻用戶,他們在實際轉化并提出問題之前已經保釋。 可能存在信任問題。 他們不知道他們在問誰或將得到什么樣的答案。 我嘗試在網站和漫游器頁面上解決這些問題。 例如,如果您不喜歡答案,則無需付款,因此無風險。
一種可能性是人們并沒有真正使用 Messenger 機器人,并且對于此類應用程序的實驗失敗。
另一個可能性是我的機器人不是很好。 完全有可能的事情。
如果您有任何想法或疑問,請告訴我。
## 獲得的經驗教訓
* **不要做您所知道的**。 在盲目做您知道的事情之前,先環顧四周,看看是否有更好的選擇。
* **API 優先**。 為您的服務提出一個抽象并將其實現在一個地方。 當您必須在不同的平臺上實現另一個客戶端時,您將感激不盡。
* **DTO 首先**。 我犯了通過代碼庫傳播數據庫訪問代碼的錯誤。 只需創建一個數據傳輸對象并將代碼從一開始就集中在一個地方即可。 然后,可以輕松打包和重用它。
* **一次**。 要做的聰明的事情是必須使一個簡單的機器人來測試這個概念。 我當時知道這一點,但是我真的很想看看在所有三個平臺上開發一個機器人的感覺。 那個決定的人是個白癡。
* **吻**。 這么容易說,很難做到。
* **提前計劃共享節點和瀏覽器模塊**。 一旦已經編寫了很多代碼,就很難進行改造。
* **代碼共享**。 在 Lambda 函數之間共享很好的模塊化庫代碼在實踐中效果很好。 它使從命令行進行測試變得容易。
* **無服務器作品**。 由于種種原因,每個人都在涌動。 它可以讓一個人完成很多工作。 您有發展機會,但管理起來卻少得多。 對于不可預測的工作負載,它便宜得多且可擴展性更高。 我不能說工具很爛,因為我選擇不使用任何工具,但是我們仍然有一種方法可以弄清所有這些在實踐中是如何工作的。
* **事件> API** 。 使用 webhooks 使用 Serverless 將系統連接在一起非常強大。 相比之下,站起來放一個盒子并運行一個過程來使用 API??似乎很原始。
像大多數課程一樣,回想起來,大多數這些令人沮喪的頭腦震撼顯而易見,但是我想這就是為什么它們是課程。
看起來很酷
哇聽起來真酷 您是獨自建造的嗎? 花了多少時間?
是的,只有我。 這花了一個令人尷尬的時間:-)
@ToddHoff 幾乎所有編程都可以,尤其是在您必須學習新知識的情況下,這幾乎總是這樣,因為有各種各樣的工具可以完成工作。
您的帖子非常有趣。 我正在嘗試從中學習。 但是我不明白一件事。
您提到了為 lambda 創建單個入口點,然后將請求路由到單獨的函數。 但是,如果沒有 API 網關,請求如何首先到達 lambda?
嗨,杰克,
可以通過 API 直接調用 Lambda 函數。 他們不需要通過 HTTP。 我大致是這樣做的:
包括適用于您的環境的 AWS API,對于 Web 或節點中的 AWS API 有所不同。
appcfg.AWS = require(“ aws-sdk”);
appcfg.DB =新的 appcfg.AWS.DynamoDB();
appcfg.DBCLIENT = new appcfg.AWS.DynamoDB.DocumentClient();
appcfg.LAMBDA = new appcfg.AWS.Lambda();
appcfg.SES =新的 appcfg.AWS.SES();
appcfg.SQS = new appcfg.AWS.SQS();
函數 ProbotService(appcfg){
this.id = 0;
var self = this;
this.invokeLambda = function(method,params,next){
var payload = {
method:method,
params:params,
id:self.id ++
}
var params = {
FunctionName:appcfg.Amazon.ProbotService,
Payload:JSON.stringify(payload)
}
appcfg.LAMBDA.invoke(params,function(error,response){
if(error)return next(error);
var payload = JSON.parse(response.Payload);
如果(payload.error)返回 next(payload.error);
如果(payload.errorMessage)返回 next(new Error(payload.errorMessage));
返回 next(空,payload.result);
})//調用
} // invokeLambda
嗨,托德,
感謝您的廣泛回應!
實際上,我知道如何調用 lambda。 我從您調用它的地方很好奇。 看來您可能是從客戶端調用它的?
PS。 我剛剛開始學習 nodejs。 因此,無論我說什么,都可能變得毫無意義。
是的,無論是在 Slack 上的 nodejs 內,還是 lambda 本身的 nodejs 內,網站上的客戶端都是如此。 盡管幾天前我關閉了 slackbot。 太昂貴了,無法繼續運行。
只需為環境添加正確的庫并正確配置即可。
在網上:
<腳本 src =“ js / aws-cognito-sdk.js” > < / script >
<腳本 src =“ js / amazon-cognito-identity.min.js” > < / script >
<腳本 src =“ https://sdk.amazonaws.com/js/aws-sdk-2.3.5.min.js” > < / script >
在 slack 和 lambda 上,它們將 sdk 安裝到 node_modules 中,并且由于用戶看不到環境,因此可以從文件加載配置。
var AWS = require('aws-sdk');
AWS.config.loadFromPath('cfg.json');
appcfg.AWS = AWS;
我保持對 appcfg 中所有服務的訪問權并將其傳遞。 這樣,您可以在啟動時以特定于環境的方式配置所有內容。
現在,您可以在所有環境中使用相同的 lambda 調用代碼。
this.giveAnswerToPro = function(answer,next){
return self.invokeLambda(“ giveAnswerToPro”,答案,下一步);
} // GiveAnswerToPro
這是我的模塊問題出現的地方。您必須小心在每個環境中包含的內容。 在網絡資料中包含一個在 nodejs 中不可用的模塊,您已將其破壞。
這很酷。 您是否考慮過在營銷中使用會計師的圖片和/或個人資料? 甚至有照片。 主頁上顯示“真實的會計師”,因此看到它可能會讓人放心。
Hi Todd,
感謝您的回復!
我知道可能要問很多。 但是,如果您不介意,會介意開放源代碼并與我們共享嗎?
對像我這樣的人進入 nodejs 和 aws 領域確實很有幫助。
謝謝。
我得考慮杰克。 我不確定如何將我的東西充分分離出來。
有趣的文章。
- LiveJournal 體系結構
- mixi.jp 體系結構
- 友誼建筑
- FeedBurner 體系結構
- GoogleTalk 架構
- ThemBid 架構
- 使用 Amazon 服務以 100 美元的價格構建無限可擴展的基礎架構
- TypePad 建筑
- 維基媒體架構
- Joost 網絡架構
- 亞馬遜建筑
- Fotolog 擴展成功的秘訣
- 普恩斯的教訓-早期
- 論文:Wikipedia 的站點內部,配置,代碼示例和管理問題
- 擴大早期創業規模
- Feedblendr 架構-使用 EC2 進行擴展
- Slashdot Architecture-互聯網的老人如何學會擴展
- Flickr 架構
- Tailrank 架構-了解如何在整個徽標范圍內跟蹤模因
- Ruby on Rails 如何在 550k 網頁瀏覽中幸存
- Mailinator 架構
- Rackspace 現在如何使用 MapReduce 和 Hadoop 查詢 TB 的數據
- Yandex 架構
- YouTube 架構
- Skype 計劃 PostgreSQL 擴展到 10 億用戶
- 易趣建筑
- FaceStat 的禍根與智慧贏得了勝利
- Flickr 的聯合會:每天進行數十億次查詢
- EVE 在線架構
- Notify.me 體系結構-同步性
- Google 架構
- 第二人生架構-網格
- MySpace 體系結構
- 擴展 Digg 和其他 Web 應用程序
- Digg 建筑
- 在 Amazon EC2 中部署大規模基礎架構的六個經驗教訓
- Wolfram | Alpha 建筑
- 為什么 Facebook,Digg 和 Twitter 很難擴展?
- 全球范圍擴展的 10 個 eBay 秘密
- BuddyPoke 如何使用 Google App Engine 在 Facebook 上擴展
- 《 FarmVille》如何擴展以每月收獲 7500 萬玩家
- Twitter 計劃分析 1000 億條推文
- MySpace 如何與 100 萬個并發用戶一起測試其實時站點
- FarmVille 如何擴展-后續
- Justin.tv 的實時視頻廣播架構
- 策略:緩存 404 在服務器時間上節省了洋蔥 66%
- Poppen.de 建筑
- MocoSpace Architecture-一個月有 30 億個移動頁面瀏覽量
- Sify.com 體系結構-每秒 3900 個請求的門戶
- 每月將 Reddit 打造為 2.7 億頁面瀏覽量時汲取的 7 個教訓
- Playfish 的社交游戲架構-每月有 5000 萬用戶并且不斷增長
- 擴展 BBC iPlayer 的 6 種策略
- Facebook 的新實時消息系統:HBase 每月可存儲 135 億條消息
- Pinboard.in Architecture-付費玩以保持系統小巧
- BankSimple 迷你架構-使用下一代工具鏈
- Riak 的 Bitcask-用于快速鍵/值數據的日志結構哈希表
- Mollom 體系結構-每秒以 100 個請求殺死超過 3.73 億個垃圾郵件
- Wordnik-MongoDB 和 Scala 上每天有 1000 萬個 API 請求
- Node.js 成為堆棧的一部分了嗎? SimpleGeo 說是的。
- 堆棧溢出體系結構更新-現在每月有 9500 萬頁面瀏覽量
- Medialets 體系結構-擊敗艱巨的移動設備數據
- Facebook 的新實時分析系統:HBase 每天處理 200 億個事件
- Microsoft Stack 是否殺死了 MySpace?
- Viddler Architecture-每天嵌入 700 萬個和 1500 Req / Sec 高峰
- Facebook:用于擴展數十億條消息的示例規范架構
- Evernote Architecture-每天有 900 萬用戶和 1.5 億個請求
- TripAdvisor 的短
- TripAdvisor 架構-4,000 萬訪客,200M 動態頁面瀏覽,30TB 數據
- ATMCash 利用虛擬化實現安全性-不變性和還原
- Google+是使用您也可以使用的工具構建的:閉包,Java Servlet,JavaScript,BigTable,Colossus,快速周轉
- 新的文物建筑-每天收集 20 億多個指標
- Peecho Architecture-鞋帶上的可擴展性
- 標記式架構-擴展到 1 億用戶,1000 臺服務器和 50 億個頁面視圖
- 論文:Akamai 網絡-70 個國家/地區的 61,000 臺服務器,1,000 個網絡
- 策略:在 S3 或 GitHub 上運行可擴展,可用且廉價的靜態站點
- Pud 是反堆棧-Windows,CFML,Dropbox,Xeround,JungleDisk,ELB
- 用于擴展 Turntable.fm 和 Labmeeting 的數百萬用戶的 17 種技術
- StackExchange 體系結構更新-平穩運行,Amazon 4x 更昂貴
- DataSift 體系結構:每秒進行 120,000 條推文的實時數據挖掘
- Instagram 架構:1400 萬用戶,1 TB 的照片,數百個實例,數十種技術
- PlentyOfFish 更新-每月 60 億次瀏覽量和 320 億張圖片
- Etsy Saga:從筒倉到開心到一個月的瀏覽量達到數十億
- 數據范圍項目-6PB 存儲,500GBytes / sec 順序 IO,20M IOPS,130TFlops
- 99designs 的設計-數以千萬計的綜合瀏覽量
- Tumblr Architecture-150 億頁面瀏覽量一個月,比 Twitter 更難擴展
- Berkeley DB 體系結構-NoSQL 很酷之前的 NoSQL
- Pixable Architecture-每天對 2000 萬張照片進行爬網,分析和排名
- LinkedIn:使用 Databus 創建低延遲更改數據捕獲系統
- 在 30 分鐘內進行 7 年的 YouTube 可擴展性課程
- YouPorn-每天定位 2 億次觀看
- Instagram 架構更新:Instagram 有何新功能?
- 搜索技術剖析:blekko 的 NoSQL 數據庫
- Pinterest 體系結構更新-1800 萬訪問者,增長 10 倍,擁有 12 名員工,410 TB 數據
- 搜索技術剖析:使用組合器爬行
- iDoneThis-從頭開始擴展基于電子郵件的應用程序
- StubHub 體系結構:全球最大的票務市場背后的驚人復雜性
- FictionPress:在網絡上發布 600 萬本小說
- Cinchcast 體系結構-每天產生 1,500 小時的音頻
- 棱柱架構-使用社交網絡上的機器學習來弄清您應該在網絡上閱讀的內容
- 棱鏡更新:基于文檔和用戶的機器學習
- Zoosk-實時通信背后的工程
- WordPress.com 使用 NGINX 服務 70,000 req / sec 和超過 15 Gbit / sec 的流量
- 史詩般的 TripAdvisor 更新:為什么不在云上運行? 盛大的實驗
- UltraDNS 如何處理數十萬個區域和數千萬條記錄
- 更簡單,更便宜,更快:Playtomic 從.NET 遷移到 Node 和 Heroku
- Spanner-關于程序員使用 NoSQL 規模的 SQL 語義構建應用程序
- BigData 使用 Erlang,C 和 Lisp 對抗移動數據海嘯
- 分析數十億筆信用卡交易并在云中提供低延遲的見解
- MongoDB 和 GridFS 用于內部和內部數據中心數據復制
- 每天處理 1 億個像素-少量競爭會導致大規模問題
- DuckDuckGo 體系結構-每天進行 100 萬次深度搜索并不斷增長
- SongPop 在 GAE 上可擴展至 100 萬活躍用戶,表明 PaaS 未通過
- Iron.io 從 Ruby 遷移到 Go:減少了 28 臺服務器并避免了巨大的 Clusterf ** ks
- 可汗學院支票簿每月在 GAE 上擴展至 600 萬用戶
- 在破壞之前先檢查自己-鱷梨的建筑演進的 5 個早期階段
- 縮放 Pinterest-兩年內每月從 0 到十億的頁面瀏覽量
- Facebook 的網絡秘密
- 神話:埃里克·布魯爾(Eric Brewer)談銀行為什么不是堿-可用性就是收入
- 一千萬個并發連接的秘密-內核是問題,而不是解決方案
- GOV.UK-不是你父親的書庫
- 縮放郵箱-在 6 周內從 0 到 100 萬用戶,每天 1 億條消息
- 在 Yelp 上利用云計算-每月訪問量為 1.02 億,評論量為 3900 萬
- 每臺服務器將 PHP 擴展到 30,000 個并發用戶的 5 條 Rockin'Tips
- Twitter 的架構用于在 5 秒內處理 1.5 億活躍用戶,300K QPS,22 MB / S Firehose 以及發送推文
- Salesforce Architecture-他們每天如何處理 13 億筆交易
- 擴大流量的設計決策
- ESPN 的架構規模-每秒以 100,000 Duh Nuh Nuhs 運行
- 如何制作無限可擴展的關系數據庫管理系統(RDBMS)
- Bazaarvoice 的架構每月發展到 500M 唯一用戶
- HipChat 如何使用 ElasticSearch 和 Redis 存儲和索引數十億條消息
- NYTimes 架構:無頭,無主控,無單點故障
- 接下來的大型聲音如何使用 Hadoop 數據版本控制系統跟蹤萬億首歌曲的播放,喜歡和更多內容
- Google 如何備份 Internet 和數十億字節的其他數據
- 從 HackerEarth 用 Apache 擴展 Python 和 Django 的 13 個簡單技巧
- AOL.com 體系結構如何發展到 99.999%的可用性,每天 800 萬的訪問者和每秒 200,000 個請求
- Facebook 以 190 億美元的價格收購了 WhatsApp 體系結構
- 使用 AWS,Scala,Akka,Play,MongoDB 和 Elasticsearch 構建社交音樂服務
- 大,小,熱還是冷-條帶,Tapad,Etsy 和 Square 的健壯數據管道示例
- WhatsApp 如何每秒吸引近 5 億用戶,11,000 內核和 7,000 萬條消息
- Disqus 如何以每秒 165K 的消息和小于 0.2 秒的延遲進行實時處理
- 關于 Disqus 的更新:它仍然是實時的,但是 Go 摧毀了 Python
- 關于 Wayback 機器如何在銀河系中存儲比明星更多的頁面的簡短說明
- 在 PagerDuty 遷移到 EC2 中的 XtraDB 群集
- 擴展世界杯-Gambify 如何與 2 人組成的團隊一起運行大型移動投注應用程序
- 一點點:建立一個可處理每月 60 億次點擊的分布式系統的經驗教訓
- StackOverflow 更新:一個月有 5.6 億次網頁瀏覽,25 臺服務器,而這一切都與性能有關
- Tumblr:哈希處理每秒 23,000 個博客請求的方式
- 使用 HAProxy,PHP,Redis 和 MySQL 處理 10 億個請求的簡便方法來構建成長型啟動架構
- MixRadio 體系結構-兼顧各種服務
- Twitter 如何使用 Redis 進行擴展-105TB RAM,39MM QPS,10,000 多個實例
- 正確處理事情:通過即時重放查看集中式系統與分散式系統
- Instagram 提高了其應用程序的性能。 這是如何做。
- Clay.io 如何使用 AWS,Docker,HAProxy 和 Lots 建立其 10 倍架構
- 英雄聯盟如何將聊天擴大到 7000 萬玩家-需要很多小兵。
- Wix 的 Nifty Architecture 技巧-大規模構建發布平臺
- Aeron:我們真的需要另一個消息傳遞系統嗎?
- 機器:惠普基于憶阻器的新型數據中心規模計算機-一切仍在變化
- AWS 的驚人規模及其對云的未來意味著什么
- Vinted 體系結構:每天部署數百次,以保持繁忙的門戶穩定
- 將 Kim Kardashian 擴展到 1 億個頁面
- HappyPancake:建立簡單可擴展基金會的回顧
- 阿爾及利亞分布式搜索網絡的體系結構
- AppLovin:通過每天處理 300 億個請求向全球移動消費者進行營銷
- Swiftype 如何以及為何從 EC2 遷移到真實硬件
- 我們如何擴展 VividCortex 的后端系統
- Appknox 架構-從 AWS 切換到 Google Cloud
- 阿爾及利亞通往全球 API 的憤怒之路
- 阿爾及利亞通往全球 API 步驟的憤怒之路第 2 部分
- 為社交產品設計后端
- 阿爾及利亞通往全球 API 第 3 部分的憤怒之路
- Google 如何創造只有他們才能創造的驚人的數據中心網絡
- Autodesk 如何在 Mesos 上實施可擴展事件
- 構建全球分布式,關鍵任務應用程序:Trenches 部分的經驗教訓 1
- 構建全球分布式,關鍵任務應用程序:Trenches 第 2 部分的經驗教訓
- 需要物聯網嗎? 這是美國一家主要公用事業公司從 550 萬米以上收集電力數據的方式
- Uber 如何擴展其實時市場平臺
- 優步變得非常規:使用司機電話作為備份數據中心
- 在不到五分鐘的時間里,Facebook 如何告訴您的朋友您在災難中很安全
- Zappos 的網站與 Amazon 集成后凍結了兩年
- 為在現代時代構建可擴展的有狀態服務提供依據
- 細分:使用 Docker,ECS 和 Terraform 重建基礎架構
- 十年 IT 失敗的五個教訓
- Shopify 如何擴展以處理來自 Kanye West 和 Superbowl 的 Flash 銷售
- 整個 Netflix 堆棧的 360 度視圖
- Wistia 如何每小時處理數百萬個請求并處理豐富的視頻分析
- Google 和 eBay 關于構建微服務生態系統的深刻教訓
- 無服務器啟動-服務器崩潰!
- 在 Amazon AWS 上擴展至 1100 萬以上用戶的入門指南
- 為 David Guetta 建立無限可擴展的在線錄制活動
- Tinder:最大的推薦引擎之一如何決定您接下來會看到誰?
- 如何使用微服務建立財產管理系統集成
- Egnyte 體系結構:構建和擴展多 PB 分布式系統的經驗教訓
- Zapier 如何自動化數十億個工作流自動化任務的旅程
- Jeff Dean 在 Google 進行大規模深度學習
- 如今 Etsy 的架構是什么樣的?
- 我們如何在 Mail.Ru Cloud 中實現視頻播放器
- Twitter 如何每秒處理 3,000 張圖像
- 每天可處理數百萬個請求的圖像優化技術
- Facebook 如何向 80 萬同時觀看者直播
- Google 如何針對行星級基礎設施進行行星級工程設計?
- 為 Mail.Ru Group 的電子郵件服務實施反垃圾郵件的貓捉老鼠的故事,以及 Tarantool 與此相關的內容
- The Dollar Shave Club Architecture Unilever 以 10 億美元的價格被收購
- Uber 如何使用 Mesos 和 Cassandra 跨多個數據中心每秒管理一百萬個寫入
- 從將 Uber 擴展到 2000 名工程師,1000 個服務和 8000 個 Git 存儲庫獲得的經驗教訓
- QuickBooks 平臺
- 美國大選期間城市飛艇如何擴展到 25 億個通知
- Probot 的體系結構-我的 Slack 和 Messenger Bot 用于回答問題
- AdStage 從 Heroku 遷移到 AWS
- 為何將 Morningstar 遷移到云端:降低 97%的成本
- ButterCMS 體系結構:關鍵任務 API 每月可處理數百萬個請求
- Netflix:按下 Play 會發生什么?
- ipdata 如何以每月 150 美元的價格為來自 10 個無限擴展的全球端點的 2500 萬個 API 調用提供服務
- 每天為 1000 億個事件賦予意義-Teads 的 Analytics(分析)管道
- Auth0 體系結構:在多個云提供商和地區中運行
- 從裸機到 Kubernetes
- Egnyte Architecture:構建和擴展多 PB 內容平臺的經驗教訓
- 縮放原理
- TripleLift 如何建立 Adtech 數據管道每天處理數十億個事件
- Tinder:最大的推薦引擎之一如何決定您接下來會看到誰?
- 如何使用微服務建立財產管理系統集成
- Egnyte 體系結構:構建和擴展多 PB 分布式系統的經驗教訓
- Zapier 如何自動化數十億個工作流自動化任務的旅程
- Jeff Dean 在 Google 進行大規模深度學習
- 如今 Etsy 的架構是什么樣的?
- 我們如何在 Mail.Ru Cloud 中實現視頻播放器
- Twitter 如何每秒處理 3,000 張圖像
- 每天可處理數百萬個請求的圖像優化技術
- Facebook 如何向 80 萬同時觀看者直播
- Google 如何針對行星級基礎設施進行行星級工程設計?
- 為 Mail.Ru Group 的電子郵件服務實施反垃圾郵件的貓捉老鼠的故事,以及 Tarantool 與此相關的內容
- The Dollar Shave Club Architecture Unilever 以 10 億美元的價格被收購
- Uber 如何使用 Mesos 和 Cassandra 跨多個數據中心每秒管理一百萬個寫入
- 從將 Uber 擴展到 2000 名工程師,1000 個服務和 8000 個 Git 存儲庫獲得的經驗教訓
- QuickBooks 平臺
- 美國大選期間城市飛艇如何擴展到 25 億條通知
- Probot 的體系結構-我的 Slack 和 Messenger Bot 用于回答問題
- AdStage 從 Heroku 遷移到 AWS
- 為何將 Morningstar 遷移到云端:降低 97%的成本
- ButterCMS 體系結構:關鍵任務 API 每月可處理數百萬個請求
- Netflix:按下 Play 會發生什么?
- ipdata 如何以每月 150 美元的價格為來自 10 個無限擴展的全球端點的 2500 萬個 API 調用提供服務
- 每天為 1000 億個事件賦予意義-Teads 的 Analytics(分析)管道
- Auth0 體系結構:在多個云提供商和地區中運行
- 從裸機到 Kubernetes
- Egnyte Architecture:構建和擴展多 PB 內容平臺的經驗教訓