自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(153)
  • 资源 (1)
  • 收藏
  • 关注

原创 详解 SPI 机制

新建一个 maven 项目// 获取型号// 开关// 调节温度// 模式变更用 maven 把它打成 jar 包,供后续的服务实现使用(服务提供者在项目中就可以引入这个 jar 包)有了这套规范,就保证了产品后期不管怎么更新换代,都能接入到系统来Spring SPI 配置文件是一个固定的文件 -//获取所有factories文件中配置的LoggingSystemFactorySpring 也是支持 ClassPath 中存在多个。

2024-10-07 12:33:59 1355

原创 深入理解 Spring Cache 的工作原理及集成其它第三方缓存

Spring 从 3.1 开始定义了和接口来统一不同的缓存技术Cache:缓存接口,定义缓存操作。RedisCache等: 缓存管理器,管理各种缓存(Cache)组件: 缓存数据时 key 生成策略serialize: 缓存数据时 value 序列化策略@Cacheable【创建、查询缓存】:触发缓存入口(一般放在创建和获取的方法上,@Cacheable注解会先查询是否已经有缓存。如果有,则直接从缓存中返回;如果没有,则会执行方法并返回结果缓存【返回方法返回 NULL,则不进行缓存】)

2024-10-07 12:07:47 1283

原创 【本地缓存】Java 中的 4 种本地缓存

是 Google 开发的 Guava 工具包中一套完善的JVM 本地缓存框架,底层实现的数据结构类似于,但是进行了更多的能力拓展,包括:缓存过期时间设置、缓存容量设置、多种淘汰策略、缓存监控等。是一个支持高并发的线程安全的本地缓存。多线程情况下也可以安全的访问或者更新 Cache,这些都是借鉴了的结果支持最大容量限制支持两种过期删除策略(插入时间和读取时间)支持简单的统计功能基于 LRU 算法实现Caffeine 官网Caffeine 是基于Java 1.8 的高性能本地缓存库。

2024-10-06 14:35:37 6978 1

原创 SpringBoot 集成 JetCache-Alibaba 实现本地缓存

官网地址官方文档JetCache是由阿里巴巴开源的一款基于 Spring 和 Redis 的分布式缓存框架,提供统一的 API 和注解来简化缓存的使用。JetCache提供了比更加强大的注解,可以原生的支持 TTL、两级缓存、分布式自动刷新,还提供了 Cache 接口用于手工缓存操作。当前有四个实现,RedisCacheTairCache(此部分未在 github 开源)、(in memory) 和一个简易的(in memory),要添加新的实现也是非常简单的通过统一的 API 访问 Cache 系统。

2024-10-06 14:35:02 1841

原创 SpringBoot 集成 Ehcache 实现本地缓存

EhCache是一种广泛使用的开源Java 分布式缓存。主要面向通用缓存、Java EE 和轻量级容器,可以和大部分 Java 项目无缝整合。Ehcache虽然也支持分布式模式,但是分布式方案不是很好,建议只将其作为单机的进程内缓存使用直接在 JVM 虚拟机中缓存,速度快,效率高支持多种缓存策略:LRU、LFU、FIFO 淘汰算法支持内存和磁盘存储,默认存储在内存中,如内存不够时把缓存数据同步到磁盘中;支持多缓存管理器实例,以及一个实例的多个缓存区域。

2024-10-06 11:20:13 2500 1

原创 SpringBoot 集成 Caffeine 实现本地缓存

Caffeine 官网Caffeine 是基于Java 1.8 的高性能本地缓存库,同样是 Google 开发的,由 Guava 改进而来,底层设计思路、功能和使用方式与 Guava 非常类似,但是各方面的性能都要远远超过前者,可以看做是 Guava cache 的升级版。而且在 Spring5 开始的默认缓存实现就将 Caffeine 代替原来的 Google Guava,官方说明指出,其缓存命中率已经接近最优值@Data@Service@Autowired// 模拟数据库数据。

2024-09-21 18:15:12 5323 2

原创 SpringBoot 整合 Guava Cache 实现本地缓存

美团技术团队-缓存那些事是 Google 开发的 Guava 工具包中一套完善的JVM 本地缓存框架,底层实现的数据结构类似于,但是进行了更多的能力拓展,包括缓存过期时间设置、缓存容量设置、多种淘汰策略、缓存监控等。是一个支持高并发的线程安全的本地缓存。多线程情况下也可以安全的访问或者更新Cache。这些都是借鉴了支持最大容量限制支持两种过期删除策略(插入时间和读取时间)支持简单的统计功能基于 LRU 算法实现。

