<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                Medium 這樣的站點看上去似乎很簡單,不過背后的復雜程度足以讓人驚訝。這還僅僅只是一個博客網站么?要是這樣的話,你用 Rails 幾天就能搭建一個出來。:) 閑話少說,我們從最底層說起。 ## 產品環境 目前我們運行在?[Amazon 的虛擬私有云](http://stackshare.io/amazon-vpc)上。我們使用?[Ansible?](http://www.oschina.net/p/ansible)做系統管理,可以讓我們的配置處于源碼控制下,可以通過可控的方式很輕松的進行更新。 我們有著面向服務的架構,在其上運行了大約一打的產品服務(取決于你如何去統計,還有很多小一點的服務)。是否作為獨立的服務來部署,主要取決于其功能,服務邊界上是否可能產生有依賴的變動,以及對資源的利用。 我們主要的應用服務器仍然寫在Node里,它允許我們在供應商和客戶之間交換代碼,我們用編輯器就要用到它,公布變革也是用它。Node為我們工作得很好,但是在我們把事件循環編寫成塊的時候,性能問題就浮現了。為了緩和這一問題,我們在每臺機器上運行多個實例,并把它們路由到昂貴的端點,以此來分隔它們。我們把它與V8運行環境相掛鉤,以深入了解哪個部件運行花費的時間較長。通常它是因為在JSON還原序列化時目標的具體化。 我們用Go編程的時候可以享受到一些輔助服務。我們發現用GO建立、打包和部署很容易。我們喜歡不需用到繁冗并調試虛擬機Java的類型安全。就我個人而言,我更喜歡在團隊環境中使用武斷的語言。它能提高一致性、減少歧義,最終讓你避免作繭自縛。 我們現在使用CloudFlare提供靜態資源,盡管我們把5%的流量送到Fastly,同時還送5%的流量到CloudFront來保持它們的緩存熱度,以防在緊急情況下萬一我們需要割接。最近我們也把CloudFlare用于應用流,基本上是為了DDOS保護。但是對于性能提升我們還是樂見其成的。 我們使用Nginx和HAProxy的結合作為反向代理,達到負載均衡,以實現我們需要的Venn Diagram特性。 我們仍然使用Datadog監測,使用PagerDuty報警,但是我們現在大量使用ELK(Elasticsearch,Logstash,Kibana)調試出現的問題。 ## 數據庫 DynamoDB仍然是我們基本的數據存儲庫,但是它仍不完美。我們遇到的常見的問題之一是在重大事件發生時和有百萬追隨用戶時的熱鍵問題。在Dynamo前面我們可以用Redis緩存器,它能通過讀取來減輕這些問題。 開發者便利性和產品穩定性二者之間的優化似乎總是存在矛盾,但是我們在努力縮小分歧。?? ? 我們開始使用Amazon Aurora獲取最新的數據,它的查詢和過濾功能比Dynamo更靈活。 我們使用Neo4J來儲存代表媒體網絡的實體之間的關系,用兩個副本來運行一個主本。 人、郵件、標簽和合類是圖表中的節點。 邊界在實體創建的基礎上建立。當人們發生以下行為,比如跟隨、推薦和強調時,我們按圖索驥,過濾并推薦相關的郵件。 ## 數據平臺 早起我們的數據很匱乏,所以在數據分析基礎架構上做了很多投資,為商業和產品上的決策提供幫助。最近以來,我們可以在同樣的數據處理流程上為整個產品體系提供更多的反饋,甚至可以運行類似 Explore 這樣的數據驅動的功能。 我們使用?[Amazon Redshift](http://stackshare.io/amazon-redshift)?作為數據倉庫,它提供了可伸縮的存儲和處理系統,我們其他的工具就運行在其上。我們持續的把核心數據(例如用戶、文章)從 Dynamo 導入到 Redshift,以及把行為日志 (例如:文章閱讀、翻頁等等) 從 S3 導入到 Redshift。 我們使用 Conduit 來對任務做調度,這是一個內部工具,可以管理計劃、數據依賴,還可以進行監控。我們的任務調度模型是基于斷言的,只有一個的所有的依賴都滿足了,這個任務才會被執行(例如,依賴全天行為日志的每日任務)。對于產品,這方面被證明是非常重要的:數據的生產者和消費者互相解耦,簡化配置,系統狀態可預知和易調試。 盡管對我們來說在 Redshift 上運行 SQL 查詢良好,我們還是需要將數據不斷輸入輸出 Redshift。我們越來越轉向 ETL 的[Apache Spark](http://stackshare.io/spark),這是因為它的靈活性與規模增長的能力。隨著時間的推移,Spark 可能會成為我們數據管道的首選工具。 我們使用[協議緩沖(Protocol Buffers)](https://developers.google.com/protocol-buffers/)對我們的模式(模式演化規則)來保持所有層的分布式系統同步,包括移動應用,web 服務,和數據倉庫。使用自定義選項,我們標注模式與表名和索引等配置細節,驗證約束最大長度的字符串,或者控制接受數據控制的范圍。 人們也需要保持移動和 web 應用程序同步,開發人員使得所有日志一樣,產品研究員可以以同樣的方式解釋字段。我們幫助我們的成員在數據處理模式規范上的工作,并嚴格記錄字段的消息,發布文檔生成的原型(*.proto*)。 ## 圖像 我們的圖片服務器現在是用?[Go](http://stackshare.io/go)?寫的,并使用了瀑布策略處理圖像。服務器使用?[groupcache](https://github.com/golang/groupcache),它提供了 memcache 的替代方案,來減少重復的工作。支持內存中的緩存是一個持久的 S3 緩存,然后來處理圖像處理需求。這讓我們的設計師可以在不同平臺上,靈活地改變圖像的表示和優化,而不必做大的批處理縮放圖像作業。 現在主要用于調整和裁剪,早期版本的網站允許顏色清洗、模糊和其他圖像效果。處理動態 gif 一直是一個巨大的頭痛的問題,這應該又是另一篇文章了。 ### 文本截圖 完整的文本截圖功能由一個小型的 Go 服務器驅動,使用?[PhantomJS](http://stackshare.io/phantomjs)?作為渲染引擎。 ![](https://box.kancloud.cn/2015-11-27_5657fc134768c.png) 我一直想把渲染引擎轉換為 Pango,但在實踐中,將圖片嵌入 HTML 的方式更為靈活和方便。這項功能的使用頻率意味著我們可以很簡單地處理吞吐量。 ## 自定義域名 我們允許用戶對他們的 Medium 作品設置自定義域名。我們想讓單點登錄和 HTTPS 無處不在,所以讓它開始工作不是件小事。我們有一組 HAProxy 服務器專門用于管理證書和導向主應用服務器的流量。在設置域名時還需要一些手動操作,但是我們通過自定義整合?[Namecheap](http://stackshare.io/namecheap)?已經自動化了很大一部分。證書的規定和公開鏈接是由一個專用服務處理的。 ## Web 前端 在網頁上,我們傾向于電子化。我們有自己的單頁應用程序框架,使用閉包作為標準庫。我們使用閉包模板在客戶端和服務器渲染,我們使用閉包編譯器壓縮代碼并把它分割成模塊。編輯器是我們網頁應用最復雜的部分,Nick 寫出了 iOS 系統。 ## iOS 系統 我們的應用程序都是本地下載好的,很少使用網絡視圖。 在 iOS 中,我們使用國產構架和內置構件的混合。在網絡層,我們使用 NSURLSession 提出請求,使用 Mantle 來把 JSON 解析成模型。 我們有一個建立在 NSKeyedArchiver 上的緩存層。我們有一個通用的方法把項目列入不同的列表,同一列表中的項目有共同特征。這就能讓我們快速建立不同類型內容的列表。后視圖是用 UICollectionView 自定義布局構建的。我們使用共享組件來渲染完整的文章和后預覽。 Medium 的員工盡一切努力來盡快開發和推出新的應用。我們發布更新的節奏是受限于 Appstore 的審閱周期的,但我們正盡己所能地推進這一進程,即使只有很少的更新。 測試我們使用 XCTest 和 OCMock. ## Android 對于 Android,我們目前會保持 SDK 和 support 庫都是最新的。我們沒有使用綜合性的框架,而是傾向于為重復的問題建立一致性的模式。我們使用?[guava](http://stackshare.io/guava)?來彌補 Java 缺失的功能。不過有的情況下,我們會使用[以特定問題為目標的第三方庫](https://medium.com/medium-eng/medium-android-tools-f827bb96b8e4)。我們的 API 的返回結果使用了 protocol buffer 協議,在 app 里會生成這些對象。 我們使用?[mockito](http://mockito.org/)?和[?robolectric](http://robolectric.org/)。我們會為動態編寫高層級的測試用例?—?在我們剛開始添加界面或者準備重構的時候會創建一些簡單的版本。在我們不斷重現 bug 后,測試用例會越來越多,幫我們避免代碼功能回退。我們編寫底層的測試用例來驗證單個類的細節?—?在實現新功能后,通過這些用例能看到類之間是如何交互的。 所有提交會自動推送到 play store,用于 alpha 版本,Medium 的員工可以立刻使用到。(這里包括另一個最受歡迎的 app,[我們的內部的 Medium? 版本—? Hatch](https://medium.com/inside/hatching-inside-medium-5ae60292d655))。大多數周五,我們會把最后一個 alpha 版本發布到?[beta 組](https://medium.com/@caramev/welcome-to-the-android-beta-4ca716ef65e4),讓大家在周末去使用。接下來在周一產品會由 beta 變成正式版本。因為最新代碼一直保持可發布狀態,所以一旦我們發現一個 bug,我們可以在正式產品上立刻修復。如果不放心某個新的功能,可以讓 beta 版測試的時間稍微長一些;如果感覺好的話,發布也可以更頻繁一些。
                  <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>

                              哎呀哎呀视频在线观看