調用關系說明:
· 0. 服務容器負責啟動,加載,運行服務提供者。
· 1. 服務提供者在啟動時,向注冊中心注冊自己提供的服務。
· 2. 服務消費者在啟動時,向注冊中心訂閱自己所需的服務。
· 3. 注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基於長連接推
送變更數據給消費者。
· 4. 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一台提供者進行調用,
如果調用失敗,再選另一台調用。
· 5. 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鍾發送一次統計
數據到監控中心。

Zookeeper 介紹
官方推薦使用 zookeeper 注冊中心。注冊中心負責服務地址的注冊與查找,相當於目錄服務,服務提供者和消費者只在啟動時與注冊中心交互,注冊中心不轉發請求,壓力較小。
Zookeeper 是 Apacahe Hadoop 的子項目,是一個樹型的目錄服務,支持變更推送,適合作為Dubbox 服務的注冊中心,工業強度較高,可用於生產環境。
(5)編寫配置文件
在src/main/resources下創建applicationContext-service.xml ,內容如下:
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<dubbo:application name="dubboxdemo-service"/> <dubbo:registry address="zookeeper://192.168.200.128:2181"/> <dubbo:annotation package="cn.itcast.dubboxdemo.service" /> </beans> |
注意:dubbo:annotation用於掃描@Service注解。
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <property name="supportedMediaTypes" value="application/json"/> <property name="features"> <array> <value>WriteMapNullValue</value> <value>WriteDateUseDateFormat</value> </array> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <!-- 引用dubbo 服務 --> <dubbo:application name="dubboxdemo-web" /> <dubbo:registry address="zookeeper://192.168.200.128:2181"/> <dubbo:annotation package="cn.itcast.dubboxdemo.controller" /> </beans> |
(6)測試運行
tomcat7:run
在瀏覽器輸入http://localhost:8082/user/showName.do,查看瀏覽器輸出結果
Dubbo 和 webservice 區別?
webservice :不同公司可以調用
服務調用方和提供方 語言可以不同
協議:soap+http協議 網絡第七層 應用層
需要通過jdk的命令 wsimport 生成接口代碼
Dubbox:只能是同一個公司調用.
語言必須相同. 服務提供和消費方必須都是java
協議:TCP協議 網絡第四層 socket連接 效率更高
dubbo只需要把接口拷貝過來即可
相同點: 都是遠程調用的框架
網絡模型七層?
7應用層 6表示層 5會話層 4傳輸層(TCP協議) 3網絡層(IP/tcp協議) 2數據鏈路層(網卡和網線連接這塊) 物理層(網線,光纖)
默認使用的是什么通信框架,還有別的選擇嗎?
默認也推薦使用netty框架,還有mina。
2、服務調用是阻塞的嗎?
因為用的是缺省協議 長連接 和NIO的模式. 非阻塞的
http是短連接 數據傳輸完畢斷開. http1.1采用的是長連接 通過tcp協議 傳輸完畢 不斷開連接 如果下次訪問相同的域名 不需要重新連接
(1)NIO和IO的區別
NIO是非阻塞的 IO是阻塞的.
NIO是采用緩沖的 數據可以在稍后處理的緩沖區中前后移動. IO
NIO可以通過一個線程通過選擇器控制多個數據通道.
3、一般使用什么注冊中心?還有別的選擇嗎?
推薦使用zookeeper注冊中心,還有redis等不推薦
4、默認使用什么序列化框架,你知道的還有哪些?
默認使用Hessian序列化, 優點:跨語言, 缺點:慢 還有Duddo、FastJson、Java自帶序列化。
5、服務提供者能實現失效踢出是什么原理?
服務失效踢出基於zookeeper的臨時節點原理。
敲黑板畫重點
zookeeper中節點是有生命周期的.具體的生命周期取決於節點的類型.節點主要分為持久節點(Persistent)和臨時節點(Ephemeral),但是更詳細的話還可以加上時序節點(Sequential),創建節點中往往組合使用,因此也就是4種.
- 持久節點
- 持久順序節點
- 臨時節點
- 臨時順序節點
持久節點
所謂持久節點,是指在節點創建后,就一直存在,直到有刪除操作來主動清除這個節點,也就是說不會因為創建該節點的客戶端會話失效而消失
臨時節點
臨時節點的生命周期和客戶端會話綁定,也就是說,如果客戶端會話失效,那么這個節點就會自動被清除掉
應用場景 怎么判斷zookeeper中的機器是否可用
zookeeper常用的應用場景我在上周已經畫了思維導圖,這里就不重復展示了.就拿分布式協調/通知來舉例(這個例子既是在回答第一個面試題,也是在回答第二個面試題).
在分布式系統中,我們常常需要知道某個機器是否可用,傳統的開發中,可以通過Ping某個主機來實現,Ping得通說明對方是可用的,相反是不可用的,因為zookeeper是一個樹形結構.ZK 中我們讓所有的機其都注冊一個臨時節點,我們判斷一個機器是否可用,我們只需要判斷這個節點在ZK中是否存在就可以了,不需要直接去連接需要檢查的機器,降低系統的復雜度
6、服務上線怎么不影響舊版本?
采用多版本開發,不影響舊版本。
7、如何解決服務調用鏈過長的問題?
可以結合zipkin實現分布式服務追蹤。
8、說說核心的配置有哪些?
服務方消費方 zookeeper注冊中心
9、dubbo推薦用什么協議?
Dubbo通訊協議
第一、dubbo
Dubbo 缺省協議采用單一長連接和 NIO 異步通訊,適合於小數據量大並發的服務調用,以及服務消費者機器數遠大於服務提供者機器數的情況。
反之,Dubbo 缺省協議不適合傳送大數據量的服務,比如傳文件,傳視頻等,除非請求量很低。
特性
缺省協議,使用基於 mina 1.1.7 和 hessian 3.2.1 的 tbremoting 交互。
- 連接個數:單連接
- 連接方式:長連接
- 傳輸協議:TCP
- 傳輸方式:NIO 異步傳輸
- 序列化:Hessian 二進制序列化
- 適用范圍:傳入傳出參數數據包較小(建議小於100K),消費者比提供者個數多,單一消費者無法壓滿提供者,盡量不要用 dubbo 協議傳輸大文件或超大字符串。
- 適用場景:常規遠程服務方法調用
第三、hessian
Hessian 1 協議用於集成 Hessian 的服務,Hessian 底層采用 Http 通訊,采用 Servlet 暴露服務,Dubbo 缺省內嵌 Jetty 作為服務器實現。
Dubbo 的 Hessian 協議可以和原生 Hessian 服務互操作,即:
- 提供者用 Dubbo 的 Hessian 協議暴露服務,消費者直接用標准 Hessian 接口調用
- 或者提供方用標准 Hessian 暴露服務,消費方用 Dubbo 的 Hessian 協議調用。
特性
- 連接個數:多連接
- 連接方式:短連接
- 傳輸協議:HTTP
- 傳輸方式:同步傳輸
- 序列化:Hessian二進制序列化
- 適用范圍:傳入傳出參數數據包較大,提供者比消費者個數多,提供者壓力較大,可傳文件。
- 適用場景:頁面傳輸,文件傳輸,或與原生hessian服務互操作
第四、Http
基於 HTTP 表單的遠程調用協議,采用 Spring 的 HttpInvoker 實現 1
特性
- 連接個數:多連接
- 連接方式:短連接
- 傳輸協議:HTTP
- 傳輸方式:同步傳輸
- 序列化:表單序列化
- 適用范圍:傳入傳出參數數據包大小混合,提供者比消費者個數多,可用瀏覽器查看,可用表單或URL傳入參數,暫不支持傳文件。
- 適用場景:需同時給應用程序和瀏覽器 JS 使用的服務。
第五、WebService
基於 WebService 的遠程調用協議,基於 Apache CXF 1 的 frontend-simple 和 transports-http 實現 2。
可以和原生 WebService 服務互操作,即:
rmi://
RMI 協議采用 JDK 標准的 java.rmi.* 實現,采用阻塞式短連接和 JDK 標准序列化方式。
注意:如果正在使用 RMI 提供服務給外部訪問 1,同時應用里依賴了老的 common-collections 包 2 的情況下,存在反序列化安全風險 3。
特性
- 連接個數:多連接
- 連接方式:短連接
- 傳輸協議:TCP
- 傳輸方式:同步傳輸
- 序列化:Java 標准二進制序列化
- 適用范圍:傳入傳出參數數據包大小混合,消費者與提供者個數差不多,可傳文件。
- 適用場景:常規遠程服務方法調用,與原生RMI服務互操作
10、同一個服務多個注冊的情況下可以直連某一個服務嗎?
可以直連,修改配置即可,也可以通過telnet直接某個服務。
開發階段就是直連的

