姓名:白國樂
學(xué)號:17021210898
專業(yè):信號與信息處理
轉(zhuǎn)載自:http://geek.csdn.net/news/detail/244695擎鸠,有刪節(jié)
【嵌牛導(dǎo)讀】微服務(wù)架構(gòu)模式(Microservice Architect Pattern)乌奇。近兩年在服務(wù)的瘋狂增長與云計算技術(shù)的進(jìn)步,讓微服務(wù)架構(gòu)受到重點關(guān)注
【嵌牛鼻子】JAVA
【嵌牛提問】什么是微服務(wù)架構(gòu)?
【嵌牛正文】微服務(wù)架構(gòu)是一種架構(gòu)模式,它提倡將單一應(yīng)用程序劃分成一組小的服務(wù),服務(wù)之間互相協(xié)調(diào)、互相配合课竣,為用戶提供最終價值。每個服務(wù)運(yùn)行在其獨立的進(jìn)程中置媳,服務(wù)與服務(wù)間采用輕量級的通信機(jī)制互相溝通(通常是基于HTTP的RESTful
API)于樟。每個服務(wù)都圍繞著具體業(yè)務(wù)進(jìn)行構(gòu)建,并且能夠被獨立地部署到生產(chǎn)環(huán)境拇囊、類生產(chǎn)環(huán)境等迂曲。另外,應(yīng)盡量避免統(tǒng)一的寥袭、集中式的服務(wù)管理機(jī)制路捧,對具體的一個服務(wù)而言,應(yīng)根據(jù)業(yè)務(wù)上下文传黄,選擇合適的語言杰扫、工具對其進(jìn)行構(gòu)建。
微服務(wù)架構(gòu)優(yōu)勢
首先簡單介紹了微服務(wù)(Microservices)的內(nèi)涵及優(yōu)勢膘掰,微服務(wù)架構(gòu)的本質(zhì)章姓,是用一些功能比較明確、業(yè)務(wù)比較精練的服務(wù)去解決更大识埋、更實際的問題凡伊。微服務(wù)架構(gòu)將服務(wù)拆分,分別采用相對獨立的服務(wù)對各方面進(jìn)行管理窒舟,彼此之間使用統(tǒng)一的接口來進(jìn)行交流系忙,架構(gòu)變得復(fù)雜,優(yōu)勢也很明顯:
復(fù)雜度可控:在將應(yīng)用分解的同時惠豺,規(guī)避了原本復(fù)雜度無止境的積累银还。每一個微服務(wù)專注于單一功能,并通過定義良好的接口清晰表述服務(wù)邊界洁墙。由于體積小见剩、復(fù)雜度低,每個微服務(wù)可由一個小規(guī)模開發(fā)團(tuán)隊完全掌控扫俺,易于保持高可維護(hù)性和開發(fā)效率苍苞。
什么是微服務(wù)架構(gòu)
微服務(wù)架構(gòu)優(yōu)勢
獨立部署:由于微服務(wù)具備獨立的運(yùn)行進(jìn)程,所以每個微服務(wù)也可以獨立部署狼纬。當(dāng)某個微服務(wù)發(fā)生變更時無需編譯羹呵、部署整個應(yīng)用。由微服務(wù)組成的應(yīng)用相當(dāng)于具備一系列可并行的發(fā)布流程疗琉,使得發(fā)布更加高效冈欢,同時降低對生產(chǎn)環(huán)境所造成的風(fēng)險,最終縮短應(yīng)用交付周期盈简。
技術(shù)選型靈活:微服務(wù)架構(gòu)下凑耻,技術(shù)選型是去中心化的太示。每個團(tuán)隊可以根據(jù)自身服務(wù)的需求和行業(yè)發(fā)展的現(xiàn)狀,自由選擇最適合的技術(shù)棧香浩。由于每個微服務(wù)相對簡單类缤,當(dāng)需要對技術(shù)棧進(jìn)行升級時所面臨的風(fēng)險較低,甚至完全重構(gòu)一個微服務(wù)也是可行的邻吭。
容錯:當(dāng)某一組建發(fā)生故障時餐弱,在單一進(jìn)程的傳統(tǒng)架構(gòu)下,故障很有可能在進(jìn)程內(nèi)擴(kuò)散囱晴,形成應(yīng)用全局性的不可用膏蚓。在微服務(wù)架構(gòu)下,故障會被隔離在單個服務(wù)中畸写。若設(shè)計良好驮瞧,其他服務(wù)可通過重試、平穩(wěn)退化等機(jī)制實現(xiàn)應(yīng)用層面的容錯枯芬。
擴(kuò)展:單塊架構(gòu)應(yīng)用也可以實現(xiàn)橫向擴(kuò)展剧董,就是將整個應(yīng)用完整的復(fù)制到不同的節(jié)點。當(dāng)應(yīng)用的不同組件在擴(kuò)展需求上存在差異時破停,微服務(wù)架構(gòu)便體現(xiàn)出其靈活性纬纪,因為每個服務(wù)可以根據(jù)實際需求獨立進(jìn)行擴(kuò)展旁涤。
互聯(lián)網(wǎng)高并發(fā)相關(guān)名詞
頁面瀏覽數(shù)(page views )
唯一身份瀏覽量(Unique PageViews)
獨立訪問者數(shù)量(unique visitors)
重復(fù)訪問者數(shù)量(repeat visitors)
每個訪問者的頁面瀏覽數(shù)(Page Views per user)
高并發(fā)
之前我將高并發(fā)的解決方法誤認(rèn)為是線程或者是隊列可以解決,因為高并發(fā)的時候是有很多用戶在訪問,導(dǎo)致出現(xiàn)系統(tǒng)數(shù)據(jù)不正確糠爬、丟失數(shù)據(jù)現(xiàn)象获诈,所以想到
的是用隊列解決劳澄,其實隊列解決的方式也可以處理羹蚣,比如我們在競拍商品、轉(zhuǎn)發(fā)評論微博或者是秒殺商品等朗鸠,同一時間訪問量特別大蚯撩,隊列在此起到特別的作用,將
所有請求放入隊列烛占,以毫秒計時單位胎挎,有序的進(jìn)行,從而不會出現(xiàn)數(shù)據(jù)丟失系統(tǒng)數(shù)據(jù)不正確的情況忆家。
經(jīng)過查資料犹菇,高并發(fā)的解決方法有倆種,一種是使用緩存芽卿、另一種是使用生成靜態(tài)頁面揭芍;還有就是從最基礎(chǔ)的地方優(yōu)化我們寫代碼減少不必要的資源浪費(fèi):(
1.不要頻繁的new對象,對于在整個應(yīng)用中只需要存在一個實例的類使用單例模式.對于String的連接操作,使用StringBuffer或者StringBuilder.對于utility類型的類通過靜態(tài)方法來訪問。
避免使用錯誤的方式,如Exception可以控制方法推出,但是Exception要保留stacktrace消耗性能,除非必要不要使用
instanceof做條件判斷,盡量使用比的條件判斷方式.使用JAVA中效率高的類,比如ArrayList比Vector性能好卸例。)
高并發(fā) - 需要解決的問題
一:應(yīng)用緩存
二:HTTP緩存
三:多級緩存
四:池化
五:異步并發(fā)
六:擴(kuò)容
七:隊列
高并發(fā)-應(yīng)用緩存
堆緩存
使用Java堆內(nèi)存來存儲緩存對象称杨。使用堆緩存的好處是沒有序列化/反序列化肌毅,是最快的緩存。缺點也很明顯姑原,當(dāng)緩存的數(shù)據(jù)量很大時悬而,GC(垃圾回收)暫停時間會變長,存儲容量受限于堆空間大小页衙。一般通過軟引用/弱引用來存儲緩存對象,即當(dāng)堆內(nèi)存不足時阴绢,可以強(qiáng)制回收這部分內(nèi)存釋放堆內(nèi)存空間店乐。一般使用堆緩存存儲較熱的數(shù)據(jù)。有
Guava
Cache:
緩存和ConcurrentMap是非常相像的呻袭,但是它們也不完全一樣眨八。最根本的區(qū)別就是,ConcurrentMap會持有所有添加的對象左电,直到被顯示的移除廉侧。而緩存為了限制其內(nèi)存的使用,通常都會配置成可以自動的將對象移除篓足。在某些情況下即使不自動移除對象也是非常有用的段誊,如LoadingCache它會自動加載緩存對象。
Ehcache 3.x:是一種廣泛使用的開源Java分布式緩存栈拖。主要面向通用緩存,Java EE和輕量級容器连舍。它具有內(nèi)存和磁盤存儲,緩存加載器,緩存擴(kuò)展,緩存異常處理程序,一個gzip緩存servlet過濾器,支持REST和SOAP api等特點涩哟。
MapDB: mapdb是一個內(nèi)嵌的純java的數(shù)據(jù)庫索赏,提供了并發(fā)的HashMap、TreeMap贴彼、Queue潜腻,可以基于堆外或者磁盤來存儲數(shù)據(jù)
高并發(fā)-應(yīng)用緩存
堆外緩存
即緩存數(shù)據(jù)存儲在堆外內(nèi)存,可以減少GC暫停時間(堆對象轉(zhuǎn)移到堆外器仗,GC掃描和移動的對象變少)融涣,但是,讀取數(shù)據(jù)時需要序列化/反序列化精钮,因此會比堆緩存要慢很多暴心。有Ehcache 3.x、MapDB實現(xiàn)
磁盤緩存
即緩存數(shù)據(jù)存儲在磁道上杂拨,在JVM重啟時數(shù)據(jù)還存在的专普,而堆緩存/堆外緩存數(shù)據(jù)會丟失,需要重新加載弹沽。有Ehcache 3.x檀夹、MapDB實現(xiàn)
分布式緩存
進(jìn)程內(nèi)緩存和磁盤緩存筋粗,在多JVM實例的情況下,會存在兩個問題:
1炸渡、單機(jī)容量問題娜亿;
2、數(shù)據(jù)一致性問題(多臺JVM實例的緩存數(shù)據(jù)不一致怎么辦蚌堵?)买决,這個問題不用糾結(jié),既然數(shù)據(jù)允許緩存吼畏,則表示允許一定時間內(nèi)的不一致督赤,因此可以設(shè)置緩存數(shù)據(jù)的過期時間來定期更新數(shù)據(jù);
3泻蚊、緩存不命中時躲舌,需要回源到DB/服務(wù)請求多變問題:每個實例在緩存不命中的情況下都會回源到DB加載數(shù)據(jù),因此多實例后DB整體的訪問量變多了解決辦法是可以使用如一致性哈希分片算法性雄。因此没卸,這些情況可以考慮使用分布式緩存來解決。
可以使用ehcache –clustered(配合 Terracotta server) 實現(xiàn)JAVA進(jìn)程間分布式緩存秒旋。最好的辦法是使用redis實現(xiàn)分布式緩存约计。
高并發(fā)- HTTP緩存
瀏覽器緩存是指當(dāng)我們使用瀏覽器訪問一些網(wǎng)站頁面或者h(yuǎn)ttp服務(wù)時,根據(jù)服務(wù)端返回的緩存設(shè)置響應(yīng)頭將響應(yīng)內(nèi)容緩存到瀏覽器迁筛,下次可以直接使用緩存內(nèi)容或者僅需要去服務(wù)端驗證內(nèi)容是否過期即可病蛉。這樣的好處可以減少瀏覽器和服務(wù)端之間來回傳輸?shù)臄?shù)據(jù)量,節(jié)省帶寬提升性能瑰煎。
解決辦法:內(nèi)容不需要動態(tài)(計算铺然、渲染等)速度更快,內(nèi)容越接近于用戶速度越快酒甸。像apache traffic server魄健、squid、varnish插勤、nginx等技術(shù)都可以來進(jìn)行內(nèi)容緩存沽瘦。還有CDN就是用來加速用戶訪問的:
即用戶首先訪問到全國各地的CDN節(jié)點(使用如ATS、Squid實現(xiàn))农尖,如果CDN沒命中析恋,會回源到中央nginx集群,該集群如果沒有命中緩存(該集群的緩存不是必須的盛卡,要根據(jù)實際命中情況等決定)助隧,最后回源到后端應(yīng)用集群。
高并發(fā)- 多級緩存(分布式緩存)
高并發(fā)-池化
在應(yīng)用系統(tǒng)開發(fā)過程中滑沧,我們經(jīng)常會用到池化技術(shù)并村,如對象池巍实、連接池、線程池等哩牍,通過池化來減少一些消耗棚潦,以提升性能。
對象池通過復(fù)用對象從而減少創(chuàng)建對象膝昆、垃圾回收 的開銷丸边。但是,池化不能太大荚孵,太大會影響GC時的掃描時間妹窖。
連接池如數(shù)據(jù)庫連接池、Redis連接池处窥、Http連接池嘱吗,通過復(fù)用TCP連接減少創(chuàng)建和釋放連接的時間來提升性能玄组。
線程池也是類似的滔驾,通過復(fù)用線程提升性能。也就是說池化的目的就是通過復(fù)用技術(shù)提升性能俄讹。
高并發(fā)-擴(kuò)容
1哆致、讀寫分離:當(dāng)數(shù)據(jù)庫訪問量還不是很大的時候,我們可以適當(dāng)增加服務(wù)器患膛,數(shù)據(jù)庫主從復(fù)制的方式將讀寫分離
2摊阀、垂直分區(qū):當(dāng)寫入操作一旦增加的時候,那么主從數(shù)據(jù)庫將花更多的時間的放在數(shù)據(jù)同步上踪蹬,這個時候服務(wù)器也是不堪重負(fù)的胞此;那么就有了數(shù)據(jù)的垂直分區(qū),數(shù)據(jù)的垂直分區(qū)思路是將寫入操作比較頻繁的數(shù)據(jù)表跃捣,如用戶表_user,或者訂單表_orders,那么我們就可以把這個兩個表分離出來漱牵,放在不同的服務(wù)器,如果這兩個表和其他表存在聯(lián)表查詢疚漆,那么就只能把原來的sql語句給拆分了酣胀,先查詢一個表,在查詢另一個娶聘,雖然說這個會消耗更過性能闻镶,但比起那種大量數(shù)據(jù)同步,負(fù)擔(dān)還是減輕了不少丸升;
3铆农、水平分區(qū):但是往往事情不盡人意,可能采取垂直分區(qū)能撐一段時間狡耻,由于網(wǎng)站太火了顿涣,訪問量又每日100w,一下子蹦到了1000w,這個時候可以采取數(shù)據(jù)的進(jìn)行分離波闹,我們可以根據(jù)user的Id不同進(jìn)行分配,如采取%2涛碑、
形式精堕,當(dāng)然這種形式對以后的擴(kuò)展有了很大的限制,當(dāng)我由10個分區(qū)增加到20個的時候蒲障,所有的數(shù)據(jù)都得重新分區(qū)歹篓,那么將是一個的很龐大的計算量;幾種常見的算法:
哈希算法:就是采用user_id%的方式;
范圍:可以根據(jù)user_id字符值范圍分區(qū)揉阎,如1-1000為一區(qū)庄撮,1001-2000則是另一個區(qū)等;
映射關(guān)系:就是將user_id存在的所對應(yīng)的分區(qū)放在數(shù)據(jù)庫中保存毙籽,當(dāng)用戶操作時先去查詢所在分區(qū)洞斯,再進(jìn)行操作.