怎么樣通過做網(wǎng)站賺錢嗎用網(wǎng)站模板建站
SpringCloud微服務(wù)之Eureka、Ribbon、Nacos詳解
- 1、認(rèn)識(shí)微服務(wù)
- 1.1、單體架構(gòu)
- 1.2、分布式架構(gòu)
- 1.3、微服務(wù)
- 1.4、SpringCloud
- 2、服務(wù)拆分與遠(yuǎn)程調(diào)用
- 2.1、服務(wù)拆分的原則
- 2.2、服務(wù)拆分示例
- 2.2、提供者與消費(fèi)者
- 3、Eureka注冊(cè)中心
- 3.1、Eureka的結(jié)構(gòu)和作用
- 3.2、搭建eureka-server
- 3.2.1、創(chuàng)建eureka-server微服務(wù)
- 3.2.2、引入eureka依賴
- 3.2.3、編寫啟動(dòng)類
- 3.2.4、編寫配置文件
- 3.2.5、啟動(dòng)服務(wù)
- 3.3、服務(wù)注冊(cè)
- 3.3.1、啟動(dòng)多個(gè)user-service實(shí)例
- 3.4、服務(wù)發(fā)現(xiàn)
- 4、Ribbon負(fù)載均衡
- 4.1、負(fù)載均衡的原理
- 4.2、負(fù)載均衡策略
- 4.3、饑餓加載
- 5、Nacos注冊(cè)中心
- 5.1、認(rèn)識(shí)和安裝Nacos
- 5.1.1、Windows安裝
- 5.1.2、Linux安裝
- 5.2、Nacos的依賴
- 5.3、服務(wù)分級(jí)存儲(chǔ)模型
- 5.3.1、給user-service配置集群
- 5.3.2、同集群優(yōu)先的負(fù)載均衡
- 5.4、權(quán)重配置
- 5.5、環(huán)境隔離
- 5.5.1、創(chuàng)建namespace
- 5.5.2、給微服務(wù)配置namespace
- 5.6、Nacos與Eureka的區(qū)別
1、認(rèn)識(shí)微服務(wù)
隨著互聯(lián)網(wǎng)行業(yè)的發(fā)展,對(duì)服務(wù)的要求也越來越高,服務(wù)架構(gòu)也從單體架構(gòu)逐漸演變?yōu)楝F(xiàn)在流行的微服務(wù)架構(gòu)。這些架構(gòu)之間有怎樣的差別呢?
1.1、單體架構(gòu)
- 單體架構(gòu):將業(yè)務(wù)的所有功能集中在一個(gè)項(xiàng)目中開發(fā),打成一個(gè)包部署。
單體架構(gòu)的優(yōu)缺點(diǎn)如下:
優(yōu)點(diǎn):
- 架構(gòu)簡(jiǎn)單、部署成本低
缺點(diǎn):
- 耦合度高(維護(hù)困難、升級(jí)困難)
1.2、分布式架構(gòu)
- 分布式架構(gòu):根據(jù)業(yè)務(wù)功能對(duì)系統(tǒng)做拆分,每個(gè)業(yè)務(wù)功能模塊作為獨(dú)立項(xiàng)目開發(fā),稱為一個(gè)服務(wù)。
分布式架構(gòu)的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):
- 降低服務(wù)耦合、有利于服務(wù)升級(jí)和拓展
缺點(diǎn):
- 服務(wù)調(diào)用關(guān)系錯(cuò)綜復(fù)雜
思考:分布式架構(gòu)雖然降低了服務(wù)耦合,但是服務(wù)拆分時(shí)也有很多問題需要思考:
- 服務(wù)拆分的粒度如何界定?
- 服務(wù)之間如何調(diào)用?
- 服務(wù)的調(diào)用關(guān)系如何管理?
人們需要制定一套行之有效的標(biāo)準(zhǔn)來約束分布式架構(gòu)。
1.3、微服務(wù)
微服務(wù)的架構(gòu)特征:
- 單一職責(zé):微服務(wù)拆分粒度更小,每一個(gè)服務(wù)都對(duì)應(yīng)唯一的業(yè)務(wù)能力,做到單一職責(zé)
- 自治:團(tuán)隊(duì)獨(dú)立、技術(shù)獨(dú)立、數(shù)據(jù)獨(dú)立,獨(dú)立部署和交付
- 面向服務(wù):服務(wù)提供統(tǒng)一標(biāo)準(zhǔn)的接口,與語言和技術(shù)無關(guān)
- 隔離性強(qiáng):服務(wù)調(diào)用做好隔離、容錯(cuò)、降級(jí),避免出現(xiàn)級(jí)聯(lián)問題
微服務(wù)的上述特性其實(shí)是在給分布式架構(gòu)制定一個(gè)標(biāo)準(zhǔn),進(jìn)一步降低服務(wù)之間的耦合度,提供服務(wù)的獨(dú)立性和靈活性。做到高內(nèi)聚,低耦合。
因此,可以認(rèn)為微服務(wù)是一種經(jīng)過良好架構(gòu)設(shè)計(jì)的分布式架構(gòu)方案 。但方案該怎么落地?選用什么樣的技術(shù)棧?全球的互聯(lián)網(wǎng)公司都在積極嘗試自己的微服務(wù)落地方案。其中在Java領(lǐng)域最引人注目的就是SpringCloud提供的方案了。
1.4、SpringCloud
SpringCloud是目前國(guó)內(nèi)使用最廣泛的微服務(wù)框架。官網(wǎng)地址:https://spring.io/projects/spring-cloud。
SpringCloud集成了各種微服務(wù)功能組件,并基于SpringBoot實(shí)現(xiàn)了這些組件的自動(dòng)裝配,從而提供了良好的開箱即用體驗(yàn)。
其中常見的組件包括:
另外,SpringCloud底層是依賴于SpringBoot的,并且有版本的兼容關(guān)系,如下:
2、服務(wù)拆分與遠(yuǎn)程調(diào)用
2.1、服務(wù)拆分的原則
- 不同微服務(wù),不要重復(fù)開發(fā)相同業(yè)務(wù)
- 微服務(wù)數(shù)據(jù)獨(dú)立,不要訪問其它微服務(wù)的數(shù)據(jù)庫(kù)
- 微服務(wù)可以將自己的業(yè)務(wù)暴露為接口,供其它微服務(wù)調(diào)用
每個(gè)微服務(wù)都有自己的數(shù)據(jù)庫(kù),用戶功能里面存的是用戶相關(guān)的數(shù)據(jù)庫(kù),商品功能里面存的是商品相關(guān)的數(shù)據(jù)庫(kù),如果想在用戶功能里面需要訂單的信息,那么訂單模塊就對(duì)外暴露成一個(gè)接口,供用戶功能的微服務(wù)調(diào)用。
2.2、服務(wù)拆分示例
- 創(chuàng)建訂單模塊的數(shù)據(jù)庫(kù)
KuangStudy_springcloud_order
,然后導(dǎo)入下述sql
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;INSERT INTO `tb_order` VALUES (101, 1, 'Apple 蘋果 iPhone 12 ', 699900, 1);
INSERT INTO `tb_order` VALUES (102, 2, '雅迪 yadea 新國(guó)標(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);
- 創(chuàng)建用戶模塊的數(shù)據(jù)庫(kù)
KuangStudy_springcloud_user
,然后導(dǎo)入下述sql
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;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, '范兵兵', '山東省青島市');
tb_user表中初始數(shù)據(jù)如下:
tb_order表中初始數(shù)據(jù)如下:
tb_order表中持有tb_user表中的id字段。
- 在order-service服務(wù)中,有一個(gè)根據(jù)id查詢訂單的接口:
根據(jù)id查詢訂單,返回值是Order對(duì)象,如圖:
在user-service中有一個(gè)根據(jù)id查詢用戶的接口:
查詢的結(jié)果如圖:
- 案例需求:修改order-service中的根據(jù)id查詢訂單業(yè)務(wù),要求在查詢訂單的同時(shí),根據(jù)訂單中包含的userId查詢出用戶信息,一起返回
因此,我們需要在order-service中 向user-service發(fā)起一個(gè)http的請(qǐng)求,調(diào)用http://localhost:8081/user/{userId}
這個(gè)接口。
大概的步驟是這樣的:
- 注冊(cè)一個(gè)RestTemplate的實(shí)例到Spring容器
- 修改order-service服務(wù)中的OrderService類中的queryOrderById方法,根據(jù)Order對(duì)象中的userId查詢User
- 將查詢的User填充到Order對(duì)象,一起返回
- 在order-service服務(wù)中的
OrderApplication
啟動(dòng)類中,注冊(cè)RestTemplate實(shí)例:
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}/*** 注冊(cè)RestTemplate*/@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}
- 修改order-service服務(wù)中的cn.itcast.order.service包下的OrderService類中的queryOrderById方法
- 訪問:
http://localhost:8080/order/101
2.2、提供者與消費(fèi)者
在服務(wù)調(diào)用關(guān)系中,會(huì)有兩個(gè)不同的角色:
-
服務(wù)提供者:一次業(yè)務(wù)中,被其它微服務(wù)調(diào)用的服務(wù)。(提供接口給其它微服務(wù))
-
服務(wù)消費(fèi)者:一次業(yè)務(wù)中,調(diào)用其它微服務(wù)的服務(wù)。(調(diào)用其它微服務(wù)提供的接口)
但是,服務(wù)提供者與服務(wù)消費(fèi)者的角色并不是絕對(duì)的,而是相對(duì)于業(yè)務(wù)而言。
思考:如果服務(wù)A調(diào)用了服務(wù)B,而服務(wù)B又調(diào)用了服務(wù)C,服務(wù)B的角色是什么?
- 對(duì)于A調(diào)用B的業(yè)務(wù)而言:A是服務(wù)消費(fèi)者,B是服務(wù)提供者
- 對(duì)于B調(diào)用C的業(yè)務(wù)而言:B是服務(wù)消費(fèi)者,C是服務(wù)提供者
- 因此,服務(wù)B既可以是服務(wù)提供者,也可以是服務(wù)消費(fèi)者。
總結(jié):一個(gè)服務(wù)既可以是提供者,也可以是消費(fèi)者
3、Eureka注冊(cè)中心
- 讀音:Eureka:you rui ka
假如我們的服務(wù)提供者user-service部署了多個(gè)實(shí)例,如圖:
大家思考幾個(gè)問題:
order-service
在發(fā)起遠(yuǎn)程調(diào)用的時(shí)候,該如何得知user-service
實(shí)例的ip地址和端口?- 有多個(gè)
user-service
實(shí)例地址,order-service
調(diào)用時(shí)該如何選擇? order-service
如何得知某個(gè)user-service
實(shí)例是否依然健康,是不是已經(jīng)宕機(jī)?
3.1、Eureka的結(jié)構(gòu)和作用
這些問題都需要利用SpringCloud中的注冊(cè)中心來解決,其中最廣為人知的注冊(cè)中心就是Eureka,其結(jié)構(gòu)如下:
Eureka分為兩層結(jié)構(gòu):
- 服務(wù)端:也就是注冊(cè)中心
- 客戶端:包含服務(wù)消費(fèi)者和服務(wù)提供者
每一個(gè)user-service
在啟動(dòng)時(shí)都會(huì)去 注冊(cè)中心 注冊(cè)服務(wù)信息,Eureka
會(huì)把這些信息記錄下來,包括ip、端口等等,如果 order-service
需要調(diào)用user-service
的接口,先去找注冊(cè)中心,注冊(cè)中心有關(guān)于user-service
的信息,則order-service
就可以獲取到user-service
的信息了。
如上圖,order-service
拿到了3個(gè)user-service
的信息,通過負(fù)載均衡挑出一個(gè),這樣order-service
就可以調(diào)用user-service
了。
思考:那挑選出來的
user-service
會(huì)不會(huì)宕機(jī)呢?答案:不會(huì),因?yàn)榭蛻舳藭?huì)每30秒給Eureka發(fā)送心跳,來續(xù)費(fèi)自己的信息,以此來讓Eureka來確保自己還活著!
這樣我們就可以回答之前的各個(gè)問題了!
- order-service如何得知user-service實(shí)例地址?
- 獲取地址信息的流程如下:
- user-service服務(wù)實(shí)例啟動(dòng)后,將自己的信息注冊(cè)到eureka-server(Eureka服務(wù)端)。這個(gè)叫服務(wù)注冊(cè)
- eureka-server保存服務(wù)名稱到服務(wù)實(shí)例地址列表的映射關(guān)系
- order-service根據(jù)服務(wù)名稱,拉取實(shí)例地址列表。這個(gè)叫服務(wù)發(fā)現(xiàn)或服務(wù)拉取
- order-service如何從多個(gè)user-service實(shí)例中選擇具體的實(shí)例?
- order-service從實(shí)例列表中利用負(fù)載均衡算法選中一個(gè)實(shí)例地址
- 向該實(shí)例地址發(fā)起遠(yuǎn)程調(diào)用
- order-service如何得知某個(gè)user-service實(shí)例是否依然健康,是不是已經(jīng)宕機(jī)?
- user-service會(huì)每隔一段時(shí)間(默認(rèn)30秒)向eureka-server發(fā)起請(qǐng)求,報(bào)告自己狀態(tài),稱為心跳
- 當(dāng)超過一定時(shí)間沒有發(fā)送心跳時(shí),eureka-server會(huì)認(rèn)為微服務(wù)實(shí)例故障,將該實(shí)例從服務(wù)列表中剔除
- order-service拉取服務(wù)時(shí),就能將故障實(shí)例排除了
3.2、搭建eureka-server
3.2.1、創(chuàng)建eureka-server微服務(wù)
在cloud-demo父工程下,創(chuàng)建一個(gè)子模塊:
填寫Maven模塊信息:
然后填寫服務(wù)信息:
3.2.2、引入eureka依賴
引入SpringCloud為eureka提供的starter依賴:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
3.2.3、編寫啟動(dòng)類
給eureka-server服務(wù)編寫一個(gè)啟動(dòng)類:
src/main/java/cn/itcast/eureka/EurekaApplication.java
- 一定要添加一個(gè)
@EnableEurekaServer
注解,開啟eureka的注冊(cè)中心功能:
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {public static void main(String[] args) {SpringApplication.run(EurekaApplication.class, args);}
}
3.2.4、編寫配置文件
編寫一個(gè)application.yml
文件,內(nèi)容如下:
server:port: 10086 # 服務(wù)端口
spring:application:name: eurekaserver # eureka的服務(wù)名稱
eureka:client:service-url: # eureka的地址信息defaultZone: http://127.0.0.1:10086/eureka
3.2.5、啟動(dòng)服務(wù)
啟動(dòng)erueka-server
微服務(wù)EurekaApplication
,然后在瀏覽器訪問:http://127.0.0.1:10086,看到如下結(jié)果則成功。
3.3、服務(wù)注冊(cè)
下面,我們將user-service注冊(cè)到eureka-server中去。
-
引入依賴
在user-service的pom文件中,引入下面的eureka-client依賴:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
-
配置文件
在user-service中,修改application.yml文件,添加服務(wù)名稱、eureka地址:
spring:application:# 微服務(wù)的名字name: userservice# eureka 服務(wù)注冊(cè)
eureka:client:service-url:# eureka的地址信息defaultZone: http://127.0.0.1:10086/eureka
3.3.1、啟動(dòng)多個(gè)user-service實(shí)例
為了演示一個(gè)服務(wù)有多個(gè)實(shí)例的場(chǎng)景,我們添加一個(gè)SpringBoot的啟動(dòng)配置,再啟動(dòng)一個(gè)user-service
。模擬多實(shí)例部署,但是為了避免端口沖突,需要修改端口設(shè)置。
- 首先,復(fù)制原來的user-service啟動(dòng)配置:
- 填寫信息,將第二個(gè)
user-service
的端口寫為8082
- 啟動(dòng)兩個(gè)
user-service
實(shí)例(第一個(gè)是8081端口、第二個(gè)是8082端口)、啟動(dòng)eureka-service
注冊(cè)中心
3.4、服務(wù)發(fā)現(xiàn)
下面,我們將order-service的邏輯修改:向eureka-server拉取user-service的信息,實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)。
- 引入依賴:之前說過,服務(wù)發(fā)現(xiàn)、服務(wù)注冊(cè)統(tǒng)一都封裝在eureka-client依賴,因此這一步與服務(wù)注冊(cè)時(shí)一致,在order-service的pom文件中,引入下面的
eureka-client
依賴:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 配置文件:服務(wù)發(fā)現(xiàn)也需要知道eureka地址,因此第二步與服務(wù)注冊(cè)一致,都是配置eureka信息,在order-service中,修改application.yml文件,添加服務(wù)名稱、eureka地址
spring:application:# 微服務(wù)的名字name: orderservice# eureka 服務(wù)注冊(cè)
eureka:client:service-url:# eureka的地址信息defaultZone: http://127.0.0.1:10086/eureka
- 服務(wù)拉取與負(fù)載均衡
最后,我們要去eureka-server中拉取user-service服務(wù)的實(shí)例列表,并且實(shí)現(xiàn)負(fù)載均衡。不過這些動(dòng)作不用我們?nèi)プ?#xff0c;只需要添加一些注解即可。
- 在order-service的OrderApplication中,給RestTemplate這個(gè)Bean添加一個(gè)
@LoadBalanced
注解:
- 修改order-service服務(wù)中的cn.itcast.order.service包下的OrderService類中的queryOrderById方法。修改訪問的url路徑,用服務(wù)名代替ip、端口:
spring會(huì)自動(dòng)幫助我們從eureka-server端,根據(jù)userservice這個(gè)服務(wù)名稱,獲取實(shí)例列表,而后完成負(fù)載均衡。
4、Ribbon負(fù)載均衡
- 讀音Ribbon:瑞奔
4.1、負(fù)載均衡的原理
SpringCloud底層其實(shí)是利用了一個(gè)名為Ribbon的組件,來實(shí)現(xiàn)負(fù)載均衡功能的。
當(dāng)微服務(wù) order-service 發(fā)起 http://userservice/user/1
的請(qǐng)求時(shí),會(huì)先被 Ribbon 攔截獲得另一個(gè)微服務(wù)名稱 user-service,Ribbon 會(huì)去找 eureka-server 注冊(cè)中心拉取 user-service 的ip和端口號(hào),然后對(duì) ip 和端口號(hào)進(jìn)行負(fù)載均衡。
思考: 那么我們發(fā)出的請(qǐng)求明明是http://userservice/user/1,怎么變成了http://localhost:8081的呢?
SpringCloudRibbon的底層采用了一個(gè)攔截器,攔截了RestTemplate發(fā)出的請(qǐng)求,對(duì)地址做了修改。用一幅圖來總結(jié)一下:
基本流程如下:
- 攔截我們的RestTemplate請(qǐng)求http://userservice/user/1
- RibbonLoadBalancerClient會(huì)從請(qǐng)求url中獲取服務(wù)名稱,也就是user-service
- DynamicServerListLoadBalancer根據(jù)user-service到eureka拉取服務(wù)列表
- eureka返回列表,localhost:8081、localhost:8082
- IRule利用內(nèi)置負(fù)載均衡規(guī)則,從列表中選擇一個(gè),例如localhost:8081
- RibbonLoadBalancerClient修改請(qǐng)求地址,用localhost:8081替代userservice,得到http://localhost:8081/user/1,發(fā)起真實(shí)請(qǐng)求
4.2、負(fù)載均衡策略
負(fù)載均衡的規(guī)則都定義在IRule接口中,而IRule有很多不同的實(shí)現(xiàn)類:
不同規(guī)則的含義如下:
內(nèi)置負(fù)載均衡規(guī)則類 | 規(guī)則描述 |
---|---|
RoundRobinRule | 簡(jiǎn)單輪詢服務(wù)列表來選擇服務(wù)器。它是Ribbon默認(rèn)的負(fù)載均衡規(guī)則。 |
AvailabilityFilteringRule | 對(duì)以下兩種服務(wù)器進(jìn)行忽略: (1)在默認(rèn)情況下,這臺(tái)服務(wù)器如果3次連接失敗,這臺(tái)服務(wù)器就會(huì)被設(shè)置為“短路”狀態(tài)。短路狀態(tài)將持續(xù)30秒,如果再次連接失敗,短路的持續(xù)時(shí)間就會(huì)幾何級(jí)地增加。 (2)并發(fā)數(shù)過高的服務(wù)器。如果一個(gè)服務(wù)器的并發(fā)連接數(shù)過高,配置了AvailabilityFilteringRule規(guī)則的客戶端也會(huì)將其忽略。 |
WeightedResponseTimeRule | 為每一個(gè)服務(wù)器賦予一個(gè)權(quán)重值。服務(wù)器響應(yīng)時(shí)間越長(zhǎng),這個(gè)服務(wù)器的權(quán)重就越小。這個(gè)規(guī)則會(huì)隨機(jī)選擇服務(wù)器,這個(gè)權(quán)重值會(huì)影響服務(wù)器的選擇。 |
ZoneAvoidanceRule | 以區(qū)域可用的服務(wù)器為基礎(chǔ)進(jìn)行服務(wù)器的選擇。使用Zone對(duì)服務(wù)器進(jìn)行分類,這個(gè)Zone可以理解為一個(gè)機(jī)房、一個(gè)機(jī)架等。而后再對(duì)Zone內(nèi)的多個(gè)服務(wù)做輪詢。 |
BestAvailableRule | 忽略那些短路的服務(wù)器,并選擇并發(fā)數(shù)較低的服務(wù)器。 |
RandomRule | 隨機(jī)選擇一個(gè)可用的服務(wù)器。 |
RetryRule | 重試機(jī)制的選擇邏輯 |
默認(rèn)的實(shí)現(xiàn)就是ZoneAvoidanceRule,是一種輪詢方案注意,一般用默認(rèn)的負(fù)載均衡規(guī)則,不做修改。
4.3、饑餓加載
Ribbon默認(rèn)是采用懶加載,即第一次訪問時(shí)才會(huì)去創(chuàng)建LoadBalanceClient,請(qǐng)求時(shí)間會(huì)很長(zhǎng)。而饑餓加載則會(huì)在項(xiàng)目啟動(dòng)時(shí)創(chuàng)建,降低第一次訪問的耗時(shí),通過下面配置開啟饑餓加載:
- 在 order-service 的 application.yaml 里面開啟饑餓加載:
ribbon:eager-load:# 開啟饑餓加載enabled: true# 指定饑餓加載的服務(wù)名稱clients: userservice
假如有多個(gè)服務(wù)需要開啟饑餓加載:
ribbon:eager-load:# 開啟饑餓加載enabled: true# 指定饑餓加載的服務(wù)名稱clients: - userservice- xxxservice
5、Nacos注冊(cè)中心
國(guó)內(nèi)公司一般都推崇阿里巴巴的技術(shù),比如注冊(cè)中心,SpringCloudAlibaba也推出了一個(gè)名為Nacos的注冊(cè)中心。
5.1、認(rèn)識(shí)和安裝Nacos
Nacos是阿里巴巴的產(chǎn)品,現(xiàn)在是SpringCloud中的一個(gè)組件。相比Eureka功能更加豐富,在國(guó)內(nèi)受歡迎程度較高。
- 去GitHub的Release下載Nacos:https://github.com/alibaba/nacos/releases
5.1.1、Windows安裝
-
我這里下載
nacos-server-1.4.7.zip
,解壓到非中文目錄下,目錄說明- bin:啟動(dòng)腳本
- conf:配置文件
-
Nacos的默認(rèn)端口是8848,如果你電腦上的其它進(jìn)程占用了8848端口,請(qǐng)先嘗試關(guān)閉該進(jìn)程。如果無法關(guān)閉占用8848端口的進(jìn)程,也可以進(jìn)入nacos的
conf/application.properties
目錄,修改配置文件中的端口
- 啟動(dòng):進(jìn)入 bin目錄,打開 cmd,執(zhí)行如下命令
# 以單機(jī)模式啟動(dòng)
startup.cmd -m standalone
- 訪問:http://127.0.0.1:8848/nacos即可,默認(rèn)賬號(hào)密碼都是
nacos
5.1.2、Linux安裝
- Nacos依賴于JDK運(yùn)行,索引Linux上也需要安裝JDK才行。(略:參考Linux下安裝JDK環(huán)境)
- 將
nacos-server-1.4.7.tar.gz
上傳到Linux服務(wù)器的某個(gè)目錄 - 解壓
tar -xvf nacos-server-1.4.7.tar.gz
- 端口配置:與Windows類似
- 啟動(dòng),在
nacos/bin
目錄中,輸入命令啟動(dòng)
sh startup.sh -m standalone
5.2、Nacos的依賴
- 引入依賴:在cloud-demo父工程的pom文件中的
<dependencyManagement>
中引入SpringCloudAlibaba的依賴
<!--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>
- 注釋掉 order-service 和 user-service 中原有的 eureka 依賴
- 引入依賴:然后在user-service和order-service中的pom文件中引入nacos-discovery依賴:
<!-- nacos客戶端依賴包 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
- 服務(wù)注冊(cè)到nacos:在user-service和order-service的application.yml中添加nacos地址:
spring:cloud:nacos:# nacos服務(wù)地址server-addr: localhost:8848
- 注釋掉 eureka 的配置
- 啟動(dòng) order-service、user-service 微服務(wù),登錄 nacos 管理頁面:http://127.0.0.1:8848/nacos,可以看到微服務(wù)信息
5.3、服務(wù)分級(jí)存儲(chǔ)模型
一個(gè)服務(wù)可以有多個(gè)實(shí)例,例如我們的user-service,可以有:
- 127.0.0.1:8081
- 127.0.0.1:8082
- 127.0.0.1:8083
假如這些實(shí)例分布于全國(guó)各地的不同機(jī)房,例如:
- 127.0.0.1:8081,在上海機(jī)房
- 127.0.0.1:8082,在上海機(jī)房
- 127.0.0.1:8083,在杭州機(jī)房
Nacos就將同一機(jī)房?jī)?nèi)的多個(gè)實(shí)例劃分為一個(gè)集群。
也就是說,user-service是服務(wù),一個(gè)服務(wù)可以包含多個(gè)集群,如杭州、上海,每個(gè)集群下可以有多個(gè)實(shí)例,形成分級(jí)模型,如圖:
微服務(wù)互相訪問時(shí),應(yīng)該盡可能訪問同集群實(shí)例,因?yàn)楸镜卦L問速度更快。當(dāng)本集群內(nèi)不可用時(shí),才訪問其它集群。例如:
杭州機(jī)房?jī)?nèi)的order-service應(yīng)該優(yōu)先訪問同機(jī)房的user-service。
5.3.1、給user-service配置集群
- 修改user-service的application.yml文件,添加集群配置:
spring:cloud:nacos:server-addr: localhost:8848discovery:# 集群名稱杭州cluster-name: HZ
重啟兩個(gè)user-service實(shí)例后,我們可以在nacos控制臺(tái)看到下面結(jié)果:
我們?cè)俅螐?fù)制一個(gè)user-service啟動(dòng)配置,添加屬性:
# 端口為8083 集群為上海
-Dserver.port=8083 -Dspring.cloud.nacos.discovery.cluster-name=SH
啟動(dòng)UserApplication3后再次查看nacos控制臺(tái):
5.3.2、同集群優(yōu)先的負(fù)載均衡
默認(rèn)的ZoneAvoidanceRule
并不能實(shí)現(xiàn)根據(jù)同集群優(yōu)先來實(shí)現(xiàn)負(fù)載均衡。因此Nacos中提供了一個(gè)NacosRule
的實(shí)現(xiàn),可以優(yōu)先從同集群中挑選實(shí)例。所以需要給 order-service也需要配置 HZ 集群信息。
- 給order-service配置集群信息:修改order-service的application.yml文件,添加集群配置:
spring:cloud:nacos:server-addr: localhost:8848discovery:cluster-name: HZ # 集群名稱
- 修改負(fù)載均衡規(guī)則:修改order-service的application.yml文件,修改負(fù)載均衡規(guī)則:
userservice:ribbon:# 負(fù)載均衡規(guī)則 NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
5.4、權(quán)重配置
實(shí)際部署中會(huì)出現(xiàn)這樣的場(chǎng)景:服務(wù)器設(shè)備性能有差異,部分實(shí)例所在機(jī)器性能較好,另一些較差,我們希望性能好的機(jī)器承擔(dān)更多的用戶請(qǐng)求。但默認(rèn)情況下NacosRule是同集群內(nèi)隨機(jī)挑選,不會(huì)考慮機(jī)器的性能問題。
因此,Nacos提供了權(quán)重配置來控制訪問頻率,權(quán)重越大則訪問頻率越高。在nacos控制臺(tái),找到user-service的實(shí)例列表,點(diǎn)擊編輯,即可修改權(quán)重:
注意:如果權(quán)重修改為0,則該實(shí)例永遠(yuǎn)不會(huì)被訪問
5.5、環(huán)境隔離
Nacos提供了namespace
來實(shí)現(xiàn)環(huán)境隔離功能。
- nacos中可以有多個(gè)namespace
- namespace下可以有g(shù)roup、service等
- 不同namespace之間相互隔離,例如不同namespace的服務(wù)互相不可見
5.5.1、創(chuàng)建namespace
默認(rèn)情況下,所有service、data、group都在同一個(gè)namespace,名為public:
我們可以點(diǎn)擊頁面新增按鈕,添加一個(gè)namespace:
5.5.2、給微服務(wù)配置namespace
給微服務(wù)配置namespace只能通過修改配置來實(shí)現(xiàn)。例如,修改order-service的application.yml文件:
spring:cloud:nacos:server-addr: localhost:8848discovery:cluster-name: HZnamespace: d494f25a-438d-4927-bdf8-aaa9d3fc0279 # 命名空間,填I(lǐng)D
重啟order-service后,訪問控制臺(tái),可以看到下面的結(jié)果:
order-service在 dev 的命名空間,user-service在 public 命名空間,此時(shí)訪問order-service,因?yàn)閚amespace不同,會(huì)導(dǎo)致找不到userservice,控制臺(tái)會(huì)報(bào)錯(cuò)
5.6、Nacos與Eureka的區(qū)別
Nacos的服務(wù)實(shí)例分為兩種類型:
-
臨時(shí)實(shí)例:如果實(shí)例宕機(jī)超過一定時(shí)間,會(huì)從服務(wù)列表剔除,默認(rèn)的類型。
-
非臨時(shí)實(shí)例:如果實(shí)例宕機(jī),不會(huì)從服務(wù)列表剔除,也可以叫永久實(shí)例。
配置一個(gè)服務(wù)實(shí)例為永久實(shí)例:
spring:cloud:nacos:discovery:ephemeral: false # 設(shè)置為非臨時(shí)實(shí)例
-
Nacos與eureka的共同點(diǎn)
- 都支持服務(wù)注冊(cè)和服務(wù)拉取
- 都支持服務(wù)提供者心跳方式做健康檢測(cè)
-
Nacos與Eureka的區(qū)別
- Nacos支持服務(wù)端主動(dòng)檢測(cè)提供者狀態(tài):臨時(shí)實(shí)例采用心跳模式,非臨時(shí)實(shí)例采用主動(dòng)檢測(cè)模式
- 臨時(shí)實(shí)例心跳不正常會(huì)被剔除,非臨時(shí)實(shí)例則不會(huì)被剔除
- Nacos支持服務(wù)列表變更的消息推送模式,服務(wù)列表更新更及時(shí)
- Nacos集群默認(rèn)采用AP方式,當(dāng)集群中存在非臨時(shí)實(shí)例時(shí),采用CP模式;Eureka采用AP方式