Dubbo是什么?
- Dubbo是阿里巴巴公司的一款开源分布式服务框架,性能优秀,使用应用可以通过高性能的 RPC (远程调用)实现服务的输出和输入功能,可以和 Spring框架无缝集成。
- Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
Dubbo能做什么?
-
透明化的远程方法调用
使用dubbo的远程调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。
-
软负载均衡及容错机制
可以通过配置实现集群中多台服务器的管理。
-
服务自动注册与发现
- 不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。
- Dubbo采用全spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。
Dubbo的架构原理
节点角色说明
- Provider:暴露服务的服务提供方
- Container:服务运行容器
- Consumer:调用远程服务的服务消费方
- Registry:服务注册与发现的注册中心
- Monitor:统计服务的调用次数和调用时间的监控中心(使用zookeeper代替)
Dubbo如何使用?
实现步骤
- 添加对应的依赖(本次使用spring+springMVC整合示例,以及maven模块分离继承的形式)
- 编写服务提供者,并注册到注册中心,并编写web.xml让服务能够独立运行。
- 编写服务消费者,并注册到注册中心,并编写web.xml让服务能够独立运行。(消费者与提供者是互通的,一个提供者也能是一个消费者)
- 需要注意的是,每一个服务都能够独立运行,这就是分布式的体现。
具体实现
-
添加指定依赖
pom.xml
<!--Dubbo的起步依赖,版本2.7之后统一为rg.apache.dubb --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.4.1</version> </dependency> <!--ZooKeeper客户端实现 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.0.0</version> </dependency> <!--ZooKeeper客户端实现 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.0.0</version> </dependency>
其他的需要依赖spring、springmvc、log4g等日志文件依赖自己添加
-
编写实体类
-
User.java
public class User implements Serializable { private Integer id; private String name; private Integer age; //其他方法省略.... }
注意:
- 实体类必须要实现
Serializable
序列化接口,因为RPC远程调用是通过流的方式传输,在服务消费方调用提供方的时候,提供方会将数据序列化进行传输;消费方拿到后,会进行反序列化给前端。 - 因为使用的是maven模块分离,其他模块需要依赖这个实体类模块,所以需要将被依赖模块
mvn install
到本地仓库
- 实体类必须要实现
-
-
编写公共接口
因为server模块与controller模块都会依赖一些公共的接口,所以为了管理,我们将一些公共接口进行抽取出来,形成一个独立的模块,注入到本地仓库中,以便能够被其他模块依赖。
-
UserService.java
/** * 公共接口 */ public interface UserService { User findById(int id); }
注意:需要
mvn install
作为jar包添加到本地仓库中
-
-
编写服务提供方
-
UserServiceImpl.java
/** * 使用dubbo提供的@Service注解 * 表示将这个类提供的方法(服务),注册到注册中心,提供对外服务 */ @Service(timeout = 5000) //生产者设置超时时间为5000毫秒 public class UserServiceImpl implements UserService { @Override public User findById(int id) { return new User(1, "不知火舞", 36); } }
注意:
- @Service注解所在包是使用的dubbo的注解
import org.apache.dubbo.config.annotation.Service;
表示将此类提供的服务(服务指的就是类中的方法)注册到注册中心。 - 当然要注册到注册中心,还需要进行一些注册中心的地址配置
- @Service注解所在包是使用的dubbo的注解
-
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!--将此项目配置到zookeeper注册中心--> <!--配置此应用的名称--> <dubbo:application name="dubbo-service"/> <!--配置注册中心的地址--> <dubbo:registry address="zookeeper://192.168.242.130:2181"/> <!--配置dubbo注解扫描--> <dubbo:annotation package="com.itheima.service.impl"/> </beans>
-
web.xml
前面说过,分布式的特点就是将一个大型项目按照业务功能划分成小服务,配置到服务器上,每一个服务都能单独运行;也就是说每一个服务都是一个web项目。
<!--加载spring配置文件--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:applicationContext.xml</param-value> </context-param> <!--添加spring提供的监听器,用于加载spring配置文件--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
-
-
编写服务消费方
-
UserController.java
@Controller @ResponseBody @RequestMapping("/user") public class UserController { /** * 此注解表示远程引用提供者提供的服务 * 执行流程 * 从zookeeper注册中心获取UserService的访问url * 实行远程调用RPC * 将得到的结果对象封装变量中。 * */ @Reference(timeout = 2000) //消费者设置超时时间为2000毫秒 private UserService userService; @RequestMapping("findById") public User findById() { return userService.findById(1); } }
@Reference是使用的dubbo提供的注解
import org.apache.dubbo.config.annotation.Reference;
-
spring-mvc.xml
每个消费者也是服务提供者,都需要将服务注册到注册中心。
<!--配置注解扫描--> <context:component-scan base-package="com.itheima.controller"/> <!--启用spring-mvc注解驱动--> <mvc:annotation-driven/> <!--配置静态资源放行--> <mvc:default-servlet-handler/> <!--将此项目配置到注册中心--> <!--配置项目的名字--> <dubbo:application name="dubbo-controller"> <!--qos是一个监控组件,他的默认端口为2222,如果在同一台电脑上启动两个dubbo会出现端口冲突,所以需要设定不端口,避免冲突--> <dubbo:parameter key="qos.port" value="3333"/> </dubbo:application> <!--配置注册中心的地址--> <dubbo:registry address="zookeeper://192.168.242.130:2181"/> <!--配置注解扫描--> <dubbo:annotation package="com.itheima.controller"/>
-
web.xml
消费者也是一个能够独立运行的服务。
<!--配置servlet--> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--加载springMVC配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring-mvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
-
测试的话就是分别启动消费者服务与提供者服务,当消费者调用提供者提供的服务,并且能够得到正确的数据时,就使用成功。
总结
-
使用dubbo实现RPC(远程调用),是建立在分布式的基础上,让每一台服务都能够独立运行。
-
将服务注册到注册中心(zk)时,会在zk服务器的根节点下生成一个dubbo节点,dubbo节点下存放的就是类的全路径名
-
完整入门项目地址:https://gitee.com/yang_haifeng618/dubbo