您好,登錄后才能下訂單哦!
這篇文章主要介紹了SpringCloud分布式微服務架構如何操作的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇SpringCloud分布式微服務架構如何操作文章都會有所收獲,下面我們一起來看看吧。
在這之前我們所有的開發都是按照單體架構開發的。什么是單體架構,其實就是所有的功能都放在一個項目中。然后部署的時候嗎,就去打包為整體的一個包進行部署。
像之前黑馬的單體架構基于Springboot和mybatisplus實現的瑞吉外賣這樣子就是單體架構。
這里面包含一些實體類,基本的配置類,以及一些公共·的數據處理的封裝的進行處理的類,還有擴展的實體類,其中主要的比較典型的就是三層架構,==數據訪問層,業務邏輯層,表現層,這是mvc三層架構的基本設計理念。非常重要。在我們剛接觸到這樣的設計模式的時候,已經覺得這樣的設計模式已經非常秒了。從小白過渡到設計模式的時候。
加上Springboot這個強大的框架,我們可以簡化非常多的操作,而且可以某些操作上做的比較優雅。
我們認為在使用spring后可以極大的降低項目開發中代碼的·1耦合度,但是其實這樣項目的功能龐大后之間的耦合度還是很高。
當然這樣開發部署的話成本肯定是成本低的。
但是單體架構帶來的缺點是什么。說幾點。
首先一定是在項目整體開發所用的編程語言,一定是只能用一種,整個項目的所有功能的開發只能用一種語言編寫。
還有耦合度帶來的問題啊,耦合度高的話,系統中只要一個模塊出現問題,系統就很容易癱瘓。
還有項目的部署上線,需要功能開發完畢后才可以上線。造成的問題就是可能需要等待,無法及時滿足需求。
等等。這些在了解到分布式微服務后就可以了解到如何解決這些問題的。
分布式架構的微服務有很多。
也就是說微服務并不是springcloud這一種。微服務的理念就是實現拆分功能的開發。將具體的功能分離出來。這樣帶來的好處就是你開發你的功能,我開發我的功能,互不影響。降低了偶爾度。而且在后面我們學到集群這些等等后,就會理解到在優化升級的時候所帶來的的好處。比較常用的詞就是單一職責。
需要了解一下
這些我們在后面的學習中就會得到理解。
現在我們提出一個簡單的需求。我們在一張訂單表中通過訂單的id 查詢到訂單的數據還有對應用戶的數據。
這樣的需求的話,我們需要在訂單的表的每個id對應一個用戶id,這樣我們才能做到表數據關聯。
tb_user 建表sql如下
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for tb_user -- ---------------------------- DROP TABLE IF EXISTS `tb_user`; CREATE TABLE `tb_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '收件人', `address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地址', PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `username`(`username`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of tb_user -- ---------------------------- INSERT INTO `tb_user` VALUES (1, '柳巖', '湖南省衡陽市'); INSERT INTO `tb_user` VALUES (2, '文二狗', '陜西省西安市'); INSERT INTO `tb_user` VALUES (3, '華沉魚', '湖北省十堰市'); INSERT INTO `tb_user` VALUES (4, '張必沉', '天津市'); INSERT INTO `tb_user` VALUES (5, '鄭爽爽', '遼寧省沈陽市大東區'); INSERT INTO `tb_user` VALUES (6, '范兵兵', '山東省青島市'); SET FOREIGN_KEY_CHECKS = 1;
tb_brand 建表sql 如下
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for tb_order -- ---------------------------- DROP TABLE IF EXISTS `tb_order`; CREATE TABLE `tb_order` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '訂單id', `user_id` bigint(20) NOT NULL COMMENT '用戶id', `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '商品名稱', `price` bigint(20) NOT NULL COMMENT '商品價格', `num` int(10) NULL DEFAULT 0 COMMENT '商品數量', PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `username`(`name`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of tb_order -- ---------------------------- INSERT INTO `tb_order` VALUES (101, 1, 'Apple 蘋果 iPhone 12 ', 699900, 1); INSERT INTO `tb_order` VALUES (102, 2, '雅迪 yadea 新國標電動車', 209900, 1); INSERT INTO `tb_order` VALUES (103, 3, '駱駝(CAMEL)休閑運動鞋女', 43900, 1); INSERT INTO `tb_order` VALUES (104, 4, '小米10 雙模5G 驍龍865', 359900, 1); INSERT INTO `tb_order` VALUES (105, 5, 'OPPO Reno3 Pro 雙模5G 視頻雙防抖', 299900, 1); INSERT INTO `tb_order` VALUES (106, 6, '美的(Midea) 新能效 冷靜星II ', 544900, 1); INSERT INTO `tb_order` VALUES (107, 2, '西昊/SIHOO 人體工學電腦椅子', 79900, 1); INSERT INTO `tb_order` VALUES (108, 3, '梵班(FAMDBANN)休閑男鞋', 31900, 1); SET FOREIGN_KEY_CHECKS = 1;
從訂單表中獲取到訂單id然后返回訂單數據對象,然后獲取到user_id,然后將user_id傳入對user表的請求路徑中,這樣我們就可以獲取到user的封裝數據。這里我們需要再加一個對象屬性。
這樣我們可以就可以對user數據進行封裝,在查詢結構中就會有這個對象數據。
這是我們準備的兩張表,當然這只是一個簡單的例子,我們后面要用這個例子做測試。
我們需要創建項目,項目下分模塊來進行設計。因為這是一個人做,我們在一個項目下,分模塊來進行分布式的這種操作模擬。
一個父模塊,兩個子模塊
先看父模塊的pom,不過在這之前我們特別注意看一下這里。
我們idea這里的maven配置。不過我每次都得改。
一定要改到自己的maven配置里面
從這里看項目初步是OK的。
這是父maven的pom
現在我們添加必要依賴,首先將這個項目變成一個springboot項目
這就是Spring Boot的父級依賴,加入之后項目就變成了Spring Boot項目。spring-boot-starter-parent是一個特殊的starter,它用來提供相關的maven默認依賴。之后再引入。其他的依賴時,可以不用指定version標簽。
我們可以給項目maven指定jdk版本和編碼,一定要注意加的位置。
還有我們做的是一個springCloud微服務啊,我們需要準備這個環境
這里特別注意springboot和springcloud的版本兼容性,否則無法運行。
需要對應到版本。所以springCloud導入這個依賴。
我們可以放到這個標簽下
復習一下它有什么用處
Maven 可以通過 dependencyManagement 元素對依賴進行管理,它具有以下 2 大特性:
在該元素下聲明的依賴不會實際引入到模塊中,只有在 dependencies 元素下同樣聲明了該依賴,才會引入到模塊中。
該元素能夠約束 dependencies 下依賴的使用,即 dependencies 聲明的依賴若未指定版本,則使用 dependencyManagement 中指定的版本,否則將覆蓋 dependencyManagement 中的版本。
我們看到,這里多了一個import,它的意思是將spring-boot-dependencies 中dependencyManagement的dependencies,全部引入到當前工程的dependencyManagement中
另外還有mysql的連接驅動,mybatis整合springboot框架分別導入進來。
還有一個我們用到的工具
lombok插件是為了方便實體類bean快速生成get set方法,從而不用手動添加
為什么我們要這樣分開寫,復習一下
dependencies即使在子項目中不寫該依賴項,那么子項目仍然會從父項目中繼承該依賴項(全部繼承)而我們的DepencyManagement是子工程依賴模塊可選擇的。
至此父級maven工程依賴如下
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>cloud01</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>order-service</module> <module>user-service</module> </modules> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.9.RELEASE</version> <relativePath/> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR10</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.29</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
來看子級別pom
現在我們導入必要依賴
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud01</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>order-server</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> </dependencies> </project>
還有一個打包插件我們暫且可以不用
兩個子工程都需要這樣導入
現在我們創建三成架構的目錄和類
添加配置信息
同樣userservice
配置yml
這樣做好以后我們去做啟動類
我們還沒有寫啟動類,
user-service
我門需要是用RestTemplate實現服務調用。按照查詢的需求,我門需要在order-service這里進行一個查詢,我門需要根據請求提交id參數查詢出來order的數據,然后根據order數據表里面id對應的用戶id查詢出來用戶的數據,然后進行一個統一的封裝。這說明order-sertvice需要調用user-service。
我們來看order-sertvice的啟動類
我們除了寫出一個啟動類的規則后,還new出了RestTemplate的bean。這個bean在哪里使用呢?
getForObject對應的就是get請求,User.class表示將返回的數據封裝到User對象里面。
order-service的端口地址指定過。在yml文件里面。
注意現在還沒有用到Springcloud的東西,我們目前是模擬實現遠程調用。只不過現在和之前相比是將功能模塊分開,而且啟動的不在是單獨的一個服務。
我們需要將兩個服務都啟動起來。
在postman中發送請求
數據測試是沒有問題的。但是似乎上面的地址請求顯得十分笨拙。還有這里其實并沒有實現真的遠程調用。只是模塊之前的不同服務的之間的調用。還有就是服務的健康信息1我們在調用的時候不得而知,如果對應調用的服務有問題我們在調用前也是無法得知的。如何對服務進行一個更好的管理,我們繼續往下看。
說明一下這個是干嘛用的
Eureka 是 Netflix 出品的用于實現服務注冊和發現的工具,Spring Cloud 封裝了 Netflix 公司開發的 Eureka 模塊來實現服務注冊和發現
Eureka采用C-S的設計架構,包含Eureka Server 和Eureka Client兩個組件
它的原理就是基于服務提供者和服務消費者。像我們的orderservice需要去訪問userservice,那么userservice就是服務提供者,orderservice就是。服務消費者。
服務啟動后向Eureka注冊,Eureka Server會將注冊信息向其他Eureka Server進行同步,當服務消費者要調用服務提供者,則向服務注冊中心獲取服務提供者地址,然后會將服務提供者地址緩存在本地,下次再調用時,則直接從本地緩存中取,完成一次調用。
在默認配置中EurekaServer服務在一定時間(默認為90秒)沒接受到某個服務的心跳連接后,EurekaServer會注銷該服務。但是會存在當網絡分區發生故障,導致該時間內沒有心跳連接,但該服務本身還是健康運行的情況。Eureka通過“自我保護模式”來解決這個問題。
在自我保護模式中,Eureka Server會保護服務注冊表中的信息,不再注銷任何服務實例。
我們可以對服務創建多個節點,如果有的節點掛掉以后,就可以去啟用另外可用的服務。
當然這個是基于springcloud的。所以我們需要導入相關的依賴。
在這之前啊,我們需要將eureka服務端創建出來
我們再創建一個模塊
打開這個pom文件添加必要依賴
然后創建啟動類
一定要注意啟動類要放在java目錄的包下面,所以最好創建包后,將這個啟動類放到下面,不要直接放在java目錄下。
這里我們做的就是服務端。
即熱是服務,那么我們還是要配置一下,比如端口等等,所以需要在resource下面創建一個yml文件。
一定要注意yml文件中字段的層級關系,這是非常嚴格的。
配置完這個后,我們需要配置客戶端。
首先還是需要引入依賴。
useservice 和orderservice都需要導入。
另外需要配置服務端的地址
同樣是都需要配置。
初步的話其實還有一定就是這里
我們需要指定一下服務名稱。先這樣配置一下,然后去啟動
三者都啟動
現在需要去訪問一個地址
注意端口10086后不需要加eureka
我們現在需要去查看服務是否注冊成功,或者說eureka服務端是否將userservice 和orderservice加入實例。
這樣就成功了。
然后我們就可以開啟去使用它了。
這里我們可以修改一下這里
但是在這之前,我們需要做一個負載均衡的指定,否則是無法解析服務地址。
然后這樣
這樣我們再次啟動,就可以去訪問了。
上面我們用到了負載策略
負載均衡是高可用網絡基礎架構的關鍵組件,通常用于將工作負載分布到多個服務器來提高網站、應用、數據庫或其他服務的性能和可靠性。
注:圖片數據來自知乎
什么是負載均衡
從這里可以去看負載均衡策略
沒有負載均衡的服務架構
有負載均衡的服務架構
我們這樣的特點可以去用多實例部署的特點。
定要記得修改端口
將這個服務啟動起來
然后我們去eureka注冊中心看看有沒有實例
可以看到userservice一共有兩個實例對象了。
這樣創建多實例的好處就是如果一個實例存在問題的話就可以換另一個。我們這里就模擬了多實例部署。
還有我們需要去觀察一下這個負載均衡策略,其實默認是輪詢的負載均衡策略。
我們可以去測試,多訪問幾次userservice,而現在userservice有兩個實例,我們在postman測試工具做出測試,發出請求,看看具體調用的哪個實例。
注意現在需要改一個東西,就是上面有一個錯誤的地方。有關日志的。
logging.level設置日志級別,后面跟生效的區域,比如root表示整個項目,也可以設置為某個包下,也可以具體到某個類名(日志級別的值不區分大小寫)這里需要注意,上面的包名沒有寫對。
然后開始測試,首先將控制臺的輸出全部清除掉。
我這里從1到6一共訪問6次。
然后來看控制臺的日志輸出,可見這是輪詢的方式
默認的是輪詢,我們可以自己去指定一個規則
所以就從這里來重新指定規則
我們在orderservice的啟動類里面寫,當然這個是代碼的方式。并且,我們需要將它做成一個bean。
我們這樣定義是選擇了隨機的原則,代表隨機選擇一個服務器。
然后我們去重新啟動測試
測試成功
如果采用配置文件的方式
兩者配置不同之處在于作用范圍。代碼配置的話就是會在全部服務中起作用,而配置文件配置的話就只會在指定的服務起作用。
還有一個就是關于啟動問題的知識點,默認是懶加載。
我們這樣去配置
Nacos是阿里巴巴的一個產品,說實話,這個注冊中心是真的好用。下面我們開始介紹。
首先我們需要安裝這個服務,服務區官網下載就可以了。
官網 可以選擇點進去github下載服務。
目錄結構
然后進去bin目錄里面,進行執行開啟服務
如何開啟服務,打開手冊。
在快速開始這里,我們可以進行執行命令。
將這個命令執行后就可以開啟這個服務了
然后我們去idea里面配置相關的東西
然后在里面配置相關的依賴,配置依賴的話就需要注釋掉eureka的依賴。
如果沒有在父工程添加阿里巴巴的依賴的話,我們需要進行添加依賴。
將這個依賴導入到父工程里面。
然后在子工程中將原來的eureka的依賴注釋掉
在pom文件當中配置的就是客戶端依賴。因為服務端是已經下載安裝的。
我們需要將服務端的service和客戶端的sevice都配置依賴。
然后我們進行配置yml文件進行配置
然后將eureka的配置注釋掉
然后我們將這幾個服務啟動。我們現在就不需要去啟動eureka了。
我們訪問nacos的服務列表
管理頁面訪問地址
進入到服務列表,我們可以看到服務列表查看注冊情況
至此注冊成功。而且我們可以看到這里userservice一共有兩個實例。
這里我們可以看到具體的一些信息,包括端口號,已經健康狀態,后面可以進行一些操作,包括服務上線下線的操作。
我們可以進去到服務列表具體實例的詳情,可以查看到一些具體的信息。
這里引入了一個新的概念。集群的概念。
這里先不用去關注集群的具體的概念,但是在結合分布式服務的話,集群可以幫助我們解決服務的跨區域的問題。跨區域部署服務器。
按照上圖所示集群部署的話,可以部署在不同的地域。杭州,上海等等。然后我們通過nacos進行集群管理。包括相關的實例部署等等。
我們可以去模擬配置集群
這里我們指定了一個集群,表示部署在此地。我們可以對這些服務都指定相關的服務集群
好,現在再次啟動重新服務
我們可以看到一共有兩個集群,這樣我們就指派成功了。
在nacos 也可以進行加權負載均衡
我們一共有兩個usersrvice的服務,我們可以去指定其中的一個權值,權值越低被訪問調用的幾率越1低,權值為0的話就不會被訪問了。我們可以測試。
我們可以用postman進行訪問測試。
用postman進行測試
可以看到多次訪問都沒有訪問到權值為0的服務實例,這樣其實就實現了一個權值的負載均衡策略。
當然你可以指定其他的值。
其實還有可以進行環境隔離的操作。
現在nacos操作平臺進行生成新的命名空間。
我們的之前的命名空間就是public類型,是一個保留空間。
我們可以自己去這里創建空間,然后自己在代碼配置中指定給那個服務配置相應的空間。
填寫保留空間的名字和描述就可以,Id可以自動生成。
我們給具體的服務配置命名空間,就配置namespace,然后將id復制過去作為鍵的值。
命名空間的作用就是相當于起到環境隔離的作用。
如果服務在不同的命名空間,那么這兩個服務就無法互相訪問。
現在我們重新啟動userservice的一個實例,我們可以將,然后這個實例是必然不會和orderservive在同一個命名空間。是不會訪問到的。
我們測試orderservice能不能訪問到userservice的服務端1。
可以看到是不能訪問到的。
臨時實例和非臨時實例(存在依賴的修改更正)
臨時實例的服務在宕機后會從nacos的列表中被刪除掉,而非臨時實例不會被刪掉。
到這里發現我之前導入的依賴是不能這樣設置的。
前面的設置都可以支持
想要支持實例的配置管理的話需要導入這個依賴
在自己需要的服務里面導入進來。我現在只在useservice這里進行驗證臨時實例和非臨時實例的特點。
我現在的服務都重啟
注意看這里,全部為false,然后現在為了對比做這樣的操作。
我將其中一個停掉。然后改為true
然后再啟動
你看這里發生了什么。為什么會有兩個8082的端口的實例服務呢?原因是我們之前給它設置為非臨時實例,就算我們剛剛重啟了服務,但是它不會被刪除,現在我們關閉服務,看看設置為true的這個實例會不會被刪掉。
看吧已經刪掉,還有一點這里的健康狀態和這個顏色我們之前的這個都變了。
對于臨時實例和非臨時實例的區別,nacos也做出了不同的檢測
臨時 實例:nacos會在超過15秒未收到心跳后將實例設置為不健康狀態;
超過30秒將實例刪除;
非臨時實例:nacos主動探知客戶端健康狀態,默認間隔為20秒;
健康檢查失敗后實例會被標記為不健康,不會被立即刪除。
我們先了解nacos是如何加載配置的
我們想要做的的是在nacos的管理界面進行配置,然后這個配置首先可以被加載,然后這樣的加載配置在我們發布以后會自動生效,而不需要我們重啟服務器,這樣的配置更新方法也叫做熱更新。
具體怎么做呢?我們先去nacos的配置管理界面。在這里我發布了一個新的配置。
我們來看具體的詳情
這樣配置后然后發布就可以了,當然這只是在nacos的配置列表進行的配置。我們還需要在idea里面操作一些東西。
我們還需要引入一個依賴。nacos的配置管理依賴
這個配置依賴需要在你想要進行統一配置和熱部署操作的服務的pom中添加。
然后我們需要創建一個配置文件
這個配置文件的優先級別高,nacos會先加載這個配置文件,然后會加載application.yml文件,將著兩個配置文件的配置合并一起。
要記得在原來的配置文件中注釋掉一些可能重復的配置或者非必要的配置。
服務名,還有地址,集群的話不需要,命名空間的話,因為我的nacos添加的配置在public下面,所以我把之前指定的也注釋掉了。
在nacos管理配置列表配置的一些東西和這里是對應的,所以一定要細心注意。
這樣的話我們如何知道配置生效,或者如何去驗證熱部署成功?
我們可以通過value讀取,將這個數據讀到Controller里面,給這個值配置一個訪問路徑。我們可以這樣去做。
這里有個坑,就是如果你的nacos無法解析的話,就需要升級一下。升級到1.4.2.。
還有一點就是需要配置自動熱更新。
我現在的服務已經啟動,我們去訪問。
你看這樣搜先加載到了。
現在我們在nacos配置管理那里稍微改動一下。
發布的時候會告訴你原始值和你修改的。
現在我們再去訪問
這樣就驗證成功了。熱部署成功·。
還有一種屬性注入方式
我們需要去寫一個配置類
然后在Controller里面這樣做
還有這種方法不需要去添加這個注解
需要注意的是,可能存在bean無法注入的問題。那么我們可以去給他掃描。
關于“SpringCloud分布式微服務架構如何操作”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“SpringCloud分布式微服務架構如何操作”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。