Dubbo
Dubbo
分布式基础理论
定义
分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统
--《分布式系统原理与范型》
分布式系统是建立在网络之上的软件系统,将原系统进行拆分,通过治理系统保证架构运行。
发展
-
单一应用架构
将所有功能部署在一起,当出现访问压力时,进行集群化处理,只能整体进行扩展,不能对单一功能进行修改。
-
垂直应用架构
将系统拆分城独立的应用,模块相互独立,在访问出现压力时每个功能独部署,但每个模块都时一个完整的系统(从用户界面到后台逻辑),增加了垂直开发的复杂度,同时应用之间的交互变得复杂。
-
分布式架构
在垂直拆分的基础上更具体化拆分(如将前后端进行分离处理),通过远程过程调用的方法达到拆分解耦和的目的。
-
面向服务架构
面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。
RPC
RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。
客户端在调用服务时不是传统在本地调用,服务的调用时通过网络调用
RPC 框架需要完成服务之间的调用传输,完成数据的传递
RPC框架:dubbo、gRPC、Thrift、HSF(High Speed Service Framework)
Dubbo简介
Apache Dubbo™ (incubating)是一款高性能Java RPC框架。
架构设计
-
注册中心
服务注册,服务管理,向消费者提供服务信息。
-
服务提供者
提供后台服务,将信息注册到注册中心,提供给消费者调用。
-
服务消费者
消费者通过订阅注册中心,得到服务提供者的信息,调用服务。
-
监控中心
监控服务提供者和服务消费者的行为。
-
框架容器
入门搭建
Zookeeper
Dubbo推荐使用Zookeeper作为注册中心,从官方网站中找到对应版本下载Zookeeper并应用。
配置文件
#将conf文件中的zoo_sample.cfg复制一份为zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
#数据目录 需要根据自己需要进行修改 也可使用默认
#默认为linux环境 目录 /tmp/zookeeper
dataDir=/tmp/zookeeper
访问端口
clientPort=2181
启动
在目录所在的bin文件夹中,包含了zookeeper启动的win和linux的启动脚本
#在Cmd或者bash中使用
zkServer.cmd/zdServer.sh
...
binding to port 0.0.0.0/0.0.0.0:2181
#zkCli.cmd 可以进行测试
zkCli.cmd
get /
ls /
create -e /newNode abc
get /newNode
#启动完成
服务接口
package com.test.Service;
public interface TestService {
public String getService();
}
提供者
//TestServiceImlp类
package com.example.provider.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.test.Service.TestService;
import org.springframework.stereotype.Component;
@Service //dubbo注解
@Component
public class TestServiceImpl implements TestService {
@Override
public String getService() {
return "This is message from provider";
}
}
#application.properties
dubbo.application.name=provider-testService
//注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
//RPC调用使用的端口和协议
dubbo.protocol.name=dubbo
dubbo.protocol.port=20000
消费者
//GetServiceController.java
package com.example.consumer.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.test.Service.TestService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GetServiceController {
@Reference
TestService testService;
@RequestMapping("/getService")
public String getService(){
String result = testService.getService();
return result;
}
}
dubbo.application.name=comsumer-useService
//注册中心
dubbo.registry.address=zookeeper://127.0.0.1:2181
server.port=80
测试
配置
属性覆盖策略
JVM 启动 -D 参数优先,这样可以使用户在部署和启动时进行参数重写,比如在启动时需改变协议的端口。
XML 次之,如果在 XML 中有配置,则 dubbo.properties 中的相应配置项无效。
Properties 最后,相当于缺省值,只有 XML 没有配置时,dubbo.properties 的相应配置项才会生效,通常用于共享公共配置,比如应用名。
可配置的属性:官方文档
启动检查
通过 spring 配置文件
关闭某个服务的启动时检查 (没有提供者时报错):
<dubbo:reference interface="com.foo.BarService" check="false" />
关闭所有服务的启动时检查 (没有提供者时报错):
<dubbo:consumer check="false" />
关闭注册中心启动时检查 (注册订阅失败时报错):
<dubbo:registry check="false" />
通过 dubbo.properties
dubbo.reference.com.foo.BarService.check=false
dubbo.reference.check=false
dubbo.consumer.check=false
dubbo.registry.check=false
通过 -D 参数
java -Ddubbo.reference.com.foo.BarService.check=false
java -Ddubbo.reference.check=false
java -Ddubbo.consumer.check=false
java -Ddubbo.registry.check=false
负载均衡
在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random
随机调用。
可以自行扩展负载均衡策略,参见:负载均衡扩展
负载均衡策略
-
Random LoadBalance
- 随机,按权重设置随机概率。
- 在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
-
RoundRobin LoadBalance
- 轮询,按公约后的权重设置轮询比率。
- 存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
-
LeastActive LoadBalance
- 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
- 使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
-
ConsistentHash LoadBalance
- 一致性 Hash,相同参数的请求总是发到同一提供者。
- 当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
- 算法参见:http://en.wikipedia.org/wiki/Consistent_hashing
- 缺省只对第一个参数 Hash,如果要修改,请配置
<dubbo:parameter key="hash.arguments" value="0,1" />
- 缺省用 160 份虚拟节点,如果要修改,请配置
<dubbo:parameter key="hash.nodes" value="320" />
配置
-
服务端服务级别
<dubbo:service interface="..." loadbalance="roundrobin" />
-
客户端服务级别
<dubbo:reference interface="..." loadbalance="roundrobin" />
-
服务端方法级别
<dubbo:service interface="..."> <dubbo:method name="..." loadbalance="roundrobin"/> </dubbo:service>
-
客户端方法级别
<dubbo:reference interface="..."> <dubbo:method name="..." loadbalance="roundrobin"/> </dubbo:reference>
直连提供者
在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连,点对点直连方式,将以服务接口为单位,忽略注册中心的提供者列表,A 接口配置点对点,不影响 B 接口从注册中心获取列表。
通过 XML 配置
如果是线上需求需要点对点,可在 <dubbo:reference>
中配置 url 指向提供者,将绕过注册中心,多个地址用分号隔开,配置如下 [1]:
<dubbo:reference id="xxxService" interface="com.alibaba.xxx.XxxService" url="dubbo://localhost:20890" />
通过 -D 参数指定
在 JVM 启动参数中加入-D参数映射服务地址 [2],如:
java -Dcom.alibaba.xxx.XxxService=dubbo://localhost:20890
通过文件映射
如果服务比较多,也可以用文件映射,用 -Ddubbo.resolve.file
指定映射文件路径,此配置优先级高于 <dubbo:reference>
中的配置 [3],如:
java -Ddubbo.resolve.file=xxx.properties
然后在映射文件 xxx.properties
中加入配置,其中 key 为服务名,value 为服务提供者 URL:
com.alibaba.xxx.XxxService=dubbo://localhost:20890
分布式事务
分布式事务基于 JTA/XA 规范实现 [1]。
两阶段提交:
- 本功能暂未实现 ↩︎