- 博客(40)
- 收藏
- 关注
原创 【问题定位】Caffeine导致的生产频繁FGC
会不会是没有驱逐,不太可能,因为这个老年代占用4个小时才上升1.5%,如果不驱逐,按当前这个数据量内存早爆了。后面大概看了下源码,实际是对Caffeine的每次put/get操作都会去尝试驱逐,也就是官网上说的“如果你的缓存吞吐量较高,那么你不用去担心你的缓存的过期维护问题”后面找到篇文章,可以说简直一模一样,就是驱逐的效率赶不上load的速度,expireAfterWrite的时间窗口是2分钟,我算了下2分钟可能已经进去2w条消息,这2w条还不会立即被驱逐;这个最低水位会一直上升,直到发生OOM。
2025-01-15 18:25:46
279
原创 【FutureTask】FutureTask原理
Future<?});Future 位于 java.util.concurrent 包下,是异步任务的顶层接口。
2024-09-27 14:31:57
647
原创 【线程池】Tomcat线程池
最近看到篇关于 Tomcat 线程池的博客,因为之前只看过 JDK 线程池,记录一下。在微服务横行的今天,确实还是有必要研究研究 Tomcat 的线程池Tomcat 线程池和 JDK 线程池最大的不同就是它先把最大线程数用完,然后再提交任务到队列里面。深入理解线程池(ThreadPoolExecutor)——细致入微的讲源码。workerstarted = true-优快云博客本文主要介绍了 Tomcat 线程池的运行流程,和 JDK 线程池的流程比起来,它确实不一样。
2024-09-22 17:14:06
1344
原创 【源码阅读】Redisson lock源码
Redisson 加锁非常简单,还支持 redis 单实例、redis 哨兵、redis cluster、redis master-slave 等各种部署架构底层原理废话不多说,直接看源码,下面的代码先不看,先看 tryAcquire 是如何获取锁的查看 tryAcquire 方法,点进去看发现调用了 tryAcquireAsync0 方法,这里 RFuture 继承自 java.util.concurrent.Future,表示这是一个异步的任务,get 方法会同步获取结果查看 tr
2024-07-30 23:59:24
952
原创 【问题记录】xxl-job admin端锁超时问题
这条 SQL 是查当前事务,能查出两条记录,一条是 LOCK_WAITS 状态的 SELECT * FROM xxl_job_lock WHERE lock_name = 'schedule_lock' FOR UPDATE;另一条是 RUNNING 状态的长事务,从 2 个小时前开始。发现获取锁超时时间确实是 50 秒,也就是说这个周期任务每次都会卡在获取行锁阻塞超时,接下来查看是什么阻塞了每次获取锁的事务。等到想查这条长事务具体的 SQL 时,却发现那条长事务已经提交或回滚了,程序又恢复正常了,晕。
2024-07-11 16:48:06
887
原创 【分布式事务】Seata AT实战
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案对业务无侵入:即减少技术架构上的微服务化所带来的分布式事务问题对业务的侵入高性能:减少分布式事务解决方案所带来的性能消耗。
2024-06-24 18:24:32
928
原创 【分布式事务】分布式事务理论
对于多数大型互联网应用的场景,节点众多、部署分散,由于现在的集群规模越来越大,所以节点故障、网络故障是常态,而且要保证服务可用性达到 N 个 9(99.99..%),并要达到良好的响应性能来提高用户体验,因此一般都会做出如下选择:保证 P 和 A,舍弃 C 强一致,保证最终一致性。比如电商系统中提交订单,订单微服务请求库存微服务扣减库存,请求会员微服务增加积分,在分布式系统中经常发生网络异常、机器宕机导致请求失败,如果库存服务扣减库存成功后宕机了,订单服务就会回滚,造成数据的不一致。
2024-06-24 16:03:23
844
原创 【ElasticSearch】ElasticSearch实战
"hasStock": { "type": "boolean" }, # 只存是否有库存,不存库存量。"catalogName": {"type": "keyword" }, # 视频里有false。"skuImg" : { "type": "keyword" }, # 视频中有false。"brandName": {"type": "keyword"}, # 视频中有false。"skuPrice": { "type": "keyword" }, # 保证精度问题。
2024-06-20 15:46:26
1092
原创 【ElasticSearch】ElasticSearch基本概念
ES 是一个开源的高扩展的分布式全文检索引擎,它是对开源库 Luence 的封装,提供 REST API 接口MySQL 更适合数据的存储和关系管理,即 CRUD;而 ES 更适合做海量数据的检索和分析,它可以秒级地从数据库中检索出我们感兴趣的数据。
2024-06-13 22:56:14
1201
1
原创 【数据结构与算法】回溯解决组合问题
回溯法也可以叫做回溯搜索法,它是一种搜索的方式,回溯的本质就是穷举,然后选出我们想要的答案。如果题目不要求时间复杂度,回溯无疑就是最容易想到的暴力解法都可以被转化为来解决,但是毫无疑问会时间超时,但是这不影响我们把它作为突破口,因为回溯只要你能够理解题意,写出正确的递归条件和跳出条件,那么一切都好解决了。
2024-06-12 23:25:24
568
原创 【数据结构与算法】BSF计算无向图最短路径
不行,因为向下和向右移动,对应着 +10 和 +1,题中的改变一个转轮的关系,可能是 +/- 100,+/- 1000,甚至是从 0 到 9999。1、每次从队列中取出这一层的所有元素,这一层的所有元素,其实就是每次判断队列非空的时候,队列中的所有元素。因为我们想要表示这些字符串之间的关系,并且这又是个搜索问题,由此可以想到构造一个无向图,每个节点表示一个字符串,相邻的节点表示其中一个字符修改后的字符串,这样该问题就转变成了无向图计算最短路径问题,自然而然会想到 BSF。
2024-06-11 17:26:02
404
原创 【问题记录】Spring FactoryBean + JDK动态代理实现网关代理
这套思路,个人感觉还是比较直观的,没有绕什么弯子。但是这里遗留了一个问题,如果我想通过 Spring Boot 自动装配直接把动态代理类注入到业务模块,应该怎么做?我的一个想法是通过 SPI 机制,但是这样会引入模块间循环依赖的问题。
2024-05-05 17:52:43
555
4
原创 【问题记录】分布式锁实现问题小记
业务场景:消费端轮询服务端接口,服务端发现任务完成,则触发事件。首先这是有一定并发量的场景,为了避免并发场景下,服务端重复触发事件,在触发事件之前必须加分布式锁。我是这样设计的:本次请求先查询事件是否已经触发,如果已经触发,那么解锁;否则尝试加分布式锁,如果获取锁成功,触发事件,如果获取锁失败,直接返回问题产生了,我发现分布式锁没有互斥性,上一个请求获取锁成功,没等到有请求来解锁,下一个请求居然又能成功获取锁。
2024-03-26 19:54:53
655
原创 Spring的事务框架
Spring的事务框架设计理念的基本原则是:让事务管理的关注点与数据访问关注点相分离PlatformTransactionManager是Spring事务抽象架构的核心接口,它的主要作用是为应用程序提供事务界定的统一方式具体实现上,在事务开始之前取得一个java.sql.Connection,然后将这个Connection绑定到当前的调用线程,在事务结束时解除绑定。
2024-03-19 16:11:06
354
原创 SpringBoot约定大于配置
"约定大于配置"(Convention Over Configuration)是一种理念,旨在通过默认约定和规则来减少开发人员需要做的配置工作。在Spring Boot框架中,这一原则得到了充分应用,帮助开发者更快地构建高效的应用程序。
2024-03-02 18:18:38
2639
原创 开发环境热部署
在实际开发中,经常要修改代码,然后重启服务,再验证代码是否生效。对于开发场景,随着项目的演进,微服务越来越多,等待重启的时间也会越来越多;对于联调场景,对一处功能的修改后通知上游联调,同样会浪费大量的碎片化时间。热部署的出现就帮我们解决了这些痛点,所谓热部署,就是在应用正在运行时升级软件,却不需要重新启动应用,它能极大的提高开发效率。
2024-02-29 11:39:00
1635
原创 恢复IDEA的myabtis、sql代码提示
在mapper页面空白行或者根路径,快捷键,选择,选择sql然后打开,把Scope排倒序,发现我们新建了一个Scope为IDE的设置修改Local name为修改Namespace为。
2024-02-26 20:27:46
412
原创 Redis客户端异常:No way to dispatch this command to Redis Cluster because keys have different slots.
项目使用jedis,执行lua脚本报错:No way to dispatch this command to Redis Cluster because keys have different slots.jedis版本如下查了下报错原因,是,于是切lettucelettuce版本如下切完还是报错:io.lettuce.core.RedisCommandExecutionException: CROSSSLOT Keys in request don't hash to the same slot。
2024-02-20 15:39:12
1390
原创 深入理解Java虚拟机_JVM高级特性与最佳实践(第3版)学习笔记
Java虚拟机栈是线程私有的,它的生命周期与线程相同虚拟机栈描述的是Java方法执行的线程内存模型局部变量表所需的内存空间在编译期间完成分配。
2024-01-19 17:59:43
541
原创 二分查找(Binary Search)
对数据大小为n的数组进行二分查找,每次需要遍历的区间为n,n/2,n/4,...,n/2^k经过k次比较后,二分查找完成,时间复杂度为O(k)。因为n/2^k=1,k=logn,故时间复杂度O(logn)
2024-01-02 16:39:49
383
1
原创 %p返回的地址
可以看到返回的char类型的数据在内存中占用1字节,我声明了一个char类型的指针,%p输出了他的地址,做+1后会指向下一字节,再次输出地址发现地址也+1了,这意味着返回的16位16进制数的每一个单位代表一个字节。64位机器的内存理论值是2的64次方字节,表示2的64次方需要64位2进制数,换算成16进制,每4位2进制数是1位16进制数,因此需要16位16进制。%p返回的这16位16进制数指向内存中的一个位置,这个位置可以存储1个字节,如果地址+1,那么这个地址就会指向下一字节。
2023-12-29 15:14:01
438
1
原创 C语言指针
定义二维数组指针*p表示p是一个指针,它指向一个数组,数组类型为int[3],这正是arr包含的每个一维数组类型,即每行。这里括号是必须的,否则p会变成一个指针数组二维数组指针遍历i < 2;这里括号是必须的,如果写作就成了函数原型,它表示函数的返回值为使用函数指针a : b;return 0;p是一个函数指针,在前面加 * 就表示对它指向的函数进行调用,这里括号同样不能省略。
2023-12-25 17:02:20
1624
原创 C语言宏定义
而 typedef 是在编译阶段由编译器处理的,它并不是简单的字符串替换,而给原有的数据类型起一个新的名字,将它作为一种新的数据类型。#define 叫做宏定义命令,它也是C语言预处理命令的一种。所谓宏定义,就是用一个标识符来表示一个字符串,如果在后面的代码中出现了该标识符,那么就全部替换成指定的字符串。#表示这是一条预处理命令,所有的预处理命令都以 # 开头。在x86机器上int指针的类型变量占8字节,int类型的变量占4字节。由此可见b变量是int类型,宏定义只是简单的字符串替换,使用时要格外小心。
2023-12-25 09:50:15
382
原创 预处理命令
C语言源文件要经过编译、链接才能生成可执行程序编译(Compile):将源文件(.c文件)转换成目标文件(.o,.obj等)链接(Link):将编译生成的多个目标文件及系统中的库、组件等合并成一个可执行程序在编译之前对源文件进行简单加工的过程,就称为预处理,即预先处理、提前处理。
2023-12-20 12:37:07
370
1
原创 Java的跨平台性
以socket编程为例,java.net.ServerSocket#accept这个方法因为要调用底层操作系统的接口,一定是平台相关的,如果使用windows版本的jdk,底层实现将是。也就是说,java借助对底层实现的封装和双亲委派的原则,屏蔽了平台相关性的细节,使得java程序只需生成在jvm上运行的目标代码(字节码),就可以在不同平台上不加修改地运行。而使用linux版本的jdk,底层实现又会是另一种。简单的说,“一次编译,到处运行”:java文件经过编译后生成和平台无关的class文件。
2023-12-19 11:06:37
398
1
原创 spring-session-data-redis原理
session是服务器端的一个 key-value 的数据结构,经常和 Cookie 配合,保持用户的登陆会话。客户端在第一次访问服务端的时候,服务端会响应一个 SessionId 并且将它存入到本地 Cookie 中,在之后的访问中浏览器会将 Cookie 中的 sessionId 放入到请求头中去访问服务器,如果通过这个 SessionId 没有找到对应的数据,那么服务器会创建一个新的SessionId并且响应给客户端。
2023-12-15 09:13:21
640
原创 mysql事务
而每行数据也有多个版本,每次事务更新数据的时候,都会生成一个新的数据版本,并且把当前事务的id赋给这个数据版本,记为row trx_id。在实现上,InnoDB为每个事务构造了一个数组,用来保存每个事务的启动瞬间,所有“活跃”的事务id,活跃是指启动了但未提交。1.最常说的视图view,由一个查询语句定义的虚拟表,在调用的时候执行查询语句并生成结果,查询方法和表一样。按照RR的定义,一个事务启动的时候,能看到当前所有已提交的事务,但是之后其他事务的更新对它不可见。该数组中事务id的最小值记为。
2023-06-08 19:44:02
37
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人