目录
1、分布式系统中的相关概念
1.1 大型互联网项目架构目标
1.2 集群和分布式
1.3 架构演进
1.3.1 单体架构
1.3.2 垂直架构
1.3.3 分布式架构
1.3.4 SOA架构
1.3.5 微服务架构
2、Dubbo概述
2.1 Dubbo架构
3、Dubbo快速入门
3.1 ZooKeeper安装
3.2 Dubbo快速入门
3.2.1 创建一个maven项目
3.2.2 创建服务提供者Provider模块
3.2.3 创建服务消费者Consumer模块
3.2.4 分别启动两个服务,打开浏览器测试
4、Dubbo高级特性
4.1 dubbo-admin管理平台
4.2 Dubbo 常用高级配置
4.2.1 序列化
4.2.2 地址缓存
4.2.3 超时与重试
4.2.4 多版本
4.2.5 负载均衡
4.2.6 集群容错
4.2.7 服务降级
5、代码仓库地址
1、分布式系统中的相关概念
1.1 大型互联网项目架构目标
首先我们要知道什么是互联网项目,聊互联网项目,就不得不需要了解一下它的另外一个兄弟,传统项目。
互联网项目就是我们经常用的像淘宝,微信,百度等,这些是面向广大网民使用的。
传统项目就是公司内部的项目,比如像OA( 办公自动化 ),HR(人力资源),CRM( 客户关系 )等,这些是面向企业内部的。
它们的区别就是,用户的群体不一样,传统项目就是企业员工,而互联网就是广大的网民了,而网民是肯定比企业员工多的,而且是非常多!
然后就是一个忍耐力,像传统项目是给企业员工用的,虽然可能会有BUG,但是你还是得用啊,你不用你就辞职,但是网民不一样,你这个软件不好用,我就换一个软件。
我们制作一个软件肯定是注重几点:
1、用户体验:美观、功能、速度、稳定性; 2、响应是否快:打开一个新页面一瞬间完成;页面内跳转,一刹那间完成。
互联网项目是传统项目复杂很多的,让我门来看看互联网项目有什么特点。
- 用户多
- 流量大,并发高
- 海量数据
- 易受攻击
- 功能繁琐
- 变更快
知道了互联网项目的特点后,我们就要知道设计互联网项的时候要达到什么样的目标:
- 高性能:提供快速的访问体验。
- 高可用:网站服务一直可以正常访问。
- 可伸缩:通过硬件增加/减少,提高/降低处理能力。
- 高可扩展:系统间耦合低,方便的通过新增/移除方式,增加/减少新的功能/模块。
- 安全性:提供网站安全访问和数据加密,安全存储等策略。
- 敏捷性:随需应变,快速响应。
我们主要需要知道衡量网站的性能指标:
- 响应时间:指执行一个请求从开始到最后收到响应数据所花费的总体时间。
- 并发数:指系统同时能处理的请求数量。
-
- 并发连接数:指的是客户端向服务器发起请求,并建立了TCP连接。每秒钟服务器连接的总TCP数量。
- 请求数:也称为QPS(Query Per Second) 指每秒多少请求。
- 并发用户数:单位时间内有多少用户。
- 吞吐量:指单位时间内系统能处理的请求数量。
-
- QPS:Query Per Second 每秒查询数。
- TPS:Transactions Per Second 每秒事务数。 一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。
- 一个页面的一次访问,只会形成一个TPS;但一次页面请求,可能产生多次对服务器的请求,就会有多个QPS。
QPS >= 并发连接数 >= TPS
1.2 集群和分布式
集群:就是很多“人”一起干一样的事情。这里人代指机器 分布式:分布式:很多“人”一起,干不一样的事。这些不一样的事,合起来是一件大事。
它们的好处是什么呢?
高性能 高可用 可伸缩 高可扩展
集群就像是两个厨师,他们要洗菜,切菜,炒菜,两个人干一样的事,这就是集群。
分布式就是只让厨师炒菜,洗菜和切菜重新找人,虽然他们干的事情都不一样,但是合起来就是做饭这一件事。
而且我们中间,比如如果觉得这个洗菜的速度太慢了,我们还可以再加一个人进来洗菜。
了解了基本的概念后呢,我们就来看看它们在互联网中长什么样。
早期的互联网项目就像上图那样,是一种单机的架构,那么这种架构有很多问题,我们要给它搭建集群,来提高它的性能,来提高它的可用性。所以就会变成这样。
我们搞了三个web服务器,然后每个web服务器都部署一份这样的项目,然后这个项目对外提供访问服务,我们就往里加入一个负载均衡的软件或者硬件。这样就提高了性能和可用性,过了一段时间后,我们觉得这样可伸缩和可扩展性不够,我们可以对这个服务进行一个拆分,那就会变成这样。
这样拆完之后,这app就分成了很多个项目,这里面又有集群又有分布式,这样做的好处就显而易见了,如果我们觉得其中一台机器性能不够,我们可以选择换一台机器,或增加一台机器。
1.3 架构演进
1.3.1 单体架构
1.3.2 垂直架构
1.3.3 分布式架构
1.3.4 SOA架构
1.3.5 微服务架构
Dubbo 是 SOA时代的产物,SpringCloud 是微服务时代的产物
2、Dubbo概述
Dubbo是阿里巴巴公司开源的一个高性能、轻量级的 Java RPC 框架。 致力于提供高性能和透明化的 RPC 远程服务调用方案,以及 SOA 服务治理方案。 官网:http://dubbo.apache.org
2.1 Dubbo架构
节点角色说明:
- Provider:暴露服务的服务提供方
- Container:服务运行容器
- Consumer:调用远程服务的服务消费方
- Registry:服务注册与发现的注册中心
- Monitor:统计服务的调用次数和调用时间的监控中心
3、Dubbo快速入门
3.1 ZooKeeper安装
Zookeeper是注册中心,为什么要使用Zookeeper作为注册中心?
因为官方推荐。
(2条消息) Linux版ZooKeeper安装_一切总会归于平淡的博客-CSDN博客
3.2 Dubbo快速入门
实现步骤:
3.2.1 创建一个maven项目
主要用作父模块管理pom依赖,下面是它的pom文件
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jie.demo</groupId>
<artifactId>dubbo-demo</artifactId>
<version>1.0</version>
<modules>
<module>dubbo-web</module>
<module>dubbo-service</module>
</modules>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.5</version>
<relativePath/>
</parent>
<properties>
<java.version>1.8</java.version>
<dubbo.version>2.7.3</dubbo.version>
</properties>
<dependencyManagement>
<dependencies>
</dependencies>
</dependencyManagement>
<dependencies>
<!--dubbo-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!--ZooKeeper-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
3.2.2 创建服务提供者Provider模块
这里比较主要的就是service层的IUserServiceImpl里的@Service注解了,它是Dubbo下的哦,不要导错了。
然后就是yml文件了。
代码语言:javascript复制server:
port: 8081
dubbo:
application:
name: dubbo-service #应用名称
registry:
address: zookeeper://192.168.58.149:2181 #zookeeper地址
# 注册服务采用的协议 端口号
protocol:
name: dubbo
port: 20880
#配置服务实现类所在包
scan:
base-packages: com.jie.dubboserice.service.impl
3.2.3 创建服务消费者Consumer模块
消费者主要就是Controller层。
然后就是要在pom文件导入服务提供者的模块,正常业务下,我们是要把它导成jar包然后导入的,这里就直接调接口了。
3.2.4 分别启动两个服务,打开浏览器测试
这里启动项目一定要先启动服务提供者。
也许会有其他遗漏的细节,代码仓库地址就放在文章最后了下面了。
4、Dubbo高级特性
4.1 dubbo-admin管理平台
dubbo-admin 管理平台,是图形化的服务管理页面,它可以使我们可以通过肉眼就可以看到有几个生产者,有几个消费者在注册中心注册了。
它的主要功能就是从注册中心中获取所有的提供者/消费者进行配置管理。
路由规则、动态配置、服务降级、访问控制、权重调整、负载均衡等管理功能
dubbo-admin 是一个前后端分离的项目。前端使用vue,后端使用springboot, 安装 dubbo-admin 其实就是部署该项目。
教程,大家看这篇dubbo-admin安装_一切总会归于平淡的博客-CSDN博客博客应该就够了。
4.2 Dubbo 常用高级配置
4.2.1 序列化
两个机器传输数据,如何传输JAVA对象?
现在消费者要去调用生产者的提供的后一个查询服务,那生产者去查数据库,就可以查出来一些数据,再将数据封装成一个对象,再把对象返回给消费者。
但是,这个消费者和生产者未来是要部署在两台机器上的两个项目,如何将生产者的这个对象,传输导消费者的电脑上去,答案就是序列化。
我们可以将这个对象序列化,序列化流的数据,将来消费者和生产者它们要进行通讯就会建立一个流的通道,我们将对象序列化流的数据,通过流发过去就可以了。
然后消费者拿到数据之后,再将其反序列化转换成对象。
不管是序列化还是反序列化,我们都会用到同一个类,我们一般的做法就是将这个类定义到一个独立的模块,消费者和生产者都通过Maven来依赖这个模块。
一套操作下来呢,可能比较麻烦的就是序列化和反序列化了,但是dubbo 内部已经将序列化和反序列化的过程内部封装了,我们只需要在定义pojo类时实现Serializable接口即可 一般会定义一个公共的pojo模块,让生产者和消费者都依赖该模块。
代码演示:
首先我们再创建一个dubbo-pojo模块用来存放对象。
然后就是在dubbo-api模块声明一个方法使用该对象,记得在api模块的pom文件继承poj模块。
接下来就是service模块实现该方法。
web模块controller调用该方法,现在我们的对象是没有序列化的,启动项目访问一下我们看看效果。
不错所料报错了。
那我们现在就去实体类实现Serializable接口。
重启项目,再访问一次。
4.2.2 地址缓存
问题:注册中心挂了,服务是否可以正常访问?
答案:可以。
原因:dubbo服务消费者在第一次调用时,会将服务提供方地址缓存到本地,以后在调用则不会访问注册中心。 当服务提供者地址发生变化时,注册中心会通知服务消费者。
大家可以去尝试一下,注册中心挂了了之后,老服务是可以使用的,但是新服务就要去重启注册中心了。
4.2.3 超时与重试
服务消费者在调用服务提供者的时候发生了阻塞、等待的情形,这个时候,服务消费者会一直等待下去。 在某个峰值时刻,大量的请求都在同时请求服务消费者,会造成线程的大量堆积,势必会造成雪崩。
遇到以上情况,Dubbo会怎么做呢?
dubbo 利用超时机制来解决这个问题,设置一个超时时间,在这个时间段内,无法完成服务访问,则自动断开连接。 使用timeout属性配置超时时间,默认值1000,单位毫秒。
代码演示:
这个属性可以配大@Service注解上,也可以配置到@Reference注解上。
我们先来看看@Service注解。
然后再访问一下,看控制台。
接下来我们看看@Reference
这里,我们只设置1秒,那边设置3秒,来看看是1秒生效,还是3秒生效。
答案是1秒生效。
这里推荐这个超时重试设置在服务的提供方。
说完超时,我们说一下重试这个机制,如果只设置了超时,其实也会引发一些问题。
如果出现网络抖动,则这一次请求就会失败。
那么Dubbo为了预防这个问题,就做了个重试的机制。
通过 retries 属性来设置重试次数。默认为 2 次。
我们之前写过,大家有兴趣可以自己去试试。
4.2.4 多版本
这个就像是,游戏正式服和体验服,当游戏有重大更新,游戏厂家一般不会直接更新到正式服,而是更新到体验服,让一部分玩家去体验服体验,如果没有重大BUG,再更到正式服,让所有玩家体验,一般像体验服这个版本我们叫做:
灰度发布:当出现新功能时,会让一部分用户先使用新功能,用户反馈没问题时,再将所有用户迁移到新功能。
那Dubbo是如何做的呢?
dubbo 中使用version 属性来设置和调用同一个接口的不同版本
4.2.5 负载均衡
在Dubbo中提供4中负载均衡的策略。
- Random :按权重随机,默认值。按权重设置随机概率。属性 weight
- RoundRobin :按权重轮询。
- LeastActive:最少活跃调用数,相同活跃数的随机。
- ConsistentHash:一致性 Hash,相同参数的请求总是发到同一提供者。
具体如何使用:
首先可以在@Service注解上设置权重
然后在@Reference
如果大家不知道在里面填啥可以,如果你用的是IDEA,可以CTRL N,查找AbstractLoadBalance,这个抽象类里面有4个不同的实现类,就是我们所说的4种不同的策略。
挑一个点进去。
现在大家如果不知道或者不记得,可以通过这种方法。
4.2.6 集群容错
对于集群容错,Dubbo提供了蛮多策略。
- Failover Cluster:失败重试。默认值。当出现失败,重试其它服务器 ,默认重试2次,使用 retries 配置。一般用于读操作。
- Failfast Cluster :快速失败,只发起一次调用,失败立即报错。通常用于写操作。
- Failsafe Cluster :失败安全,出现异常时,直接忽略。返回一个空结果。
- Failback Cluster :失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
- Forking Cluster :并行调用多个服务器,只要一个成功即返回。
- Broadcast Cluster :广播调用所有提供者,逐个调用,任意一台报错则报错。
怎么设置呢?
属性是cluster,那剩下的策略是什么呢?我们可以用老办法。
CTRL N,搜索Cluster。
它这里有很多的实现类。
大家就选择自己要使用 的策略点进去看就好了。
4.2.7 服务降级
服务降级就像是,一台机器里面有A,B,C三个服务,然后机器的CPU和内存都要爆满,快要崩了,这个时候运维人员就要看看是否可以舍弃掉一些服务,只留下重要的服务。
Dubbo服务降级的方式有哪些。
如何使用,就是在@Reference注解上使用,例如:
代码语言:javascript复制@Reference(mock = "force:return null")
这个就代表 不在调用某个service 服务。
5、代码仓库地址
Demo地址:dubbo-demo: 初学dubbo