微服務是一種軟件架構風格,它是以專注于單一職責的很多小型項目為基礎,組合出復雜的大型應用。
微服務是一種架構。
微服務是一種架構。
微服務是一種架構。
以前自己做項目最常用的架構是單體架構。單體項目不適合開發大型項目。
學習微服務技術來解決服務拆分碰到的問題。
使用微服務技術(工具)把單體項目拆成微服務項目。
上圖是一些微服務技術,解決相應問題。
什么是單體架構
將業務的所有功能集中在一個項目中開發,打成一個包部署。
優點:架構簡單、部署成本低。
缺點:團隊協作成本高、系統發布效率低、系統可用性差。
總結:單體架構適合開發功能相對簡單,規模較小的項目。
微服務架構
微服務架構,是服務化思想指導下的一套最佳實踐架構方案。服務化,就是把單體架構中的功能模塊拆分為多個獨立項目。
SpringCloud
SpringCloud是目前國內使用最廣泛的微服務框架。SpringCloud集成了各種微服務功能組件,并基于SpringBoot實現了這些組件的自動裝配,從而提供了良好的開箱即用體驗。(但對于Springboot的版本也有要求)
(題外話:Springboot最擅長自動裝配和依賴管理)
拆分原則
目標:高內聚、低耦合
拆分方式:橫向拆分(抽取公共服務,提高復用性)、縱向拆分(按照業務模塊拆分)
拆分服務
工程結構有兩種:獨立project、Maven聚合
遠程調用
一旦微服務進行了拆分,數據產生了隔離,服務也產生了隔離,沒法像以前一樣調用了,如果想要像以前一樣查詢,查別人的數據,就必須通過網絡調用。
注冊中心
為什么要有注冊中心?8081不能寫死,8082和8083服務也要訪問。
1.服務調用者不知道服務提供者的地址,因為寫代碼的那一刻項目還沒啟動。
2.就算知道了地址,要訪問哪個。
3.寫好了代碼卻掛了,怎么知道新的服務的地址。
這就是服務遠程調用時可能出現的問題,可以用注冊中心來解決這個問題。設一個中介。
?Nacos——注冊中心的技術
Nacos是目前國內企業中占比最多的注冊中心組件。它是阿里巴巴的產品,目前已經加入SpringCloudAlibaba中。
服務注冊
拆好的服務去實現服務的注冊,引入依賴,配ip和端口,注冊后可以通過Nacos看到注冊好的服務。
服務發現
服務調用者去Nacos里拉取服務的信息。也要引入依賴,獲取ip和端口才行,提供好了這個API。
最簡單的負載均衡,隨機負載均衡,Ramdom。
OpenFeign
OpenFeign是一個聲明式的http客戶端,用來發送http請求的。讓剛剛的代碼也就是下圖的代碼變得簡單。
簡化后(OpenFeign已經被SpringCloud自動裝配)
連接池
日志
總結
服務拆分嘗試(以支付微服務為例)
首先去支付部分的controller, 看里面的各種接口進到serviceImpl里,然后看是否用到其他微服務,用到了就把此接口拆出來,放到新的client里,加上FeignClient注解,由api統一向所有的發請求(包括拆出來的client),然后回到servicelmpl里修改那些調用的主體。把那些不變的復制粘貼過來。
網關
就是網絡的關口,負責請求的路由,轉發,身份驗證。
在SpringCloud中網關的實現包括兩種:Spring Cloud Gateway、Netfilx Zuul
網關路由
1.創建新模塊
2.引入網關依賴:起步依賴(網關依賴、負載均衡依賴、Nacos依賴)
3.編寫啟動器:xxxApplication.java(記得帶SpringbootApplication注解)
4.配置路由規則
【GeekHour】30分鐘Nginx入門教程_嗶哩嗶哩_bilibili?
路由屬性
網關路由對應的java類型是RouteDefinition,其中常見的屬性:
id:路由唯一標識
url:路由目標地址
predicates:路由斷言,判斷請求是否符合當前路由(不僅可以指定路徑,還能設置在某時之前之后的條件)
filters:路由過濾器,對請求或響應做特殊處理(可添加修改請求頭、響應頭、路徑重寫、去路徑n段前綴)
網關登錄校驗
網關就像小區的開門大爺,是整個微服務的入口。
我們就不必在每個微服務里都校驗一次,在網關里這個入口jwt校驗一次就可以了。
這個校驗一定要放在網關轉發之前去做,就像看門大爺在找人前必須校驗外來人員。
?基于路由斷言RoutePredicateHandMapping去做路由匹配,然后到過濾器形成過濾器鏈...
綜上,如何在網關轉發之前做登錄校驗?在網關自定義一個過濾器,保證這個過濾器執行的順序在NettyRoutingFilter之前,并且在它的pre邏輯去實現jwt的校驗。(pre是轉發之前,post是之后)
網關如何傳遞用戶信息給微服務?不同的微服務tomcat都不一樣,所以肯定沒法用threadlocal(threadlocal在tomcat內部,線程之間去共享)。可以保存用戶到請求頭。
如何在微服務之間傳遞用戶信息?也是保存用戶要請求頭。
自定義過濾器
網關過濾器由兩種:GatewayFilter、GlobalFilter
GatewayFilter:路由過濾器,可以任意指定路由范圍
GlobalFilter:全局過濾器,作用范圍是所有路由
自定義過濾器仿寫:微服務02-05.網關登錄校驗-自定義GlobalFilter_嗶哩嗶哩_bilibili
方法1.自定義過濾器GlobalFilter類直接實現GlobalFilter接口就行了,如果向控制自定義過濾器的執行順序,加個order就可以了:利用exchang參數獲取請求信息,然后寫過濾器業務邏輯,然后放行(調用過濾器鏈chain的下一個過濾器)
方法2.利用gateway自定義過濾器,回頭再寫吧。
登錄校驗
自定義過濾器寫好了,準備工作就完畢了,可以寫登錄校驗了。(黑馬商城是JWT實現的登錄校驗)
hmall.jks文件打開亂碼,是保存jwt密鑰的文件,所以看起來亂碼。配置在hm的jwt里(yaml),有個類(jwtProperties.java)去加載配置里的屬性,真正去讀取文件生成密鑰的在securityConfig.java里。還有一個jwtTool。
excludePaths不用登錄校驗的,放行的路徑。也要有一個屬性類去讀取(回頭再看吧)
如果不用登錄攔截就直接放行chain鏈調用下一個,否則獲取token再校驗并解析token,可以的話就傳遞用戶信息后放行。
網關傳遞用戶
攔截器
步驟:
1.在網關的登錄校驗過濾器中,把獲取到的用戶寫入請求頭。(有API)
2.在hm-common中編寫SpringMVC攔截器,獲取登錄用戶。(因為每個微服務都有登錄用戶的需求)
OpenFeign傳遞用戶
微服務之間也要傳遞用戶。
openFeign中提供了一個攔截接口,所有由OpenFeign發起的請求都會先調用攔截器處理請求,其中的RequestTemplate類中提供了一些方法可以讓我們修改請求頭。
攔截器每個微服務都會用,公共的,所以放在hm-api里。
總結:
1.登錄校驗問題:
網關部分定義了一個過濾器,過濾器主要做兩件事:請求來了之后先去做JWT登錄校驗,從而獲取token中的用戶信息,把用戶信息保存到請求頭,轉發這個請求的時候自然就傳到微服務了。這里用到的過濾器是GlobalFilter。
當請求到達微服務部分,我們需要在微服務里獲取用戶信息。該微服務里有好多業務都要去獲取用戶信息,不可能在每個微服務的每個業務里都寫這個邏輯,為了簡化這個操作,我們就在微服務里定義了一個攔截器,攔截器可以幫助我們把網關傳過來的請求頭中的用戶信息給取出來,取完之后為了方便使用,保存信息到threadlocal里(因為這是微服務內部,可以線程來回調,就可以用threadlocal)。這樣的攔截器是SpringMVC的攔截器,叫做HandlerInterceptor。
微服務之間的相互調用:有一些業務比較復雜,可能會出現微服務之間的相互調用,往往這些可以通過OpenFeign去實現,而這些微服務要怎么拿到用戶信息呢(從微服務,而不是網關)?也保存到請求頭,后續的微服務才能拿到用戶信息。用到OpenFeign的攔截器,requestInterceptor。
配置管理
微服務太多,重復配置太多,如mysql
優點:配置共享;避免配置更新后的重啟,實現配置熱更新。
而之前我們用到提供注冊中心服務的nacos,也可以提供配置管理服務。
配置共享
步驟:
1.添加共享配置到Nacos中,包括jdbc、MybatisPlus、日志、Swagger、OpenFeign等。
2.拉取共享配置:基于NacosConfig拉取共享配置代替微服務的本地配置。
引入依賴->新建bootstrap.yaml?
配置熱更新
當我們修改配置文件中的配置中時,微服務無需重啟即可使配置生效。
配置前提:
1.nacos中要有一個與微服務名有關的配置文件。
2.微服務中要以特定方式讀取需要熱更新的配置屬性。