中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

縣城做信息網(wǎng)站賺不賺錢搜索關(guān)鍵詞

縣城做信息網(wǎng)站賺不賺錢,搜索關(guān)鍵詞,北京免費發(fā)布企業(yè)信息網(wǎng)站,kesion系統(tǒng)做網(wǎng)站教程一、微服務(wù)演變 1、單體架構(gòu)(Monolithic Architecture) 是一種傳統(tǒng)的軟件架構(gòu)模式,應(yīng)用程序的所有功能和組件都集中在一個單一的應(yīng)用中。 在單體架構(gòu)中,應(yīng)用程序通常由一個大型的、單一的代碼庫組成,其中包含了所有…

一、微服務(wù)演變

1、單體架構(gòu)(Monolithic Architecture)

是一種傳統(tǒng)的軟件架構(gòu)模式,應(yīng)用程序的所有功能和組件都集中在一個單一的應(yīng)用中。

在單體架構(gòu)中,應(yīng)用程序通常由一個大型的、單一的代碼庫組成,其中包含了所有的功能模塊和業(yè)務(wù)邏輯。這個應(yīng)用程序作為一個整體部署和運行在一個應(yīng)用服務(wù)器上,并共享相同的內(nèi)存和數(shù)據(jù)庫。

當(dāng)單體架構(gòu)項目的性能無法滿足需求時,但又希望繼續(xù)沿用單體架構(gòu)的話,你可以采取以下一些優(yōu)化手段來改善性能,如以下方法:

  1. 使用緩存:引入緩存機制,將經(jīng)常請求的數(shù)據(jù)緩存起來,減少對數(shù)據(jù)庫等后端系統(tǒng)的訪問,以提高性能。

  2. 數(shù)據(jù)庫優(yōu)化:進行數(shù)據(jù)庫性能調(diào)優(yōu),包括建立索引、優(yōu)化查詢語句、使用合適的數(shù)據(jù)庫引擎等,以提高數(shù)據(jù)庫的響應(yīng)速度。

  3. 使用消息隊列:引入消息隊列來解耦耗時操作,將其轉(zhuǎn)化為異步的處理任務(wù)。這樣可以提高并發(fā)處理能力和系統(tǒng)的響應(yīng)性能。

  4. 水平擴展:通過復(fù)制多個實例來處理更多的請求??梢允褂秘撦d均衡器將請求分發(fā)到不同的實例上,從而提高系統(tǒng)的整體性能和容量。

  5. 引入分布式架構(gòu):將應(yīng)用程序拆分為多個獨立的服務(wù),并通過網(wǎng)絡(luò)進行通信和協(xié)作。這樣可以將負載分散到多個節(jié)點上,提高整體性能和可伸縮性。

?接下來就說一下單體架構(gòu)優(yōu)化中的引入分布式架構(gòu)。

2、分布式架構(gòu)

將系統(tǒng)的各個組件部署在不同的計算機節(jié)點上,并通過網(wǎng)絡(luò)進行通信和協(xié)作的軟件架構(gòu)模式。在分布式架構(gòu)中,各個節(jié)點可以獨立運行和處理任務(wù),并通過消息傳遞、遠程過程調(diào)用或其他通信機制進行數(shù)據(jù)交換和協(xié)調(diào)。

?在使用分布式時,我們就會有一下的疑問:

  • 服務(wù)拆分到什么程度?
  • 服務(wù)集群地址如何維護?
  • 服務(wù)之間如何實現(xiàn)遠程調(diào)用?
  • 服務(wù)健康狀況如何感知?

?3、微服務(wù)

?微服務(wù)是一種經(jīng)過改良好的架構(gòu)設(shè)計的分布式架構(gòu)方案,微服務(wù)架構(gòu)特征:

  1. 單一職責(zé):微服務(wù)拆分力度更小,每個服務(wù)都對應(yīng)唯一的服務(wù)能力,做的單一職責(zé),避免重復(fù)開發(fā)
  2. 面向服務(wù):微服務(wù)對外暴露業(yè)務(wù)接口
  3. 自治:團隊獨立、技術(shù)獨立、數(shù)據(jù)獨立、部署獨立
  4. 隔離性強:服務(wù)調(diào)用做好隔離、容錯、降級,避免出現(xiàn)級聯(lián)問題

假如我們有一個電商系統(tǒng),其中有以下一些微服務(wù):

  1. 用戶服務(wù)(User Service)負責(zé)用戶的注冊、登錄、信息管理等功能。
  2. 商品服務(wù)(Product Service)負責(zé)商品的查詢、添加、更新等功能。
  3. 訂單服務(wù)(Order Service)負責(zé)訂單的創(chuàng)建、支付、取消等功能。

現(xiàn)在假設(shè)用戶服務(wù)依賴于商品服務(wù)來獲取商品信息,并且訂單服務(wù)依賴于用戶服務(wù)來獲取用戶信息。這里我們可以看到微服務(wù)的幾個特征是如何應(yīng)用的:

  1. 單一職責(zé):每個微服務(wù)都具有清晰的職責(zé)。例如,用戶服務(wù)只負責(zé)用戶相關(guān)的功能,而不涉及商品或訂單。
  2. 面向服務(wù):每個微服務(wù)都對外暴露業(yè)務(wù)接口,其他微服務(wù)可以通過調(diào)用這些接口來訪問所需的功能。例如,用戶服務(wù)可以提供獲取用戶信息的接口給訂單服務(wù)使用。
  3. 自治:每個微服務(wù)的團隊在技術(shù)和數(shù)據(jù)上都是獨立的。例如,用戶服務(wù)的團隊可以獨立開發(fā)、測試、部署和擴展該服務(wù),無需依賴其他團隊。
  4. 隔離性強:微服務(wù)之間的調(diào)用需要做好隔離、容錯和降級,以避免出現(xiàn)級聯(lián)問題。例如,當(dāng)商品服務(wù)不可用時,用戶服務(wù)可以使用緩存或默認數(shù)據(jù)來避免影響用戶操作。

這個例子中提供了不同的微服務(wù)來處理不同的功能,并且彼此解耦、獨立運行。每個微服務(wù)都具有單一職責(zé),對外提供明確定義的業(yè)務(wù)接口,團隊在技術(shù)和數(shù)據(jù)上具有自治能力,同時采取適當(dāng)?shù)母綦x措施來保證系統(tǒng)的彈性和穩(wěn)定性。這些特征有助于提高開發(fā)效率、靈活性和可維護性,使得微服務(wù)架構(gòu)在構(gòu)建大型、復(fù)雜系統(tǒng)時具有優(yōu)勢。

4、 總結(jié)

單體架構(gòu)特點:簡單方便,高度耦合,擴展性差,合適小型項目。如:學(xué)生管理系統(tǒng)。

分布式架構(gòu)特點:松耦合,擴展性好,但架構(gòu)復(fù)雜,難道大,適合大型互聯(lián)網(wǎng)項目。如:京東、淘寶

微服務(wù):一種良好的分布式架構(gòu)方案。

  • 優(yōu)點:拆分粒度更小、服務(wù)更獨立、耦合更低
  • 缺點:架構(gòu)非常復(fù)雜,運維、監(jiān)控、部署難道更高

5、微服務(wù)架構(gòu)

微服務(wù)這方案需要技術(shù)框架來落地實現(xiàn),全球的互聯(lián)網(wǎng)公司都在積極嘗試自己的微服務(wù)落地技術(shù)。在國內(nèi)最知名的就是SpringCloud和阿里巴巴的Dubbo。

5.1、 微服務(wù)技術(shù)對比

?Dubbo、Spring Cloud、Spring Cloud和Spring Cloud Alibaba都是用于構(gòu)建分布式系統(tǒng)的開源框架。盡管它們的目標(biāo)相同,但它們在實現(xiàn)方式和功能特點上有所不同。

  1. Dubbo:Dubbo是一個高性能的分布式服務(wù)框架,由阿里巴巴開發(fā)。它基于傳統(tǒng)的服務(wù)治理理念,提供了服務(wù)注冊、發(fā)現(xiàn)、路由、負載均衡、容錯等功能。Dubbo的核心特點是高性能和低延遲的RPC調(diào)用,適用于大規(guī)模的微服務(wù)架構(gòu)。Dubbo提供了對多種協(xié)議(如Dubbo協(xié)議、REST協(xié)議)和注冊中心(如ZooKeeper、Consul)的支持。

  2. Spring Cloud:Spring Cloud是一個由Pivotal開發(fā)的微服務(wù)框架,構(gòu)建在Spring Framework之上,使得構(gòu)建分布式系統(tǒng)更加便捷。它提供了一系列的組件和模塊,用于實現(xiàn)服務(wù)注冊與發(fā)現(xiàn)、負載均衡、斷路器、配置管理、消息總線等功能。Spring Cloud采用了Spring Boot作為底層的開發(fā)框架,提供了更簡潔、快速搭建分布式系統(tǒng)的解決方案。

  3. Spring Cloud Alibaba:Spring Cloud Alibaba是Spring Cloud與Alibaba開放平臺合作的結(jié)果,提供了一些在云原生應(yīng)用開發(fā)中常用的解決方案。它主要基于Spring Cloud框架,結(jié)合了一些Alibaba技術(shù)棧,如Nacos(服務(wù)注冊與發(fā)現(xiàn))、Sentinel(流量控制和熔斷降級)、RocketMQ(消息驅(qū)動)等。Spring Cloud Alibaba旨在提供云原生應(yīng)用開發(fā)的全棧解決方案。

雖然Dubbo和Spring Cloud都是用于構(gòu)建分布式系統(tǒng)的框架,但Dubbo更加注重于高性能的RPC調(diào)用和服務(wù)治理,而Spring Cloud則提供了一整套更全面的微服務(wù)解決方案。而Spring Cloud Alibaba則是在Spring Cloud的基礎(chǔ)上,進一步整合了Alibaba的一些技術(shù),為云原生應(yīng)用提供更全面的開發(fā)支持。選擇適合的框架取決于具體的需求、技術(shù)棧和團隊偏好。

5.2、企業(yè)需求

  1. Spring Cloud + Spring Cloud Alibaba:Spring Cloud提供了豐富的微服務(wù)組件和解決方案,包括服務(wù)注冊與發(fā)現(xiàn)、負載均衡、斷路器、配置管理等。Spring Cloud Alibaba擴展了Spring Cloud,整合了阿里巴巴技術(shù)棧,如Nacos(服務(wù)注冊與發(fā)現(xiàn))、Sentinel(流量控制和熔斷降級)、RocketMQ(消息驅(qū)動)等。組合使用這兩個框架可以獲得全面的云原生應(yīng)用開發(fā)解決方案,適用于構(gòu)建現(xiàn)代化的微服務(wù)架構(gòu)。

  2. Dubbo原生模式 + Spring Cloud Alibaba:Dubbo是一個高性能的RPC框架,提供了服務(wù)治理、負載均衡、容錯等功能。Spring Cloud Alibaba擴展了Dubbo,為Dubbo提供了更多云原生的支持,如Nacos作為注冊中心、Sentinel用于流量控制和熔斷降級等。通過將Dubbo和Spring Cloud Alibaba集成,可以獲得高性能的RPC調(diào)用和全面的云原生的服務(wù)治理解決方案。

無論是使用Spring Cloud + Spring Cloud Alibaba還是Dubbo原生模式 + Spring Cloud Alibaba,都可以受益于Spring Cloud和Spring Cloud Alibaba提供的豐富的微服務(wù)功能和云原生支持。具體選擇哪種組合取決于企業(yè)需求、技術(shù)棧和團隊實際情況。需要評估技術(shù)要求、性能需求、開發(fā)復(fù)雜度等因素,選擇適合的框架組合來構(gòu)建穩(wěn)定、高效的分布式系統(tǒng)。

二、spring cloud

SpringCloud是目前國內(nèi)使用最廣泛的微服務(wù)框架。官網(wǎng)地址:

????????????????????????????????????????????????Spring Cloud

SpringCloud集成了各種微服務(wù)功能組件,并基于SpringBoot實現(xiàn)了這些組件的自動裝配,從而提供了良好的開箱即用體驗:

?springCloud與SpringBoot的版本兼容關(guān)系

?本文學(xué)習(xí)版本是Hoxton.SR10,因此對應(yīng)的springboot版本是2.3.x版本。

1、服務(wù)拆分及遠程調(diào)用

1.1、服務(wù)拆分
1.1.1、服務(wù)拆分注意事項
  1. 不同微服務(wù),不要重復(fù)開發(fā)相同業(yè)務(wù)
  2. 微服務(wù)數(shù)據(jù)獨立,不要訪問其他微服務(wù)的數(shù)據(jù)庫
  3. 微服務(wù)可以將自己的業(yè)務(wù)暴露為接口,供其它微服務(wù)調(diào)用

1.1.2、項目實戰(zhàn)

實戰(zhàn)代碼:阿里云下載

把數(shù)據(jù)庫文件那到數(shù)據(jù)庫管理工具里執(zhí)行和idea中導(dǎo)入cloud-demo項目

最終數(shù)據(jù)庫結(jié)構(gòu):

?對與cloud-demo這個項目主要看一下用戶和訂單如何進行項目拆分的,結(jié)合這單體架構(gòu)的結(jié)果對比一下有什么變化和不同。

1.1.3、總結(jié)
  1. 微服務(wù)需要根據(jù)業(yè)務(wù)模塊拆分,做到單一職責(zé),不要重復(fù)開發(fā)相同業(yè)務(wù)。
  2. 微服務(wù)可以將業(yè)務(wù)暴露為接口,供其他微服務(wù)使用。
  3. 不同微服務(wù)都應(yīng)該有自己獨立的數(shù)據(jù)庫。
1.2、遠程調(diào)用

?需求:根據(jù)訂單id查詢訂單的同時,把訂單所屬的用戶信息一起返回。

