<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # Zapier 如何自動化數十億個工作流自動化任務的旅程 > 原文: [http://highscalability.com/blog/2016/2/29/a-journey-through-how-zapier-automates-billions-of-workflow.html](http://highscalability.com/blog/2016/2/29/a-journey-through-how-zapier-automates-billions-of-workflow.html) *這是[的來賓](http://stackshare.io/zapier/scaling-zapier-to-automate-billions-of-tasks)[轉貼了](http://stackshare.io/zapier/scaling-zapier-to-automate-billions-of-tasks) [Bryan Helmig](http://stackshare.io/bryanhelmig) ,是 [Zapier](http://stackshare.io/zapier) 的共同創始人& CTO,他可以輕松地在 Web 之間自動執行任務 應用。* ![](https://img.kancloud.cn/72/2e/722e48edeaf2a81fd488b12e808df6b4_996x589.png) [Zapier](http://stackshare.io/zapier) 是一項 Web 服務,可自動執行 500 多個 Web 應用程序之間的數據流,其中包括 MailChimp,Salesforce,GitHub,Trello 等。 想象一下[建立一個工作流](https://zapier.com/multi-step-zaps/)(或我們稱為“ Zap”)的操作,該操作在用戶填寫您的 Typeform 表單時觸發,然后在您的 Google 日歷上自動創建事件,發送 Slack 通知并完成以下操作 在 Google 表格電子表格中添加一行。 那是扎皮爾。 即使對于非技術用戶來說,構建這樣的 Zaps 也非常容易,并且可以無限地自定義。 作為首席技術官和聯合創始人,我構建了許多原始的核心系統,如今領導工程團隊。 我想帶您**,了解我們的堆棧**,以及我們如何構建它以及如何在今天繼續改進它! ## 幕后的團隊 使 Zapier 滴答作響需要很多時間,因此我們在工程領域有四個不同的團隊: * **前端團隊**在非常強大的工作流編輯器上工作。 * **全棧團隊**是跨功能的,但專注于工作流引擎。 * **開發人員小組**保持引擎嗡嗡作響。 * **平臺團隊**(可協助質量檢查)以及我們開發人員平臺的入門合作伙伴。 總而言之,這涉及約 15 名工程師(并且還在不斷增加!)。 ## 架構 **我們的堆棧不會贏得任何新奇獎**-我們正在使用一些非常標準的(但很棒的)工具為 Zapier 提供動力。 更有趣的是我們使用它們來解決特定品牌問題的方式,但讓我們將基礎知識排除在外: ### 前端 從主干**過渡到 React** 的過程中,我們感到有些困惑。 我們使用 ES6 的 [Babel](http://stackshare.io/babel) 和 [Webpack](http://stackshare.io/webpack) + [Gulp](http://stackshare.io/gulp) 來編譯前端。 我們嚴重依賴 [CodeMirror](http://stackshare.io/codemirror) 來做一些我們需要的更復雜的輸入小部件,并使用 [React](http://stackshare.io/react) + [Redux](http://stackshare.io/reduxjs) 為超級用戶做很多繁重的工作 -強大的 Zap 編輯器。 ### 后端 [Python](http://stackshare.io/python) 為我們的大部分后端提供了動力。 [Django](http://stackshare.io/django) 是 HTTP 方面的首選框架。 [Celery](http://stackshare.io/celery) 是我們分布式工作流程引擎的*大型*部分。 大部分常規 API 工作都是通過具有歷史意義的 [`requests`](https://github.com/kennethreitz/requests) 庫(帶有一堆自定義適配器和抽象)完成的。 ### 數據 [MySQL](http://stackshare.io/mysql) 是我們的主要關系數據存儲-您會在 MySQL 內部找到我們的用戶,Zaps 等。 [Memcached](http://stackshare.io/memcached) 和 [McRouter](http://stackshare.io/mcrouter) 看起來像是無處不在的緩存層。 其他類型的數據將進入其他更有意義的數據存儲中。 例如,在 [Redis](http://stackshare.io/redis) 中發現了用于計費和節流的飛行中任務計數,而 [Elasticsearch](http://stackshare.io/elasticsearch) 存儲了 Zaps 的歷史活動提要。 對于數據分析,我們喜歡一些 [AWS Redshift](http://stackshare.io/amazon-redshift) 。 ### 該平臺 我們的大多數平臺都位于我們相當**的整體式核心 Python 代碼庫**中,但是有許多有趣的分支提供了專門的功能。 最好的例子可能是我們如何利用 [AWS Lambda](http://stackshare.io/aws-lambda) 運行合作伙伴/用戶提供的代碼來自定義應用程序行為和 API 通信。 ### 基礎設施 由于 Zapier **在 AWS** 上運行,因此我們觸手可及。 [EC2](http://stackshare.io/amazon-ec2) 和 [VPC](http://stackshare.io/amazon-vpc) 是此處的中心,盡管我們會盡可能使用 [RDS](http://stackshare.io/amazon-rds) 以及大量的自動伸縮組,以確保服務器池處于最佳狀態。 頂部形狀。 [Jenkins](http://stackshare.io/jenkins) , [Terraform](http://stackshare.io/terraform) , [Puppet](http://stackshare.io/puppet) 和 [Ansible](http://stackshare.io/ansible) 都是開發團隊的日常工具。 為了監視,我們對 [Statsd](http://stackshare.io/statsd) , [Graylog](http://stackshare.io/graylog) 和 [Sentry](http://stackshare.io/sentry) (他們*很好*)不夠滿意。 ## 一些粗糙的數字 這些數字代表一個大概的最小值,以幫助讀者了解 Zapier 體系結構的總體大小和尺寸: * 每天約有超過 800 萬個任務自動化 * 每天超過約 6000 萬次 API 調用 * 每天有超過 1000 萬個入站 Webhooks * 在 [ELB](http://stackshare.io/aws-elastic-load-balancing) 之后運行 HTTP 的?12 個 c3.2xlarge 框 * 運行 [Celery](http://stackshare.io/celery) 的大約 100 個 m3.2xlarge 后臺工作者(在輪詢,掛鉤,電子郵件,雜項中分隔) * 集群中約 3 m3.medium [RabbitMQ](http://stackshare.io/rabbitmq) 節點 * ?4 個 r3.2xlarge [Redis](http://stackshare.io/redis) 實例-一個熱,兩個故障轉移,一個備份/映像 * ?6 個 c3.xlarge McRouter 實例之后的?12 m2.xlarge [Memcached](http://stackshare.io/memcached) 實例 * ?3 m3.xlarge 無數據 ElasticSearch 實例之后的?10 m3.xlarge [ElasticSearch](http://stackshare.io/elasticsearch) 實例 * ?1 個 c3.2xlarge Graylog 服務器后面的?6 m3.xlarge ElasticSearch 實例 * 集群中約 10 個 dc1.large [Redshift](http://stackshare.io/amazon-redshift) 節點 * 1 個主 db.m2.2xlarge [RDS MySQL](http://stackshare.io/amazon-rds) 實例,帶有?2 個以上的副本,可用于生產讀取和分析 * 少數支持 RDS MySQL 實例(下面有更多詳細信息) * ...以及大量的微服務和雜項專業服務 ## 改善架構 雖然架構的主要內容保持不變-我們僅執行了幾次大規模遷移-但為將產品分為兩類進行了大量工作: 1. 支持重大新產品功能 2. 為更多用戶擴展應用程序 讓我們深入研究每個示例,盡可能多地獲取細節,而不會陷入困境! #### 大型功能,例如多步 Zaps 當我們在 Startup 周末啟動 Zapier(有趣的事實:它首先被稱為 Snapier!)時,我們在不到 54 個小時的時間內布置了基本架構(由大量的咖啡和更多的啤酒推動)。 總的來說,這是體面的。 **我們保持設計非常非常簡單**,這在當時是正確的選擇。 除了**之外,*也是*簡單**。 具體來說,我們將 Zaps 分為兩步:將觸發器與一個動作配對,一個句號。 我們很快就意識到了錯過的機會,但是過渡將非常復雜。 我們必須實現一個有向樹,并支持任意數量的步驟(節點),但要對現有 Zaps(其中已有數十萬個)保持 1 對 1 的支持。 我們必須做到這一點,同時還要保留對數百個獨立合作伙伴 API 的支持。 從數據模型開始,我們在 MySQL 中構建了一個非常簡單的有向樹結構。 想象一下一個表,其中每行都有一個自引用`parent_id`外鍵,再加上一個額外的`root_id`外鍵以簡化查詢,您幾乎就可以了。 我們討論了切換到適當的圖形數據庫(例如 neo4j)的決定,但由于我們進行的查詢種類簡單且遍歷較小的孤立圖形(大約 2 至 50 個節點),因此決定拒絕這樣做。 進行此工作的一個關鍵方面是步驟間的獨立性。 每一步都必須消耗一些數據(例如,要讀取哪個文件夾或要添加到哪個列表 ID),做一些 API 魔術操作并返回一些數據(例如,創建的新文件或添加到列表的新卡) ,但不知道其在工作流程中的位置。 每個獨立的步驟都是愚蠢的。 中間是**全知的工作流引擎,該引擎通過將步驟作為任務串在一起來協調獨立的 Celery 任務**-一步是由 Zap 的有根樹定義的。 這個無所不知的引擎還包含所有其他優點,例如錯誤&重試處理,報告,日志記錄,節流等。 即使在獲得后端支持之后,我們仍然遇到另一個巨大的問題:**您如何為該對象構建 UI?** 首先,確保團隊中有一些*出色的*設計師和 Javascript 工程師。 然后,您將在嵌套的 Backbone 視圖中工作一段時間,然后再進入 React。 :-)認真地說: [React](/react) 是我們正在構建的各種復雜接口的天賜之物。 React 的獨特之處之一是性能特性對開發人員很友好,但前提是您必須弄清楚數據。 如果您不使用不可變的數據結構,則應使用一些結構共享庫來進行所有突變,以及正在開發的深層`Object.freeze()`來捕捉直接嘗試突變的地方。 構建如此復雜的 UI 面臨許多挑戰,其中大部分圍繞測試和反饋,但要花費大量時間才能從不同的 API 中獲取長尾數據,以使其優雅地適合于相同位置。 幾乎每種奇怪的數據形狀都必須考慮在內。 最后,我們的任務是讓新編輯器在用戶面前進行 alpha 和 beta 測試。 為此,我們同時發布了兩個版本的編輯器,并使用功能開關選擇了加入用戶。在對結果感到滿意之前,我們進行了數月的測試和調整,您可以查看 [Multi-Step Zap 發布 頁](https://zapier.com/multi-step-zaps/)了解其最終結果。 ![](https://img.kancloud.cn/c5/c5/c5c5d4dbddc24c63fac289bd9efcb64b_2254x705.png) ## 擴展應用程序 如果服務無法正常啟動并可靠運行,那將是徒勞的。 因此,我們的大部分注意力集中在支持水平可伸縮性*和*冗余基礎結構以確保可用性的應用程序設計上。 到目前為止,我們做出的一些更明智的決策是**,使我們對**感到滿意的技術倍增,而**遇到瓶頸**時,則會分離出隔離的功能。 關鍵是**重用完全相同的解決方案,然后將其移動到另一個可以自由漫游 CPU 和 RAM 新鮮牧場的盒子**。 例如,在過去一年左右的時間里,我們注意到會話數據耗盡了主數據庫的 IO 和存儲量。 由于會話數據實際上是具有較弱一致性要求的鍵/值排列,因此我們對諸如 [Cassandra](http://stackshare.io/cassandra) 或 [Riak](http://stackshare.io/riak) (甚至是 Redis!)之類的方案進行了激烈的辯論,但最終決定站起來 具有單個會話表的 MySQL 實例。 作為工程師,我們的本能是找到最適合該工作的工具,但是**作為實際問題**,該工作并不能保證額外的操作復雜性。 我們知道 MySQL,它可以進行簡單的鍵/值存儲,我們的應用程序已經支持它。 暢所欲言。 此外,仔細設計應用程序可以使水平縮放同樣簡單。 長期運行的后臺任務(例如我們的多步驟 Zaps)不受**輕寫模式**的嚴格一致性要求的約束,因此**使用 MySQL 讀操作是微不足道的(而且很安全!)。 僅將**復制為*主要*接觸點。 即使我們偶爾在幾分鐘內得到了可怕的復制品延遲,但 99.9%的 Zaps 并沒有改變-并且肯定不會很快改變-因此它們繼續嗡嗡作響。 另一個好的做法是**假設最壞的**。 從一開始就設計失敗。 盡管通常說起來容易做起來難,但如今實際上卻很容易做到。 對于初學者:**將自動縮放組與自動替換**一起使用。 一個常見的誤解是,ASG 僅用于擴展以適應波動的負載。 **錯誤!** **ASG + ELB 組合可以成為可靠性的骨干**,它使您可以隨意殺死實例,而不必擔心,因為它們會迅速被替換。 不知何故,我們不斷地學習到,系統越簡單,您的睡眠就越好。 ## 日常 在本地,我們的工程師享受 [Docker](http://stackshare.io/docker) 提供的功能全面的環境。 `[docker-machine](http://stackshare.io/docker-machine)`和 [`docker-compose`](http://stackshare.io/docker-compose) 一起構成了 MySQL,Memcached,Redis,Elasticsearch 以及所有 Web 和后臺工作人員的正確版本。 我們通常建議在本地運行 [`npm`](/npm) 甚至是`runserver`,因為 VirtualBox 會破壞文件監視功能。 規范的 [GitHub](http://stackshare.io/github) “拉動請求模型”驅動了我們的大部分工程重點項目,其中記錄了日常工作,并在合并之前進行了最終代碼審查。 [Hackpad](http://stackshare.io/hackpad) 包含了我們的大部分文檔,其中包括大量的入門文檔。 Zapier 的一大優勢是[所有人都支持](https://zapier.com/blog/everyone-on-support/)。 每四到五周,每位工程師都會花費整整一周的支持來幫助調試和解決棘手的客戶問題。 這對我們非常重要,因為它為了解客戶的痛苦提供了基線(此外,您可能必須處理所運送的錯誤!)。 對于 CI 和部署,我們使用 [Jenkins](http://stackshare.io/jenkins) 對每個 PR 中的每個提交運行測試,并提供公司任何人都可以按下的“一鍵式部署”。 新工程師在工作的第一周點擊部署按鈕的情況并不少見! 我們在獨立的 VPC 中擁有一個**完整的登臺環境,以及一些非常適合測試長期拉動請求的獨立 Web 框。 金絲雀部署到生產中很常見-完整記錄所有錯誤,由 Graylog 提供。** ## 你也可以扎皮爾! 開發人員可以使用 Zapier 來做一些很棒的事情。 除了多步驟 Zaps,我們還啟用了將 [Python](https://zapier.com/help/code-python/) 和 [Javascript](https://zapier.com/help/code/) 編寫為工作流中的代碼步驟的功能。 無需自己托管和運行腳本-我們會處理所有這些。 我們還提供了綁定以調用網絡(`requests`和`fetch`),甚至在兩次運行之間存儲一些狀態! 我們的用戶正在采用代碼步驟來構建 [Slack](http://stackshare.io/slack) 機器人(以及游戲!),以替換一次性腳本以及更多其他內容。 我個人使用代碼步驟來編寫機器人和工具,以將代碼&錯誤度量標準跟蹤到電子表格中,轉換格式奇怪的數據,并替換*噸* crontabs。 或者,如果您具有希望非開發人員能夠使用的 API,那么我們也將擁有一個史詩般的[開發人員平臺](https://zapier.com/developer/)。 只需定義觸發器,搜索和操作,任何用戶都可以將您的 API 混合到他們的工作流中,并將您的應用程序與 GitHub,Salesforce,Google Docs 等 500 多種應用程序集成。 而且,我們經常在招聘,因此,如果您想幫助我們幫助人們更快地工作并自動執行最繁瑣的任務,請關注我們的[工作頁面](https://zapier.com/jobs/)! [關于 HackerNews](https://news.ycombinator.com/item?id=11082359) 鏈接已斷開... 感謝抓住 Gigi! 為什么使用 MySQL? Postgres 不是它的超集嗎? 您能否評論一下如何在芹菜上實現編排? 以我的經驗,很難做到這一點,因為很多邏輯是在任務級別定義的,例如,很難在運行時修改任務的行為,因為它的定義是靜態的,并且在將模塊加載到工作程序時變成靜態的。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看