分布式重点知识总结

目录

网关

[分布式 ID](#分布式 ID)

分布式锁

CDN

负载均衡

消息队列

Kafka

RocketMQ

RabbitMQ


网关

微服务背景下,一个系统被拆分为多个服务,但是像安全认证,流量控制,日志,监控等功能是每个服务都需要的,没有网关的话,我们就需要在每个服务中单独实现,这使得我们做了很多重复的事情并且没有一个全局的视图来统一管理这些功能。

网关主要做了两件事情:请求转发 + 请求过滤。

绝大部分网关可以提供下面这些功能等(有一些功能需要借助其他框架或者中间件):

  • 请求转发:将请求转发到目标微服务。
  • 负载均衡:根据各个微服务实例的负载情况或者具体的负载均衡策略配置对请求实现动态的负载均衡。
  • 安全认证:对用户请求进行身份验证并仅允许可信客户端访问 API,并且还能够使用类似 RBAC 等方式来授权。
  • 参数校验:支持参数映射与校验逻辑。
  • 日志记录:记录所有请求的行为日志供后续使用。
  • 监控告警:从业务指标、机器指标、JVM 指标等方面进行监控并提供配套的告警机制。
  • 流量控制:对请求的流量进行控制,也就是限制某一时刻内的请求数。
  • 熔断降级:实时监控请求的统计信息,达到配置的失败阈值后,自动熔断,返回默认值。
  • 响应缓存:当用户请求获取的是一些静态的或更新不频繁的数据时,一段时间内多次请求获取到的数据很可能是一样的。对于这种情况可以将响应缓存起来。这样用户请求可以直接在网关层得到响应数据,无需再去访问业务服务,减轻业务服务的负担。

分布式 ID

分布式 ID 作为分布式系统中必不可少的一环,很多地方都要用到分布式 ID。

一个最基本的分布式 ID 需要满足下面这些要求:

  • 全局唯一:ID 的全局唯一性肯定是首先要满足的!
  • 高性能:分布式 ID 的生成速度要快,对本地资源消耗要小。
  • 高可用:生成分布式 ID 的服务要保证可用性无限接近于 100%。
  • 方便易用:拿来即用,使用方便,快速接入!

分布式锁

为了保证共享资源被安全地访问,我们需要使用互斥操作对共享资源进行保护,即同一时刻只允许一个线程访问共享资源,其他线程需要等待当前线程释放后才能访问。这样可以避免数据竞争和脏数据问题,保证程序的正确性和稳定性。

如何才能实现共享资源的互斥访问呢? 锁是一个比较通用的解决方案,更准确点来说是悲观锁。

悲观锁总是假设最坏的情况,认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改),所以每次在获取资源操作的时候都会上锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程

一个最基本的分布式锁需要满足:

  • 互斥:任意一个时刻,锁只能被一个线程持有。
  • 高可用:锁服务是高可用的,当一个锁服务出现问题,能够自动切换到另外一个锁服务。并且,即使客户端的释放锁的代码逻辑出现问题,锁最终一定还是会被释放,不会影响其他线程对共享资源的访问。这一般是通过超时机制实现的。
  • 可重入:一个节点获取了锁之后,还可以再次获取锁。

除了上面这三个基本条件之外,一个好的分布式锁还需要满足下面这些条件:

  • 高性能:获取和释放锁的操作应该快速完成,并且不应该对整个系统的性能造成过大影响。
  • 非阻塞:如果获取不到锁,不能无限期等待,避免对系统正常运行造成影响。

CDN

CDN 全称是 Content Delivery Network/Content Distribution Network,翻译过的意思是 内容分发网络

我们可以将内容分发网络拆开来看:

  • 内容:指的是静态资源比如图片、视频、文档、JS、CSS、HTML。
  • 分发网络:指的是将这些静态资源分发到位于多个不同的地理位置机房中的服务器上,这样,就可以实现静态资源的就近访问比如北京的用户直接访问北京机房的数据。

所以,简单来说,CDN 就是将静态资源分发到多个不同的地方以实现就近访问,进而加快静态资源的访问速度,减轻服务器以及带宽的负担。

  • 回源:当 CDN 节点上没有用户请求的资源或该资源的缓存已经过期时,CDN 节点需要从原始服务器获取最新的资源内容,这个过程就是回源。当用户请求发生回源的话,会导致该请求的响应速度比未使用 CDN 还慢,因为相比于未使用 CDN 还多了一层 CDN 的调用流程。
  • 预热:预热是指在 CDN 上提前将内容缓存到 CDN 节点上。这样当用户在请求这些资源时,能够快速地从最近的 CDN 节点获取到而不需要回源,进而减少了对源站的访问压力,提高了访问速度。

负载均衡

负载均衡 指的是将用户请求分摊到不同的服务器上处理,以提高系统整体的并发处理能力以及可靠性。

负载均衡可以简单分为 服务端负载均衡客户端负载均衡 这两种。

服务端负载均衡 主要应用在 系统外部请求网关层 之间,可以使用 软件 或者 硬件 实现。

