- 博客(71)
- 收藏
- 关注
原创 RabbitMQ 推拉模式
RabbitMQ 支持两种消息传递模式 : 推模式 (push) 和 拉模式 (pull).推模式 : 消息中间件主动将消息推送给消费者 (对消息的获取更加实时, 适合对数据实时性要求较高的业务, 例如实时数据处理 : 监控系统, 报表系统)拉模式 : 消费者主动从消息中间件拉去消息 (消费端可以按照自己的处理速度来消费, 避免消息积压, 适合需要流量控制或者需要大量计算资源的任务, 拉取模式允许消费者准备好之后再请求消息, 避免资源浪费)RabbitMQ 主要就是基于退模式工作的.
2025-09-09 12:00:00
380
原创 RabbitMQ 幂等性, 顺序性 和 消息积压
幂等性是指对一个系统进行重复调用 (相同的参数), 不论请求多少次, 这些请求对系统的影响都是相同的效果.比如, 数据库中的 seletc 操作, 不同时间两次查询结果可能不同, 但是这个操作是复合幂等性的. 幂等性指的是对资源的影响, 而不是返回结果. 查询操作对数据资源本身不会产生影响, 之所以结果不同, 可能是因为两次查询之间有其他的操作对资源进行了修改.比如, i++ 这个操作, 就是非幂等性的. 如果调用方没有控制好逻辑, 一次流程重复调用好几次, 结果就会不同.
2025-09-08 17:01:58
1095
1
原创 RabbitMQ 事务 和 消息分发
RabbitMQ 队列拥有多个消费者时, 队列会把收到的消息分派给不同的消费者, 消费者之间的消息不会重复. 但是由于 RabbitMQ 的默认分发机制是 轮询进行的, 而没有管消费者是否已经消费或是确认了之前的消息. 结合消费者的消费速度不同, 就很容易造成消费者手中的消息数量差异太大.为了避免这一情况, RabbitMQ 引入限制消费者手中已有的消息数量来控制这种情况.channel.basicQos(int prefetchCount) 用参数的大小来限制;
2025-09-08 12:00:00
632
1
原创 RabbitMQ 死信队列 和 延迟队列
在重试和 TTL 机制里, 我们会淘汰一些不和规定的消息, 但是这些消息可能我们后面会用到, 那我们该去哪里找他们呢?那就是我们的死信队列.消息变成死信消息的原因 :队列达到最大长度消息过期消息被拒绝, 即消息确认中手动确认的两种拒绝情况, 并且不允许重新入队列. (可以是超过重试次数)在某些情况下. 生产者发送了消息, 消费者可能不需要及时的去接受, 而是让消息延迟一段时间发送给消费者.应用场景 :用户发起退款后, 24 小时内商家未处理, 默认退款。
2025-09-08 06:30:00
682
1
原创 RabbitMQ 重试机制 和 TTL
在消息传递过程中, 可能会遇到各种问题, 如网络故障, 服务不可用, 资源不足... 这些问题可能导致消息处理失败. 为了解决这些问题, RabbitMQ 提供了重试机制, 允许消息在处理失败后重新发送. 但如果是程序逻辑引起的错误, 那么多次重试也是没有用的, 可以设置重试次数.
2025-09-07 20:39:05
1003
1
原创 RabbitMQ 可靠传输性(包括消息确认, 持久性和发送方确认)
RabbitMQ 作为消息中间件来说, 最重要的就是收发消息了, 但是我们在收发消息的时候, 可能会因为一系列特殊情况导致消息丢失 : RabbitMQ 对上面消息丢失的情况进行考虑, 做出了不同的应对措施 : RabbitMQ 向消费者发送消息后, 就会删除这条消息. 但是, 如果消费者处理消息异常, 就会造成消息丢失. 为了解决消息在 Broker 和 消费者之间问题 RabbitMQ 推出了消息确认.消费者在订阅队列时, 可以指定 autoAck 参数, 根据这个参数设置, 消息确认机制可以分为两种
2025-09-07 15:53:34
1232
1
原创 RabbitMQ 初步认识
目录2. RabbitMq 的工作流程3. 协议4. 简单的生产者, 消费者模型4.1 我们先引入 rabbitmq 的依赖4.2 生产者4.3 消费者
2025-09-06 12:00:00
441
1
原创 Redis 分布式锁
分布式锁其实就是在一个分布式系统中, 涉及到多个节点访问同一个公共资源的时候, 这个时候就需要通过索来做互斥控制, 否则可能会出现类似 "线程安全" 的问题.
2025-09-05 12:00:00
853
5
原创 Redis 缓存
缓存就是我们可以存放数据的地方, 不过访问缓存比 访问我们一开始存放数据的地方 快.换存的核心思路就是把一些常用的数据放到触手可及(访问速度更快)的地方, 方便随时读取.对于硬件的访问速度来说, 一般情况下, CPU 寄存器 > 内存 > 硬盘 > 网络对于计算机硬件来说, 往往访问速度越快的设备, 成本越高, 存储空间越小, 所以多大部分的时候, 我们在缓存中只放一些热点数据.关于 "二八定律" :20% 的热点数据, 能够应对 80% 的访问场景.
2025-09-04 12:00:00
827
1
原创 Redis 集群
比如有 redis1, redis2, redis3, 这样三个具有主从关系的节点, 其中, redis1 是主节点, redis2 和 redis3 是从节点. 这个时候要是主节点 redis1 挂了, 那么集群就会充当哨兵的作用, 从redis1 管理的两个 从节点中选一个出来当做 主节点, 这个时候 redis1 就变成了从节点. 重启 redis1, redis1 依然会是从节点.这里只是一种可能的分片方式, 实际上分片是非常灵活的, 分片的槽位可以是连续的, 也可以是不连续的.
2025-09-03 20:23:37
1244
1
原创 Redis 哨兵 (基于 Docker)
哨兵节点不能只有一个. 否则哨兵节点挂了也会影响系统可用性.哨兵节点最好是奇数个. 方便选举leader, 得票更容易超过半数.哨兵节点不负责存储数据. 仍然是 redis 主从节点负责存储哨兵 + 主从复制解决的问题是 "提高可用性", 不能解决 "数据极端情况下写丢失" 的问题.哨兵 + 主从复制不能提高数据的存储容量. 当我们需要存的数据接近或者超过机器的物理内存, 这样的结构就难以胜任了.
2025-09-02 19:58:06
1415
1
原创 Redis 主从复制
在若干个 redis 节点中, 有的是 主节点, 有的是从节点, 主节点的数据会同步到从节点中从节点不可以进行数据的修改, 只能进行读操作在分布式系统中, 希望使用多个服务器来部署 redis, 存在一下几种 redis 的部署方式 :主从模式主从 + 哨兵模式集群模式。
2025-09-01 12:00:00
714
1
原创 Redis 事务
redis 事务是只具备原子性的不具备一致性 : redis 没有约束, 也没有回滚机制, 事务执行的过程中如果某个谢盖操作出现是被, 就可能引起不一致的情况不具备持久性 : redis 本身就是内存数据库, 数据是存储在内存中的, 虽然 redis 也有持久化机制, 但是这里的持久化机制和食物没啥直接关系不涉及隔离性 : redis 是一个单线程模型的服务器程序, 所有的请求/事务, 都是 "串行" 执行的。
2025-08-31 14:44:51
340
原创 Redis 持久化策略
我们知道 redis 是一个内存数据库, 把数据存储到内存中的, 然而内存中的数据时不持久的, 想要能够做到持久, 就需要让 redis 把数据存储到硬盘上为了保证速度快, 数据肯定还是得在内存中. 但是为了持久, 数据还得想办法存储在硬盘上Redis 决定, 内存中也存数据. 硬盘上也存数据这样的两份数据, 理论上是完全相同的. 实际上可能存在一个小的概率有差异~~ 取决于咱们具体怎么进行持久化当要插入一个新的数据的时候, 就需要把这个数据, 同时写入内存和硬盘(具体怎么写是不同的策略)~
2025-08-23 15:59:47
880
原创 一篇文章带你搞懂 redis 的基本操作
将 key 对应的 string 表示的浮点数加上对应的值. 如果对应的值是负数, 则视为减去对应的值. 如果 key 不存在, 则视为 key 对应的 value 是0. 如果 key 对应的不是 string, 或者不是一个浮点数, 则报错. 允许采用科学计数法表示浮点数.将 key 对应的 string 表示的数字加上对应的值. 如果 key 不存在, 则视为 key 对应的 value 是0. 如果 key 对应的 string 不是一个整型或者范围超过了 64 位有符号整型, 则报错.
2025-08-05 18:19:00
682
1
原创 Cookie and Session (会话)
很快, 一周过去了~~ 我去复查~~ 我发现, 当时我第一天来看病的这个医生, 她不在!此时, 如果每个医生只是考自己的记忆, 来存储病人的状态, 此时两次访问到不同的医生, 医生就很难知道病人之前的情况了~~硬着头皮, 就去了, 这个新的医生, 就拿着我的就诊卡, 一刷, 就在他的电脑上就出现了我之前的病例。雾化理疗~~ 治疗手段~~ 先开了一周的量~~ 医生说, 先搞一周看看, 一周之后, 再来复查。我大概前段时间, 生病了~~ 声带发炎了~~ 发炎到, 完全说不出话了~~
2025-08-01 08:38:19
170
1
原创 Redis 为啥效率这么高? 速度这么快?
一个线程, 就可以管理多个 socket针对 TCP 来说, 服务器这边每次 要服务一个客户端, 都需要给这个客户端安排一个 socket一个服务器服务多个客户端, 同时就有很多个 socket. 这些 socket 上都是无事不刻的在传输数据嘛???很多情况下, 每个客户端和服务器之间的通信也没那么频繁, 此时这么多 socket 大部分时间都是 静默 的, 上面是没有数据需要传输的.同一时刻, 只有少数 socket 是活跃的~~
2025-07-31 11:27:55
302
1
原创 Redis 中 key 的过期策略 和 定时器的两种实现方式
一个 redis 中可能同时存在很多的 key, 这些 key 中可能有很大一部分都有过期时间, 此时 redis 服务器咋知道哪些 key 已经过期要被删除, 哪些 key 还没过期?如果要直接遍历所有的 key, 显然是行不通的, 效率非常的低。
2025-07-30 16:48:06
632
2
原创 MySQL 事务和锁
事务是把一组SQL语句打包成为一个整体,在这组SQL的执行过程中,要么全部成功,要么全部失败。如果不用事务管理,当执行第一条SQL语句之后,服务器崩溃了那么整体的数据就不正确了。
2025-07-27 13:58:19
1048
1
原创 双写缓冲区 & Redo Log
Redo Log 从内存刷到磁盘上的日志文件使用循环写入的方式,也就是从第一个日志文件顺序写到最后一个日志文件,当最后一个日志文件写满时又重新写第一个日志文件,那么就可能出现日志被覆盖的情况,那么哪些日志可以被覆盖哪些不能被覆盖呢?
2025-07-23 17:05:32
744
1
原创 撤销日志简介
当事务对数据进行修改的时候,每个修改操作都会在磁盘上创建与之对应的UndoLog当事务需要回滚时,会根据UndoLog逐一进行撤销操作,从而保证事务的原子性。也就是说撤销日志是为事务的回滚操作而诞生的机制,它是一个撤销操作记录的集合。Undo日志保存在Undo日志段中,Undo日志段位于回滚段中,回滚段位于undo表空间和全局临时表空间中。
2025-07-21 17:25:08
986
原创 表空间简介
什么是表空间 : 表空间可以理解为MYSQL为了管理数据而设计的一种数据结构,主要描述的对结构的定义,表空间文件是对定义的具体实现,以文件的形式存在于磁盘上,以后我们说的表空间指的就是表空间文件InnoDB存储引擎的表空间包括:系统表空间、独立表空间、通用表空间、临时表空间和撤销表空间。
2025-07-19 14:59:36
929
1
原创 自适应哈希索引 和 日志缓冲区
如果日志不通过LogBuffer直接写入磁盘,那么每次进行DML操作都会进行一次磁盘l/O,这样会严重影响效率,所以把日志统一写入内存中的LogBuffer,根据刷盘策略统一进行落盘操作,可以实现一次磁盘I/O写入多条日志,从而提升效率。在对数据库进行DML操作时,InnoDB会记录对应操作的日志,比如为保证数据完整性实现数据库崩溃恢复的Redo Log,,这些日志会首先写入LogBuffer中,从而解决同步写磁盘导致的性能问题,然后根据不同落盘策略最终写入磁盘。自适应哈希索引的主要作用就是提升查询效率。
2025-07-16 17:39:44
403
1
原创 变更缓冲池简介
由于聚集索引具有唯一性,我们分析一下聚集索引为什么不能被放入变更缓存,假设表中有一个主键(ID),现在有两条INSER 语句,都在插入数据时ID的值相同(id=1),那么在变更缓冲区中就存在两个修改操作,如果以后要合并到缓冲池中,这时就会出现重复的主键值,所以聚集索引的修改不能被加入到变更缓冲区;
2025-07-15 09:40:25
359
1
原创 缓冲池简介
缓冲池中主要缓存的是磁盘中的数据页,由于数据页中没有一个字段用来表示内存中下一页的地址,InnoDB定义了"控制块"的数据结构,控制块中有一个指向数据页内存地址的指针实现"控制块"与数据页的一一对应,并且把每个控制块连接成一个双向链表,用一个单独的头节点记录链表的第一个和最后一个节点,这样通过遍历控制块链表就可以遍历内存中的数据页。面介绍了 Chunk中管理的是具体的数据页,当缓冲池初始化完成时会把每个数据页所占用的内存空间和对应的控制块分配好,只不过是没有从磁盘加载数据时,内存中的数据页是空的而已。
2025-07-14 14:22:08
809
1
原创 数据行结构
为每个没有定义NOT NULL约束也就是可以为NULL的列在NULL值列表中都安排了一个bit位,按列序号从小到大的顺序从右至左依序安排,这就是常说的逆序排列,NULL值列表最小1字节即8bit,如果没有那么多可以为NULL的列,则会用0补满8bit,如果为值为NULL的列超过8个,则新开辟1字节的空间,依此类推;行结构的最左侧是变长字段列表,也叫可变字段长度列表,在这个列表中记录了数据行中所有变长字段的实际长度,这样做的目的,是为了在真实数据区域,可以根据列的长度进行列与列之间的分割;
2025-07-08 18:43:30
726
原创 MySQL 存储结构
表空间文件是用来存储表中数据的文件, 表空间文件的大小由储存的数据多少决定, 不同的表空间文件存储的种类也有所不同, 在 MySQL中表空间分为五类 : 系统表空间, 独立表空间, 通用表空间, 临时表空间和撤销表空间。
2025-07-08 13:21:06
1130
2
原创 存储引擎简介
MyISAM 的三种存储格式中,静态格式是最简单和最安全的(最不容易损坏),同时也是最快的磁盘格式,因为每行的长度固定,根据索引中的行号乘以行长度就可以计算出行位置,此外,每次读取固定数量的行也非常的高效。2. 多个表中根据相同的 ID 查询数据, 建议使用表连接 (如果表多的话, 在表连接的时候会有一个 笛卡尔积, 会有很大的数据), 可以在连接的列上定义外键, 添加外键可以确保被引用的列是用索引。和8.0有所不同的是,在MySQL5.X及以前的版本中使用一个后缀为。
2025-07-03 11:20:34
630
1
原创 MySQL 架构
连接层主要是用于 MySQL 服务和 客户端的连接的MySQL 是一个 网络服务器, 可以通过 IP + 端口号进行访问数据库服务层是整个数据库服务的核心, 主要包含 接收, 解析, 优化, 缓存 ...1. 对数据进行处理2. 如何保证数据安全3. 如何保证读写效率4. 使用哪种储存介质包含了 MySQL 发行版的文件和程序, 以及具体数据和文件和日志, 保存了我们的数据, 存储引擎层所拿的数据就是从这一层拿的。
2025-07-02 11:48:24
1078
1
原创 JavaEE->多线程3
DataSource数据源, 一开始初始化了很多个数据库连接, 当需要用连接的时候从池子中获取一个连接, 用完了还给池子,并不真正的销毁。平时业务程序很难应对流量暴增的情况,正常的流量可以满足,大流量的时,程序会申请很多线程,各种资源,最终服务器资源耗尽,被打爆。线程池中的县城不停的扫描保存任务的集合, 当有任务的时候执行任务, 没有任务的时候阻塞等待, 但不是正真的销毁线程。cpu调度的过程中可能会产生执行顺序的问题,或当一个线程执行到一半的时间被调度走的现象。
2025-06-21 10:16:42
766
1
原创 JavaEE->多线程2
由于线程在执行逻辑之前要拿到锁,当拿到锁时,上一个线程已经执行完了所有的指令,并把修改的值刷回了主内存,当前线程读到了永远都是上一个线程修改后的值。线程A拿到了锁,别的线程如果执行被锁住的代码,必须要等到线程A释放锁,如果线程A没有释放锁,那么别的线程只能阻塞等待,这个状态就是BLOCK。2.线程A,B共同抢一把锁的是时候,存在锁竞争,谁先拿到就先执行自己的逻辑,另一个线程阻塞等待,等到持有锁的线程释放所之后,再参与竞争锁。t1释放锁之后,也有可能第二次循环时t1先于t2拿到锁,因为线程时抢占式执行的。
2025-06-19 23:16:06
786
1
原创 JavaEE->多线程1
操作系统:1.对下(硬件)管理更多计算机设备2.对上(软件)为各种软件提供一个稳定运行环境描述进程:进程控制块(PCB)1.PID(标识系统中正在运行的进程)2.内存指针:程序运行之前操作系统会为它分配一份有效的内存空间3.文件描述符表(集合):程序运行起来需要访问一些文件资源,操作系统负责为程序分配资源4.进程的状态:就绪,阻塞5.进程的优先级:哪个进程利用CPU资源更多(不太准)6.进程的上下文:保存上下文(读档),恢复上下文(存档)
2025-06-17 23:08:51
988
1
原创 java--字符串不可变的原因
1.首先我们要了解为什么字符串是不可变的, 我们从 JDK 源码来看, 字符串类型的变量储存在一个字符数组中, 而这个字符数组是被 final 所修饰的, 这就表名了这个字符数组是不可变的, 然后我们再观察源码可知, 源码中只有在构造函数中定义了 String类型的定义, 这就说明字符串被创建后没有别的方法可以在改变它(当然这肯定不包括反射), 那会不会来个类继承这个类在构造方法中使用父类的super(...), 来改变原来的字符串呢?2.现在来说下这样设计的好处。
2025-06-13 09:10:55
216
1
原创 抽象类和接口的区别
1.首先抽象类也是类, 既可以有正常方法, 也可以有抽象方法, 然而接口相当于多个类的规范, 没有方法体, 里面所有的方法和属性都会被隐式定义为 public abstract, java中不允许被多继承, 但允许多实现。2. 抽象类就像是一个产品的半成品, 里面既可以有完整的方法, 也可以有抽象的方法, 接口就像是一个制定标准和规范。抽象类不能实例化对象, 只能创建抽象类的子类, 然后由子类重写抽象类中的抽象方法(全都要重写, 不然还是抽象类)接口是一种引用类型, 但是不能直接实例化。
2025-06-12 20:00:00
526
1
原创 java--认识反射
9. 通过 Class对象 我们可以创建反射对象, 反射私有构造方法, 反射私有属性, 反射所有私有方法, 但是 Enum 对象反射无法得到, 因为在源码中特判了要是属于 Enum 对象, 无法被反射。> parameterTypes) : 获得该类的某个公有的方法。getDeclaredAnnotation(Class annotationClass) : 返回该类中与参数类型匹配的所有注解。getDeclaredClasses() : 返回一个数组, 这个数组包含该类的所有接口类和对象(包括私有的)
2025-06-11 21:58:57
475
1
原创 java--怎么定义枚举类
但是我们会发现 values() 并不在其中, 这是因为枚举类的 values() 方法是在 Java编译器自动添加的, 当使用 enum 关键字定义枚举类是, 虽然我们在代码中没有显示声明 values() 方法, 但编译器会在编译过程中为枚举类生成这个方法。values() : 以数组形式返回枚举类型的所有成员(注意是枚举类型)1.我们要知道我们定义的枚举类默认是继承与Enum(一个抽象类)compareTo() : 比较两个枚举成员在定义时的顺序。4.我们查找枚举类都继承的Enum类。
2025-06-10 23:57:39
406
1
原创 字符串常量池
然后这部分就会在堆中开辟一个空间用来存这个字符串, 同时这个字符串同时在字符串常量池中开辟一个新空间用来存这个字符串, 当在创建一个字符串 String s2 = "aaa";当然这两个字符串的内容要相同,), 当然栈和堆中的地址指向的是同一个位置, 但是在堆中, 字符串有 value 和 hash 之, value存的是字符串的值, 栈中的地址指向的就是这个value 和 hash了。1.首先我们先要了解下字符串是怎么存储的, 我们创建一个字符串 String s = "aaa", 首先我们会在。
2025-06-09 00:25:44
316
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