1.2.1、遠程調(diào)用方法

?在我們的controller類中使用@GetMapping("/user/{id}")向外暴露了一個接口來訪問,可以將user信息放回為json數(shù)據(jù)格式,我們可以想一下瀏覽器可以發(fā)一個Ajax請求來獲取數(shù)據(jù),我們的訂單服務(wù)可不可以發(fā)一個Ajax請求來獲取數(shù)據(jù)呢?

1.2.2、實現(xiàn)遠程調(diào)用步驟
1)注冊RestTemplate
Spring Cloud中也使用了RestTemplate類。RestTemplate是Spring框架中的一部分,它在Spring Cloud項目中被廣泛用于進行微服務(wù)之間的通信。在微服務(wù)架構(gòu)中,各個微服務(wù)之間通常通過RESTful API進行通信。為了簡化這個過程,Spring Cloud對RestTemplate進行了增強,以便更好地支持微服務(wù)架構(gòu)。在Spring Cloud中,RestTemplate被稱為"服務(wù)調(diào)用"的一部分。通過使用RestTemplate,開發(fā)人員可以方便地發(fā)起HTTP請求來調(diào)用其他微服務(wù)的API。Spring Cloud還提供了一些增強功能,例如服務(wù)發(fā)現(xiàn)和負載均衡。開發(fā)人員可以使用服務(wù)名代替具體的URL,Spring Cloud會自動根據(jù)服務(wù)名找到可用的實例并進行負載均衡,從而實現(xiàn)更靈活和高效的服務(wù)調(diào)用。需要注意的是,自Spring Cloud 2020.0.0版本(即Hoxton.SR9及之后的版本)開始,官方推薦使用WebClient替代RestTemplate作為HTTP客戶端,因為WebClient提供了更強大、更靈活的功能,并且更適用于非阻塞的響應(yīng)式編程模型。但是,為了向后兼容,RestTemplate仍然可以繼續(xù)使用并被支持。

在order-service的OrderApplication中注冊ResteTemplate,將ResteTemplate用@Bean注解注冊為spring管理的對象,以后不管在什么地方都可以使用到RestTemplate對象。

?完成調(diào)用主要是在service層中實現(xiàn),向被調(diào)用服務(wù)發(fā)起一個Rest請求,在需要調(diào)用其他服務(wù)的服務(wù)中使用,實現(xiàn)步驟:

1、在服務(wù)啟動類中注冊RestTemplate,如這里是在order的啟動類中

2、在要調(diào)用其他服務(wù)的服務(wù)中的service層中自動裝配RestTemplate對象

3、使用RestTemplate的api來實現(xiàn)即可,里面有很多api,這里我使用的是getForObject()方法

4、將遠程調(diào)用返回的數(shù)據(jù)封裝到要封裝的對象中即可,這里我使用的是將遠程調(diào)用獲取的user對象信息封裝到order對象中。

1.3、提供者與消費者

?服務(wù)提供者:一次業(yè)務(wù)中,被其他微服務(wù)調(diào)用的服務(wù)。(提供接口給其他服務(wù)調(diào)用)如:user服務(wù)

服務(wù)消費者:一次業(yè)務(wù)中,調(diào)用其他微服務(wù)的服務(wù)。(調(diào)用其他微服務(wù)提供的接口)如order服務(wù)

總結(jié):

1.服務(wù)調(diào)用關(guān)系

  • ? ? ? ? ? ? ? ? ? ? ? ? ? ?服務(wù)提供者:暴露接口給其它微服務(wù)調(diào)用
  • ? ? ? ? ? ? ? ? ? ? ? ? ? ?服務(wù)消費者:調(diào)用其它微服務(wù)提供的接口
  • ? ? ? ? ? ? ? ? ? ? ? ? ? ?提供者與消費者角色其實是相對的
  • ? ? ? ? ? ? ? ? ? ? ? ? ? ?一個服務(wù)可以同時是服務(wù)提供者和服務(wù)消費者

三、Eureka注冊中心

1、服務(wù)調(diào)用出現(xiàn)的問題

在前面我們使用RestTemplate來實現(xiàn)服務(wù)遠程調(diào)用,在寫url時使用的是硬編碼方式,就會產(chǎn)生以下的問題,這些問題是值得我們考慮一下的。

  • 服務(wù)消費者該如何獲取服務(wù)提供者的地址信息?
  • 如果有多個服務(wù)提供者,消費者該如何選擇?
  • 消費者如何得知服務(wù)提供者的健康狀態(tài)?

2、 Eureka基本原理

Eureka是Netflix開源的服務(wù)治理框架,在Spring Cloud中廣泛應(yīng)用。它的基本原理是建立了一個分布式的服務(wù)注冊中心,用于管理和維護各個微服務(wù)實例的注冊和發(fā)現(xiàn)。

以下是Eureka的基本原理:

  1. Eureka服務(wù)器:Eureka由一個或多個Eureka服務(wù)器組成,它們構(gòu)成了服務(wù)注冊中心。每個微服務(wù)實例都將自己的信息注冊到Eureka服務(wù)器,包括服務(wù)名、主機名、端口號等。

  2. 服務(wù)注冊:微服務(wù)啟動時,會向Eureka服務(wù)器發(fā)送注冊請求,將自己的信息注冊到注冊中心。注冊中心維護一個服務(wù)注冊表,記錄所有已注冊的微服務(wù)實例。

  3. 服務(wù)發(fā)現(xiàn):其他微服務(wù)需要調(diào)用某個服務(wù)時,首先向注冊中心發(fā)送查詢請求,獲得目標(biāo)服務(wù)的實例列表。注冊中心將會返回所有可用的服務(wù)實例信息,包括IP地址、端口號等。

  4. 服務(wù)監(jiān)控:Eureka服務(wù)器會定期向已注冊的微服務(wù)實例發(fā)送心跳請求,微服務(wù)實例返回響應(yīng)以證明自己的健康狀態(tài)。如果一個微服務(wù)長時間未發(fā)送心跳消息或返回異常狀態(tài),Eureka服務(wù)器將從注冊表中刪除該實例。

  5. 服務(wù)同步:Eureka服務(wù)器之間會相互復(fù)制注冊表信息,以保證數(shù)據(jù)的一致性。當(dāng)有新的微服務(wù)實例注冊或注銷時,注冊中心會通知其他服務(wù)器進行注冊表更新。

通過Eureka提供的服務(wù)注冊和發(fā)現(xiàn)機制,微服務(wù)之間可以動態(tài)地發(fā)現(xiàn)和調(diào)用其他微服務(wù),從而實現(xiàn)了服務(wù)之間的解耦和靈活性。Eureka還提供了負載均衡、故障恢復(fù)等一些附加功能,使得微服務(wù)架構(gòu)更加可靠和高效。

回顧之前我們的幾個問題:

消費者該如何獲取服務(wù)提供者具體信息?

  • 服務(wù)提供者啟動時向eureka注冊自己的信息
  • eureka保存這些信息
  • 消費者根據(jù)服務(wù)名稱向eureka拉取提供者信息

如果有多個服務(wù)提供者,消費者該如何選擇?

  • 服務(wù)消費者利用負載均衡算法,從服務(wù)列表中挑選一個

消費者如何感知服務(wù)提供者健康狀態(tài)?

  • 服務(wù)提供者會每隔30秒向EurekaServer發(fā)送心跳請求,報告健康狀態(tài)
  • eureka會更新記錄服務(wù)列表信息,心跳不正常會被剔除
  • 消費者就可以拉取到最新的信息
?總結(jié)

在Eureka架構(gòu)中,微服務(wù)角色有兩類:

? ?1、EurekaServer:服務(wù)端,注冊中心

  • 記錄服務(wù)信息
  • 心跳監(jiān)控

? ?2、EurekaClient: 客戶端

? ? ? ? ?1)Provider:服務(wù)提供者,例如案例中的 user-service

  • ? ? ? ? ? ? ? 注冊自己的信息到EurekaServer
  • ? ? ? ? ? ? ? 每隔30秒向EurekaServer發(fā)送心跳

? ? ? ? ?2)consumer:服務(wù)消費者,例如案例中的 order-service

  • ? ? ? ? ? ? ? ? ? ? 根據(jù)服務(wù)名稱從EurekaServer拉取服務(wù)列表
  • ? ? ? ? ? ? ? ? ? ? 基于服務(wù)列表做負載均衡,選中一個微服務(wù)后發(fā)起遠程調(diào)用

3、手動實戰(zhàn)

3.1、搭建eureka服務(wù)注冊中心(服務(wù)名稱)

1、創(chuàng)建項目,引入spring-cloud-starter-netflix-eureka-server的依賴

    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>

?2、啟用Eureka服務(wù)器:創(chuàng)建一個啟動類,并使用@EnableEurekaServer注解來啟用Eureka服務(wù)器功能。

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {public static void main(String[] args) {SpringApplication.run(EurekaApplication.class,args);}
}

3、配置Eureka服務(wù)器:在應(yīng)用程序的配置文件(如application.propertiesapplication.yml)中配置Eureka服務(wù)器的相關(guān)信息,例如:

# 服務(wù)器配置
server:port: 10001   # Eureka服務(wù)器運行的端口號# Spring應(yīng)用程序配置
spring:application:name: eurekaserver   # Eureka服務(wù)器應(yīng)用程序的名稱# Eureka客戶端配置
eureka:client:service-url:defaultZone: http://localhost:10001/eureka/# Eureka客戶端注冊自身的Eureka服務(wù)器的URL# 在本例中,將Eureka服務(wù)器的URL設(shè)置為運行在10001端口的本地服務(wù)器
3.2、注冊user-service

這個操作是在user-service項目下實現(xiàn)的,主要是將服務(wù)信息注冊到Eureka服務(wù)端,eureka將這些服務(wù)信息保存到注冊表中進行管理。

將user-service服務(wù)注冊到EurekaServer步驟:
1、在user-service項目中引入spring-cloud-starter-netflix-eureka-client的依賴
   <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
2、在application.yml位置文件中編寫配置
spring:application:name: userservice  #配置服務(wù)名稱
eureka:client:service-url:defaultZone: http://localhost:10001/eureka/   #配置eureka服務(wù)地址信息

其實orderservice的注冊也是這兩個步驟,我就寫了。

做完之后,我我們可以瀏覽一下eureka的服務(wù)網(wǎng)站看一下:http://localhost:10001

這里的端口號是你在自己的eureka的配置文件application.yml配置的eureka端口號一致。

?總結(jié):

1.服務(wù)注冊

  • 引入eureka-client依賴
  • 在application.yml中配置eureka地址

2.無論是消費者還是提供者,引入eureka-client依賴
知道eureka(服務(wù)注冊中心)地址后,都可以完成服務(wù)注冊

3.3、在order-service完成服務(wù)拉取

服務(wù)拉取是基于服務(wù)名稱獲取服務(wù)列表,然后在對服務(wù)列表做負載均衡

1.修改OrderService的代碼,修改訪問的url路徑,用服務(wù)名代替ip、端口:
String url ="http://userservice/user/" + order.getUserId();
2.在order-service項目的啟動類OrderApplication中的RestTemplate添加負載均衡注解:
@Bean
@LoadBalanced  #負載均衡
public RestTemplate restTemplate() {return new RestTemplate();
}
總結(jié)

1.搭建EurekaServer

  • 引入eureka-server依賴
  • 添加@EnableEurekaServer注解
  • 在application.yml中配置eureka地址

2.服務(wù)注冊

  • 引入eureka-client依賴
  • 在application.yml中配置連接eureka服務(wù)注冊中心地址

3.服務(wù)發(fā)現(xiàn)

  • 引入eureka-client依賴
  • 在application.yml中配置eureka服務(wù)注冊中心地址
  • 給RestTemplate添加@LoadBalanced注解
  • 用服務(wù)提供者的服務(wù)名稱遠程調(diào)用

四、Ribbon負載均衡

Ribbon是一個負載均衡解決方案,主要用于在分布式系統(tǒng)中將負載均勻地分發(fā)給多個服務(wù)實例。它是Netflix開 源的一個組件,常用于微服務(wù)架構(gòu)中。

1、負載均衡流程

?Ribbon的負載均衡原理可以概括如下:

  1. 服務(wù)注冊:Ribbon首先需要與服務(wù)注冊中心(如Eureka、Consul等)進行交互,獲取可用的服務(wù)實例列表。

  2. 負載均衡策略:Ribbon支持多種負載均衡策略,如隨機策略、輪詢策略、權(quán)重策略等。根據(jù)選擇的策略,Ribbon會根據(jù)服務(wù)實例的狀態(tài)、性能等因素來選擇一個合適的服務(wù)實例。

  3. 服務(wù)調(diào)用:一旦選擇了一個服務(wù)實例,Ribbon會將請求發(fā)送給該實例。它會維護一個與服務(wù)實例的長連接,并在需要時將請求發(fā)送給該實例。

  4. 失敗處理:如果請求在與服務(wù)實例的通信中失敗,Ribbon會嘗試選擇另一個可用的服務(wù)實例進行重試,以增加系統(tǒng)的可用性。

Ribbon還可以與其他組件配合使用,例如Netflix的Hystrix熔斷器,用于實現(xiàn)服務(wù)的容錯和故障保護。

總之,Ribbon通過動態(tài)獲取服務(wù)實例列表并根據(jù)負載均衡策略選擇合適的實例來進行負載均衡,從而提高系統(tǒng)的性能、可用性和可擴展性。

源碼執(zhí)行流程:

?2、Ribbon負載均衡策略

Ribbon負載均衡規(guī)則是一個叫做IRule的接口來實現(xiàn)的,每個子接口都是一種規(guī)則:

2.1、 負載均衡策略

?2.2、調(diào)整負責(zé)均衡策略的規(guī)則

