① Dubbo配置參數詳解-generic
畫外音:目前Dubbo在開源中國舉辦的2019年度最受歡迎中國開源軟體中排名第3名,支持Dubbo的朋友可以去投票哇。 2019年度最受歡迎中國開源軟體
Consumer端正常調用Dubbo服務時,一般都需要服務提供方提供一個jar包,只有在項目中引入該jar包,才能調用相關服務;能不能向http調用那樣,我只需手顫要知道我要調用的url就可以直接調用Dubbo服務?
有的,這就是generic做的事。
generic :通用服務調用,當我們已經知道我們要調用的服務的全限定鬧薯磨名及方法,就不需要服務提供者的jar就能調用Dubbo服務了。
generic要配合interfaceName參數一起使用,其中interfaceName是Dubbo服務的全限定名,比如:
當provider接收到請求時,會調用一系列的過濾器對請求進行處理,這其中就包含處理generic的過濾器: GenericFilter
該過濾器會判斷液斗調用的方法是否是$invoke,如果是則會通過反射調用正在的方法
筆者認為該參數最大的用武之地是作為網關使用,筆者所在公司的網關就提供了http轉換成bbo介面調用的功能,前端使用http調用,後端使用bbo服務進行處理;網關提供一個介面配置頁面,只需要業務方在頁面配置url與bbo介面的轉換關系即可,網關不需要引用服務提供者的jar包,如果介面有變動,網關無需知道,只要業務方修改配置即可。
② bbo version: 2.6.0, current host: 192.168.245.1
您可以通過修改橡大緩Dubbo配置文件來設置Dubbo應用的IP地址。Dubbo應用的IP地址可以通過bbo.registry.address配置項來指定。例如,您可以在Dubbo配置文件中添加以下配置項:
bbo.registry.address = zookeeper://192.168.245.1:2181
這里的IP地址為您希望Dubbo應用使用的IP地址。這個配置仿困項指定了Dubbo應用使用Zookeeper作為注冊中心,並將Zookeeper的地址設置為192.168.245.1:2181。您也可以使用其他類型的注冊中心,例如Redis、Consul等,具體配置方梁模式可以參考Dubbo文檔。
③ Dubbo的多注冊中心配置
最近項目中用到了Dubbo,Zookeeper,因為底層不同服務之間的調用,宴團涉及到了不同的注冊前祥磨中心。由此寫一下關於多注冊中心的配置。
SpringBoot框架:
使用yml配置:
bbo:
registry:
protocol: zookeeper
address: ****.****:2181|****.****:2181
注意:| 豎線分割線就是表示不同的注冊中心
bbo:
registry:
protocol: zookeeper
address: ****.****:2181,****.****:2181
注意:, 逗號表示同慧斗一注冊中心不同的集群
Spring xml配置
注冊到不同的服務中心
<bbo:registry id="bbo" address="****.****:2181"/>
<bbo:registry id="bbo" address="****.****:2181"/>
個人公號:【排骨肉段】,可以關注一下。
④ 調用bbo服務時事務配置在哪
bbo實現了分布式遠程調用框架,多運行節點既能提高可靠性,又能提升負載能力。bbo配置主要有注冊中心(推薦zookeeper或redis)、提供者provider、消費者consumer,注冊中心是第三方實現,所以主要配置好服務提供者和消費者就可以了。實際上服務介面和實現都是需要我們自己設計和實現的,bbo做的事情就是將服務實現發布到注冊中心,然後消費者從注冊中心訂閱服務介面,之後對介面的調用就由bbo調度提供者去執行並返回結果。以下配置都有源碼,見右側「免費資源」。
提供者provider的配置:提供者是獨立運行的節點,可以多實例運行,將服務注冊到注冊中心
必須要有application name,注冊中心配置zookeeper,協議bbo,超時6秒失敗不重試,提供者載入repository和service層bean,然後發布介面service。
<bbo:application name="ite-provider" />
<bbo:registry address="zookeeper://127.0.0.1:2181"/>
<bbo:protocol name="bbo" port="20880" />
<bbo:provider timeout="6000" retries="0"/>
<import resource="classpath:cache.xml"/>
<import resource="classpath:ite-repository.xml"/>
<import resource="classpath:ite-service.xml"/>
<import resource="classpath:ite-provider.xml"/>
ite-provider.xml,ref引用的bean是ite-service.xml已經定義好的介面實現,bbo:service就是把介面實現發布到注冊中心
<bbo:service ref="codeListService" interface="com.itecheast.ite.domain.service.CodeListService" />
<bbo:service ref="idService" interface="com.itecheast.ite.domain.service.IdService" />
<bbo:service ref="passwordService" interface="com.itecheast.ite.domain.service.PasswordService" />
<bbo:service ref="rolePermissionService" interface="com.itecheast.ite.domain.service.RolePermissionService" />
provider是可以獨立運行的,bbo.jar裡面有assembly目錄,運行mvn assembly:directory就可以生成能直接運行的provider目錄
assembly.xml內容,可以切換dir或tar.gz兩種格式
<assembly>
<id>assembly</id>
<formats>
<!-- <format>tar.gz</format> -->
<format>dir</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>src/main/assembly/bin</directory>
<outputDirectory>bin</outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>src/main/assembly/conf</directory>
<outputDirectory>conf</outputDirectory>
<fileMode>0644</fileMode>
</fileSet>
<fileSet>
<directory>src/test/resources</directory>
<outputDirectory>conf</outputDirectory>
<fileMode>0644</fileMode>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
</assembly>
bbo.properties,運行start.bat或start.sh時,將從屬性文件讀取bbo配置信息,provider節點可以多處復制並運行。
bbo.container=log4j,spring
bbo.application.name=ite-provider
bbo.registry.address=zookeeper://127.0.0.1:2181
bbo.monitor.protocol=registry
bbo.protocol.name=bbo
bbo.protocol.port=20880
bbo.spring.config=provider.xml
bbo.log4j.file=logs/ite-provider.log
bbo.log4j.level=WARN
消費者consumer的配置,使用bbo:reference訂閱注冊中心裡的服務即可,然後就可以@Autowired注入服務介面了。
<bbo:application name="ite-consumer" />
<bbo:registry address="zookeeper://127.0.0.1:2181"/>
<bbo:reference id="codeListService" interface="com.itecheast.ite.domain.service.CodeListService" />
<bbo:reference id="idService" interface="com.itecheast.ite.domain.service.IdService" />
<bbo:reference id="passwordService" interface="com.itecheast.ite.domain.service.PasswordService" />
<bbo:reference id="rolePermissionService" interface="com.itecheast.ite.domain.service.RolePermissionService" />
如果前端項目是一個消費者,就可以在web.xml里直接載入consumer.xml訂閱服務了。
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:consumer.xml,classpath:cache.xml,classpath:shiro.xml,classpath:front.xml</param-value>
</context-param>
實際上本地調試開發時,可以不必啟用分布式配置,只需要更改web.xml即可,所有的服務都已經是配置好了的。
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:ite-repository.xml,classpath:ite-service.xml,classpath:cache.xml,classpath:shiro.xml,classpath:front.xml</param-value>
</context-param>
zookeeper的配置很簡單,
wget http://tool.xlongwei.com/softwares/zookeeper-3.4.6.tar.gz
tar -zxvf zookeeper-3.4.6.tar.gz
cd zookeeper-3.4.6/conf
cp zoo_sample.cfg zoo.cfg
vi zoo.cfg #配置zookeeper參數
單機配置(集群配置待研究)
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/bbo/zookeeper-3.3.3/data
clientPort=2181
運行或停止zookeeper
sh zkServer.sh start | stop
⑤ Dubbo(一)——Dubbo 集成於 Spring 的原理
最近一直在看bbo的源碼部分。在閱讀耐團的時候,需要有一個入手點,才能一點一點的進行下去。自己在研究的時候,發現思緒比較亂,於是就以 芋道源碼 為基礎,一點一點的啃食。芋道源碼是直接從bbo的配置和一些核心的API開始講起,是從bbo已經啟動的過程作為開始節點岩畝猜,而這些核心 API 與 Spring 的之間的關系被省略了,這些東西對我來說屬於前置的知識點,所以花了比較長的時間又從 Dubbo 的核心 API 倒著往前看。
在閱讀 Dubbo 時,發現前置知識越來越多,如:Spring 的 refresh 中的一些核心點,Spring 中 bean 的生命周期,BeanFactory 與 FactoryBean 的區別等。所以這些前置知識花了特別多的時間去補。所幸,雖然補前置知識雖然時間長,但是性價比還是可以的。Dubbo 是依賴於Spring 的上下文環境的框架,其他依賴於 Spring 的框架也是相同的道理。Spring 的一些對外的擴展點,讀過之後也會心中有數。
1、本篇主要是描述了 Dubbo 在 Spring 創建上下文的時候,是如何從創建,到能完整提供一個RPC調用能力的一些相關點。
2、由於源碼比較多,直接貼斷點也太過臃腫,所以僅僅貼一些關鍵點來概括整個流程。
3、本文是依賴於前面的 bbo 項目進行斷點分析,項目結構可以參照這里。項目中 bbo 的配置方式是 xml 文件,所以本篇主要說 xml 配置方式。其他方式道理相同,並不是問題的關鍵點。
4、項目啟動的是 bbo-user 服務,所以 UserService 為 bbo:service,OrderService 為 bbo:reference。
下圖為Spring 啟動時是如何載入 Dubbo 的,其中省略了大量過程,只保留了一些關鍵節點,省略的部分可以略微腦補一下。
整個流程的入口是 Spring 的 refresh 方法。每個方法都有比較深的調用棧。與 Dubbo 有關的入口是 refresh 中的 方法
這個方法是執行 beanFactory 的一些後處理操作,其核心流程為在Spring容器中找出實現了BeanFactoryPostProcessor介面的processor並執行。Spring容器會委託給的方法執行。
是比較核心的類,在這里我們關注一下這個類。它的作用是對項目中配置的類進行處理。具體處理粗型可以分為幾步:
在載入類信息時,spring 會去用各種方式掃到注冊的 bean 信息。我們在 spring 中注冊的 bean,逃不出這個方法的掃描方式。 核心方法是:
掃描之後,會將掃描到的 bean 注冊到 beanDefinitionMap 中
首先是此處 org.springframework.beans.factory.xml.#parseBeanDefinitions,可以看出方法會以配置文件根節點起,遍歷所有子節點。
其次是這里 org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseCustomElement(org.w3c.dom.Element, org.springframework.beans.factory.config.BeanDefinition), 此方法會通過解析出來的節點,獲取對應的 Spring 的 namespaceUri ,進而獲取對應的配置文件處理器。
此處 ele 參數實際值為 <bbo:service ... />,namespaceUri 為 http://code.alibabatech.com/schema/bbo
我們看一下 resolve 方法中的細節。因為這個方法內部才是 Dubbo 依賴於 Spring 的關鍵點。
此處的 NamespaceHandler 為 DubboNamespaceHandler,再創建結束之後,進行 init 初始化。
可以看到,DubboNamespaceHandler 在初始化的時候,會創建所有 bbo 標簽對應的Config 類的 DubboBeanDefinitionParser。並將 DubboBeanDefinitionParser 和 對應的 bbo 標簽類注冊到 NamespaceHandlerSupport 的 parsers 中。
最後,會在 com.alibaba.bbo.config.spring.schema.DubboBeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, java.lang.Class<?>, boolean) 方法中進行處理
Dubbo 服務比較特殊,beanDefinition 跟普通的 bean 不太一樣。在向 beanDefinitionMap 注冊時,普通的 beanDefinition 的 beanName 與 beanClass 是對應的;而 bbo 服務的 beanDefinition 的 beanName 是bbo 服務的名稱,beanClass 為 bbo 對應的 Bean。
普通的 beanDefinition:
bbo 引用的服務的 beanDefinition:
這一步的核心流程是從 beanFactory 中獲取所有的 ApplicationListener,然後注冊到監聽器集合中。它的關鍵點其實是 ServiceBean。因為 ServiceBean 是 ApplicationListener 的實現。
所以 beanFactory 中 ServiceBean 也會被注冊到監聽器集合中。項目中的 ServiceBean 的 beanClass 實際是 UserService。
這一步的核心點,主要是創建剩餘的各類對象,並將其保存到 singletonObjects 中。其中關聯的前置知識為 Spring 中 bean 的生命周期 。它的核心方法是:
org.springframework.beans.factory.support.#doCreateBean
它的具體流程為:
ps:此處並不是只有這一步才會跟 bean 生命周期相關,bean 生命周期貫穿在 refresh 的很多流程中,只要執行doGetBean 方法,都會走這個流程。此處僅僅借樓關聯一下。
這一步的核心點,是通知所有的監聽器上下文刷新結束的事件。在這一步執行時,會通知到 ServiceBean。
此處暴露的是 UserService。
Dubbo 的啟動條件是完全依賴於 Spring 的啟動流程,Spring 的啟動流程中核心的點是 refresh 方法。所以只要搞懂 refresh 方法,其他的拓展框架流程也會明白。只不過關聯的知識點太多了,還是需要時間的積累才能一點一點的搞懂。
如果本篇有描述不清,或者描述有誤的地方,還望在下方留言,大家一起交流,一起學習,一起進步~
⑥ Dubbo簡介
Dubbo是Alibaba開源的分布式服務框架,它按照分層的方式來架構,使用這種方式可以使各層解耦。
Dubbo在調用遠程的服務的時候再本地有一個介面,就想調用本地方法一樣去調用,底層實現好參數傳輸和遠程服務運行結果傳回之後的返回。
Dubbo的特點:
(1)它主要使用高效的網路框架和序列化框架,讓分布式服務之間調用效率更高。
(2)採用注冊中心管理眾多的服務介面地址,當你想調用服務的時候只需要跟注冊中心詢問即可,不像使用WebService一樣每個服務都得記錄好介面調用方式。
(3)監控中心時實現服務方和調用方之間運行狀態的監控,還能控制服務的優先順序、許可權、權重、上下線等,讓整個龐大的分布式服務系統的維護和治理比較方便。
(4)高可用,如果有服務掛了,注冊中心就會從服務列表去掉該節點,客戶端會像注冊中心請求另一台可用的服務節點重新調用。同時注冊中心也能實現高可用(ZooKeeper)。
(5)負載均衡,採用軟負載均衡演算法實現對多個相同服務的節點的請求負載均衡。
Dubbo需要四大基本組件:Rigistry,Monitor,Provider,Consumer。
1、監控中心的配置文件-bbo.properties文件
(1)容器,監控中心是在jetty和spring環境下運行,依賴於注冊中心,日誌系統是log4j
bbo.container = log4j,spring,registry,jetty
(2)監控服務的名稱,監控系統對整個Dubbo服務系統來說也是一個服務
bbo.application.name = simple-monitor
(3)服務的所有者,這是Dubbbo的服務的功能,可以指定服務的負責人
bbo.application.owner = coselding
(4)注冊中心的地址,配置後監控中心就能通過注冊中心獲取當前可用的服務列表及其狀態,在頁面向你匯報Dubbo中的服務運行情況。
bbo.registr.address = multicast://{ip}:{port} //廣播
bbo.registr.address = zookeeper://{ip}:{port} //zookeper
bbo.registr.address = redis://{ip}:{port} //redis
bbo.registr.address = bbo://{ip}:{port} //bbo
(5)bbo協議埠號
bbo.protocol.port = 7070
(6)jetty工作埠號
bbo.jetty.port = 8082
(7)工作目錄,用於存放監控中心的數據
bbo.jetty.directory = ${user.home}/monitor
(8)監控中心報表存放目錄
bbo.charts.directory=${bbo.jetty.directory}/charts
(9)監控中心數據資料目錄
bbo.statistics.directory=${user.home}/monitor/statistics
(10)監控中心日誌文件路徑
bbo.log4j.file=logs/bbo-monitor-simple.log
(11)監控中心日誌記錄級別
bbo.log4j.level=WARN
2、Dubbo提供負載均衡方式
(1)Random,隨機,按權重配置隨機概率,調用量越大分布越均勻,默認方式。
(2)RounRobin,輪詢,按權重設置輪詢比例,如果存在比較慢的機器容易在這台機器上請求阻塞較多。
(3)LeastActive,最少活躍調用數,不支持權重,只能根據自動識別的活躍數分配,不能靈活調配。
(4)ConsistenHash,一致性hash,對相同參數的請求路由到一個服務提供者上,如果有類似灰度發布需求可採用。
3、Dubbo過濾器
Dubbo初始化過程載入ClassPath下的META-INF/bbo/internal/,META-INF/bbo/,META-INF/services/三個路徑下的com.alibaba.bbo.rpc.Filter文件。文件內容:
Name = FullClassName,這些類必須實現Filter介面。
自定義Filter類:
配置文件在配置過濾器,consumer.xml中:
Dubbo對過濾器的載入過程:
先載入三個路徑下的com.alibaba.bbo.rpc.Filter文件裡面的鍵值對,key為過濾器名稱,value為過濾器的類的全限定名(這個類必須實現Dubbo中的Filter介面)。
自定義的類中@Active註解是過濾器設定的全局基本屬性。
Spring在載入consumer.xml文件時,通過 <bbo:consumer filter="xxx" id = "xxx" retrries = "0">這個配置指定消費者端要載入的過濾器,通過filter屬性指定過濾器名稱。
@Activate註解-自動激活,group屬性是表示匹配了對應的角色才被載入,value表示表明過濾條件,不寫則表示所有條件都會被載入,寫了則只有bbo URL中包含該參數名且參數值不為空才被載入,這個參數會以bbo協議的一個參數K-V對傳到Provider。
4、Dubbo的Provider配置
5、Dubbo的Consumer配置
1、Dubbo是什麼?
Dubbo是阿里巴巴開源的基於Java的高性能RPC分布式框架。
2、為什麼使用Dubbo?
很多公司都在使用,經過很多線上的考驗,內部使用了Netty,Zookeeper,保證了高性能可用性。
使用Dubbo可以將核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,可以提高業務復用靈活性擴展,使前端應用能快速的響應對邊的市場需求。分布式架構可以承受更大規模的並發流量。
Dubbo的服務治理圖:
3、Dubbo和Spring Cloud的區別
兩個沒有關聯,但是非要說區別,有如下幾點:
(1)通信方式不同,Dubbo使用RPC通信,Spring Cloud使用HTTP Restful方式
(2)組成部分不同
4、Dubbo支持的協議
bbo:// (推薦);rmi:// ;hessian:// ;http:// ;webservice:// ;thrift:// ;memcached:// ;redis:// ;rest:// 。
5、Dubbo需要容器嗎?
不需要,如果硬要容器的話,會增加復雜性,同時也浪費資源。
6、Dubbo內置的服務容器
Spring Container;Jetty Container;Log4j Container。
7、Dubbo中節點角色
Register,Monitor,Provider,Consumer,Container(服務運行的容器)。
8、Dubbo的服務注冊和發現的流程圖
9、Dubbo的注冊中心
默認使用Zookeper作為注冊中心,還有Redis,Multicast,bbo注冊中心。
10、Dubbo的配置方式
Spring配置方式和Java API配置方式
11、Dubbo的核心配置
(1)bbo:service 服務配置
(2)bbo:referece 引用配置
(3)bbo:protocol 協議配置
(4)bbo:application 應用配置
(5)bbo:registry 注冊中心配置
(6)bbo:monitor 監控中心配置
(7)bbo:provider 提供方配置
(8)bbo:consumer 消費方配置
(9)bbo:method 方法配置
(10)bbo:argument 參數配置
12、在Provider 節點上可以配置Consumer端的屬性有哪些?
(1)timeout:方法調用超時
(2)retries:失敗重試次數,默認是2次
(3)loadbalance:負載均衡演算法,默認隨機
(4)actives消費者端,最大並發調用控制
13、Dubbo啟動時如果依賴的服務不可用會怎樣
Dubbo預設會在啟動時檢查依賴的服務是否可用,不可用時會拋出異常,阻止Spring初始化完成。默認check ="true"。
14、Dubbo序列化框架
推薦使用Hessian序列化,還有Dubbo,Fastjson,Java自帶序列化。
15、Dubbo的通信框架
默認使用Netty框架,另外也提供了Mina,Grizzly。
16、Dubbo集群容錯方案
(1)Failover Cluster,失敗自動切換,自動重試其他伺服器。
(2)Failfast Cluster,快速失敗,立即報錯,只發起一次調用。
(3)Failsafe Cluster,失敗安全,出現異常時,直接忽略。
(4)Failback Cluster,失敗自動恢復,記錄失敗請求,定時重發。
(5)Forking Cluster,並行調用多個伺服器,只要一個返回成功即可。
(6)Broadcast Cluster,廣播逐個調用所有提供者,任意一個報錯則報錯。
17、Dubbo的負載均衡策略
(1)Random LoadBalance,隨機,按權重設置隨機概率,默認。
(2)RoundRobin LoadBalace,輪詢,按公約後的權重設置輪訓比例。
(3)LeastActive LoadBalace,最少活躍調用數,相同活躍數的隨機。
(4)ConsistenHash LoadBalance,一致性hash,相同參數的請求總是發到用一個伺服器。
18、指定某一個服務
可以配置環境點對點直連,繞過注冊中心,將以服務介面為單位,忽略注冊中心的提供者列表。
<bbo:reference interface="com.weidian.bbo.IMyDemo" version="1.0" id="myDemo" url="bbo://127.0.0.1:20880/"></bbo:reference>
19、Dubbo多協議
Dubbo允許配置多協議,在不同伺服器上支持不同協議,或者同一服務支持多種協議。
20、當一個服務有多種實現時怎麼做?
當一個介面有多種是現實,可以用group屬性來分組,服務提供方和消費方都指定同一個group即可。
21、兼容舊版本
使用版本號過度,多個不同版本的服務注冊到注冊中心,版本號不同的服務相互間不引用。
22、Dubbo可以緩存嗎?
Dubbo提供聲明式緩存,用於加速熱門數據的訪問速度,以減少用戶加緩存的工作量。
23、Dubbo服務之間的調用時阻塞的嗎?
默認是同步等待結果阻塞的,支持非同步調用。Dubbo是基於NIO的非阻塞實現並行調用的,客戶端不需要啟動多線程即可完成並行調用多個遠程服務,相對多線程開銷較小,非同步調用會返回一個Future對象。
24、Dubbo不支持分布式事務
25、Dubbo必須依賴的包
Dubbo必須依賴JDK,其他為可選。
26、Dubbo使用過程中的問題
Dubbo的設計目的是為了滿足高並發小數據量的rpc請求,在大數據量下性能表現不是很好,建議使用rmi或http協議。
27、Dubbo的管理控制台的作用
路由規則,動態配置,服務降級,訪問控制,權重調整,負載均衡。
28、Spring boot整合Dubbo
(1)添加依賴
<!-- https://mvnrepository.com/artifact/com.alibaba.boot/bbo-spring-boot-project -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>bbo-spring-boot-starter</artifactId>
<version>0.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.101tec/zkclient -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
(2)配置bbo
## Dubbo 服務提供者配置
spring.bbo.application.name=provider
spring.bbo.registry.address=zookeeper://127.0.0.1:2181
spring.bbo.protocol.name=bbo
spring.bbo.protocol.port=20880
spring.bbo.scan=org.spring.springboot.bbo
## Dubbo 服務消費者配置
spring.bbo.application.name=consumer
spring.bbo.registry.address=zookeeper://127.0.0.1:2181
spring.bbo.scan=org.spring.springboot.bbo
⑦ eclipse jetty啟動bbo 怎麼配置
eclipse jetty啟動
DUBBO安裝配置注意事項
管理端:
記得更改TOMCAT的埠號,不然會和監控器的8080沖突(如何部署在同一機器)
bbo.properties 文件
bbo.registry.address=zookeeper://x.x.x.x:2181
bbo.admin.root.password=用戶
bbo.admin.guest.password=密碼
=============
監控端:
bbo.properties文件
bbo.container=log4j,spring,registry,jetty
bbo.application.name=simple-monitor
bbo.application.owner=
#bbo.registry.address=multicast://224.5.6.7:1234
#bbo.registry.address=zookeeper://127.0.0.1:2181
#bbo.registry.address=redis://127.0.0.1:6379
#bbo.registry.address=bbo://127.0.0.1:9090
bbo.registry.address=zookeeper://x.x.x.x:2181
bbo.protocol.port=7070
bbo.jetty.port=8080
bbo.jetty.directory=${user.home}/monitor
bbo.charts.directory=${bbo.jetty.directory}/charts
bbo.statistics.directory=${user.home}/monitor/statistics
bbo.log4j.file=logs/bbo-monitor-simple.log
bbo.log4j.level=WARN
在安裝的時候,小嶠同學遇到了一個妖怪的問題,就是監控端可能只能在JDK1.8以上的版本才能啟動,在JDK1.7上啟動時,老是說什麼MONITOR進程已存在啟動,然後就停了。
我直接注釋相關的SHELL就搞定了。。
不知對不對。。
if [ -z "$SERVER_NAME" ]; then
SERVER_NAME=`hostname`fi#PIDS=`ps -f | grep java | grep "$CONF_DIR" |awk '{print $2}'`
#if [ -n "$PIDS" ]; then
# echo "ERROR: The $SERVER_NAME already started!"
# echo "PID: $PIDS"
# exit 1
#fiif [ -n "$SERVER_PORT" ]; then
SERVER_PORT_COUNT=`netstat -tln | grep $SERVER_PORT | wc -l` if [ $SERVER_PORT_COUNT -gt 0 ]; then
echo "ERROR: The $SERVER_NAME port $SERVER_PORT already used!"
exit 1
fifi
⑧ Dubbo與Zookeeper集群配置
bbo.properties配置:
bbo.application.name=sdp_order_srv
#zk集群的時候bbo只能這樣配置
bbo.service.register.address=zookeeper://10.10.100.152:3181?backup=10.10.100.152:4181,10.10.100.152:5181
#zk單點的話下面兩種簡辯配置都可乎念以
#bbo.service.register.address=zookeeper:/攔頃缺/${zookeeper.address}
#bbo.service.register.address=zookeeper://10.1.203.171:2181
bbo.service.protocol.name=bbo
bbo.service.protocol.port=20885
zk配置
#\u7cfb\u7edf\u53c2\u6570\u914d\u7f6e
zookeeper.sessionTimeout=60000
zookeeper.connectionTimeout=5000
#zk集群配置
zookeeper.address=10.10.100.152:3181,10.10.100.152:4181,10.10.100.152:5181
zookeeper.connect.status=true
zookeeper.connect.countersign=false
zookeeper.connect.username=
zookeeper.connect.password=
⑨ Dubbo——HTTP 協議 + JSON-RPC
Protocol 還有一個實現分支是 AbstractProxyProtocol,如下圖所示:
從圖中我們可以看到:gRPC、HTTP、WebService、Hessian、Thrift 等協議對應的 Protocol 實現,都是繼承自 AbstractProxyProtocol 抽象類。
目前互聯網的技術棧百花齊放,很多公司會使用 Node.js、Python、Rails、Go 等語言來開發 一些 Web 端應用,同時又有很多服務會使用 Java 技術棧實現,這就出現了大量的跨語言調用的需求。Dubbo 作為一個 RPC 框架,自然也希望能實現這種跨語言的調用,目前 Dubbo 中使用「HTTP 協議 + JSON-RPC」的方式來達到這一目的,其中 HTTP 協議和 JSON 都是天然跨語言的標准,在各種語言中都有成熟的類庫。
下面就重點來分析 Dubbo 對 HTTP 協議的支持。首先,會介紹 JSON-RPC 的基礎,並通過一個示例,快速入門,然後介紹 Dubbo 中 HttpProtocol 的具體實現,也就是如何將 HTTP 協議與 JSON-RPC 結合使用,實現跨語言調用的效果。
Dubbo 中支持的 HTTP 協議實際上使用的是 JSON-RPC 協議。
JSON-RPC 是基於 JSON 的跨語言遠程調用協議。Dubbo 中的 bbo-rpc-xml、bbo-rpc-webservice 等模塊支持的 XML-RPC、WebService 等協議與 JSON-RPC 一樣,都是基於文本的協議,只不過 JSON 的格式比 XML、WebService 等格式更加簡潔、緊湊。與 Dubbo 協議、Hessian 協議等二進制協議相比,JSON-RPC 更便於調試和實現,可見 JSON-RPC 協議還是一款非常優秀的遠程調用協議。
在 Java 體系中,有很多成熟的 JSON-RPC 框架,例如 jsonrpc4j、jpoxy 等,其中,jsonrpc4j 本身體積小巧,使用方便,既可以獨立使用,也可以與 Spring 無縫集合,非常適合基於 Spring 的項目。
下面先來看看 JSON-RPC 協議中請求的基本格式:
JSON-RPC請求中各個欄位的含義如下:
在 JSON-RPC 的服務端收到調用請求之後,會查找到相應的方法並進行調用,然後將方法的返回值整理成如下格式,返回給客戶端:
JSON-RPC響應中各個欄位的含義如下:
Dubbo 使用 jsonrpc4j 庫來實現 JSON-RPC 協議,下面使用 jsonrpc4j 編寫一個簡單的 JSON-RPC 服務端示例程序和客戶端示常式序,並通過這兩個示常式序說明 jsonrpc4j 最基本的使用方式。
首先,需要創建服務端和客戶端都需要的 domain 類以及服務介面。先來創建一個 User 類,作為最基礎的數據對象:
接下來創建一個 UserService 介面作為服務介面,其中定義了 5 個方法,分別用來創建 User、查詢 User 以及相關信息、刪除 User:
UserServiceImpl 是 UserService 介面的實現類,其中使用一個 ArrayList 集合管理 User 對象,具體實現如下:
整個用戶管理業務的核心大致如此。下面我們來看服務端如何將 UserService 與 JSON-RPC 關聯起來。
首先,創建 RpcServlet 類,它是 HttpServlet 的子類,並覆蓋了 HttpServlet 的 service() 方法。我們知道,HttpServlet 在收到 GET 和 POST 請求的時候,最終會調用其 service() 方法進行處理;HttpServlet 還會將 HTTP 請求和響應封裝成 HttpServletRequest 和 HttpServletResponse 傳入 service() 方法之中。這里的 RpcServlet 實現之中會創建一個 JsonRpcServer,並在 service() 方法中將 HTTP 請求委託給 JsonRpcServer 進行處理:
最後,創建一個 JsonRpcServer 作為服務端的入口類,在其 main() 方法中會啟動 Jetty 作為 Web 容器,具體實現如下:
這里使用到的 web.xml 配置文件如下:
完成服務端的編寫之後,下面再繼續編寫 JSON-RPC 的客戶端。在 JsonRpcClient 中會創建 JsonRpcHttpClient,並通過 JsonRpcHttpClient 請求服務端:
在 AbstractProxyProtocol 的 export() 方法中,首先會根據 URL 檢查 exporterMap 緩存,如果查詢失敗,則會調用 ProxyFactory.getProxy() 方法將 Invoker 封裝成業務介面的代理類,然後通過子類實現的 doExport() 方法啟動底層的 ProxyProtocolServer,並初始化 serverMap 集合。具體實現如下:
在 HttpProtocol 的 doExport() 方法中,與前面介紹的 DubboProtocol 的實現類似,也要啟動一個 RemotingServer。為了適配各種 HTTP 伺服器,例如,Tomcat、Jetty 等,Dubbo 在 Transporter 層抽象出了一個 HttpServer 的介面。
bbo-remoting-http 模塊的入口是 HttpBinder 介面,它被 @SPI 註解修飾,是一個擴展介面,有三個擴展實現,默認使用的是 JettyHttpBinder 實現,如下圖所示:
HttpBinder 介面中的 bind() 方法被 @Adaptive 註解修飾,會根據 URL 的 server 參數選擇相應的 HttpBinder 擴展實現,不同 HttpBinder 實現返回相應的 HttpServer 實現。HttpServer 的繼承關系如下圖所示:
這里以 JettyHttpServer 為例簡單介紹 HttpServer 的實現,在 JettyHttpServer 中會初始化 Jetty Server,其中會配置 Jetty Server 使用到的線程池以及處理請求 Handler:
可以看到 JettyHttpServer 收到的全部請求將委託給 DispatcherServlet 這個 HttpServlet 實現,而 DispatcherServlet 的 service() 方法會把請求委託給對應接埠的 HttpHandler 處理:
了解了 Dubbo 對 HttpServer 的抽象以及 JettyHttpServer 的核心之後,回到 HttpProtocol 中的 doExport() 方法繼續分析。
在 HttpProtocol.doExport() 方法中會通過 HttpBinder 創建前面介紹的 HttpServer 對象,並記錄到 serverMap 中用來接收 HTTP 請求。這里初始化 HttpServer 以及處理請求用到的 HttpHandler 是 HttpProtocol 中的內部類,在其他使用 HTTP 協議作為基礎的 RPC 協議實現中也有類似的 HttpHandler 實現類,如下圖所示:
在 HttpProtocol.InternalHandler 中的 handle() 實現中,會將請求委託給 skeletonMap 集合中記錄的 JsonRpcServer 對象進行處理:
skeletonMap 集合中的 JsonRpcServer 是與 HttpServer 對象一同在 doExport() 方法中初始化的。最後,我們來看 HttpProtocol.doExport() 方法的實現:
介紹完 HttpProtocol 暴露服務的相關實現之後,下面再來看 HttpProtocol 中引用服務相關的方法實現,即 protocolBindinRefer() 方法實現。該方法首先通過 doRefer() 方法創建業務介面的代理,這里會使用到 jsonrpc4j 庫中的 JsonProxyFactoryBean 與 Spring 進行集成,在其 afterPropertiesSet() 方法中會創建 JsonRpcHttpClient 對象:
下面來看 doRefer() 方法的具體實現:
在 AbstractProxyProtocol.protocolBindingRefer() 方法中,會通過 ProxyFactory.getInvoker() 方法將 doRefer() 方法返回的代理對象轉換成 Invoker 對象,並記錄到 Invokers 集合中,具體實現如下:
本文重點介紹了在 Dubbo 中如何通過「HTTP 協議 + JSON-RPC」的方案實現跨語言調用。首先介紹了 JSON-RPC 中請求和響應的基本格式,以及其實現庫 jsonrpc4j 的基本使用;接下來我們還詳細介紹了 Dubbo 中 AbstractProxyProtocol、HttpProtocol 等核心類,剖析了 Dubbo 中「HTTP 協議 + JSON-RPC」方案的落地實現。
⑩ 【bbo源碼】5.配置信息解析-註解版
用於把bbo.properties讀到spring的environment中,
這個工作是由Spring的類來完成的.檢測到某個需要注冊的Bean上有@PropertySource註解,就會讀該文件的配置信息,弄到environment對象的MutablePropertySources對象中。
後期會把配置信息弄到bbo 配置類中.
該註解上還有@DubboComponentScan,@EnableDubboConfig,這兩個註解是bbo用註解與spring集成的核心了
該註解用@import導入了這個類
實現了ImportBeanDefinitionRegistrar介面,那麼spring在實例化的時候會調用重寫ImportBeanDefinitionRegistrar介面的registerBeanDefinitions方法,並且將用亮逗@Import導入的類的元數據包裝成importingClassMetadata對象。
其實就是為了獲取入口類AnnoBean上的@EnableDubboConfig註解里的multiple屬性配置的值,默認是true.
然後注冊了兩個DubboConfigConfiguration的內部類
通過讀Class對象注冊到ioc容器
類上有@EnableDubboConfigBindings,值為@EnableDubboConfigBinding數組
通過綁定,將有對應前綴的配置信拍鍵含息賦值到對應的配置類中
又用@Import導入DubboConfigBindingsRegistrar類,DubboConfigBindingsRegistrar這個類又實現了ImportBeanDefinitionRegistrar,EnvironmentAware介面
實現ImportBeanDefinitionRegistrar肯定是為了另外導襲笑入一些類,並且拿到導入的源類,獲取源類上配置的信息
實現EnvironmentAware是為了拿到spring的environment對象,因為 bbo.properties 已經被@PropertySource註解機制載入到了environment.MutablePropertySources中,在這里只對beanName的創建有作用。
registrar.registerBeanDefinitions :
注冊的過程中,需要從environment對象中拿bbo相關的配置,比如ApplicationConfig只拿
bbo.application.*相關的配置,然後創建ApplicationConfig的BeanDefinition.
如果 @EnableDubboConfigBinding配置的multiple為true(默認為false),並且在配置文件中配置了同樣前綴的屬性,如:
這樣會為同一種配置類型,生成兩個BD.beanName不同的配置Bean,名稱規則如下所示, #0表示的是'.'在配置的key中出現的位置
之後還會注冊一個BeanPostProcessor類型的類的beanDefinition,BeanPostProcessor類型 會在每一個Bean實例化的過程中,根據配置的前綴,從environment拿出所需的配置,根據beanName來處理beanName相同的這一個配置Bean,把配置信息綁定到配置類的屬性中。
.
利用 bboConfigBinder 對象來綁定前綴為bbo.application的配置信息到配置Bean中
這里bboConfigBinder對象是中的一個屬性,是在因為這個類實現了InitializingBean這個介面的afterPropertiesSet方法,bboConfigBinder對象就是在這里初始化的
最後用的DataBinder的api把一個MutablePropertyValues綁定到Bean的屬性
@import進來了DubboComponentScanRegistrar類
DubboComponentScanRegistrar又實現了ImportBeanDefinitionRegistrar介面,實現registerBeanDefinitions方法.
跟xml的邏輯一樣,同樣是