11、畫一畫服務注冊與發現的流程圖
12、集群容錯怎么做?
讀操作建議使用Failover失敗自動切換,默認重試兩次其他服務器。寫操作建議使用Failfast快速失敗,發一次調用失敗就立即報錯。
13、在使用過程中都遇到了些什么問題?
14、dubbo和dubbox之間的區別?
15、你還了解別的分布式框架嗎?
1 面試題:Dubbo中zookeeper做注冊中心,如果注冊中心集群都掛掉,發布者和訂閱者之間還能通信么?
可以的,啟動dubbo時,消費者會從zk拉取注冊的生產者的地址接口等數據,緩存在本地。每次調用時,按照本地存儲的地址進行調用
注冊中心對等集群,任意一台宕掉后,會自動切換到另一台
注冊中心全部宕掉,服務提供者和消費者仍可以通過本地緩存通訊
服務提供者無狀態,任一台 宕機后,不影響使用
服務提供者全部宕機,服務消費者會無法使用,並無限次重連等待服務者恢復
2 dubbo連接注冊中心和直連的區別
在開發及測試環境下,經常需要繞過注冊中心,只測試指定服務提供者,這時候可能需要點對點直連,
點對點直聯方式,將以服務接口為單位,忽略注冊中心的提供者列表,
服務注冊中心,動態的注冊和發現服務,使服務的位置透明,並通過在消費方獲取服務提供方地址列表,實現軟負載均衡和Failover, 注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基於長連接推送變更數據給消費者。
服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。注冊中心負責服務地址的注冊與查找,相當於目錄服務,服務提供者和消費者只在啟動時與注冊中心交互,注冊中心不轉發請求,服務消費者向注冊中心獲取服務提供者地址列表,並根據負載算法直接調用提供者,注冊中心,服務提供者,服務消費者三者之間均為長連接,監控中心除外,注冊中心通過長連接感知服務提供者的存在,服務提供者宕機,注冊中心將立即推送事件通知消費者
注冊中心和監控中心全部宕機,不影響已運行的提供者和消費者,消費者在本地緩存了提供者列表
注冊中心和監控中心都是可選的,服務消費者可以直連服務提供者
3、Dubbo在安全機制方面是如何解決的
Dubbo通過Token令牌防止用戶繞過注冊中心直連,然后在注冊中心上管理授權。Dubbo還提供服務黑白名單,來控制服務所允許的調用方
Dubbo簡介
Dubbo |ˈdʌbəʊ|是一個由阿里巴巴開源的、分布式的RPC(Remote Procedure Call Protocol-遠程過程調用)和微服務框架,現為Apache頂級項目。
Dubbo提供了三個關鍵功能:基於接口的遠程調用,容錯與負載均衡,服務自動注冊與發現。
Dubbo使得調用遠程服務就像調用本地java服務一樣簡單。
下圖為Dubbo的結構圖:
關於Dubbo的使用可以參考官方文檔http://dubbo.apache.org ,本文不作贅述。
2. Dubbo服務暴露與消費過程
先來看下面問題:
1) Dubbo服務提供者發布服務的流程
2) Dubbo服務消費者消費服務的流程
3) 什么是本地暴露和遠程暴露,他們的區別
Dubbo服務提供者發布服務過程:
先來看dubbo的啟動日志:
圖中從上到下框起來的日志分別是:
1) 暴露服務到本地
2) 暴露服務到遠程
3) 啟動netty服務
4) 連接zookeeper
5) 注冊服務到zookeeper
6) 監聽zookeeper中消費服務
關於這個過程的實現細節可以參考Dubbo官方文檔->實現細節->遠程調用細節->服務提供者暴露一個服務的詳細過程。截圖如下:
Dubbo服務消費者消費服務過程:
關於這個過程的實現細節可以參考Dubbo官方文檔->實現細節->遠程調用細節->服務消費者消費一個服務的詳細過程。截圖如下:
下面來看本地暴露於遠程暴露的區別:
本地暴露是暴露在本機JVM中,調用本地服務不需要網絡通信.
遠程暴露是將ip,端口等信息暴露給遠程客戶端,調用遠程服務時需要網絡通信.
3. Dubbo相關協議
Dubbo 允許配置多協議,在不同服務上支持不同協議或者同一服務上同時支持多種協議。
不同服務在性能上適用不同協議進行傳輸,比如大數據用短連接協議,小數據大並發用長連接協議。
Dubbo支持的協議主要有:
dubbo:
Dubbo 缺省協議是dubbo協議,采用單一長連接和 NIO 異步通訊,適合於小數據量大並發的服務調用,以及服務消費者機器數遠大於服務提供者機器數的情況。
反之,Dubbo 缺省協議不適合傳送大數據量的服務,比如傳文件,傳視頻等,除非請求量很低。rmi:
RMI協議采用阻塞式(同步)短連接和 JDK 標准序列化方式。適用范圍:傳入傳出參數數據包大小混合,消費者與提供者個數差不多,可傳文件。
hessian:
Hessian底層采用Http通訊(同步),采用Servlet暴露服務。適用於傳入傳出參數數據包較大,提供者比消費者個數多,提供者壓力較大,可傳文件。
dubbo還支持的其他協議有:http, webservice, thrift, memcached, redis
4. Dubbo相關配置
先看下面問題:
Dubbo主要的配置項有哪些,作用是什么?
如果Dubbo的服務端未啟動,消費端能起來嗎?
Dubbo主要配置項:
配置應用信息:
<dubbo:application name="app-provider" />
配置注冊中心相關信息:
<dubbo:registryid="zk" protocol="zookeeper" address="127.0.0.1:2181" />
配置服務協議:
<dubbo:protocol name="dubbo" port="20880" threadpool="cached" threads="80" />
配置所有暴露服務缺省值:
<dubbo:provider registry="zk" protocol="dubbo" retries="0" version="1.0.0" timeout="3000" threadpool="cached" threads="4"/>
配置暴露服務:
<dubbo:service interface="" ref="" />
配置所有引用服務缺省值:
<dubbo:consumer check="false" timeout="1000" version="1.0" retries="0" async="false" />
配置引用服務:
<dubbo:reference id="" interface="" />
備注:其中reference的check默認=true,啟動時會檢查引用的服務是否已存在,不存在時報錯
注解配置:
com.alibaba.dubbo.config.annotation.Service 配置暴露服務
com.alibaba.dubbo.config.annotation.Reference配置引用服務
第二篇
zookeeper 注冊中心
Zookeeper 是 Apacahe Hadoop 的子項目,是一個樹型的目錄服務,支持變更推送,適合作為 Dubbo 服務的注冊中心,工業強度較高,可用於生產環境,並推薦使用 1。