通過定義IRule實現(xiàn)可以修改負載均衡規(guī)則,有兩種方式:

方式一:代碼方式

如消費者服務(wù)order-service,只要在OrderApplication類中定義一個新的IRule:

@Bean
public IRule iRule(){return new RandomRule();
}

其實也不一定要在OrderApplication啟動類中配置,也可以自己創(chuàng)建一個配置類來配置,在有@configuration注解的類就可以。

這種配置方案是全局的配置,只要使用了這種配置方案,以后不管你調(diào)用的是user-service服務(wù)還是order-service服務(wù)都是使用這里的配置方案。

方式二:配置文件方式

在order-service的application.yml文件中,添加新的配置也可以修改規(guī)則:

userservice: #被調(diào)用微服務(wù)器的服務(wù)名稱ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #負載均衡規(guī)則

這種配置方案是只針對某個微服務(wù)的,是局部配置。

3、Ribbon餓加載

Ribbon默認是采用懶加載,即第一次訪問才會創(chuàng)建LoadBalanceClient,請求時間會很長。

而餓加載則會在項目啟動時創(chuàng)建,降低每一次訪問的耗時

3.1、配置開啟配置饑餓加載
#當(dāng)服務(wù)饑餓加載
ribbon:eager-load:enabled: true #開啟饑餓加載clients: userservice #指定對userservice這個服務(wù)饑餓加載#當(dāng)有多個服務(wù)需要饑餓加載可以用下面的方式:
ribbon:eager-load:enabled: true #開啟饑餓加載clients:  #指定對userservice這個服務(wù)饑餓加載- userservice - xxservice
總結(jié)
1.Ribbon負載均衡規(guī)則
  • 規(guī)則接口是IRule
  • 默認實現(xiàn)是ZoneAvoidanceRule,根據(jù)zone選擇服務(wù)列表,然后輪詢
2.負載均衡自定義方式
  • 代碼方式:配置靈活,但修改時需要重新打包布
  • 配置方式:直觀,方便,無需重新打包發(fā)布但是無法做全局配置
3.饑餓加載
  • 開啟饑餓加載
  • 指定饑餓加載的微服務(wù)名稱

五、Nacos注冊中心

微服務(wù)的注冊中心我們已經(jīng)學(xué)了eureka,大家肯定會有疑問,為啥還有學(xué)校nacos呢?

其實nacos不僅有服務(wù)注冊中心和服務(wù)發(fā)現(xiàn)功能,還有更加強大的功能。

1、nacos和eureka對比

Nacos和Eureka是兩個常用的服務(wù)發(fā)現(xiàn)和注冊工具,它們都具有類似的功能,但在一些方面存在一些差異。以下是Nacos和Eureka的一些對比:

  1. 開發(fā)者生態(tài)圈:Nacos是由Alibaba開發(fā)并開源,擁有龐大的Alibaba生態(tài)圈支持,而Eureka是由Netflix開發(fā)并開源,得到了Netflix和Spring Cloud社區(qū)的廣泛應(yīng)用。

  2. 功能和特性:Nacos提供了更多的功能和特性,除了服務(wù)注冊與發(fā)現(xiàn)外,還包括配置管理、動態(tài)DNS、動態(tài)路由和流量管理等功能。Eureka主要關(guān)注服務(wù)注冊與發(fā)現(xiàn)的功能。

  3. 容錯性:Nacos具有更強的容錯性,支持多數(shù)據(jù)中心的分布式部署,可以保證在網(wǎng)絡(luò)分區(qū)和節(jié)點故障情況下的高可用性。Eureka在這方面的容錯性相對較弱。

  4. 數(shù)據(jù)一致性:Nacos使用Raft算法來實現(xiàn)數(shù)據(jù)一致性和高可用性,而Eureka使用的是AP模型,即優(yōu)先保證可用性而不保證強一致性。

  5. 社區(qū)活躍度:Nacos的開源社區(qū)活躍度相對較高,有更多的貢獻者和更新的版本發(fā)布。Eureka的開源社區(qū)相對較少活躍,更新較為緩慢。

選擇使用Nacos還是Eureka可以根據(jù)具體需求和項目背景來決定。如果需要更多的功能和特性,以及較強的容錯性和高可用性,Nacos可能是更好的選擇。如果項目已經(jīng)依賴于Netflix和Spring Cloud生態(tài)圈,或者對于服務(wù)注冊和發(fā)現(xiàn)的簡單功能需求,Eureka可能是更適合的選項。

2、Nacos下載安裝服務(wù)注冊中心

2.1下載nacos

在Nacos的GitHub頁面,提供有下載鏈接,可以下載編譯好的Nacos服務(wù)端或者源代碼:

GitHub主頁:https://github.com/alibaba/nacos

GitHub的Release下載頁:https://github.com/alibaba/nacos/releases

這里我提供了阿里云盤下載:Nacos1.4.1

2.2、解壓Nacos

?我這里使用的是在Windows下安裝的。

直接解壓到一個沒有中文字符的路徑下。

?目錄說明:

  • - bin:啟動腳本
  • - conf:配置文件
2.2.1、配置端口

Nacos的默認端口是8848,如果你電腦上的其它進程占用了8848端口,請先嘗試關(guān)閉該進程。

**如果無法關(guān)閉占用8848端口的進程**,也可以進入nacos的conf目錄,修改配置文件中的端口:

修改其中的內(nèi)容修改為一個沒有被占用的端口號。

2.2.2.啟動nacos服務(wù)注冊中心

啟動非常簡單,進入bin目錄,進入cmd窗口執(zhí)行下面的命令

startup.cmd -m standalone#startup.cmd -m standalone 的含義是執(zhí)行Nacos服務(wù)器的啟動腳本,并使用獨立模式啟動Nacos服務(wù)器。
#這將在單個節(jié)點上運行Nacos,并使用默認的配置文件和端口。這個命令適用于簡單部署或測試,并非生產(chǎn)環(huán)境下常見的集群模式啟動命令。

執(zhí)行后的效果如圖:?

在瀏覽器輸入地址:http://127.0.0.1:8848/nacos即可:

用戶名和密碼都是:nacos

?網(wǎng)頁直接就是中文的,對于英語不太好的比eureka的友好。

3、將服務(wù)注冊到nacos服務(wù)注冊中心

1、在cloud-demo父工程中添加spring-cloud-alibaba的管理依賴:

            <!--nacos版本管理--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.5.RELEASE</version><type>pom</type><scope>import</scope></dependency>

2、注釋掉order-service和user-service中原有的eureka依賴。

3、添加nacos的客戶端依賴:

        <!-- nacos客戶端依賴包 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>

4、修改user-service & order-service中的application.yml文件,注釋掉eureka的地址,添加nacos地址:

spring:cloud:nacos:server-addr: localhost:8848

啟動項目測試:

?其實eureka和nacos在spring-cloud中除了依賴和端口號配置不同外其他的使用都是一樣的,他們底層使用的接口都是一樣的,所以代碼其他地方根本不用做改變。

總結(jié):

1.Nacos服務(wù)搭建
  • 下載安裝包
  • 解壓
  • 在bin目錄下運行指令:startup.cmd -mstandalone
2.Nacos服務(wù)注冊或發(fā)現(xiàn)
  • 引入nacos.discovery依賴
  • 配置nacos地址spring.cloudnacos.server-addr

4、Nacos服務(wù)分級存儲模型

之前我們在學(xué)中,我們的服務(wù)分層都是只有兩層的,第一層是服務(wù),第二層是實例(如user-service、order-service),在我們部署時,都是將這些服務(wù)我實例部署到一個機器上或者一個機房里,但是如果這個機房收到破壞(地震、火災(zāi))時,服務(wù)就無法訪問了。

? 而nacos服務(wù)分層存儲模型則引出了集群的概念,一個集群就好比是我們的一個機房,而我們的一個服務(wù)下面就可以部署很多個集群,每個集群就可以部署在全球各地(北京、上海、深圳等),因此服務(wù)的層次結(jié)構(gòu)就變成了三層(服務(wù)、集群、實例)。

4.1、服務(wù)跨集群調(diào)用問題
  • ?服務(wù)調(diào)用盡可能選擇本地集群的服務(wù),跨集群調(diào)用延遲高
  • 本地集群不可以訪問時,在去訪問其他集群

?4.2、服務(wù)集群實現(xiàn)

1、修改application.yml,添加如下內(nèi)容,配置服務(wù)集群名稱

spring:cloud:nacos:server-addr: localhost:8848  #nacos 服務(wù)端地址cluster-name: YN #配置集群名稱,也就是機房位置,例如:YN ,云南

2、在Nacos控制臺可以看到集群變化

?現(xiàn)在的集群變成了yn,在沒有配置集群名稱是default。

總結(jié)
1.Nacos服務(wù)分級存儲模型
  • 一級是服務(wù),例如userservice
  • 二級是集群,例如杭州或上海
  • 三級是實例,例如杭州機房的某臺部署了userservice的服務(wù)器
2.如何設(shè)置實例的集群屬性
  • 修改application.yml文件,添加spring.cloud.nacos.discovery.cluster-name屬性即可
4.3、Nacos集群負載均衡

Nacos集群負載均衡的規(guī)則其實是優(yōu)先選擇本集群內(nèi)的服務(wù),如果本服務(wù)掛了,才會去選擇其他集群的服務(wù)來訪問。

配置

1、修改order-service中的application.yml,設(shè)置集群為HZ:

spring:cloud:nacos:server-addr: Localhost:8848    # nacos 服務(wù)端地加discovery:cLuster-name: HZdiscovery:cluster-name: bj    #配集群名稱,也就是機房位置

2、然后在order-service中設(shè)置負載均衡的IRule為NacosRule,這個規(guī)則優(yōu)先會尋找與自己同集群的服務(wù):

userservice:    #服務(wù)名稱ribbon:NFLoadBalancerRulecassName: com.alibaba.cloud.nacos.ribbon.NacosRule #負載均衡規(guī)則

3、注意將user-service的權(quán)重都設(shè)置為1

總結(jié):

1.NacosRule負載均衡策略

  • 優(yōu)先選擇同集群服務(wù)實例列表
  • 本地集群找不到提供者,才去其它集群尋找,并且會報警告
  • 確定了可用實例列表后,再采用隨機負載均衡挑選實例
4.4、根據(jù)權(quán)重負載均衡

假設(shè)有一個微服務(wù)架構(gòu)的電子商務(wù)網(wǎng)站,其中包括以下幾個服務(wù):商品服務(wù)、訂單服務(wù)用戶服務(wù)。這些服務(wù)都注冊到了Nacos中進行服務(wù)發(fā)現(xiàn),并且它們有不同的實例數(shù)和性能配置。在這種情況下,可以通過基于權(quán)重的負載均衡來實現(xiàn)對這些服務(wù)實例的合理請求分配。以下是一些示例場景:

  1. 不同實例性能差異較大:

    假設(shè)商品服務(wù)有3個實例,其中實例A和實例B配置較高,實例C配置較低。此時,可以設(shè)置實例A和實例B的權(quán)重為2,實例C的權(quán)重為1。這樣,每次有請求到來時,有較高性能的實例A和實例B將會處理更多的請求,而較低性能的實例C將會處理較少的請求,從而實現(xiàn)了性能調(diào)控。

  2. 服務(wù)實例容量不均衡:

    假設(shè)訂單服務(wù)有5個實例,其中實例A、B和C的容量比實例D和E大??梢詾閷嵗鼳、B和C設(shè)置較高的權(quán)重值,如3,而為實例D和E設(shè)置較低的權(quán)重值,如1。這樣,請求將均衡分配到實例A、B和C之間,并保持實例D和E的請求數(shù)較少。

  3. 降低故障實例的負載:

    假設(shè)用戶服務(wù)有4個實例,其中實例A由于某種原因,出現(xiàn)了故障或不穩(wěn)定情況。為了減少對實例A的請求分配,可以為其設(shè)置較低的權(quán)重值,如0,而將其他正常的實例設(shè)置為較高的權(quán)重值,如3。這樣,請求將主要被分配給其他正常的實例,降低了對故障實例A的負載。

通過在Nacos中設(shè)置服務(wù)實例的權(quán)重,可以根據(jù)實際情況動態(tài)調(diào)整請求的負載比例。這樣能夠充分利用資源、提高系統(tǒng)性能、保證服務(wù)穩(wěn)定性,并對不同實例進行合理分配。

Nacos提供了權(quán)重配置來控制訪問頻率,權(quán)重越大則訪問頻率越高。

配置

?

?4.5、環(huán)境隔離-namespace
1、認識環(huán)境隔離-namvespace

應(yīng)用場景:

假設(shè)有一個電商平臺,該平臺設(shè)計了一個基于Nacos的命名空間配置和服務(wù)注冊方案,以支持環(huán)境隔離和多租戶功能。

首先,假設(shè)該電商平臺有三個環(huán)境:開發(fā)環(huán)境、測試環(huán)境和生產(chǎn)環(huán)境。每個環(huán)境都有獨立的配置和服務(wù)需求。

  1. 環(huán)境隔離和配置管理:

    • 使用Nacos的命名空間功能,平臺管理員可以創(chuàng)建三個命名空間:dev-namespace、test-namespace和prod-namespace。

    • 在dev-namespace中,可以配置開發(fā)環(huán)境所需的各種參數(shù),如數(shù)據(jù)庫連接信息、調(diào)試模式等。

    • 在test-namespace中,可以配置測試環(huán)境所需的參數(shù),如測試數(shù)據(jù)庫連接信息、測試數(shù)據(jù)源等。

    • 在prod-namespace中,可以配置生產(chǎn)環(huán)境所需的參數(shù),如正式數(shù)據(jù)庫連接信息、生產(chǎn)級別的服務(wù)配置等。

    • 每個命名空間下的配置項是相互隔離的,這樣就保證了不同環(huán)境配置的獨立性,并且可根據(jù)需求靈活管理和更新配置信息。

  2. 服務(wù)注冊和版本管理:

    • 在每個命名空間中,可以注冊相應(yīng)環(huán)境需要的服務(wù)實例,如商品服務(wù)、訂單服務(wù)等。

    • 平臺管理員可以使用命名空間功能來管理不同環(huán)境的服務(wù)注冊表,確保每個環(huán)境只能訪問屬于自己的服務(wù)實例。

    • 每個命名空間可以獨立管理服務(wù)實例的版本,例如,在開發(fā)環(huán)境中可以注冊和測試新的服務(wù)版本,而在生產(chǎn)環(huán)境中則使用穩(wěn)定的服務(wù)版本。

