文章目錄
- 前提知識概要
- 分布式系統
- 單體架構
- 垂直應用架構
- 分布式架構
- 流式架構
- RPC
- Dubbo
- 概念
- Dubbo環境搭建
- Zookeeper
- 測試 Zookeeper
- Window環境下使用Dubbo-admin
- 版本匹配不對
- 服務注冊實戰
- 內容總結
- 導入相關依賴
- 選擇 Zookeeper 版本
- 配置并啟用 Zookeeper
- 創建服務接口和實現(DubboService)類,這里是配置`Provider`
- 啟動Dubbo的掃描(EnableDubbo)
- 重復上述操作,將需要注冊Dubbo的配置下
- 編寫Service,這次是消費者,調用提供者所提供的內容
前提知識概要
分布式系統
- “分布式系統是若干獨立計算機的集合,這些計算機對于用戶來說就像單個相關系統”;
- 其目的是利用更多的機器,處理更多的數據。
- 用小而多,代替大且貴
- 只有當單個節點的處理能力無法滿足日益增長的計算、存儲任務的時候,且硬件的提升(加內存、加磁盤、使用更好的CPU)高昂到得不償失的時候,應用程序也不能進一步優化的時候,我們才需要考慮分布式系統;
- 分布式系統要解決的問題本身就是和單機系統一樣的,而由于分布式系統多節點、通過網絡通信的拓撲結構,會引入很多單機系統沒有的問題,為了解決這些問題又會引入更多的機制、協議,帶來更多的問題;
- 但是 缺點也在于這里 過分的依賴于 網絡通信協議;
單體架構
網絡吞吐量小時,使用一個應用(application),將所有的功能都部署在一起,以減少部署的節點和成本。為此簡化CRUD的數據訪問框架ORM就是關鍵。
ORM:Mybatis、Hibernate
使用場景:小型網站,將所有功能都部署到一個地方,簡單,易用
缺點:
- 性能擴展比較難
- 協同開發問題
- 不利于升級維護
垂直應用架構
數據吞吐量打的時候,單一的應用會增加機器所在壓力,將應用的幾塊拆成互不相干的幾個應用以提升效率。這個時候加速前端頁面開發的WEB框架又是關鍵:
WEB框架:MVC,MVVM
通過切分業務 來實現各個模塊的獨立部署,降低了維護和部署的難度,團隊各司其職更易管理,性能拓展也更加的方便,更有針對性。
缺點:
- 公用的模塊無法重復利用;
- 多重復寫功能導致資源浪費;
分布式架構
當垂直的應用越來越多,應用之間的交互不可避免,就去優化垂直應用架構;
將核心的業務提取,成為獨立的服務,逐步形成穩定的服務中心,是前段更好的應用市場。
提高業務服用整合的**分布式框架 **又是關鍵。
分布式框架:RPC
流式架構
當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,這個時候有需要一個調度中心,能夠將有限的資源得到最大的利用, 這時候,用于提高機器利用率的資源調度又成為了重點
提高機器利用率的資源調度和治理中心(SOA)[Service Oriented Architecture]是關鍵
RPC
RPC【Remote Procedure Call】是指遠程過程調用,是一只進程思想,而不是一種規范,類似于我們的。
允許程序調用另一個地址空間。(通常是共享網絡的另一臺機器上)的過程或函數,而不用程序員顯式編碼這個遠程調用的細節。
兩臺服務器A、B,主要是部署在A服務器上,想要調用B服務器,但是不在一個機器中,不能直接去調用,需要利用網絡,通過網絡傳輸將自己想要的數據及想要在B服務站執行的內容 傳輸過去。
RPC 所實現的內容就是讓A服務器調用B服務器 的過程被忽略,在調用函數的時候像調用A自己本身的函數一樣;
RPC的兩個核心就是:通訊(HTTP、RPC)、序列化(序列化的方式就是方便數據傳輸);
如何給老婆解釋什么是RPC
假設你有一個計算器接口,Calculator,以及它的實現類CalculatorImpl,那么在系統還是單體應用時,你要調用Calculator的add方法來執行一個加運算,直接new一個CalculatorImpl,然后調用add方法就行了,這其實就是非常普通的本地函數調用,因為在同一個地址空間,或者說在同一塊內存,所以通過方法棧和參數棧就可以實現。
現在,基于高性能和高可靠等因素的考慮,你決定將系統改造為分布式應用,將很多可以共享的功能都單獨拎出來,比如上面說到的計算器,你單獨把它放到一個服務里頭,讓別的服務去調用它。
**問題:**服務A里頭并沒有CalculatorImpl這個類,那它要怎樣調用服務B的CalculatorImpl的add方法呢?
- 可以模仿B/S架構的調用方式呀,在B服務暴露一個Restful接口,然后A服務通過調用這個Restful接口來間接調用CalculatorImpl的add方法。
很好,這已經很接近RPC了,不過如果是這樣,那每次調用時,是不是都需要寫一串發起http請求的代碼呢?比如httpClient.sendRequest…之類的,能不能像本地調用一樣,去發起遠程調用,讓使用者感知不到遠程調用的過程呢,像這樣:
- 用代理模式呀!而且最好是結合Spring IoC一起使用,通過Spring注入calculator對象,注入時,如果掃描到對象加了@Reference注解,那么就給它生成一個代理對象,將這個代理對象放進容器中。而這個代理對象的內部,就是通過httpClient來實現RPC遠程過程調用的。
就是很多RPC框架要解決的問題和解決的思路,比如阿里的Dubbo。
ps:Dubbo以前是阿里的,后來才移交給了Apache
RPC要解決的兩個問題:
- 解決分布式系統中,服務之間的調用問題。
- 遠程調用時,要能夠像本地調用一樣方便,讓調用者感知不到遠程調用的邏輯。
RPC很少用到http(超文本傳輸協議)協議來進行數據傳輸,畢竟我只是想傳輸一下數據而已,何必動用到一個文本傳輸的應用層協議呢,我為什么不直接使用二進制傳輸?比如直接用Java的Socket協議進行傳輸。
以左邊的Client端為例,Application就是rpc的調用方,Client Stub就是我們上面說到的代理對象,也就是那個看起來像是Calculator的實現類,其實內部是通過rpc方式來進行遠程調用的代理對象,至于Client Run-time Library,則是實現遠程調用的工具包,比如jdk的Socket,最后通過底層網絡實現實現數據的傳輸。
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
作者:柳樹之
鏈接:https://www.jianshu.com/p/2accc2840a1b
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
Client將數據進行序列化 傳輸給Server,Server對數據進行反序列化,讀取數據內容,只進行服務調用,程序處理,將處理的內容結果通過在進行序列化 傳輸到Client,最終實現全局的調用;
Dubbo
類比于SpringCloud,都是使用的分布式架構思想,但是Dubbo
是一個框架,而SpringCloud
是一套整合于Spring的生態;
概念
Apache Dubbo |?d?b??| 是一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:
- 面向接口的遠程方法調用;
- 智能容錯和負載均衡;
- 服務自動注冊和發現;
官網:cn.dubbo.apache.org
QuickStart:https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/quick-start/starter/
- 基本概念
**服務提供者(**Provider):暴露服務的服務提供方,服務提供者在啟動時,向注冊中心注冊自己提供的服務。
服務消費者(Consumer):調用遠程服務的服務消費方,服務消費者在啟動時,向注冊中心訂閱自己所需的服務,服務消費者,從提供者地址列表中,基于軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
注冊中心(Registry):注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基于長連接推送變更數據給消費者
監控中心(Monitor):服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心
調用關系:
- 服務
Provider
容器Container
負責啟動start
,加載,運行服務提供者。 - 服務提供者
Provider
在啟動時,向注冊中心Registry
注冊register
自己提供的服務。 - 服務消費者
Consumer
在啟動時,向注冊中心Registry
訂閱subscribe
自己所需的服務。 - 注冊中心
Registry
返回服務提供者Provider
地址列表通知notify
給消費者,如果有變更,注冊中心將基于長連接推送invoke
變更數據給消費者。 - 服務消費者
Consumer
,從提供者地址列表中,基于軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
Dubbo環境搭建
在最新的3.3.0
版本官網上,可以直接創建你 基于Spring Boot 的微服務應用 ,需要注意
因為是看的狂神的20年的視頻,所以先按照他當時的做法思路使用zookeeper
,這個要參照官網
Zookeeper
學習文檔:https://cn.dubbo.apache.org/zh-cn/overview/reference/integrations/zookeeper/
Zookeeper: https://zookeeper.apache.org/releases.html
- 下載Zookeeper
下載3.8.4 是穩定版;
官網太慢,去鏡像站下載:https://mirrors.aliyun.com/apache/zookeeper
- 解壓
apache-zookeeper-3.8.4
,widows
運行"D:\work\apache-zookeeper-3.8.4\bin\zkServer.cmd"
,添加pause
,報錯查看錯誤信息 - 解決
java.lang.ClassNotFoundException
問題
發現調用jar包找不到,我下載的是源碼版,重新下載個二進制版,把lib
copy進去,網絡不好的情況下不要自己編譯。
- 解決
Error processing D:\work\apache-zookeeper-3.8.4\bin\..\conf\zoo.cfg
的問題
目錄下沒有zoo.cfg
文件,copy sample生成一個,根據上述內容配置,然后啟動
- 啟動成功
測試 Zookeeper
- run
zkCli.cmd
,顯示連接成功; create –e /aaa 123
:創建一個aaa節點,值為123
在 Zookeeper 3.8 版本之后,create -e(表示創建一個帶有 ephemeral 選項的節點)已被廢棄。現在,如果你想創建一個臨時節點(ephemeral node),你應該使用 create 命令時直接指定 -e 參數后面跟路徑和數據。
get /aaa
,顯示沒有創建?檢查問題,重新創建使用create /aaa 123
就好了;
Window環境下使用Dubbo-admin
在官網可以看到這段描述,Dubbo-admin可以對整個集群進行查詢調用,
官網:
- https://cn.dubbo.apache.org/zh-cn/overview/reference/proposals/admin/
- https://cn.dubbo.apache.org/zh-cn/overview/notices/admin/
文檔編輯完 沒檢查就提交了 哈哈哈
- 下載Dubbo-admin
- https://cn.dubbo.apache.org/zh-cn/overview/reference/setup/install/
- https://cn.dubbo.apache.org/zh-cn/download/
- 下載完解壓,使用目前最新的 最穩定版本,解壓 ;
- 檢查
dubbo-admin-server\src\main\resources\application.properties
的端口號配置; - 打包 cd 到根目錄
mvn clean package -Dmaven.test.skip=true
,等待打包完成; - 執行打包好的jar包
java -jar dubbo-admin-0.4.0.jar
, Session 0x0 for server 127.0.0.1/<unresolved>:2181, unexpected error, closing socket connection and attempting reconnect
提示報錯,配置host文件 把localhost的地址映射加進去;- 一直啟動失敗??問題好奇怪
- 訪問
http://localhost:7001/
?,默認賬號名root
密碼root
版本匹配不對
對應的版本不對?
- Dubbo Admin 0.4.0發布于2020年,其設計主要針對JDK8環境
- Zookeeper 3.8.4對JDK17的支持尚不完善,已知存在NIO通道問題
更換完版本后,啟動依舊報錯,系統提示 java.lang.IllegalStateException
java.lang.IllegalStateException: zookeeper not connected, the address is: zookeeper://127.0.0.1:2181/org.apache.dubbo.config.ConfigCenterConfig?check=true&config-file=dubbo.properties&group=dubbo&highest-priority=false&namespace=dubbo&timeout=30000 at org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient.<init> (CuratorZookeeperClient.java:118)
Jdk17連接zookeeper報錯:127.0.0.1/<unresolved>:2181_java.lang.illegalargumentexception: unable to cano-CSDN博客
使用 Dubbo Admin 0.6.0看看,訪問 http://localhost:38080
好了,終于進去了,使用Dubbo Admin 0.6.0
也是報錯,之后再去檢查pom中的依賴,發現org.apache.zookeeper
的依賴默認版本是zookeeper-3.4.14,于是將他升級為最新版,啟動成功。其他問題還在等待校驗。
服務注冊實戰
官方文檔: https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/zookeeper/
內容總結
- zookeeper :一個jar包 (必須存在)
- dubbo-admin:是一個監控管理后臺 (可有可無)
- Dubbo:jar包 (需要用)
- 最新的Dubbo 有好多實現方案,根據具體情況使用,阿里云本身有nacos
導入相關依賴
- SpringBoot
<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>3.3.0</version>
</dependency>
<!-- 僅當 Zookeeper Server 版本是 3.4.x 及以下時,使用此依賴 -->
<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-zookeeper-spring-boot-starter</artifactId><version>3.3.0</version>
</dependency>
<!-- 僅當 Zookeeper Server 版本是 3.5.x 及以上時,使用此依賴-->
<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-zookeeper-curator5-spring-boot-starter</artifactId><version>3.3.0</version>
</dependency>
檢查自己 的Zookeeper的版本是 3.8.4
所以使用dubbo-zookeeper-curator5-spring-boot-starter
;
找不著依賴就mvn clean install
- 不使用SpringBoot
<dependencies><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo</artifactId><version>3.3.0</version></dependency><!-- This dependency helps to introduce Curator and Zookeeper dependencies that are necessary for Dubbo to work with zookeeper as transitive dependencies. --><!-- 僅當 Zookeeper Server 版本是 3.4.x 及以下時,使用此依賴 --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-dependencies-zookeeper</artifactId><version>3.3.0</version><type>pom</type></dependency><!-- 僅當 Zookeeper Server 版本是 3.5.x 及以上時,使用此依賴 --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-dependencies-zookeeper-curator5</artifactId><version>3.3.0</version><type>pom</type></dependency></dependencies>
選擇 Zookeeper 版本
Dubbo 3.3.0 版本開始正式支持 JDK 17,如果您使用 JDK 17,則必須選用 dubbo-dependencies-zookeeper-curator5 或 dubbo-zookeeper-curator5-spring-boot-starter 依賴,對應的 Zookeeper Server 推薦是 3.8.0 版本及以上。
::當前使用的最新穩定版 3.8.4
配置并啟用 Zookeeper
配置properties
,注冊中心的地址,服務發現名 和 掃描包
# dubbo.properties
dubbo.registry.address=zookeeper://localhost:2181
# 新用戶請設置此值,表示啟用應用級服務發現,可選值 interface、instance、all,默認值為 all,未來版本將切換默認值為 instance
dubbo.registry.register-mode=instance
address 是啟用 zookeeper 注冊中心唯一必須指定的屬性,而在生產環境下,address 通常被指定為集群地址,如 address=zookeeper://10.20.153.10:2181?backup=10.20.153.11:2181,10.20.153.12:2181
protocol 與 address 分開配置的模式也可以,
如 <dubbo:registry protocol="zookeeper" address="10.20.153.10:2181,10.20.153.11:2181,10.20.153.12:2181" />
創建服務接口和實現(DubboService)類,這里是配置Provider
使用@DubboService
的注解 ,為了將接口暴漏出去,使外部接口可以掃描的到TicketService
package com.demo.service.impl;import com.demo.service.TicketService;
import org.apache.dubbo.config.annotation.DubboService;@DubboService
public class TicketImpl implements TicketService {@Overridepublic String getTicket() {return "Mrs.K sailed ticket";}
}
啟動Dubbo的掃描(EnableDubbo)
- 如果沒有找到注解
@EnableDubbo
,記得去更新下maven包,看看有沒有把依賴導進來,依賴啟動器導入的情況下一般就能夠發現;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@EnableDubbo
@SpringBootApplication
public class Springboot09DubboserveApplication {public static void main(String[] args) {SpringApplication.run(Springboot09DubboserveApplication.class, args);}}
- 啟動項目測試,項目正常啟動,
- 服務測試
重復上述操作,將需要注冊Dubbo的配置下
- 配置端口,注冊地址;
- 啟動類開啟Dubbo;
編寫Service,這次是消費者,調用提供者所提供的內容
在Dubbo中,分提供者Provider
和消費者Consumer
兩個概念;
- 提供者實現接口,提供具體的實現內容;
- 消費者負責調用接口,使用提供者所實現的功能;
- 因為不是在一個服務中啟動,所以存在RPC的管理,Dubbo的解決方案由此而生;
- 在Dubbo中,消費者所需要使用的是Refer,選擇指向的地址
@DubboReference
@Component
public class UserServiceImpl implements UserService {//我們需要去拿去注冊中心的服務@DubboReferenceprivate TicketService ticketService;public void buyTicket() {System.out.println("》》User正在買票...");System.out.println("User正在調用ticket服務...");System.out.println(ticketService.getTicket());System.out.println("調用Ticket完成《《");}}
- 這樣子代碼就會去找
TicketService
接口,但是因為TicketService
是在另一個服務中啟用的,所以需要把那個接口在這重現一下
package com.demo.service;public interface TicketService {String getTicket();}
- 在Dubbo-admin中查找,啟用成功
- 代碼測試,要先關閉Dubbo-admin,還是不行。。。
技術沒到家,一直在報端口占用服務沖突的錯
package com.demo;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.demo.service.UserService;@SpringBootTest
class Springboot09DubboserveApplicationTests {@AutowiredUserService userService;@Testvoid contextLoads() {userService.buyTicket();}
}
- 寫個Controller,在Controller中調用Service之后,啟動頁面測試
- 優化下 優化內容顯示到頁面上
項目啟動成功:
測試功能