2024-09-07 23:11:32 2592 1

原创 SpringCloud Alibaba】(十三)学习 RocketMQ 消息队列

引入MQ最大的优点就是异步解耦和流量削峰,但是引入 MQ 后也有很多需要注意的事项和问题,主要包括:系统的整体可用性降低、系统的复杂度变高、引入了消息一致性的问题。重新打开 cmd 命令行,进入 RocketMQ 的 bin 目录,在命令行输入如下命令调用 RocketMQ 自带的消费者程序消费 RocketMQ 中的消息。下单成功后将订单的信息发送到 RocketMQ,然后用户微服务订阅 RocketMQ 的消息,接收到消息后进行打印。说明生产者发送到 RocketMQ 的消息,被消费者成功消费到了。

2024-09-01 20:42:08 1650 5

原创 【SpringCloud Alibaba】(十二)学习 Sleuth + ZipKin

Zipkin 是一种分布式链路跟踪系统,能够收集微服务运行过程中的实时调用链路信息,并能够将这些调用链路信息展示到 Web 界面上供开发人员分析,开发人员能够从 ZipKin 中分析出调用链路中的性能瓶颈,识别出存在问题的应用程序,进而定位问题和解决问题。

2024-09-01 12:44:26 1602

原创 【SpringCloud Alibaba】(十一)学习 Sleuth 链路追踪

随着互联网业务快速扩展,企业的业务系统变得越来越复杂,不少企业开始向分布式、微服务方向发展,将原本的单体应用拆分成分布式、微服务。这也使得当客户端请求系统的接口时,原本在同一个系统内部的请求逻辑变成了需要在多个微服务之间流转的请求。单体架构中可以使用 AOP 在调用具体的业务逻辑前后分别打印一下时间即可计算出整体的调用时间,使用 AOP 捕获异常也可知道是哪里的调用导致的异常。

2024-09-01 10:28:00 1324

原创 【SpringCloud Alibaba】(十)学习 Gateway 服务网关技术

Gateway 支持自定义断言功能,我们可以在具体业务中,基于 Gateway 自定义特定的断言功能Gateway 虽然提供了多种内置的断言功能,但是在某些场景下无法满足业务的需要,此时,我们就可以基于 Gateway 自定义断言功能,以此来满足我们的业务场景基于 Gateway 实现断言功能,实现后的效果是在服务网关的 ·application.yml·文件中的节点下的spring:cloud:gateway:routes: # 路由配置【数组】

2024-08-31 16:34:13 1262

原创 【SpringCloud Alibaba】(九)学习 Gateway 服务网关

当采用分布式、微服务的架构模式开发系统中,服务网关是整个系统中必不可少的一部分。Spring Cloud Gateway 是 Spring 公司基于 Spring 5.0, Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。

2024-08-25 20:44:02 1766 1

原创 【SpringCloud Alibaba】(八)学习 Sentinel 核心技术与配置规则(下)

在 Sentinel 中,指定发生异常时的处理策略非常简单,只需要使用注解即可。@Inherited//资源名称//entry类型,标记流量的方向,取值IN/OUT,默认是OUT//处理BlockException的函数名称,函数要求://1. 必须是 public//2.返回类型 参数与原方法一致//3. 默认需和原方法在同一个类中。若希望使用其他类的函数,可配置//blockHandlerClass ,并指定blockHandlerClass里面的方法。

2024-08-25 19:29:53 780

原创 十一:深入理解 Semaphore —— 信号量

不管线程 D 有没有进入阻塞队列【如果没有进入,那么此时,线程 D 和 线程 C 竞争许可证】,这里假设是线程 C 获取许可证成功,没有多余的许可证(propagate = 0),那么线程 D 就会进入到同步队列【此时,有可能阻塞(线程C.waitStatus = -1),也有可能没阻塞(线程C.waitStatus = 0)】:将当前线程封装为【共享模式】节点入同步队列,再自旋,如果当前节点前驱是 head 节点,再次获取许可证,如果返回结果 >= 0,则表示获取许可证成功,则调用。

2024-04-20 11:47:16 1121

原创 十:深入理解 CyclicBarrier—— 栅栏锁

让一组线程到达某个屏障,被阻塞,一直到组内的最后一个线程到达,然后屏障开放,接着,所有的线程继续运行是通过独占锁实现的,底层包含了 “ReentrantLock 对象 lock” 和 “Condition 对象 trip”,通过条件队列 trip 来对线程进行阻塞的,并且其内部维护了两个 int 型的变量 parties 和 count。

