目录
一、dubbo简介
二、dubbo环境搭建&快速启动
三、dubbo配置
四、Dubbo执行过程
五、横向对比
1.1 dubbo是什么
dubbo是一款高性能、轻量级的开源Java RPC框架
1.2 dubbo主要功能
面向接口的远程方法调用
智能容错和负载均衡
以及服务自动注册和发现
1.3 dubbo结构
角色:注册中心,服务提供者,服务消费者,dubbo框架容器,监控中心
dubbo启动流程:
0)dubbo容器启动,加载、运行服务提供者
1)服务提供者启动时,向注册中心注册自己的服务
2)服务消费者启动时,从注册中心订阅自己所需的服务
3)注册中心返回服务提供者的地址列表给消费者,当服务提供者发生变化时;注册中心将基于长连接推送变更数据给消费者
4)服务消费者基于软负载均衡策略执行服务调用
5)服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
1.4 dubbo发展历程
独家专访阿里高级技术专家北纬:Dubbo开源重启半年来的快意江湖
2.1 注册中心(zookeeper)安装
wget http://mirrors.cnnic.cn/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz #嫌慢的化可以直接下载附件
tar -zxvf zookeeper-3.4.14.tar.gz
cd zookeeper-3.4.14
cp conf/zoo_sample.cfg conf/zoo.cfg #解压包里面只有zoo_sample.cfg,而没有zoo.cfg,zookeeper的启动依赖zoo.cfg
#按照自己需求配置zookeeper启动属性
bash zkServer.sh start #默认启动端口为2181
zookeeper-3.4.14.tar.gz
注册中心 |
成熟度 |
优点 |
缺点 |
建议 |
Zookeeper注册中心 |
Stable |
支持基于网络的集群方式,有广泛周边开源产品,建议使用dubbo-2.3.3以上版本(推荐使用) |
依赖于Zookeeper的稳定性 |
可用于生产环境 |
Redis注册中心 |
Stable |
支持基于客户端双写的集群方式,性能高 |
要求服务器时间同步,用于检查心跳过期脏数据 |
可用于生产环境 |
Multicast注册中心 |
Tested |
去中心化,不需要安装注册中心 |
依赖于网络拓扑和路由,跨机房有风险 |
小规模应用或开发测试环境 |
Simple注册中心 |
Tested |
Dogfooding,注册中心本身也是一个标准的RPC服务 |
没有集群支持,可能单点故障 |
试用 |
2.2 dubbo管理控制台安装
SpringBoot + dubbo-admin-server + dubbo-admin-ui:(可选,不影响使用。安装管理控制台,可以可视化的管理服务)
下载管理控制台 https://github.com/apache/incubator-dubbo-admin (springboot项目)
启动dubbo-admin-server(后面需要在本地启动服务提供中和服务消费者,为了防止端口冲突,此处配置端口为8888)
启动dubbo-admin-ui,前端使用的是vue,需要Node环境
nvm install 8.4.0
nvm use 8.4.0
cd dubbo-admin-ui
npm install
#更改config/index.js的target端口号为8888(dubbo-admin-server配置的端口号)
npm run dev
#浏览器访问localhost:8081
2.3 dubbo服务提供者
pom.xml
com.alibaba
dubbo-bom
2.6.4
pom
import
com.alibaba
dubbo
2.6.4
org.springframework
spring-context
4.3.10.RELEASE
org.apache.curator
curator-framework
2.12.0
provider.xml
provider代码
3.1 HelloWorldService.java
public interface HelloWorldService {
String sayHello(String name);
}
3.2 HelloWorldServiceImpl.java
import com.sankuai.api.HelloWorldService;
import org.springframework.stereotype.Service;
@Service("helloWorldService")
public class HelloWorldServiceImpl implements HelloWorldService {
@Override
public String sayHello(String name) {
System.out.println("hello" + name);
return "hello" + name;
}
}
3.3 加载spring配置
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("provider.xml");
ctx.start();
System.in.read();
}
}
2.4 dubbo消费者
pom.xml
com.alibaba
dubbo-bom
2.6.4
pom
import
com.alibaba
dubbo
2.6.4
org.springframework
spring-context
4.3.10.RELEASE
org.apache.curator
curator-framework
2.12.0
com.sankuai
dubbo.studying
1.0-SNAPSHOT
consumer.xml
consumer代码
3.1 Conmunicate.java
public interface Conmunicate {
String communicate(String name) ;
}
3.2 ConmunicateImpl.java
import com.sankuai.api.HelloWorldService;
import com.sankuai.consumer.api.Conmunicate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("conmunicateService")
public class ConmunicateImpl implements Conmunicate {
@Autowired
HelloWorldService helloWorldService;
public String communicate(String name) {
return helloWorldService.sayHello(name);
}
}
3.3 加载spring配置,并调用远程服务
import com.sankuai.consumer.impl.ConmunicateImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("consumer.xml");
ConmunicateImpl conmunicate = (ConmunicateImpl) ctx.getBean("conmunicateService");
String s = conmunicate.communicate("zhuyafeng");
System.out.println(s);
System.in.read();
}
}
3.4 监控中心观察消费者信息
2.5 dubbo监控中心安装
下载管理控制中心(https://github.com/apache/dubbo-admin/tree/master)
3.1 配置之间的依赖关系
3.2 dubbo标签配置
标签 |
用途 |
解释 |
备注 |
---|---|---|---|
|
服务配置 |
用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心 |
|
|
引用配置 |
用于创建一个远程服务代理,一个引用可以指向多个注册中心 |
引用缺省是延迟初始化的,只有引用被注入到其它 Bean,或被 getBean() 获取,才会初始化。如果需要饥饿加载,即没有人引用也立即生成动态代理,可以配置: |
|
协议配置 |
用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受 |
|
|
应用配置 |
用于配置当前应用信息,不管该应用是提供者还是消费者 |
|
|
模块配置 |
用于配置当前模块信息,可选 |
|
|
注册中心配置 |
用于配置连接注册中心相关信息 |
|
|
监控中心配置 |
用于配置连接监控中心相关信息,可选 |
|
|
提供方配置 |
当 ProtocolConfig 和 ServiceConfig 某属性没有配置时,采用此缺省值,可选 |
|
|
消费方配置 |
当 ReferenceConfig 某属性没有配置时,采用此缺省值,可选 |
|
|
方法配置 |
用于 ServiceConfig 和 ReferenceConfig 指定方法级的配置信息 |
|
|
参数配置 |
用于指定方法参数配置 |
|
3.3 常用dubbo配置(以xml配置为例)
功能 |
功能 |
配置方式 |
备注 |
---|---|---|---|
启动时检查 |
Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 check="true" |
|
|
集群容错 |
在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试 |
集群容错模式 failover Cluster:失败自动切换,当出现失败,重试其它服务器 Failfast Cluster:快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。 Failsafe Cluster:失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。 Failback Cluster:失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作 Forking Cluster:并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。
|
默认为failover,配合重试使用 |
负载均衡 |
在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用 |
服务端服务级别 客户端服务级别 服务端方法级别 客户端方法级别 |
|
直连服务提供者 |
在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连,点对点直连方式,将以服务接口为单位,忽略注册中心的提供者列表,A 接口配置点对点,不影响 B 接口从注册中心获取列表。 |
|
不要在线上使用!!! |
多协议暴露 |
Dubbo 允许配置多协议,在不同服务上支持不同协议或者同一服务上同时支持多种协议。 |
|
|
服务分组 |
当一个接口有多种实现时,可以用 group 区分 |
服务提供者 服务消费者 |
dubbo2.2.0以上版本,服务消费者支持使用任意版本
|
多版本 |
当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。 可以按照以下的步骤进行版本迁移:
|
老版本服务提供者配置: 新版本服务提供者配置: 老版本服务消费者配置: 新版本服务消费者配置: 如果不需要区分版本,可以按照以下的方式配置 [1]: |
Consumer只能消费与自己 “接口+分组+版本号” 一致的Provider提供的服务。
|
结果缓存 |
结果缓存 ,用于加速热门数据的访问速度,Dubbo 提供声明式缓存,以减少用户加缓存的工作量 |
接口级设置 方法级设置
|
|
上下文信息 |
获取当前RPC的上下文信息 |
|
|
provider异步执行 |
|
1.定义CompletableFuture签名的接口 通过return CompletableFuture.supplyAsync(),业务执行已从Dubbo线程切换到业务线程,避免了对Dubbo线程池的阻塞。 2.使用AsyncContext Dubbo提供了一个类似Serverlet 3.0的异步接口AsyncContext,在没有CompletableFuture签名接口的情况下,也可以实现Provider端的异步执行。
|
|
consumer异步调用 |
|
1.使用CompletableFuture签名的接口,此方法依赖于服务提供者事先定义CompletableFuture签名的服务
2.使用RpcContext
3. 利用Java 8提供的default接口实现,重载一个带有带有CompletableFuture签名的方法 |
方法1是直接使用服务端实现的异步执行
方法2,3是在客户端执行异步调用
Provider端异步执行和Consumer端异步调用是相互独立的,你可以任意正交组合两端配置
|
本地伪装 |
本地伪装通常用于服务降级,比如某验权服务,当服务提供方全部挂掉后,客户端不抛出异常,而是通过 Mock 数据返回授权失败。 |
|
|
本地伪装 |
本地伪装通常用于服务降级,比如某验权服务,当服务提供方全部挂掉后,客户端不抛出异常,而是通过 Mock 数据返回授权失败。 |
|
|
令牌验证 |
通过令牌验证在注册中心控制权限,以决定要不要下发令牌给消费者,可以防止消费者绕过注册中心访问提供者,另外通过注册中心可灵活改变授权方式,而不需修改或升级提供者 |
可以全局设置开启令牌验证: 或 也可在服务级别设置: 或 |
|
线程栈自动dump |
当业务线程池满时,我们需要知道线程都在等待哪些资源、条件,以找到系统的瓶颈点或异常点。dubbo通过Jstack自动导出线程堆栈来保留现场,方便排查问题
|
默认策略:
指定导出路径: # dubbo.properties dubbo.application.dump.directory=/tmp
|
|
序列化 |
dubbo支持多种序列化方式,支持使用高效的Java序列化(Kryo和FST) |
|
性能:dubbo>hession2>json>java 其中dubbo序列化为阿里自研,不建议生产环境使用 |
3.3 dubbo配置属性的覆盖策略
dubbo的属性配置可以出现在狠多地方,关于这些配置的查找顺序符合以下规则:
方法级优先,接口级次之,全局配置再次之。
如果级别一样,则消费方优先,提供方次之。
4.1 服务注册时序图
4.2 服务发现时序图
4.3 服务调用
5.1 各大互联网公司使用的RPC框架
公司 |
RPC框架 |
---|---|
阿里巴巴 |
HSF、Dubbo |
腾讯 |
Tars |
百度 |
brpc |
美团点评 |
mtthrift(基于thrift)、pigeon |
微博 |
Motan |
京东 |
JSF(基于Dubbo) |
网易考拉 |
Dubbok(基于Dubbo) |
当当 |
Dubbox(基于Dubbo) |
|
grpc |
|
thrift |
|
finagle |
5.2 pigeon&dubbo对比
|
Dubbo |
pigeon |
备注 |
---|---|---|---|
开发语言 |
Java |
Java |
|
分布式(服务治理) |
dubbo monitor |
pigeon |
|
序列化方式 |
dubbo(基于hession2)、hession、json、jdk fst、kryo 支持扩展 |
hessian、json、protobuf3、thrift、jdk fst 支持扩展 |
|
注册中心 |
zookeeper、redis、multicast、simple |
zookeeper->mns(基于zookeeper) |
|
跨编程语言 |
不支持 |
不支持 |
|
配置方式 |
注解配置、schema配置、api配置 |
注解配置、schema配置、属性配置、api配置 |
|
服务通信协议 |
Dubbo 协议、 Rmi 协议、 Hessian 协议、 HTTP 协议、 WebService 协议、Dubbo Thrift 协议、Memcached 协议 |
HTTP协议,TCP协议 |
|
负载均衡 |
RandomLoadBalance (默认)、RoundRobinLoadBalance 、 ConsistentHash、LeastActive |
WeightedAutoaware(默认,根据客户端到服务节点的在途请求数,结合有效权重,重新计算请求容量,挑选请求容量最小的服务节点进行随机负载)、Random、RoundRobin |
|
服务容错 |
Failover(默认策略,重试次数2) Failfast(只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录) Failsafe(失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作) Failback (失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作) Forking(调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数) Broadcast(广播调用所有提供者,逐个调用,任意一台报错则报错 。通常用于通知所有提供者更新缓存或日志等本地资源信息) |
failfast(默认,失败之后直接返回) failover(失败转移策略,当调用一个节点失败后,会调用另一个服务节点,重试次数默认为-1,不显示设置retry则不会重试) failsafe(调用失败后,不抛异常,会返回默认值null) forking(并行策略,并行同时调用多个服务节点,以最先返回的结果为最终结果返) hedged(发起调用后,超过hedgedDelay时间后未返回结果,会再次向其他服务节点发送一个请求,以最先返回的结果为结果返回,主要用在解决服务调用长尾问题)
|
|
服务调用方式 |
同步(默认,通过配置asyn属性) 异步 oneway(通过方法里面配置return=“false”属性,同时可以使用sent="true"来等待消息发出,发送失败则抛异常) callback
事件通知:Consumer 端在调用之前、调用之后或出现异常时,触发 oninvoke、onreturn、onthrow 三个事件。
|
sync 默认 oneway 提交请求,无需等待,不需要返回结果 future 请求提交给pigeon后立即返回,不等待返回结果,由pigeon负责等待返回结果,客户端可以自行决定何时何地来取返回结果 callback 回调方式,客户端将请求提交给pigeon后立即返回,也不等待返回结果,它与future方式的区别是,callback必须提供一个实现了pigeon提供的ServiceCallback接口的回调对象给pigeon,pigeon负责接收返回结果并传递回给这个回调对象 Pigeon 异步使用说明 |
其实不管是dubbo还是pigeon,同步调用的底层IO也是异步实现的。客户端发起同步调用之后,会得到一个future对象,只不过同步调用的线程会阻塞到timeout,如果超时没有还没有返回,则返回调用失败
调用方式判断:DubboInvoker |