通過這樣的命名空間配置和服務(wù)注冊方案,電商平臺能夠?qū)崿F(xiàn)對不同環(huán)境的配置和服務(wù)進行隔離,并支持多租戶功能。開發(fā)團隊可以獨立管理各自環(huán)境的配置和服務(wù),而不會相互干擾。此外,平臺還可以利用灰度發(fā)布和版本管理功能,在不同命名空間中進行服務(wù)版本控制,確保系統(tǒng)穩(wěn)定性和可用性。

2、配置命名空間

1)創(chuàng)建命名空間(在nacos服務(wù)頁面創(chuàng)建)

?2、將服務(wù)配置到指定的命名空間中(修改application.yml配置文件)
server:port: 8081
spring:datasource:url: jdbc:mysql://192.168.10.130:3306/cloud-user?useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.jdbc.Driverapplication:name: userservice  #配置服務(wù)名稱cloud:nacos:server-addr: localhost:8848discovery:cluster-name: yn #集群名稱,地址在云南namespace: 074da7cb-c3e3-4848-b893-3d15114e8729  #命令空間id

?此時,配置了namespace的服務(wù)已經(jīng)被配置到dev中了

?如果此時使用order-service去調(diào)用user-service就會報錯了

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: No instances available for userservice] with root causeservlet .service()的servlet [dispatcherServlet]在上下文與路徑[]拋出異常[請求處理失敗;嵌套異常是java.lang.IllegalStateException: No instances available for userservice],有根本原因

5、nacos注冊中介細節(jié)分析

?服務(wù)注冊:服務(wù)提供者啟動時,會向服務(wù)注冊中心發(fā)起注冊請求,包括服務(wù)名、IP 地址、端口等。注冊中心會將這些信息保存起來。

服務(wù)發(fā)現(xiàn):服務(wù)發(fā)現(xiàn)有兩種(pull和push相結(jié)合)

  1. pull:服務(wù)消費者會每隔30秒定時主動向服務(wù)注冊中心發(fā)起請求,來拉取服務(wù)信息,在服務(wù)消費者中有一個服務(wù)列表緩存,用于緩存從服務(wù)注冊中心拉取下的服務(wù)信息。
  2. push:當(dāng)有服務(wù)停掉后服務(wù)注冊中心會主動推送變更信息給消費者,消費者就會更新服務(wù)列表緩存。

心跳與健康檢查:也是有兩種(對臨時實力和非臨時實例)

  1. 臨時實例:采心跳檢測,是臨時實例主動向注冊中心發(fā)送心跳檢測,如果一段時間注冊中心沒有收到臨時實例心跳檢測,就會剔除該臨時實例。
  2. 非臨時實例:采用nacos主動詢問,nacos主動詢問非臨時實例的健康狀態(tài),如果非臨時實例停止了,也不會剔除非臨時實例,只是修改非臨時實例的健康轉(zhuǎn)態(tài),會等待非臨時實例健康。

負載均衡:負載均衡和流量控制是由服務(wù)消費者一側(cè)的客戶端組件來實現(xiàn)的,而不是由注冊中心來處理。當(dāng)客戶端從Nacos注冊中心獲取到可用的服務(wù)實例列表后,負載均衡和流量控制的責(zé)任落在了客戶端的實現(xiàn)上。

5.1、臨時實例與非臨時實例

Nacos中的實例分為臨時實例和非臨時實例,它們在生命周期和用途上有所不同:

1、非臨時實例(Persistent Instance):

  • 非臨時實例是指注冊到Nacos注冊中心的服務(wù)實例,其生命周期不會受到外部因素的影響,除非主動取消注冊或服務(wù)下線。
  • 這種實例適用于通常情況下穩(wěn)定運行的服務(wù),它們的注冊信息會被持久化存儲在Nacos服務(wù)器中,提供持久性的服務(wù)發(fā)現(xiàn)和注冊功能。

2、臨時實例(Ephemeral Instance):

  • 臨時實例是指服務(wù)實例在持有連接的客戶端斷開連接時,會自動從Nacos注冊中心上注銷的一種實例類型。
  • 當(dāng)客戶端與Nacos注冊中心建立心跳連接后,臨時實例會周期性地向注冊中心進行連接進行檢測。如果一段時間注冊中心沒有收到臨時實例的心態(tài)檢測,注冊中心會將對應(yīng)的實例注銷。
  • 臨時實例適用于動態(tài)擴縮容、臨時性訪問等場景,允許實例根據(jù)連接狀態(tài)進行動態(tài)管理。

臨時實例和非臨時實例在實踐中有不同的應(yīng)用場景:

  • 對于穩(wěn)定運行的服務(wù),應(yīng)使用非臨時實例。這樣服務(wù)實例的注冊信息將持久存在于注冊中心中,即使服務(wù)發(fā)生故障或重啟,也能保證注冊信息的持久性,其他服務(wù)能夠繼續(xù)發(fā)現(xiàn)和使用該實例。

  • 對于臨時性的任務(wù),如定時任務(wù)、臨時數(shù)據(jù)處理服務(wù)等,可以選擇使用臨時實例。這樣在任務(wù)完成后,實例會自動注銷,降低注冊中心中無用實例的數(shù)量,也能更好地適應(yīng)動態(tài)需求變化。

需要注意的是,臨時實例的自動注銷是基于與Nacos注冊中心之間的心跳連接,而非基于服務(wù)實例的具體運行狀態(tài)。因此,在使用臨時實例時,需要相應(yīng)地配置和管理心跳連接,以保證實例的不間斷注冊和注銷。

5.2、配置臨時實例與非臨時實例(默認是臨時實例)

服務(wù)注冊到nacos時,可以選擇注冊為臨時或非臨時實例,通過在application.yml文件中添加下面的配置來設(shè)置:

spring:cloud:nacos:discovery:   #discovery:發(fā)現(xiàn),透露 ; ephemeral:短暫的ephemeral: false  #設(shè)置為非臨時實例

?總結(jié)
1.Nacos與eureka的共同點
  • 都支持服務(wù)注冊和服務(wù)拉取
  • 都支持服務(wù)提供者心跳方式做健康檢測
2.Nacos與Eureka的區(qū)別
  • Nacos支持服務(wù)端主動檢測提供者狀態(tài):臨時實例采用心跳模式,非臨時實例采用主動檢測模式
  • 臨時實例心跳不正常會被剔除,非臨時實例則不會被剔除
  • Nacos支持服務(wù)列表變更的消息推送模式,服務(wù)列表更新更及時
  • Nacos集群默認采用AP方式,當(dāng)集群中存在非臨時實例時,采用CP模式;Eureka采用AP方式

6、Nacos配置管理

以下是幾個使用Nacos配置管理的實際業(yè)務(wù)場景的例子:

  1. 微服務(wù)配置管理:
    假設(shè)你的公司采用了微服務(wù)架構(gòu),有多個微服務(wù)需要連接到不同的數(shù)據(jù)庫。通過使用Nacos配置管理,你可以將每個微服務(wù)的數(shù)據(jù)庫連接信息存儲在Nacos中,并動態(tài)地更新配置。例如,當(dāng)你需要更改數(shù)據(jù)庫的連接地址或密碼時,你可以直接在Nacos中修改配置,而無需重新部署微服務(wù),所有微服務(wù)將自動獲取最新的配置信息。

  2. 多環(huán)境配置管理:
    假設(shè)你的應(yīng)用在開發(fā)、測試和生產(chǎn)環(huán)境中運行,并且每個環(huán)境都有不同的配置。使用Nacos配置管理,你可以為每個環(huán)境創(chuàng)建不同的配置文件,并通過Nacos的命名空間和配置組進行組織。開發(fā)人員可以通過選擇不同的命名空間和配置組,輕松地切換到不同的環(huán)境,而不必手動修改配置文件。

  3. 動態(tài)路由配置:
    假設(shè)你的微服務(wù)架構(gòu)中使用了Spring Cloud Gateway作為API網(wǎng)關(guān),并且你希望能夠動態(tài)路由請求到不同的后端服務(wù)。通過使用Nacos配置管理,你可以將路由規(guī)則存儲在Nacos中,并通過Spring Cloud Gateway與Nacos集成。當(dāng)需要更新路由規(guī)則時,你可以直接在Nacos中修改配置,Spring Cloud Gateway將自動更新路由,并將請求動態(tài)地轉(zhuǎn)發(fā)到相應(yīng)的后端服務(wù)。

  4. 定時任務(wù)配置:
    假設(shè)你的應(yīng)用需要執(zhí)行定時任務(wù),例如生成報表或清理數(shù)據(jù)。通過使用Nacos配置管理,你可以將定時任務(wù)的觸發(fā)時間、任務(wù)參數(shù)等信息存儲在Nacos中,并由任務(wù)調(diào)度器定期從Nacos獲取最新的配置。當(dāng)你需要調(diào)整定時任務(wù)的執(zhí)行時間或參數(shù)時,只需在Nacos中修改配置,任務(wù)調(diào)度器將自動根據(jù)最新的配置執(zhí)行任務(wù)。

這些例子只是Nacos配置管理功能的一部分,Nacos還提供了更多的特性,例如配置監(jiān)聽、配置推送等,可以根據(jù)具體的業(yè)務(wù)需求進行靈活使用。

6.1、統(tǒng)一配置管理
6.1.1、配置更改熱更新

?在Nacos中添加配置信息:

?在彈出表單中填寫配置信息:

?在nacos服務(wù)頁面中配置,讓服務(wù)找到nacos的配置:

1、引入nacos的配置管理客戶依賴:
        <!--nacos配置管理依賴--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency>
2、在userservice中的resource目錄添加一個bootstrap.yml文件,這個文件是引導(dǎo)文件,優(yōu)先級高于application.yml:
spring:application:name: userservice  #配置服務(wù)名稱cloud:nacos:server-addr: localhost:8848   #配置nacos服務(wù)地址config:file-extension: yaml  #文件后綴profiles:active: dev  #開發(fā)環(huán)境,這里是dev

可以在Usercontroller類中獲取一下nacos配置的信息來驗證一下:

    @Value("${pattern.dateformat}")private String dateformat;@GetMapping("/now")public String now(){return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));}
6.1.2、配置自動刷新

nacos中的配置文件變更后,微服務(wù)無需重新啟動就可以感知。不過需要通過下面兩種配置實現(xiàn):

方式一:在@Value注入的變量所在類上添加注解@RefreshScope

?方式二:使用@ConfigurationProperties注解

這種方式使用的是約束大于配置的配置方法。

@Data
@Component
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {private String dateformat;
}

使用了Spring框架的注解(Data,Component,ConfigurationProperties)。這段代碼定義了一個名為PatternProperties的類。

@ConfigurationProperties注解是Spring框架中用于綁定配置屬性的注解。它的prefix屬性指定了配置文件中的屬性前綴為"pattern",這意味著在配置文件中,所有以"pattern"開頭的屬性會被綁定到PatternProperties類的對應(yīng)屬性上。

PatternProperties類中只有一個私有的String類型屬性dateformat,它對應(yīng)配置文件中的"pattern.dateformat"屬性。在配置文件中,你可以設(shè)置這個屬性的值,例如:

pattern:dateformat: yyyy-MM-dd HH:mm:ss

這樣,當(dāng)你運行程序時,Spring框架會自動將配置文件中的值綁定到PatternProperties類的dateformat屬性上,你可以通過獲取PatternProperties實例的方式來訪問并使用這個屬性的值。

在類中使用nacos中配置時可以通過以下方式獲取:

?總結(jié)
Nacos配置更改后,微服務(wù)可以實現(xiàn)熱更新,方式:
  • 通過@Value注解注入,結(jié)合@RefreshScope來刷新
  • 通過@ConfigurationProperties注入,自動刷新
注意事項:
  • 不是所有的配置都適合放到配置中心,維護起來比較麻煩
  • 建議將一些關(guān)鍵參數(shù),需要運行時調(diào)整的參數(shù)放到nacos配置中心,一般都是自定義配置

7、Nacos集群搭建

7.1、集群結(jié)構(gòu)圖
官方給出的Nacos集群圖:

其中包含3個nacos節(jié)點,然后一個負載均衡器代理3個Nacos。這里負載均衡器可以使用nginx。

DNS(Domain Name System)、SLB(Server Load Balancer)和Nacos可以一起使用來構(gòu)建一個完整的服務(wù)發(fā)現(xiàn)和負載均衡的系統(tǒng)。

DNS是用于將域名解析為對應(yīng)的IP地址的系統(tǒng)。在服務(wù)發(fā)現(xiàn)和負載均衡中,DNS可以被用來解析服務(wù)名稱為對應(yīng)的服務(wù)實例的IP地址。例如,假設(shè)有一個服務(wù)名為"my-service",通過將其注冊到DNS中,可以將"my-service"解析為具體的服務(wù)實例的IP地址。

SLB是一種負載均衡器,用于將流量分發(fā)到多個后端服務(wù)實例上,從而實現(xiàn)負載均衡和高可用性。SLB可以接收客戶端請求,并根據(jù)負載均衡算法將請求分發(fā)到多個服務(wù)實例上。例如,當(dāng)有多個服務(wù)實例提供相同的服務(wù)時,SLB可以根據(jù)負載情況,將請求分發(fā)到負載較低的實例上,以實現(xiàn)流量的均衡分布。