2024-04-18 17:05:22 632

原创 九:深入理解 CountDownLatch —— 闭锁/倒计时锁

通过构造方法初始化:设置 AQS 中的 state 的值调用方法:调用 AQS 的释放同步状态的方法,每调用一次,state 就自减 1,直至为 0调用await()方法:如果 state 不为 0,则阻塞线程并入队列。当 state 为 0 后,唤醒其它所有阻塞的线程。

2024-04-18 14:24:29 1222

原创 八:深入理解 Condition —— 线程通信(等待/通知)

当一个持有锁的线程调用将当前线程加入到条件等待队列中,状态为【CONDITION】彻底释放锁,并唤醒同步队列中阻塞的一个线程判断自己是否在同步等待队列中,如果不在,将自己阻塞起来如果被signal()方法唤醒了,则去竞争同步锁当一个持有锁的线程调用删除条件等待节点的头节点将头节点添加到同步等待队列的 tail 之后,如果添加成功,则退出循环;否则,如果条件等待队列中还有节点,则后移,循环步骤 1、2修改头结点的状态【CONDITION => 0】

2024-04-16 16:37:01 1168

原创 七:深入理解 ReentrantReadWriteLock —— 读写锁

`ReentrantReadWriteLock`:读写锁。它表示两个锁,一个是读操作相关的锁,称为共享锁;一个是写相关的锁,称为排他锁。适用于**读多写少**的场景(如果用独占锁,效率及其低下),提高并发性能,但也需要更多的内存和处理器时间来维护状态信息

2024-04-15 14:22:52 756

原创 六:深入理解 ReentrantLock —— 可重入锁

在文章中,我们介绍了 AQS 的基本原理。是我们比较常用的一种锁,也是基于 AQS 实现的。所以,接下来我们就来分析一下锁的实现。

2024-04-13 11:46:03 995

原创 五:深入理解 AbstractQueuedSynchronizer

抽象队列同步器,定义了一套多线程访问共享资源的同步器框架(同步:线程之间的通信、协作),许多同步类实现都依赖于它,如:Lock 包中的各种锁()、concurrent包中的各种同步器(如Semaphore),还有阻塞队列和线程池的实现都有使用到 AQS实现原理:在多线程访问共享资源时,若标识的共享资源【state】空闲,则将当前获取到共享资源的线程设置为有效工作线程,共享资源设置为锁定状态(独占模式下),其他线程没有获取到资源的线程进入阻塞队列【CLH】,等待当前线程释放资源后,继续尝试获取。

2024-04-12 11:54:10 945 1

原创 四:深入理解 volatile 关键字

volatile 变量,保证新值能立即同步回主内存,以及每次使用前立即从主内存刷新,所以我们说volatile保证了多线程操作变量的可见性

2024-04-11 15:57:04 714

原创 三:深入理解 synchronized 关键字

count = 0;_waiters = 0,//等待线程数//重入次数//持有锁的线程(逻辑上,实际上除了THREAD,还可能是Lock Record)//线程wait之后会进入该列表//等待获取锁的线程列表,和_EntryList配合使用//等待获取锁的线程列表,和_cxq配合使用//当前持有者是否为THREAD类型,如果是轻量级锁膨胀而来,还没有enter的话,//_owner存储的可能会是Lock Record当多个线程同时访问一段同步代码时,首先会进入。

2024-04-09 20:42:20 766

原创 二:深入理解 JAVA 内存模型 JMM

上述问题是因硬件的不断升级导致的。那么,有没有什么机制可以很好的解决上面的这些问题呢?——内存模型为了保证共享内存的正确性(可见性、有序性、原子性),内存模型定义了共享内存系统中多线程程序读写操作行为的规范。通过这些规则来规范对内存的读写操作,从而保证指令执行的正确性【与处理器/缓存/并发/编译器有关】。它解决了 CPU 多级缓存、处理器优化、指令重排等导致的内存访问问题,保证了并发场景下的一致性、原子性和有序性。限制处理器优化和使用内存屏障同一套内存模型规范,不同语言在实现上可能会有些差别。

2024-04-09 12:02:42 792

原创 【MYSQL】MYSQL 的学习教程(十三)之 MySQL的加锁规则

