上面调用了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),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。