Nacos是一個用于服務(wù)發(fā)現(xiàn)、配置管理和服務(wù)治理的開源項目。在服務(wù)發(fā)現(xiàn)和負載均衡中,Nacos作為服務(wù)注冊中心和配置中心,可以用來管理各個服務(wù)實例的注冊和注銷,以及維護服務(wù)實例的元數(shù)據(jù)信息。Nacos可以提供給SLB和DNS所需的服務(wù)實例信息,從而實現(xiàn)服務(wù)發(fā)現(xiàn)和負載均衡的功能。

結(jié)合這三個組件,整體的架構(gòu)可以如下所示:

  1. 服務(wù)實例注冊:服務(wù)實例可以將自己的元數(shù)據(jù)信息注冊到Nacos中,包括服務(wù)名稱、IP地址、端口等信息。

  2. Nacos服務(wù)注冊中心:Nacos注冊中心負責(zé)存儲和管理所有服務(wù)實例的元數(shù)據(jù)信息。

  3. Nacos配置中心:Nacos配置中心負責(zé)存儲和管理應(yīng)用程序的配置信息。

  4. DNS解析:客戶端可以通過DNS解析服務(wù)名稱為具體的服務(wù)實例的IP地址。

  5. SLB負載均衡器:SLB可以接收客戶端請求,并根據(jù)負載均衡算法將請求分發(fā)到多個服務(wù)實例上。

通過這樣的結(jié)構(gòu),客戶端可以通過DNS解析獲取到服務(wù)實例的IP地址,并通過SLB將請求發(fā)送到可用的服務(wù)實例上,實現(xiàn)負載均衡。同時,Nacos作為服務(wù)注冊中心和配置中心,可以管理服務(wù)實例的注冊和配置信息,以確保服務(wù)的可用性和配置的一致性。這樣的架構(gòu)既提供了可靠的服務(wù)發(fā)現(xiàn)和負載均衡,也保證了配置的集中管理和動態(tài)更新能力。

我們計劃的集群結(jié)構(gòu):

?三個nacos節(jié)點的地址:

| 節(jié)點 ? | ip ? ? ? ? ? ?| port || nacos1 | 192.168.150.1 | 8845 || nacos2 | 192.168.150.1 | 8846 || nacos3 | 192.168.150.1 | 8847 |
7.2、集群搭建

搭建集群的基本步驟:

- 搭建數(shù)據(jù)庫,初始化數(shù)據(jù)庫表結(jié)構(gòu)- 下載nacos安裝包- 配置nacos- 啟動nacos集群- nginx反向代理

六、Feign遠程調(diào)用

RestTemplate方法調(diào)用存在的問題

先看一下我們以前利用RestTemplate發(fā)起遠程調(diào)用的代碼:

存在下面的問題:

  • 代碼可讀性差,編程體驗不統(tǒng)一
  • 參數(shù)復(fù)雜URL難維護

1、Feign的介紹

Feign 提供了一種簡單且優(yōu)雅的方式來定義和調(diào)用基于HTTP的遠程服務(wù)。通過使用Feign,您可以在客戶端代碼中定義接口,然后Feign會根據(jù)這些接口的定義自動生成實際的HTTP請求,并將其轉(zhuǎn)發(fā)到遠程服務(wù)。這樣,您可以像調(diào)用本地方法一樣調(diào)用遠程服務(wù)的方法,無需顯式地處理HTTP請求和響應(yīng)。

Feign 還支持對請求進行編碼和解碼、錯誤處理、請求和響應(yīng)攔截器等功能,使得在微服務(wù)架構(gòu)中處理遠程服務(wù)變得更加方便和高效。

使用Feign的一些優(yōu)點包括:

  1. 簡化了客戶端代碼,使其更易于維護和理解。
  2. 減少了手動處理HTTP請求和響應(yīng)的工作量。
  3. 支持多種編解碼器,可處理多種數(shù)據(jù)格式。
  4. 可與Spring Cloud等微服務(wù)框架無縫集成。

在使用Feign時,您需要定義一個Java接口,該接口包含與遠程服務(wù)相對應(yīng)的方法和參數(shù)。然后,通過在應(yīng)用程序的配置中啟用Feign并使用Spring的依賴注入功能,您可以將Feign客戶端注入到您的代碼中,從而實現(xiàn)對遠程服務(wù)的調(diào)用。

Feign作為一個聲明式的HTTP客戶端,在微服務(wù)架構(gòu)和分布式系統(tǒng)中有許多應(yīng)用場景。以下是一些常見的使用場景:

  1. 微服務(wù)間的通信:在微服務(wù)架構(gòu)中,各個服務(wù)之間需要頻繁地進行通信,Feign可以幫助簡化服務(wù)間的HTTP通信,使得調(diào)用遠程服務(wù)更加方便。

  2. 服務(wù)消費者:當(dāng)一個服務(wù)需要調(diào)用其他服務(wù)提供的API時,可以使用Feign來作為客戶端來消費這些服務(wù),而無需手動處理HTTP請求和響應(yīng)。

  3. 代理遠程API:Feign可以將遠程服務(wù)的API映射為本地接口,使得調(diào)用遠程服務(wù)的過程就像調(diào)用本地方法一樣簡單。

  4. 負載均衡:結(jié)合負載均衡的工具(如Ribbon),Feign可以實現(xiàn)在多個服務(wù)實例之間進行負載均衡,從而提高系統(tǒng)的可用性和性能。

  5. 聲明式的錯誤處理:Feign支持定義統(tǒng)一的錯誤處理邏輯,使得在發(fā)生錯誤時可以采取一致的處理方式,從而減少重復(fù)代碼。

  6. 數(shù)據(jù)格式處理:Feign支持多種編解碼器,可以處理不同的數(shù)據(jù)格式,例如JSON、XML等,使得數(shù)據(jù)的傳輸和解析更加靈活和便捷。

  7. 請求攔截與日志:Feign支持請求和響應(yīng)攔截器,可以在發(fā)送請求和接收響應(yīng)時進行攔截和處理,例如記錄日志、鑒權(quán)等。

總體而言,Feign適用于任何需要在微服務(wù)架構(gòu)中進行HTTP通信的場景,特別是當(dāng)您希望簡化遠程服務(wù)調(diào)用的代碼并增加可讀性和可維護性時,Feign是一個非常有用的工具。

2、定義和使用Feign客戶端

在之前我是在調(diào)用其他服務(wù)提供的接口是使用的是RestTempale,為什么還要學(xué)Feign呢?

Feign和RestTemplate都是在Spring框架中用于進行HTTP請求的工具,但它們在使用方式和特點上有一些區(qū)別。

  1. 聲明式 vs. 編程式:

    • Feign是一個聲明式的HTTP客戶端,它允許您通過定義接口來描述對遠程服務(wù)的請求,并自動生成底層HTTP調(diào)用。Feign使用注解來配置請求的URL、HTTP方法、請求參數(shù)等信息,使得代碼更加簡潔和易讀。
    • RestTemplate是一個編程式的HTTP客戶端,您需要在代碼中顯式地構(gòu)建HTTP請求,包括指定URL、HTTP方法、請求頭、請求體等信息。雖然可以通過RestTemplate靈活地控制請求細節(jié),但相比Feign,代碼可能會更冗長和復(fù)雜。
  2. 整合Spring Cloud vs. 單獨使用:

    • Feign是Spring Cloud項目的一部分,它與Spring Cloud的其他組件(如Eureka、Ribbon、Hystrix等)緊密集成,使得在微服務(wù)架構(gòu)中使用Feign更加方便,并且提供了一些額外的特性,如負載均衡、服務(wù)發(fā)現(xiàn)等。
    • RestTemplate是Spring Framework的一部分,它可以單獨使用,沒有與Spring Cloud的深度集成。如果您在非微服務(wù)環(huán)境中,或者不需要Spring Cloud提供的其他功能,RestTemplate是一個不錯的選擇。
  3. 自動化的負載均衡:

    • Feign與Ribbon(Spring Cloud中的負載均衡組件)集成,可以自動進行負載均衡,使得在多個服務(wù)實例中選擇合適的目標(biāo)服務(wù)。
    • RestTemplate在默認情況下不支持自動的負載均衡,您需要手動編寫代碼來實現(xiàn)負載均衡,或者結(jié)合Ribbon來實現(xiàn)自動化負載均衡。
  4. 請求攔截器和錯誤處理:

    • Feign允許您定義請求和響應(yīng)攔截器,從而可以在發(fā)送請求和接收響應(yīng)時進行攔截和處理,例如記錄日志、鑒權(quán)等。它還提供了聲明式的錯誤處理機制,讓您可以統(tǒng)一處理請求錯誤。
    • RestTemplate也支持請求和響應(yīng)攔截器,但是在處理錯誤時可能相對繁瑣,需要通過捕獲異常等方式來處理請求錯誤。

綜上所述,如果您在使用Spring Cloud和微服務(wù)架構(gòu),特別是在Feign與Ribbon、Eureka等組件進行集成時,Feign可能是更好的選擇,因為它提供了一種簡單且聲明式的方式來定義和調(diào)用遠程服務(wù)。然而,如果您在非微服務(wù)環(huán)境或不需要Spring Cloud提供的其他功能,RestTemplate仍然是一個可行的選擇,尤其是當(dāng)您需要更多的靈活性和對HTTP請求的直接控制時。

2.1、Feign實戰(zhàn)

定義和使用Feign客戶端需要以下步驟:

1、添加依賴:首先,您需要在項目中添加Feign的依賴。如果您是使用Spring Boot項目,可以在pom.xml中添加以下依賴:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2、啟用Feign客戶端:為了使Feign客戶端生效,您需要在Spring Boot應(yīng)用程序的主類上添加@EnableFeignClients注解,這將啟用Feign客戶端的自動配置和發(fā)現(xiàn)。

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
@EnableFeignClients
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}}

3、創(chuàng)建Feign客戶端接口:接下來,您需要定義一個Java接口,該接口將包含與遠程服務(wù)相對應(yīng)的方法和參數(shù)。這些方法的定義類似于普通的Spring組件接口,但是您可以使用Spring的注解來定義遠程服務(wù)的URL、HTTP方法和其他相關(guān)信息。

package cn.itcast.order.clients;import cn.itcast.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;@FeignClient("userservice")  //使用@FeignClient來指導(dǎo)這個接口所有接口方法要訪問的服務(wù)名稱
public interface UserClient {//定義調(diào)用接口@GetMapping("/user/{id}")  User findUserById(@PathVariable("id") Long id);
}

?4、使用Feign客戶端:現(xiàn)在您可以在其他組件或服務(wù)中注入Feign客戶端,并使用它來調(diào)用遠程服務(wù)的方法。

package cn.itcast.order.service;import cn.itcast.order.clients.UserClient;
import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import cn.itcast.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate UserClient userClient;   //注入User的Feign客戶端public Order queryOrderById(Long id){Order order = orderMapper.findById(id);Long userId = order.getUserId();//使用Feign遠程調(diào)用User user = userClient.findUserById(userId);order.setUser(user);return order;}
}
總結(jié)

Feign的使用步驟

  1. 引入依賴
  2. 添加@EnableFeignClients注解
  3. 編寫FeignClient接口
  4. 使用FeignClient中定義的方法代替RestTemplate

3、自定義Feign的配置

Feign運行自定義配置來覆蓋默認配置,可以修改的配置如下:

?一般我們需要配置的就是日志級別。

日志級別

Feign支持四種不同的日志級別,您可以根據(jù)需要選擇適合的日志級別。這些日志級別用于控制Feign在發(fā)送請求和接收響應(yīng)時記錄的日志信息的詳細程度。

  1. NONE:該日志級別最低,不記錄任何日志信息。如果您不想在控制臺輸出任何關(guān)于Feign請求和響應(yīng)的日志,可以選擇此級別。

  2. BASIC:在BASIC級別下,Feign僅記錄請求方法、URL和響應(yīng)狀態(tài)碼的基本信息。這對于快速了解請求的基本情況很有幫助,但不會記錄請求和響應(yīng)的詳細內(nèi)容。

  3. HEADERS:在HEADERS級別下,Feign將記錄請求和響應(yīng)的頭部信息,包括請求頭和響應(yīng)頭。這樣可以更詳細地查看請求和響應(yīng)的頭部信息,有助于調(diào)試和了解請求的上下文。

  4. FULL:FULL級別是最詳細的日志級別,它會記錄請求和響應(yīng)的所有詳細信息,包括請求頭、請求體、響應(yīng)頭和響應(yīng)體。如果您需要完整的請求和響應(yīng)信息來進行詳細的調(diào)試和排查問題,FULL級別是最合適的選擇。

3.1自定義Feign的配置方式
方式一:配置文件方式

當(dāng)使用配置文件的方式來配置Feign的自定義配置時,您可以借助Spring Boot的屬性配置功能來實現(xiàn)。通過在配置文件(如application.properties或application.yml)中添加特定的屬性,您可以自定義Feign的行為。

首先,您需要在配置文件中添加Feign的相關(guān)屬性。以YAML格式的配置文件為例,假設(shè)您想要配置Feign的日志級別為FULL,可以這樣寫:

1、全局生效
# application.yml
feign:client:config:default: #這里用default就是全局配置,如果是寫服務(wù)器名稱,則是針對在某個微服務(wù)的配置loggerLevel: full  #日志級別
2、局部生效
# application.yml
feign:client:config:orderservice:    #這里用服務(wù)名稱,則只針對這個服務(wù)的配置loggerLevel: full   #日志級別
方式二:java代碼方式,需要先聲明一個Bean:

