分类 dubbo
什么是dubbo?
背景
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。
单一应用架构
当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。
垂直应用架构
当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。
分布式服务架构
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。
流动计算架构
当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键。
演进表:
简介
DUBBO是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。
Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度来看,Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。关于注册中心、协议支持、服务监控等内容。
RPC
RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
有多种 RPC模式和执行。最初由 Sun 公司提出。IETF ONC 宪章重新修订了 Sun 版本,使得 ONC RPC 协议成为 IETF 标准协议。现在使用最普遍的模式和执行是开放式软件基础的分布式计算环境(DCE)。
-来自官方
架构
节点角色说明
节点 | 角色说明 |
---|---|
Provider | 暴露服务的服务提供方 |
Consumer | 调用远程服务的服务消费方 |
Registry | 服务注册与发现的注册中心 |
Monitor | 统计服务的调用次数和调用时间的监控中心 |
Container | 服务运行容器 |
RPC需要解决的问题
通讯问题 : 主要是通过在客户端和服务器之间建立TCP连接,远程过程调用的所有交换的数据都在这个连接里传输。连接可以是按需连接,调用结束后就断掉,也可以是长连接,多个远程过程调用共享同一个连接。
寻址问题 : A服务器上的应用怎么告诉底层的RPC框架,如何连接到B服务器(如主机或IP地址)以及特定的端口,方法的名称名称是什么,这样才能完成调用。比如基于Web服务协议栈的RPC,就要提供一个endpoint URI,或者是从UDDI服务上查找。如果是RMI调用的话,还需要一个RMI Registry来注册服务的地址。
序列化 与 反序列化 : 当A服务器上的应用发起远程过程调用时,方法的参数需要通过底层的网络协议如TCP传递到B服务器,由于网络协议是基于二进制的,内存中的参数的值要序列化成二进制的形式,也就是序列化(Serialize)或编组(marshal),通过寻址和传输将序列化的二进制发送给B服务器。
同理,B服务器接收参数要将参数反序列化。B服务器应用调用自己的方法处理后返回的结果也要序列化给A服务器,A服务器接收也要经过反序列化的过程。
开始前
本Demo中的注册中心采用的是Zookeeper
Zookeeper是一个分布式的服务框架,是树形的目录服务的数据存储,能做到集群管理数据,这里能很好的作为Dubbo服务的注册中心。
Dubbo能与Zookeeper做到集群部署,当提供者出现断电等异常停机的时候。Zookeeper注册中心能自动的删除提供者的信息,当提供者重启时,能自动恢复注册数据,以及订阅请求。
关于Zookeeper安装和启动方法,请各位看官自行google
mac用户如果已经安装brew可以直接使用brew install zookeeper
,如下图
Last login: Sat Aug 11 03:52:07 on ttys000
liaozixudeMBP:~ liaozixu$ brew install zookeeper
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core, homebrew/cask).
==> New Formulae
amtk node_exporter
...
==> Renamed Formulae
cdiff -> ydiff crystal-lang -> crystal saltstack -> salt
==> Deleted Formulae
artifactory-cli-go boot2docker-completion
boot2docker wry
==> Downloading https://homebrew.bintray.com/bottles/zookeeper-3.4.12.high_sierr
######################################################################## 100.0%
==> Pouring zookeeper-3.4.12.high_sierra.bottle.tar.gz
==> Caveats
To have launchd start zookeeper now and restart at login:
brew services start zookeeper
Or, if you don t wantneed a background service you can just run:
zkServer start
==> Summary
/usr/local/Cellar/zookeeper/3.4.12: 242 files, 32.9MB
liaozixudeMBP:~ liaozixu$
要先确认Zookeeper开启状态
liaozixudeMBP:~ liaozixu$ zkServer status
ZooKeeper JMX enabled by default
Using config: /usr/local/etc/zookeeper/zoo.cfg
Mode: standalone
创建Dubbo-Server
本人一般使用maven进行包管理,所以本教材中也是使用maven
在pom中加入com.alibaba的dubbo包和org.apache.zookeeper的zookeeper包以及对应的依赖包
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.1</version>
</dependency>
创建DemoService和实现类
DemoService.java
package com.liaozixu.dubbo.server;
public interface DemoService {
String hello(String world);
}
DemoServiceImpl.java
package com.liaozixu.dubbo.server.impl;
import com.liaozixu.dubbo.server.DemoService;
public class DemoServiceImpl implements DemoService {
public String hello(String world) {
System.out.println("hello : " + world);
return "hello " + world;
}
}
applicationProvider
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
<dubbo:application name="dubbo-demo" />
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<dubbo:protocol name="dubbo" port="20880" />
<bean id="demoService" class="com.liaozixu.dubbo.server.impl.DemoServiceImpl" />
<dubbo:service interface="com.liaozixu.dubbo.server.DemoService" ref="demoService" executes="10" />
</beans>
开启服务
main.java
package com.liaozixu.dubbo.server;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class Main {
public static void main(String[] args){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( new String[] { "applicationProvider.xml" });
context.start();
System.out.println("servier is running...");
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
context.close();
}
}
文件结构和运行
至此,服务端已经完成
开始写dubbo-client
创建Dubbo-Client
applicationConsumer
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
<dubbo:application name="dubbo-client" />
<dubbo:registry protocol="zookeeper" address="zookeeper://127.0.0.1:2181" />
<dubbo:reference id="demoService" interface="com.liaozixu.dubbo.server.DemoService" />
</beans>
main.java
package com.liaozixu.dubbo.client;
import com.liaozixu.dubbo.server.DemoService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String args[]){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "applicationConsumer.xml" });
context.start();
DemoService service = (DemoService) context.getBean("demoService");
System.out.println(service.hello("world"));
context.close();
}
}
文件结构和运行
相关代码已经托管在github:https://github.com/liaozixu/dubbo-demo