- dubbo介绍
Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring 框架无缝集成。Dubbo 框架,是基于容器 运行的.。容器是 Spring。 官方网站 : http://dubbo.apache.org/ 。阿里巴巴已经将 dubbo 框架捐献给了 Apache 软件基金会
- 框架结构
1.1registry
注册中心. 是用于发布和订阅服务的一个平台.用于替代SOA结构体系框架中的ESB服 务总线的。
1.1.1 发布
开发服务端代码完毕后, 将服务信息发布出去. 实现一个服务的公开.
1.1.2 订阅
客户端程序,从注册中心下载服务内容 这个过程是订阅. 订阅服务的时候, 会将发布的服务所有信息,一次性下载到客户端. 客户端也可以自定义, 修改部分服务配置信息. 如: 超时的时长, 调用的重试次数等.
1.2 consumer
服务的消费者, 就是服务的客户端. 消费者必须使用 Dubbo 技术开发部分代码. 基本上都是配置文件定义.
1.3 provider
服务的提供者, 就是服务端. 服务端必须使用 Dubbo 技术开发部分代码. 以配置文件为主.
1.4 container
容器. Dubbo 技术的服务端(Provider), 在启动执行的时候, 必须依赖容器才能正常启动. 默认依赖的就是 spring 容器. 且 Dubbo 技术不能脱离 spring 框架. 在 2.5.3 版本的 dubbo 中, 默认依赖的是 spring2.5 版本技术. 可以选用 spring4.5 以下版
本.
在 2.5.7 版本的 dubbo 中, 默认依赖的是 spring4.3.10 版本技术. 可以选择任意的 spring 版本.
1.5 monitor
监控中心. 是 Dubbo 提供的一个 jar 工程. 主要功能是监控服务端(Provider)和消费端(Consumer)的使用数据的. 如: 服务端是什么, 有多少接口,多少方法, 调用次数, 压力信息等. 客户端有多少, 调用过哪些服务端, 调用了 多少次等.
- 执行流程
0 start: 启动 Spring 容器时,自动启动 Dubbo 的 Provider
1 register: Dubbo 的 Provider 在启动后自动会去注册中心注册内容.注册的内容包括:
1.1 Provider 的 IP
1.2 Provider 的端口.
1.3 Provider 对外提供的接口列表.哪些方法.哪些接口类
1.4 Dubbo 的版本.
1.5 访问 Provider 的协议.
2 subscribe: 订阅.当 Consumer 启动时,自动去 Registry 获取到所已注册的服务的信息.
3 notify: 通知.当 Provider 的信息发生变化时, 自动由 Registry 向 Consumer 推送通知.
4 invoke: 调用. Consumer 调用 Provider 中方法
4.1 同步请求.消耗一定性能.但是必须是同步请求,因为需要接收调用方法后的结果.
5 count:次数. 每隔 2 分钟,provoider 和 consumer 自动向 Monitor 发送访问次数.Monitor 进行统计.
- 支持协议
dubbo协议(官方支持协议)
优点: 采用 NIO 复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率, 性能较好(推荐使用) 缺点: 大文件上传时,可能出现问题(不使用 Dubbo 文件上传)
RMI(Remote Method Invocation)协议
优点: JDK 自带的能力。可与原生 RMI 互操作,基于 TCP 协议 缺点: 偶尔连接失败.
Hessian 协议
优点: 可与原生 Hessian 互操作,基于 HTTP 协议 缺点: 需 hessian.jar 支持,http 短连接的开销大
- 注册中心(zookeeper注册中心)
- 入门案例
生产者:
环境注入:
<dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.101tec/zkclient -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
</dependencies>
创建服务接口:
public interface DubboService {
String showMsg(String str);
}
实现具体服务:
public class DubboServiceImpl implements DubboService {
@Override
public String showMsg(String str) {
return "Hello Dubbo "+str;
}
}
配置服务,连接注册中心:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 给应用起名 -->
<dubbo:application name="myprovider"/>
<!-- 配置注册中心 -->
<!-- address: 注册中心的IP和端口,注意:如果zookeeper是一个集群,哪些要将集群中所有的IP和端口添加该属性中-->
<!-- protocol: 注册中心的类型-->
<dubbo:registry address="192.168.139.133:2181,192.168.139.133:2182,192.168.139.133:2183" protocol="zookeeper"></dubbo:registry>
<!-- 配置协议与端口 -->
<dubbo:protocol name="dubbo" port="20880"></dubbo:protocol>
<!-- 配置注册接口 -->
<dubbo:service interface="com.bjsxt.service.DubboService" ref="dubboServiceImpl"></dubbo:service>
<bean id="dubboServiceImpl" class="com.bjsxt.service.impl.DubboServiceImpl"></bean>
</beans>
发布服务:
public class Start {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("/META-INF/spring/application-dubbo.xml");
ac.start();
System.in.read();
//Main类下的main方法在启动时默认的回去classpath:/META-INF/spring/*.xml
//Main.main(args);
}
}
消费者(Consumer):
依赖注入:
需要将service服务注入到项目中,用户获取接口,这里只是注入接口,并没有去获取接口的实现类,也就是服务,真正的服务在注册中心。当生产这成功向注册中心注册服务时,消费者去注册中心按照所提供的接口类型去寻找到服务,再总注册中心获取服务到当前项目中。
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<context:component-scan base-package="com.bjsxt.service" />
<dubbo:application name="myconsumer" />
<dubbo:registry address="192.168.139.133:2181,192.168.139.133:2182,192.168.139.133:2183" protocol="zookeeper"></dubbo:registry>
<!-- 获取接口 -->
<!-- 获取到接口的代理对象,生成接口的 Proxy, 放入到 spring 容器中 -->
<dubbo:reference id="dubboService" interface="com.bjsxt.service.DubboService"></dubbo:reference>
</beans>
服务接口:
public interface UserService {
public void showMsg(String str);
}
接口实现类:
@Service
public class UserServiceImpl implements UserService{
@Autowired
private DubboService dubboService;
@Override
public void showMsg(String str) {
// TODO Auto-generated method stub
System.out.println(this.dubboService.toString());
String strs=this.dubboService.showMsg(str);
System.out.println(strs);
}
}
配置:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<context:component-scan base-package="com.bjsxt.service" />
<dubbo:application name="myconsumer" />
<dubbo:registry address="192.168.139.133:2181,192.168.139.133:2182,192.168.139.133:2183" protocol="zookeeper"></dubbo:registry>
<!-- 获取接口 -->
<!-- 获取到接口的代理对象,生成接口的 Proxy, 放入到 spring 容器中 -->
<dubbo:reference id="dubboService" interface="com.bjsxt.service.DubboService"></dubbo:reference>
</beans>
启动消费:
public class UserTest {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService bean = ac.getBean(UserService.class);
bean.showMsg("hello");
}
}