在使用Feign時,您可以通過自定義配置來修改其行為和屬性。為了自定義Feign的配置,您需要創(chuàng)建一個配置類,并在其中添加相關(guān)的Bean定義。下面是一個簡單的示例來說明如何自定義Feign的配置:

package cn.itcast.order.config;import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class FeignConfig {@Beanpublic Logger.Level feignLogLevel(){return Logger.Level.BASIC;}
}
全局配置:

如果是全局配置,則把它放到@EnableFeignClients這個注解中:

@EnableFeignClients(defaultConfiguration = FeignConfig.class)
局部配置:

如果是局部配置,則把它放到@FeignClient這個注解中:

@FeignClient(value = "userservice",configuration = FeignConfig.class)  
總結(jié)

Feign的日志配置
1.方式一是配置文件,feign.client.config.xxx.loggerLevel

  1. O如果xxx是default則代表全局
  2. 如果xxx是服務(wù)名稱,例如userservice則代表某服務(wù)

2.方式二是java代碼配置Logger.Level這個Bean

  1. 如果在@EnableFeignClients注解聲明則代表全局
  2. 如果在@FeignClient注解中聲明則代表某服務(wù)

4、Feign的性能優(yōu)化

Feign的底層客戶端實現(xiàn)是通過集成了其他HTTP客戶端庫來實現(xiàn)的。具體來說,Feign支持兩種主要的HTTP客戶端實現(xiàn):JDK的URLConnection和Apache HttpClient。

  1. JDK的URLConnection:這是Java標(biāo)準庫中提供的用于HTTP通信的API。Feign可以直接使用JDK的URLConnection來發(fā)送HTTP請求。它是輕量級的,對于簡單的HTTP通信,可能足夠滿足需求。如果您在項目中沒有引入其他HTTP客戶端庫,Feign會默認使用JDK的URLConnection作為底層的客戶端實現(xiàn)。

  2. Apache HttpClient:Apache HttpClient是Apache基金會提供的一個功能豐富、靈活的HTTP客戶端庫。它提供了許多高級功能,如連接池、重試機制、認證等。如果您在項目中引入了Apache HttpClient的依賴,Feign會自動選擇使用Apache HttpClient作為底層的客戶端實現(xiàn)。

  3. OkHttp:OkHttp是Square公司開發(fā)的一款高效的HTTP客戶端庫。它支持HTTP/2、連接池、攔截器等現(xiàn)代特性。如果您在項目中引入了OkHttp的依賴,Feign會自動切換到OkHttp作為底層實現(xiàn)。

Feign的這種設(shè)計使得您可以根據(jù)需要靈活地選擇底層的HTTP客戶端。默認情況下,如果項目中沒有引入其他HTTP客戶端庫,Feign將使用JDK的URLConnection作為底層客戶端。如果您希望使用Apache HttpClient或OkHttp,只需在項目中添加相應(yīng)的依賴,Feign會自動檢測并使用它們作為底層實現(xiàn)。

通過這種方式,Feign可以同時滿足不同項目對HTTP客戶端的需求,并提供簡便的遠程服務(wù)調(diào)用方式。

因此優(yōu)化Feign的性能主要包括:
  1. 使用連接池代替默認的URLConnection
  2. 日志級別,做好使用basic或者none
4.1、 Feign性能優(yōu)化HttpClient的支持:
1、Feign添加HttpClient的支持:

引入依賴:

        <dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId></dependency>

配置連接池:

#feign自定義配置,配置日志級別
feign:client:config:default:  #這里用default就是全局配置,如果是寫服務(wù)器名稱,則是針對在某個微服務(wù)的配置loggerLevel: basic  #日志級別httpclient:enabled: true   #開啟feign對HttpClient的支持max-connections: 200   #最大連接數(shù)量max-connections-per-route: 50   #每個路徑的最大連接數(shù)量
總結(jié)

Feign的優(yōu)化
1.日志級別盡量用basic
2.使用HttpClient或OKHttp代替URLConnection

  1. 引入feign-httpClient依賴
  2. 配置文件開啟httpClient功能,設(shè)置連接池參數(shù)

5、Feign的最佳實際

方式一(繼承):給消費者的FeignClient和提供者的controller系統(tǒng)定義一個父接口作為標(biāo)準。

這種實現(xiàn)方式雖然可以讓Controller和Feign Client共享同一個接口定義,但存在一些問題和注意事項:

  1. 潛在的耦合:共享同一個接口定義會讓Controller和Feign Client在代碼層面產(chǎn)生耦合,導(dǎo)致它們緊密地關(guān)聯(lián)在一起。一旦接口定義發(fā)生變化,兩者都需要進行相應(yīng)的修改,這可能影響到多個模塊。

  2. 不符合單一職責(zé)原則:Controller負責(zé)處理HTTP請求和返回響應(yīng),而Feign Client負責(zé)遠程服務(wù)調(diào)用。將它們共享同一個接口可能會讓代碼功能變得混亂,違反了單一職責(zé)原則。

  3. 難以做到完全解耦:盡管接口定義可以共享,但是在Feign Client的實現(xiàn)中,仍然需要涉及到遠程服務(wù)調(diào)用的邏輯。這會讓Feign Client的實現(xiàn)和Controller之間仍然有一定的耦合。

  4. 接口定義可能會變得復(fù)雜:為了適應(yīng)不同的調(diào)用場景,共享接口可能會變得復(fù)雜,可能需要添加各種參數(shù)和注解,從而導(dǎo)致接口的冗長和不易維護。

  5. 功能不一致問題:在Controller和Feign Client共享同一個接口的情況下,兩者的功能可能不完全一致。在Controller中可能需要做一些本地邏輯處理,而在Feign Client中可能需要進行額外的遠程服務(wù)調(diào)用。

綜上所述,雖然共享接口可以在一定程度上減少重復(fù)代碼,但也會引入潛在的問題和復(fù)雜性。在實際開發(fā)中,更常見的做法是將Controller和Feign Client分別定義獨立的接口,通過接口定義來規(guī)范各自的功能和職責(zé)。在需要共享方法定義的情況下,可以使用Java接口繼承來實現(xiàn)方法的復(fù)用,而避免在Feign Client中直接實現(xiàn)Controller的方法。這樣可以更好地保持代碼的清晰和可維護性,并符合單一職責(zé)原則。

方式二(抽取):將FeignClient抽取為獨立模塊,并且把接口有關(guān)的POJO、默認的Feign配置都放到這個模塊中,提供給所有消費者使用

以前實現(xiàn)?

假如:我們有order-service、pay-service和user-service兩個服務(wù),現(xiàn)在order-service和pay-service都要去調(diào)用user-service提供的接口,我們就得order-service和pay-service服務(wù)里都要實現(xiàn)UserClient,假如我們不止只有這兩個服務(wù)調(diào)用user-service呢,有10個、20個服務(wù)都要調(diào)用,那UserClient就得寫10遍、20遍,就會重復(fù)的開發(fā)代碼了。

現(xiàn)在

我們獨立創(chuàng)建一個項目,將哪些重復(fù)的代碼編寫的東西全部放到這個項目/模塊中(如UserClient、User實體類、DefaultConfig等),我們可以把這個項目的內(nèi)容打成jar包,假如以后服務(wù)需要的時候直接引用依賴就可以

?總結(jié)

Feign的最佳實踐

  1. 讓controller和FeignClient繼承同一接口
  2. 將FeignClient、poJo、Feign的默認配置都定義到一個項目中,供所有消費者使用
?抽取FeignClient
實現(xiàn)最佳實踐方式二的步驟如下:
1、創(chuàng)建一個module,命名為feign-api,然后引入feign的starter依賴

引入feign的starter依賴:

    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
2、將order-service中編寫的UserClient、User、DefaultFeignConfiguration都復(fù)制到feign-api項目中

?之前在order-service服務(wù)模塊中餓這些東西就可以刪除了。

?3、在order-service中引入feign-api的依賴
        <!--引入feign的同一api--><dependency><groupId>cn.itcast.demo</groupId><artifactId>feign-api</artifactId><version>1.0</version></dependency>

這個依賴是我們項目中的feign-api模塊里的內(nèi)容。

4、修改order-service中的所有與上述三個組件有關(guān)的import部分,改成導(dǎo)入feign-api中的包

5、重啟測試
當(dāng)定義的FeignClient不在springApplication的包掃描范圍時,這些FeignClient無法使用問題

重啟order-service服務(wù)后我們會發(fā)現(xiàn)報錯了

Field userClient in cn.itcast.order.service.OrderService required a bean of type 'cn.itcast.feign.clients.UserClient' that could not be found.該錯誤信息表明在OrderService類中的userClient字段的類型為cn.itcast.feign.clients.UserClient,但是Spring容器中找不到該類型的Bean。

說明我們在自動裝配UserClient時是找不到這個對象的實例的,原因是我們現(xiàn)在在order-service模塊中使用的UserClient是通過添加了feign-api依賴而導(dǎo)進來的,在order-service模塊啟動時spring只會對啟動類所在目錄及這個目錄里所有類進行掃描注冊到spring容器中的,而UserClient所在的包就沒有被掃描到,所在在order-service這個模塊中的spring容器中就找不到了對于的對象實例了。

解決辦法方式一:指定FeignClient所在包
@EnableFeignClients(basePackages = "cn.itcast.feign.clients")
解決辦法方式二:指定FeignClient字節(jié)碼
@EnableFeignClients(clients = {UserClient.class})
總結(jié)

不同包的FeignClient的導(dǎo)入有兩種方式

  1. 在@EnableFeignClients注解中添加basePackages,指定FeignClient所在的包
  2. 在@EnableFeignClients注解中添加clients,指定具體FeignClient的字節(jié)碼

七、Gateway服務(wù)網(wǎng)關(guān)

網(wǎng)關(guān)(Gateway)服務(wù)在微服務(wù)架構(gòu)中起著重要的作用。它是位于客戶端和后端微服務(wù)之間的中間層,用于處理和轉(zhuǎn)發(fā)請求。為什么要使用網(wǎng)關(guān)服務(wù)呢?以下是一些主要的原因:

  1. 統(tǒng)一入口:網(wǎng)關(guān)服務(wù)提供了一個統(tǒng)一的入口,客戶端只需要向網(wǎng)關(guān)發(fā)送請求,而不需要直接調(diào)用各個微服務(wù)。這樣簡化了客戶端的調(diào)用邏輯,同時也方便地對請求進行統(tǒng)一管理和處理。

  2. 路由和負載均衡:網(wǎng)關(guān)服務(wù)可以根據(jù)請求的URL路徑或其他條件將請求路由到相應(yīng)的微服務(wù)實例。它還可以配合負載均衡算法,確保請求被均勻地分發(fā)給不同的服務(wù)實例,提高了系統(tǒng)的可用性和性能。

  3. 安全控制:通過網(wǎng)關(guān)服務(wù),可以實現(xiàn)對請求進行安全控制和認證。網(wǎng)關(guān)可以驗證請求的身份、權(quán)限以及合法性,確保只有授權(quán)的請求能夠訪問相應(yīng)的微服務(wù)。

  4. 聚合和分解請求:網(wǎng)關(guān)服務(wù)可以聚合多個微服務(wù)的請求,將它們合并為一個請求返回給客戶端,從而減少了客戶端與后端服務(wù)之間的請求次數(shù),降低了網(wǎng)絡(luò)開銷。

  5. 緩存:網(wǎng)關(guān)服務(wù)可以對請求的響應(yīng)進行緩存,從而減少重復(fù)請求對后端服務(wù)的壓力,提高了系統(tǒng)的性能和響應(yīng)速度。

  6. 降級和容錯:網(wǎng)關(guān)服務(wù)可以實現(xiàn)對后端服務(wù)的降級和容錯處理。當(dāng)某個微服務(wù)出現(xiàn)故障或不可用時,網(wǎng)關(guān)可以提供默認的響應(yīng)或調(diào)用備用服務(wù),避免了系統(tǒng)級的故障。

  7. 監(jiān)控和日志:通過網(wǎng)關(guān)服務(wù),可以實現(xiàn)對請求和響應(yīng)進行監(jiān)控和日志記錄。這有助于實時追蹤請求的流程和性能,發(fā)現(xiàn)問題并進行及時的處理。

綜上所述,網(wǎng)關(guān)服務(wù)在微服務(wù)架構(gòu)中扮演了一個重要的角色,它提供了統(tǒng)一入口、路由和負載均衡、安全控制、聚合和分解請求、緩存、降級和容錯、監(jiān)控和日志等功能,為整個系統(tǒng)提供了更高效、更安全、更穩(wěn)定的請求處理和管理能力。

1、網(wǎng)關(guān)技術(shù)

?在springcloud中網(wǎng)關(guān)的實現(xiàn)有兩種:gateway和zuul

Zuul和Spring Cloud Gateway都是常用的網(wǎng)關(guān)實現(xiàn),用于在微服務(wù)架構(gòu)中處理和轉(zhuǎn)發(fā)請求。它們都可以作為反向代理和請求路由器,但在設(shè)計和功能上有一些區(qū)別。

  1. Zuul:

    Zuul是Netflix提供的網(wǎng)關(guān)服務(wù),被稱為Netflix Zuul。它是一個基于Servlet的網(wǎng)關(guān)實現(xiàn),構(gòu)建在傳統(tǒng)的Spring Cloud項目上。Zuul 1.x版本采用阻塞式I/O模型,Zuul 2.x版本采用非阻塞式I/O模型,基于Netty。

    特點:

    • Zuul 1.x的阻塞式I/O模型限制了并發(fā)性能,雖然可以通過多實例部署來提高吞吐量,但對于高并發(fā)場景可能不夠高效。
    • Zuul 2.x基于非阻塞式I/O模型,可以提供更好的性能和吞吐量。
    • Zuul支持動態(tài)路由和過濾器等功能,可以實現(xiàn)請求的動態(tài)轉(zhuǎn)發(fā)和預(yù)處理。
    • 配置方式較為靈活,可以使用Groovy或Java DSL配置路由和過濾器。
  2. Spring Cloud Gateway:

    Spring Cloud Gateway是Spring Cloud項目中的網(wǎng)關(guān)服務(wù),從Spring Cloud 2.x版本開始引入。它是基于Spring 5和Spring Boot 2構(gòu)建的,采用了WebFlux框架,支持響應(yīng)式編程。

    特點:

    • Spring Cloud Gateway采用基于異步非阻塞的WebFlux框架,提供了更好的性能和響應(yīng)能力,適用于高并發(fā)場景。
    • 支持動態(tài)路由和過濾器等功能,可以實現(xiàn)請求的動態(tài)轉(zhuǎn)發(fā)和預(yù)處理。
    • 提供了豐富的過濾器,支持全局和局部過濾器的定義和使用。
    • 配置方式靈活,可以使用YAML或Java配置路由和過濾器。

