学习笔记:dubbo+Zookeeper

架构分类:单体架构、垂直架构、SOA架构、微服务架构
分布式 RPC 框架 Apache Dubbo :
RPC 全称为 remote procedure call ,即远程过程调用。Java 中的 RPC 框架比较多,广泛使用的有 RMI Hessian Dubbo 等。
Dubbo 架构

节点 角色名称
Provider
暴露服务的服务提供方
Consumer
调用远程服务的服务消费方
Registry
服务注册与发现的注册中心
Monitor
统计服务的调用次数和调用时间的监控中心
Container
服务运行容器
调用关系说明 :
0. 服务容器负责启动,加载,运行服务提供者。
1. 服务提供者在启动时,向注册中心注册自己提供的服务。
2. 服务消费者在启动时,向注册中心订阅自己所需的服务。
3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失
败,再选另一台调用。
5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
服务注册中心 Zookeeper
Zookeeper Apache Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用
思考一: 上面的 Dubbo 入门案例中我们是将 HelloService 接口从服务提供者工程
(dubbodemo_provider) 复制到服务消费者工程 (dubbodemo_consumer) 中,这种做法是否合适?还有
没有更好的方式?
答:这种做法显然是不好的,同一个接口被复制了两份,不利于后期维护。更好的方式是单独创建一个maven 工程,将此接口创建在这个 maven 工程中。需要依赖此接口的工程只需要在自己工程的
pom.xml 文件中引入 maven 坐标即可。
思考二: 在服务消费者工程 (dubbodemo_consumer) 中只是引用了 HelloService接口,并没有提供实现类, Dubbo 是如何做到远程调用的?
答: Dubbo 底层是基于代理技术为 HelloService接口创建代理对象,远程调用是通过此代理对象完成的。可以通过开发工具的 debug 功能查看此代理对象的内部结构。另外, Dubbo实现网络传输底层是基于 Netty 框架完成的。
思考三: 上面的 Dubbo 入门案例中我们使用 Zookeeper作为服务注册中心,服务提供者需要将自己的服务信息注册到 Zookeeper ,服务消费者需要从 Zookeeper 订阅自己所需要的服务,此时 Zookeeper服务就变得非常重要了,那如何防止 Zookeeper 单点故障呢?
答: Zookeeper 其实是支持集群模式的,可以配置 Zookeeper 集群来达到 Zookeeper服务的高可用,防止出现单点故障。
Dubbo 管理控制台
我们在开发时,需要知道 Zookeeper注册中心都注册了哪些服务,有哪些消费者来消费这些服务。我们 可以通过部署一个管理中心来实现。其实管理中心就是一个 web 应用,部署到 tomcat 即可。
解决 Dubbo 无法发布被事务代理的 Service 问题
前面我们已经完成了 Dubbo 的入门案例,通过入门案例我们可以看到通过 Dubbo提供的标签配置就可 以进行包扫描,扫描到 @Service 注解的类就可以被发布为服务。
但是我们如果在服务提供者类上加入 @Transactional事务控制注解后,服务就发布不成功了。原因是事 务控制的底层原理是为服务提供者类创建代理对象,而默认情况下 Spring 是基于 JDK动态代理方式创建 代理对象,而此代理对象的完整类名为 com.sun.proxy.$Proxy42(最后两位数字不是固定的),导致Dubbo在发布服务前进行包匹配时无法完成匹配,进而没有进行服务的发布。
解决方案
通过上面的断点调试可以看到,在 HelloServiceImpl 类上加入事务注解后, Spring 会为此类基于 JDK动 态代理技术创建代理对象,创建的代理对象完整类名为 com.sun.proxy.$Proxy35 ,导致 Dubbo在进行 包匹配时没有成功(因为我们在发布服务时扫描的包为 com.lxs.service),所以后面真正发布服务的代 码没有执行。
解决方式操作步骤:
(1 )修改 applicationContext-service.xml 配置文件,开启事务控制注解支持时指定proxy-target-class属性,值为 true 。其作用是使用 cglib 代理方式为 Service 类创建代理对象
<!-- 开启事务控制的注解支持 -->
<tx:annotation-driven transaction-manager = "transactionManager" proxy-target-
class = "true" />

(2 )修改 HelloServiceImpl 类,在 Service 注解中加入 interfaceClass 属性,值为 HelloService.class, 作用是指定服务的接口类型
@Service ( interfaceClass = HelloService . class )
@Transactional
public class HelloServiceImpl implements HelloService {
        public String sayHello ( String name ) {
                return "hello " + name ;
        }
}
此处也是必须要修改的,否则会导致发布的服务接口为 SpringProxy ,而不是 HelloService 接口,如
下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值