上面調用了DubboServer類的靜態方法startServer,如下所示:
01 |
public static void startServer(String
config) { |
02 |
ClassPathXmlApplicationContext
context = new ClassPathXmlApplicationContext(config); |
03 |
try { |
04 |
context.start(); |
05 |
System.in.read(); |
06 |
} catch (IOException
e) { |
07 |
e.printStackTrace(); |
08 |
} finally { |
09 |
context.close(); |
10 |
} |
11 |
} |
方法中主要是初始化Spring IoC容器,全部對象都交由容器來管理。
- 服務消費方
服務消費方就容易了,只需要知道註冊中心地址,並引用服務提供方提供的接口,消費方調用服務實現如下所示:
01 |
package org.shirdrn.dubbo.consumer; |
02 |
03 |
import java.util.Arrays; |
04 |
import java.util.List; |
05 |
06 |
import org.apache.commons.logging.Log; |
07 |
import org.apache.commons.logging.LogFactory; |
08 |
import org.shirdrn.dubbo.api.ChatRoomOnlineUserCounterService; |
09 |
import org.springframework.context.support.AbstractXmlApplicationContext; |
10 |
import org.springframework.context.support.ClassPathXmlApplicationContext; |
11 |
12 |
public class ChatRoomDubboConsumer
{ |
13 |
14 |
private static final Log
LOG = LogFactory.getLog(ChatRoomDubboConsumer. class ); |
15 |
|
16 |
public static void main(String[]
args) throws Exception
{ |
17 |
AbstractXmlApplicationContext
context = new ClassPathXmlApplicationContext( "classpath:consumer.xml" ); |
18 |
try { |
19 |
context.start(); |
20 |
ChatRoomOnlineUserCounterService
chatRoomOnlineUserCounterService = (ChatRoomOnlineUserCounterService) context.getBean( "chatRoomOnlineUserCounterService" ); |
21 |
getMaxOnlineUserCount(chatRoomOnlineUserCounterService); |
22 |
getRealtimeOnlineUserCount(chatRoomOnlineUserCounterService); |
23 |
System.in.read(); |
24 |
} finally { |
25 |
context.close(); |
26 |
} |
27 |
|
28 |
} |
29 |
30 |
private static void getMaxOnlineUserCount(ChatRoomOnlineUserCounterService
liveRoomOnlineUserCountService) { |
31 |
List<String>
maxUserCounts = liveRoomOnlineUserCountService.getMaxOnlineUserCount( |
32 |
Arrays.asList( new String[]
{ "1482178010" , "1408492761" , "1430546839" , "1412517075" , "1435861734" }), "20150327" , "yyyyMMdd" ); |
33 |
LOG.info( "After
getMaxOnlineUserCount invoked: maxUserCounts= " +
maxUserCounts); |
34 |
} |
35 |
36 |
private static void getRealtimeOnlineUserCount(ChatRoomOnlineUserCounterService
liveRoomOnlineUserCountService) |
37 |
throws InterruptedException
{ |
38 |
String
rooms = "1482178010,1408492761,1430546839,1412517075,1435861734" ; |
39 |
String
onlineUserCounts = liveRoomOnlineUserCountService.queryRoomUserCount(rooms); |
40 |
LOG.info( "After
queryRoomUserCount invoked: onlineUserCounts= " +
onlineUserCounts); |
41 |
} |
42 |
} |
對應的配置文件爲consumer.xml,內容如下所示:
01 |
<? xml version = "1.0" encoding = "UTF-8" ?> |
02 |
03 |
< beans xmlns = "http://www.springframework.org/schema/beans" |
04 |
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo = "http://code.alibabatech.com/schema/dubbo" |
05 |
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd |
07 |
08 |
< dubbo:application name = "chatroom-consumer" /> |
09 |
< dubbo:registry address = "zookeeper://zk1:2181?backup=zk2:2181,zk3:2181" /> |
10 |
|
11 |
< dubbo:reference id = "chatRoomOnlineUserCounterService" interface = "org.shirdrn.dubbo.api.ChatRoomOnlineUserCounterService" version = "1.0.0" > |
12 |
< dubbo:method name = "queryRoomUserCount" retries = "2" /> |
13 |
</ dubbo:reference > |
14 |
15 |
</ beans > |
也可以根據需要配置dubbo:reference相關的屬性值,也可以配置dubbo:method指定調用的方法的配置信息,詳細配置屬性可以參考Dubbo官方文檔。
- 部署與驗證
開發完成提供方服務後,在本地開發調試的時候可以怎麼簡單怎麼做,如果是要部署到生產環境,則需要打包後進行部署,可以參考下面的Maven POM配置:
01 |
< build > |
02 |
< plugins > |
03 |
< plugin > |
04 |
< groupId >org.apache.maven.plugins</ groupId > |
05 |
< artifactId >maven-shade-plugin</ artifactId > |
06 |
< version >1.4</ version > |
07 |
< configuration > |
08 |
< createDependencyReducedPom >true</ createDependencyReducedPom > |
09 |
</ configuration > |
10 |
< executions > |
11 |
< execution > |
12 |
< phase >package</ phase > |
13 |
< goals > |
14 |
< goal >shade</ goal > |
15 |
</ goals > |
16 |
< configuration > |
17 |
< transformers > |
18 |
< transformer implementation = "org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" /> |
19 |
< transformer implementation = "org.apache.maven.plugins.shade.resource.ManifestResourceTransformer" > |
20 |
< mainClass >org.shirdrn.dubbo.provider.ChatRoomClusterServer</ mainClass > |
21 |
</ transformer > |
22 |
</ transformers > |
23 |
</ configuration > |
24 |
</ execution > |
25 |
</ executions > |
26 |
</ plugin > |
27 |
</ plugins > |
28 |
</ build > |
這裏也給出Maven POM依賴的簡單配置:
1 |
< dependencies > |
2 |
< dependency > |
3 |
< groupId >org.shirdrn.dubbo</ groupId > |
4 |
< artifactId >dubbo-api</ artifactId > |
5 |
< version >0.0.1-SNAPSHOT</ version > |
6 |
</ dependency > |
7 |
</ dependencies > |
我們開發的服務應該是分佈式的,首先是通過配置內容來決定,例如設置集羣模式、設置負載均衡模式等,然後在部署的時候,可以在多個節點上同一個服務,這樣多個服務都會註冊到Dubbo註冊中心,如果某個節點上的服務不可用了,可以根據我們配置的策略來選擇其他節點上的可用服務,後面通過Dubbo服務管理中心和監控中心就能更加清楚明瞭。
Dubbo服務管理與監控
我們需要在安裝好管理中心和監控中心以後,再將上面的開發的提供方服務部署到物理節點上,然後就能夠通過管理中心和監控中心來查看對應的詳細情況。
- Dubbo服務管理中心
安裝Dubbo服務管理中心,需要選擇一個Web容器,我們使用Tomcat服務器。首先下載Dubbo管理中心安裝文件dubbo-admin-2.5.3.war,或者直接從源碼構建得到該WAR文件。這裏,我們已經構建好對應的WAR文件,然後進行安裝,執行如下命令:
1 |
cd apache-tomcat-6.0.35 |
2 |
rm -rf
webapps/ROOT |
3 |
unzip
~/dubbo-admin-2.5.3.war -d webapps/ROOT |
修改配置文件~/apache-tomcat-6.0.35/webapps/ROOT/WEB-INF/dubbo.properties,指定我們的註冊中心地址以及登錄密碼,內容如下所示:
1 |
dubbo.registry.address=zookeeper://zk1:2181?backup=zk2:2181,zk3:2181 |
2 |
dubbo.admin.root.password=root |
3 |
dubbo.admin.guest.password=guest |
然後,根據需要修改~/apache-tomcat-6.0.35/conf/server.xml配置文件,主要是Tomcat HTTP 端口號(我這裏使用8083端口),完成後可以直接啓動Tomcat服務器:
1 |
cd ~/apache-tomcat-6.0.35/ |
2 |
bin/catalina.sh
start |
然後訪問地址http://10.10.4.130:8083/即可,根據配置文件指定的root用戶密碼,就可以登錄Dubbo管理控制檯。
我們將上面開發的服務提供方服務,部署到2個獨立的節點上(192.168.14.1和10.10.4.125),然後可以通過Dubbo管理中心查看對應服務的狀況,如圖所示:
上圖中可以看出,該服務有兩個獨立的節點可以提供,因爲配置的集羣模式爲failover,如果某個節點的服務發生故障無法使用,則會自動透明地重試另一個節點上的服務,這樣就不至於出現拒絕服務的情況。如果想要查看提供方某個節點上的服務詳情,可以點擊對應的IP:Port鏈接,示例如圖所示:
上圖可以看到服務地址:
1 |
dubbo://10.10.4.125:20880/org.shirdrn.dubbo.api.ChatRoomOnlineUserCounterService?actives=100&anyhost=true&application=chatroom-cluster-provider&cluster=failover&dubbo=0.0.1-SNAPSHOT&executes=200&interface=org.shirdrn.dubbo.api.ChatRoomOnlineUserCounterService&loadbalance=random&methods=getMaxOnlineUserCount,queryRoomUserCount&pid=30942&queryRoomUserCount.actives=50&queryRoomUserCount.loadbalance=leastactive&queryRoomUserCount.retries=2&queryRoomUserCount.timeout=500&retries=2&revision=0.0.1-SNAPSHOT&side=provider&timeout=1000×tamp=1427793652814&version=1.0.0 |
如果我們直接暴露該地址也是可以的,不過這種直連的方式對服務消費方不是透明的,如果以後IP地址更換,也會影響調用方,所以最好是通過註冊中心來隱蔽服務地址。同一個服務所部署在的多個節點上,也就對應對應着多個服務地址。另外,也可以對已經發布的服務進行控制,如修改訪問控制、負載均衡相關配置內容等,可以通過上圖中“消費者”查看服務消費方調用服務的情況,如圖所示:
也在管理控制檯可以對消費方進行管理控制。
- Dubbo監控中心
Dubbo監控中心是以Dubbo服務的形式發佈到註冊中心,和普通的服務時一樣的。例如,我這裏下載了Dubbo自帶的簡易監控中心文件dubbo-monitor-simple-2.5.3-assembly.tar.gz,可以解壓縮以後,修改配置文件~/dubbo-monitor-simple-2.5.3/conf/dubbo.properties的內容,如下所示:
01 |
dubbo.container=log4j,spring,registry,jetty |
02 |
dubbo.application.name=simple-monitor |
03 |
dubbo.application.owner= |
04 |
dubbo.registry.address=zookeeper://zk1:2181?backup=zk2:2181,zk3:2181 |
05 |
dubbo.protocol.port=7070 |
06 |
dubbo.jetty.port=8087 |
07 |
dubbo.jetty.directory=${user.home}/monitor |
08 |
dubbo.charts.directory=${dubbo.jetty.directory}/charts |
09 |
dubbo.statistics.directory=${user.home}/monitor/statistics |
10 |
dubbo.log4j.file=logs/dubbo-monitor-simple.log |
11 |
dubbo.log4j.level=WARN |
然後啓動簡易監控中心,執行如下命令:
1 |
cd ~/dubbo-monitor-simple-2.5.3 |
2 |
bin/start.sh |
這裏使用了Jetty Web容器,訪問地址http://10.10.4.130:8087/就可以查看監控中心,Applications選項卡頁面包含了服務提供方和消費方的基本信息,如圖所示:
上圖主要列出了所有提供方發佈的服務、消費方調用、服務依賴關係等內容。
接着,查看Services選項卡頁面,包含了服務提供方提供的服務列表,如圖所示:
點擊上圖中Providers鏈接就能看到服務提供方的基本信息,包括服務地址等,如圖所示:
點擊上圖中Consumers鏈接就能看到服務消費方的基本信息,包括服務地址等,如圖所示:
由於上面是Dubbo自帶的一個簡易監控中心,可能所展現的內容並不能滿足我們的需要,所以可以根據需要開發自己的監控中心。Dubbo也提供了監控中心的擴展接口,如果想要實現自己的監控中心,可以實現接口com.alibaba.dubbo.monitor.MonitorFactory和com.alibaba.dubbo.monitor.Monitor,其中MonitorFactory接口定義如下所示:
01 |
/** |
02 |
*
MonitorFactory. (SPI, Singleton, ThreadSafe) |
03 |
* |
04 |
*
@author william.liangf |
05 |
*/ |
06 |
@SPI ( "dubbo" ) |
07 |
public interface MonitorFactory
{ |
08 |
|
09 |
/** |
10 |
*
Create monitor. |
11 |
*
@param url |
12 |
*
@return monitor |
13 |
*/ |
14 |
@Adaptive ( "protocol" ) |
15 |
Monitor
getMonitor(URL url); |
16 |
17 |
} |
Monitor接口定義如下所示:
1 |
/** |
2 |
*
Monitor. (SPI, Prototype, ThreadSafe) |
3 |
* |
4 |
*
@see com.alibaba.dubbo.monitor.MonitorFactory#getMonitor(com.alibaba.dubbo.common.URL) |
5 |
*
@author william.liangf |
6 |
*/ |
7 |
public interface Monitor extends Node,
MonitorService { |
8 |
9 |
} |
具體定義內容可以查看MonitorService接口,不再累述。
總結
Dubbo還提供了其他很多高級特性,如路由規則、參數回調、服務分組、服務降級等等,而且很多特性在給出內置實現的基礎上,還給出了擴展的接口,我們可以給出自定義的實現,非常方便而且強大。更多可以參考Dubbo官網用戶手冊和開發手冊。
附錄:Dubbo使用Maven構建依賴配置
01 |
< properties > |
02 |
< spring.version >3.2.8.RELEASE</ spring.version > |
03 |
< project.build.sourceEncoding >UTF-8</ project.build.sourceEncoding > |
04 |
</ properties > |
05 |
06 |
< dependencies > |
07 |
< dependency > |
08 |
< groupId >com.alibaba</ groupId > |
09 |
< artifactId >dubbo</ artifactId > |
10 |
< version >2.5.3</ version > |
11 |
< exclusions > |
12 |
< exclusion > |
13 |
< groupId >org.springframework</ groupId > |
14 |
< artifactId >spring</ artifactId > |
15 |
</ exclusion > |
16 |
< exclusion > |
17 |
< groupId >org.apache.zookeeper</ groupId > |
18 |
< artifactId >zookeeper</ artifactId > |
19 |
</ exclusion > |
20 |
< exclusion > |
21 |
< groupId >org.jboss.netty</ groupId > |
22 |
< artifactId >netty</ artifactId > |
23 |
</ exclusion > |
24 |
</ exclusions > |
25 |
</ dependency > |
26 |
< dependency > |
27 |
< groupId >org.springframework</ groupId > |
28 |
< artifactId >spring-core</ artifactId > |
29 |
< version >${spring.version}</ version > |
30 |
</ dependency > |
31 |
< dependency > |
32 |
< groupId >org.springframework</ groupId > |
33 |
< artifactId >spring-beans</ artifactId > |
34 |
< version >${spring.version}</ version > |
35 |
</ dependency > |
36 |
< dependency > |
37 |
< groupId >org.springframework</ groupId > |
38 |
< artifactId >spring-context</ artifactId > |
39 |
< version >${spring.version}</ version > |
40 |
</ dependency > |
41 |
< dependency > |
42 |
< groupId >org.springframework</ groupId > |
43 |
< artifactId >spring-context-support</ artifactId > |
44 |
< version >${spring.version}</ version > |
45 |
</ dependency > |
46 |
< dependency > |
47 |
< groupId >org.springframework</ groupId > |
48 |
< artifactId >spring-web</ artifactId > |
49 |
< version >${spring.version}</ version > |
50 |
</ dependency > |
51 |
52 |
< dependency > |
53 |
< groupId >org.slf4j</ groupId > |
54 |
< artifactId >slf4j-api</ artifactId > |
55 |
< version >1.6.2</ version > |
56 |
</ dependency > |
57 |
< dependency > |
58 |
< groupId >log4j</ groupId > |
59 |
< artifactId >log4j</ artifactId > |
60 |
< version >1.2.16</ version > |
61 |
</ dependency > |
62 |
< dependency > |
63 |
< groupId >org.javassist</ groupId > |
64 |
< artifactId >javassist</ artifactId > |
65 |
< version >3.15.0-GA</ version > |
66 |
</ dependency > |
67 |
< dependency > |
68 |
< groupId >com.alibaba</ groupId > |
69 |
< artifactId >hessian-lite</ artifactId > |
70 |
< version >3.2.1-fixed-2</ version > |
71 |
</ dependency > |
72 |
< dependency > |
73 |
< groupId >com.alibaba</ groupId > |
74 |
< artifactId >fastjson</ artifactId > |
75 |
< version >1.1.8</ version > |
76 |
</ dependency > |
77 |
< dependency > |
78 |
< groupId >org.jvnet.sorcerer</ groupId > |
79 |
< artifactId >sorcerer-javac</ artifactId > |
80 |
< version >0.8</ version > |
81 |
</ dependency > |
82 |
< dependency > |
83 |
< groupId >org.apache.zookeeper</ groupId > |
84 |
< artifactId >zookeeper</ artifactId > |
85 |
< version >3.4.5</ version > |
86 |
</ dependency > |
87 |
< dependency > |
88 |
< groupId >com.github.sgroschupf</ groupId > |
89 |
< artifactId >zkclient</ artifactId > |
90 |
< version >0.1</ version > |
91 |
</ dependency > |
92 |
< dependency > |
93 |
< groupId >org.jboss.netty</ groupId > |
94 |
< artifactId >netty</ artifactId > |
95 |
< version >3.2.7.Final</ version > |
96 |
</ dependency > |
97 |
</ dependencies > |
參考鏈接
- http://alibaba.github.io/dubbo-doc-static/User+Guide-zh.htm
- http://alibaba.github.io/dubbo-doc-static/User+Guide-zh.htm#UserGuide-zh-%E9%9B%86%E7%BE%A4%E5%AE%B9%E9%94%99
- http://alibaba.github.io/dubbo-doc-static/cluster.jpg-version=1&modificationDate=1321028038000.jpg
- http://alibaba.github.io/dubbo-doc-static/User+Guide-zh.htm#UserGuide-zh-%E7%AD%96%E7%95%A5%E6%88%90%E7%86%9F%E5%BA%A6
- http://alibaba.github.io/dubbo-doc-static/User+Guide-zh.htm#UserGuide-zh-%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1
- http://alibaba.github.io/dubbo-doc-static/Developer+Guide-zh.htm#DeveloperGuide-zh-%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1%E6%89%A9%E5%B1%95
- http://coolshell.cn/articles/4787.html
- http://shiyanjun.cn/archives/349.html
- http://shiyanjun.cn/archives/341.html
本文基於署名-非商業性使用-相同方式共享 4.0許可協議發佈,歡迎轉載、使用、重新發布,但務必保留文章署名時延軍(包含鏈接:http://shiyanjun.cn),不得用於商業目的,基於本文修改後的作品務必以相同的許可發佈。如有任何疑問,請與我聯繫。