MySQL 分成了 Server 层和存储引擎两部分,每当执行一个查询时,Server 层负责生成执行计划,然后交给存储引擎去执行。弄懂了上面两个认识,会对后续大家理解有很大帮助。例如:对于进行分析的时候,为什么会出现说第一次加锁是精确查询?它明明是范围查询呀!这是因为第一次是要寻找到 id = 5 的记录,对于 Innodb 来说,它就是精确查找,不是范围查找。随后找到 id = 5 的记录之后,就要找 id > 5 的记录了,此时就变成了范围查找了。

2024-01-09 15:16:40 1475

原创 【MYSQL】MYSQL 的学习教程(十二)之 MySQL 啥时候用记录锁,啥时候用间隙锁

在「读未提交」和「读已提交」隔离级别下,都只会使用;而对于「可重复读」隔离级别来说,会使用那么 MySQL 啥时候会用记录锁,啥时候会用间隙锁,啥时候又会用 Next-Key 锁呢?

2024-01-08 16:48:12 1337

原创 【MYSQL】MYSQL 的学习教程(十一)之 MySQL 不同隔离级别,都使用了哪些锁

在「读未提交」隔离级别下,读写操作可以同时进行,但写写操作无法同时进行。与此同时,该隔离级别下只会使用行级别的记录锁,并不会用间隙锁在「读已提交」隔离级别下,只会使用行级别的记录锁,并不会用间隙锁。在「可重复读」隔离级别下,使用了记录锁、间隙锁、Next-Key 锁三种类型的锁可重复读存在幻读的问题,但实际上在 MySQL 中,因为其使用了间隙锁,所以在「可重复读」隔离级别下,可用加锁解决幻读问题。因此,MySQL 将「可重复读」作为了其默认的隔离级别。

2024-01-06 11:20:03 1403

原创 【MYSQL】MYSQL 的学习教程(十)之 InnoDB 锁

表锁:当存储引擎不支持行级锁时,使用表锁;SQL 语句没有匹配到索引时,使用表锁元数据锁:对表做增删改查时,会加上 MDL 读锁。对表结构做变更时,会加上 MDL 写锁意向锁:对表中的行记录加锁时,会用到意向锁行级锁:增删改查匹配到索引时,会使用行级锁。

2023-12-28 16:24:21 1410

原创 【MYSQL】MYSQL 的学习教程(九)之 23 个 SQL 优化小技巧

这篇文章从 15 个方面,分享了 sql 优化的一些小技巧,希望对你有所帮助。

2023-12-26 13:57:00 1003

原创 【MYSQL】MYSQL 的学习教程(八)之 索引失效场景

当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为**“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”**。一般有更新 SQL 才可能会导致脏页。

2023-12-25 18:04:29 3330 2

原创 【MYSQL】MYSQL 的学习教程(七)之 索引为什么要用 B+ 树

开启 profiling 参数后,后续执行的 SQL 语句都会记录其资源开销,包括 IO,上下文切换,CPU,内存等等,我们可以根据这些开销进一步分析当前慢 SQL 的瓶颈再进一步进行优化。profile 只能查看到 SQL 的执行耗时,但是无法看到 SQL 真正执行的过程信息,即不知道 MySQL 优化器是如何选择执行计划。定义,默认是 15。如果我们需要看单独某条 SQL 的分析,可以 show profile 查看最近一条 SQL 的分析,也可以使用。表示查询时能够使用到的索引(显示的是索引名称),

2023-12-25 18:03:32 1355

原创 【MYSQL】MYSQL 的学习教程(六)之 索引

Buffer Pool 是 MySQL 的一个非常重要的组件,因为针对数据库的增删改操作都是在 Buffer Pool 中完成的Undo log 记录的是数据操作前的样子redo log 记录的是数据被操作后的样子(redo log 是 Innodb 存储引擎特有)bin log 记录的是整个操作记录(这个对于主从复制具有非常重要的意义)首先执行器根据 MySQL 的执行计划来查询数据,先是从缓存池中查询数据,如果没有就会去数据库中查询,如果查询到了就将其放到缓存池中。

2023-12-22 17:34:07 1289

原创 【MYSQL】MYSQL 的学习教程(五)之 MYSQL 日志文件:undo、redo、bin log

阶数:一个节点最多有多少个孩子节点。(一般用字母m表示)关键字:节点上的数值就是关键字度:一个节点拥有的子节点的数量。B- 树(B树)是一种平衡的多叉树,它比较适用于对外查找一颗 m 阶的 B- 树,有以下特征:根结点至少有两个子女;每个非根节点所包含的关键字个数 j 满足:⌈m/2⌉ - 1

2023-12-22 10:39:55 1260

