什么是Dubbo?
总结一句话,就是:
Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了面向接口的远程方法调用、集群容错和负载均衡、以及服务自动注册和发现的功能。
从这句话我们可以知道 Dubbo的基本定位是RPC框架,另外Dubbo也作为一个分布式服务治理框架,除了能够提供通用RPC框架的远程方法调用功能外,还能提供负载均衡、服务注册与发现等功能。
为什么选择Dubbo?
RPC(Remote Procedure Call):远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的思想。
RPC是一种思想,不是指某种具体的技术。 它的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。为实现该目标,RPC 框架需提供一种透明调用机制让使用者不必显式的区分本地调用和远程调用。常见 RPC 技术和框架有:RMI、Spring RMI、WebService、HTTP、Hessian、Dubbo等。RMI、HTTP、Hessian我们都比较熟悉了,他们用起来也比较简单。实际上在大规模服务化之前,应用可能只是通过RMI或者Hessian等工具,简单的暴露和引用远程服务,通过配置服务的URL地址进行调用,通过F5等硬件进行负载均衡。
但是如果只是简单地配置URL来处理应用与应用之间的远程调用,当远程调用交互越来越多时,URL配置会变得非常庞大,不利于管理,F5硬件负载均衡器的单点压力也越来越大。这个时候将配置URL这一部分功能抽出来作为一个服务注册中心,会更加清晰合理。服务注册中心的一个功能,就是能够自动理清应用间的依赖关系。通过在接收方获取服务提供方地址列表,实现软负载均衡和 Failover,降低对F5硬件负载均衡器的依赖,也能减少部分成本。
另外,不同的服务、同一个服务在不同的时间需要的机器支持可能都是不同的,这个服务需要多少机器支撑?什么时候该加机
器?如何监控各个服务的调用量、响应时间,是需要考虑的。对这些有了清晰的了解之后,才可以更有效率的利用硬件设备,节省成本。
以12306系统为例,平日里的访问量和春运时的访问量是完全不同的。硬件设备容量不足,必然导致春运时系统崩溃,而保证了春运时的硬件设备,在平日里访问量剧减,又浪费了成本。这些都需要一个解决方案来动态的、流动性的调度各个服务。
dubbo就是其中一种解决方案,也是dubbo出现的原因。
Dubbo架构和工作流程
我们先看一下Dubbo的架构图:
节点角色说明:
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次调和调用时间的监控中心。
Container: 服务运行容器。
调用过程说明:
服务容器负责启动,加载,运行服务提供者。
服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者在启动时,向注册中心订阅自己所需的服务。
注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
那么,我们究竟是在什么地方使用到的 Dubbo 呢?大家请看下面的流程图:
简单来说,用户发送的请求转交给 Nginx,然后 Nginx 决定将请求发送那个服务器(此处为 Tomcat),然后 Tomcat 将请求发送给 Dubbo,由它来决定继续调用哪个 service 层去数据库读取数据。
相信大家对于 Dubbo 作用于何处应该有个大体的了解了。(好像所有RPC框架都是这个流程。。)
Dubbo实现远程方法调用
下面我们一起来用 Dubbo来实现下面的小目标。
(终于要回到我们熟悉的代码部分了,Code Time Begin !)
小目标:对基于远程通信技术(Dubbo技术)的编程有初步的了解。具体需求如下:
1)从消费端(Consumer)把“Hello, I am xxx. Here is Dubbo Consumer.”作为参数调用服务提供端的远程方法;
2)从服务提供端(Provider)读取该参数,并返回消息:“Hello, xxx, nice to meet you! Here is Dubbo Provider.”
我们可以按照以下步骤实现上述需求:
一、定义统一的Api接口
首先我们创建一个公用项目dubbo-api,此项目为Consumer、Provider项目提供接口,保证生产者和消费者所使用的接口统一。我们在 dubbo-api 项目中创建包 com.jvxb.test.dubbo.api,并添加 HelloDubboService 接口。
public interface HelloDubboService {
String helloDubbo(String requestMsg);
}
二、服务端实现接口
import com.jvxb.test.dubbo.api.HelloDubboService;
import org.springframework.stereotype.Service;
@Service("helloDubboService")
public class HelloDubboServiceImpl implements HelloDubboService {
@Override
public String helloDubbo(String requestMsg) {
System.out.println("服务端收到客户端信息:" + requestMsg);
return "Hello, jvxb, nice to meet you! Here is Dubbo Server.";
}
}
三、将服务端实现的接口注册到服务中心
接口实现类添加后,我们需要将其注册到注册中心,只有这样,其他应用才有可能请求到,接下来我们在 src / main / resources 下创建 provider.xml 文件,用于配置dubbo服务端注册,代码如下:
3.1 此时服务端pom.xml中要先引入dubbo 和 zookeeper的依赖。
com.jvxb.test
dubbo-api
0.0.1-SNAPSHOT
com.alibaba
dubbo
2.5.3
org.springframework
spring
com.github.sgroschupf
zkclient
0.1
3.2 在provider.xml中注册提供的服务
3.3 在启动类DubboProviderApplication上添加注解
四、消费端通过注册中心引用接口
4.1 此时消费端pom.xml中要先引入dubbo 和 zookeeper的依赖。(同服务端,此处略)
4.2 在 consumer.xml中获取注册的服务
.3 在启动类DubboConsumerApplication上添加注解