使用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服务的可靠性:
容错:单个数据存储节点,不 ...
手把手教你改造 Sentinel Dashboard 实现配置持久化
一. 概述Sentinel客户端默认情况下接收到 Dashboard 推送的规则配置后,可以实时生效。但是有一个致命缺陷,Dashboard和业务服务并没有持久化这些配置,当业务服务重启后,这些规则配置将全部丢失。
Sentinel 提供两种方式修改规则:
通过 API 直接修改 (loadRules)
通过 DataSource 适配不同数据源修改
通过 API 修改比较直观,可以通过以下几个 API 修改不同的规则:
12FlowRuleManager.loadRules(List<FlowRule> rules); // 修改流控规则DegradeRuleManager.loadRules(List<DegradeRule> rules); // 修改降级规则
手动修改规则(硬编码方式)一般仅用于测试和演示,生产上一般通过动态规则源的方式来动态管理规则。
上述 loadRules() 方法只接受内存态的规则对象,但更多时候规则存储在文件、数据库或者配置中心当中。DataSource 接口给我们提供了对接任意配置源的能力。相比直接通过 API 修改规则 ...
一文读懂Apollo客户端配置加载流程
本文基于 apollo-client 2.1.0 版本源码进行分析
Apollo 是携程开源的配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性。
Apollo支持4个维度管理Key-Value格式的配置:
application (应用)
environment (环境)
cluster (集群)
namespace (命名空间)
同时,Apollo基于开源模式开发,开源地址:https://github.com/ctripcorp/apollo
一. SpringBoot集成Apollo1.1 引入Apollo客户端依赖12345<dependency> <groupId>com.ctrip.framework.apollo</groupId> <artifactId>apollo-client</artifactId> <version>2.1.0</version></dependency> ...