公眾號:Java架構(gòu)師聯(lián)盟,每日更新技術(shù)好文
Spring Cloud+Nginx架構(gòu)的主要組件
以crazy-springcloud開發(fā)腳手架為例衅胀,一個Spring Cloud+Nginx應(yīng)用的架構(gòu)如圖1-1所示沪饺。
圖1-1 基于Spring Cloud+Nginx的應(yīng)用架構(gòu)
Nginx作為反向代理服務(wù)器纸巷,代理內(nèi)部Zuul網(wǎng)關(guān)服務(wù)粥喜,通過Nginx自帶的負(fù)載均衡算法實(shí)現(xiàn)客戶端請求的代理轉(zhuǎn)發(fā)、負(fù)載均衡等功能鸥拧。
Zuul網(wǎng)關(guān)主要實(shí)現(xiàn)了微服務(wù)集群內(nèi)部的請求路由、負(fù)載均衡削解、統(tǒng)一校驗(yàn)等功能富弦。雖然在路由服務(wù)和負(fù)載均衡方面,Zuul和Nginx的功能比較類似氛驮,但是Zuul是自身注冊到Eureka/Nacos腕柜,通過微服務(wù)的serviceID實(shí)現(xiàn)微服務(wù)提供者之間的路由和轉(zhuǎn)發(fā)。
Eureka矫废、Nacos都是Spring Cloud技術(shù)體系中提供服務(wù)注冊與發(fā)現(xiàn)的中間件媳握。Eureka是Netflix開源的一款產(chǎn)品,提供了完整的服務(wù)注冊和發(fā)現(xiàn)磷脯,是Spring Cloud“全家桶”中的核心組件之一蛾找。
Nacos是阿里巴巴推出來的一個開源項(xiàng)目,也是一個服務(wù)注冊與發(fā)現(xiàn)中間件赵誓,它用于完成服務(wù)的動態(tài)注冊打毛、動態(tài)發(fā)現(xiàn)、服務(wù)管理俩功,還兼具了配置管理的功能幻枉。Nacos提供了一組簡單易用的特性集,用于實(shí)現(xiàn)動態(tài)服務(wù)發(fā)現(xiàn)诡蜓、服務(wù)配置熬甫、服務(wù)元數(shù)據(jù)及流量管理。
由于新版本的Eureka已經(jīng)閉源蔓罚,而阿里巴巴的Nacos除了具備Eureka注冊中心功能外椿肩,還具備Spring Cloud Config配置中心的功能,因此大大地降低了使用和維護(hù)的成本豺谈。另外郑象,Nacos還具有分組隔離功能,一套Nacos集群可以支撐多項(xiàng)目茬末、多環(huán)境厂榛。綜合上述多個原因,在實(shí)際的開發(fā)場景中,推薦大家使用Nacos击奶。但是辈双,本文出于學(xué)習(xí)目的,注冊中心和配置中心的內(nèi)容還是介紹Eureka+Config組合柜砾,其實(shí)在原理上辐马,Nacos和Eureka+Config組合是差不多的。
除了一系列基礎(chǔ)設(shè)施中間件技術(shù)組件之外局义,微服務(wù)架構(gòu)中大部分獨(dú)立業(yè)務(wù)模型都是以服務(wù)提供者的角色出現(xiàn)的喜爷。一般來說,系統(tǒng)可以按照各類業(yè)務(wù)模塊進(jìn)行細(xì)粒度的微服務(wù)拆分萄唇,例如秒殺系統(tǒng)中的用戶檩帐、商品等,每個業(yè)務(wù)模塊拆分成一個微服務(wù)提供者Provider組件另萤,作為獨(dú)立應(yīng)用程序進(jìn)行啟動和執(zhí)行湃密。
在Spring Cloud生態(tài)中,微服務(wù)提供者Provider之間的遠(yuǎn)程調(diào)用是通過Feign+Ribbon+Hystrix組合來完成的:Feign用于完成RPC遠(yuǎn)程調(diào)用的代理封裝四敞;Ribbon用于在客戶端完成各遠(yuǎn)程目標(biāo)服務(wù)實(shí)例之間的負(fù)載均衡泛源;Hystrix用于完成自動熔斷降級等多個維度的RPC保護(hù)。在Nginx+Spring Cloud架構(gòu)中還存在一系列輔助中間件忿危,包括日志記錄达箍、鏈路跟蹤、應(yīng)用監(jiān)控铺厨、JVM性能指標(biāo)缎玫、物理資源監(jiān)控等等。本文并沒有對上述輔助中間件做專門的介紹解滓。
Spring Cloud和Spring Boot的版本選擇
Spring Cloud是基于Spring Boot構(gòu)建的赃磨,它們之間的版本有配套的對應(yīng)關(guān)系。在構(gòu)建項(xiàng)目時洼裤,要注意版本之間的這種對應(yīng)關(guān)系邻辉,版本若對應(yīng)不上則會出現(xiàn)問題。
Spring Cloud和Spring Boot的版本配套關(guān)系如表1-1所示腮鞍。
表1-1 Spring Cloud與Spring Boot的版本配套關(guān)系
表1-1 Spring Cloud與Spring Boot的版本配套關(guān)系
Spring Cloud包含一系列子組件值骇,如Spring Cloud Config、Spring Cloud Netflix缕减、Spring Cloud Openfeign等雷客,為了防止與這些子組件的版本號混淆芒珠,Spring Cloud的版本號全部使用英文單詞形式命名。具體來說,Spring Cloud的版本號使用了英國倫敦地鐵站的名稱來命名蘸秘,并按字母A~Z的次序發(fā)布版本,它的第一個版本叫作Angel部逮,第二個版本叫作Brixton,以此類推嫂易。另外兄朋,每個大版本在解決了一個嚴(yán)重的Bug后,Spring Cloud會發(fā)布一個Service Release版本(小版本)怜械,簡稱SRX版本颅和,其中X是順序的編號,比如Finchley.SR4是Finchley大版本的第4個小版本缕允。
大家做技術(shù)選型時非常喜歡用最高版本峡扩,但是對于Spring全家桶的選擇來說,高版本不一定是最佳選擇障本。比如教届,目前最高的Spring CloudHoxton版本是基于Spring Boot 2.2構(gòu)建的,Spring Boot 2.2又是基于Spring Framework 5.2構(gòu)建的驾霜,也就是說案训,這是一次整體的、全方位的大版本升級粪糙。大家在項(xiàng)目上會用到非常多的第三方組件强霎,總會有一些組件沒有來得及進(jìn)行配套升級而不能兼容Spring Boot 2.2或SpringFramework 5.2,如果貿(mào)然地進(jìn)行基礎(chǔ)框架的整體升級蓉冈,就會給項(xiàng)目開發(fā)帶來各種各樣的疑難雜癥脆栋,甚至帶來潛在的線上Bug。
除此之外洒擦,Spring Cloud高版本推薦了不少自家的新組件椿争,但是這些新組件沒有經(jīng)過大規(guī)模實(shí)踐應(yīng)用的考驗(yàn),其功能尚待豐富和完善熟嫩。以負(fù)載均衡組件為例秦踪,Spring Cloud Hoxton推薦的自家組件spring?cloud-loadbalancer在功能上與Ribbon的負(fù)載均衡功能相比就弱很多。
Spring Cloud Finchley到Greenwich版本的升級其實(shí)很小掸茅,可以說微乎其微椅邓,主要是提升了對Java 11的兼容性。然而昧狮,在當(dāng)前的生產(chǎn)場景中Java 8才是各大項(xiàng)目的主流選擇景馁,另外Java 11(2019年4月之后的升級補(bǔ)丁)已經(jīng)不完全免費(fèi)了逗鸣。當(dāng)然合住,和Java 11一樣绰精,Java 8在2019年4月之后的補(bǔ)丁版本也面臨收費(fèi)的問題。使用Java 8的理由是透葛,自2014年3月18日發(fā)布起至目前笨使,Java 8被廣泛使用,且被維護(hù)了這么多年僚害,已經(jīng)非常成熟和穩(wěn)定了硫椰。
綜上所述,本文選用了Spring Cloud Finchley作為學(xué)習(xí)萨蚕、研究和使用的版本靶草,推薦使用的子版本為Finchley.SR4。具體的Maven依賴坐標(biāo)如下:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n24" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.8.RELEASE</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement></pre>
Spring Cloud微服務(wù)開發(fā)所涉及的中間件
在基于crazy-springcloud腳手架(其他的腳手架類似)的微服務(wù)開發(fā)和自驗(yàn)證過程中岳遥,所涉及的基礎(chǔ)中間件大致如下:
1.ZooKeeper
ZooKeeper是一個開放源碼的分布式協(xié)調(diào)應(yīng)用程序爱致,是大數(shù)據(jù)框架Hadoop和HBase的重要組件。在分布式應(yīng)用中寒随,它能夠高可用地提供保
障數(shù)據(jù)一致性的很多基礎(chǔ)功能:分布式鎖糠悯、選主、分布式命名服務(wù)等妻往。
在crazy-springcloud腳手架中互艾,高性能分布式ID生成器用到了ZooKeeper。
2.Redis
Redis是一個高性能的緩存數(shù)據(jù)庫讯泣。在高并發(fā)的場景下纫普,Redis可以對關(guān)系數(shù)據(jù)庫起到很好的緩沖作用;在提高系統(tǒng)的并發(fā)能力和響應(yīng)速度方面好渠,Redis至關(guān)重要昨稼。crazy-springcloud腳手架的分布式Session用到了Redis。
3.Eureka
Eureka是Netflix開發(fā)的服務(wù)注冊和發(fā)現(xiàn)框架拳锚,它本身是一個REST服務(wù)提供者假栓,主要用于定位運(yùn)行在AWS(Amazon云)上的中間層服務(wù),以達(dá)到負(fù)載均衡和中間層服務(wù)故障轉(zhuǎn)移的目的霍掺。Spring Cloud將Eureka集成在子項(xiàng)目spring-cloud-netflix中匾荆,以實(shí)現(xiàn)Spring Cloud的服務(wù)注冊和發(fā)現(xiàn)功能。
4.Spring Cloud Config
Spring Cloud Config是Spring Cloud全家桶中最早的配置中心杆烁,雖然在生產(chǎn)場景中很多企業(yè)已經(jīng)使用Nacos或者Consul整合型的配置中心替代了獨(dú)立的配置中心牙丽,但是Config依然適用于Spring Cloud項(xiàng)目,通過簡單地配置即可使用兔魂。
5.Zuul
Zuul是Netflix開源網(wǎng)關(guān)烤芦,可以和Eureka、Ribbon析校、Hystrix等組件配合使用构罗,Spring Cloud對Zuul進(jìn)行了整合與增強(qiáng)铜涉,使用它作為微服務(wù)集群的內(nèi)部網(wǎng)關(guān),負(fù)責(zé)給集群內(nèi)部的各個Provider(服務(wù)提供者)提供RPC路由和對請求進(jìn)行過濾绰播。
6.Nginx/OpenResty
Nginx是一個高性能HTTP和反向代理服務(wù)器骄噪,是由伊戈?duì)枴べ愃饕驗(yàn)槎砹_斯訪問量第二的Rambler.ru站點(diǎn)開發(fā)的Web服務(wù)器尚困。Nginx源代碼以類BSD許可證的形式對外發(fā)布蠢箩,它的第一個公開版本0.1.0在2004年10月4日發(fā)布,1.0.4版本在2011年6月1日發(fā)布事甜。Nginx因高穩(wěn)定性谬泌、豐富的功能集、內(nèi)存消耗少逻谦、并發(fā)能力強(qiáng)而聞名全球掌实,并被廣泛使用,百度邦马、京東贱鼻、新浪、網(wǎng)易滋将、騰訊邻悬、淘寶等都是它的用戶。OpenResty是一個基于Nginx與Lua的高性能Web平臺随闽,它的內(nèi)部集成了大量精良的Lua庫父丰、第三方模塊以及大多數(shù)的依賴項(xiàng),用于快速搭建能夠處理超高并發(fā)的擴(kuò)展性極高的動態(tài)Web應(yīng)用掘宪、Web服務(wù)和動態(tài)網(wǎng)關(guān)蛾扇。
以上中間件的端口配置以及部分安裝與使用的演示視頻如表1-2所示。
表1-2 本文案例涉及的主要中間件的端口配置以及部分安裝與使用的演示視頻
[圖片上傳失敗...(image-b187f4-1620107594131)]
Spring Cloud微服務(wù)開發(fā)和自驗(yàn)證環(huán)境
在開始學(xué)習(xí)Spring Cloud核心編程之前魏滚,先來介紹一下開發(fā)和自驗(yàn)證環(huán)境的準(zhǔn)備镀首、中間件的安裝以及抓包工具的準(zhǔn)備。
開發(fā)和自驗(yàn)證環(huán)境的系統(tǒng)選項(xiàng)和環(huán)境變量配置
首先介紹開發(fā)和自驗(yàn)證系統(tǒng)的選型鼠次。大部分開發(fā)人員學(xué)習(xí)開發(fā)都用過Windows環(huán)境蘑斧,在這種情況下,強(qiáng)烈建議使用虛擬機(jī)裝載CentOS作為自驗(yàn)證環(huán)境须眷。為什么要推薦CentOS呢竖瘾?
1.提前暴露生產(chǎn)環(huán)境中的問題
在生產(chǎn)環(huán)境上,90%以上的Java應(yīng)用都是使用Linux環(huán)境(如CentOS)來部署的花颗。因此捕传,使用CentOS作為自驗(yàn)證環(huán)境可以提前暴露生產(chǎn)環(huán)境中的潛在問題,避免在開發(fā)時沒有發(fā)現(xiàn)有問題的程序扩劝,一旦部署到生產(chǎn)環(huán)境中就出現(xiàn)問題(筆者親歷)庸论。
2.學(xué)習(xí)Shell命令和腳本
在生產(chǎn)環(huán)境中定位职辅、分析、解決線上Bug時聂示,需要用到基礎(chǔ)的Shell命令和腳本域携,因此平時要多使用、多練習(xí)鱼喉。另外秀鞭,Shell命令和腳本是Java程序員必知必會的面試題。使用CentOS作為自驗(yàn)證環(huán)境能方便大家學(xué)習(xí)Shell命令和腳本扛禽。
當(dāng)然锋边,可以借助一些文件同步或共享工具提高開發(fā)效率。比如编曼,可以通過VMware Tools共享Windows和CentOS之間的文件夾豆巨,這樣在后續(xù)的Lua腳本的開發(fā)和調(diào)試過程中能避免來回地復(fù)制文件。
這里給大家介紹一下crazy-springcloud腳手架開發(fā)和自驗(yàn)證環(huán)境的準(zhǔn)備掐场,主要涉及兩個方面:
(1)中間件(含Eureka往扔、Redis、MySQL等)相關(guān)信息的環(huán)境變量的配置熊户。
(2)主機(jī)名稱的配置萍膛。
對于中間件相關(guān)信息(如IP地址、端口敏弃、用戶賬號等)卦羡,很多項(xiàng)目都是直接以明文編碼的方式存放在配置文件中,這樣存在安全隱患甚至?xí)l(fā)泄密的風(fēng)險(xiǎn)麦到。對于這些信息绿饵,建議通過操作系統(tǒng)環(huán)境變量進(jìn)行配置,然后在配置文件中使用環(huán)境變量而不是明文編碼瓶颠。
例如拟赊,可以對Eureka的IP提前配置好環(huán)境變量EUREKA_ZONE_HOST,然后在應(yīng)用的配置文件bootstrap.yml中按照如下方式來使用:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n59" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">eureka:
client:
serviceUrl:
defaultZone: ${SCAFFOLD_EUREKA_ZONE_HOSTS:http://localhost:7777/eureka/}</pre>
在上面的配置中粹淋,通過${ SCAFFOLD_EUREKA_ZONE_HOSTS}表達(dá)式從環(huán)境變量中獲取Eureka的service-url地址吸祟。環(huán)境變量SCAFFOLD_EUREKA_ZONE_HOSTS后面跟著一個冒號和一個默認(rèn)值,表示如果環(huán)境變量值為空桃移,就會使用默認(rèn)值 http://localhost:7777/eureka/作為配置項(xiàng)的值屋匕。
通過環(huán)境變量配置中間件的信息有什么好處呢?
一是使配置信息的切換多了一層靈活性借杰,如果切換IP过吻,那么只需修改環(huán)境變量即可;二是可以不用在配置文件中以明文編碼方式存放密碼之類的敏感信息蔗衡,多了一層安全性纤虽。
crazy-springcloud微服務(wù)開發(fā)腳手架用到的環(huán)境變量較多乳绕,以自驗(yàn)證環(huán)境CentOS中的配置文件/etc/profile為例,部分內(nèi)容大致如下:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n64" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">export SCAFFOLD_DB_HOST=192.168.233.128
export SCAFFOLD_DB_USER=root
export SCAFFOLD_DB_PSW=root
export SCAFFOLD_REDIS_HOST=192.168.233.128
export SCAFFOLD_REDIS_PSW=123456
export SCAFFOLD_EUREKA_ZONE_HOSTS=http://192.168.233.128:7777/eureka/
export RABBITMQ_HOST=192.168.233.128
export SCAFFOLD_ZOOKEEPER_HOSTS=192.168.233.128:2181</pre>
以上環(huán)境變量中的192.168.233.128是筆者自驗(yàn)證環(huán)境CentOS虛擬機(jī)的IP地址逼纸,Redis洋措、ZooKeeper、Eureka杰刽、MySQL菠发、Nginx等中間件都運(yùn)行在這臺虛擬機(jī)上,大家在運(yùn)行crazy-springcloud微服務(wù)開發(fā)腳手架之前需要進(jìn)行相應(yīng)的更改专缠。
最后介紹一下有關(guān)主機(jī)名稱的配置雷酪。如果在調(diào)試過程中直接通過IP訪問REST接口淑仆,那么在Fiddler工具抓包中查看報(bào)文就不方便涝婉。為了方便抓包,將IP地址都映射成主機(jī)名稱蔗怠。在筆者使用的Windows開發(fā)環(huán)境中墩弯,hosts文件內(nèi)配置的主機(jī)名稱如下:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n67" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">127.0.0.1 crazydemo.com
127.0.0.1 file.crazydemo.com
127.0.0.1 admin.crazydemo.com
127.0.0.1 xxx.crazydemo.com
192.168.233.128 eureka.server
192.168.233.128 zuul.server
192.168.233.128 nginx.server
192.168.233.128 admin.nginx.server</pre>
注意,本書后文的演示用例用到的URL會使用以上主機(jī)名稱取代IP地址寞射。
使用Fiddler工具抓包和查看報(bào)文
在微服務(wù)程序開發(fā)和驗(yàn)證的過程中渔工,一般來說對HTTP接口發(fā)起請求有多種方式:
(1)直接發(fā)起請求。
(2)通過內(nèi)部網(wǎng)關(guān)代理(如Zuul)發(fā)起請求桥温。
(3)通過外部網(wǎng)關(guān)反向代理(如Nginx)發(fā)起請求引矩。
以crazy-springcloud腳手架中的uaa-provider服務(wù)的HTTP接口/api/user/detail/v1為例,通過以上3種方式發(fā)起請求的HTTP鏈路示意圖如圖1-2所示侵浸。
圖1-2 3種方式請求uaa-provider的HTTP鏈路示意圖
在生產(chǎn)環(huán)境下旺韭,為了滿足內(nèi)外網(wǎng)之間的轉(zhuǎn)發(fā)、多服務(wù)器之間的負(fù)載均衡要求掏觉,外部反向代理(Nginx)往往不止一層区端。因此,請求的HTTP鏈路往往更加復(fù)雜澳腹。
無論是在開發(fā)環(huán)境织盼、自驗(yàn)證環(huán)境、測試環(huán)境還是在生產(chǎn)環(huán)境中酱塔,查看HTTP接口的訪問鏈路和報(bào)文內(nèi)容對于定位沥邻、分析、解決問題來說都非常重要羊娃,這就需要使用抓包工具唐全。抓包工具的類型比較多,筆者目前使用較多的為Fiddler迁沫。
比如芦瘾,在調(diào)試本書crazy-springcloud腳手架中的uaa-provider功能時捌蚊,使用Fiddler能全面地查看發(fā)往服務(wù)端的HTTP報(bào)文的請求頭和響應(yīng)頭,如圖1-3所示近弟。
圖1-3 使用Fiddler查看請求頭和響應(yīng)頭
在開發(fā)過程中缅糟,F(xiàn)iddler這類抓包工具的使用對于分析和定位問題非常有用。筆者經(jīng)常使用Fiddler完成下面的工作:
(1)查看REST接口的處理時間祷愉,在解決性能問題時幫助查看接口的整體時間窗宦。
(2)查看REST接口的請求頭、響應(yīng)頭二鳄、響應(yīng)內(nèi)容赴涵,主要用于查看請求URL、請求頭订讼、響應(yīng)頭是否正確髓窜,并且在必要的時候可以將所有請求頭一次性地復(fù)制到Postman等請求發(fā)起工具,幫助新請求快速地構(gòu)造同樣的HTTP頭部欺殿。
(3)請求重發(fā)寄纵,除了可以使用獨(dú)立的請求工具(如Swagger?UI/Postman等)重發(fā)請求之外,還可以在Fiddler中直接進(jìn)行請求重發(fā)脖苏,重發(fā)的請求有相同的頭部和參數(shù)程拭,調(diào)試時非常方便。
crazy-springcloud微服務(wù)開發(fā)腳手架
無論是單體應(yīng)用還是分布式應(yīng)用棍潘,如果從零開始開發(fā)恃鞋,那么都會涉及很多基礎(chǔ)性的、重復(fù)性的工作亦歉,比如用戶認(rèn)證恤浪、Session管理等。
有了開發(fā)腳手架鳍徽,這些基礎(chǔ)工作就可以省去资锰,直接利用腳手架提供的基礎(chǔ)模塊,然后按照腳手架的規(guī)范進(jìn)行業(yè)務(wù)模塊的開發(fā)即可阶祭。
筆者在開源平臺看到過不少開源的腳手架绷杜,但是發(fā)現(xiàn)這些腳手架很少可以直接拿來進(jìn)行業(yè)務(wù)模塊的開發(fā),要么封裝過于重量級而不好解耦濒募,要么業(yè)務(wù)模塊分包不清晰而不方便開發(fā)鞭盟,所以本著簡潔和清晰的原則,筆者發(fā)起的瘋狂創(chuàng)客圈社群推出了自己的微服務(wù)開發(fā)腳手架crazy-springcloud瑰剃,它的模塊和功能如下:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n90" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">crazymaker-server -- 根項(xiàng)目
│ ├─cloud-center -- 微服務(wù)的基礎(chǔ)設(shè)施中心
│ │ ├─cloud-eureka -- 注冊中心
│ │ ├─cloud-config -- 配置中心
│ │ ├─cloud-zuul -- 網(wǎng)關(guān)服務(wù)
│ │ ├─cloud-zipkin -- 監(jiān)控中心
│ ├─crazymaker-base -- 公共基礎(chǔ)依賴模塊
│ │ ├─base-common -- 普通的公共依賴齿诉,如utils類的公共方法
│ │ ├─base-redis -- 公共的Redis操作模塊
│ │ ├─base-zookeeper -- 公共的ZooKeeper操作模塊
│ │ ├─base-session -- 分布式Session模塊
│ │ ├─base-auth -- 基于JWT + SpringSecurity的用戶憑證與認(rèn)證模塊
│ │ ├─base-runtime -- 各Provider的運(yùn)行時公共依賴,裝配了一些通用Spring
IOC Bean實(shí)例
│ ├─crazymaker-uaa -- 業(yè)務(wù)模塊: 用戶認(rèn)證與授權(quán)
│ │ ├─uaa-api -- 用戶DTO、Constants等
│ │ ├─uaa-client -- 用戶服務(wù)的Feign遠(yuǎn)程客戶端
│ │ ├─uaa-provider -- 用戶認(rèn)證與權(quán)限的實(shí)現(xiàn)粤剧,包含controller層歇竟、service層、dao層的代碼實(shí)現(xiàn)
│ ├─crazymaker-seckill -- 業(yè)務(wù)模塊:秒殺練習(xí)
│ │ ├─seckill-api -- 秒殺DTO抵恋、Constants等
│ │ ├─seckill-client -- 秒殺服務(wù)的Feign遠(yuǎn)程調(diào)用模塊
│ │ ├─seckill-provider -- 秒殺服務(wù)核心實(shí)現(xiàn)焕议,包含controller層、service層弧关、 dao層的代碼實(shí)現(xiàn)
│ ├─crazymaker-demo -- 業(yè)務(wù)模塊:練習(xí)演示
│ │ ├─demo-api -- 演示模塊的DTO盅安、Constants等
│ │ ├─demo-client -- 演示模塊的Feign遠(yuǎn)程調(diào)用模塊
│ │ ├─demo-provider -- 演示模塊的核心實(shí)現(xiàn),包含controller層世囊、service層别瞭、 dao層的代碼實(shí)現(xiàn)</pre>
在業(yè)務(wù)模塊如何分包的問題上,大部分企業(yè)都有自己的統(tǒng)一規(guī)范株憾。crazy-springcloud腳手架從職責(zé)清晰蝙寨、方便維護(hù)、能快速導(dǎo)航代碼的角度出發(fā)号胚,將每一個業(yè)務(wù)模塊細(xì)分成以下3個子模塊籽慢。
(1){module}-api:該子模塊定義了一些公共的Constants業(yè)務(wù)常量和DTO傳輸對象浸遗,既被業(yè)務(wù)模塊內(nèi)部依賴猫胁,又可能被依賴該業(yè)務(wù)模塊的外部模塊所依賴。
(2){module}-client:該子模塊定義了一些被外部模塊所依賴的Feign遠(yuǎn)程調(diào)用客戶類跛锌,是專供給外部模塊的依賴弃秆,不能被內(nèi)部的其他子模塊所依賴。
(3){module}-provider:該子模塊是整個業(yè)務(wù)模塊的核心髓帽,也是一個能夠獨(dú)立啟動菠赚、運(yùn)行的服務(wù)提供者(Application)。該模塊包含涉及業(yè)務(wù)邏輯的controller層郑藏、service層衡查、dao層的完整代碼實(shí)現(xiàn)。
crazy-springcloud微服務(wù)開發(fā)腳手架在以下兩方面進(jìn)行了弱化:
(1)在部署方面對容器的介紹進(jìn)行了弱化必盖,沒有使用Docker容器而是使用Shell腳本拌牲。這有多方面的原因:一是本腳手架的目的是學(xué)習(xí),使用Shell腳本而不是Docker去部署歌粥,方便大家學(xué)習(xí)Shell命令和腳本塌忽;二是Java和Docker其實(shí)整合得很好,學(xué)習(xí)起來非常容易失驶,稍加配置就能做到一鍵發(fā)布土居,找點(diǎn)資料學(xué)習(xí)一下就可以輕松掌握;三是部署和運(yùn)維是一項(xiàng)專門的工作,生產(chǎn)環(huán)境的部署擦耀,甚至是整個自動化構(gòu)建和部署的工作實(shí)際上是屬于運(yùn)維的專項(xiàng)工作棉圈,由專門的運(yùn)維人員去完成,而部署的核心仍然是Shell腳本眷蜓,所以對于開發(fā)人員來說掌握Shell腳本才是重中之重迄损。
(2)對監(jiān)控軟件的介紹進(jìn)行了弱化。本書沒有專門介紹鏈路監(jiān)控账磺、JVM性能指標(biāo)芹敌、熔斷器監(jiān)控軟件的使用,這也有多方面的原因:一是監(jiān)控軟件太多垮抗,如果介紹得太全氏捞,篇幅就不夠,介紹得太少冒版,大家又不一定會用到液茎;二是監(jiān)控軟件的使用大多是一些軟件的操作步驟和說明,原理性的內(nèi)容比較少辞嗡,傳播這類知識使用視頻的形式比文字的形式效果更好捆等。瘋狂創(chuàng)客圈后續(xù)可能會推出一些微服務(wù)監(jiān)控方面的教學(xué)視頻供大家參考,請大家關(guān)注社群博客续室。無論如何栋烤,只要掌握了Spring Cloud的核心原理,那么掌握監(jiān)控組件的使用對大家來說基本上就是小菜一碟挺狰。
以秒殺作為Spring Cloud+Nginx的實(shí)戰(zhàn)案例
本文的綜合性實(shí)戰(zhàn)案例是實(shí)現(xiàn)一個高性能的秒殺系統(tǒng)明郭。為何要以秒殺作為本書的綜合性實(shí)戰(zhàn)案例呢?先回顧一下在單體架構(gòu)還是主流的年代丰泊,大家學(xué)習(xí)J2EE技術(shù)時的綜合性實(shí)戰(zhàn)案例薯定。一般來說,都是從0開始編寫代碼瞳购,一行一行地編寫一個購物車應(yīng)用话侄。通過編寫購物車應(yīng)用能對J2EE有一個全方位的練習(xí),包括前端的HTML網(wǎng)頁学赛、JavaScript腳本年堆,后端的MVC框架、數(shù)據(jù)庫罢屈、事務(wù)嘀韧、多線程等各種技術(shù)。
時代在變缠捌,技術(shù)的復(fù)雜度在變锄贷,前端和后端的分工也變了∫氲伲現(xiàn)在的J2EE開發(fā)已經(jīng)進(jìn)入分布式微服務(wù)架構(gòu)的時代,前端和后端框架都變得非常復(fù)雜谊却,前端和后端工程師已經(jīng)有比較明確的分工柔昼。后端程序員專門做Java開發(fā),前端程序員專門做前端的開發(fā)炎辨。后端程序員可以不需要懂前端的技術(shù)捕透,如Vue、TypeScript等碴萧,當(dāng)然乙嘀,很多前端程序員也不一定需要懂后端技術(shù)。
相比單體服務(wù)時代破喻,現(xiàn)在的分布式開發(fā)時代學(xué)習(xí)Java后端技術(shù)的難度大多了虎谢。首先面臨一大堆分布式、高性能中間件的學(xué)習(xí)曹质,比如Netty婴噩、ZooKeeper、RabbitMQ羽德、Spring Cloud几莽、Redis等都是當(dāng)今后端程序員必知必會的。然后像JMeter這類壓力測試工具和Fiddler這類抓包工具宅静,已經(jīng)成為每個后端程序員必須掌握的知識章蚣。因?yàn)樵诜植际江h(huán)境下需要定位、發(fā)現(xiàn)并解決數(shù)據(jù)一致性坏为、高可靠性等問題究驴,通過壓力測試,本來很正常的代碼也會在運(yùn)行時出現(xiàn)很多性能相關(guān)的問題匀伏。
另外,隨著移動互聯(lián)網(wǎng)蝴韭、物聯(lián)網(wǎng)的發(fā)展够颠,當(dāng)前面臨的高并發(fā)場景已經(jīng)不局限于電商,在其他的應(yīng)用中也越來越多榄鉴。所以履磨,現(xiàn)在高并發(fā)開發(fā)技術(shù)由少數(shù)工程師需要掌握的高精尖技術(shù)變成了大多數(shù)人都需要掌握的基礎(chǔ)技能。一般來說庆尘,高并發(fā)開發(fā)的三大利器為緩存剃诅、降級和限流。緩存的目的是提高系統(tǒng)訪問速度驶忌,它是對抗高并發(fā)的銀彈矛辕;而降級是當(dāng)服務(wù)出問題或者服務(wù)影響到核心流程時笑跛,可以將服務(wù)暫時屏蔽掉,待高峰或者問題解決后再打開聊品;而有些場景并不能用緩存和降級來解決飞蹂,比如稀缺資源(秒殺、搶購)翻屈、寫數(shù)據(jù)(如評論陈哑、下單)等,這種情況下可以使用限流措施來對接口進(jìn)行保護(hù)伸眶。
有了緩存惊窖、降級和限流這三大利器,遇到像京東618厘贼、阿里雙11這樣的高并發(fā)應(yīng)用場景爬坑,才不用擔(dān)心瞬間流量導(dǎo)致系統(tǒng)雪崩,哪怕是最終只能做到有損的服務(wù)涂臣,也不會出現(xiàn)某些小電商平臺在活動期間服務(wù)器宕機(jī)數(shù)小時的事故盾计。
秒殺程序的業(yè)務(wù)足夠簡單,涉及的技術(shù)又足夠全面赁遗,可以說是分布式應(yīng)用場景非常好的實(shí)戰(zhàn)案例署辉。另外,現(xiàn)在IT行業(yè)人才流動性比較大岩四,大家都會為面試做準(zhǔn)備哭尝。在面試中,秒殺業(yè)務(wù)所覆蓋的緩存剖煌、降級材鹦、高并發(fā)限流、分布式鎖耕姊、分布式ID桶唐、數(shù)據(jù)一致性等問題一般是重點(diǎn)、熱門問題茉兰。
本文給大家講解的內(nèi)容是Spring Cloud+Nginx架構(gòu)的主要組件
下篇文章給大家講解的是Spring Cloud入門實(shí)戰(zhàn)尤泽;
覺得文章不錯的朋友可以轉(zhuǎn)發(fā)此文關(guān)注小編;
感謝大家的支持!