基于dubbo的分布式项目实例应用
本文主要学习dubbo服务的启动检查、集群容错、服务均衡、线程模型、直连提供者、只定阅、只注册等知识点,希望通过实例演示进一步理解和掌握这些知识点。
启动检查
Dubbo缺省会在启动消费者时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认check=true。
关闭没有提供者时报错
<dubbo:reference interface="com.mcweb.api.service.IUserService" id="userService" check="false" />
<!--或者采用全局配置-->
<dubbo:consumer check="false" />
check="false"表示不启动服务提供者mcweb-logic,mcweb-web照样能正常启动。
关闭注册订阅失败时报错
<dubbo:registry check="false" />
check="false"表示,注册中心未启动,mcweb-web照样能正常启动。
集群容错
基本概念
首先,我们要明确dubbo是怎么做集群的。dubbo的集群即同一个服务部署多台机或者同一台机不同端口注册到注册中心,消费者就通过访问规则访问集群内的不同节点的服务。
集群只需多个相同服务注册相同的注册中心。在每个服务提供者配置相同集群策略和访问策略,对于消费者是透明,消费者通过框架决定访问那个服务提供者。消费者通过注册中心提供的服务端的协议信息,决定访问哪个服务。
dubbo的集群容错即当服务消费者调用服务提供者集群中的服务失败时,Dubbo提供了多种容错方案,缺省为failover重试(失败自动切换,当出现失败,重试其它服务器)。Dubbo提供的集群容错模式有:
Failover Cluster(失败自动切换,当出现失败,重试其它服务器。(缺省))
Failfast Cluster(快速失败,只发起一次调用,失败立即报错。)
Failsafe Cluster(失败安全,出现异常时,直接忽略。)
Failback Cluster(失败自动恢复,后台记录失败请求,定时重发。)
Forking Cluster(并行调用多个服务器,只要一个成功即返回。)
Broadcast Cluster(广播调用所有提供者,逐个调用,任意一台报错则报错。)
详细解析参考
http://dubbo.io/User+Guide-zh.htm#UserGuide-zh-%E9%9B%86%E7%BE%A4%E5%AE%B9%E9%94%99
集群模式配置
在《基于dubbo构建分布式项目与服务模块》一文中,我们创建了服务消费者mcweb-web与服务提供者mcweb-logic,现在我们再增加两个服务提供者,和mcweb-logic属于同一个服务,便于区分,将模块名称命名为mcweb-logic-a,mcweb-logic-b。现在mcweb-logic,mcweb-logic-a,mcweb-logic-b都属于同一个服务,均提供IUserService服务。需要将三个相同的服务以不同的端口注册到zookeeper中并指定集群容错模式,集群容错模式也可以在服务提供者配置。
<!--\mcweb\mcweb-web\src\main\resources\spring\dubbo-consumer.xml-->
<dubbo:reference
interface="com.mcweb.api.service.IUserService"
id="userService"
check="false"
protocol="dubbo"
cluster="failover"
retries="2"
/>
<!---或者->
<!--\mcweb\mcweb-logic\src\main\resources\spring\dubbo-provider.xml-->
<dubbo:protocol name="dubbo" port="" />
<dubbo:service
interface="com.mcweb.api.service.IUserService"
ref="userService"
protocol="dubbo"
cluster="failover"
retries="2"
/>
运行服务集群
在《基于dubbo构建分布式项目与服务模块》一文中,我们采用了tomcat容器来运行服务消费者和服务提供者,现在我们采用main方法来运行,这种方式通常在测试环境中使用。
<!--\mcweb\mcweb-logic\src\main\java\com\mcweb\logic\test\DubboServiceStart.java-->
public class DubboServiceStart {
public static void main(String[] args) throws IOException {
ApplicationContext ctx = new
ClassPathXmlApplicationContext("classpath*:spring/applicationContext.xml");
System.out.println("mcweb-logic 服务已启动...");
//为保证服务一直开着,利用输入流的阻塞来模拟
System.in.read();
}
}
分别以这种方式运行另外两个服务。在dubbo管控台可以看到:
集群容错测试
服务集群对消费者来说是透明的,消费者只需注明注册中心和需要的服务即可,无需关注服务是单节点还是集群。因为在同一台机子上测试,将消费者的端口改为20883
<!--\mcweb\mcweb-web\src\main\resources\spring\dubbo-consumer.xml-->
<dubbo:protocol name="dubbo" port=""/>
现在我们来运行消费者。
<!--\mcweb\mcweb-web\src\main\java\com\mcweb\web\test\DubboConsumerStart.java-->
public class DubboConsumerStart {
public static void main(String[] args) throws Exception {
ApplicationContext ctx=new
ClassPathXmlApplicationContext("classpath*:spring/applicationContext.xml");
System.out.println("mcweb-web 消费者已启动..."); for(int i=0; i<1000;i++) {
IUserService userService=(IUserService) ctx.getBean("userService");
User user = userService.query("testid");
System.out.println(i + ":" + user.getUserName());
Thread.sleep(1000);
}
}
}
运行结果:
...
10:Get user from mcweb-logic-b
11:Get user from mcweb-logic
12:Get user from mcweb-logic-a
13:Get user from mcweb-logic-b
14:Get user from mcweb-logic-a
15:Get user from mcweb-logic
16:Get user from mcweb-logic
17:Get user from mcweb-logic
18:Get user from mcweb-logic-b
19:Get user from mcweb-logic
20:Get user from mcweb-logic
...
可见,默认情况下,dubbo服务集群是带有负载均衡的(默认为random算法随机调用),集群中的服务被均匀的调用,在cluster="failover"模式下,当调用失败时,会尝试调用其他服务器。可以在dubbo管控台中对服务进行“倍权”,“半权”,“禁用”等操作观察消费者的调用情况。
负载均衡
基本概念
负载均衡(Load Balance)是分布式系统架构设计中必须考虑的因素之一,它通常指将请求/数据均匀分摊到多个操作单元(集群服务节点)上执行,负载均衡的关键在于均匀。dubbo在服务集群负载均衡时,提供了多种均衡策略,缺省为random随机调用。
Random LoadBalance随机,按权重设置随机概率。
RoundRobin LoadBalance 轮循,按公约后的权重设置轮循比率。
LeastActive LoadBalance 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
ConsistentHash LoadBalance 一致性Hash,相同参数的请求总是发到同一提供者。
详细参考
http://dubbo.io/User+Guide-zh.htm#UserGuide-zh-%E9%9B%86%E7%BE%A4%E5%AE%B9%E9%94%99
负载均衡配置
同理,负载均衡可以在消费者或者提供者中配置。
<!--\mcweb\mcweb-web\src\main\resources\spring\dubbo-consumer.xml-->
<dubbo:reference
interface="com.mcweb.api.service.IUserService"
id="userService"
check="false"
protocol="dubbo"
cluster="failover"
retries="2"
loadbalance="random"
/>
我们采用random随机均衡算法,在dubbo管控台中设置mcweb-logic(192.168.2.1:20880),mcweb-logic-a(192.168.2.1:20881),mcweb-logic-b(192.168.2.1:20882)的权重分别为200,100,50。
看看mcweb-web的调用情况:
0:Get user from mcweb-logic-b
1:Get user from mcweb-logic-a
2:Get user from mcweb-logic-a
3:Get user from mcweb-logic-b
4:Get user from mcweb-logic-a
5:Get user from mcweb-logic
6:Get user from mcweb-logic
7:Get user from mcweb-logic-b
8:Get user from mcweb-logic-a
9:Get user from mcweb-logic-b
10:Get user from mcweb-logic
11:Get user from mcweb-logic-a
12:Get user from mcweb-logic-a
13:Get user from mcweb-logic-a
14:Get user from mcweb-logic
15:Get user from mcweb-logic
16:Get user from mcweb-logic
17:Get user from mcweb-logic
18:Get user from mcweb-logic-b
19:Get user from mcweb-logic-b
20:Get user from mcweb-logic
21次调用中,mcweb-logic调用了8次,mcweb-logic-a调用了7次,mcweb-logic-b调用了6次,符合权重越大,调用次数越多。随着调用次数的增多,每个节点上的服务被调用的次数会逐渐趋向设置的权重所占的比率。
线程模型
基本概念
dubbo的线程模型关注的是“请求/响应”是直接在IO线程上执行还是分发到线程池上由线程中的线程去执行具体的服务。说明如下:
l 如果事件处理的逻辑能迅速完成,并且不会发起新的IO请求,则直接在IO线程上处理更快,因为减少了线程池调度。
l 如果事件处理逻辑较慢,或者需要发起新的IO请求,则必须派发到线程池,否则IO线程阻塞,将导致不能接收其它请求。
线程模型配置
线程模型通常在服务提供者的<dubbo:protocol>标签中配置
<dubbo:protocol
name="dubbo"
port="20880"
dispatcher="all"
threadpool="fixed"
threads="100"
/>
dispatcher分发类型取值有:
l all 所有消息都派发到线程池。
l direct 所有消息都不派发到线程池,全部在IO线程上直接执行。
l message 只有请求响应消息派发到线程池。
l execution 只请求消息派发到线程池。
l connection 在IO线程上,将连接断开事件放入队列,有序逐个执行。
threadpool的取值有:
l fixed 固定大小线程池,启动时建立线程,不关闭,一直持有。(缺省)
l cached 缓存线程池,空闲一分钟自动删除,需要时重建。
l limited 可伸缩线程池,但池中的线程数只会增长不会收缩。
详情参考
http://dubbo.io/User+Guide-zh.htm#UserGuide-zh-%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B
直连提供者
直连提供者,从字面上就知道,消费者绕过注册中心直接连接服务提供者,这通常在开发测试中为了方便使用。
修改\mcweb\mcweb-web\src\main\resources\spring\dubbo-consumer.xml
<!-- 注册中心地址 -->
<!-- <dubbo:registry protocol="zookeeper" address="192.168.2.129:2181" check="true"/> -->
<dubbo:reference
interface="com.mcweb.api.service.IUserService"
id="userService"
check="false"
protocol="dubbo"
cluster="failover"
retries="2"
loadbalance="random"
url="dubbo://127.0.0.1:20880"
/>
在<dubbo:reference>中配置url指向提供者,将绕过注册中心,多个地址用分号隔开。注释掉mcweb-web的直 <dubbo:registry ...> 直连接本地的mcweb-logic。看看日志
[DUBBO] Successed connect to server /192.168.2.1:20880 from NettyClient 192.168.2.1 using dubbo version 2.5.3, channel is
[DUBBO] Start NettyClient DESKTOP-HBGAL7B/192.168.2.1 connect to the server /192.168.2.1:20880,
[DUBBO] Refer dubbo service com.mcweb.api.service.IUserService from url dubbo://127.0.0.1:20880/com.mcweb.api.service.IUserService?
mcweb-web 消费者已启动...
0:Get user from mcweb-logic
1:Get user from mcweb-logic
2:Get user from mcweb-logic
只订阅
只订阅是指正在开发中的服务提供者,只订阅自己依赖的服务,而不注册到注册中心,通过直连自己依赖的服务来测试正在开发中的服务。这样可以避免开发未完成的提供者注册到注册中心后影响其它消费者的运行的问题。
禁用注册配置
<dubbo:registry protocol="zookeeper" address="192.168.2.129:2181" register="false"/>
只注册
只注册是指在两个注册中心中,服务提供者只向其中一个注册中心注册服务而不订阅服务。这个又是为了解决什么问题呢,先看下图
服务A和服务B都注册到了两个注册中心中,且都依赖于服务C(需要服务C都在两个注册中心注册),
服务C又依赖服务D (服务C只需要订阅zookeeper2的的D服务,服务D注册到zookeeper2而不从zookeeper2订阅服务)。
禁用订阅配置
<dubbo:registry protocol="zookeeper" address="192.168.2.129:2181" subscribe="false"/>
本文到此,后面我们继续学习多注册中心、服务分组等内容。
基于dubbo的分布式项目实例应用的更多相关文章
- 基于Dubbo的分布式事务框架(LCN)
原文地址:http://原文地址:https://github.com/1991wangliang/transaction 基于Dubbo的分布式事务框架(LCN) 该框架依赖Redis/dubbo/ ...
- 基于 dubbo 的分布式架构
前言 现在越来越多的互联网公司还是将自己公司的项目进行服务化,这确实是今后项目开发的一个趋势,就这个点再凭借之前的 SSM 项目来让第一次接触的同学能快速上手. 浅谈分布式架构 分布式架构单看这个名字 ...
- 基于dubbo构建分布式项目与服务模块
关于分布式服务架构的背景和需求可查阅http://dubbo.io/.不同于传统的单工程项目,本文主要学习如何通过maven和dubbo将构建分布项目以及服务模块,下面直接开始. 创建项目以及模块 ...
- 基于Dubbo框架构建分布式服务(一)
Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配 ...
- 基于Dubbo框架构建分布式服务
Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配 ...
- 如何开发基于Dubbo RPC的分布式服务?
什么是Dubbo? Dubbo能做什么? 在Crystal框架下,如何开发基于Dubbo RPC的服务? 在Crystal框架下,如何调用Dubbo RPC服务? 相关的文章 什么是Dubbo? Du ...
- [转载] 基于Dubbo框架构建分布式服务
转载自http://shiyanjun.cn/archives/1075.html Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务 ...
- Dubbo框架应用之(四)--Dubbo基于Zookeeper实现分布式实例
上三篇文章主要是解决了概念性的补充和学习,充分结合实战来深入理解 入门实例解析 第一:provider-提供服务和相应的接口 创建DemoService接口 package com.unj.dubbo ...
- 基于Nginx和Zookeeper实现Dubbo的分布式服务
一.前言 公司的项目基于阿里的Dubbo 微服务框架开发.为了符合相关监管部门的安全要求,公司购买了华东1.华东2两套异地服务器,一套是业务服务器,一套是灾备服务器.准备在这两套服务器上实现 Dubb ...
随机推荐
- [Objective-c开源库]HHRouter
---恢复内容开始--- 目的 统一客户端内部和外部跳转处理,支持传参数 代码 添加vc,block映射 针对路径做映射,如/user/:userId -> UserViewController ...
- 仅用aspx文件实现Ajax调用后台cs程序。(实例)
仅用aspx文件实现Ajax调用后台cs无刷新程序.(实例) 两个文件:aaa.aspx 和aaa.aspx.cs 一.aaa.aspx <script type="text/java ...
- centos6.5 mysql-server 5.1.73启动失败
yum install mysql-server 安装mysql服务端会把相应的客户端也装上 service mysqld start 启动mysql服务 解决办法: 1.chomod 777 / ...
- YII2之 Scenario
使用方法 // scenario is set as a property $model = new User; $model->scenario = User::SCENARIO_SHOW; ...
- Java关于IO流的介绍
JDK提供的流继承了四大类:InputStream(字节输入流).OutputStream(字节输出流).Reader(字符输入流).Writer(字符输出流). 字符流和字节流的主要区别: ...
- Node.js配合node-http-proxy解决本地开发ajax跨域问题
情景: 前后端分离,本地前端开发调用接口会有跨域问题,一般有以下3种解决方法: 1. 后端接口打包到本地运行(缺点:每次后端更新都要去测试服下一个更新包,还要在本地搭建java运行环境,麻烦) 2. ...
- rocketmq生产者和消费者
1.生产者: package com.ebways.mq.test.mq; import com.alibaba.rocketmq.client.exception.MQClientException ...
- c++单链表基本功能
head_LinkNode.h /*单链表类的头文件*/#include<assert.h>#include"compare.h"typedef int status; ...
- ABAP 将单元格设置编辑状态 FORM
FORM set_style USING fieldname style TYPE string CHANGING ...
- Markdown 语法说明(持续更新-20160822)
Markdown 是一种轻量级的「标记语言」.Markdown 语法的目标是:成为一种适用于网络的书写语言.Markdown 的语法简单,熟悉Markdown语法规则,事倍功半. 语法 插入图片如何定 ...