Dubbo 学习记录
本文最后更新于 2022年3月1日 下午
Dubbo
为什么要使用分布式架构
单一应用架构
一种把系统中所有的功能、模块耦合在一个应用中的架构方式,一般只操作一个数据库。代表技术:Struts2,SpringMVC,Spring,MyBatis等。
- 特点:打包成一个独立的单元(导成一个唯一的jar包或者是war包)。会以一个进程的方式来运行。
- 优点:项目易于管理、部署简单。
- 缺点:测试成本高、可伸缩性差、可靠性差、迭代困难、跨语言程度差、团队协作难
RPC架构
远程过程调用。一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。代表技术:Thrift ( Facebook开发的系统内部各语言之间协调通讯的RPC框架,带有强大的代码生成引擎,支持跨语言、多平台调用的。Apache官网有资料)、Hessian (基于HTTP协议的RPC框架,提供RMI功能,且采用二进制协议的轻量级框架)等等。
- 特点:应用直接调用服务,服务之间是隔离的。
- 缺点:服务过多时,管理成本高昂。服务治理,服务注册、发现,服务容错,服务跟踪,服务网关,IP暴露等都是此架构无法避免的问题。
微服务架构
一个大型的复杂软件应用,由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松相合的。每个微服务仅关注于完成一件任务并很好的完成该任务。微服务就是一个轻量级的服务治理方案。对比SOA架构,使用注册中心代替ESB服务总线。注册中心相比服务总线来说,更加轻量级。代表技术:SpringCloud,Dubbo。
- 特点:系统是由多个服务构成,每个服务可以单独独立部署,每个服务之间是松帮合的。服务内部是高内聚的,外部是低耦合的。高内聚就是每个服务只关注完成一个功能。低耦合就是服务之间没有直接关联。
- 优点:
- 测试容易:服务高内聚低耦合,每个服务可以独立测试。
- 可伸缩性强:服务相对独立,可随时增删服务实现系统服务变化,可针对某服务独立水平扩展。
- 可靠性强:服务出现问题,受影响的位置是当前服务,不会影响其他服务。应用健壮性有更好的保证。
- 跨语言程度会更加灵活:可针对服务特性使用不同的语言开发,尽可能发挥出每种语言的特性。
- 团队协作容易:团队专注自主研发的服务,对其他服务的了解可局限在服务的调用上。
- 系统迭代容易:当服务发生变更时,只需针对单一服务进行系统升级迭代。
- 缺点:
- 运维成本过高,部署数量较多:服务过多导致运维成本成倍提升。
- 接口兼容多版本:因服务可独立升级迭代,所以会导致接口版本过多。
- 分布式系统的复杂性:系统分部,导致通讯成本提升,系统复杂度提升。
- 分布式事务:分布式系统会引出分布式事务的出现,现在有很多的分布式事务解决方案,分布式事务不是不可解决的,这不会影响微服务架构的应用。
RPC协议(Remote Procedure Call Protocol)
远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。RPC采用C/S模式。请求程序就是一个Client,而服务提供程序就是一个Server。首先,Client调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,Client调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
其中,Client发送到Server需要经过序列化,接受Server的信息要反序列化,同样,Server接收Client的请求时需要反序列化,发送给Client需要序列化。
基于RMI的RPC实现(不推荐)
项目有rmi-api,rmi-server,rmi-client模块
rmi-api定义接口以及实体类:
rmi-server实现api接口,基于springboot框架:
rmi-client实现Controller,基于springboot:
rmi-server实现类:
1 |
|
rmi-client Controller:
1 |
|
由于RPC需要跨进程即调用不同JVM的方法,故需要配置RMI:
rmi-server,为Client暴露服务:
1 |
|
rmi-client订阅服务:
1 |
|
先启动rmi-server,再启动rmi-client,程序无异常,接口正常调用
Dubbo框架使用
Apache Dubbo提供了六大核心能力:面向接口代理的高性能RPC调用,智能容错和负载均衡,服务自动注册和发现,高度可扩展能力,运行期流量调度,可视化的服务治理与运维。
主要流程如下:
调用关系说明:
- 服务容器负责启动,加载,运行服务提供者。
- 服务提供者在启动时,向注册中心注册自己提供的服务。
- 服务消费者在启动时,向注册中心订阅自己所需的服务。
- 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者
- 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台供消费者进行调用,如果调用失败,再选另一台调用。
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时发送一次统计数据到监控中心。
相关配置和代码编写
与RMI项目一样,Dubbo项目也有三个模块,dubbo-api,dubbo-provider,dubbo-consumer,其中provider,consumer使用springboot框架。
除了springboot起步依赖,还需要映入dubbo:
pom.xml
1 |
|
接口,实体,实现类,Controller均与上面类似,基于注解开发:
provider实现类:
1 |
|
consumer Controller需要引入Service:
1 |
|
Dubbo使用springboot的application.yml配置
provider的application.yml:
1 |
|
consumer的application.yml:
1 |
|
consumer和provider均使用multicast注册中心,特点:不需要启动任何中间节点,只要广播地址一样,就可以互相发现。
注意provider和consumer均使用多播地址,其中consumer的注解
1 |
|
关闭了provider向consumer的单播。
调用http://localhost:9002/user/{id}接口,正常返回json。
使用Zookeeper注册中心
Zookeepr特点,树形结构,支持变更推送,结构图如下:
流程如下:
- 服务提供者启动时:向/dubbo/com.foo.BarService/providers目录下写入自己的URL地址。
- 服务消费者启动时:订阅/dubbo/com.foo.BarService/providers目录下的提供者URL地址。并向/dubbo/com.foo.BarService/consumers目录下写入自己的 URL 地址。
- 监控中心启动时:订阅/dubbo/com.foo.Barservice目录下的所有提供者和消费者URL地址。
使用Docker配置Zookeeper集群以及监控中心
docker-compose.yml
1 |
|
直接sudo docker-compose up -d
启动服务
使用sudo docker-compose stop
关闭容器
使用sudo docker exec -it zookeeper_zoo3_1 /bin/bash
进入第三个zookeepr环境命令行中。
使用./bin/zkCli.sh
与zookeeper连接:
可以看到正常连接。
退出,使用./bin/zkServer.sh status
查看zookeeper状态:
在之前的Dubbo中,只需要修改provider和consumer的application.yml的:
1 |
|
单机则不需要backup:
1 |
|
访问接口:
Dubbo-Admin
docker-compose中已经配置好了,并设置了环境变量。
访问对应端口: