Dubbo3学习笔记
一、分布式系统中的相关概念
-
并发数:指系统同时能处理的请求数量。
-
并发连接数:指的是客户端向服务器发起请求,并建立了TCP连接。每秒钟服务器连接的总TCP数量
-
请求数:也称为QPS(Query Per Second) 指每秒多少请求.
-
并发用户数:单位时间内有多少用户
-
吞吐量:指单位时间内系统能处理的请求数量。
-
QPS:Query Per Second 每秒查询数。 (一个页面的一次访问,只会形成一个TPS;但一次页面请求,可能产生多次对服务器的请求,就会有多个QPS)
-
TPS:Transactions Per Second 每秒事务数。 (一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。)
-
集群:很多“人”一起 ,干一样的事。
一个业务模块,部署在多台服务器上。
-
分布式:很多“人”一起,干不一样的事。这些不一样的事,合起来是一件大事。
一个大的业务系统,拆分为小的业务模块,分别部署在不同的机器上。
-
服务治理:注册中心、负载均衡、容错、配置中心、限流…
-
架构演进:单体架构 —>水平架构(应用集群)—> 垂直架构 —> 分布式架构(Rpc架构) —> SOA架构 —> 微服务架构
单体架构(全部模块都在一起,但是性能和可伸缩、可扩展性很差)
垂直架构(把模块拆分成独立应用,但是重复模块太多)
分布式架构(抽取重复模块为公共模块,模块之间使用RPC框架调用,但是服务提供者一旦改变,服务消费者会很麻烦)
SOA架构(中间添加一个ESB企业服务总线(Enperpraise Service Bus),就是服务中介,负责服务之间的交互)
SOA = RPC + 服务治理
微服务架构(在SOA的基础上,更加注重组件化和服务化,细分,要求每个模块有独立的数据库,各个模块可以采用不同的技术开发,最终通过http调用)
二、Dubbo概述
-
Dubbo是阿里巴巴公司开源的一个高性能、轻量级的WebRPC 框架,可以帮我们构建企业级的微服务。
-
Dubbo 是 SOA时代的产物,SpringCloud 是微服务时代的产物,Dubbo是一个javaRPC框架,只能远程嗲用,但是SpringCloud有很多现成微服务的解决方案,推荐使用SpringCloud,相当于Dubbo是一款CPU,但是SpringCloud是一台电脑。
-
dubbo3.0之后,阿里巴巴推出自己的微服务解决方案DNS,即Dubbo(webrpc框架)+Nacos(注册中心)+Sentinel(服务降级、限流)
-
dubbo架构中的成员
- 通用内容commons-api
- 功能提供者provider
- 功能调用者consumer
- 注册中心register
-
为什么Provider提供了UserService的实现,而在另一个JVM的Consumer中可以调用?Consumer中调用的到底是什么?
没有直接调用远端的UserServiceImpl,实际上调用的是远端UserServiceImpl的代理对象,Proxy。
-
代理的核心工作是什么?
被consumer实际调用。通过代理对consumer屏蔽网络通信的过程(通信方式、协议、序列化),数据传递。
-
dubbo的端口用-1好一些,避免服务太多时,明写端口发生冲突,端口用-1,如果默认端口20880被占用,那么dubbo就会加一20881作为服务端口,以此类推,所以不会发生端口冲突。
三、基于SpringBoot整合Dubbo3
注意:不管你是发布服务还是调用服务,在Springboot中只需要导入一个dubbo-spring-boot-starter和注册中心依赖即可。其实只需要三个模块:commons-api、consumer和provider就可以实现服务的发布和调用了。
1. 安装注册中心
zookeeper安装(单节点)-------------------------可选
- 下载解压,复制zoo.cfg配置文件,然后新建数据目录,修改zoo.cfg配置文件中的数据存放地址。
- 启动
2.代码实现
1. 创建子父工程----------------可选
这个地方,dubbo-demo是maven父工程,dubbo-api是maven子模块,dubbo-consuer和dubbo-provider都是springboot子模块。
2.父工程导入依赖--------------可选
其实这里后面consumer和provider并没有继承这些依赖,如果想继承,就需要优化一下项目的结构,使consumer和provder都继承父工程,然后在父工程中把公共依赖定义好。
<dependencies>
<!--简化实体类开发-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
<!--logback日志,自带slf4j-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.9</version>
</dependency>
</dependencies>
3.api模块编写公共接口和实体类
实体类
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private String name;
private String password;
}
接口
public interface UserService {
public boolean login(String name,String password);
}
4.服务提供者provider
-
添加依赖
<!--dubbo依赖--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>3.2.0</version> </dependency> <!--导入公共模块依赖--> <dependency> <groupId>pers.jl</groupId> <artifactId>dubbo-api</artifactId> <version>1.0</version> </dependency>
-
添加配置
# 服务名称 spring: application: name: dubbo-provider # dubbo协议和服务端口 dubbo: protocol: name: dubbo port: -1 #端口不会冲突
-
启动类启动Dubbo
@SpringBootApplication @EnableDubbo public class DubboProviderApplication { public static void main(String[] args) { SpringApplication.run(DubboProviderApplication.class, args); } }
-
添加服务实体类发布服务
@DubboService public class UserServiceImpl implements UserService { @Override public boolean login(String name, String password) { System.out.println("我登录啦!用户名:"+name+",密码是:"+password); return false; } }
5.服务调用者consumer
-
添加依赖
<!--dubbo依赖--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>3.2.0</version> </dependency> <!--导入公共模块依赖--> <dependency> <groupId>pers.jl</groupId> <artifactId>dubbo-api</artifactId> <version>1.0</version> </dependency>
-
添加配置
# 调用服务项目名称 spring: application: name: dubbo-consumer # 关闭dubbo的qos dubbo: application: qos-enable: false
-
使用注解调用服务
@SpringBootTest class DubboConsumerApplicationTests { //注意是,由于目前练习是Dubbo直连RPC的方式,所以注入远端Dubbo服务还要添加地址,后续使用注册中心,就不用写地址了,由注册中心去找 @DubboReference(url = "dubbo://192.168.45.166:20880/entity.Service.UserService") private UserService userService; @Test void contextLoads() { userService.login("小明","234567"); } }
-
启动类启动Dubbo
,调用者也有可能成为发布服务的项目,所以添加这个注解好一点。
@SpringBootApplication @EnableDubbo public class DubboConsumerApplication { public static void main(String[] args) { SpringApplication.run(DubboConsumerApplication.class, args); } }
3.注解详解
-
@EnableDubbo
用于扫描@DubboService(加在启动类上,就会扫描启动类所在包及其子包内的所有@DubboService),并把对应的对象实例化,发布成RPC服务。
如果需要扫描其他包下的注解,使用@DubboComponentScan注解即可。
在yml配置文件中,扫描包dubbo.scan.base-packages等同于@EnableDubbo注解
-
@DubboService
SpringBoot会创建这个对象,并发布为Dubbo服务。
实体类最好添加Spring本身的@Service注解,兼容性好一点。
-
@DubboReference
注入远程服务的代理对象。
4.其他
1.DubboRPC直连开发
-
就是最原始的RPC调用,没有注册中心参与,等同于SpringCloud体系中的OpenFeign,但是性能好很多。
-
其中直连开发涉及三个点:协议、服务器(通信方式)、序列化
-
怎么传、用什么传、传递的数据格式是怎样的
-
协议(双方传数据的约定):
- 应用层协议,如Http1.x 、 Http2.x
- 传输层协议:私有协议(就是自定义传参格式,比如路径传参、请求题json)、dubbo
-
通信方式(用什么方式通信,类似手机、电脑):
- 传输层:BIO、NIO、Netty、Mina-----------------(Dubbo内置默认通信是Netty4)
- 应用层:Tomcat、Resin、Jetty
-
序列化(数据传输的格式,会影响传输速度和数据大小)
- hassian
2.Dubbo序列化详解
- 常见Dubbo序列化方式
- Hessian Dubbo协议中默认的序列化实现⽅案
- Java Serialization JDK的序列化⽅式
- Dubbo序列化 阿⾥尚未开发成熟的⾼效java序列化实 现,阿⾥不建议在⽣产环境使⽤它。
- Json序列化 ⽬前有两种实现,⼀种是采⽤的阿⾥的 fastjson库,另⼀种是采⽤dubbo中⾃⼰实现的简单json 库。
- Kryo Java序列化⽅式,后续替换Hessian2,是 ⼀种⾮常成熟的序列化实现,已经在Twitter、 Groupon、Yahoo以及多个著名开源项⽬(如Hive、 Storm)中⼴泛的使⽤。
- FST Java序列化⽅式,后续替换Hessian2,是 ⼀种较新的序列化实现,⽬前还缺乏⾜够多的成熟使⽤ 案例。
- 跨语⾔序列化⽅式 ProtoBuf,Thrift,Avro, MsgPack(MessagePack是⼀种⾼效的⼆进制序列化格式。它允许您在 多种语⾔(如JSON)之间交换数据。但它更 快更⼩。短整型被编码成⼀个字节)
3.Kryo序列化
-
引入依赖
<dependency> <groupId>org.apache.dubbo.extensions</groupId> <artifactId>dubbo-serialization-kryo</artifactId> <version>1.0.1</version> </dependency>
-
配置序列化
-
XML配置方式
<dubbo:protocol name="dubbo" port="20880" serialization="kryo"/>
-
yml配置方式
dubbo: protocol: name: dubbo port: -1 serialization: kryo
-
-
Consumer端调用
@DubboReference(url = "dubbo://192.168.50.62:20880/com.suns.service.UserService?serialization=kryo")