小時候老是跟媽媽着去上班。媽媽是兒科醫生。有一天來了一個媽媽帶着他的寶寶掛了媽媽的專家號。寶寶長得很可愛,可是臉上沒有任何表情,腦殼很大,四肢和剛出生的寶寶同樣大。媽媽擡起寶寶的四肢,一放手它又耷拉回去。媽媽說話聲音很沉重,說我直接給你開個證實吧,你能夠再要一個孩子。那個媽媽一句話都沒說,只是坐在那裏抱着她的寶寶。這個媽媽在化工廠工做,每天和染料打交道。這已經不是她的第一個寶寶了,每一個寶寶命運都差很少。這個媽媽的絕望和醫學無關。因此高考的時候,怎麼都不願聽媽媽的。本身報了計算機。媽媽知道後讓我去找老師改回來。我走到半路給媽媽買了件衣服就回來了。媽媽雖然仍是很想讓我學醫,可是看到我買的衣服顯然很高興,也明白她是拗不過個人,只好做罷。php
這個選型主要決定於系統複雜度。先回顧一下。前端
1>單一應用架構:對於一個流量很小的網站來講,只需一個應用,將全部功能都部署在一塊兒,以減小部署節點和成本。以前在上家公司作過一個微信公衆號的開發就是基於這種架構,我和一個大牛的前端架構師兩我的就是一個項目,仍是挺happy的。可是這種架構其實用java的成本有點高,用PHP更快。因此我本身接了個私活作個相似攜程+如家的網站用的就是php。java
2>垂直應用架構:訪問量再大一點,能夠將應用拆成互不相干的幾個應用,以提高效率。8年前剛進人人網的時候用的就是這個架構。由於是社交網站,被拆分紅了SNS,UGC,各個遊戲等子模塊。redis
3>分佈式服務架構:垂直應用多了,交互不可避免,將核心業務抽取出來做爲獨立的服務,造成穩定的服務中心。大概從11年起,人人網逐漸採用這種架構。隨之而來的是採用一些技術,記得最初也採用過RMI的,都是內部調用,防火牆也應該不是問題。可是後來hession和thrift開始流行,咱們又進行了這方面的嘗試。zookeeper用做註冊中心,主要是配置管理方面。算法
4>流動計算架構:當服務愈來愈多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時須要增長一個調度中心基於訪問壓力實時管理集羣容量,資源調度和提升集羣利用率。spring
Dubbo是Alibaba開源的分佈式服務框架,按照分層來架構,使各個層之間解耦合。在咱們項目中,做爲服務層和業務層的橋樑來使用。Dubbo層能夠用servlet容器啓動,也能夠直接用main函數直接加載ApplicationContext。總之,dubbo是依賴於spring來管理的。Dubbo框架設計共劃分了10層。其中服務接口層,配置層,服務代理層是開發須要自行寫入的,用法自行百度。數據庫
下面說一下服務註冊層。它以服務URL爲中心,擴展接口爲RegistryFactory,Registry和RegistryService。打開RegistryFactory的源碼能夠看到,這是一個SPI的,核心工做就是取得其註冊的信息。內部實現類是DubboRegistryFactory。做用就是根據url從一個本地的concurrenthashmap中取出其註冊信息,若是註冊信息不存在,則建立一個。同時將此註冊目錄加入集羣。這種concurrenthashmap的東西要返回視圖,返回的通常都是一個unmodify的拷貝。Dubbo裏爲了減小對apache的依賴,用的是java.util裏的Collections.unmodifiableCollection。apache
集羣層。這一層是上面提到的流動架構的體現。封裝多個提供者的路由及負載均衡,並橋接註冊中心,以Invoker爲中心,擴展接口爲Cluster,Directory,Router和LoadBalance。從SPI的配置文件來看,支持4種經常使用的負載均衡緩存
random=com.alibaba.dubbo.rpc.cluster.loadbalance.RandomLoadBalance roundrobin=com.alibaba.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance leastactive=com.alibaba.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance consistenthash=com.alibaba.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance
具體類裏基本都是算法的實現,能夠不用看了。Cluster支持的算法以下:微信
mock=com.alibaba.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper failover=com.alibaba.dubbo.rpc.cluster.support.FailoverCluster failfast=com.alibaba.dubbo.rpc.cluster.support.FailfastCluster failsafe=com.alibaba.dubbo.rpc.cluster.support.FailsafeCluster failback=com.alibaba.dubbo.rpc.cluster.support.FailbackCluster forking=com.alibaba.dubbo.rpc.cluster.support.ForkingCluster available=com.alibaba.dubbo.rpc.cluster.support.AvailableCluster mergeable=com.alibaba.dubbo.rpc.cluster.support.MergeableCluster broadcast=com.alibaba.dubbo.rpc.cluster.support.BroadcastCluster
監控層:RPC調用次數和調用時間監控,以Statistics爲中心,擴展接口爲MonitorFactory, Monitor和MonitorService。實現上和註冊層的實現是同樣的。
遠程調用層:封裝RPC調用,以Invocation和Result爲中心,擴展接口爲Protocol,Invoker和Exporter。Protocal是服務域,它是Invoker暴露和引用的主功能入口,負責Invoker的生命週期管理。Invoker是實體域,它是Dubbo的核心模型,其餘模型轉換成它。它表明一個可執行體,可向它發起invoker調用,它有多是一個本地實現,也多是一個遠程的實現,也多是一個集羣實現。相信瞭解過java動態代理的話,這個不難理解。
信息交換層:封裝請求響應模式,同步轉異步,以Request和Response爲中心,擴展接口爲Exchanger,ExchangeChannel,ExchangeClient和ExchangeServer。
網絡傳輸層:抽象mina和netty爲統一接口,以Message爲中心,擴展接口爲Channel,Transporter,Client,Server和Codec。
數據序列化層:可複用的一些工具,擴展接口爲Serialization,ObjectInput,ObjectOutput和ThreadPool。
能夠以dubbo配置項的解析爲入口跟進源碼。在dubbo jar包下META-INF裏面的spring.handlers裏,有自定義的spring命名空間處理器,能夠找到對應的java類。dubbo的引入不可避免的帶來IO,像我們寫代碼的,這兒壓縮幾個字節,那兒解開一個循環,這些代碼優化可能輕易就被低效的IO所抵消。IO操做比在內存中進行數據處理所需的時間通常長20倍。前段時間用CAT作性能監控就發現,若是沒有dubbo層大概幾ms的操做,引入dubbo執行時間正常都在幾百ms。因此SOA要謹慎。要懂一些底層原理的話,其實架構的選擇就能少些糾結,看各類框架也能立刻就明白。網友問我在讀什麼書,其實如今不多有時間讀,開放平臺項目進入聯調階段了,還有不少細節能夠優化的地方,仍是挺忙的。之因此看到個人文章亂序嚴重也是由於我是用特別零散的時間來寫的。可是前段時間不是看了<netty in action>嘛,看這本書就不得再也不看看<java nio>作一下對比,看了<java nio>呢,裏面做者又推薦讀一下《操做系統第六版》,話說我大學也是計算機的,可是這本書仍是須要從新看一遍的。每本書做者都會引入一些相關的好書,因此個人書單永遠空不了。
dubbo底層不論是用mina也好,netty也好,IO原理都是同樣的。好比和底層相關的,以前我也提到我曾經本身分析過圖片的二進制流來獲取圖片翻轉信息。在這個過程當中我瞭解到和底層操做系統相關的兩個標準,Intel標準和摩托羅拉標準。分別對應兩種字節順序:大端字節順序和小端字節順序。瞭解這個對於nio的緩衝區也有幫助。而通道不是分爲單工,雙工,半雙工嘛。面向流的socket確定是雙工的,因此流在網絡中請求和響應的讀寫操做才能夠同時進行。而像文件IO這樣的,讀寫確定是分離的,單工進行的。
上週有人問我咱們的項目使用緩存和數據庫就能解決問題,爲啥要開發一個搜索引擎,考慮問題的角度不是應該放在數據分析上嗎?我表示贊成他的觀點,由於我本身沒組織好語言說服不了人家的時候我都是這個態度。實際上,首先說咱們已經分析出來了,瓶頸就在緩存上了。緩存採用memcached也是緩存,redis也是緩存。實際上solr也是緩存啊!這種緩存是基於多維數據結構的獲取,合適咱們的項目也合適不少列表帶維度的項目。我認爲之後是頗有前景的。而solr或者說es或者說dubbo或者memcached或者redis面臨的問題都是同樣的,性能嘛,而性能最大的消耗點就是io。咱們項目用的dubbo+緩存。是兩次跨網絡的io。dubbo解決的是服務複用的問題,緩存解決的是空間換時間的問題,搜索引擎能夠作爲一個獨立的服務一次io同時解決這兩個問題,我爲啥讓人家明白不了呢