Spring State Machine入门实践
Spring State Machine入门实践一. 状态机1.1 什么是状态先来解释什么是状态( State )。现实事物是有不同状态的,例如一个自动门,就有 open 和 closed 两种状态。我们通常所说的状态机是有限状态机,也就是被描述的事物的状态的数量是有限个,例如自动门的状态就是两个 open 和 closed 。
状态机,也就是 State Machine ,不是指一台实际机器,而是指一个数学模型。说白了,一般就是指一张状态转换图。
状态机的全称是有限状态自动机,自动两个字也是包含重要含义的。给定一个状态机,同时给定它的当前状态以及输入,那么输出状态时可以明确的运算出来的。例如对于自动门,给定初始状态 closed ,给定输入“开门”,那么下一个状态时可以运算出来的。
1.2 状态机中的概念下面来给出状态机的四大概念:
State:状态,一个状态机至少要包含两个状态。
Event:事件,事件就是执行某个操作的触发条件或者口令。对于自动门,“按开门按钮”就是一个事件。
Action:动作,事件发生以后要执行动作。例如事件是“按开门按钮”,动作是“开门”。编程的时候,一个 ...
深入剖析缓存一致性问题:延时双删的利弊与替代方案
在当今的分布式系统架构中,缓存凭借其快速的数据读取能力,成为提升系统性能和响应速度的关键组件。然而,缓存的引入也带来了缓存一致性问题,这一问题成为开发者在系统设计与维护中必须攻克的难关。缓存一致性问题聚焦于数据更新时,如何确保数据库和缓存中的数据始终保持同步,一旦处理不当,数据不一致的情况就会出现,进而引发各类难以排查和修复的系统故障。
一. 缓存一致性问题的常见场景在实际的系统运行中,缓存一致性问题主要集中在数据更新操作阶段。当数据库中的数据发生变动,缓存中的对应数据也需要及时更新,以保证数据的一致性。常见的读写场景如下:
读操作流程:系统首先尝试从缓存中读取数据。若缓存中存在所需数据,直接返回;若缓存未命中,则从数据库中读取数据,并将读取到的数据存入缓存,以便后续读取操作能够更快响应。
写操作流程:一般的做法是先更新数据库,然后再更新缓存。但如果在更新数据库之后、更新缓存之前出现异常情况,比如系统崩溃、网络中断等,就会导致数据库和缓存中的数据不一致,数据库已更新为新数据,而缓存中仍保留着旧数据。
二. 单次删除在并发场景下的问题在缓存一致性问题的解决思路中,简单的单 ...
使用ZSH美化Windows系统Git Bash
此前,我们讲解了一种借助 Windows Subsystem for Linux(WSL)让用户在 Windows 操作系统中运用 Linux Shell 命令,进而高效地实现文件访问、编译等开发工作。
Windows系统命令行的最佳实践 | 听到微笑的博客
这种借助 Windows Subsystem for Linux(WSL)的方式,其显著优势在于提供了完整的 Linux 子系统环境,这意味着在常规 Linux 系统中所使用的各类命令,在 WSL 中均可无障碍执行,极大地拓展了 Windows 用户对于 Linux 工具和命令的使用场景。
然而,WSL 是在 Windows 内核之上搭建的轻量级 Linux 兼容层,从某种程度上可以类比为一个能够访问宿主文件的虚拟机。这种架构也引发了一些性能问题。在文件访问性能上,WSL 子系统对 Windows 宿主文件的访问效率偏低,这在处理大量文件的编译打包场景可能会产生明显的延迟。
此外,在环境配置的兼容性上也存在局限。例如,当在 Windows 宿主系统中安装并配置好 Java JDK 后,WSL 子系统并不能直接调用宿主机环境的 ja ...
探寻快速排序的局限性及其优化策略
一. 快速排序之局限快速排序的平均时间复杂度为O(nlogn)。其核心步骤是:先从待排序数组中选定一个元素作为基准(pivot),通过一趟排序将数组分成两部分,使得左边部分的元素都小于等于基准元素,右边部分的元素都大于等于基准元素;接着对划分后的左右子数组分别递归进行上述操作,即再次选择基准元素划分子数组,持续此过程,直至子数组长度为或,此时整个数组变为有序状态。
然而,快速排序的性能与基准元素的选取策略紧密相关。若始终选取第一个或最后一个元素作为基准,当输入数组恰好有序或逆序时,每次划分都会得到极不均衡的两个子数组,其中一个子数组可能为空,另一个子数组则几乎包含所有剩余元素。这将导致快速排序退化为类似冒泡排序的操作,时间复杂度从平均的恶化为 O(n²)。此时,第三方攻击者可能进行复杂度攻击,他们刻意构造有序或逆序的输入数据,使快速排序算法陷入最坏情况的执行路径,导致算法效率急剧下降。这在对性能要求极高且涉及安全敏感的场景中,可能引发严重问题。
二. 优化策略的多维探索2.1 基准优化的关键举措随机基准:随机选择基准元素可以减少最坏情况的发生概率。在快速排序中,基准元素的选择对算法的性 ...
HTTPS如何保证传输安全
一. 什么是 HTTPSHTTP 由于是明文传输,所谓的明文,就是说客户端与服务端通信的信息都是肉眼可见的,随意使用一个抓包工具都可以截获通信的内容。
所以安全上存在以下三个风险:
窃听风险,比如通信链路上可以获取通信内容,用户号容易没。
篡改风险,比如强制植入垃圾广告,视觉污染,用户眼容易瞎。
冒充风险,比如冒充淘宝网站,用户钱容易没。
HTTPS 在 HTTP 与 TCP 层之间加入了 TLS 协议,来解决上述的风险。
二. HTTPS 加密流程HTTPS 主要是通过在 HTTP 协议基础上加入 SSL/TLS 协议来实现加密,HTTPS 是应用层协议,需要先建立 TCP 连接,并完成 TLS 握手后,才能建立通信安全的连接。其加密过程分为对称加密和非对称加密两个阶段。非对称加密阶段主要目的是为了交换对称加密密钥,我们也称之为 TLS 协议握手,TLS 握手成功后,就会使用对称机密的方式进行加密传输。
在非对称加密阶段,服务器拥有一对公钥和私钥(非对称加密特性:公钥加密的数据只有私钥能解密,私钥加密的数据只有公钥能解密)。服务器将公钥发送给客户端,客户端使用公钥对一 ...
RocketMQ实现原理十问十答
RocketMQ 架构RocketMQ 主要有两大组件,一个是 NameServer,相当于注册中心,内部暂存着 Broker 相关信息;另一个是 Broker,它是消息处理、存储的组件。一个 Topic 消息数据可以分片在多个 Broker 上,这样消息的存储就能做到横向扩展,如果现有的 broker 性能不能满足要,只需要扩展 broker 节点数量即可。每一个 broker 上可以有多个 queue,队列的数量决定着消费者实例的数量,本质上决定着消费能力的上限(一个队列通常情况下只会被一个 Consumer 消费,如果多个消费者消费一个队列,就会有并发问题,需要加锁,这样与整体高性能的设计目标背道而驰)。
Broker在启动时,会将自身保存的 topic 信息全部注册至NameServer,然后每隔30s会向NameServer通过心跳更新自身的Topic信息。NameServer 每隔10s 会扫描 brokerLiveTable,检测表中上次收到心跳包的时间,比较当前时间与上一次时间,如果超过120s,则会认为broker不可用,移除路由表中该broker相关的所有信息。
...
深入剖析RocketMQ消息消费原理
本文参考转载至《RocketMQ技术内幕 第2版》
一. 消息消费概述消息消费以组的模式开展,一个消费组可以包含多个消费者,每个消费组可以订阅多个主题,消费组之间有集群模式和广播模式两种消费模式。集群模式是当前主题下的同一条消息只允许被其中一个消费者消费。广播模式是当前主题下的同一条消息将被集群内的所有消费者消费一次。
消息服务器与消费者之间的消息传送也有两种方式:推模式和拉模式。所谓的拉模式,是消费端主动发起拉取消息的请求,而推模式是消息到达消息服务器后,再推送给消息消费者。RocketMQ消息推模式基于拉模式实现,在拉模式上包装一层,一个拉取任务完成后开始下一个拉取任务。
集群模式下,多个消费者如何对消息队列进行负载呢?消息队列负载机制遵循一个通用的思想:一个消息队列同一时间只允许被一个消费者消费,一个消费者可以消费多个消息队列。
RocketMQ 支持局部顺序消息消费,也就是保证同一个消息队列上的消息按顺序消费。不支持消息全局顺序消费,如果要实现某一主题的全局顺序消息消费,可以将该主题的队列数设置为1,牺牲高可用性。RocketMQ支持两种消息过滤模式:表达式(TAG、SQL ...
Raft协议深度解析:RocketMQ中基于DLedger的日志主从复制
本文所涉及的注释源码:bigcoder84/dledger
Raft 协议主要包含两个部分:Leader选举和日志复制。
前面我们在 Raft协议深度解析:RocketMQ中的自动Leader选举与故障转移 一文中已经详细介绍了DLedger如何实现Leader选举的,而本文主要聚焦于Leader选举完成后的日志复制的过程。
一. RocketMQ DLedger 存储实现说起日志的复制,就必须要从日志存储实现说起,它约束着Raft每一个结点如何存储数据。下面先介绍一次Raft存储的核心实现类:
1.1 存储实现核心类
DLedgerStore:存储抽象类,该类有如下核心抽象方法:
getMemberState: 获取节点状态机
appendAsLeader:向主节点追加日志(数据)
appendAsFollower:向从节点广播日志(数据)
get:根据日志下标查找日志
getLedgerEndTerm:获取Leader节点当前最大的投票轮次
getLedgerEndIndex:获取Leader节点下一条日志写入的日志序号
truncate:删除日志
getFirst ...
Raft协议深度解析:RocketMQ中的自动Leader选举与故障转移
本文所涉及的注释源码:bigcoder84/dledger
RocketMQ 4.5版本之前,可以采用主从架构进行集群部署,但是如果 master 节点挂掉,不能自动在集群中选举出新的 master 节点,需要人工介入,在4.5版本之后提供了 DLedger 模式,DLedger 是 Open Messaging 发布的一个基于 Raft 协议实现的Java类库,可以方便引用到系统中,满足其高可用、高可靠、强一致的需求,其中在 RocketMQ 中作为消息 Broker 存储高可用实现的一种解决方案。使用Raft算法,如果 master 节点出现故障,可以自动选举出新的 master 进行切换。
在阅读本文之前,建议先仔细了解Raft协议的思路,具体可移步至:深度解析 Raft 分布式一致性协议
一. Raft协议概述在分布式系统应用中,高可用、一致性是经常面临的问题,针对不同的应用场景,我们会选择不同的架构方式,比如master-slave、基于ZooKeeper 选主。随着时间的推移,出现了基于Raft算法自动选主的方式,Raft 是在 Paxos 的基础上,做了一些 ...
深度解析 Raft 分布式一致性协议
本文参考转载至:
浅谈 Raft 分布式一致性协议|图解 Raft - 白泽来了 - 博客园 (cnblogs.com)
深度解析 Raft 分布式一致性协议 - 掘金 (juejin.cn)
raft-zh_cn/raft-zh_cn.md at master · maemual/raft-zh_cn (github.com)
本篇文章将模拟一个KV数据读写服务,从提供单一节点读写服务,到结合分布式一致性协议(Raft)后,逐步扩展为一个分布式的,满足一致性读写需求的读写服务的过程。
其中将配合引入Raft协议的种种概念:选主、一致性、共识、安全等,通篇阅读之后,将帮助你深刻理解什么是分布式一致性协议。
一. 单机Key-Value数据读写服务
DB Engine这里可以简单看成对数据的状态进行存储(比如B+树型的组织形式),负责存储Key-Value的内容 ,并假设这个Key-Value服务将提供如下接口:
Get(key) —> value
Put([key, value])
思考此时Key-Value服务的可靠性:
容错:单个数据存储节点,不 ...