Dubbo

来自ling
跳转至: 导航搜索

问题总结

  • 如果启动找不到注册的内容,检查dubbo.spring.config=classpath*:/beans/**/*.xml是否指向正确,也有可能是日志没出来,查看是否有引用的项目根目录有log4j.xml,没有事不行的
  • customer中scan扫描到的bean和<dubbo:reference的bean重复,如何解决?

编码规范

  • 所有xxx.provider继承ling.pl.dubbo.core,xxx.impl
  • provider的xml文件放在包beans.dubbo.provider中命名为dubbo-xxx-provider.xml
  • 所有xxx.customer继承ling.pl.dubbo.core,xxx.api
  • provider的xml文件放在包beans.dubbo.customer中命名为dubbo-xxx-customer.xml

模块的循环依赖避免

spring javaconfig和dubbo的完美结合

  • dubbo的spring context位置由根目录dubbo.properties中dubbo.spring.config属性指定
  • spring的context由 SpringConfig中@ImportResource(locations = "classpath*:beans/**/*.xml")//提供对老配置的兼容指定
  • 所以指定dubbo.spring.config=classpath*:/beans/**/*.xml后 spring javaconfig 能自动得到dubbo的配置spring启动dubbo
  • 而通过javaconfig启动dubbo,也能自动加载sping javaconfig的配置dubbo启动spring
  1. 需要dubbo.properties指定dubbo.spring.javaconfig=com.deloitte 标识dubbo的javaconfig类在com.deloitte包下
  • 相互启动时的异常情况
    • spring加载到dubbo配置(server,reference...),就会启动dubbo流程,则按dubbo.properties启动(非dubbo java config),如果配置不全,就会启动报错
    • spring没有加载到dubbo配置,启动不会报错,即使dubbo.properties存在,且有配置内容
      • 所以dubbo的xml不能和api impl一起存在,否则存java单独调用无法启动
      • 也不建议再api impl中添加dubbo注解,否则去掉dubbo相关,api impl无法编译通过
  • @ContextConfiguration(classes = {SpringConfig.class})
  • @ContextConfiguration(classes = {SpringConfig.class,DubboProviderContextConfig.class})

profile,version,VATCompanyUtils使用场景与分工

  • 实施版本不同,可以通过将原类重构为base,新建接口实现并设置version来供不同实施使用,减少分支的使用,同时可以配合VATCompanyUtils完成业务逻辑差异
  • profile方式定义的实现BEAN_ID使用接口中定义的BEAN_ID
  • 实施原因定义的实现BEAN_ID使用接口中定义的BEAN_ID+COMPANYID
  • 如何与profile分工

服务注册和使用规范

  • spring bean使用注解方式,便于使用java组件模式时的自动注入
  • 模块划分
  1. xxx-api 接口规范
  2. xxx-impl服务实现者,组件方式时调用,依赖xxx-impl
  3. xxx-provider 服务提供者服务方式时使用,依赖xxx-impl获取到spring bean和api
    1. 模块独立启动测试
    2. 单元测试
  4. xxx-customer 服务消费者,内容为reference,依赖xxx-api
  5. 相同模块provider,customer不共存
  6. 服务使用者,通过maven引用xxx-customer来达到使用相应模块的能力,而不是直接使用xx-api或xxx-impl
  • 因为scan的问题,provider,customer只能通过xml文件方式注册服务.重构时全局替换*.xml
  • 就代码模块重构规则:原来模块只留下dubbo reference定义(即customer),接口独立为api. impl独立为impl,为impl独立出provider
  • 1.0,2.0....这类版本号和实施版本号不能同时存在.实施不支持多版本号.
  • 接口默认实现不加版本号,reference也不加版本号,因为特殊原因需要保留版本,才在已存在的最后版本号上+1作为新版本号,同时reference上指明使用的版本号

服务注册属性配置规范

  • 子模块有自己不同的名称
  • 通过profile 解决启动配置属性问题,不涉及dubbo的服务注册和引用

单元测试规范

  • provider单元测试内容 测试服务能正常注册到zookeeper,启动为王,无业务逻辑单元测试
  • customer单元测试内容 完成所有的业务单元测试内容,测试必须2套,即rest测试方式,spring bean方式
  1. rest测试方式保证了nginx集群下对app模式数据请求下的数据可用性
  2. spring bean测试方式保证了dubbo模式下数据情况的可用性
  • 测试方式如下:
    • dubbo (必须javaconfig,否则不能使用SpringConfig特性,使用dubbo.properties配置) main方式启动
    • junit javaconfig方式启动无dubbo内容
    • web启动impl
    • seb启动dubbo
  • 单元测试可以有单独项目,通过javaconfig中使用@ImportResource方式配合AnnotationConfigApplicationContext等来测试

单元测试问题和解决

  • 如何保证测试相应模块时provider模块为启动状态
  • rest测试是tomcat端口,必须要指定端口,如何随机端口和测试
  • a需要b模块,b需要c模块环境下的测试

增加提供服务版本号和消费服务版本号

这个具体来说不算是一个问题,而是一种问题的解决方案,在我们的实际工作中会面临各种环境资源短缺的问题,也是很实际的问题,刚开始我们还可以提供一个服务进行相关的开发和测试,但是当有多个环境多个版本,多个任务的时候就不满足我们的需求,这时候我们可以通过给提供方增加版本的方式来区分.这样能够剩下很多的物理资源,同时为今后更换接口定义发布在线时,可不停机发布,使用版本号.
<dubbo:serviceinterface=“com.xxx.XxxService”ref=“xxxService” version=“1.0” />
<dubbo:referenceid=“xxxService”interface=“com.xxx.XxxService” version=“1.0”/>

