Dubbo产生的背景
Dubbo全称是Apache Dubbo,是一款高性能Java RPC框架。Dubbo由阿里巴巴工程师研发,并且已经贡献给了Apache软件基金会。
官网地址:http://dubbo.apache.org/zh-cn/index.html
Dubbo是在传统应用的单体架构和常规的垂直架构无法再应对大规模应用的背景下产生的。这时候阿里巴巴需要将企业内部大型应用的核心业务抽取出来拆分成一个个相对独立且稳定的模块服务,从而形成一种新的架构,这种架构就是分布式服务架构,Dubbo将被设计成能够支持这种新的架构的基础框架。
那么传统的的单体架构(垂直架构)和分布式服务架构有哪些区别呢?我们通过下面的表格进行比较一下:
单体架构(垂直架构) | 分布式服务架构 | |
---|---|---|
新功能研发成本 | 研发成本高 | 研发成本较低 |
部署成本 | 容易部署,对应用影响很大 | 部署难度大,对应用影响较小 |
系统稳定性 | 故障影响大,稳定性低 | 故障影响小,稳定性高 |
架构设计成本 | 难度小,设计成本低 | 难度大,设计成本高 |
系统性能 | 响应较快,但吞吐量小 | 响应慢,但吞吐量大 |
系统维护成本 | 维护成本低 | 维护成本高,运维负责 |
系统扩展性 | 扩展性很差 | 扩展性很好 |
排查问题 | 简单 | 复杂 |
在使用分布式服务架构进行大规模服务化之前,Dubbo需要解决服务的暴露和调用远程服务这两个问题,所以需要有一个服务注册中心,动态地注册和发现服务,使服务的位置透明。并通过在消费方获取服务提供方地址列表,实现软负载均衡和 Failover,降低对 F5 硬件负载均衡器的依赖,也能减少部分成本。
此外由于使用了分布式服务架构,服务实例大规模增加,监控服务的调用量、响应时间、负载等等这些信息将变得非常必要,能够让运维知道服务需要多少机器支撑,什么时候该加机器。
Dubbo架构
Dubbo架构图
节点角色说明
节点 | 角色说明 |
---|---|
Provider | 暴露服务的服务提供方 |
Consumer | 调用远程服务的服务消费方 |
Registry | 服务注册与发现的注册中心 |
Monitor | 统计服务的调用次数和调用时间的监控中心 |
Container | 服务运行容器 |
调用关系说明
- 服务容器负责启动,加载,运行服务提供者。
- 服务提供者在启动时,向注册中心注册自己提供的服务。
- 服务消费者在启动时,向注册中心订阅自己所需的服务。
- 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
Dubbo快速入门
第一步:使用Zookeeper作为Dubbo框架的注册中心。ZooKeeper是一个分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。Dubbo默认推荐使用Zookeeper作为其注册中心。
zookeeper下载地址(使用3.4.13版本):https://archive.apache.org/dist/zookeeper/zookeeper-3.4.13/
下载完成之后,拷贝到Linux机器下运行,windows环境也是可以的。
#上传文件到linux服务器使用tar命令解压
tar -zxvf zookeeper-3.4.13.tar.gz
#进入到zookeeper目录
cd zookeeper-3.4.13
#创建数据目录
mkdir data
#复制配置文件
cp conf/zoo_sample.cfg conf/zoo.conf
#根据需要修改相关配置 这里我只修改了data目录
vi conf/zoo.conf
在bin目录执行./zkServer.sh start 启动Zookeeper。
测试Zookeeper是否启动正常。
[root@test1 bin]# ./zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /home/server/zookeeper-3.4.13/bin/../conf/zoo.cfg
Mode: standalone
第二步:安装Dubbo管理台Dubbo Admin。Dubbo提供了一个简易的管理台,通过管理台可以看到注册到注册中心Zookeeper上面的服务的基本情况。
Dubbo管理台下载地址:https://github.com/apache/dubbo-admin/tree/master
下载完成之后解压进入到dubbo-admin文件夹,使用maven命令mvn package编译打包Dubb-admin。
打包完成之后得到dubbo-admin-0.0.1-SNAPSHOT.jar,这是一个springboot项目,所以可以直接使用java -jar dubbo-admin-0.0.1-SNAPSHOT.jar命令运行Dubbo管理台。
注意:运行Dubbo管理台之前需要先运行zookeeper注册中心。
Dubbo管理台默认端口是7001,用户名和密码都是root。
第三步: 创建测试项目dubbo-learn
<modules>
<module>provider-service</module>
<module>api-service</module>
<module>consumer-service</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<dubbo.version>2.6.2</dubbo.version>
<curator.version>2.12.0</curator.version>
</properties>
api-service模块:
@Data
public class UserInfo implements Serializable {
private String name;
private String address;
private Date birthday;
private Integer age;
}
public interface UserInfoService {
List<UserInfo> userInfoList(String name);
}
第四步: 提供者服务依赖Dubbo框架。
<dependencies>
<dependency>
<groupId>com.luke.dubbo</groupId>
<artifactId>api-service</artifactId>
<version>1.0</version>
</dependency>
<!--dubbo-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!--操作zookeeper客户端-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator.version}</version>
</dependency>
</dependencies>
public class UserInfoServiceImpl implements UserInfoService {
@Override
public List<UserInfo> userInfoList(String name) {
System.out.println("---------------------userInfoList---------------------"+name);
UserInfo userInfo1 = new UserInfo();
userInfo1.setName(name);
userInfo1.setAddress("beijing");
userInfo1.setAge(18);
userInfo1.setBirthday(new Date());
UserInfo userInfo2 = new UserInfo();
userInfo2.setName(name);
userInfo2.setAddress("shanghai");
userInfo2.setAge(19);
userInfo2.setBirthday(new Date());
return Arrays.asList(userInfo1,userInfo2);
}
}
<?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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://dubbo.apache.org/schema/dubbo
http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系(服务名称) -->
<dubbo:application name="provider-service"/>
<!--指定注册中心地址-->
<dubbo:registry protocol="zookeeper" address="192.168.0.127:2181"/>
<!-- 用dubbo协议在20880端口暴露服务(低层通讯框架Netty监听端口) -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.luke.dubbo.api.UserInfoService" ref="userInfoServiceImpl"/>
<!-- 和本地bean一样实现服务 -->
<bean id="userInfoServiceImpl" class="com.luke.dubbo.provider.service.impl.UserInfoServiceImpl"/>
</beans>
public class ProviderApp {
public static void main(String[] args) throws Exception{
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("provider.xml");
context.start();
System.in.read(); // 按任意键退出
}
}
启动provider-service服务后,可以在Dubbo管理台看到注册信息。
第五步: 消费者服务依赖Dubbo框架。
<dependencies>
<dependency>
<groupId>com.luke.dubbo</groupId>
<artifactId>api-service</artifactId>
<version>1.0</version>
</dependency>
<!--dubbo-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!--操作zookeeper客户端-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator.version}</version>
</dependency>
</dependencies>
public interface TestService {
List<UserInfo> userInfoList(String name);
}
@Service
public class TestServiceImpl implements TestService {
@Autowired
private UserInfoService userInfoService;
@Override
public List<UserInfo> userInfoList(String name) {
return userInfoService.userInfoList(name);
}
}
<?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://dubbo.apache.org/schema/dubbo" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://dubbo.apache.org/schema/dubbo
http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--扫描包-->
<context:component-scan base-package="com.luke.dubbo.consumer"></context:component-scan>
<!-- 提供方应用信息,用于计算依赖关系(服务名称) -->
<dubbo:application name="consumer-service"/>
<!--指定注册中心地址-->
<dubbo:registry protocol="zookeeper" address="192.168.0.127:2181"/>
<!--引用远程服务-->
<dubbo:reference id="userInfoService" interface="com.luke.dubbo.api.UserInfoService" />
</beans>
public class ConsumerApp {
public static void main(String[] args) throws Exception{
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("consumer.xml");
TestService testService = context.getBean(TestService.class);
List<UserInfo> userInfos = testService.userInfoList("test");
userInfos.forEach(userInfo -> System.out.println(userInfo.getAddress()));
context.start();
System.in.read();
}
}
第六步:测试验证。
执行消费者服务后,控制打印出调用结果:
beijing
shanghai
同时可以在Dubbo管理台看到消费者服务注册信息。