Dubbo 是一个分布式服务治理框架,提供高性能的RPC远程服务调用及服务治理。
Dubbo是阿里巴巴开源的产品(2012),2018年捐献给了apache,现在是apache下的一个顶级开源项目,国内大量企业都在使用Dubbo框架。
Dubbo的官方网站: http://dubbo.apache.org
作用:
1.RPC远程调用
dubbo
spring cloud
hessian
thrift
Motan (新浪微博)
gRPC(google)
2.服务治理
dubbo
spring cloud
motan
dubbo 整体架构
五大核心部件:
Provider: 提供服务的服务提供方(生产者)。
Consumer: 调用远程服务的服务消费方(消费者)。
Registry: 服务注册与发现的注册中心(注册中心)。
Monitor: 统计服务调用次数和调用时间的监控中心(监控中心)。
Container: 服务运行容器(运行容器 spring ioc)。
image.png
Dubbo 的使用
1.引入dubbo依赖
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo (https://mvnrepository.com/artifact/com.alibaba) (<=2.6.7)(https://mvnrepository.com/artifact/org.apache.dubbo) ( >=2.7.0 )
-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.3</version>
</dependency>
2.开发服务接口层,或者说的服务接口定义
通常包括:接口,实体类,常量类,通用异常类等
3.开发服务提供者即provider
<!-- Spring.xml配置文件添加dubbo命名空间和dubbo的schema文件位置-->
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
<!--spring 和 dubbo整合在一起(基于spring scheme文件扩展)-->
<!--该配置是结算服务依赖关系的,可以是配置成项目名称-->
<dubbo:application name="zl-dubbo-provider">
<!--处理QOS 端口占用-->
<dubbo:parameter key="qos.enable" value="true"/>
<dubbo:parameter key="qos.accept.foreign.ip" value="false"/>
<dubbo:parameter key="qos.port" value="33333"/>
</dubbo:aplication>
<!--暴露服务,让其他服务可以调用-->
<!--无注册中心-->
<dubbo:service interface="com.bj.zl.learn.contract.service.UserService"
ref="userService" registry="N/A"/>
<!--有注册中心-->
<dubbo:service interface="com.bj.zl.learn.contract.service.UserService"
ref="userService"/>
<!--服务提供者采用hessian协议,那么到时候消费者就只能用hessian协议来调用我
默认是dubbo协议,选择是dubbo协议,可以不配置
<dubbo:protocol name="dubbo" port="20880" />
dubbo协议底层是Netty,采用TCP协议传输数据,适合小数据量大并发的服务间调用
Hessian协议用于集成Hessian的服务,Hessian底层采用Http通讯,采用Servlet暴露服务,Dubbo框架默认内嵌了Jetty作为服务器实现。
Hessian是Caucho开源的一个RPC框架:[http://hessian.caucho.com],其通讯效率高于WebService和Java自带的序列化。
hessian 需要引入依赖
<!-- hessian -->
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.62</version>
</dependency>
由于采用内嵌的jetty服务器发布服务,所以需要加入jetty的jar包:
<!-- jetty-server -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.4.20.v20190813</version>
</dependency>
<!-- jetty-servlet -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.4.20.v20190813</version>
</dependency>
可以支持多协议
<dubbo:protocol name="hessian" port="9090" server="servlet" contextpath="16-xxx-service"/>
<dubbo:protocol name="dubbo" port="20885" />
<dubbo:service interface="com.bjpowernode.service.UserService" ref="userServiceImpl" protocol="dubbo,hessian"/>
-->
<dubbo:protocol name="hessian" port="9090" server="servlet" contextpath="zl-dubbo-provider"/>
<!--注册中心可以是 zookeeper,redis ,nacos -->
<!--zookeeper注册中心,两种写法,zookeeper注册中心需要引入zookeeper,curator jar包-->
<!--
zookeeper 集群配置方式
<dubbo:registry address="zookeeper://127.0.0.1:2181?backup=127.0.0.3:2181,127.0.0.3:2181,127.0.0.2:2181"/>
<dubbo:registry protocol="zookeeper" address="127.0.0.3:2181,127.0.0.3:2181,127.0.0.2:2181"/>
-->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" />
<!--redis 注册中心,需要引入redis的客户端 jedis jar包
[https://github.com/xetorthio/jedis]-->
<dubbo:registry address="redis://127.0.0.1:6379" />
<dubbo:registry protocol="redis" address="127.0.0.1:6379" />
<!--如果redis有密码,需要配置密码,用户名可以随便写-->
<dubbo:registry address="redis:///127.0.0.1:6379" username="435d23r52" password="123456"/>
<!--nacos 注册中心 需要引入依赖
<!-- nacos-client -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.1.3</version>
</dependency>
[https://github.com/alibaba/nacos/releases]
-->
<dubbo:registry address="nacos:///127.0.0.1:8848" />
4.consumer
<!--该配置是结算服务依赖关系的,可以是配置成项目名称-->
<dubbo:application name="zl-dubbo-consumer"/>
<!--dubbo引用远程服务,底层是TCP连接,端口默认是20880-->
<!--目前是采用直连的方式, 没有注册中心,URL指定连接地址-->
<!--<dubbo:reference id="userService" interface="com.bj.zl.learn.contract.service.UserService"
url="127.0.0.1:20880"/>
-->
<!--
zookeeper 集群配置方式
<dubbo:registry address="zookeeper://127.0.0.1:2181?backup=127.0.0.3:2181,127.0.0.3:2181,127.0.0.2:2181"/>
<dubbo:registry protocol="zookeeper" address="127.0.0.3:2181,127.0.0.3:2181,127.0.0.2:2181"/>
-->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!--超时配置,provider和consumer都可以配置,
provider超时,provider在 provider timeout没有返回,则会超时
consumer超时,consumer没有收到返回结构则会超时
,dubbo默认是1秒, 所有的服务都不检查,即不去检查provider是否可用-->
<dubbo:consumer timeout="10000" check="false"/>
<!--retries="2" 禁止重试设为0 provider与consumer都有的话,以consumer为准-->
<dubbo:service interface="com.bj.zl.learn.contract.service.UserService"
ref="userService" protocol="hessian" retries="2"/>
负载均衡
在集群部署时,Dubbo 提供了多种均衡策略,默认为 random随机 调用。
负载均衡策略
Random LoadBalance
随机策略,随机调用;
RoundRobin LoadBalance
轮询策略,轮流请求,一个请求一次;
LeastActive LoadBalance
最少活跃调用数,使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大;
ConsistentHash LoadBalance
一致性 Hash(算法),相同参数的请求总是发到同一提供者;
random , roundrobin, leastactive
Dubbo令牌验证
通过令牌验证在注册中心控制权限,以决定要不要下发令牌给消费者,可以防止消费者绕过注册中心访问提供者,另外通过注册中心可灵活改变授权方式,而不需修改或升级提供者;
全局设置开启令牌验证:
在服务级别设置:
<dubbo:service interface="com.bjpowernode.UserService" token="true" />
或
<dubbo:service interface="com.bjpowernode.UserService" token="123456" />;
服务提供者设置了token,消费者不需要改变,消费者访问注册中心是回获取到令牌
Dubbo配置覆盖
1、消费者配置优先;
2、最小配置优先;
5、Dubbo集群容错
Failover
失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数 (不含第一次);
Failfast
快速失败,只发起一次调用,失败后立即报错,通常用于写操作,比如新增记录;
Failsafe
失败安全,当调用出现异常时,直接忽略掉,通常用于记录日志等允许失败的操作;
Failback
失败自动恢复,后台记录失败请求,定时重新发起请求,通常用于消息通知操作;
Forking
并行调用多个服务器,只要一个成功即返回,通常用于实时性要求较高的读操作,但需要浪费更多服务资源,可通过 forks="2" 来设置最大并行数;
Broadcast
广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息;
集群容错在服务提供者和消费者,两边都可以配置:
<dubbo:service cluster="failsafe" />
或
<dubbo:reference cluster="failsafe" />
6、Dubbo服务降级
当服务提供方出现故障,或者某些不重要的服务在流量高峰时段关闭调用,可以通过 Mock 返回服务降级数据;
(只能在消费者这边配置,提供者不支持mock配置)
<dubbo:reference interface="com.bjpowernode.UserService" mock="true" />
<dubbo:reference interface="com.bjpowernode.UserService" mock="com.bjpowernode.UserServiceMock" />
<dubbo:reference interface="com.foo.BarService" mock="return null" />
<dubbo:reference interface="com.foo.BarService" mock="force:return null" />
服务降级类要放在接口包下,放在其他地方是不行的,另外在接口类后面加一个Mock并实现接口的所有方法,固定写法;
<dubbo:service/>用于配置服务提供者暴露自己的服务
<dubbo:reference/>用于配置服务消费者引用服务
<dubbo:protocol/>用于配置服务提供者的访问协议
<dubbo:registry/>用于配置注册中心
<dubbo:application/>用于配置应用信息
<dubbo:provider/> 用于配置服务提供者的默认值,即设置<dubbo:service>和<dubbo:protocol>标签的默认值
<dubbo:consumer/>用于配置服务消费者的默认值,即<dubbo:reference>标签的默认值
七大常用标签的联系
公共标签
<dubbo:application/>
<dubbo:registry/>
服务提供者标签
<dubbo:provider/>
<dubbo:protocol/>
<dubbo:service/>
服务消费者标签
<dubbo:consumer/>
<dubbo:reference/>