流程說明:
- 服務提供者啟動時: 向
/dubbo/com.foo.BarService/providers目錄下寫入自己的 URL 地址 - 服務消費者啟動時: 訂閱
/dubbo/com.foo.BarService/providers目錄下的提供者 URL 地址。並向/dubbo/com.foo.BarService/consumers目錄下寫入自己的 URL 地址 - 監控中心啟動時: 訂閱
/dubbo/com.foo.BarService目錄下的所有提供者和消費者 URL 地址。
支持以下功能:
- 當提供者出現斷電等異常停機時,注冊中心能自動刪除提供者信息
- 當注冊中心重啟時,能自動恢復注冊數據,以及訂閱請求
- 當會話過期時,能自動恢復注冊數據,以及訂閱請求
- 當設置
<dubbo:registry check="false" />時,記錄失敗注冊和訂閱請求,后台定時重試 - 可通過
<dubbo:registry username="admin" password="1234" />設置 zookeeper 登錄信息 - 可通過
<dubbo:registry group="dubbo" />設置 zookeeper 的根節點,不設置將使用無根樹 - 支持
*號通配符<dubbo:reference group="*" version="*" />,可訂閱服務的所有分組和所有版本的提供者
3)Redis 注冊中心

使用 Redis 的 Key/Map 結構存儲數據結構:
- 主 Key 為服務名和類型
- Map 中的 Key 為 URL 地址
- Map 中的 Value 為過期時間,用於判斷臟數據,臟數據由監控中心刪除 3
使用 Redis 的 Publish/Subscribe 事件通知數據變更:
- 通過事件的值區分事件類型:
register,unregister,subscribe,unsubscribe - 普通消費者直接訂閱指定服務提供者的 Key,只會收到指定服務的
register,unregister事件 - 監控中心通過
psubscribe功能訂閱/dubbo/*,會收到所有服務的所有變更事件
調用過程:
- 服務提供方啟動時,向
Key:/dubbo/com.foo.BarService/providers下,添加當前提供者的地址 - 並向
Channel:/dubbo/com.foo.BarService/providers發送register事件 - 服務消費方啟動時,從
Channel:/dubbo/com.foo.BarService/providers訂閱register和unregister事件 - 並向
Key:/dubbo/com.foo.BarService/providers下,添加當前消費者的地址 - 服務消費方收到
register和unregister事件后,從Key:/dubbo/com.foo.BarService/providers下獲取提供者地址列表 - 服務監控中心啟動時,從
Channel:/dubbo/*訂閱register和unregister,以及subscribe和unsubsribe事件 - 服務監控中心收到
register和unregister事件后,從Key:/dubbo/com.foo.BarService/providers下獲取提供者地址列表 - 服務監控中心收到
subscribe和unsubsribe事件后,從Key:/dubbo/com.foo.BarService/consumers下獲取消費者地址列表
4)Simple 注冊中心
Simple 注冊中心本身就是一個普通的 Dubbo 服務,可以減少第三方依賴,使整體通訊方式一致。
三、集群容錯
Failover Cluster
失敗自動切換,當出現失敗,重試其它服務器 1。通常用於讀操作,但重試會帶來更長延遲。可通過 retries="2" 來設置重試次數(不含第一次)。
重試次數配置如下:
<dubbo:service retries="2" />
或
<dubbo:reference retries="2" />
或
-
<dubbo:reference>
-
<dubbo:method name="findFoo" retries="2" />
-
</dubbo:reference>
Failfast Cluster
快速失敗,只發起一次調用,失敗立即報錯。通常用於非冪等性的寫操作,比如新增記錄。
Failsafe Cluster
失敗安全,出現異常時,直接忽略。通常用於寫入審計日志等操作。
Failback Cluster
失敗自動恢復,后台記錄失敗請求,定時重發。通常用於消息通知操作。
Forking Cluster
並行調用多個服務器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過 forks="2" 來設置最大並行數。
Broadcast Cluster
廣播調用所有提供者,逐個調用,任意一台報錯則報錯 2。通常用於通知所有提供者更新緩存或日志等本地資源信息