綜合來說,Zuul和Spring Cloud Gateway都是成熟的網(wǎng)關(guān)實現(xiàn),各有優(yōu)勢。如果您在使用Spring Cloud項目,推薦使用Spring Cloud Gateway,特別是在需要高并發(fā)和響應(yīng)能力的場景下。而如果您在使用Netflix項目,可以選擇使用Netflix Zuul 2.x版本或更高的版本,或考慮遷移到Spring Cloud Gateway。選擇哪個網(wǎng)關(guān)取決于您的項目需求、技術(shù)棧和預(yù)期的性能要求。

總結(jié)

網(wǎng)關(guān)的作用:

  • 對用戶請求做身份認證、權(quán)限校驗
  • 將用戶請求路由到微服務(wù),并實現(xiàn)負載均衡
  • 對用戶請求做限流

2、搭建網(wǎng)關(guān)服務(wù)

2.1、搭建網(wǎng)關(guān)服務(wù)的步驟:
  1. 創(chuàng)建Gateway項目:首先,創(chuàng)建一個新的Spring Boot項目作為Gateway服務(wù)網(wǎng)關(guān)。

  2. 添加依賴:在Gateway項目中,添加Spring Cloud Gateway和Nacos的依賴,以便使用Gateway和Nacos的功能。在pom.xml文件中添加以下依賴:

<dependencies><!-- Spring Cloud Gateway --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!-- Spring Cloud Nacos 作為服務(wù)注冊和發(fā)現(xiàn)中心 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- 其他依賴 -->
</dependencies>

3、配置網(wǎng)關(guān)路由:在application.yml中配置網(wǎng)關(guān)的路由規(guī)則,將請求路由到對應(yīng)的微服務(wù)。例如:

server:port: 10009  # 配置服務(wù)端口spring:application:name: gateway  # 服務(wù)名稱cloud:nacos:server-addr: localhost:8848  # 配置Nacos注冊中心的地址和端口gateway:routes:- id: userservice_route   # 路由規(guī)則的唯一標(biāo)識,用于識別該路由規(guī)則。自定義的標(biāo)識可以方便管理和維護。uri: lb://userservice   # 指定目標(biāo)微服務(wù)的服務(wù)名。lb://前綴表示使用負載均衡器來選擇目標(biāo)微服務(wù)的實例。這里目標(biāo)微服務(wù)的服務(wù)名是userservice。predicates:    # 斷言條件列表,用于匹配請求是否符合該路由規(guī)則。- Path=/user/**      # 匹配的URL路徑,當(dāng)請求的URL路徑以/user/開頭時,該路由規(guī)則會匹配。**表示匹配任意后續(xù)路徑。- id: orderservice_route   # 另一個路由規(guī)則的唯一標(biāo)識,用于識別該路由規(guī)則。uri: lb://orderservice  # 指定目標(biāo)微服務(wù)的服務(wù)名。這里目標(biāo)微服務(wù)的服務(wù)名是orderservice。predicates:             # 斷言條件列表,用于匹配請求是否符合該路由規(guī)則。- Path=/order/**      # 匹配的URL路徑,當(dāng)請求的URL路徑以/order/開頭時,該路由規(guī)則會匹配。**表示匹配任意后續(xù)路徑。

4、啟動nacos服務(wù)

#Windows系統(tǒng)命令
startup.cmd -m standalone#Linux系統(tǒng)命令
sh startup.sh -m standalone

就可以直接使用gateway的ip+端口來訪問數(shù)據(jù)了,可以直接讓gateway來將這些訪問地址轉(zhuǎn)發(fā)到相應(yīng)的服務(wù)實例上,從而來訪問數(shù)據(jù)(如訪問地址:localhost:10009/order/101)

2.2、搭建網(wǎng)關(guān)服務(wù)流程圖

  1. 客戶端發(fā)起請求:客戶端(如Web應(yīng)用、移動端應(yīng)用、或其他服務(wù))發(fā)起HTTP請求。

  2. 請求到達Gateway:請求首先到達Gateway服務(wù)網(wǎng)關(guān)。

  3. Gateway進行路由匹配:Gateway根據(jù)預(yù)先配置的路由規(guī)則,匹配請求的URL路徑、請求頭等信息,找到對應(yīng)的微服務(wù)實例。

  4. 服務(wù)發(fā)現(xiàn):Gateway需要通過服務(wù)注冊中心(如Nacos)來獲取微服務(wù)實例的信息。它向Nacos發(fā)送服務(wù)發(fā)現(xiàn)請求,Nacos會返回目標(biāo)微服務(wù)的實例列表。

  5. 負載均衡:Gateway使用負載均衡算法從目標(biāo)微服務(wù)實例列表中選擇一個實例,將請求轉(zhuǎn)發(fā)給該微服務(wù)實例。

  6. 微服務(wù)接收請求:目標(biāo)微服務(wù)實例接收到請求。

  7. 微服務(wù)處理請求:微服務(wù)實例處理請求,并根據(jù)業(yè)務(wù)邏輯執(zhí)行相應(yīng)的操作。

  8. 微服務(wù)返回響應(yīng):微服務(wù)實例生成響應(yīng)結(jié)果,并將響應(yīng)返回給Gateway。

  9. Gateway接收響應(yīng):Gateway接收到微服務(wù)實例的響應(yīng)。

  10. Gateway處理響應(yīng):Gateway可以對微服務(wù)實例的響應(yīng)進行處理,如添加響應(yīng)頭、日志記錄等。

  11. 響應(yīng)返回客戶端:Gateway將處理后的響應(yīng)返回給客戶端。

通過服務(wù)注冊中心(如Nacos)來進行服務(wù)發(fā)現(xiàn),Gateway能夠動態(tài)地獲取微服務(wù)的實例信息,從而實現(xiàn)請求的動態(tài)轉(zhuǎn)發(fā)和負載均衡。這樣,Gateway就能找到相應(yīng)的服務(wù)并將請求轉(zhuǎn)發(fā)給它們。感謝您的指正,希望這次的回答更加準確。

總結(jié)
網(wǎng)關(guān)搭建步驟
  1. 創(chuàng)建項目,引入nacos服務(wù)發(fā)現(xiàn)和gateway依賴

  2. 配置application.yml,包括服務(wù)基本信息、nacos地址、路由

路由配置包括
  1. 路由id:路由的唯一標(biāo)示
  2. 路由目標(biāo) (uri):路由的目標(biāo)地址,http代表固定地址,lb代表根據(jù)服務(wù)名負載均衡
  3. 路由斷言 (predicates): 判斷路由的規(guī)則
  4. 路由過濾器 (filters):對請求或響應(yīng)做處理

3、路由斷言工廠Route Predicate Factory

  • 路由斷言工廠(Route Predicate Factory)是Spring Cloud Gateway中的一種配置方式,用于根據(jù)請求的條件來進行路由匹配。它可以根據(jù)請求的不同屬性(例如URL路徑、請求頭、請求方法等)來判斷請求是否匹配某個路由規(guī)則,如果匹配成功,則將請求轉(zhuǎn)發(fā)到相應(yīng)的目標(biāo)地址(服務(wù)實例)。
  • 例如:Path=/order/**是按照路徑匹配,這個規(guī)則是由org.springframework.cloud.gateway.handler.predicata.PathRoutePredicateFactory類來處理
  • 像這種短語工廠在SpringCloudGateway還有十幾個
3.1、spring提供了11種基本的Predicate工廠

?當(dāng)使用其他的Predicate工廠時,可到spring官網(wǎng)上看如何使用:spring route

?總結(jié)
  • PredicateFactory的作用是什么?

????????讀取用戶定義的斷言條件,對請求做出判斷

  • Path=/user/**是什么含義?

????????路徑是以/user開頭的就認為是符合的

4、路由過濾器(Route Filter)

路由過濾器(Route Filter)是Spring Cloud Gateway中的另一個重要組件,它用于在請求被路由到目標(biāo)服務(wù)之前或之后,對請求或響應(yīng)進行一系列的處理操作。通過路由過濾器,您可以對請求和響應(yīng)進行修改、增強或驗證,從而實現(xiàn)更加靈活和強大的網(wǎng)關(guān)功能。

?例如:

假設(shè)我們有一個微服務(wù)架構(gòu),包含多個服務(wù),其中一個是認證服務(wù)(Authentication Service),負責(zé)處理用戶的身份認證。其他服務(wù)(如用戶服務(wù)、訂單服務(wù)等)需要保護某些資源,只允許經(jīng)過認證的用戶訪問。

在這種情況下,我們可以使用Spring Cloud Gateway作為網(wǎng)關(guān),通過路由過濾器來實現(xiàn)請求認證和授權(quán):

  1. 全局過濾器(Global Filter):我們可以創(chuàng)建一個全局過濾器來攔截所有的請求,在這個過濾器中進行用戶身份認證的檢查。比如,我們可以檢查請求中是否包含有效的身份令牌(Token),以確定請求是否是經(jīng)過認證的用戶發(fā)起的。

  2. 局部過濾器(Route-Specific Filter):對于特定需要授權(quán)訪問的服務(wù),我們可以在路由配置中使用局部過濾器。在這個過濾器中,我們可以對請求進行權(quán)限驗證,檢查用戶是否有權(quán)限訪問該服務(wù)提供的資源。如果用戶沒有合法的權(quán)限,則可以拒絕請求或返回相應(yīng)的錯誤信息。

這樣,通過路由過濾器,我們可以實現(xiàn)全局的請求認證,并對需要授權(quán)訪問的服務(wù)進行權(quán)限控制。用戶在發(fā)起請求時,首先經(jīng)過全局過濾器進行認證,然后再經(jīng)過局部過濾器進行權(quán)限驗證。只有通過認證和授權(quán)的請求才能繼續(xù)訪問后端的微服務(wù)。

這種方式使得認證和授權(quán)邏輯從業(yè)務(wù)服務(wù)中剝離出來,統(tǒng)一交給網(wǎng)關(guān)進行處理,簡化了業(yè)務(wù)服務(wù)的實現(xiàn)和管理,同時提高了系統(tǒng)的安全性和可維護性。

4.1、過濾工廠 GratewayFilterFactory

在Spring Cloud Gateway中,過濾工廠(Filter Factory)是用于創(chuàng)建過濾器的工廠類,它用于生成過濾器實例并配置過濾器的行為。過濾工廠是一種更高級別的抽象,它將過濾器的創(chuàng)建和配置過程封裝在一起,使得配置網(wǎng)關(guān)過濾器更加簡單和靈活。

過濾工廠與過濾器的區(qū)別在于:

  • 過濾器:是過濾器實際的執(zhí)行邏輯,它需要開發(fā)者自己實現(xiàn)并繼承特定的Filter接口(如GlobalFilter或GatewayFilter),完成請求和響應(yīng)的處理。
  • 過濾工廠:是用于創(chuàng)建過濾器的工廠類,它將過濾器的創(chuàng)建和配置封裝起來,通過配置工廠的參數(shù),可以快速創(chuàng)建不同類型的過濾器,并指定過濾器的行為。

過濾工廠的優(yōu)勢在于,它提供了一些預(yù)定義的工廠,可以輕松地為常見的過濾器場景創(chuàng)建過濾器,而無需開發(fā)者自己編寫過濾器的實現(xiàn)。通過簡單的配置,開發(fā)者可以使用這些預(yù)定義的過濾工廠創(chuàng)建自定義的過濾器,從而實現(xiàn)特定的路由和請求處理邏輯。

spring提供了31種不同的路由過濾器工廠,一些常用的過濾工廠包括:

通過使用過濾工廠,您可以在網(wǎng)關(guān)中快速配置和管理過濾器,實現(xiàn)對請求和響應(yīng)的靈活處理。過濾工廠是Spring Cloud Gateway提供的一種高級配置方式,幫助開發(fā)者更加方便地定制和擴展網(wǎng)關(guān)的功能。

如果想使用其他的可以到過往進行學(xué)習(xí):spring GatewayFilterFactory

4.1.1、案例
?給所有進入userservice的請求添加一個請求頭

?默認過濾器

總結(jié)
  • ?過濾器的作用是什么?

????????????????對路由的請求或響應(yīng)做加工處理,比如添加請求頭

????????????????配置在路由下的過濾器只對當(dāng)前路由的請求生效

  • defaultFilters的作用是什么?

????????????????對所有路由都生效的過濾器

5、全局過濾器 GlobalFilter

全局過濾器(Global Filter):我們可以創(chuàng)建一個全局過濾器來攔截所有的請求,在這個過濾器中進行用戶身份認證的檢查。比如,我們可以檢查請求中是否包含有效的身份令牌(Token),以確定請求是否是經(jīng)過認證的用戶發(fā)起的。

全局過濾器的作用也是處理一切進入網(wǎng)關(guān)的請求和微服務(wù)響應(yīng),與GatewayFilter的作用一樣。區(qū)別在于GatewayFilter通過配置定義,處理邏輯是固定的。而GlobalFilter的邏輯需要自己寫代碼實現(xiàn)。定義方式是實現(xiàn)GlobalFilter接口。

5.1、實現(xiàn)步驟

自定義來,實現(xiàn)GlobalFilter接口,添加@Order注解

import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;/*** 自定義全局過濾器:用于校驗請求中的authorization參數(shù)是否合法*/
@Component
@Order(-1)
public class AuthorizeFilter implements GlobalFilter {/*** 過濾器方法,用于校驗請求中的authorization參數(shù)是否合法* @param exchange 服務(wù)器WebExchange對象,包含請求和響應(yīng)信息* @param chain GatewayFilterChain對象,用于傳遞請求給下一個過濾器或路由處理器* @return Mono<Void>,表示請求的處理結(jié)果*/@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 獲取請求參數(shù)MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();// 獲取authorization參數(shù)String authorization = params.getFirst("authorization");// 校驗authorization參數(shù)if ("ltc".equals(authorization)) {// 授權(quán)通過,請求繼續(xù)傳遞給下一個過濾器或路由處理器return chain.filter(exchange);} else {// 授權(quán)不通過,設(shè)置響應(yīng)狀態(tài)碼為403(禁止訪問),并結(jié)束處理,返回禁止訪問的響應(yīng)exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);return exchange.getResponse().setComplete();}}
}
總結(jié)