客户端负载均衡 主要应用于系统内部的不同的服务之间,可以使用现成的负载均衡组件来实现。

在客户端负载均衡中,客户端会自己维护一份服务器的地址列表,发送请求之前,客户端会根据对应的负载均衡算法来选择具体某一台服务器处理请求。

Java 领域主流的微服务框架 Dubbo、Spring Cloud 等都内置了开箱即用的客户端负载均衡实现。Dubbo 属于是默认自带了负载均衡功能,Spring Cloud 是通过组件的形式实现的负载均衡,属于可选项,比较常用的是 Spring Cloud Load Balancer(官方,推荐) 和 Ribbon(Netflix,已被弃用)。

消息队列

我们可以把消息队列看作是一个存放消息的容器,当我们需要使用消息的时候,直接从容器中取出消息供自己使用即可。由于队列 Queue 是一种先进先出的数据结构,所以消费消息时也是按照顺序来消费的。

我们知道操作系统中的进程通信的一种很重要的方式就是消息队列。我们这里提到的消息队列稍微有点区别,更多指的是各个服务以及系统内部各个组件/模块之前的通信,属于一种 中间件

中间件就是一类为应用软件服务的软件,应用软件是为用户服务的,用户不会接触或者使用到中间件。

通常来说,使用消息队列主要能为我们的系统带来下面三点好处:

  1. 通过异步处理提高系统性能(减少响应所需时间)
  2. 削峰/限流
  3. 降低系统耦合性

Kafka

Kafka 是一个分布式流式处理平台。

流平台具有三个关键功能:

  1. 消息队列:发布和订阅消息流,这个功能类似于消息队列,这也是 Kafka 也被归类为消息队列的原因。
  2. 容错的持久方式存储记录消息流:Kafka 会把消息持久化到磁盘,有效避免了消息丢失的风险。
  3. 流式处理平台: 在消息发布的时候进行处理,Kafka 提供了一个完整的流式处理类库。

Kafka 主要有两大应用场景:

  1. 消息队列:建立实时流数据管道,以可靠地在系统或应用程序之间获取数据。
  2. 数据处理: 构建实时的流数据处理程序来转换或处理数据流。

与RocketMQ、RabbitMQ 对比优点

  • 极致的性能:基于 Scala 和 Java 语言开发,设计中大量使用了批量处理和异步的思想,最高可以每秒处理千万级别的消息。
  • 生态系统兼容性无可匹敌:Kafka 与周边生态系统的兼容性是最好的没有之一,尤其在大数据和流计算领域。

RocketMQ

RocketMQ 是一个 队列模型 的消息中间件,具有高性能、高可靠、高实时、分布式 的特点。它是一个采用 Java 语言开发的分布式的消息系统,由阿里巴巴团队开发,在 2016 年底贡献给 Apache,成为了 Apache 的一个顶级项目。 在阿里内部,RocketMQ 很好地服务了集团大大小小上千个应用,在每年的双十一当天,更有不可思议的万亿级消息通过 RocketMQ 流转。

RabbitMQ

RabbitMQ 是一个在 AMQP(Advanced Message Queuing Protocol )基础上实现的,可复用的企业消息系统。它可以用于大型软件系统各个模块之间的高效通信,支持高并发,支持可扩展。

  • 可靠性: RabbitMQ 使用一些机制来保证可靠性, 如持久化、传输确认及发布确认等。
  • 灵活的路由 : 在消息进入队列之前,通过交换器来路由消息。对于典型的路由功能, RabbitMQ 己经提供了一些内置的交换器来实现。针对更复杂的路由功能,可以将多个交换器绑定在一起, 也可以通过插件机制来实现自己的交换器。
  • 扩展性: 多个 RabbitMQ 节点可以组成一个集群,也可以根据实际业务情况动态地扩展 集群中节点。
  • 高可用性 : 队列可以在集群中的机器上设置镜像,使得在部分节点出现问题的情况下队 列仍然可用。
  • 多种协议: RabbitMQ 除了原生支持 AMQP 协议,还支持 STOMP, MQTT 等多种消息 中间件协议。
  • 多语言客户端 :RabbitMQ 几乎支持所有常用语言,比如 Java、 Python、 Ruby、 PHP、 C#、 JavaScript 等。
  • 管理界面 : RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息、集 群中的节点等。
  • 插件机制 : RabbitMQ 提供了许多插件 , 以实现从多方面进行扩展,当然也可以编写自 己的插件。

RabbitMQ 整体上是一个生产者与消费者模型,主要负责接收、存储和转发消息。可以把消息传递的过程想象成:当你将一个包裹送到邮局,邮局会暂存并最终将邮件通过邮递员送到收件人的手上,RabbitMQ 就好比由邮局、邮箱和邮递员组成的一个系统。从计算机术语层面来说,RabbitMQ 模型更像是一种交换机模型。

相关推荐
m0_5719575843 分钟前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
魔道不误砍柴功3 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2343 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨3 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
测开小菜鸟4 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity5 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天5 小时前
java的threadlocal为何内存泄漏
java
caridle6 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^6 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋36 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx