Dubbo入门

本文详细介绍了Dubbo分布式服务框架,包括它的核心能力、架构及为何具备高性能。同时,深入讲解了Zookeeper作为服务注册中心的角色、目标以及如何在Linux下安装。通过一个具体的Dubbo入门案例,展示了服务提供方和消费方的开发流程,最后讨论了Dubbo在处理事务代理服务发布问题的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Dubbo简介

1、Dubbo是什么?

        Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及微服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架.。
        Dubbo提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

2、Dubbo架构

在这里插入图片描述
节点角色说明:

  • Provider:暴露服务的服务提供方
  • Consumer:调用远程服务的服务消费方
  • Registry:服务注册与发现的注册中心
  • Monitor:统计服务的调用次数和调用时间的监控中心
  • Container:服务运行容器

        虚线都是异步访问,实线都是同步访问 蓝色虚线:在启动时完成的功能 红色虚线(实线)都是程序运行过程中执行的功能。

调用关系说明:

  1. 服务容器负责启动,加载,运行服务提供者。
  2. 服务提供者在启动时,向注册中心注册自己提供的服务。
  3. 服务消费者在启动时,向注册中心订阅自己所需的服务。
  4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  5. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  6. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

3、为什么Dubbo说自己高性能?

        高性能要从底层的原理说起,既然是一个RPC框架,主要干的就是远程过程(方法)调用, 那么提升性能就要从最关键、最耗时的两个方面入手:序列化和网络通信。

  • 序列化:我们学习 Java 网络开发的时候知道,本地的对象要在网络上传输,必须要实现Serializable 接口,也就是必须序列化。我们序列化的方案很多:xml、json、二进制流…其中效率最高的就是二进制流(因为计算机就是二进制的)。然而Dubbo采用的就是效率最高的二进制。
  • 网络通信:不同于HTTP需要进行7步走(三次握手和四次挥手),Dubbo采用Socket通信机制,一步到位,提升了通信效率,并且可以建立长连接,不用反复连接,直接传输数据

二、服务注册中心Zookeeper

        通过前面的Dubbo架构图可以看到,Registry(服务注册中心)在其中起着至关重要的作用。Dubbo官方推荐使用Zookeeper作为服务注册中心。

1、Zookeeper是什么?

        ZooKeeper由雅虎研究院开发,是Google Chubby的开源实现,后来托管到Apache,于2010年11月正式成为Apache的顶级项目。
        ZooKeeper是一个经典的分布式数据一致性解决方案,致力于为分布式应用提供一个高性能、高可用,且具有严格顺序访问控制能力的分布式协调服务。
        分布式应用程序可以基于ZooKeeper实现数据发布与订阅、负载均衡、命名服务、分布式协调与通知、集群管理、Leader选举、分布式锁、分布式队列等功能。

2、Zookeeper目标

        ZooKeeper致力于为分布式应用提供一个高性能、高可用,且具有严格顺序访问控制能力的分布式协调服务

2.1 高性能

ZooKeeper将全量数据存储在内存中,并直接服务于客户端的所有非事务请求,尤其适用于以读为主的应用场景

2.2 高可用

ZooKeeper一般以集群的方式对外提供服务,一般3 ~ 5台机器就可以组成一个可用的Zookeeper集群了,每台机器都会在内存中维护当前的服务器状态,并且每台机器之间都相互保持着通信。只要集群中超过一般的机器都能够正常工作,那么整个集群就能够正常对外服务

2.3 严格顺序访问

对于来自客户端的每个更新请求,ZooKeeper都会分配一个全局唯一的递增编号,这个编号反映了所有事务操作的先后顺序

3、Linux下安装Zookeeper

第一步:安装 jdk(略)
第二步:把 zookeeper 的压缩包(zookeeper-3.4.6.tar.gz)上传到 linux 系统
第三步:解压缩压缩包 tar -zxvf zookeeper-3.4.6.tar.gz -C /usr
第四步:进入zookeeper-3.4.6目录,创建data目录 mkdir data
第五步:进入conf目录 ,把zoo_sample.cfg 改名为zoo.cfg,cd conf,mv zoo_sample.cfg zoo.cfg
第六步:打开zoo.cfg文件, 修改data属性:dataDir=/usr/zookeeper-3.4.6/data

4、启动、停止Zookeeper

