Dubbo配置以及使用总结

来源:互联网 发布:无线传感器软件 编辑:程序博客网 时间:2024/06/10 22:05

一直被dubbo的spring相关配置搞得比较晕,dubbo作为淘宝自己搞得东东,也没有太多像样的成系统的书籍资料,所以相关知识显得比较零碎。趁机会把相关知识尤其是配置知识整理记录一下,以供记忆。

Application层的配置

<dubbo:applicationname="dubbo-provider" />

--应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者,这一层目前只知道name字段的配置,表示应用的名字,服务端和客户端名字不同

Registry层的配置

<dubbo:registryprotocol="zookeeper" address="132.121.127.30:2181"  client="curator"file="D:\\dubbo_cache.txt" register="true" />

--注册中心配置,注册与注册中心相连接的相关信息,正常情况下说白了就是和zookeeper连接的相关信息,包括连接协议protocol="zookeeper",zookeeper的ip:port, client默认是zkclient,至于curator和zkclient的区别后续还需进一步了解。File字段是持久化了dubbo服务提供者的ip:端口等相关信息,目的是为了在注册中心挂掉的情况下,消费者可以使用本地持久化的这份缓存文件去寻找服务提供者。Register为false时表示服务提供者不注册到注册中心,默认是true。

Protocol层的配置

<dubbo:protocol name="dubbo"port="20880" dispatcher="all" threadpool="fixed"accesslog="D:\\dubbo.log" />

--协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。(意思是消费端不需要这块配置,服务提供方配就行),name="dubbo"协议一般用的就是dubbo协议,好像也支持其他协议。Port就是服务提供者的服务端口。dispatcher="all"表示所有的请求响应消息都派发到线程池中。threadpool="fixed"表示线程池是固定大小的,启动时就建立线程。Accesslog字段是表示存储消费者访问提供者命令的文件。(通过该文件可以查询到任意时刻消费者访问提供者的相关命令)

 

事件处理线程说明

如果事件处理的逻辑能迅速完成,并且不会发起新的IO请求,比如只是在内存中记个标识,则直接在IO线程上处理更快,因为减少了线程池调度。

但如果事件处理逻辑较慢,或者需要发起新的IO请求,比如需要查询数据库,则必须派发到线程池,否则IO线程阻塞,将导致不能接收其它请求。

如果用IO线程处理事件,又在事件处理过程中发起新的IO请求,比如在连接事件中发起登录请求,会报“可能引发死锁”异常,但不会真死锁。

 

Dispatcher

all 所有消息都派发到线程池,包括请求,响应,连接事件,断开事件,心跳等。

direct 所有消息都不派发到线程池,全部在IO线程上直接执行。

message 只有请求响应消息派发到线程池,其它连接断开事件,心跳等消息,直接在IO线程上执行。

execution 只请求消息派发到线程池,不含响应,响应和其它连接断开事件,心跳等消息,直接在IO线程上执行。

connection 在IO线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池。

 

ThreadPool

fixed 固定大小线程池,启动时建立线程,不关闭,一直持有。(缺省)

cached 缓存线程池,空闲一分钟自动删除,需要时重建。

limited 可伸缩线程池,但池中的线程数只会增长不会收缩。(为避免收缩时突然来了大流量引起的性能问题)。

 

Service层的配置

<dubbo:serviceinterface="server.DubboProvider" ref="DubboProvider"executes="100" />

--服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心。Interface要配接口名(必须是接口,如果是实现类的话会报错)。Ref配的是实现类的bean id,比如<bean id="DubboProvider"class="server.DubboProviderImpl" />,executes表示的是服务级别的最大并发执行数。如果想禁止消费者绕过注册中心直接通过服务提供者的地址访问服务,可以再服务提供者的配置那边加上token项,比如token=”123456”,这样一来消费者就得必须经过注册中心才能得到token,才能访问服务提供者,否则就报错,这一层配置是服务提供者独有的。

 

Reference层的配置

<dubbo:referenceid="DubboProvider" interface="server.DubboProvider"url="dubbo://192.168.1.103:20880/" />

--引用服务配置,用于创建一个远程服务代理,一个引用可以指向多个注册中心。其中interface要和提供者的service层的interface保持一致。Id是作为java代码getBean时的参数。如果要绕过注册中心直接访问服务提供者,则需要直接在这一层配置上要访问的服务提供者的ip:端口,比如url="dubbo://192.168.1.103:20880/"。正常情况下是应该通过注册中心去自动发现服务提供者的。比如则这一层配置是消费者独有的。

 

--以上是最基本的dubbo服务提供方和消费方的spring配置。其中Application层的配置、Registry层的配置是服务提供方和消费方都要用到的,而Protocol层的配置、Service层的配置是服务提供方的独有的,Reference层的配置是消费方独有的。搞清楚这个大框架就基本能使用dubbo的基本xml配置。

 

除了上面所述那些,还有几个相对少用到的配置层(见绿色内容)

<dubbo:service/> 服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心。

eg、<dubbo:serviceref="demoService"interface="com.unj.dubbotest.provider.DemoService" />

 

<dubbo:reference/> 引用服务配置,用于创建一个远程服务代理,一个引用可以指向多个注册中心。

eg、<dubbo:referenceid="demoService"interface="com.unj.dubbotest.provider.DemoService" />

 

<dubbo:protocol/> 协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。

eg、<dubbo:protocolname="dubbo" port="20880" />

 

<dubbo:application/> 应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者。

eg、<dubbo:applicationname="xixi_provider" />

   <dubbo:application name="hehe_consumer" />

 

<dubbo:registry/> 注册中心配置,用于配置连接注册中心相关信息。

eg、<dubbo:registryaddress="zookeeper://192.168.2.249:2181" />

 

<dubbo:module/>模块配置,用于配置当前模块信息,可选。

<dubbo:monitor/>监控中心配置,用于配置连接监控中心相关信息,可选。

<dubbo:provider/>提供方的缺省值,当ProtocolConfigServiceConfig某属性没有配置时,采用此缺省值,可选。

<dubbo:consumer/>消费方缺省配置,当ReferenceConfig某属性没有配置时,采用此缺省值,可选。

<dubbo:method/>方法配置,用于ServiceConfigReferenceConfig指定方法级的配置信息。

<dubbo:argument/>用于指定方法参数配置。

 

使用dubbo需要代码方面注意的一个地方:

Dubbo还有一个比较奇怪的地方,就是在代码启动服务提供方时,程序会自动结束退出而不是自动阻塞等待访问,所以需要手工在服务提供方的中添加上阻塞线程的代码,比如

synchronized (springContext) {

                while(true){

                    try {

                                               springContext.wait();

                                     }catch (InterruptedException e) {

                                               //TODO Auto-generated catch block

                                               e.printStackTrace();

                                     }

           }

                   }

--这样就能使主线程一直保持阻塞状态(并且是无法唤醒),等待消费端的访问。

 

而消费方就恰恰相反,服务调用完了程序也会一直阻塞不结束,所以也得手工去添加结束spring容器生命周期和程序强制退出的代码,比如:

springContext.close();

System.exit(0);

原创粉丝点击