全局過濾器的作用是什么?

  • 對所有路由都生效的過濾器,并且可以自定義處理邏輯

實現(xiàn)全局過濾器的步驟?

  1. 實現(xiàn)GlobalFilter接口
  2. 添加@Order注解或?qū)崿F(xiàn)Ordered接口
  3. 編寫處理邏輯

6、過濾器執(zhí)行順序

請求進入網(wǎng)關(guān)會碰到三類過濾器: 當(dāng)前路由的過濾器、DefaultFilter、GlobalFilter

請求路由后,會將當(dāng)前路由過濾器和DefaultFilter、GlobalFilter,合并到一個過濾器鏈(集合)中,排序后依次執(zhí)行每個過濾器。

這是我們就會想,這三個過濾器相同嗎?怎么就可以放在同一個集合中進行排序了,別著急。

?對于當(dāng)前路由過濾器和DefaultFilter的配置方法是非常相似的,區(qū)別就是當(dāng)前路由過濾器放在路由內(nèi),而DefaultFilter是放在默認的過濾器內(nèi)的。從java的底層來看他兩個本質(zhì)是一樣的,只是作用范圍不一樣而已。

?在配置文件中配置的當(dāng)前路由過濾器和DefaultFilter(默認過濾器)都是由AddRequestHeaderGatewayFilterFactory過濾器工廠來讀取,然后生成了GatewayFilter過濾器,所以這兩個過濾器本質(zhì)都是同一類,他們兩個都叫GatewayFilter過濾器。

但是GlobalFilter全局過濾器為什么又可以和GatewayFilter來進行配置執(zhí)行呢?

在網(wǎng)關(guān)中有一個適配器GatewayFilterAdapter,他就可以將GlobalFilter適配成GatewayFilter來用。

?GatewayFilterAdapter適配器這個類就實現(xiàn)了GatewayFilter接口,他內(nèi)部還接收了GlobalFilter全局過濾器,如果我們給他傳入一個GlobalFilter全局過濾器,他就會將GlobalFilter適配成GatewayFilter來用。所以在網(wǎng)關(guān)中所有的過濾器都會被適配成Gateway來使用,所以這些過濾器就可以放到一個集合中來進行排序了。

這時就會出現(xiàn)一個新的問題了,那放到了一個集合后,有怎么進行排序呢?

6.1、過濾器執(zhí)如何排序
  • ?每個過濾器都必須指定一個int類型的order值,order值越小,優(yōu)先級越高,執(zhí)行順序越靠前。
  • GlobalFilter通過實現(xiàn)Order接口,或者添加@Order注解來指定order值,由我們自己指定。
  • 路由過濾器和defaultFilter的order由Spring指定,默認是按照聲明順序從1遞增。

?多余多個路由過濾器 和多個默認路由器:

  • 如果有多個路由過濾器,那他們是按照聲明的順序來遞增order的值的,來排序他們的執(zhí)行順序。
  • 多個默認路由也是如此的,也是按聲明的順序來遞增order的值,來排序他們的執(zhí)行順序。

但是當(dāng)默認過濾器、路由過濾器和GlobalFilter全局過濾器的order值相同呢,那又該怎么辦呢?

  • 當(dāng)過濾器的order值一樣時,會按照defaultFilter > 路由過濾器 > GlobalFilter全局過濾器的順序執(zhí)行。

底層源碼中有兩個類是用來加載這三種過濾器的:

當(dāng)服務(wù)啟動后RouteDefinitionRouteLocator類的getFilter()方法會首先執(zhí)行,會先去配置文件中加載defaultFilters,然后才會去加載某個路由的route的filter,然后合并。?

當(dāng)getFilter()方法執(zhí)行完后,FilteringWebHandler類的handle()方法才會進行加載全局過濾器,加載后會與之前加載的過濾器合并后更具order排序,組織過過濾器鏈

總結(jié)

路由過濾器、defaultFilter、全局過濾器的執(zhí)行順序?

  1. order值越小,優(yōu)先級越高
  2. 當(dāng)order值一樣時,順序是defaultFilter最先,然后是局部的路由過濾器,最后是全局過濾器

7、跨域問題處理

7.1、跨越問題

跨域問題(Cross-Origin Issue)是由瀏覽器的同源策略引起的。同源策略是一種安全機制,限制了網(wǎng)頁文檔或腳本從一個源(協(xié)議、域名、端口號的組合)加載或操作另一個源的內(nèi)容。如果兩個網(wǎng)頁的協(xié)議、域名和端口號都相同,它們就是同源的,否則就被認為是跨域的。

跨域:域名不一致就是跨域,主要包括:

  • 域名不同:www.taobao.com和 www.taobao.org 和 wwwjd.com 和 miaoshajd.com
  • 域名相同,端口不同: localhost:8080和localhost8081

跨越問題:瀏覽器禁止請求的發(fā)起者和服務(wù)端發(fā)生跨域Ajax請求,請求被瀏覽器攔截的問題。

跨域問題的出現(xiàn)是為了防止惡意網(wǎng)站利用客戶端的漏洞進行攻擊,保護用戶的隱私和安全。瀏覽器會強制執(zhí)行同源策略,禁止網(wǎng)頁在不同源之間進行以下操作:

  1. 通過 XMLHttpRequest 或 Fetch API 發(fā)送跨域請求。
  2. 訪問其他源的 Cookie、LocalStorage 和 IndexedDB。
  3. 獲取其他源的 DOM 元素。
  4. 在其他源的窗口中執(zhí)行腳本。

舉個例子來說明跨域問題:假設(shè)網(wǎng)站A的域名是 https://www.example.com,網(wǎng)站B的域名是 https://api.example.com。如果網(wǎng)站A的網(wǎng)頁中使用 XMLHttpRequest 或 Fetch API 向網(wǎng)站B發(fā)送請求,那么由于它們不是同源的,瀏覽器會阻止這個請求,返回一個錯誤。這就是跨域問題。

7.2、跨越問題解決辦法 CORS

只需要在application.yml文件中添加下面的配置即可。

spring:cloud:gateway:globalcors:corsConfigurations:'[/**]': # 配置所有路徑的全局CORS設(shè)置allowedOrigins: "https://example.com" # 允許的跨域請求源,這里設(shè)置為https://example.comallowedMethods: "GET, POST, PUT, DELETE" # 允許的請求方法,這里設(shè)置為GET、POST、PUT、DELETEallowedHeaders: "*" # 允許的請求頭,這里設(shè)置為"*"表示允許任意請求頭allowCredentials: true # 是否允許發(fā)送憑證信息(如Cookie),這里設(shè)置為true表示允許發(fā)送憑證信息maxAge: 3600 # 預(yù)檢請求的緩存時間(單位:秒),這里設(shè)置為3600秒add-to-simple-url-handler-mapping: true  #處理option請求被攔截問題

?配置詳細介紹:

  1. corsConfigurations: 這個屬性用于配置全局的CORS設(shè)置。[/**] 表示匹配所有路徑,也就是對所有請求生效的全局CORS配置。

  2. allowedOrigins: 允許的跨域請求源。這里設(shè)置為 https://example.com,表示只允許來自 https://example.com 域名的請求進行跨域訪問。你可以根據(jù)實際需求設(shè)置允許的域名,也可以使用通配符 * 表示允許所有域名的請求。

  3. allowedMethods: 允許的請求方法。這里設(shè)置為 GET, POST, PUT, DELETE,表示只允許這些HTTP方法的請求進行跨域訪問。你可以根據(jù)需要添加或刪除允許的方法。

  4. allowedHeaders: 允許的請求頭。這里設(shè)置為 *,表示允許任意請求頭。你也可以設(shè)置具體的請求頭名稱,比如 "Content-Type, Authorization",只允許這些請求頭進行跨域訪問。

  5. allowCredentials: 是否允許發(fā)送憑證信息(如Cookie)。這里設(shè)置為 true,表示允許發(fā)送憑證信息。如果設(shè)置為 false,則不允許發(fā)送憑證信息。

  6. maxAge: 預(yù)檢請求的緩存時間(單位:秒)。預(yù)檢請求是指瀏覽器在發(fā)送跨域請求前先發(fā)送一個 OPTIONS 請求來檢查服務(wù)器是否允許跨域訪問。這里設(shè)置為 3600 秒,表示預(yù)檢請求的結(jié)果在 3600 秒內(nèi)可以被緩存,減少預(yù)檢請求的次數(shù)。

  7. add-to-simple-url-handler-mapping: 這個屬性設(shè)置為 true,將CORS配置添加到簡單URL處理程序映射中。這是一個內(nèi)部屬性,通常不需要手動設(shè)置。

通過以上配置,Spring Cloud Gateway 將會在響應(yīng)中添加相應(yīng)的CORS響應(yīng)頭,允許來自 https://example.com 域名的跨域請求,允許的方法有 GET、POST、PUT、DELETE,允許任意請求頭,允許發(fā)送憑證信息(如 Cookie),并且預(yù)檢請求的緩存時間為 3600 秒。

總結(jié)

·CORS跨域要配置的參數(shù)包括哪幾個?

  • 允許哪些域名跨域?
  • 允許哪些請求頭?
  • 允許哪些請求方式?
  • 是否允許使用cookie?
  • 有效期是多久?

?此篇是在學(xué)習(xí)黑馬課springcloud程是做的詳細的筆記,內(nèi)容是自己總結(jié)過后,易懂,但是就是篇幅有點多,需要大家多花時間去看。


---------------------
作者:m0_62498006
來源:CSDN
原文:https://blog.csdn.net/m0_62498006/article/details/131927338
版權(quán)聲明:本文為作者原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!
內(nèi)容解析By:CSDN,CNBLOG博客文章一鍵轉(zhuǎn)載插件

http://www.risenshineclean.com/news/51447.html

相關(guān)文章:

  • 學(xué)做網(wǎng)站論壇vip賬號破解360手機助手
  • 企業(yè)型網(wǎng)站建設(shè)咨詢電話百度搜索引擎網(wǎng)站
  • 獨立網(wǎng)站開發(fā)者兼職網(wǎng)站seo外包公司報價
  • 德州做網(wǎng)站的公司有哪些千萬別在百度上搜別人名字
  • 南昌優(yōu)化網(wǎng)站服務(wù)哪里有免費的網(wǎng)站推廣
  • 織夢做的網(wǎng)站怎么加彈窗哪里有軟件培訓(xùn)班
  • 免費域名網(wǎng)站推薦關(guān)鍵詞優(yōu)化師
  • 怎么做新聞網(wǎng)站網(wǎng)站友情鏈接購買
  • wordpress收費破解模板搜索優(yōu)化seo
  • 武漢疫情最新消息今天佛山百度快照優(yōu)化排名
  • 莆田建站培訓(xùn)seo實戰(zhàn)密碼第四版pdf
  • 新聞網(wǎng)站策劃方案seo綜合查詢網(wǎng)站源碼
  • 網(wǎng)站建設(shè)對標(biāo)行業(yè)分析站內(nèi)優(yōu)化
  • 網(wǎng)站主辦者刷推廣鏈接人數(shù)的軟件
  • 網(wǎng)站追蹤如何做免費找客戶軟件
  • .net 建網(wǎng)站線上教育培訓(xùn)機構(gòu)十大排名
  • 開發(fā)網(wǎng)站設(shè)計百度競價推廣開戶價格
  • 網(wǎng)站建設(shè)方案 安全優(yōu)化營商環(huán)境心得體會2023
  • 做網(wǎng)站怎么讓百度收錄了高質(zhì)量外鏈代發(fā)
  • web程序設(shè)計與實踐做網(wǎng)站搜索引擎關(guān)鍵詞優(yōu)化技巧
  • 上海網(wǎng)站建設(shè)工作室微博推廣平臺
  • 四川住建廳官方網(wǎng)站的網(wǎng)址樂云seo
  • 武漢做網(wǎng)站的知名公司個人網(wǎng)頁怎么制作
  • 網(wǎng)站建設(shè)淺析昆明seo
  • 網(wǎng)站做百度推廣搜狐綜合小時報2022113011
  • 虛擬網(wǎng)站什么是搜索引擎營銷?
  • 網(wǎng)站建設(shè)哪家好 上海廣州疫情升級
  • 古典風(fēng)格網(wǎng)站模板htmlseo的搜索排名影響因素主要有
  • 天河做網(wǎng)站系統(tǒng)放單平臺
  • 南寧網(wǎng)站建設(shè)制作優(yōu)化大師哪個好