进入Zookeeper的bin目录,
启动服务命令:./zkServer.sh start
停止服务命令:./zkServer.sh stop
查看服务状态:./zkServer.sh status
客户端连接:./zkCli.sh

三、Dubbo入门案例

1、服务提供方开发

1.1 引入依赖

<!-- dubbo相关 -->
 <dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>dubbo</artifactId>
  <version>2.6.0</version>
 </dependency>
 <dependency>
  <groupId>org.apache.zookeeper</groupId>
  <artifactId>zookeeper</artifactId>
  <version>3.4.7</version>
 </dependency>
 <dependency>
  <groupId>com.github.sgroschupf</groupId>
  <artifactId>zkclient</artifactId>
  <version>0.1</version>
 </dependency>
 <dependency>
  <groupId>javassist</groupId>
  <artifactId>javassist</artifactId>
  <version>3.12.1.GA</version>
 </dependency>
 <dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.47</version>
 </dependency>

1.2 配置web.xml文件

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
 <display-name>Archetype Created Web Application</display-name>
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:applicationContext*.xml</param-value>
 </context-param>
 <listener>
  <listener-
class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
</web-app>

1.3 创建服务接口及实现类

package com.lxs.service;
public interface HelloService {
  public String sayHello(String name);
}
package com.lxs.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.lxs.service.HelloService;
@Service
public class HelloServiceImpl implements HelloService {
  public String sayHello(String name) {
    return "hello " + name;
 }
}

注意:服务实现类上使用的Service注解是Dubbo提供的,用于对外发布服务

1.4 配置文件

在src/main/resources下创建applicationContext-service.xml并进行如下配置:

<!-- 当前应用名称,用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样 -->
<dubbo:application name="dubbodemo_provider" />
<!-- 连接服务注册中心zookeeper ip为zookeeper所在服务器的ip地址-->
<dubbo:registry address="zookeeper://192.168.134.129:2181"/>
<!-- 注册 协议和port -->
<dubbo:protocol name="dubbo" port="20881"></dubbo:protocol>
<!-- 扫描指定包,加入@Service注解的类会被发布为服务 -->
<dubbo:annotation package="com.lxs.service.impl" />

1.5 启动服务

启动tomcat即可发布服务。

2、服务消费方开发

2.1 引入依赖

1、pom.xml配置和上面服务提供者相同,只需要修改一下Tomcat插件的端口号即可
2、将服务提供者工程中的HelloService接口复制到当前工程

2.2 配置web.xml文件

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
 <display-name>Archetype Created Web Application</display-name>
 <servlet>
  <servlet-name>springmvc</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-
class>
  <!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载 -->
  <init-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>classpath:applicationContext-web.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>springmvc</servlet-name>
  <url-pattern>*.do</url-pattern>
 </servlet-mapping>
</web-app>

2.3 编写controller

package com.lxs.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.lxs.service.HelloService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/demo")
public class HelloController {
  @Reference
  private HelloService helloService;
  @RequestMapping("/hello")
  @ResponseBody
  public String getName(String name){
    //远程调用
    String result = helloService.sayHello(name);
    System.out.println(result);
    return result;
 }
}

注意:Controller中注入HelloService使用的是Dubbo提供的@Reference注解

2.4 配置文件

在src/main/resources下创建applicationContext-web.xml并进行如下配置:

<!-- 当前应用名称,用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样 -->
<dubbo:application name="dubbodemo-consumer" />
<!-- 连接服务注册中心zookeeper ip为zookeeper所在服务器的ip地址-->
<dubbo:registry address="zookeeper://192.168.134.129:2181"/>
<!-- 扫描的方式暴露接口 -->
<dubbo:annotation package="com.lxs.controller" />

2.5 运行测试

启动tomcat访问即可

四、Dubbo无法发布被事务代理的service问题

1、问题描述

        当给服务添加事务时,即在HelloServiceImpl类上加入@Transactional注解,接着启动服务提供者和服务消费者,并访问dubbo管理控制台,发现服务并没有被发布,如下:
在这里插入图片描述

2、问题原因

        通过调试可发现,在HelloServiceImpl类上加入事务注解后,Spring会为此类基于JDK动态代理技术创建代理对象,创建的代理对象完整类名为com.sun.proxy.$Proxy35,导致Dubbo在进行包匹配时没有成功(因为我们在发布服务时扫描的包为com.lxs.service),所以后面真正发布服务的代码没有执行。

3、解决方案

(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接口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我待Java如初恋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值