• Dubbo探索(二)


    spring配置解析

    1、<dubbo:service/>

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

    <dubbo:service ref="userService" interface="com.patty.dubbo.api.service.UserService"/>
    interface用于指定接口名,ref指定服务引用对象,这两者必填,此外还有一些其他属性可供选择,比如:
    group: 服务分组,当一个接口有多个实现,可以用分组区分
    timeout: 远程服务调用超时时间(毫秒),默认1000ms
    retries: 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0,默认值为2

    2、<dubbo:reference/> 

      1) 引用配置,用于创建一个远程服务代理,一个引用可以指向多个注册中心。

    <dubbo:reference id="userService" interface="com.patty.dubbo.api.service.UserService"
    timeout="10000" retries="3" check="false"/>
    id: 服务所引用的bean id, 对应service中ref属性的值
    check:启动时检查提供者是否存在,为false表示关闭检查。
    <dubbo:consumer check="false" /> 关闭所有服务的检查,没有提供者的时候check值为true报错,false忽略
    <dubbo:registry check="false" /> 关闭注册中心启动时检查,注册订阅失败时check值为true报错, false忽略

    2)在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连直连服务,通过设置url属性可指定服务提供者地址,多个地址用逗号隔开。
    <dubbo:reference id=
    "xxxService" interface="com.alibaba.xxx.XxxService" url="dubbo://localhost:20890" />
    也可以通过JVM启动参数设置, 如:java -Dcom.alibaba.xxx.XxxService=dubbo://localhost:20890

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

    <dubbo:protocol name="${dubbo.protocol.name}" port="${dubbo.protocol.port}"/>
    name: 协议名称
    port: 服务端口
    可选协议有
    1) dubbo:// Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。
    <dubbo:protocol name=“dubbo” port=“9090” server=“netty” client=“netty” codec=“dubbo” serialization=“hessian2” charset=“UTF-8” threadpool=“fixed” threads=“100” queues=“0” iothreads=“9” buffer=“8192” accepts=“1000” payload=“8388608” />
     

          server: 协议的服务器端实现类型

          client:协议的客户端实现类型

          codec: 协议编码方式

      serialization: 协议序列化方式

      threadpool: 线程池类型,可选:fixed/cached

    •  ThreadPool
      • fixed 固定大小线程池,启动时建立线程,不关闭,一直持有。(缺省)
      • cached 缓存线程池,空闲一分钟自动删除,需要时重建。
      • limited 可伸缩线程池,但池中的线程数只会增长不会收缩。(为避免收缩时突然来了大流量引起的性能问题)。

      threads: 服务线程池大小(固定大小),默认100

      accepts: 服务提供者最大可接受连接数

      缺省协议,使用基于mina1.1.7+hessian3.2.1的tbremoting交互。

      •   连接个数:单连接
      •   连接方式:长连接
      •   传输协议:TCP
      •   传输方式:NIO异步传输
      •   序列化:Hessian二进制序列化
      •   适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用dubbo协议传输大文件或超大字符串
      •   适用场景:常规远程服务方法调用

      2) rmi://

      3)hessian://

      4) http:// 

    • 连接个数:多连接
    • 连接方式:短连接
    • 传输协议:HTTP
    • 传输方式:同步传输
    • 序列化:表单序列化
    • 适用范围:传入传出参数数据包大小混合,提供者比消费者个数多,可用浏览器查看,可用表单或URL传入参数,暂不支持传文件。
    • 适用场景:需同时给应用程序和浏览器JS使用的服务。

         可选的server有jetty和servlet.

      5) thrift://

      6) memcached://

      7)redis://

      8) webservice://

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

    <dubbo:application name="${dubbo.application.name}"/>

       name:当前应用名称,用于注册中心计算应用间依赖关系,服务方和消费方不必保持一样,该名称不是匹配条件

       version:当前应用的版本

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

    1)<dubbo:registry protocol="${dubbo.registry.protocol}" address="${dubbo.registry.address}"/>
    protocol: 注同中心地址协议,支持dubbo, http, local三种协议,分别表示,dubbo地址,http地址,本地注册中心
    address:注册中心服务器地址,如果地址没有端口缺省为9090,同一集群内的多个地址用逗号分隔,如:ip:port,ip:port,不同集群的注册中心,请配置多个<dubbo:registry>标签

    2)为方便开发测试,经常会在线下共用一个所有服务可用的注册中心,这时,如果一个正在开发中的服务提供者注册,可能会影响消费者不能正常运行。可以让服务提供者开发方,只订阅服务(开发的服务可能依赖其它服务),而不注册正在开发的服务,通过直连测试正在开发的服务。
    <
    dubbo:registry address="10.20.153.10:9090" register="false" />
    3)同样设置属性subscribe="false",则服务提供方将不进行订阅操作。

    6、其他的一些配置项

    • <dubbo:module/> 模块配置,用于配置当前模块信息,可选。
    • <dubbo:monitor/> 监控中心配置,用于配置连接监控中心相关信息,可选。
    • <dubbo:provider/> 提供方的缺省值,当ProtocolConfig和ServiceConfig某属性没有配置时,采用此缺省值,可选。
    • <dubbo:consumer/> 消费方缺省配置,当ReferenceConfig某属性没有配置时,采用此缺省值,可选。
    • <dubbo:method/> 方法配置,用于ServiceConfig和ReferenceConfig指定方法级的配置信息。
    • <dubbo:argument/> 用于指定方法参数配置。

    7、配置优先级

    • 上图中以timeout为例,显示了配置的查找顺序,其它retries, loadbalance, actives等类似。
      • 方法级优先,接口级次之,全局配置再次之。
      • 如果级别一样,则消费方优先,提供方次之。
    • 其中,服务提供方配置,通过URL经由注册中心传递给消费方。
    • 建议由服务提供方设置超时,因为一个方法需要执行多长时间,服务提供方更清楚,如果一个消费方同时引用多个服务,就不需要关心每个服务的超时设置。
    • 理论上ReferenceConfig的非服务标识配置,在ConsumerConfig,ServiceConfig, ProviderConfig均可以缺省配置。

    8、属性配置方式

    1)dubbo.properties文件

    如果公共配置很简单,没有多注册中心,多协议等情况,或者想多个Spring容器想共享配置,可以使用dubbo.properties作为缺省配置

    Dubbo将自动加载classpath根目录下的dubbo.properties,可以通过JVM启动参数:-Ddubbo.properties.file=xxx.properties 改变缺省配置位置

    覆盖策略:

    • JVM启动-D参数优先,这样可以使用户在部署和启动时进行参数重写,比如在启动时需改变协议的端口。
    • XML次之,如果在XML中有配置,则dubbo.properties中的相应配置项无效。
    • Properties最后,相当于缺省值,只有XML没有配置时,dubbo.properties的相应配置项才会生效,通常用于共享公共配置,比如应用名。

    2)注解配置

    服务提供方注解:

    import com.alibaba.dubbo.config.annotation.Service;
     
    @Service(version="1.0.0")
    public class FooServiceImpl implements FooService {
     
        // ......
     
    }

    服务提供方配置:

    <!-- 公共信息,也可以用dubbo.properties配置 -->
    <dubbo:application name="annotation-provider" />
    <dubbo:registry address="127.0.0.1:4548" />
     
    <!-- 扫描注解包路径,多个包用逗号分隔,不填pacakge表示扫描当前ApplicationContext中所有的类 -->
    <dubbo:annotation package="com.foo.bar.service" />
     

    服务消费方注解:

    import com.alibaba.dubbo.config.annotation.Reference;
    import org.springframework.stereotype.Component;
     
    @Component
    public class BarAction {
     
        @Reference(version="1.0.0")
        private FooService fooService;
     
    }

    服务消费方配置:

    <!-- 公共信息,也可以用dubbo.properties配置 -->
    <dubbo:application name="annotation-consumer" />
    <dubbo:registry address="127.0.0.1:4548" />
     
    <!-- 扫描注解包路径,多个包用逗号分隔,不填pacakge表示扫描当前ApplicationContext中所有的类 -->
    <dubbo:annotation package="com.foo.bar.action" />

    3)API配置,不推荐

    9、多协议服务配置

    实际应用中, 不同服务在性能上适用不同协议进行传输,比如大数据用短连接协议,小数据大并发用长连接协议。

        <!-- 多协议配置 -->
        <dubbo:protocol name="dubbo" port="20880" />
        <dubbo:protocol name="rmi" port="1099" />
     
        <!-- 使用dubbo协议暴露服务 -->
        <dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" protocol="dubbo" />
        <!-- 使用rmi协议暴露服务 -->
        <dubbo:service interface="com.alibaba.hello.api.DemoService" version="1.0.0" ref="demoService" protocol="rmi" />
    当然也可以同一服务使用多协议暴露出去,如:
    <!-- 使用多个协议暴露服务 -->
        <dubbo:service id="helloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" protocol="dubbo,rmi" />
     
    10、多注册中心
        <!-- 多注册中心配置 -->
        <dubbo:registry id="hangzhouRegistry" address="10.20.141.150:9090" />
        <dubbo:registry id="qingdaoRegistry" address="10.20.141.151:9010" default="false" />
     
        <!-- 同一服务向多个注册中心注册 -->
        <dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" registry="hangzhouRegistry,qingdaoRegistry" />
        
        <!-- 不同服务向不同的注册中心注册 -->
        <!-- 向中文站注册中心注册 -->
        <dubbo:service interface="com.alibaba.hello.api.TestService" version="1.0.0" ref="testService" registry="chinaRegistry" />
     
        <!-- 向国际站注册中心注册 -->
        <dubbo:service interface="com.alibaba.hello.api.DemoService" version="1.0.0" ref="demoService" registry="intlRegistry" />
     
    11、服务分组与聚合
    当一个接口有多个实现的时候,可以用group进行分组。例如,我们对第一节的UserService接口,再写一个mock数据的实现
    /**
     * Version: 3.0
     * Author: pattywgm
     * Time: 17/6/28 下午11:14
     * Desc: UserService的另一个实现类,用来测试同一接口多个实现的情况下,将服务进行分组group
     */
    @Service("anotherUserService")
    public class AnotherUserServiceImpl implements UserService {
    
        public AnotherUserServiceImpl(){
    
        }
    
        @Override
        public List<UserVo> findAllUsers() {
            ArrayList<UserVo> userVos = new ArrayList<UserVo>();
            userVos.add(new UserVo("10", "patty", 23, "13812931251"));
            userVos.add(new UserVo("11", "jack", 22, "18719092278"));
            return userVos;
        }
    
        @Override
        public UserVo findUserById(String id) {
            return new UserVo("15", "rose", 22, "17712013366");
        }
    }

    然后,注册该服务,并对其与之前的服务分别进行分组

     <dubbo:service ref="userService" group="db" interface="com.patty.dubbo.api.service.UserService"/>
    
     <dubbo:service ref="anotherUserService" group="mock" interface="com.patty.dubbo.api.service.UserService"/>

    在消费方,我们可以根据分组来调用相应的服务,有两种方式:

    一是指定某个特定的分组:

    <dubbo:reference id="userService" group="db" interface="com.patty.dubbo.api.service.UserService"  timeout="10000" retries="3" mock="true"/>

    比如测试代码中,调用db组,是从数据库取数据,得到结果如下:

    二是指定任意组,调用时只会调用其中一个可用组的实现。

    <dubbo:reference id="userService" group="*" interface="com.patty.dubbo.api.service.UserService"  timeout="10000" retries="3" mock="true"/>

    示例代码运行结果,调用的是mock组的实现,输出结果如下:

    如果想要是的所有分组的实现都被调用(当然,我们也可以通过group="db,mock"指定特定的分组),可以在<dubbo: reference>中设置merger="true",表示调用所有指定分组的实现,并将各个分组的结果合并作为最终结果,比如:

    <dubbo:reference id="userService" group="db,mock" interface="com.patty.dubbo.api.service.UserService"
    timeout="10000" retries="3" mock="true" merger="true"/>

    输出结果为:

    此时, 我们的设置是对所调用服务的所有方法,都合并结果,dubbo为我们提供了方法级别的merger,即可以指定只合并多个分组的特定方法,或者只对某个特定方法不合并最终结果。配置方式如下:

    <dubbo:reference id="userService" group="*" interface="com.patty.dubbo.api.service.UserService"
    timeout="10000" retries="3" mock="true">
    <!-- 指定findAllUsers方法结果合并, 其他方法将只调用某个group的可用实现-->
    <dubbo:method name="findAllUsers" merger="true">
    </dubbo:method>
    </dubbo:reference>
    <!-- 指定所有分组的所有方法,除了findUserById 方法外,都合并结果 -->

    <dubbo:reference id="userService" group="*" interface="com.patty.dubbo.api.service.UserService"

    timeout="10000" retries="3" mock="true" merger="true">
        <dubbo:method name="findUserById" merger="false">
    </dubbo:method>
    </dubbo:reference>
  • 相关阅读:
    IoC容器设计
    乐观锁(Optimistic Lock)
    file,path,uri互相转换
    QGraphicsView的paintEvent双缓存绘画
    简单的串口通信程序控制光源
    Qt--QMdiArea和QMdiSubWindow的基本用法
    Qt--支持鼠标拖动来移动内容的QScrollArea视窗
    快速排序算法记录
    结构体在内存中的对齐规则
    求N个数的数组中第K大的数的值
  • 原文地址:https://www.cnblogs.com/java-wgm/p/7086361.html
Copyright © 2020-2023  润新知