應用系統架構演變初探

背景

    近幾年的互聯網創業風潮持續在高漲中,所涉及的行業從涵蓋了社交、資訊、電商、生活服務等方方面面。其中也涌現很多優秀的APP,而這些產品或平臺的特色都包含了"快速",即更新快,迭代快的特性。
    然而做爲一名軟件工程師的角度,按之前軟件工程的理論來講,系統在設計初期應考慮更多的複雜度、良好的擴展性,儘量達到以不變應萬變的結果,而這些快速變動的新秀產品,在系統架構上如何作到靈活擴展、快速演進的呢? 這即是如下要開始探討的內容。
 
 

1、初定系統架構

    在最開始的時候,產品經理(或項目經理)找到你,在嘮嘮叨叨敘述完整個系統的功能需求後,要求你一個月內就開發出來。
    
經理:
    "領導那邊催得要命,一個月內必須上線!"
    "這些功能都很常規呢,須要開發這麼久嗎!"
 
你:
    ...

 

    固然,以上的場景稍顯誇張,但在互聯網思惟方式的APP開發場景下,這樣的節奏其實很常見。
    研發經理都是不辭辛苦的角兒,因而乎,大腦開始高速運轉:
"這麼短的的時間" .. "好吧,先不考慮性能問題了!"
"單元測試也能夠省了,作好自測就能夠,能省下很多時間呢"

   

    通過一輪掙扎和思考,研發經理推斷出了產品的第一代系統架構html

    
    
 
    架構特色
        單點,以知足功能爲主,簡單、輕量級架構。
 
    數據流
        來自多種場景的的http請求直接由單個server接入、完成業務邏輯處理、輸出計算結果。
 
    組件介紹 

         1    App Server,應用系統的服務端節點,能夠有不少種選擇,以Java系列爲例java

             tomcatmysql

             最流行不過的j2ee容器,官網 http://tomcat.apache.org/nginx

             jettyweb

             一款更爲輕量級的servlet容器,輕量小巧,提供可編程server的實現(容易嵌入),在continuation機制也有比較良好的表現。redis

             詳細參見 http://www.eclipse.org/jetty/sql

             playframework數據庫

             此前最爲喜好的一款非主流應用服務器,應該是首個java版本的"ruby on rails"的實現。其摒棄了j2ee繁重的各類理念枷鎖,讓編程變得更加簡單、可依賴。
             playframework框架目前已經主推2.x (同時支持java和scala)版本,然而學習曲線相較1.2.x版本更加陡峭,建議可從1.2.5版本開始入門使用。
                   
             值得一提的是該框架內置了netty以支持http請求的接入及處理。
             netty是一款基於NIO實現的輕量級http服務器,
                         關於netty的實現原理可參考: http://stonexmx.blog.163.com/blog/static/122158587201061331614536/
             play框架的官網:https://www.playframework.com/
             
            2  mysql,流行的開源數據庫,應用基於JPA/JDBC進行訪問,以實現數據持久化
 
            3  memcached, 高速的內存服務器系統,支持KV數據流的快速讀寫,用做數據緩存及加速訪問
                官網地址:http://memcached.org/
 
 

2、演變的開始

       好的,通過一個月的努力,系統上線了。
       運營也開始幹活,緊接着是對線上各類問題的緊急修復。
 
       系統漸漸有了一些活躍度,在幾個月內,產品經理和研發經理開始聽到了一些抱怨:
 
 "系統怎麼老掛啊,動不動就訪問不了,這什麼破玩意啊"
 "我這都已經換成wifi了,圖片怎麼仍是一直加載不了呢?"
.....

     所謂積少成怨,團隊終於頂不住壓力,下決心開始優化系統。針對上述的問題,分析以下:apache

       1  可用性;
           單點發生崩潰,整個系統直接不可用,全部用戶將受到影響;
           JVM的內存溢出,系統進程意外終止均可能致使這樣的問題。
 
       2  帶寬;
           應用系統在初期設計時更多的考慮了網絡調用、html動態頁面的輸出,而針對圖片的訪問並未作過多考慮,所以文件資源訪問很快出現了瓶頸。
 
         研發經理決定將架構優化以下
 
         
     
         負載均衡
         使用nginx提供應用服務器的負載均衡,提供兩個應用服務器節點,保證單點崩潰時而系統仍然可用。
 
         文件訪問分離
         使用單獨的web服務器(nginx)用做文件訪問服務器,全部的靜態圖片地址將指向獨立域名。
 
         

3、加速進化

       繼上一次優化以後,用戶的抱怨已經明顯減小,產品經理和領導都對這次工做表示滿意。
       研發經理開始感覺到了史無前例的成就感。
 
       然而好景不長,在幾個月後公司重點引入了營銷團隊。這是至關給力的團隊,在短短的時間內,在各大網絡平臺佈置了多個入口。
      各類推廣活動、事件營銷接踵而來。最可觀的如在微信朋友圈的一次事件營銷直接引入了好幾倍的用戶量。
      這樣的狀況在互聯網產品的發展軌跡上至少也能夠稱得上一次小小的爆發式增加了。
 
       固然,領導、產品經理都開心和興奮起來了。但此次,研發經理心裏開始發愁了:
 
      1  訪問壓力;
          一個server的併發處理能力很容易達到上限,一旦超過負載閾值,將直接致使訪問時長加大,甚至系統崩潰、沒法訪問等情形;
 
      2  數據存取;
          數據量的擴充,單個數據庫表不斷增大,查詢速度將產生降低;
          此外數據庫的單點也成爲隱患
      
      3  緩存空間;
          與數據庫同理,爲加速更多數據的訪問,須要提供更大容量緩存空間;
 
      此次,研發經理將系統架構作了一次較爲完全的改進:
 
            
 
       負載均衡
       增長負載均衡的服務器節點,提升總體處理能力;
       
       數據庫擴展
       採起水平切分的方式,實現基於Shard的分佈式數據庫集羣;
      
       memcached集羣
       開啓多個memcached節點,組成高可用的緩存集羣,同時可支持更大的緩存空間
 
       其中對於服務端程序改造最大的在於分佈式Shard數據的實現,通常可從數據量較大的局部表開始切分,在數據存取上加入水平分庫的機制;
       固然此時的數據遷移工做也是一個重點。
 
 

4、將來的展望

       至此,系統優化已經告一段落。當前的後臺架構已經處在一個表現穩定,容易擴展的一個狀態。
       性能指標方面大體已經能夠達到百萬級用戶量,日PV過百萬,甚至還可能更好。
       然而這還僅僅是一個雛形,應用系統的場景是多種多樣的,在將來須要解決的問題每每不只僅這些,好比:
 
    
      1  系統存在全文搜索、或是標籤式搜索的場景,爲了提升搜索性能,你可能會引入sphinx中間件;
          sphinx的中文版本爲coreseek(可支持中文全文搜索),。
          詳見官網:http://www.coreseek.cn/
 
      2  爲了提升事務處理的效率,你須要隊列服務器來解決,這個能夠是ttserver + worker的模式;
 
      3  頻繁的處理緩存數據的解析在開發上會比較麻煩,你還能夠更換redis來直接支持數據結構式的緩存...
          redis爲一款支持數據結構緩存及數據持久化的優秀的nosql中間件,
          官網地址:http://redis.io/
 

 備註

        架構設計需秉承的"適用"原則,不一樣業務場景所採起的架構都會有些差別, 此處僅僅討論最多見的擴展思路,關於讀寫分離、數據主備等作法在此不作討論。
        本文所說起的故事情節均屬杜撰,若有雷同,實屬巧合。
相關文章
相關標籤/搜索