SpringCloud学习——SpringCloud Alibaba Sentinel
官方文档:home (sentinelguard.io)
Sentinel 是什么?随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。是分布式系统的流量防卫兵。
Sentinel 的主要特性:
微服务搭建jar 包启动:java -jar sentinel-dashboard-1.8.4.jar --server.port=8888。
1234<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>
12345678910111213141516171819server: port: 8401spring: application: name: sentinel-service cloud ...
SpringCloud学习——Histrix服务限流、降级、熔断
服务降级&熔断&限流服务降级服务降级指的是当服务器压力剧增的情况下,为了保证核心功能的可用性 ,而选择性的降低一些功能的可用性,或者直接关闭该功能。
服务降级是从整个系统的负荷情况出发和考虑的,对某些负荷会比较高的情况,为了预防某些功能(业务场景)出现负荷过载或者响应慢的情况,在其内部暂时舍弃对一些非核心的接口和数据的请求,而直接返回一个提前准备好的 fallback 兜底处理。这样,虽然提供的是一个有损的服务,但却保证了整个系统的稳定性和可用性。
服务熔断现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。
熔断和降级是两个比较容易混淆的概念 ...
SpringCloud学习——配置中心
在分布式微服务系统中,几乎所有服务的运行都离不开配置文件的支持,这些配置文件通常由各个服务自行管理,以 properties 或 yml 格式保存在各个微服务的类路径下,例如 application.properties 或 application.yml 等。
这种将配置文件散落在各个服务中的管理方式,存在以下问题:
管理难度大:配置文件散落在各个微服务中,难以管理。
安全性低:配置跟随源代码保存在代码库中,容易造成配置泄漏。
时效性差:微服务中的配置修改后,必须重启服务,否则无法生效。
局限性明显:无法支持动态调整,例如日志开关、功能开关。
ConfigSpringCloud Config 为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。
SpringCloud Config 分为服务端和客户端两部分。
Config Server:也被称为分布式配置中心,它是一个独立运行的微服务应用,用来连接配置仓库并为客户端提供获取配置信息、加密信息和解密信息的访问接口。
Config Client:指的是微服务架构中 ...
SpringCloud学习——服务网关Gateway
在微服务架构中,一个系统往往由多个微服务组成,而这些服务可能部署在不同机房、不同地区、不同域名下。这种情况下,客户端(例如浏览器、手机、软件工具等)想要直接请求这些服务,就需要知道它们具体的地址信息,例如 IP 地址、端口号等。
这种客户端直接请求服务的方式存在以下问题:
当服务数量众多时,客户端需要维护大量的服务地址,这对于客户端来说,是非常繁琐复杂的。
在某些场景下可能会存在跨域请求的问题。
身份认证的难度大,每个微服务需要独立认证。
API 网关是一个搭建在客户端和微服务之间的服务,我们可以在 API 网关中处理一些非业务功能的逻辑,例如权限验证、监控、缓存、请求路由等。
API 网关就像整个微服务系统的门面一样,是系统对外的唯一入口。有了它,客户端会先将请求发送到 API 网关,然后由 API 网关根据请求的标识信息将请求转发到微服务实例。
对于服务数量众多、复杂度较高、规模比较大的系统来说,使用 API 网关具有以下好处:
客户端通过 API 网关与微服务交互时,客户端只需要知道 API 网关地址即可,而不需要维护大量的服务地址,简化了客户端的开发。
客户端直接与 A ...
SpringCloud学习——服务调用与负载均衡(Ribbon、OpenFeign)
RibbonSpring Cloud Ribbon 是一套基于 Netflix Ribbon 实现的客户端负载均衡和服务调用工具。
Ribbon 会从服务注册中心(如 Eureka Server)中获取服务端列表,然后通过某种负载均衡策略(如简单轮询、随机连接等)将请求分摊给多个服务提供者,从而达到负载均衡的目的。
依赖:由于spring-cloud-starter-netflix-eureka-client 已经包含spring-cloud-starter-netfilx-ribbon ,故而无需额外添加依赖。
负载均衡负载均衡(Load Balance) ,简单点说就是将用户的请求平摊分配到多个服务器上运行,以达到扩展服务器带宽、增强数据处理能力、增加吞吐量、提高网络的可用性和灵活性的目的。常见的负载均衡方式有两种:
服务端负载均衡
客户端负载均衡
服务端负载均衡/集中式负载均衡服务端负载均衡是在客户端和服务端之间建立一个独立的负载均衡服务器,该服务器既可以是硬件设备(例如 F5),也可以是软件(例如 Nginx)。这个负载均衡服务器维护了一份可用服务端清单,然后通过心跳机 ...
MySQL主从延迟的解决方案
之前项目中基于 MySQL 主从复制以及 AOP 的方式实现了读写分离,也写了博客记录了这个实现过程,《SpringBoot实现MySQL读写分离》。
既然配置了 MySQL 主从复制,那么自然会存在主从延迟,如何尽可能减小主从延迟对应用系统的影响是很有必要的思考点。关于这个问题,我阅读了很多资料与博客,并经过自己的实践,总结下了这篇博客。
什么是主从延迟在讨论如何解决主从延迟之前,我们先了解下什么是主从延迟。
为了完成主从复制,从库需要通过 I/O 线程获取主库中 dump 线程读取的 binlog 内容并写入到自己的中继日志 relay log 中,从库的 SQL 线程再读取中继日志,重做中继日志中的日志,相当于再执行一遍 SQL,更新自己的数据库,以达到数据的一致性。
与数据同步有关的时间点主要包括以下三个:
主库执行完一个事务,写入 binlog,将这个时刻记为 T1;
之后传给从库,将从库接收完这个 binlog 的时刻记为 T2;
从库执行完成这个事务,将这个时刻记为 T3。
所谓主从延迟,就是同一个事务,从库执行完成的时间与主库执行完成的时间之差,也就是 T3 - ...
SpringCloud学习——服务注册中心(Eureka、ZooKeeper、Nacos)
服务注册中心在微服务架构中,一个系统通常被拆分为多个模块 / 服务,此时就涉及到模块之间的服务调用问题。
在服务是单实例情况下,可以采用点对点的 HTTP 直接调用,即 IP + Port + 接口的形式。可各模块通常都是多实例集群部署的,以应对服务的压力以及保证可用性。但此时又面临一个问题,调用方如何知晓调用哪个实例,当实例运行失败后,如何转移到别的实例上去处理请求?如果采用了负载均衡,但往往是静态的,在服务不可用时,如果动态的更新负载均衡列表,保证调用者的正常调用呢?
服务注册中心便是为了解决上述问题,将所有的服务统一的、动态的管理起来。所有的服务都与注册中心发生连接,由注册中心统一配置管理,不再由实例自身直接调用。服务管理过程大致过程如下:
服务提供者启动时,将服务提供者的信息主动提交到服务注册中心进行服务注册。
服务调用者启动时,将服务提供者信息从注册中心下载到调用者本地,调用者从本地的服务提供者列表中,基于某种负载均衡策略选择一台服务实例发起远程调用,这是一个点到点调用的方式。
服务注册中心能够感知服务提供者某个实例下线,同时将该实例服务提供者信息从注册中心清除,并通知服务 ...
Zookeeper实战——分布式锁实现以及原理
分布式锁是控制分布式系统之间同步访问共享资源的一种方式。分布式锁的实现方式有很多种,比如 Redis 、数据库 、zookeeper 等。这篇文章主要介绍用 Zookeeper 实现分布式锁。
Zookeeper 分布式锁实现原理先说结论:Zookeeper 是基于临时顺序节点以及 Watcher 监听器机制实现分布式锁的。
(1)ZooKeeper 的每一个节点都是一个天然的顺序发号器。
在每一个节点下面创建临时顺序节点(EPHEMERAL_SEQUENTIAL)类型,新的子节点后面会加上一个次序编号,而这个生成的次序编号是上一个生成的次序编号加一。
例如,有一个用于发号的节点 “/test/lock” 为父节点,可以在这个父节点下面创建相同前缀的临时顺序子节点,假定相同的前缀为 “/test/lock/seq-”。第一个创建的子节点基本上应该为 /test/lock/seq-0000000001,下一个节点则为 /test/lock/seq-0000000002,依次类推。
(2)ZooKeeper 节点的递增有序性可以确保锁的公平。
一个 ZooKeeper 分布式锁,首先需要 ...
哈夫曼树 & 哈夫曼编码
哈夫曼树哈夫曼树的定义:设二叉树具有 n 个带权值的叶节点,那么从根节点到各个叶节点的路径长度与相应叶节点权值的乘积的和,叫作二叉树的带权路径长度 WPL (Weighted Path Length)。具有最小带权路径长度的二叉树称为哈夫曼树 (Huffman Tree),也称为最优二叉树。权值较大的结点离根较近。
构造哈夫曼树的原则(贪心思想):
权值越大的叶节点越靠近根节点
权值越小的叶节点越远离根节点
哈夫曼编码哈夫曼编码就是规定哈夫曼树中的左分支为 0,右分支为 1,从根节点到每个叶节点所经过的分支对应的 0 和 1 组成的序列便为该节点对应字符的编码。这样的编码称为哈夫曼编码。
哈夫曼编码其实就是哈夫曼树的一个非常重要的应用,是可变字长编码 (VLC) 的一种,目的是为了减少存储体积。
如何减少存储体积呢?举个例子:一篇文档只包含字母 A、B、C、D、E、F,它们的出现次数为:A 30次,B 25次,C 20次,D 10次,E 10次,F 5次 。
在数据传送时,信息表现为 0 和 1 的二进制比特流形式。如果每个字符都是定长编码,由于总共有 6 中字母,则每个字母最少使 ...
从 Reactor 模式看 Netty、Redis 线程模型
Reactor 模式目前存在的线程模型有:传统阻塞 I/O 服务模型 和 Reactor 模式。
Reactor 模式是基于事件驱动开发的,核心组成部分包括 Reactor 和线程池,其中 Reactor 负责监听和分发事件,线程池负责处理事件。Reactor 分为三种模型:
单线程模型 (单 Reactor 单线程)
多线程模型 (单 Reactor 多线程)
主从多线程模型 (多 Reactor 多线程)
单 Reactor 单线程Reactor 和 Handler 都在同一个线程中执行,即 select 多路复用、事件分发和事件处理都是在同一个线程上完成的。既要接收客户端的连接请求,向服务端发起连接,又要发送/读取请求或应答/响应消息。
优点:模型简单,没有多线程频繁切换、资源竞争的问题,全部都在一个线程中完成。
缺点:性能问题:一个 NIO 线程同时处理成百上千的链路,存在性能问题,无法完全发挥多核 CPU 的性能,当 Handler在处理某个连接上的业务时,如果发生阻塞,其他所有 Handler 都得不到执行,将无法输入输出,也无法建立连接。
缺点:可靠性问题:若线程进 ...