原创 【MYSQL】MYSQL 的学习教程(四)之 一条 SQL 语句的执行流程

当操作符左右两边的数据类型不一致时,会发生隐式转换当查询字段为数值类型时发生了隐式转换,那么对效率影响不大,但还是不推荐这么做当查询字段为字符类型时发生了隐式转换,那么会导致索引失效,造成全表扫描效率极低字符串转换为数值类型时,非数字开头的字符串会转化为 0,以数字开头的字符串会截取从第一个字符到第一个非数字内容为止的值为转化结果所以,我们在写 SQL 时一定要养成良好的习惯,查询的字段是什么类型,等号右边的条件就写成对应的类型。

2023-12-20 10:16:55 1694

原创 【MYSQL】MYSQL 的学习教程(三)之 InnoDB 结构

回表:当查询的数据在索引树中,找不到的时候,需要回到主键索引树中去获取,这个过程叫做回表需要查询所有列的数据,idx_age 普通索引不能满足,需要拿到主键 id 的值后,再回到id主键索引查找获取,这个过程就是回表如果我们查询 SQL 的select *修改为的话,其实是不需要回表的。因为 id 和 age 的值,都在idx_age 索引树的叶子节点上覆盖索引是 select 的数据列只用从索引中就能够取得,不必回表,换句话说,查询列要被所建的索引覆盖。所以,在日常开发中,尽量不要。

2023-12-19 11:51:05 1138

原创 【MYSQL】MYSQL 的学习教程(二) 之 InnoDB 数据页结构

在实际开发中,大部分的情况下都不是从单表中查询数据,一般都是多张表联合查询取出最终的结果。一个业务都会对应多张表,比如:学生和班级,起码两张表③:内连接和外连接的区别:假设 A 和 B 表进行连接。

2023-12-06 14:41:11 1368

原创 【MYSQL】MYSQL 的学习教程(一) 之 MYSQL 简介 & 架构 & 存储引擎

连接层为每个连接分配一个线程,该线程用来控制查询的执行。当连接通过用户名/密码的认证后,该连接可以发送 SQL 查询。连接层接受通过协议的应用程序连接。连接协议通过客户端的库及驱动实施,连接协议的速度因本地设置而异。上述协议中,MySQL 可以通过 TCP/IP 协议在网络间传送消息,其他的协议仅支持在本地使用(客户端和服务器必须在同一台主机上)TCP/IP协议除了用于网络间的远程连接,也可以用于本地连接。使用TCP/IP协议时需要使用IP地址或者DNS名称标识主机,并使用端口号标识服务。

2023-12-05 16:29:28 1020

原创 【Redis】Redis 的学习教程(十三)Redis 各场景

由于Redis 支持比较丰富的数据结构,因此他能实现的功能并不仅限于缓存,而是可以运用到各种业务场景中,开发出既简洁、又高效的系统

2023-12-05 15:22:29 408

原创 【Redis】Redis 的学习教程(十二)之在 Redis使用 lua 脚本

基于 Redis 的分布式锁。

2023-09-28 16:14:50 1504

原创 【Redis】Redis 的学习教程(十一)之使用 Redis 实现分布式锁

在多线程环境下,为了保证数据的线程安全,锁保证同一时刻,只有一个可以访问和更新共享数据。在单机系统我们可以使用 synchronized 锁、Lock 锁保证线程安全。synchronized 锁是 Java 提供的一种内置锁,在单个 JVM 进程中提供线程之间的锁定机制,控制多线程并发。只适用于单机环境下的并发控制。想要在多个节点中提供锁定,在分布式系统并发控制共享资源,确保同一时刻只有一个访问可以调用,避免多个调用者竞争调用和数据不一致问题,保证数据的一致性,就需要。

2023-09-21 16:54:13 796

原创 【Redis】Redis 的学习教程(十)之使用 Redis 实现消息队列

消息队列需要满足的要求:Redis 提供了三种不同的方式来实现消息队列:因为 list 底层的实现就是一个「链表」,在头部和尾部操作元素,时间复杂度都是 O(1),这意味着它非常符合消息队列的模型如果你的业务需求足够简单,想把 Redis 当作队列来使用,肯定最先想到的就是使用 list 这个数据类型常用的命令:生产者:消费者:这个模型非常简单,如下图:当队列中已经没有消息了,消费者在执行 RPOP 时,会返回 NULL我们在编写消费者逻辑时,一般是一个「死循环」,这个逻辑需要不断地从队列中拉取消息进行处理

2023-09-18 16:00:07 7180 3

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除