1毯辅、分布式基礎(chǔ)理論
1.1)袄友、什么是分布式系統(tǒng)?
《分布式系統(tǒng)原理與范型》定義:
“分布式系統(tǒng)是若干獨(dú)立計(jì)算機(jī)的集合,這些計(jì)算機(jī)對(duì)于用戶來(lái)說(shuō)就像單個(gè)相關(guān)系統(tǒng)”
分布式系統(tǒng)(distributed system)是建立在網(wǎng)絡(luò)之上的軟件系統(tǒng)父虑。
隨著互聯(lián)網(wǎng)的發(fā)展,網(wǎng)站應(yīng)用的規(guī)模不斷擴(kuò)大方援,常規(guī)的垂直應(yīng)用架構(gòu)已無(wú)法應(yīng)對(duì)黎休,分布式服務(wù)架構(gòu)以及流動(dòng)計(jì)算架構(gòu)勢(shì)在必行,亟需一個(gè)治理系統(tǒng)確保架構(gòu)有條不紊的演進(jìn)乐导。
1.2)苦丁、發(fā)展演變
單一應(yīng)用架構(gòu)
當(dāng)網(wǎng)站流量很小時(shí),只需一個(gè)應(yīng)用物臂,將所有功能都部署在一起旺拉,以減少部署節(jié)點(diǎn)和成本。此時(shí)棵磷,用于簡(jiǎn)化增刪改查工作量的數(shù)據(jù)訪問(wèn)框架(ORM)是關(guān)鍵蛾狗。
適用于小型網(wǎng)站,小型管理系統(tǒng)仪媒,將所有功能都部署到一個(gè)功能里沉桌,簡(jiǎn)單易用。
缺點(diǎn): 1算吩、性能擴(kuò)展比較難
2留凭、協(xié)同開(kāi)發(fā)問(wèn)題
3、不利于升級(jí)維護(hù)
垂直應(yīng)用架構(gòu)
當(dāng)訪問(wèn)量逐漸增大偎巢,單一應(yīng)用增加機(jī)器帶來(lái)的加速度越來(lái)越小蔼夜,將應(yīng)用拆成互不相干的幾個(gè)應(yīng)用,以提升效率压昼。此時(shí)求冷,用于加速前端頁(yè)面開(kāi)發(fā)的Web框架(MVC)是關(guān)鍵。
通過(guò)切分業(yè)務(wù)來(lái)實(shí)現(xiàn)各個(gè)模塊獨(dú)立部署窍霞,降低了維護(hù)和部署的難度匠题,團(tuán)隊(duì)各司其職更易管理,性能擴(kuò)展也更方便但金,更有針對(duì)性韭山。
缺點(diǎn): 公用模塊無(wú)法重復(fù)利用,開(kāi)發(fā)性的浪費(fèi)
分布式服務(wù)架構(gòu)
當(dāng)垂直應(yīng)用越來(lái)越多冷溃,應(yīng)用之間交互不可避免掠哥,將核心業(yè)務(wù)抽取出來(lái),作為獨(dú)立的服務(wù)秃诵,逐漸形成穩(wěn)定的服務(wù)中心续搀,使前端應(yīng)用能更快速的響應(yīng)多變的市場(chǎng)需求。此時(shí)菠净,用于提高業(yè)務(wù)復(fù)用及整合的分布式服務(wù)框架(RPC)是關(guān)鍵禁舷。
流動(dòng)計(jì)算架構(gòu)
當(dāng)服務(wù)越來(lái)越多彪杉,容量的評(píng)估,小服務(wù)資源的浪費(fèi)等問(wèn)題逐漸顯現(xiàn)牵咙,此時(shí)需增加一個(gè)調(diào)度中心基于訪問(wèn)壓力實(shí)時(shí)管理集群容量派近,提高集群利用率。此時(shí)洁桌,用于提高機(jī)器利用率的資源調(diào)度和治理中心****(SOA)****[ Service Oriented Architecture]****是關(guān)鍵渴丸。
1.3)、RPC
什么叫RPC
RPC【Remote Procedure Call】是指遠(yuǎn)程過(guò)程調(diào)用另凌,是一種進(jìn)程間通信方式谱轨,他是一種技術(shù)的思想,而不是規(guī)范吠谢。它允許程序調(diào)用另一個(gè)地址空間(通常是共享網(wǎng)絡(luò)的另一臺(tái)機(jī)器上)的過(guò)程或函數(shù)土童,而不用程序員顯式編碼這個(gè)遠(yuǎn)程調(diào)用的細(xì)節(jié)。即程序員無(wú)論是調(diào)用本地的還是遠(yuǎn)程的函數(shù)工坊,本質(zhì)上編寫(xiě)的調(diào)用代碼基本相同献汗。
RPC基本原理
RPC兩個(gè)核心模塊:通訊,序列化王污。
2罢吃、dubbo核心概念
2.1)、簡(jiǎn)介
Apache Dubbo (incubating) |?d?b??| 是一款高性能昭齐、輕量級(jí)的開(kāi)源Java RPC框架刃麸,它提供了三大核心能力:面向接口的遠(yuǎn)程方法調(diào)用,智能容錯(cuò)和負(fù)載均衡司浪,以及服務(wù)自動(dòng)注冊(cè)和發(fā)現(xiàn)。
官網(wǎng):http://dubbo.apache.org/
2.2)把沼、基本概念
服務(wù)提供者(Provider):暴露服務(wù)的服務(wù)提供方啊易,服務(wù)提供者在啟動(dòng)時(shí),向注冊(cè)中心注冊(cè)自己提供的服務(wù)饮睬。
服務(wù)消費(fèi)者(Consumer): 調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費(fèi)方租谈,服務(wù)消費(fèi)者在啟動(dòng)時(shí),向注冊(cè)中心訂閱自己所需的服務(wù)捆愁,服務(wù)消費(fèi)者割去,從提供者地址列表中,基于軟負(fù)載均衡算法昼丑,選一臺(tái)提供者進(jìn)行調(diào)用呻逆,如果調(diào)用失敗,再選另一臺(tái)調(diào)用菩帝。
注冊(cè)中心(Registry):注冊(cè)中心返回服務(wù)提供者地址列表給消費(fèi)者咖城,如果有變更茬腿,注冊(cè)中心將基于長(zhǎng)連接推送變更數(shù)據(jù)給消費(fèi)者
監(jiān)控中心(Monitor):服務(wù)消費(fèi)者和提供者,在內(nèi)存中累計(jì)調(diào)用次數(shù)和調(diào)用時(shí)間宜雀,定時(shí)每分鐘發(fā)送一次統(tǒng)計(jì)數(shù)據(jù)到監(jiān)控中心
調(diào)用關(guān)系說(shuō)明:
- 服務(wù)容器負(fù)責(zé)啟動(dòng)切平,加載,運(yùn)行服務(wù)提供者辐董。
- 服務(wù)提供者在啟動(dòng)時(shí)悴品,向注冊(cè)中心注冊(cè)自己提供的服務(wù)。
- 服務(wù)消費(fèi)者在啟動(dòng)時(shí)简烘,向注冊(cè)中心訂閱自己所需的服務(wù)苔严。
- 注冊(cè)中心返回服務(wù)提供者地址列表給消費(fèi)者,如果有變更夸研,注冊(cè)中心將基于長(zhǎng)連接推送變更數(shù)據(jù)給消費(fèi)者邦蜜。
- 服務(wù)消費(fèi)者,從提供者地址列表中亥至,基于軟負(fù)載均衡算法悼沈,選一臺(tái)提供者進(jìn)行調(diào)用,如果調(diào)用失敗姐扮,再選另一臺(tái)調(diào)用絮供。
- 服務(wù)消費(fèi)者和提供者,在內(nèi)存中累計(jì)調(diào)用次數(shù)和調(diào)用時(shí)間茶敏,定時(shí)每分鐘發(fā)送一次統(tǒng)計(jì)數(shù)據(jù)到監(jiān)控中心壤靶。
3、dubbo環(huán)境搭建
3.1)惊搏、【windows】-安裝zookeeper
1贮乳、下載zookeeper
網(wǎng)址 https://archive.apache.org/dist/zookeeper/zookeeper-3.4.13/
2、解壓zookeeper
解壓運(yùn)行zkServer.cmd 恬惯,初次運(yùn)行會(huì)報(bào)錯(cuò)向拆,沒(méi)有zoo.cfg配置文件
3、修改zoo.cfg配置文件
將conf下的zoo_sample.cfg復(fù)制一份改名為zoo.cfg即可酪耳。
注意幾個(gè)重要位置:
dataDir=./ 臨時(shí)數(shù)據(jù)存儲(chǔ)的目錄(可寫(xiě)相對(duì)路徑)
clientPort=2181 zookeeper的端口號(hào)
修改完成后再次啟動(dòng)zookeeper
4浓恳、使用zkCli.cmd測(cè)試
ls /:列出zookeeper根下保存的所有節(jié)點(diǎn)
create –e /atguigu 123:創(chuàng)建一個(gè)atguigu節(jié)點(diǎn),值為123
get /atguigu:獲取/atguigu節(jié)點(diǎn)的值
3.2)碗暗、【windows】-安裝dubbo-admin管理控制臺(tái)
dubbo本身并不是一個(gè)服務(wù)軟件颈将。它其實(shí)就是一個(gè)jar包能夠幫你的java程序連接到zookeeper,并利用zookeeper消費(fèi)言疗、提供服務(wù)晴圾。所以你不用在Linux上啟動(dòng)什么dubbo服務(wù)。
但是為了讓用戶更好的管理監(jiān)控眾多的dubbo服務(wù)噪奄,官方提供了一個(gè)可視化的監(jiān)控程序疑务,不過(guò)這個(gè)監(jiān)控即使不裝也不影響使用沾凄。
1、下載dubbo-admin
下載地址:https://github.com/apache/incubator-dubbo-ops
2知允、進(jìn)入目錄撒蟀,修改dubbo-admin配置
修改 src\main\resources\application.properties 指定zookeeper地址
3、打包dubbo-admin
mvn clean package -Dmaven.test.skip=true
4温鸽、運(yùn)行dubbo-admin
java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
注意:【有可能控制臺(tái)看著啟動(dòng)了保屯,但是網(wǎng)頁(yè)打不開(kāi),需要在控制臺(tái)按下ctrl+c即可】
默認(rèn)使用root/root 登陸
3.3)涤垫、【linux】-安裝zookeeper
1姑尺、安裝jdk
1、下載jdk
網(wǎng)址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
不要使用wget命令獲取jdk鏈接蝠猬,這是默認(rèn)不同意切蟋,導(dǎo)致下載來(lái)的jdk壓縮內(nèi)容錯(cuò)誤
2、上傳到服務(wù)器并解壓
3榆芦、設(shè)置環(huán)境變量
/usr/local/java/jdk1.8.0_171
文件末尾加入下面配置
export JAVA_HOME=/usr/local/java/jdk1.8.0_171
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
4柄粹、使環(huán)境變量生效&測(cè)試JDK
2、安裝zookeeper
1匆绣、下載zookeeper
網(wǎng)址 <u>https://archive.apache.org/dist/zookeeper/zookeeper-3.4.11/</u>
wget <u>https://archive.apache.org/dist/zookeeper/zookeeper-3.4.11/zookeeper-3.4.11.tar.gz</u>
2驻右、解壓
3、移動(dòng)到指定位置并改名為zookeeper
3崎淳、開(kāi)機(jī)啟動(dòng)zookeeper
1)-復(fù)制如下腳本
#!/bin/bash
#chkconfig:2345 20 90
#description:zookeeper
#processname:zookeeper
ZK_PATH=/usr/local/zookeeper
export JAVA_HOME=/usr/local/java/jdk1.8.0_171
case $1 in
start) sh $ZK_PATH/bin/zkServer.sh start;;
stop) sh $ZK_PATH/bin/zkServer.sh stop;;
status) sh $ZK_PATH/bin/zkServer.sh status;;
restart) sh $ZK_PATH/bin/zkServer.sh restart;;
*) echo "require start|stop|status|restart" ;;
esac
2)-把腳本注冊(cè)為Service
3)-增加權(quán)限
4堪夭、配置zookeeper
1、初始化zookeeper配置文件
拷貝/usr/local/zookeeper/conf/zoo_sample.cfg
到同一個(gè)目錄下改個(gè)名字叫zoo.cfg
2拣凹、啟動(dòng)zookeeper
3.4)森爽、【linux】-安裝dubbo-admin管理控制臺(tái)
1、安裝Tomcat8(舊版dubbo-admin是war嚣镜,新版是jar不需要安裝Tomcat)
1爬迟、下載Tomcat8并解壓
https://tomcat.apache.org/download-80.cgi](https://tomcat.apache.org/download-80.cgi)
wget: http://mirrors.shu.edu.cn/apache/tomcat/tomcat-8/v8.5.32/bin/apache-tomcat-8.5.32.tar.gz
2、解壓移動(dòng)到指定位置
3祈惶、開(kāi)機(jī)啟動(dòng)tomcat8
#!/bin/bash
#chkconfig:2345 21 90
#description:apache-tomcat-8
#processname:apache-tomcat-8
CATALANA_HOME=/opt/apache-tomcat-8.5.32
export JAVA_HOME=/opt/java/jdk1.8.0_171
case $1 in
start)
echo "Starting Tomcat..."
$CATALANA_HOME/bin/startup.sh
;;
stop)
echo "Stopping Tomcat..."
$CATALANA_HOME/bin/shutdown.sh
;;
restart)
echo "Stopping Tomcat..."
$CATALANA_HOME/bin/shutdown.sh
sleep 2
echo
echo "Starting Tomcat..."
$CATALANA_HOME/bin/startup.sh
;;
*)
echo "Usage: tomcat {start|stop|restart}"
;; esac
4、注冊(cè)服務(wù)&添加權(quán)限
5扮匠、啟動(dòng)服務(wù)&訪問(wèn)tomcat測(cè)試
2捧请、安裝dubbo-admin
dubbo本身并不是一個(gè)服務(wù)軟件。它其實(shí)就是一個(gè)jar包能夠幫你的java程序連接到zookeeper棒搜,并利用zookeeper消費(fèi)疹蛉、提供服務(wù)。所以你不用在Linux上啟動(dòng)什么dubbo服務(wù)力麸。
但是為了讓用戶更好的管理監(jiān)控眾多的dubbo服務(wù)可款,官方提供了一個(gè)可視化的監(jiān)控程序育韩,不過(guò)這個(gè)監(jiān)控即使不裝也不影響使用。
1闺鲸、下載dubbo-admin
網(wǎng)址:https://github.com/apache/incubator-dubbo-ops
2筋讨、進(jìn)入目錄,修改dubbo-admin配置
修改 src\main\resources\application.properties 指定zookeeper地址
3摸恍、打包dubbo-admin
mvn clean package -Dmaven.test.skip=true
4悉罕、運(yùn)行dubbo-admin
java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
默認(rèn)使用root/root 登陸
4、dubbo-helloworld
4.1)立镶、提出需求
某個(gè)電商系統(tǒng)壁袄,訂單服務(wù)需要調(diào)用用戶服務(wù)獲取某個(gè)用戶的所有地址;
我們現(xiàn)在 需要?jiǎng)?chuàng)建兩個(gè)服務(wù)模塊進(jìn)行測(cè)試
模塊功能
模塊 | 功能 |
---|---|
訂單服務(wù)web模塊 | 創(chuàng)建訂單等 |
用戶服務(wù)service模塊 | 查詢用戶地址等 |
測(cè)試預(yù)期結(jié)果:
訂單服務(wù)web模塊在A服務(wù)器媚媒,用戶服務(wù)模塊在B服務(wù)器嗜逻,A可以遠(yuǎn)程調(diào)用B的功能。
4.2)缭召、工程架構(gòu)
根據(jù) dubbo《服務(wù)化最佳實(shí)踐》
1栈顷、分包
建議將服務(wù)接口,服務(wù)模型恼琼,服務(wù)異常等均放在 API 包中妨蛹,因?yàn)榉?wù)模型及異常也是 API 的一部分,同時(shí)晴竞,這樣做也符合分包原則:重用發(fā)布等價(jià)原則(REP)蛙卤,共同重用原則(CRP)。
如果需要噩死,也可以考慮在 API 包中放置一份 spring 的引用配置颤难,這樣使用方,只需在 spring 加載過(guò)程中引用此配置即可已维,配置建議放在模塊的包目錄下行嗤,以免沖突,如:com/alibaba/china/xxx/dubbo-reference.xml垛耳。
2栅屏、粒度
服務(wù)接口盡可能大粒度,每個(gè)服務(wù)方法應(yīng)代表一個(gè)功能堂鲜,而不是某功能的一個(gè)步驟栈雳,否則將面臨分布式事務(wù)問(wèn)題,Dubbo 暫未提供分布式事務(wù)支持。
服務(wù)接口建議以業(yè)務(wù)場(chǎng)景為單位劃分,并對(duì)相近業(yè)務(wù)做抽象营密,防止接口數(shù)量爆炸南缓。
不建議使用過(guò)于抽象的通用接口蛀骇,如:Map query(Map)厌秒,這樣的接口沒(méi)有明確語(yǔ)義,會(huì)給后期維護(hù)帶來(lái)不便擅憔。
4.3)鸵闪、創(chuàng)建模塊
1、gmall-interface:公共接口層(model雕欺,service岛马,exception…)
作用:定義公共接口,也可以導(dǎo)入公共依賴
1屠列、Bean模型
public class UserAddress implements Serializable{
private Integer id;
private String userAddress;
private String userId;
private String consignee;
private String phoneNum;
private String isDefault;
}
3啦逆、Service接口
UserService
public List<UserAddress> getUserAddressList(String userId)
2、gmall-user:用戶模塊(對(duì)用戶接口的實(shí)現(xiàn))
pom.xml
<dependencies>
<dependency>
<groupId>com.atguigu.dubbo</groupId>
<artifactId>gmall-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
2笛洛、Service
public class UserServiceImpl implements UserService {
@Override
public List<UserAddress> getUserAddressList(String userId) {
// TODO Auto-generated method stub
return userAddressDao.getUserAddressById(userId);
}
}
4夏志、gmall-order-web:訂單模塊(調(diào)用用戶模塊)
1、pom.xml
<dependencies>
<dependency>
<groupId>com.atguigu.dubbo</groupId>
<artifactId>gmall-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
2苛让、測(cè)試
public class OrderService {
UserService userService;
/**
* 初始化訂單沟蔑,查詢用戶的所有地址并返回
* @param userId
* @return
*/
public List<UserAddress> initOrder(String userId){
return userService.getUserAddressList(userId);
}
}
4.4)、使用dubbo改造
1狱杰、改造gmall-user作為服務(wù)提供者
1瘦材、引入dubbo
<!-- 引入dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
<!-- 由于我們使用zookeeper作為注冊(cè)中心,所以需要操作zookeeper
dubbo 2.6以前的版本引入zkclient操作zookeeper
dubbo 2.6及以后的版本引入curator操作zookeeper
下面兩個(gè)zk客戶端根據(jù)dubbo版本2選1即可
-->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<!-- curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
2仿畸、配置提供者
<!--當(dāng)前應(yīng)用的名字 -->
<dubbo:application name="gmall-user"></dubbo:application>
<!--指定注冊(cè)中心的地址 -->
<dubbo:registry address="zookeeper://118.24.44.169:2181" />
<!--使用dubbo協(xié)議食棕,將服務(wù)暴露在20880端口 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 指定需要暴露的服務(wù) -->
<dubbo:service interface="com.atguigu.gmall.service.UserService" ref="userServiceImpl" />
3、啟動(dòng)服務(wù)
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("classpath:spring-beans.xml");
System.in.read();
}
2错沽、改造gmall-order-web作為服務(wù)消費(fèi)者
1簿晓、引入dubbo
<!-- 引入dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
<!-- 由于我們使用zookeeper作為注冊(cè)中心,所以需要引入zkclient和curator操作zookeeper -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<!-- curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
2千埃、配置消費(fèi)者信息
<!-- 應(yīng)用名 -->
<dubbo:application name="gmall-order-web"></dubbo:application>
<!-- 指定注冊(cè)中心地址 -->
<dubbo:registry address="zookeeper://118.24.44.169:2181" />
<!-- 生成遠(yuǎn)程服務(wù)代理憔儿,可以和本地bean一樣使用demoService -->
<dubbo:reference id="userService" interface="com.atguigu.gmall.service.UserService"></dubbo:reference>
3、測(cè)試調(diào)用
訪問(wèn)gmall-order-web的initOrder請(qǐng)求放可,會(huì)調(diào)用UserService獲取用戶地址谒臼;
調(diào)用成功。說(shuō)明我們order已經(jīng)可以調(diào)用遠(yuǎn)程的UserService了耀里;
4蜈缤、注解版
1、服務(wù)提供方
<dubbo:application name="gmall-user"></dubbo:application>
<dubbo:registry address="zookeeper://118.24.44.169:2181" />
<dubbo:protocol name="dubbo" port="20880" />
<dubbo:annotation package="com.atguigu.gmall.user.impl"/>
import com.alibaba.dubbo.config.annotation.Service;
import com.atguigu.gmall.bean.UserAddress;
import com.atguigu.gmall.service.UserService;
import com.atguigu.gmall.user.mapper.UserAddressMapper;
@Service //使用dubbo提供的service注解备韧,注冊(cè)暴露服務(wù)
public class UserServiceImpl implements UserService {
@Autowired
UserAddressMapper userAddressMapper;
2劫樟、服務(wù)消費(fèi)方
<dubbo:application name="gmall-order-web"></dubbo:application>
<dubbo:registry address="zookeeper://118.24.44.169:2181" />
<dubbo:annotation package="com.atguigu.gmall.order.controller"/>
@Controller
public class OrderController {
@Reference //使用dubbo提供的reference注解引用遠(yuǎn)程服務(wù)
UserService userService;
5痪枫、監(jiān)控中心
5.1)织堂、dubbo-admin
圖形化的服務(wù)管理頁(yè)面叠艳;安裝時(shí)需要指定注冊(cè)中心地址,即可從注冊(cè)中心中獲取到所有的提供者/消費(fèi)者進(jìn)行配置管理
5.2)易阳、dubbo-monitor-simple
簡(jiǎn)單的監(jiān)控中心附较;
1、安裝
1潦俺、下載 dubbo-ops
**網(wǎng)址:https://github.com/apache/incubator-dubbo-ops **
2拒课、修改配置指定注冊(cè)中心地址
進(jìn)入 dubbo-monitor-simple\src\main\resources\conf
修改 dubbo.properties文件
3、打包dubbo-monitor-simple
mvn clean package -Dmaven.test.skip=true
4事示、解壓 tar.gz 文件早像,并運(yùn)行start.bat
如果缺少servlet-api,自行導(dǎo)入servlet-api再訪問(wèn)監(jiān)控中心
5肖爵、啟動(dòng)訪問(wèn)8080
2卢鹦、監(jiān)控中心配置
所有服務(wù)配置連接監(jiān)控中心,進(jìn)行監(jiān)控統(tǒng)計(jì)
<!-- 監(jiān)控中心協(xié)議劝堪,如果為protocol="registry"冀自,表示從注冊(cè)中心發(fā)現(xiàn)監(jiān)控中心地址,否則直連監(jiān)控中心 -->
<dubbo:monitor protocol=*"registry"*></dubbo:monitor>
Simple Monitor 掛掉不會(huì)影響到 Consumer 和 Provider 之間的調(diào)用秒啦,所以用于生產(chǎn)環(huán)境不會(huì)有風(fēng)險(xiǎn)熬粗。
Simple Monitor 采用磁盤(pán)存儲(chǔ)統(tǒng)計(jì)信息,請(qǐng)注意安裝機(jī)器的磁盤(pán)限制余境,如果要集群驻呐,建議用mount共享磁盤(pán)。
6葛超、整合SpringBoot
1暴氏、引入spring-boot-starter以及dubbo和curator的依賴
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
注意starter版本適配:
2、配置application.properties
提供者配置:
dubbo.application.name=gmall-user
dubbo.registry.protocol=zookeeper
dubbo.registry.address=192.168.67.159:2181
dubbo.scan.base-package=com.atguigu.gmall
dubbo.protocol.name=dubbo
application.name就是服務(wù)名绣张,不能跟別的dubbo提供端重復(fù)
registry.protocol 是指定注冊(cè)中心協(xié)議
registry.address 是注冊(cè)中心的地址加端口號(hào)
protocol.name 是分布式固定是dubbo,不要改答渔。
base-package 注解方式要掃描的包
消費(fèi)者配置:
dubbo.application.name=gmall-order-web
dubbo.registry.protocol=zookeeper
dubbo.registry.address=192.168.67.159:2181
dubbo.scan.base-package=com.atguigu.gmall
dubbo.protocol.name=dubbo
3、dubbo注解
@Service侥涵、@Reference
【如果沒(méi)有在配置中寫(xiě)****dubbo.scan.base-package,****還需要使用****@****EnableDubbo注解****】
1沼撕、配置原則
JVM 啟動(dòng) -D 參數(shù)優(yōu)先,這樣可以使用戶在部署和啟動(dòng)時(shí)進(jìn)行參數(shù)重寫(xiě)芜飘,比如在啟動(dòng)時(shí)需改變協(xié)議的端口务豺。
XML 次之,如果在 XML 中有配置嗦明,則 dubbo.properties 中的相應(yīng)配置項(xiàng)無(wú)效笼沥。
Properties 最后,相當(dāng)于缺省值,只有 XML 沒(méi)有配置時(shí)奔浅,dubbo.properties 的相應(yīng)配置項(xiàng)才會(huì)生效馆纳,通常用于共享公共配置,比如應(yīng)用名汹桦。
2鲁驶、重試次數(shù)
失敗自動(dòng)切換,當(dāng)出現(xiàn)失敗舞骆,重試其它服務(wù)器钥弯,但重試會(huì)帶來(lái)更長(zhǎng)延遲《角荩可通過(guò) retries="2" 來(lái)設(shè)置重試次數(shù)(不含第一次)脆霎。
重試次數(shù)配置如下:
<dubbo:service retries="2" />
或
<dubbo:reference retries="2" />
或
<dubbo:reference>
<dubbo:method name="findFoo" retries="2" />
</dubbo:reference>
3、超時(shí)時(shí)間
由于網(wǎng)絡(luò)或服務(wù)端不可靠狈惫,會(huì)導(dǎo)致調(diào)用出現(xiàn)一種不確定的中間狀態(tài)(超時(shí))绪穆。為了避免超時(shí)導(dǎo)致客戶端資源(線程)掛起耗盡,必須設(shè)置超時(shí)時(shí)間虱岂。
1玖院、Dubbo消費(fèi)端
全局超時(shí)配置
<dubbo:consumer timeout="5000" />
指定接口以及特定方法超時(shí)配置
<dubbo:reference interface="com.foo.BarService" timeout="2000">
<dubbo:method name="sayHello" timeout="3000" />
</dubbo:reference>
2、Dubbo服務(wù)端
全局超時(shí)配置
<dubbo:provider timeout="5000" />
指定接口以及特定方法超時(shí)配置
<dubbo:provider interface="com.foo.BarService" timeout="2000">
<dubbo:method name="sayHello" timeout="3000" />
</dubbo:provider>
3第岖、配置原則
dubbo推薦在Provider上盡量多配置Consumer端屬性:
1难菌、作服務(wù)的提供者,比服務(wù)使用方更清楚服務(wù)性能參數(shù)蔑滓,如調(diào)用的超時(shí)時(shí)間郊酒,合理的重試次數(shù),等等
2键袱、在Provider配置后燎窘,Consumer不配置則會(huì)使用Provider的配置值,即Provider配置可以作為Consumer的缺省值蹄咖。否則褐健,Consumer會(huì)使用Consumer端的全局設(shè)置,這對(duì)于Provider不可控的澜汤,并且往往是不合理的
配置的覆蓋規(guī)則:
- 方法級(jí)配置別優(yōu)于接口級(jí)別蚜迅,即小Scope優(yōu)先
- Consumer端配置 優(yōu)于 Provider配置 優(yōu)于 全局配置,
- 最后是Dubbo Hard Code的配置值(見(jiàn)配置文檔)
4俊抵、版本號(hào)
當(dāng)一個(gè)接口實(shí)現(xiàn)谁不,出現(xiàn)不兼容升級(jí)時(shí),可以用版本號(hào)過(guò)渡徽诲,版本號(hào)不同的服務(wù)相互間不引用刹帕。
可以按照以下的步驟進(jìn)行版本遷移:
在低壓力時(shí)間段吵血,先升級(jí)一半提供者為新版本
再將所有消費(fèi)者升級(jí)為新版本
然后將剩下的一半提供者升級(jí)為新版本
老版本服務(wù)提供者配置:
<dubbo:service interface="com.foo.BarService" version="1.0.0" />
新版本服務(wù)提供者配置:
<dubbo:service interface="com.foo.BarService" version="2.0.0" />
老版本服務(wù)消費(fèi)者配置:
<dubbo:reference id="barService" interface="com.foo.BarService" version="1.0.0" />
新版本服務(wù)消費(fèi)者配置:
<dubbo:reference id="barService" interface="com.foo.BarService" version="2.0.0" />
如果不需要區(qū)分版本,可以按照以下的方式配置:
<dubbo:reference id="barService" interface="com.foo.BarService" version="*" />
三偷溺、高可用
1践瓷、zookeeper宕機(jī)與dubbo直連
現(xiàn)象:zookeeper注冊(cè)中心宕機(jī),還可以消費(fèi)dubbo暴露的服務(wù)亡蓉。
原因:
健壯性
- 監(jiān)控中心宕掉不影響使用,只是丟失部分采樣數(shù)據(jù)
- 數(shù)據(jù)庫(kù)宕掉后喷舀,注冊(cè)中心仍能通過(guò)緩存提供服務(wù)列表查詢砍濒,但不能注冊(cè)新服務(wù)
- 注冊(cè)中心對(duì)等集群,任意一臺(tái)宕掉后硫麻,將自動(dòng)切換到另一臺(tái)
- 注冊(cè)中心全部宕掉后爸邢,服務(wù)提供者和服務(wù)消費(fèi)者仍能通過(guò)本地緩存通訊
- 服務(wù)提供者無(wú)狀態(tài),任意一臺(tái)宕掉后拿愧,不影響使用
- 服務(wù)提供者全部宕掉后杠河,服務(wù)消費(fèi)者應(yīng)用將無(wú)法使用,并無(wú)限次重連等待服務(wù)提供者恢復(fù)
高可用:通過(guò)設(shè)計(jì)浇辜,減少系統(tǒng)不能提供服務(wù)的時(shí)間券敌;
2、集群下dubbo負(fù)載均衡配置
在集群負(fù)載均衡時(shí)柳洋,Dubbo 提供了多種均衡策略待诅,缺省為 random 隨機(jī)調(diào)用。
負(fù)載均衡策略
Random LoadBalance
隨機(jī)熊镣,按權(quán)重設(shè)置隨機(jī)概率卑雁。
在一個(gè)截面上碰撞的概率高,但調(diào)用量越大分布越均勻绪囱,而且按概率使用權(quán)重后也比較均勻测蹲,有利于動(dòng)態(tài)調(diào)整提供者權(quán)重。
RoundRobin LoadBalance
輪循鬼吵,按公約后的權(quán)重設(shè)置輪循比率扣甲。
存在慢的提供者累積請(qǐng)求的問(wèn)題,比如:第二臺(tái)機(jī)器很慢齿椅,但沒(méi)掛文捶,當(dāng)請(qǐng)求調(diào)到第二臺(tái)時(shí)就卡在那,久而久之媒咳,所有請(qǐng)求都卡在調(diào)到第二臺(tái)上粹排。
LeastActive LoadBalance
最少活躍調(diào)用數(shù),相同活躍數(shù)的隨機(jī)涩澡,活躍數(shù)指調(diào)用前后計(jì)數(shù)差顽耳。
使慢的提供者收到更少請(qǐng)求,因?yàn)樵铰奶峁┱叩恼{(diào)用前后計(jì)數(shù)差會(huì)越大。
ConsistentHash LoadBalance
一致性 Hash射富,相同參數(shù)的請(qǐng)求總是發(fā)到同一提供者膝迎。
當(dāng)某一臺(tái)提供者掛時(shí),原本發(fā)往該提供者的請(qǐng)求胰耗,基于虛擬節(jié)點(diǎn)限次,平攤到其它提供者,不會(huì)引起劇烈變動(dòng)柴灯。算法參見(jiàn):http://en.wikipedia.org/wiki/Consistent_hashing
缺省只對(duì)第一個(gè)參數(shù) Hash卖漫,如果要修改,請(qǐng)配置 <dubbo:parameter key="hash.arguments" value="0,1" />
缺省用 160 份虛擬節(jié)點(diǎn)赠群,如果要修改羊始,請(qǐng)配置 <dubbo:parameter key="hash.nodes" value="320" />
3、整合hystrix查描,服務(wù)熔斷與降級(jí)處理
1突委、服務(wù)降級(jí)
什么是服務(wù)降級(jí)?
當(dāng)服務(wù)器壓力劇增的情況下冬三,根據(jù)實(shí)際業(yè)務(wù)情況及流量匀油,對(duì)一些服務(wù)和頁(yè)面有策略的不處理或換種簡(jiǎn)單的方式處理,從而釋放服務(wù)器資源以保證核心交易正常運(yùn)作或高效運(yùn)作勾笆。
可以通過(guò)服務(wù)降級(jí)功能臨時(shí)屏蔽某個(gè)出錯(cuò)的非關(guān)鍵服務(wù)钧唐,并定義降級(jí)后的返回策略。
向注冊(cè)中心寫(xiě)入動(dòng)態(tài)配置覆蓋規(guī)則:
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null"));
其中:
- mock=force:return+null 表示消費(fèi)方對(duì)該服務(wù)的方法調(diào)用都直接返回 null 值匠襟,不發(fā)起遠(yuǎn)程調(diào)用钝侠。用來(lái)屏蔽不重要服務(wù)不可用時(shí)對(duì)調(diào)用方的影響。
- 還可以改為 mock=fail:return+null 表示消費(fèi)方對(duì)該服務(wù)的方法調(diào)用在失敗后酸舍,再返回 null 值帅韧,不拋異常。用來(lái)容忍不重要服務(wù)不穩(wěn)定時(shí)對(duì)調(diào)用方的影響啃勉。
2忽舟、集群容錯(cuò)
在集群調(diào)用失敗時(shí),Dubbo 提供了多種容錯(cuò)方案淮阐,缺省為 failover 重試叮阅。
集群容錯(cuò)模式
Failover Cluster
失敗自動(dòng)切換,當(dāng)出現(xiàn)失敗泣特,重試其它服務(wù)器浩姥。通常用于讀操作,但重試會(huì)帶來(lái)更長(zhǎng)延遲状您±盏可通過(guò) retries="2" 來(lái)設(shè)置重試次數(shù)(不含第一次)兜挨。
重試次數(shù)配置如下:
<dubbo:service retries="2" />
或
<dubbo:reference retries="2" />
或
<dubbo:reference>
<dubbo:method name="findFoo" retries="2" />
</dubbo:reference>
Failfast Cluster
快速失敗,只發(fā)起一次調(diào)用眯分,失敗立即報(bào)錯(cuò)拌汇。通常用于非冪等性的寫(xiě)操作,比如新增記錄弊决。
Failsafe Cluster
失敗安全噪舀,出現(xiàn)異常時(shí),直接忽略飘诗。通常用于寫(xiě)入審計(jì)日志等操作与倡。
Failback Cluster
失敗自動(dòng)恢復(fù),后臺(tái)記錄失敗請(qǐng)求疚察,定時(shí)重發(fā)。通常用于消息通知操作仇奶。
Forking Cluster
并行調(diào)用多個(gè)服務(wù)器貌嫡,只要一個(gè)成功即返回。通常用于實(shí)時(shí)性要求較高的讀操作该溯,但需要浪費(fèi)更多服務(wù)資源岛抄。可通過(guò) forks="2" 來(lái)設(shè)置最大并行數(shù)狈茉。
Broadcast Cluster
廣播調(diào)用所有提供者夫椭,逐個(gè)調(diào)用,任意一臺(tái)報(bào)錯(cuò)則報(bào)錯(cuò) [2]氯庆。通常用于通知所有提供者更新緩存或日志等本地資源信息蹭秋。
集群模式配置
按照以下示例在服務(wù)提供方和消費(fèi)方配置集群模式
<dubbo:service cluster="failsafe" />
或
<dubbo:reference cluster="failsafe" />
3、整合hystrix
Hystrix 旨在通過(guò)控制那些訪問(wèn)遠(yuǎn)程系統(tǒng)堤撵、服務(wù)和第三方庫(kù)的節(jié)點(diǎn)仁讨,從而對(duì)延遲和故障提供更強(qiáng)大的容錯(cuò)能力。Hystrix具備擁有回退機(jī)制和斷路器功能的線程和信號(hào)隔離实昨,請(qǐng)求緩存和請(qǐng)求打包洞豁,以及監(jiān)控和配置等功能
1、配置spring-cloud-starter-netflix-hystrix
spring boot官方提供了對(duì)hystrix的集成荒给,直接在pom.xml里加入依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
然后在Application類上增加@EnableHystrix來(lái)啟用hystrix starter:
@SpringBootApplication
@EnableHystrix
public class ProviderApplication {
2丈挟、配置Provider端
在Dubbo的Provider上增加@HystrixCommand配置,這樣子調(diào)用就會(huì)經(jīng)過(guò)Hystrix代理志电。
@Service(version = "1.0.0")
public class HelloServiceImpl implements HelloService {
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000") })
@Override
public String sayHello(String name) {
// System.out.println("async provider received: " + name);
// return "annotation: hello, " + name;
throw new RuntimeException("Exception to show hystrix enabled.");
}
}
3曙咽、配置Consumer端
對(duì)于Consumer端,則可以增加一層method調(diào)用挑辆,并在method上配置@HystrixCommand桐绒。當(dāng)調(diào)用出錯(cuò)時(shí)夺脾,會(huì)走到fallbackMethod = "reliable"的調(diào)用里。
@Reference(version = "1.0.0")
private HelloService demoService;
@HystrixCommand(fallbackMethod = "reliable")
public String doSayHello(String name) {
return demoService.sayHello(name);
}
public String reliable(String name) {
return "hystrix fallback value";
}
四茉继、dubbo原理
1咧叭、RPC原理
一次完整的RPC調(diào)用流程(同步調(diào)用,異步另說(shuō))如下:
1)服務(wù)消費(fèi)方(client)調(diào)用以本地調(diào)用方式調(diào)用服務(wù)烁竭;
2)client stub接收到調(diào)用后負(fù)責(zé)將方法菲茬、參數(shù)等組裝成能夠進(jìn)行網(wǎng)絡(luò)傳輸?shù)南Ⅲw;
3)client stub找到服務(wù)地址派撕,并將消息發(fā)送到服務(wù)端婉弹;
4)server stub收到消息后進(jìn)行解碼;
5)server stub根據(jù)解碼結(jié)果調(diào)用本地的服務(wù)终吼;
6)本地服務(wù)執(zhí)行并將結(jié)果返回給server stub镀赌;
7)server stub將返回結(jié)果打包成消息并發(fā)送至消費(fèi)方;
8)client stub接收到消息际跪,并進(jìn)行解碼商佛;
9)服務(wù)消費(fèi)方得到最終結(jié)果救巷。
RPC框架的目標(biāo)就是要2~8這些步驟都封裝起來(lái)摆尝,這些細(xì)節(jié)對(duì)用戶來(lái)說(shuō)是透明的,不可見(jiàn)的遭居。
|
2幔戏、netty通信原理
Netty是一個(gè)異步事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架玛追, 用于快速開(kāi)發(fā)可維護(hù)的高性能協(xié)議服務(wù)器和客戶端。它極大地簡(jiǎn)化并簡(jiǎn)化了TCP和UDP套接字服務(wù)器等網(wǎng)絡(luò)編程闲延。
BIO:(Blocking IO)
NIO (Non-Blocking IO)
Selector 一般稱 為選擇器痊剖,也可以翻譯為 多路復(fù)用器,
Connect(連接就緒)垒玲、Accept(接受就緒)邢笙、Read(讀就緒)、Write(寫(xiě)就緒)
Netty基本原理:
3侍匙、dubbo原理
1氮惯、dubbo原理 -框架設(shè)計(jì)
config 配置層:對(duì)外配置接口,以 ServiceConfig, ReferenceConfig 為中心想暗,可以直接初始化配置類妇汗,也可以通過(guò) spring 解析配置生成配置類
proxy 服務(wù)代理層:服務(wù)接口透明代理,生成服務(wù)的客戶端 Stub 和服務(wù)器端 Skeleton, 以 ServiceProxy 為中心说莫,擴(kuò)展接口為 ProxyFactory
registry 注冊(cè)中心層:封裝服務(wù)地址的注冊(cè)與發(fā)現(xiàn)杨箭,以服務(wù) URL 為中心,擴(kuò)展接口為 RegistryFactory, Registry, RegistryService
cluster 路由層:封裝多個(gè)提供者的路由及負(fù)載均衡储狭,并橋接注冊(cè)中心互婿,以 Invoker 為中心捣郊,擴(kuò)展接口為 Cluster, Directory, Router, LoadBalance
monitor 監(jiān)控層:RPC 調(diào)用次數(shù)和調(diào)用時(shí)間監(jiān)控,以 Statistics 為中心慈参,擴(kuò)展接口為 MonitorFactory, Monitor, MonitorService
protocol 遠(yuǎn)程調(diào)用層:封裝 RPC 調(diào)用呛牲,以 Invocation, Result 為中心,擴(kuò)展接口為 Protocol, Invoker, Exporter
exchange 信息交換層:封裝請(qǐng)求響應(yīng)模式驮配,同步轉(zhuǎn)異步娘扩,以 Request, Response 為中心,擴(kuò)展接口為 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer
transport 網(wǎng)絡(luò)傳輸層:抽象 mina 和 netty 為統(tǒng)一接口壮锻,以 Message 為中心琐旁,擴(kuò)展接口為 Channel, Transporter, Client, Server, Codec
serialize 數(shù)據(jù)序列化層:可復(fù)用的一些工具,擴(kuò)展接口為 Serialization, ObjectInput, ObjectOutput, ThreadPool