分布式理論什么是分布式系統(tǒng)? 在《分布式系統(tǒng)原理與范型》一書中有如下定義:“分布式系統(tǒng)是若干獨(dú)立計(jì)算機(jī)的集合,,這些計(jì)算機(jī)對于用戶來說就像單個相關(guān)系統(tǒng)”; 分布式系統(tǒng)是由一組通過網(wǎng)絡(luò)進(jìn)行通信,、為了完成共同的任務(wù)而協(xié)調(diào)工作的計(jì)算機(jī)節(jié)點(diǎn)組成的系統(tǒng)。分布式系統(tǒng)的出現(xiàn)是為了用廉價的,、普通的機(jī)器完成單個計(jì)算機(jī)無法完成的計(jì)算、存儲任務(wù),。其目的是利用更多的機(jī)器,,處理更多的數(shù)據(jù)。 分布式系統(tǒng)(distributed system)是建立在網(wǎng)絡(luò)之上的軟件系統(tǒng),。 首先需要明確的是,,只有當(dāng)單個節(jié)點(diǎn)的處理能力無法滿足日益增長的計(jì)算、存儲任務(wù)的時候,,且硬件的提升(加內(nèi)存,、加磁盤、使用更好的CPU)高昂到得不償失的時候,,應(yīng)用程序也不能進(jìn)一步優(yōu)化的時候,,我們才需要考慮分布式系統(tǒng)。因?yàn)?,分布式系統(tǒng)要解決的問題本身就是和單機(jī)系統(tǒng)一樣的,,而由于分布式系統(tǒng)多節(jié)點(diǎn)、通過網(wǎng)絡(luò)通信的拓?fù)浣Y(jié)構(gòu),,會引入很多單機(jī)系統(tǒng)沒有的問題,,為了解決這些問題又會引入更多的機(jī)制、協(xié)議,,帶來更多的問題,。。,。 Dubbo文檔 隨著互聯(lián)網(wǎng)的發(fā)展,,網(wǎng)站應(yīng)用的規(guī)模不斷擴(kuò)大,常規(guī)的垂直應(yīng)用架構(gòu)已無法應(yīng)對,,分布式服務(wù)架構(gòu)以及流動計(jì)算架構(gòu)勢在必行,,急需一個治理系統(tǒng)確保架構(gòu)有條不紊的演進(jìn)。 在Dubbo的官網(wǎng)文檔有這樣一張圖 單一應(yīng)用架構(gòu) 當(dāng)網(wǎng)站流量很小時,,只需一個應(yīng)用,,將所有功能都部署在一起,以減少部署節(jié)點(diǎn)和成本,。此時,,用于簡化增刪改查工作量的數(shù)據(jù)訪問框架(ORM)是關(guān)鍵。 適用于小型網(wǎng)站,,小型管理系統(tǒng),,將所有功能都部署到一個功能里,簡單易用。 缺點(diǎn): 1,、性能擴(kuò)展比較難 2,、協(xié)同開發(fā)問題 3、不利于升級維護(hù) 垂直應(yīng)用架構(gòu) 當(dāng)訪問量逐漸增大,,單一應(yīng)用增加機(jī)器帶來的加速度越來越小,,將應(yīng)用拆成互不相干的幾個應(yīng)用,以提升效率,。此時,,用于加速前端頁面開發(fā)的Web框架(MVC)是關(guān)鍵。 通過切分業(yè)務(wù)來實(shí)現(xiàn)各個模塊獨(dú)立部署,,降低了維護(hù)和部署的難度,,團(tuán)隊(duì)各司其職更易管理,性能擴(kuò)展也更方便,,更有針對性,。 缺點(diǎn): 公用模塊無法重復(fù)利用,開發(fā)性的浪費(fèi) 分布式服務(wù)架構(gòu) 當(dāng)垂直應(yīng)用越來越多,,應(yīng)用之間交互不可避免,,將核心業(yè)務(wù)抽取出來,作為獨(dú)立的服務(wù),,逐漸形成穩(wěn)定的服務(wù)中心,,使前端應(yīng)用能更快速的響應(yīng)多變的市場需求。此時,,用于提高業(yè)務(wù)復(fù)用及整合的分布式服務(wù)框架(RPC)是關(guān)鍵,。 流動計(jì)算架構(gòu) 當(dāng)服務(wù)越來越多,容量的評估,,小服務(wù)資源的浪費(fèi)等問題逐漸顯現(xiàn),,此時需增加一個調(diào)度中心基于訪問壓力實(shí)時管理集群容量,提高集群利用率,。此時,,用于提高機(jī)器利用率的資源調(diào)度和治理中心(SOA)[ Service Oriented Architecture]是關(guān)鍵。 RPC什么是RPC,? RPC【Remote Procedure Call】是指遠(yuǎn)程過程調(diào)用,,是一種進(jìn)程間通信方式,他是一種技術(shù)的思想,,而不是規(guī)范,。它允許程序調(diào)用另一個地址空間(通常是共享網(wǎng)絡(luò)的另一臺機(jī)器上)的過程或函數(shù),而不用程序員顯式編碼這個遠(yuǎn)程調(diào)用的細(xì)節(jié),。即程序員無論是調(diào)用本地的還是遠(yuǎn)程的函數(shù),,本質(zhì)上編寫的調(diào)用代碼基本相同,。 也就是說兩臺服務(wù)器A,B,,一個應(yīng)用部署在A服務(wù)器上,,想要調(diào)用B服務(wù)器上應(yīng)用提供的函數(shù)/方法,由于不在一個內(nèi)存空間,,不能直接調(diào)用,,需要通過網(wǎng)絡(luò)來表達(dá)調(diào)用的語義和傳達(dá)調(diào)用的數(shù)據(jù)。為什么要用RPC呢,?就是無法在一個進(jìn)程內(nèi),甚至一個計(jì)算機(jī)內(nèi)通過本地調(diào)用的方式完成的需求,,比如不同的系統(tǒng)間的通訊,,甚至不同的組織間的通訊,由于計(jì)算能力需要橫向擴(kuò)展,,需要在多臺機(jī)器組成的集群上部署應(yīng)用,。RPC就是要像調(diào)用本地的函數(shù)一樣去調(diào)遠(yuǎn)程函數(shù); 推薦閱讀文章:https://www.jianshu.com/p/2accc2840a1b RPC基本原理 步驟解析:
RPC兩個核心模塊:通訊,,序列化,。 Dubbo概念什么是dubbo? Apache Dubbo |?d?b??| 是一款高性能,、輕量級的開源Java RPC框架,,它提供了三大核心能力:面向接口的遠(yuǎn)程方法調(diào)用,智能容錯和負(fù)載均衡,,以及服務(wù)自動注冊和發(fā)現(xiàn),。 1.了解Dubbo的特性 2.查看官方文檔 dubbo基本概念 服務(wù)提供者(Provider):暴露服務(wù)的服務(wù)提供方,服務(wù)提供者在啟動時,,向注冊中心注冊自己提供的服務(wù),。 服務(wù)消費(fèi)者(Consumer): 調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費(fèi)方,服務(wù)消費(fèi)者在啟動時,,向注冊中心訂閱自己所需的服務(wù),,服務(wù)消費(fèi)者,從提供者地址列表中,,基于軟負(fù)載均衡算法,,選一臺提供者進(jìn)行調(diào)用,如果調(diào)用失敗,,再選另一臺調(diào)用,。 注冊中心(Registry):注冊中心返回服務(wù)提供者地址列表給消費(fèi)者,如果有變更,,注冊中心將基于長連接推送變更數(shù)據(jù)給消費(fèi)者 監(jiān)控中心(Monitor):服務(wù)消費(fèi)者和提供者,,在內(nèi)存中累計(jì)調(diào)用次數(shù)和調(diào)用時間,定時每分鐘發(fā)送一次統(tǒng)計(jì)數(shù)據(jù)到監(jiān)控中心 調(diào)用關(guān)系說明 l 服務(wù)容器負(fù)責(zé)啟動,加載,,運(yùn)行服務(wù)提供者,。 l 服務(wù)提供者在啟動時,向注冊中心注冊自己提供的服務(wù),。 l 服務(wù)消費(fèi)者在啟動時,,向注冊中心訂閱自己所需的服務(wù)。 l 注冊中心返回服務(wù)提供者地址列表給消費(fèi)者,,如果有變更,,注冊中心將基于長連接推送變更數(shù)據(jù)給消費(fèi)者。 l 服務(wù)消費(fèi)者,,從提供者地址列表中,,基于軟負(fù)載均衡算法,選一臺提供者進(jìn)行調(diào)用,,如果調(diào)用失敗,,再選另一臺調(diào)用。 l 服務(wù)消費(fèi)者和提供者,,在內(nèi)存中累計(jì)調(diào)用次數(shù)和調(diào)用時間,,定時每分鐘發(fā)送一次統(tǒng)計(jì)數(shù)據(jù)到監(jiān)控中心。 Dubbo環(huán)境搭建點(diǎn)進(jìn)dubbo官方文檔,,推薦我們使用Zookeeper 注冊中心 什么是zookeeper呢,?可以查看官方文檔 window下安裝zookeeper1. 下載zookeeper :地址, 我們下載3.4.14 ,, 最新版,! 解壓zookeeper 2. 運(yùn)行/bin/zkServer.cmd ,初次運(yùn)行會報(bào)錯,,沒有zoo.cfg配置文件,; 可能遇到問題:閃退 ! 解決方案:編輯zkServer.cmd文件末尾添加 3. 修改zoo.cfg配置文件 將conf文件夾下面的zoo_sample.cfg復(fù)制一份改名為zoo.cfg即可,。 注意幾個重要位置: dataDir=./ 臨時數(shù)據(jù)存儲的目錄(可寫相對路徑) clientPort=2181 zookeeper的端口號 修改完成后再次啟動zookeeper 4.使用zkCli.cmd測試 ls /:列出zookeeper根下保存的所有節(jié)點(diǎn) [zk: 127.0.0.1:2181(CONNECTED) 4] ls / [zookeeper] create –e /kuangshen 123:創(chuàng)建一個kuangshen節(jié)點(diǎn),,值為123
get /kuangshen:獲取/kuangshen節(jié)點(diǎn)的值 我們再來查看一下節(jié)點(diǎn) window下安裝dubbo-admindubbo本身并不是一個服務(wù)軟件。它其實(shí)就是一個jar包,,能夠幫你的java程序連接到zookeeper,,并利用zookeeper消費(fèi)、提供服務(wù),。 但是為了讓用戶更好的管理監(jiān)控眾多的dubbo服務(wù),,官方提供了一個可視化的監(jiān)控程序dubbo-admin,,不過這個監(jiān)控即使不裝也不影響使用。 我們這里來安裝一下: 1. 下載dubbo-admin 地址 :https://github.com/apache/dubbo-admin/tree/master 2,、解壓進(jìn)入目錄 修改 dubbo-admin\src\main\resources \application.properties 指定zookeeper地址 server.port=7001spring.velocity.cache=falsespring.velocity.charset=UTF-8spring.velocity.layout-url=/templates/default.vm spring.messages.fallback-to-system-locale=falsespring.messages.basename=i18n/message spring.root.password=root spring.guest.password=guest dubbo.registry.address=zookeeper://127.0.0.1:2181 3.在項(xiàng)目目錄下打包dubbo-admin mvn clean package -Dmaven.test.skip=true 第一次打包的過程有點(diǎn)慢,,需要耐心等待!直到成功,! 4. 執(zhí)行 dubbo-admin\target 下的dubbo-admin-0.0.1-SNAPSHOT.jar java -jar dubbo-admin-0.0.1-SNAPSHOT.jar 【注意:zookeeper的服務(wù)一定要打開,!】 執(zhí)行完畢,我們?nèi)ピL問一下 http://localhost:7001/ ,, 這時候我們需要輸入登錄賬戶和密碼,,我們都是默認(rèn)的root-root; 登錄成功后,,查看界面 安裝完成,! SpringBoot + Dubbo + zookeeper框架搭建1. 啟動zookeeper ! 2. IDEA創(chuàng)建一個空項(xiàng)目,; 3.創(chuàng)建一個模塊,實(shí)現(xiàn)服務(wù)提供者:provider-server ,, 選擇web依賴即可 4.項(xiàng)目創(chuàng)建完畢,,我們寫一個服務(wù),比如賣票的服務(wù),; 編寫接口 package com.kuang.provider.service;public interface TicketService {public String getTicket(); } 編寫實(shí)現(xiàn)類 package com.kuang.provider.service;public class TicketServiceImpl implements TicketService { @Overridepublic String getTicket() {return "《狂神說Java》"; } } 5.創(chuàng)建一個模塊,,實(shí)現(xiàn)服務(wù)消費(fèi)者:consumer-server , 選擇web依賴即可 6.項(xiàng)目創(chuàng)建完畢,,我們寫一個服務(wù),,比如用戶的服務(wù); 編寫service package com.kuang.consumer.service;public class UserService {//我們需要去拿去注冊中心的服務(wù)} 需求:現(xiàn)在我們的用戶想使用買票的服務(wù),,這要怎么弄呢 ,? 服務(wù)提供者1. 將服務(wù)提供者注冊到注冊中心,我們需要整合Dubbo和zookeeper,,所以需要導(dǎo)包 我們從dubbo官網(wǎng)進(jìn)入github,,看下方的幫助文檔,找到dubbo-springboot,,找到依賴包 <!-- Dubbo Spring Boot Starter --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.7.3</version></dependency> zookeeper的包我們?nèi)aven倉庫下載,,zkclient; <!-- https:///artifact/com.github.sgroschupf/zkclient --><dependency><groupId>com.github.sgroschupf</groupId><artifactId>zkclient</artifactId><version>0.1</version></dependency> 【新版的坑】zookeeper及其依賴包,,解決日志沖突,,還需要剔除日志依賴; <!-- 引入zookeeper --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>2.12.0</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>2.12.0</version></dependency><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.14</version><!--排除這個slf4j-log4j12--><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency> 2. 在springboot配置文件中配置dubbo相關(guān)屬性,! #當(dāng)前應(yīng)用名字 dubbo.application.name=provider-server #注冊中心地址 dubbo.registry.address=zookeeper://127.0.0.1:2181 #掃描指定包下服務(wù) dubbo.scan.base-packages=com.kuang.provider.service 3. 在service的實(shí)現(xiàn)類中配置服務(wù)注解,,發(fā)布服務(wù),!注意導(dǎo)包問題 import org.apache.dubbo.config.annotation.Service;import org.springframework.stereotype.Component; @Service //將服務(wù)發(fā)布出去@Component //放在容器中public class TicketServiceImpl implements TicketService { @Overridepublic String getTicket() {return "《狂神說Java》"; } } 邏輯理解 : 應(yīng)用啟動起來,dubbo就會掃描指定的包下帶有@component注解的服務(wù),,將它發(fā)布在指定的注冊中心中,! 消費(fèi)者1.導(dǎo)入依賴,和之前的依賴一樣,; <!--dubbo--><!-- Dubbo Spring Boot Starter --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.7.3</version></dependency><!--zookeeper--><!-- https:///artifact/com.github.sgroschupf/zkclient --><dependency><groupId>com.github.sgroschupf</groupId><artifactId>zkclient</artifactId><version>0.1</version></dependency><!-- 引入zookeeper --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>2.12.0</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>2.12.0</version></dependency><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.14</version><!--排除這個slf4j-log4j12--><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency> 2.配置參數(shù) #當(dāng)前應(yīng)用名字 dubbo.application.name=consumer-server #注冊中心地址 dubbo.registry.address=zookeeper://127.0.0.1:2181 3. 本來正常步驟是需要將服務(wù)提供者的接口打包,,然后用pom文件導(dǎo)入,我們這里使用簡單的方式,,直接將服務(wù)的接口拿過來,,路徑必須保證正確,即和服務(wù)提供者相同,; 4. 完善消費(fèi)者的服務(wù)類 package com.kuang.consumer.service;import com.kuang.provider.service.TicketService;import org.apache.dubbo.config.annotation.Reference;import org.springframework.stereotype.Service; @Service //注入到容器中public class UserService { @Reference //遠(yuǎn)程引用指定的服務(wù),,他會按照全類名進(jìn)行匹配,看誰給注冊中心注冊了這個全類名TicketService ticketService;public void bugTicket(){ String ticket = ticketService.getTicket(); System.out.println("在注冊中心買到"+ticket); } } 5. 測試類編寫,; @RunWith(SpringRunner.class) @SpringBootTestpublic class ConsumerServerApplicationTests { @Autowired UserService userService; @Testpublic void contextLoads() { userService.bugTicket(); } } 啟動測試1. 開啟zookeeper 2. 打開dubbo-admin實(shí)現(xiàn)監(jiān)控【可以不用做】 3. 開啟服務(wù)者 4. 消費(fèi)者消費(fèi)測試,,結(jié)果: 監(jiān)控中心 : ok , 這就是SpingBoot + dubbo + zookeeper實(shí)現(xiàn)分布式開發(fā); |
|