摘要:個(gè)人認(rèn)為將此等思想放諸四海而皆準(zhǔn),在微服務(wù)的實(shí)踐過程中,同樣需要謹(jǐn)慎因應(yīng)。不患無位,患所以立當(dāng)微服務(wù)被廣泛地被業(yè)界認(rèn)可和接受時(shí),或許你總會(huì)擔(dān)心在何處實(shí)踐,因此,在心態(tài)上
楔子
目前業(yè)界最流行的微服務(wù)架構(gòu)正在或者已被各種規(guī)模的互聯(lián)網(wǎng)公司廣泛接受和認(rèn)可,業(yè)已成為互聯(lián)網(wǎng)開發(fā)人員必備技術(shù)。無論是互聯(lián)網(wǎng)、云計(jì)算還是大數(shù)據(jù),Java平臺(tái)已成為全棧的生態(tài)體系,其重要性幾乎不可替代。
這兩年微服務(wù)作為一個(gè)非常新的技術(shù),各種理論流派試圖從不同的角度去闡述其概念和優(yōu)勢(shì),我一開始是拒絕的,因?yàn)槲覜]有”Duang“的一下想清楚。個(gè)人感性地認(rèn)知是,姿勢(shì)不對(duì),純靠意會(huì)。理性的看法則是,在思想上,那些布道師們并未達(dá)到一致。經(jīng)過參考各家思想之后,得到了一些自己的領(lǐng)悟,我分享給大家。
微服務(wù)是什么? 微服務(wù)是一種細(xì)粒度(Fine-Grain)的SOA個(gè)人認(rèn)為,與其說微服務(wù)是一種技術(shù),不如將其定義為一種架構(gòu),而架構(gòu)則是“技”的實(shí)現(xiàn)與“術(shù)”的策略相輔相成?!靶g(shù)”的策略需要分析使用場(chǎng)景,進(jìn)行合理地劃分業(yè)務(wù)邊界,實(shí)現(xiàn)“業(yè)以類聚”,然而“技”的實(shí)現(xiàn)則通過特定的技術(shù)在實(shí)現(xiàn)業(yè)務(wù)邏輯之時(shí),更多的考慮實(shí)現(xiàn)過程中的效率性、測(cè)試的便利性、維護(hù)的可持續(xù)性,達(dá)到“技以群分”的目的。
由此而論,我個(gè)人偏好將其定義為:“微服務(wù)是一種細(xì)粒度的SOA”。
這樣定義的好處在于,沒必要去重復(fù)地“抹黑”“單體應(yīng)用”(Monolithic,也有人翻譯成“巨石應(yīng)用”),緣于SOA技術(shù)的衍化過程中早已提及。那么,細(xì)粒度更多的體現(xiàn)在“取其精華,去其糟粕”。
SOA又是什么? SOA = Service-Oriented ArchitectureSOA 中文定義是面向服務(wù)架構(gòu),它并非是今日的重點(diǎn),請(qǐng)?jiān)徫也荒芑ù笃鶃砑右躁U述。我用“點(diǎn)到為止”的方式描述SOA具備哪些特征,以及相關(guān)的技術(shù)。
SOA有什么? 特征面向服務(wù)( Service-Oriented )
松耦合(Loose-Coupling)
模塊化(Modular)
分布式計(jì)算(Distributed Computing)
平臺(tái)無關(guān)性(Independent Platform)
集中管理(Center Government)
技術(shù) Web ServicesWeb Services 技術(shù)演進(jìn)的目的在于解決分布式計(jì)算中,統(tǒng)一異構(gòu)系統(tǒng)的服務(wù)調(diào)用的通訊協(xié)議。前期的Web Services有XML-PRC、WSDL、SOAP等技術(shù),不但解決了Windows平臺(tái)COM+以及Java 平臺(tái)RMI無法跨平臺(tái)的問題,而且使用了可讀性強(qiáng)的本文協(xié)議替代了復(fù)雜的二進(jìn)制協(xié)議,如CORBA技術(shù)?,F(xiàn)代的WebServices 技術(shù)主要代表有REST等。
Message QueueMessage Queue 技術(shù)設(shè)計(jì)的目的主要有兩個(gè)方面,從架構(gòu)上來說,消息隊(duì)列服務(wù)幫助系統(tǒng)之間依賴關(guān)系解耦;從技術(shù)上來看,消息隊(duì)列為系統(tǒng)提供異步處理的能力,解決了并發(fā)同步調(diào)用導(dǎo)致資源消耗過集中和過快等問題,將上下游系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)提供了統(tǒng)一的傳輸介質(zhì)。
ESBESB 則是 SOA 集大成實(shí)現(xiàn)。
SOA不是什么? SOA ≠ MonolithicSOA 不但不是Monolithic,而且是要解決Monolithic,Monolithic 個(gè)人偏好翻譯成“單體應(yīng)用”,也被翻譯成“巨石應(yīng)用”。Monolithic是什么? 故宮
故宮.png
朋友可能覺得奇怪,故宮與“單體應(yīng)用”有什么關(guān)系?故宮是帝王居住和辦公的場(chǎng)所,她象征著“最高權(quán)利”和“中央集權(quán)”。華夏民族,自秦朝的“三公九卿制”,還是隋朝的“三省六部制”,以及明清的“內(nèi)閣制度”,無一例外地致力于鞏固“中央集權(quán)”。
近兩千年來,雖然王朝不斷更迭,這個(gè)制度一直被沿用,并且沒有出現(xiàn)大的詬病??墒?,1793年,英國(guó)勛爵馬戛爾尼出使中國(guó),代表英皇為乾隆皇帝祝壽,也負(fù)有促成中英通商的使命。雖然當(dāng)時(shí)的中國(guó)籠罩在“乾隆盛世”的光環(huán)下,不過在馬戛爾尼看來中國(guó)無論從科技還是社會(huì)制度上,均處于相對(duì)落后的階段?!蹲髠鳌酚醒裕骸懊裰嘈?,國(guó)之不幸”,當(dāng)時(shí)的大多數(shù)國(guó)民視英國(guó)為“蠻夷”,不與商貿(mào)往來。五十年后,中英鴉片戰(zhàn)爭(zhēng)爆發(fā),1840年,中華帝國(guó)第一個(gè)不平等條約《南京條約》被迫簽訂,它不但打擊中華名族,而且“打醒”了大和民族。明治維新后的日本,屢屢挑戰(zhàn)中國(guó)的東亞地位,直到中日甲午戰(zhàn)爭(zhēng)失利。1895年《馬關(guān)條約》簽訂,割臺(tái)灣,賠巨款。但仍有康有為等不愿放棄,聯(lián)名千人“公車上書”,認(rèn)為“中央集權(quán)”并不是問題所在?!爸醒爰瘷?quán)”職責(zé)臃腫,行政不力,中央政策想要對(duì)地方面面俱到是不可能的,無法做到“因地制宜”。
我想說的是,單體應(yīng)用不正像一個(gè)“中央集權(quán)”的政府嗎?而微服務(wù)應(yīng)用則更像“多權(quán)分立”的“自治”政府,各個(gè)“自治”政府之間在“聯(lián)邦”的架構(gòu)下“分工”和“協(xié)作”。
為什么要微服務(wù)? 效率的需要應(yīng)用進(jìn)行微服務(wù)化后,規(guī)模和體積變得更加輕量級(jí),在編譯、打包、分發(fā)、部署等環(huán)節(jié)節(jié)約了時(shí)間,開發(fā)上效率提升。
質(zhì)量的需要微服務(wù)應(yīng)用面向持續(xù)集成友好,自動(dòng)化編譯、單元和集成測(cè)試用例執(zhí)行和回歸,提高應(yīng)用整體質(zhì)量。
穩(wěn)定的需要當(dāng)應(yīng)用大而全時(shí),往往牽一發(fā)而動(dòng)全身,其中一個(gè)服務(wù)出現(xiàn)問題,整體受到牽動(dòng)效應(yīng)。整體穩(wěn)定性得不到保證,因此,經(jīng)過微服務(wù)化后,應(yīng)用由原來的服務(wù)內(nèi)部組裝到服務(wù)自由組合,一旦關(guān)聯(lián)服務(wù)存在問題,整體應(yīng)用可以選擇性地降級(jí)或熔斷等措施,待問題服務(wù)恢復(fù),一切照常執(zhí)行。
運(yùn)維的需要微服務(wù)應(yīng)用具備自動(dòng)化編譯、打包、分發(fā)、部署和運(yùn)維的能力。傳統(tǒng)的應(yīng)用不但需要開發(fā)、還需要測(cè)試和運(yùn)維人員,微服務(wù)應(yīng)用實(shí)現(xiàn)后,將理想化的全棧(Full-Stack)工程師變?yōu)榭赡堋?/p> 成長(zhǎng)的需要
微服務(wù)能夠更好,更快地適配新技術(shù),比如目前流行的Apache Kafka。而工程人員需要接觸新的技術(shù),為未來可能的技術(shù)選型做好準(zhǔn)備。我的建議在一些不那么重要的微服務(wù)應(yīng)用中,可以嘗試一些新的技術(shù),在其提供的功能與實(shí)際需要之間,找到一些自己的理解,也是自我成長(zhǎng)的需要。
為什么不必微服務(wù)?論語有言:“子絕四:‘毋意、毋必、毋固、毋我’?!保?jiǎn)單地說,不要臆斷,不要固執(zhí),不要自我感覺良好,也有什么是必定的。那么,在微服務(wù)實(shí)踐過程中,哪些因素可以不必微服務(wù)呢?請(qǐng)注意用詞,這里說的是“不必”,不是“不要”。場(chǎng)景單一
當(dāng)應(yīng)用的場(chǎng)景單一時(shí),沒有必要非得微服務(wù),因?yàn)樗旧砭褪俏⒎?wù),例如一些靜態(tài)的通告頁面。邏輯簡(jiǎn)單
當(dāng)應(yīng)用邏輯簡(jiǎn)單時(shí),同樣也違背了微服務(wù)的初衷,因?yàn)槲⒎?wù)是為了解決復(fù)雜業(yè)務(wù)邏輯而衍生,因此這種情況下也不必實(shí)施微服務(wù)。
業(yè)務(wù)漸逝首先,我解釋一下“漸逝”,也就是逐漸消逝的意思。當(dāng)應(yīng)用所關(guān)注的業(yè)務(wù)趨于消逝狀態(tài)時(shí),盡管有實(shí)施的空間,但無實(shí)施的必要。因?yàn)檫@樣的應(yīng)用隨時(shí)可能不復(fù)存在,好比沒有必要去對(duì)BB機(jī)或者短信業(yè)務(wù)大張旗鼓的重構(gòu)一般。
“老成持重”老成持重的原意是形容人做事情老練和沉穩(wěn)。這里我引用了這個(gè)成語,是為了方便記憶,需要將其拆開,多帶帶解釋。
“老”是指年老的應(yīng)用,多久算得上年老呢?個(gè)人經(jīng)驗(yàn),應(yīng)用服役年齡超過三年以上。
“成”則表示應(yīng)用的規(guī)模已成形,業(yè)務(wù)上幾乎不再變化,比如通知應(yīng)用。
“持”說明應(yīng)用的場(chǎng)景還將持續(xù)較長(zhǎng)時(shí)間。
“重”表示應(yīng)用所處的位置舉足輕重,不能隨時(shí)重構(gòu),比如交易應(yīng)用。
當(dāng)應(yīng)用符合其中一條以上的特征時(shí),該應(yīng)用不必實(shí)行微服務(wù)。
技術(shù)盲從這一點(diǎn)是我最為關(guān)注,也是最擔(dān)心朋友觸犯的。我們同為工程人員,對(duì)技術(shù)的追求毋容置疑,可是千萬不能因?yàn)榧夹g(shù)而技術(shù),新的技術(shù)推出或是解決現(xiàn)有問題,或是提供便利性,可是也有夸大其詞的成分。理性地評(píng)估和謹(jǐn)慎地實(shí)施,更是我們更要關(guān)注的地方。技術(shù)困難挑戰(zhàn)聰明才智,理智對(duì)待則考驗(yàn)情緒控制。
How
前面提到的部分是“What”和“Why”,接下來,進(jìn)入“How”的部分,顧名思義,就是怎么做,如何做的意思。
“多見闕殆,慎行其余”
以上兩句處于孔子的學(xué)生子張請(qǐng)教孔子關(guān)于如何干好工,孔子的回答是:“多聞闕疑,慎言其余,則寡尤。多見闕殆,慎行其余,則寡悔。言寡尤,行寡悔,祿在其中矣”。儒家經(jīng)典總在告誡我們,言行需謹(jǐn)慎,如臨深淵、如履薄冰,戰(zhàn)戰(zhàn)兢兢。個(gè)人認(rèn)為將此等思想放諸四海而皆準(zhǔn),在微服務(wù)的實(shí)踐過程中,同樣需要謹(jǐn)慎因應(yīng)。
怎么實(shí)現(xiàn)微服務(wù)
怎么樣實(shí)現(xiàn)微服務(wù),我想從以下三個(gè)方面來說明:
心態(tài)
技術(shù)
思想
心態(tài)
“子路有聞,未之能行,唯恐有聞”
句中的開頭二字“子路”,是一個(gè)人名??鬃娱T徒三千,七十二賢,最著名的是“孔門十哲”,其中就包括子路。子路,也就是仲由,字子路。整句話的意思是說,子路聽到新的知識(shí)或者道理,沒有付諸于實(shí)踐,又擔(dān)心新的知識(shí)或道理的出現(xiàn)。這句話能很好地反應(yīng)當(dāng)今這個(gè)浮躁的互聯(lián)網(wǎng)時(shí)代,看似科技突飛猛進(jìn),新的技術(shù)層出不窮,而實(shí)踐不力,導(dǎo)致首鼠兩端的心態(tài)。凡是他人掌握了新的技術(shù),自己卻沒有,就覺得不如人,反之亦然。我想告訴大家的是,微服務(wù)并不是新的技術(shù),而是新的思路,只不過咨詢發(fā)達(dá),加上基礎(chǔ)的沉淀,讓老的技術(shù)或理論在新的時(shí)代能夠“飛入尋常百姓家”。
“不患無位,患所以立”
當(dāng)微服務(wù)被廣泛地被業(yè)界認(rèn)可和接受時(shí),或許你總會(huì)擔(dān)心在何處實(shí)踐,因此,在心態(tài)上,需要做到不要擔(dān)心它花落誰家,更要放平心態(tài),思考它為什么存在的理由。
“攻乎異端,斯害也已”
當(dāng)你或你的團(tuán)隊(duì)在推廣微服務(wù)過程中,你得首先做好被挑戰(zhàn)甚至是攻擊的準(zhǔn)備,據(jù)不完全統(tǒng)計(jì),世界上有5%的人,是因?yàn)榉磳?duì)而反對(duì)的人。但是反對(duì)負(fù)面情緒可能會(huì)印象其他50%的人。由此前提之后,還需具備攻擊“異端邪說”的能力,這樣就能達(dá)到“斯害也已”(這種危害也可以被消滅)。
“過則勿憚改”
最后一種心態(tài)則是不要怕犯錯(cuò),錯(cuò)了不要忌憚改正。作為工程人員,實(shí)施的過程中不出錯(cuò)是不可能的,除非不去做。不要畏懼犯錯(cuò),犯錯(cuò)也是更好地縮小內(nèi)心期望和現(xiàn)實(shí)情況的鴻溝,不犯錯(cuò)就沒有成長(zhǎng)的空間,因此,不怕錯(cuò),也不忌改正。 前面的部分用了不少詩詞,接下來就不會(huì)那么“詩”了,來點(diǎn)“干”的,也是今天的技術(shù)重頭戲。馬上進(jìn)入技術(shù)的部分。
技術(shù)
技術(shù)上,在阿里微服務(wù)的實(shí)踐過程中也不能免俗,基本上也是以下三個(gè)套路:
Docker
DDD
Middleware(Java)
Docker
在阿里巴巴集團(tuán)技術(shù)體系中,自行研發(fā)與Docker兼容的AliDocker,并且提供了一些其他能力和輔助工具。本人相對(duì)這塊不是特別熟悉,如果大家需要進(jìn)一步的了解,可以考慮后續(xù)加入“微服務(wù)技術(shù)交流”群中,與我的同事一同討論和交流,這里只能做一些簡(jiǎn)單地介紹。
測(cè)試環(huán)境:AliDocker + ECS(阿里云)
生成環(huán)境:AliDocker + 物理機(jī)
DDD
DDD是Domain Driven Design(領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))的簡(jiǎn)寫,該技術(shù)源于Eric Evans 在其名著《Domain Driven Design》。從年代來看,已是相當(dāng)老的設(shè)計(jì)方法論了。它作為微服務(wù)重要的理論依據(jù),如今又如“鳳凰涅槃”一般,重新進(jìn)入軟件領(lǐng)域的視野。DDD的三大實(shí)施策略在具體微服務(wù)實(shí)踐過程中,取二舍一。當(dāng)然,整個(gè)DDD的理論并不限于此,個(gè)人理解,DDD好像是一個(gè)傳說,大家都聽說過,但是誰也沒有見到過。而是實(shí)現(xiàn)這種理想就如同烏托邦式的“共產(chǎn)主義”,目前仍未到時(shí)候。
有界上下文(Bounded Context)
有界上下文的思想,個(gè)人認(rèn)為是在《設(shè)計(jì)模式》中的“單職責(zé)原則”進(jìn)一步發(fā)展而言。其實(shí)也體現(xiàn)了東西方文化的差異,東方是以古代中國(guó)為代表的“中央集權(quán)”思想,和古希臘城邦的“三權(quán)分立”的民治思想。微服務(wù)則屬于“權(quán)力分立”思想的范疇。在微服務(wù)實(shí)踐過程中,確定應(yīng)用邊界是必要的,也是困難的。必要性反應(yīng)在系統(tǒng)職責(zé)劃分,要簡(jiǎn)約、清晰,不耦合。困難性則體現(xiàn)在重構(gòu)過程不是一蹴而就,而是循序漸進(jìn),同時(shí),應(yīng)用還伴隨著業(yè)務(wù)發(fā)展而同步開發(fā),其間的困難是可預(yù)知的。雖然過程是痛苦的,但是也不得不去做。
持續(xù)集成(Continuous integration)
持續(xù)集成是繼承了TDD(Test Driven Development,測(cè)試驅(qū)動(dòng)開發(fā))的思想,對(duì)應(yīng)形成規(guī)模的公司而言,基本上都部署了持續(xù)集成的環(huán)境,在阿里則是Aone 系統(tǒng)來統(tǒng)籌。一些流行的開源軟件,如GitLab、Jenkins(Hudson)等。
上下文映射(Context Map)
以上兩個(gè)策略均在實(shí)踐中被采納,那么上下文映射(Context Map)則被舍棄,舍棄的原因并不在于其不合理,而是難以駕馭。例如,用戶服務(wù)提供用戶的模型,其中包括了姓名、生日、電話等。可是下游系統(tǒng),需要僅僅需要用戶的姓名信息,而實(shí)際情況,用戶服務(wù)無法提供這么細(xì)粒度的服務(wù),那么不得不在中間做一層上下文映射,將兩者不再直接關(guān)聯(lián)。這種情況貌似還看不出端倪,可是為服務(wù)化后,服務(wù)數(shù)量眾多,其映射環(huán)節(jié)基本上不可控制,下游系統(tǒng)配合改動(dòng)也是代價(jià)頗高,因此,在實(shí)踐過程中,還是保持原有的調(diào)用關(guān)系。盡量做到改造過程中,減低錯(cuò)誤率。
Middleware
中間件是微服務(wù)實(shí)施過程中不可或缺的一個(gè)環(huán)節(jié),實(shí)現(xiàn)中間件的編程語言可以任意,不過目前市場(chǎng)上最為流行還屬Java。經(jīng)剛才粗略的統(tǒng)計(jì),在座的朋友們從事Java居多,本人恰好也相對(duì)熟悉這個(gè)領(lǐng)域。接下來,我們一同來探討,Java 中間件在微服務(wù)實(shí)踐過程中的措施。由于時(shí)間的關(guān)系,無法做到一一列舉,因此,以下每個(gè)小節(jié)均有實(shí)例說明。
Spring
Spring Boot
Spring Cloud
Spring Cloud Stream
Spring Boot DevOps
Spring
Annotation驅(qū)動(dòng)
在微服務(wù)實(shí)踐的過程中,中間件部門向各條業(yè)務(wù)線的開發(fā)推廣,用Annotation驅(qū)動(dòng)的方式替代過去XML配置的方式:
Annotation驅(qū)動(dòng)方式
在Spring 3.1 以及更好的版本中,提供了大量的Annotation作為XML配置的替代一下方式(現(xiàn)場(chǎng)統(tǒng)計(jì),基本上沒有人知道這種方式):
XML配置方式
工程人員相對(duì)XML的方式更為熟悉,以上XML配置了是Spring WebMVC的一些組件Bean。實(shí)際上,除了@EnableWebMvc以外,還提供了很多@EnableXXX的替代方式,例如@EnableAsync、@EnableAspectJAutoProxy等。在實(shí)施過程中,很多開發(fā)人員錯(cuò)誤的認(rèn)為這些是Spring Boot的帶來的便利,其實(shí)不然。
Spring Boot
在Spring Boot 推廣實(shí)施過程中,除了以上Annotation重構(gòu)方式以外,我想在前端渲染引擎選型評(píng)估方面談?wù)勛约旱男牡煤腕w會(huì),建議大家時(shí)刻保持懷疑的態(tài)度,一家之言,僅供參考。
渲染引擎
Thymeleaf(Spring 推薦)
優(yōu)點(diǎn):HTML結(jié)構(gòu)化、UI友好,表達(dá)式功能強(qiáng)大
HTML結(jié)構(gòu)化、UI友好
Thymeleaf 設(shè)計(jì)初衷就是針對(duì)UI友好,讓開發(fā)人員在編輯模板頁面時(shí),遵循標(biāo)準(zhǔn)HTML結(jié)構(gòu)。
表達(dá)式功能強(qiáng)大
不但兼容標(biāo)準(zhǔn) OGNL 表達(dá)式,而且也支持Spring 表達(dá)。Spring 表達(dá)式為Spring 3 之后推出的重要功能提供動(dòng)態(tài)的執(zhí)行程序的能力。
缺點(diǎn):編碼略微繁瑣、性能一般、擴(kuò)展復(fù)雜
編碼略微繁瑣
沒有比較不存在優(yōu)劣,Thymeleaf 在編輯過程中相對(duì)繁瑣,相比較于Velocity和JSP而言。
性能一般
最明顯的缺點(diǎn)是,性能著實(shí)一般,因此,不建議用在訪問過頻繁的頁面,比如寶貝詳情頁面。
擴(kuò)展復(fù)雜
Thymeleaf 元素標(biāo)簽相對(duì)比較復(fù)雜。 以下為 Thymeleaf 模板頁面的內(nèi)容,其中“th”為Thymeleaf 標(biāo)簽(tag)的命名空間(namespace):
Thymeleaf 模板頁面
Velocity(廣泛應(yīng)用)
優(yōu)點(diǎn):性能良好、易于擴(kuò)展、事件處理、配置靈活
性能良好
相比較于 Thymeleaf 而言,Velocity的性能良好。
易于擴(kuò)展
在擴(kuò)展性方面,Velocity提供宏(Marco)擴(kuò)展,實(shí)現(xiàn)代碼復(fù)用。
事件處理
開發(fā)人員可能對(duì)于事件處理上相對(duì)陌生,我簡(jiǎn)單地介紹以下,Velocity 提"org.apache.velocity.app.event.EventHandler"接口,其中典型代表為:"org.apache.velocity.app.event.ReferenceInsertionEventHandler”接口,主要用于攔截引用插入前的事件。
配置靈活
也是Velocity顯著特點(diǎn),提供了大量靈活的配置項(xiàng),方便開發(fā)人員設(shè)置,例如配置模板位置、字符編碼等。
缺點(diǎn):HTML結(jié)構(gòu)化不友好、發(fā)展停滯
HTML結(jié)構(gòu)化不友好
由于Velocity模板的語法特點(diǎn)并非HTML結(jié)構(gòu)化友好,指令(Directive)以及宏(Marco)均直接在頁面非標(biāo)簽區(qū)域植入,比如 #set 這種寫法。
發(fā)展停滯
Velocity 1.7 版本自2010年以來,不再更新,因此,Spring 4.3 版本(或者Spring Boot 1.4)開始,將Velocity支持標(biāo)記為Deprecated。
常規(guī)Velocity模板
Velocity宏(Marco)
Velocity 指令(Directive)
JSP(Java EE標(biāo)準(zhǔn))
優(yōu)點(diǎn):編碼靈活、兼容性好、性能優(yōu)秀、多種頁面結(jié)構(gòu)化
編碼靈活
較以上兩種模板引擎,JSP編碼方式更為靈活,其中包括:
Scriptlets
早期類PHP腳本語法,即在JSP頁面中直接添加 Java 代碼,這種編程模式稱為 Scriptlets ,其對(duì)應(yīng)的J2EE(當(dāng)時(shí)還稱作J2EE,即現(xiàn)在的Java EE)設(shè)計(jì)模型為Model 1。
EL(Express Language)
由于Scriptlets編程模式在頁面上植入太多的 Java 代碼,代碼既難以復(fù)用,維護(hù)成本又相當(dāng)巨大。JSP 2.0 規(guī)范引入了EL(Express Language)1.0 規(guī)范,隨后該能力被用在J2EE設(shè)計(jì)模式中,逐步發(fā)展成 Model 2 以及 MVC ,JSP頁面不再負(fù)責(zé)數(shù)據(jù)組裝等邏輯,而是僅承載頁面渲染的作用(當(dāng)然還是具備 Scriptlets 能力,只是不推薦使用這種方式)。 兼容性好 JSP屬于Java EE規(guī)范,因此Java EE均提供了實(shí)現(xiàn),比如 Tomcat、Jetty、WebLogic 等等。因此,JSP 具備天然性兼容,不需要額外引入其他資源。
性能優(yōu)秀
JSP屬于解釋編譯型模板語言,無論是 Scriptlets 還是 EL 均可以翻譯成 Java 源文件,然后將 Java 源文件編譯成 Java Class 文件,再經(jīng)過容器加載并且執(zhí)行相關(guān)方法調(diào)用(可參考o(jì)rg.apache.jasper.servlet.JspServlet)。 多種頁面結(jié)構(gòu)化 這個(gè)特點(diǎn)是很多國(guó)內(nèi) Java 工程人員不太關(guān)注的特性,通常將JSP頁面結(jié)構(gòu)定格在HTML,實(shí)際上,它的頁面結(jié)構(gòu)格式可以設(shè)置成更為嚴(yán)格的XHTML,甚至是XML。順便提一句,Thymeleaf 也具備該能力,而 Velocity 不具備。因此,在我看來,JSP 并不是太落伍,而是太超前。
缺點(diǎn):限制表達(dá)式(EL)、擴(kuò)展繁瑣、規(guī)約較多、Servlet強(qiáng)依賴
限制表達(dá)式(EL)
EL 的實(shí)現(xiàn)是OGNL 表達(dá)式的子集,僅實(shí)現(xiàn)了簡(jiǎn)單地?cái)?shù)據(jù)讀取和邏輯運(yùn)行。類似于 Bean 方法調(diào)用這樣的高級(jí)語法,需要配合 JSF 這樣的Web技術(shù)來配合( JSF 叫座不叫好的 Web 框架 )。
擴(kuò)展繁瑣
JSP 擴(kuò)展主要是JSP 標(biāo)簽擴(kuò)展,JSP 標(biāo)簽擴(kuò)展被很多人視為反模式,我倒不怎么認(rèn)為,但是對(duì)其配置上倒是頗為復(fù)雜,舉個(gè)例子,每個(gè) Tag 的屬性需要綁定一個(gè)對(duì)應(yīng)的實(shí)現(xiàn)類屬性,并且類型復(fù)雜,功能各異,比如 IterationTag 和 BodyTag 的作用存在一定的區(qū)別。
規(guī)約較多
JSP 除了tag lib的規(guī)約以外,還有jsp-property-group 等,我用一段web.xml中的配置為例:http://tae-sdk.taobao.com/taglibs/sdk /META-INF/config/taglibs/sdk-web-1.0.tld *.jsp GBK /WEB-INF/jsp/coda/footer.jspf true
Servlet強(qiáng)依賴
JSP 對(duì)于 Servlet API 是強(qiáng)依賴的,主要執(zhí)行邏輯與Servlet 相同( init 方法、service 方法以及 destroy 方法 ),在現(xiàn)代化的Java Web 編程模式中,基本上屏蔽了Servlet API接口,比如 Spring WebMVC 中的@RequestParam 用于獲取請(qǐng)求參數(shù),去取代Servlet API中的 javax.servlet.http.HttpServletRequest#getParameter(String) 方法,因?yàn)樵摲椒▋H返回 String 類型,如要轉(zhuǎn)化成 Integer 類型,不得不調(diào)用 Integer#valueOf(String) 方法進(jìn)行轉(zhuǎn)化。再則,目前流行的HTTP 2 Web服務(wù)器 - Undertow 并不兼容 Servlet API 方案,因此 Spring Boot 官方文檔說明有一段特別說明:
Spring Boot 官方文檔說明
Spring Boot 部分點(diǎn)到為止,會(huì)后可以進(jìn)一步交流,接下來,進(jìn)入Spring Cloud的部分。
Spring Cloud
Spring Cloud 官方提供了基本功能描述,其中包括:分布式/版本化配置(Distributed/versioned configuration)、注冊(cè)與發(fā)現(xiàn)(Registry and Discovery)、路由(Routing)、服務(wù)調(diào)用(Service-to-service calls)、負(fù)載均衡(Load balancing)、短路( Circuit Break )以及分布式消息(Distributed messaging)。技術(shù)點(diǎn)不少,這里我選取了分布式配置為例。詳細(xì)描述,我已在《2016.11.19 微服務(wù)實(shí)踐之路(廈門) 演講稿》(本微信公眾號(hào)內(nèi))中提到,請(qǐng)大家會(huì)后參考。
分布式配置
Spring Framework 3.1 開始,提供了一個(gè)新的接口:org.springframework.core.env.Environment,該接口的標(biāo)準(zhǔn)實(shí)現(xiàn)中組合了 org.springframework.core.env.PropertySources 對(duì)象(組合了多個(gè)org.springframework.core.env.PropertySource 對(duì)象),利用這個(gè)對(duì)象可以方便地 resolve Property。同時(shí),PropertySources 可以追加新的 org.springframework.core.env.PropertySource 對(duì)象。因此,Spring Cloud 提供了一個(gè)定位器 org.springframework.cloud.bootstrap.config.PropertySourceLocator 能夠便利地追加org.springframework.core.env.PropertySource 對(duì)象到org.springframework.core.env.PropertySources 對(duì)象中。 結(jié)合Alibaba 內(nèi)部分布式配置管理中間件 Diamond(類似于ZooKeeper),部分實(shí)現(xiàn)邏輯如下:
部分實(shí)現(xiàn)邏輯
具體使用則是通過@Value的方式獲取配置內(nèi)容中的Property,將其關(guān)聯(lián)到對(duì)象字段中,如下圖:
字段與配置項(xiàng)映射代碼
在ArchimedesProperties上方,有一個(gè)@RefreshScope的注解,這個(gè)注解的用途是通知 Spring Cloud,如果配置項(xiàng)發(fā)生變更后,變更后的屬性值將會(huì)同步到對(duì)象的字段值上。 下一張圖所示,配置內(nèi)容監(jiān)聽器的實(shí)現(xiàn),符合現(xiàn)代Annotation 驅(qū)動(dòng)的方式,將配置項(xiàng)的內(nèi)容轉(zhuǎn)化成需要的類型:
監(jiān)聽配置內(nèi)容類型裝換
Spring Cloud 部分完結(jié),下一個(gè)環(huán)節(jié)進(jìn)入 Spring Cloud Stream。
Spring Cloud Stream
在Martin Fowler的名著《Enterprise Integration Patterns》(企業(yè)整合模式 )中提到過(Channel)的概念,Spring Cloud Stream 付諸于實(shí)踐,提供抽象實(shí)現(xiàn)。這種抽象實(shí)現(xiàn)的好處在于對(duì)應(yīng)用透明,應(yīng)用不再強(qiáng)制綁定在某種具體技術(shù)上,對(duì)它而言,Spring Cloud Stream 為其建立管道(Channel),其中有兩個(gè)概念被涉及:Source(發(fā)送端)和Sink(接收端)。 類似于 Kafka 消息中間件,Alibaba 也自主研發(fā)了一套Message Queue,名叫 MetaQ ,早一陣子提交到開源社區(qū) Apache 上,與 Kalfa 為同級(jí)的項(xiàng)目,很了不起。無論是 Kafka 還是 MetaQ 都有自帶的API,為了增加應(yīng)用依賴透明性,針對(duì) MetaQ 做了Spring Cloud Stream 的適配,如下圖所示:
Source(發(fā)送端)發(fā)送消息實(shí)例代碼
Source(發(fā)送端)發(fā)送消息實(shí)例代碼:
Sink(接收器)消費(fèi)消息實(shí)例代碼
以上代碼相當(dāng)簡(jiǎn)單,與JMS中的消息訂閱模式類似。 前面三小節(jié)均為實(shí)現(xiàn)部分,最后一個(gè)技術(shù)小節(jié),繼續(xù)討論一下針對(duì) Spring Boot 的 DevOps。
Spring Boot DevOps
整體架構(gòu)
Archimedes整體架構(gòu)圖
每個(gè)微服務(wù)應(yīng)用均有一個(gè)應(yīng)用名,通過接入 Eureka Client ,向注冊(cè)中心 Eureka Server 注冊(cè)。Eureka Server保存所有注冊(cè)應(yīng)用的信息,這些信息被 Archimedes 通過Eureka Client 提供 REST 接口獲取,將獲取的應(yīng)用列表并發(fā)地獲取他們的Endpoint 和 Metrics信息。同時(shí) Archimedes 也提供了REST API 接口,暴露應(yīng)用元信息給 Archimedes Dashboard 提供頁面展示。將需要的Metrics信息存放時(shí)序數(shù)據(jù)庫,比如OpenTSDB。再通過OpenTSDB的HTTP API進(jìn)行查詢,最后將查詢結(jié)果顯示在監(jiān)控頁面中。
線程管理
Archimedes Dashboard 提供了圖形化的線程管理,如下單實(shí)例線程總數(shù)時(shí)序圖所示:
單實(shí)例線程總數(shù)時(shí)序圖
下圖所示,其功能類似于JStack,將具體線程運(yùn)行的狀態(tài)以及堆棧詳細(xì)列出:
活動(dòng)線程堆棧信息
內(nèi)存管理
JVM 的內(nèi)存管理相對(duì)比較復(fù)雜,不但包括內(nèi)存部分,內(nèi)存池、和相關(guān)垃圾回收的算法。其中JVM 內(nèi)存有包括:Jjava 內(nèi)存使用、堆使用、以及非堆使用。 在 Archimedes Dashboard 中,將幾者結(jié)合起來,集中展示。
整體內(nèi)存使用情況以及垃圾回收
垃圾回收前后對(duì)比
內(nèi)存池使用詳情
日志管理
個(gè)人認(rèn)為日志管理是獨(dú)創(chuàng),雖然Spring Admin 也提供了日志切換的能力,不過它不具備多種日志實(shí)現(xiàn)一同切換的能力,其中適配了四種流行的日志框架:Java Logging、Log4j、Log4j2 以及 Logback。
log4j 日志調(diào)控
Logback 日志調(diào)控
Archimedes 中會(huì)自動(dòng)識(shí)別應(yīng)用所使用的日志框架,雖然不推薦一個(gè)應(yīng)用中使用多套日志框架,可是現(xiàn)實(shí)情況不得不一并思考,比如有些二方j(luò)ar包中存在的獨(dú)立的日志處理。
思想
聊完了技術(shù),下面來談?wù)勊枷敕矫娴膶?shí)現(xiàn),我總結(jié)為三大點(diǎn):
少談”敏捷”
國(guó)外很多流派在“吹噓”,敏捷已死。不好我覺得有些夸張的成分,但是也無需過度的實(shí)施,借鑒一點(diǎn)即可。
推崇”簡(jiǎn)潔”
簡(jiǎn)潔很重要,牢記“Simple is beautiful”。微服務(wù)系統(tǒng)設(shè)計(jì)越簡(jiǎn)潔越好,這里簡(jiǎn)潔不是簡(jiǎn)單。
學(xué)習(xí)“狄仁杰”
這點(diǎn)可能很多朋友覺得非常突兀,和狄仁杰有什么關(guān)系。這里這么描述主要是狄閣老總問李元芳:“元芳,你怎么看?”。這種不恥下問的精神,知道我們來學(xué)習(xí)。狄仁杰并非事事明察,也需要李元芳這樣的武夫分析和提點(diǎn),能夠達(dá)到破案的目的,有為何不可呢?
朋友們,你們?cè)趺纯矗?/p>
(全篇完)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/70135.html
摘要:左傳有言民之多幸,國(guó)之不幸,當(dāng)時(shí)的大多數(shù)國(guó)民視英國(guó)為蠻夷,不與商貿(mào)往來。那么,在微服務(wù)實(shí)踐過程中,哪些因素可以不必微服務(wù)呢請(qǐng)注意用詞,這里說的是不必,不是不要。當(dāng)應(yīng)用符合其中一條以上的特征時(shí),該應(yīng)用不必實(shí)行微服務(wù)。 楔子 目前業(yè)界最流行的微服務(wù)架構(gòu)正在或者已被各種規(guī)模的互聯(lián)網(wǎng)公司廣泛接受和認(rèn)可,業(yè)已成為互聯(lián)網(wǎng)開發(fā)人員必備技術(shù)。無論是互聯(lián)網(wǎng)、云計(jì)算還是大數(shù)據(jù),Java平臺(tái)已成為全棧的生態(tài)...
摘要:作為微服務(wù)的基礎(chǔ)設(shè)施之一,背靠強(qiáng)大的生態(tài)社區(qū),支撐技術(shù)體系。微服務(wù)實(shí)踐為系列講座,專題直播節(jié),時(shí)長(zhǎng)高達(dá)小時(shí),包括目前最流行技術(shù),深入源碼分析,授人以漁的方式,幫助初學(xué)者深入淺出地掌握,為高階從業(yè)人員拋磚引玉。 簡(jiǎn)介 目前業(yè)界最流行的微服務(wù)架構(gòu)正在或者已被各種規(guī)模的互聯(lián)網(wǎng)公司廣泛接受和認(rèn)可,業(yè)已成為互聯(lián)網(wǎng)開發(fā)人員必備技術(shù)。無論是互聯(lián)網(wǎng)、云計(jì)算還是大數(shù)據(jù),Java平臺(tái)已成為全棧的生態(tài)體系,...
摘要:本次演講將介紹蘑菇街微服務(wù)治理體系經(jīng)歷的架構(gòu)演進(jìn)歷程,面臨的技術(shù)難點(diǎn)和解決思路。年加入蘑菇街,目前負(fù)責(zé)蘑菇街內(nèi)部中間件平臺(tái),包括分布式服務(wù)通信框架配置中心服務(wù)發(fā)現(xiàn)消息隊(duì)列等其他服務(wù)基礎(chǔ)設(shè)施等項(xiàng)目。文章來源網(wǎng)易云社區(qū) 微服務(wù)的概念最早由Martin Fowler與James Lewis于2014年共同提出,核心思想是圍繞業(yè)務(wù)能力組織服務(wù),各個(gè)微服務(wù)可被獨(dú)立部署,服務(wù)間是松耦合的關(guān)系,以及...
摘要:個(gè)推針對(duì)服務(wù)場(chǎng)景,基于和搭建了微服務(wù)框架,提高了開發(fā)效率。三容器化在微服務(wù)落地實(shí)踐時(shí)我們選擇了,下面將詳細(xì)介紹個(gè)推基于的實(shí)踐。 2016年伊始Docker無比興盛,如今Kubernetes萬人矚目。在這個(gè)無比需要?jiǎng)?chuàng)新與速度的時(shí)代,由容器、微服務(wù)、DevOps構(gòu)成的云原生席卷整個(gè)IT界。個(gè)推針對(duì)Web服務(wù)場(chǎng)景,基于OpenResty和Node.js搭建了微服務(wù)框架,提高了開發(fā)效率。在微服...
閱讀 610·2024-11-06 13:38
閱讀 877·2024-09-10 13:19
閱讀 1054·2024-08-22 19:45
閱讀 1402·2021-11-19 09:40
閱讀 2658·2021-11-18 13:14
閱讀 4310·2021-10-09 10:02
閱讀 2351·2021-08-21 14:12
閱讀 1301·2019-08-30 15:54