SpringCloud?分布式微服務(wù)架構(gòu)操作步驟
前言
這篇筆記文章我還是沒有接上之前的java,因?yàn)槲抑虚g偷懶了,寫不動(dòng)了。打算先把這篇安排下,然后再把之前的spring和springboot缺失的筆記補(bǔ)一下。至于啥時(shí)候補(bǔ)全,我也沒有定論。
寫博客的真正目的就是做個(gè)筆記,以后自己忘記的知識(shí)點(diǎn)自己回顧一下。至于其他網(wǎng)站的盜文,我都無所謂了。畢竟網(wǎng)絡(luò)文章博文這些其實(shí)還是沒有什么保護(hù)的,又不是軟件著作權(quán)。
一直在看學(xué)習(xí)視頻,一直在b站學(xué)習(xí)。雖然自己菜啊,但是還是要努力??!不然在這個(gè)社會(huì)我怕餓死。
那就從SpringCloud開始,還沒有補(bǔ)充前面的spring和springboot,但是之后一定會(huì)補(bǔ)全的。
SpringCloud是一種微服務(wù)的框架,利用它我們可以去做分布式服務(wù)開發(fā)。
至于具體的,我們現(xiàn)在開始介紹。
SpringCloud微服務(wù)
單體架構(gòu)和微服務(wù)分布式架構(gòu)
單體架構(gòu)分析
在這之前我們所有的開發(fā)都是按照單體架構(gòu)開發(fā)的。什么是單體架構(gòu),其實(shí)就是所有的功能都放在一個(gè)項(xiàng)目中。然后部署的時(shí)候嗎,就去打包為整體的一個(gè)包進(jìn)行部署。
像之前黑馬的單體架構(gòu)基于Springboot和mybatisplus實(shí)現(xiàn)的瑞吉外賣這樣子就是單體架構(gòu)。
這里面包含一些實(shí)體類,基本的配置類,以及一些公共·的數(shù)據(jù)處理的封裝的進(jìn)行處理的類,還有擴(kuò)展的實(shí)體類,其中主要的比較典型的就是三層架構(gòu),==數(shù)據(jù)訪問層,業(yè)務(wù)邏輯層,表現(xiàn)層,這是mvc三層架構(gòu)的基本設(shè)計(jì)理念。非常重要。在我們剛接觸到這樣的設(shè)計(jì)模式的時(shí)候,已經(jīng)覺得這樣的設(shè)計(jì)模式已經(jīng)非常秒了。從小白過渡到設(shè)計(jì)模式的時(shí)候。
加上Springboot這個(gè)強(qiáng)大的框架,我們可以簡化非常多的操作,而且可以某些操作上做的比較優(yōu)雅。
我們認(rèn)為在使用spring后可以極大的降低項(xiàng)目開發(fā)中代碼的·1耦合度,但是其實(shí)這樣項(xiàng)目的功能龐大后之間的耦合度還是很高。
當(dāng)然這樣開發(fā)部署的話成本肯定是成本低的。
但是單體架構(gòu)帶來的缺點(diǎn)是什么。說幾點(diǎn)。
首先一定是在項(xiàng)目整體開發(fā)所用的編程語言,一定是只能用一種,整個(gè)項(xiàng)目的所有功能的開發(fā)只能用一種語言編寫。
還有耦合度帶來的問題啊,耦合度高的話,系統(tǒng)中只要一個(gè)模塊出現(xiàn)問題,系統(tǒng)就很容易癱瘓。
還有項(xiàng)目的部署上線,需要功能開發(fā)完畢后才可以上線。造成的問題就是可能需要等待,無法及時(shí)滿足需求。
等等。這些在了解到分布式微服務(wù)后就可以了解到如何解決這些問題的。
微服務(wù)分布式架構(gòu)分析
分布式架構(gòu)的微服務(wù)有很多。
也就是說微服務(wù)并不是springcloud這一種。微服務(wù)的理念就是實(shí)現(xiàn)拆分功能的開發(fā)。將具體的功能分離出來。這樣帶來的好處就是你開發(fā)你的功能,我開發(fā)我的功能,互不影響。降低了偶爾度。而且在后面我們學(xué)到集群這些等等后,就會(huì)理解到在優(yōu)化升級(jí)的時(shí)候所帶來的的好處。比較常用的詞就是單一職責(zé)。
需要了解一下
這些我們?cè)诤竺娴膶W(xué)習(xí)中就會(huì)得到理解。
服務(wù)拆分和遠(yuǎn)程調(diào)用
服務(wù)拆分 案例需求準(zhǔn)備
現(xiàn)在我們提出一個(gè)簡單的需求。我們?cè)谝粡堄唵伪碇型ㄟ^訂單的id 查詢到訂單的數(shù)據(jù)還有對(duì)應(yīng)用戶的數(shù)據(jù)。
這樣的需求的話,我們需要在訂單的表的每個(gè)id對(duì)應(yīng)一個(gè)用戶id,這樣我們才能做到表數(shù)據(jù)關(guān)聯(lián)。
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, '鄭爽爽', '遼寧省沈陽市大東區(qū)'); 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 '商品價(jià)格', `num` int(10) NULL DEFAULT 0 COMMENT '商品數(shù)量', 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 新國標(biāo)電動(dòng)車', 209900, 1); INSERT INTO `tb_order` VALUES (103, 3, '駱駝(CAMEL)休閑運(yùn)動(dòng)鞋女', 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 人體工學(xué)電腦椅子', 79900, 1); INSERT INTO `tb_order` VALUES (108, 3, '梵班(FAMDBANN)休閑男鞋', 31900, 1); SET FOREIGN_KEY_CHECKS = 1;
從訂單表中獲取到訂單id然后返回訂單數(shù)據(jù)對(duì)象,然后獲取到user_id,然后將user_id傳入對(duì)user表的請(qǐng)求路徑中,這樣我們就可以獲取到user的封裝數(shù)據(jù)。這里我們需要再加一個(gè)對(duì)象屬性。
這樣我們可以就可以對(duì)user數(shù)據(jù)進(jìn)行封裝,在查詢結(jié)構(gòu)中就會(huì)有這個(gè)對(duì)象數(shù)據(jù)。
這是我們準(zhǔn)備的兩張表,當(dāng)然這只是一個(gè)簡單的例子,我們后面要用這個(gè)例子做測(cè)試。
我們需要?jiǎng)?chuàng)建項(xiàng)目,項(xiàng)目下分模塊來進(jìn)行設(shè)計(jì)。因?yàn)檫@是一個(gè)人做,我們?cè)谝粋€(gè)項(xiàng)目下,分模塊來進(jìn)行分布式的這種操作模擬。
一個(gè)父模塊,兩個(gè)子模塊
先看父模塊的pom,不過在這之前我們特別注意看一下這里。
我們idea這里的maven配置。不過我每次都得改。
一定要改到自己的maven配置里面
從這里看項(xiàng)目初步是OK的。
這是父maven的pom
現(xiàn)在我們添加必要依賴,首先將這個(gè)項(xiàng)目變成一個(gè)springboot項(xiàng)目
這就是Spring Boot的父級(jí)依賴,加入之后項(xiàng)目就變成了Spring Boot項(xiàng)目。spring-boot-starter-parent是一個(gè)特殊的starter,它用來提供相關(guān)的maven默認(rèn)依賴。之后再引入。其他的依賴時(shí),可以不用指定version標(biāo)簽。
我們可以給項(xiàng)目maven指定jdk版本和編碼,一定要注意加的位置。
還有我們做的是一個(gè)springCloud微服務(wù)啊,我們需要準(zhǔn)備這個(gè)環(huán)境
這里特別注意springboot和springcloud的版本兼容性,否則無法運(yùn)行。
需要對(duì)應(yīng)到版本。所以springCloud導(dǎo)入這個(gè)依賴。
我們可以放到這個(gè)標(biāo)簽下
復(fù)習(xí)一下它有什么用處
Maven 可以通過 dependencyManagement 元素對(duì)依賴進(jìn)行管理,它具有以下 2 大特性:
在該元素下聲明的依賴不會(huì)實(shí)際引入到模塊中,只有在 dependencies 元素下同樣聲明了該依賴,才會(huì)引入到模塊中。
該元素能夠約束 dependencies 下依賴的使用,即 dependencies 聲明的依賴若未指定版本,則使用 dependencyManagement 中指定的版本,否則將覆蓋 dependencyManagement 中的版本。
我們看到,這里多了一個(gè)import,它的意思是將spring-boot-dependencies 中dependencyManagement的dependencies,全部引入到當(dāng)前工程的dependencyManagement中
另外還有mysql的連接驅(qū)動(dòng),mybatis整合springboot框架分別導(dǎo)入進(jìn)來。
還有一個(gè)我們用到的工具
lombok插件是為了方便實(shí)體類bean快速生成get set方法,從而不用手動(dòng)添加
為什么我們要這樣分開寫,復(fù)習(xí)一下
dependencies即使在子項(xiàng)目中不寫該依賴項(xiàng),那么子項(xiàng)目仍然會(huì)從父項(xiàng)目中繼承該依賴項(xiàng)(全部繼承)而我們的DepencyManagement是子工程依賴模塊可選擇的。
至此父級(jí)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>
來看子級(jí)別pom
現(xiàn)在我們導(dǎo)入必要依賴
<?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>
還有一個(gè)打包插件我們暫且可以不用
兩個(gè)子工程都需要這樣導(dǎo)入
現(xiàn)在我們創(chuàng)建三成架構(gòu)的目錄和類
添加配置信息
同樣userservice
配置yml
這樣做好以后我們?nèi)プ鰡?dòng)類
遠(yuǎn)程調(diào)用初步
我們還沒有寫啟動(dòng)類,
user-service
我門需要是用RestTemplate實(shí)現(xiàn)服務(wù)調(diào)用。按照查詢的需求,我門需要在order-service這里進(jìn)行一個(gè)查詢,我門需要根據(jù)請(qǐng)求提交id參數(shù)查詢出來order的數(shù)據(jù),然后根據(jù)order數(shù)據(jù)表里面id對(duì)應(yīng)的用戶id查詢出來用戶的數(shù)據(jù),然后進(jìn)行一個(gè)統(tǒng)一的封裝。這說明order-sertvice需要調(diào)用user-service。
我們來看order-sertvice的啟動(dòng)類
我們除了寫出一個(gè)啟動(dòng)類的規(guī)則后,還new出了RestTemplate的bean。這個(gè)bean在哪里使用呢?
getForObject對(duì)應(yīng)的就是get請(qǐng)求,User.class表示將返回的數(shù)據(jù)封裝到User對(duì)象里面。
order-service的端口地址指定過。在yml文件里面。
注意現(xiàn)在還沒有用到Springcloud的東西,我們目前是模擬實(shí)現(xiàn)遠(yuǎn)程調(diào)用。只不過現(xiàn)在和之前相比是將功能模塊分開,而且啟動(dòng)的不在是單獨(dú)的一個(gè)服務(wù)。
我們需要將兩個(gè)服務(wù)都啟動(dòng)起來。
在postman中發(fā)送請(qǐng)求
數(shù)據(jù)測(cè)試是沒有問題的。但是似乎上面的地址請(qǐng)求顯得十分笨拙。還有這里其實(shí)并沒有實(shí)現(xiàn)真的遠(yuǎn)程調(diào)用。只是模塊之前的不同服務(wù)的之間的調(diào)用。還有就是服務(wù)的健康信息1我們?cè)谡{(diào)用的時(shí)候不得而知,如果對(duì)應(yīng)調(diào)用的服務(wù)有問題我們?cè)谡{(diào)用前也是無法得知的。如何對(duì)服務(wù)進(jìn)行一個(gè)更好的管理,我們繼續(xù)往下看。
Eureka注冊(cè)中心
服務(wù)注冊(cè)與負(fù)載均衡
服務(wù)注冊(cè)
說明一下這個(gè)是干嘛用的
Eureka 是 Netflix 出品的用于實(shí)現(xiàn)服務(wù)注冊(cè)和發(fā)現(xiàn)的工具,Spring Cloud 封裝了 Netflix 公司開發(fā)的 Eureka 模塊來實(shí)現(xiàn)服務(wù)注冊(cè)和發(fā)現(xiàn)
Eureka采用C-S的設(shè)計(jì)架構(gòu),包含Eureka Server 和Eureka Client兩個(gè)組件
它的原理就是基于服務(wù)提供者和服務(wù)消費(fèi)者。像我們的orderservice需要去訪問userservice,那么userservice就是服務(wù)提供者,orderservice就是。服務(wù)消費(fèi)者。
服務(wù)啟動(dòng)后向Eureka注冊(cè),Eureka Server會(huì)將注冊(cè)信息向其他Eureka Server進(jìn)行同步,當(dāng)服務(wù)消費(fèi)者要調(diào)用服務(wù)提供者,則向服務(wù)注冊(cè)中心獲取服務(wù)提供者地址,然后會(huì)將服務(wù)提供者地址緩存在本地,下次再調(diào)用時(shí),則直接從本地緩存中取,完成一次調(diào)用。
在默認(rèn)配置中EurekaServer服務(wù)在一定時(shí)間(默認(rèn)為90秒)沒接受到某個(gè)服務(wù)的心跳連接后,EurekaServer會(huì)注銷該服務(wù)。但是會(huì)存在當(dāng)網(wǎng)絡(luò)分區(qū)發(fā)生故障,導(dǎo)致該時(shí)間內(nèi)沒有心跳連接,但該服務(wù)本身還是健康運(yùn)行的情況。Eureka通過“自我保護(hù)模式”來解決這個(gè)問題。
在自我保護(hù)模式中,Eureka Server會(huì)保護(hù)服務(wù)注冊(cè)表中的信息,不再注銷任何服務(wù)實(shí)例。
我們可以對(duì)服務(wù)創(chuàng)建多個(gè)節(jié)點(diǎn),如果有的節(jié)點(diǎn)掛掉以后,就可以去啟用另外可用的服務(wù)。
當(dāng)然這個(gè)是基于springcloud的。所以我們需要導(dǎo)入相關(guān)的依賴。
在這之前啊,我們需要將eureka服務(wù)端創(chuàng)建出來
我們?cè)賱?chuàng)建一個(gè)模塊
打開這個(gè)pom文件添加必要依賴
然后創(chuàng)建啟動(dòng)類
一定要注意啟動(dòng)類要放在java目錄的包下面,所以最好創(chuàng)建包后,將這個(gè)啟動(dòng)類放到下面,不要直接放在java目錄下。
這里我們做的就是服務(wù)端。
即熱是服務(wù),那么我們還是要配置一下,比如端口等等,所以需要在resource下面創(chuàng)建一個(gè)yml文件。
一定要注意yml文件中字段的層級(jí)關(guān)系,這是非常嚴(yán)格的。
配置完這個(gè)后,我們需要配置客戶端。
首先還是需要引入依賴。
useservice 和orderservice都需要導(dǎo)入。
另外需要配置服務(wù)端的地址
同樣是都需要配置。
初步的話其實(shí)還有一定就是這里
我們需要指定一下服務(wù)名稱。先這樣配置一下,然后去啟動(dòng)
三者都啟動(dòng)
現(xiàn)在需要去訪問一個(gè)地址
注意端口10086后不需要加eureka
我們現(xiàn)在需要去查看服務(wù)是否注冊(cè)成功,或者說eureka服務(wù)端是否將userservice 和orderservice加入實(shí)例。
這樣就成功了。
然后我們就可以開啟去使用它了。
這里我們可以修改一下這里
但是在這之前,我們需要做一個(gè)負(fù)載均衡的指定,否則是無法解析服務(wù)地址。
然后這樣
這樣我們?cè)俅螁?dòng),就可以去訪問了。
Ribbon負(fù)載均衡
上面我們用到了負(fù)載策略
負(fù)載均衡是高可用網(wǎng)絡(luò)基礎(chǔ)架構(gòu)的關(guān)鍵組件,通常用于將工作負(fù)載分布到多個(gè)服務(wù)器來提高網(wǎng)站、應(yīng)用、數(shù)據(jù)庫或其他服務(wù)的性能和可靠性。
注:圖片數(shù)據(jù)來自知乎
什么是負(fù)載均衡
從這里可以去看負(fù)載均衡策略
沒有負(fù)載均衡的服務(wù)架構(gòu)
有負(fù)載均衡的服務(wù)架構(gòu)
我們這樣的特點(diǎn)可以去用多實(shí)例部署的特點(diǎn)。
定要記得修改端口
將這個(gè)服務(wù)啟動(dòng)起來
然后我們?nèi)ureka注冊(cè)中心看看有沒有實(shí)例
可以看到userservice一共有兩個(gè)實(shí)例對(duì)象了。
這樣創(chuàng)建多實(shí)例的好處就是如果一個(gè)實(shí)例存在問題的話就可以換另一個(gè)。我們這里就模擬了多實(shí)例部署。
還有我們需要去觀察一下這個(gè)負(fù)載均衡策略,其實(shí)默認(rèn)是輪詢的負(fù)載均衡策略。
我們可以去測(cè)試,多訪問幾次userservice,而現(xiàn)在userservice有兩個(gè)實(shí)例,我們?cè)趐ostman測(cè)試工具做出測(cè)試,發(fā)出請(qǐng)求,看看具體調(diào)用的哪個(gè)實(shí)例。
注意現(xiàn)在需要改一個(gè)東西,就是上面有一個(gè)錯(cuò)誤的地方。有關(guān)日志的。
logging.level設(shè)置日志級(jí)別,后面跟生效的區(qū)域,比如root表示整個(gè)項(xiàng)目,也可以設(shè)置為某個(gè)包下,也可以具體到某個(gè)類名(日志級(jí)別的值不區(qū)分大小寫)這里需要注意,上面的包名沒有寫對(duì)。
然后開始測(cè)試,首先將控制臺(tái)的輸出全部清除掉。
我這里從1到6一共訪問6次。
然后來看控制臺(tái)的日志輸出,可見這是輪詢的方式
指定負(fù)載均衡規(guī)則
默認(rèn)的是輪詢,我們可以自己去指定一個(gè)規(guī)則
所以就從這里來重新指定規(guī)則
我們?cè)趏rderservice的啟動(dòng)類里面寫,當(dāng)然這個(gè)是代碼的方式。并且,我們需要將它做成一個(gè)bean。
我們這樣定義是選擇了隨機(jī)的原則,代表隨機(jī)選擇一個(gè)服務(wù)器。
然后我們?nèi)ブ匦聠?dòng)測(cè)試
測(cè)試成功
如果采用配置文件的方式
兩者配置不同之處在于作用范圍。代碼配置的話就是會(huì)在全部服務(wù)中起作用,而配置文件配置的話就只會(huì)在指定的服務(wù)起作用。
還有一個(gè)就是關(guān)于啟動(dòng)問題的知識(shí)點(diǎn),默認(rèn)是懶加載。
我們這樣去配置
Nocas 注冊(cè)中心
環(huán)境配置啟動(dòng)服務(wù)注冊(cè)
Nacos是阿里巴巴的一個(gè)產(chǎn)品,說實(shí)話,這個(gè)注冊(cè)中心是真的好用。下面我們開始介紹。
首先我們需要安裝這個(gè)服務(wù),服務(wù)區(qū)官網(wǎng)下載就可以了。
官網(wǎng) 可以選擇點(diǎn)進(jìn)去github下載服務(wù)。
目錄結(jié)構(gòu)
然后進(jìn)去bin目錄里面,進(jìn)行執(zhí)行開啟服務(wù)
如何開啟服務(wù),打開手冊(cè)。
在快速開始這里,我們可以進(jìn)行執(zhí)行命令。
將這個(gè)命令執(zhí)行后就可以開啟這個(gè)服務(wù)了
然后我們?nèi)dea里面配置相關(guān)的東西
然后在里面配置相關(guān)的依賴,配置依賴的話就需要注釋掉eureka的依賴。
如果沒有在父工程添加阿里巴巴的依賴的話,我們需要進(jìn)行添加依賴。
將這個(gè)依賴導(dǎo)入到父工程里面。
然后在子工程中將原來的eureka的依賴注釋掉
在pom文件當(dāng)中配置的就是客戶端依賴。因?yàn)榉?wù)端是已經(jīng)下載安裝的。
我們需要將服務(wù)端的service和客戶端的sevice都配置依賴。
然后我們進(jìn)行配置yml文件進(jìn)行配置
然后將eureka的配置注釋掉
然后我們將這幾個(gè)服務(wù)啟動(dòng)。我們現(xiàn)在就不需要去啟動(dòng)eureka了。
我們?cè)L問nacos的服務(wù)列表
管理頁面訪問地址
進(jìn)入到服務(wù)列表,我們可以看到服務(wù)列表查看注冊(cè)情況
至此注冊(cè)成功。而且我們可以看到這里userservice一共有兩個(gè)實(shí)例。
這里我們可以看到具體的一些信息,包括端口號(hào),已經(jīng)健康狀態(tài),后面可以進(jìn)行一些操作,包括服務(wù)上線下線的操作。
我們可以進(jìn)去到服務(wù)列表具體實(shí)例的詳情,可以查看到一些具體的信息。
Nacos 分級(jí)存儲(chǔ)模型與集群
這里引入了一個(gè)新的概念。集群的概念。
這里先不用去關(guān)注集群的具體的概念,但是在結(jié)合分布式服務(wù)的話,集群可以幫助我們解決服務(wù)的跨區(qū)域的問題??鐓^(qū)域部署服務(wù)器。
按照上圖所示集群部署的話,可以部署在不同的地域。杭州,上海等等。然后我們通過nacos進(jìn)行集群管理。包括相關(guān)的實(shí)例部署等等。
我們可以去模擬配置集群
這里我們指定了一個(gè)集群,表示部署在此地。我們可以對(duì)這些服務(wù)都指定相關(guān)的服務(wù)集群
好,現(xiàn)在再次啟動(dòng)重新服務(wù)
我們可以看到一共有兩個(gè)集群,這樣我們就指派成功了。
負(fù)載均衡
在nacos 也可以進(jìn)行加權(quán)負(fù)載均衡
我們一共有兩個(gè)usersrvice的服務(wù),我們可以去指定其中的一個(gè)權(quán)值,權(quán)值越低被訪問調(diào)用的幾率越1低,權(quán)值為0的話就不會(huì)被訪問了。我們可以測(cè)試。
我們可以用postman進(jìn)行訪問測(cè)試。
用postman進(jìn)行測(cè)試
可以看到多次訪問都沒有訪問到權(quán)值為0的服務(wù)實(shí)例,這樣其實(shí)就實(shí)現(xiàn)了一個(gè)權(quán)值的負(fù)載均衡策略。
當(dāng)然你可以指定其他的值。
namespace 環(huán)境隔離
其實(shí)還有可以進(jìn)行環(huán)境隔離的操作。
現(xiàn)在nacos操作平臺(tái)進(jìn)行生成新的命名空間。
我們的之前的命名空間就是public類型,是一個(gè)保留空間。
我們可以自己去這里創(chuàng)建空間,然后自己在代碼配置中指定給那個(gè)服務(wù)配置相應(yīng)的空間。
填寫保留空間的名字和描述就可以,Id可以自動(dòng)生成。
我們給具體的服務(wù)配置命名空間,就配置namespace,然后將id復(fù)制過去作為鍵的值。
命名空間的作用就是相當(dāng)于起到環(huán)境隔離的作用。
如果服務(wù)在不同的命名空間,那么這兩個(gè)服務(wù)就無法互相訪問。
現(xiàn)在我們重新啟動(dòng)userservice的一個(gè)實(shí)例,我們可以將,然后這個(gè)實(shí)例是必然不會(huì)和orderservive在同一個(gè)命名空間。是不會(huì)訪問到的。
我們測(cè)試orderservice能不能訪問到userservice的服務(wù)端1。
可以看到是不能訪問到的。
臨時(shí)實(shí)例和非臨時(shí)實(shí)例(存在依賴的修改更正)
臨時(shí)實(shí)例的服務(wù)在宕機(jī)后會(huì)從nacos的列表中被刪除掉,而非臨時(shí)實(shí)例不會(huì)被刪掉。
到這里發(fā)現(xiàn)我之前導(dǎo)入的依賴是不能這樣設(shè)置的。
前面的設(shè)置都可以支持
想要支持實(shí)例的配置管理的話需要導(dǎo)入這個(gè)依賴
在自己需要的服務(wù)里面導(dǎo)入進(jìn)來。我現(xiàn)在只在useservice這里進(jìn)行驗(yàn)證臨時(shí)實(shí)例和非臨時(shí)實(shí)例的特點(diǎn)。
我現(xiàn)在的服務(wù)都重啟
注意看這里,全部為false,然后現(xiàn)在為了對(duì)比做這樣的操作。
我將其中一個(gè)停掉。然后改為true
然后再啟動(dòng)
你看這里發(fā)生了什么。為什么會(huì)有兩個(gè)8082的端口的實(shí)例服務(wù)呢?原因是我們之前給它設(shè)置為非臨時(shí)實(shí)例,就算我們剛剛重啟了服務(wù),但是它不會(huì)被刪除,現(xiàn)在我們關(guān)閉服務(wù),看看設(shè)置為true的這個(gè)實(shí)例會(huì)不會(huì)被刪掉。
看吧已經(jīng)刪掉,還有一點(diǎn)這里的健康狀態(tài)和這個(gè)顏色我們之前的這個(gè)都變了。
對(duì)于臨時(shí)實(shí)例和非臨時(shí)實(shí)例的區(qū)別,nacos也做出了不同的檢測(cè)
臨時(shí) 實(shí)例:nacos會(huì)在超過15秒未收到心跳后將實(shí)例設(shè)置為不健康狀態(tài);
超過30秒將實(shí)例刪除;
非臨時(shí)實(shí)例:nacos主動(dòng)探知客戶端健康狀態(tài),默認(rèn)間隔為20秒;
健康檢查失敗后實(shí)例會(huì)被標(biāo)記為不健康,不會(huì)被立即刪除。
統(tǒng)一配置管理與熱更新
我們先了解nacos是如何加載配置的
我們想要做的的是在nacos的管理界面進(jìn)行配置,然后這個(gè)配置首先可以被加載,然后這樣的加載配置在我們發(fā)布以后會(huì)自動(dòng)生效,而不需要我們重啟服務(wù)器,這樣的配置更新方法也叫做熱更新。
具體怎么做呢?我們先去nacos的配置管理界面。在這里我發(fā)布了一個(gè)新的配置。
我們來看具體的詳情
這樣配置后然后發(fā)布就可以了,當(dāng)然這只是在nacos的配置列表進(jìn)行的配置。我們還需要在idea里面操作一些東西。
我們還需要引入一個(gè)依賴。nacos的配置管理依賴
這個(gè)配置依賴需要在你想要進(jìn)行統(tǒng)一配置和熱部署操作的服務(wù)的pom中添加。
然后我們需要?jiǎng)?chuàng)建一個(gè)配置文件
這個(gè)配置文件的優(yōu)先級(jí)別高,nacos會(huì)先加載這個(gè)配置文件,然后會(huì)加載application.yml文件,將著兩個(gè)配置文件的配置合并一起。
要記得在原來的配置文件中注釋掉一些可能重復(fù)的配置或者非必要的配置。
服務(wù)名,還有地址,集群的話不需要,命名空間的話,因?yàn)槲业膎acos添加的配置在public下面,所以我把之前指定的也注釋掉了。
在nacos管理配置列表配置的一些東西和這里是對(duì)應(yīng)的,所以一定要細(xì)心注意。
這樣的話我們?nèi)绾沃琅渲蒙?,或者如何去?yàn)證熱部署成功?
我們可以通過value讀取,將這個(gè)數(shù)據(jù)讀到Controller里面,給這個(gè)值配置一個(gè)訪問路徑。我們可以這樣去做。
這里有個(gè)坑,就是如果你的nacos無法解析的話,就需要升級(jí)一下。升級(jí)到1.4.2.。
還有一點(diǎn)就是需要配置自動(dòng)熱更新。
我現(xiàn)在的服務(wù)已經(jīng)啟動(dòng),我們?nèi)ピL問。
你看這樣搜先加載到了。
現(xiàn)在我們?cè)趎acos配置管理那里稍微改動(dòng)一下。
發(fā)布的時(shí)候會(huì)告訴你原始值和你修改的。
現(xiàn)在我們?cè)偃ピL問
這樣就驗(yàn)證成功了。熱部署成功·。
還有一種屬性注入方式
我們需要去寫一個(gè)配置類
然后在Controller里面這樣做
還有這種方法不需要去添加這個(gè)注解
需要注意的是,可能存在bean無法注入的問題。那么我們可以去給他掃描。
------未完續(xù)更,等待
到此這篇關(guān)于SpringCloud 分布式微服務(wù)架構(gòu)的文章就介紹到這了,更多相關(guān)SpringCloud微服務(wù)架構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringCloud使用Feign實(shí)現(xiàn)遠(yuǎn)程調(diào)用流程詳細(xì)介紹
- SpringCloud使用Feign實(shí)現(xiàn)動(dòng)態(tài)路由操作
- springcloud使用feign調(diào)用服務(wù)時(shí)參數(shù)內(nèi)容過大問題
- SpringCloud之@FeignClient()注解的使用方式
- SpringCloud分布式鏈路追蹤組件Sleuth配置詳解
- SpringCloud?分布式鎖的多種實(shí)現(xiàn)
- SpringCloudAlibaba分布式組件詳解
- SpringCloud分布式項(xiàng)目下feign的使用示例詳解
相關(guān)文章
springboot集成mybatis-maven插件自動(dòng)生成pojo的詳細(xì)教程
這篇文章主要介紹了springboot集成mybatis-maven插件自動(dòng)生成pojo的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01Java設(shè)計(jì)模式之觀察者模式(Observer Pattern)詳解
觀察者模式(Observer Pattern)是一種行為型設(shè)計(jì)模式,它定義了一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都能夠自動(dòng)地得到通知并進(jìn)行更新,本文將詳細(xì)的給大家介紹一下Java觀察者模式,需要的朋友可以參考下2023-07-07