dubbo reference注解问题

@Reference只能在springbean实例对应的当前类中使用,暂时无法在父类使用;如果确实要在父类声明一个引用,可通过配置文件配置dubbo:reference,然后在需要引用的地方跟引用springbean一样就可以了.

Dubbo REST中如何实现负载均衡和容错(failover)

  • 如果dubbo REST的消费端也是dubbo的,则Dubbo REST和其他dubbo远程调用协议基本完全一样,由dubbo框架透明的在消费端做load balance、failover等等。
  • 如果dubbo REST的消费端是非dubbo的,甚至是非java的,则最好配置服务提供端的软负载均衡机制,目前可考虑用LVS、HAProxy、 Nginx等等对HTTP请求做负载均衡。

服务超时问题

此问题也是在项目中非常常见的一个问题,但是这个问题背后可能是各种原因导致.目前如果存在超时,情况基本都在如下:

  • 一种情况是服务请求超时.
客户端耗时大,也就是超时异常时的client elapsedxxx,这个是从创建Future对象开始到使用channel发出请求的这段时间,中间没有复杂操作,只要CPU没问题基本不会出现大耗时,顶多1ms属于正常IOThread繁忙,默认情况下,dubbo协议一个客户端与一个服务提供者会建立一个共享长连接,如果某个客户端处于特别繁忙而且一直往一个服务提供者塞请求,可能造成IOThread阻塞,一般非常特殊的情况才会出现服务端工作线程池中线程全部繁忙,接收消息后塞入队列等待,如果等待时间比预想长会引起超时网络抖动,如果上述情况都排除了,还出现在请求发出后,服务接收请求前超过预想时间,只能归类到网络抖动了,需要SA一起查看问题服务自身耗时大,这个需要应用自身做好耗时统计,当出现这种情况的时候需要用数据来说明问题及规划优化方案,建议采用缓存埋点的方式统计服务中各个执行阶段的耗时情况,最终如果超过预想时间则把缓存统计的耗时情况打日志,减少日志量,且能够得到更明确的信息现在我们应用使用过程中发现两种类型的耗时,一种我们目前只能归类到网络抖动,后续需要找运维一起关注这个问题,另外一种是由于一些历史原因,数据库查询容易发生抖动,总有一个时间点会突然多出很多超时。
  • 二大类的情况是调用的版本不对.

在上面我们已经说了具体的版本问题,如果你调用的对方版本不对的话,就相当于你的消费者没有提供者.所以会出现超时,此时只需要把版本对应好即可.

  • 提供者的服务被禁止.

这是一种人为的控制,通过监控中心我们可以对具体的服务,以及它的权重进行控制,当我将一个具体的服务禁止之后消费者就调不到相关的服务,此时就会出现超时的问题.解决方案,取消禁止即可.注意这里有一定时间的缓存,实际操作的时候应该注意.

服务保护

服务保护的原则上是避免发生类似雪崩效应,尽量将异常控制在服务周围,不要扩散开。说到雪崩效应,还得提下dubbo自身的重试机制,默认3次,当失败时会进行重试,这样在某个时间点出现性能问题,然后调用方再连续重复调用,很容易引起雪崩,建议的话还是很据业务情况规划好如何进行异常处理,何时进行重试。服务保护的话 考虑服务的dubbo线程池类型(fix线程池的话考虑线程池大小)、数据库连接池、dubbo连接数限制是否都合适.

注册中心的分组group和服务的不同实现group

这两个东西完全不同的概念,使用的时候不要弄混了。registry上可以配置group,用于区分不同分组的注册中心,比如在同一个注册中心下,有一部分注册信息是要给开发环境用的,有一部分注册信息时要给测试环境用的,可以分别用不同的group区分开,目前对这个理解还不透彻,大致就是用于区分不同环境。service和reference上也可以配置group,这个用于区分同一个接口的不同实现,只有在reference上指定与service相同的group才会被发现。

源代码下载

https://github.com/alibaba/dubbo/tree/master

Zookeeper注册中心

参见zookeeper

简易监控中心

  • 下载可执行版本http://code.alibabatech.com/mvn/releases/com/alibaba/dubbo-monitor-simple/2.5.3/dubbo-monitor-simple-2.5.3-assembly.tar.gz
  • 修改conf/dubbo.properties中配置
  • 可以下载源代码后在SimpleMonitor中通过main执行
  • 可以下载可执行包
./bin/server.sh start
./bin/server.sh stop
./bin/server.sh restart
./bin/server.sh debug
./bin/server.sh dump

访问:http://127.0.0.1:7080

  • Simple Monitor挂掉不会影响到Consumer和Provider之间的调用,所以用于生产环境不会有风险。
  • Simple Monitor采用磁盘存储统计信息,请注意安装机器的磁盘限制,如果要集群,建议用mount共享磁盘。
  • charts目录必须放在jetty.directory下,否则页面上访问不了。

管理控制台

  • 管理控制台为内部裁剪版本,开源部分主要包含:路由规则,动态配置,服务降级,访问控制,权重调整,负载均衡,等管理功能。
  • 修改配置webapps/ROOT/WEB-INF/dubbo.properties
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest
  • 可以在源代码上用tomcat运行.访问地址

http://127.0.0.1:7002/dubbo-admin

  • 服务器默认访问地址

http://127.0.0.1:8702/dubbo-admin

  • 用户名和密码

root/root

guest/guest

简易demo

参见dubbo demo