- 博客(172)
- 收藏
- 关注
原创 线程池调优关键指标与策略
示例:目标QPS=1000,平均处理时间50ms,阻塞占比60% → 核心线程数=1000×0.05/(1-0.6)=125。需求:峰值QPS=5000,平均处理时间20ms,任务不可丢失,CPU核心数=32。队列容量 = 峰值QPS × 容忍时间 = 5000 × 1s = 5000。调整:若任务含大对象(如图片),需缩小队列容量或优化任务内存。核心线程数:基于QPS和处理时间计算,结合CPU核心数调整。拒绝策略:任务不可降级时,需持久化或阻塞等待,但需权衡风险。
2025-04-03 17:14:48
293
原创 线程池调优
若线程数已达上限 → 改用SynchronousQueue(无缓冲队列,强制快速扩容)。增大线程数(如使用线程数 = CPU核心数 × (1 + 平均阻塞时间比例))。核心线程数(corePoolSize)与最大线程数(maxPoolSize)。活跃线程数(activeCount):正在执行任务的线程数量。拒绝任务数(rejectedCount):被拒绝的任务数量。优化:逐步增加核心线程数(如从20→25),观察性能变化。拒绝策略兜底:始终配置合理的拒绝策略(如降级、日志记录)。
2025-04-03 12:50:24
475
原创 基于 Prometheus + Grafana 的数据库慢查询与死锁排查指南
一、监控体系搭建数据库指标采集:MySQL:使用 mysqld_exporter 暴露指标,配置项包括:yaml复制复制yaml复制二、慢查询排查复制sql复制执行计划分析:sql复制三、死锁排查yaml复制。
2025-03-30 23:12:09
298
原创 数据库 CPU 飙高的可能原因及排查指标
大量复杂查询:执行高计算量的 SQL(如聚合、排序、多表 JOIN)。索引缺失或失效:全表扫描导致 CPU 负载升高。锁竞争:行锁、表锁或死锁导致线程阻塞,CPU 空转。配置不当:innodb_buffer_pool_size 过小,频繁磁盘 I/O。并发请求过高:超出数据库处理能力,线程堆积。2. 排查指标与工具阈值(秒)bash复制。
2025-03-30 21:55:14
219
原创 rabbitmq消息积压的线程池调优
这个方案在保证500 QPS稳定处理的同时,提供了良好的可扩展性,当流量增长时可以通过增加消费者线程快速应对。在您的500 QPS场景下,即使是单线程也完全能处理,但使用多线程可以提供更好的弹性。小消息(1KB) 3,000-5,000 10,000-50,000。中消息(10KB) 1,000-2,000 5,000-15,000。大消息(100KB+) 100-500 500-3,000。数据库压力 高(500事务/秒) 中等(25批量/秒)消息大小:通常小消息(1KB以下)吞吐量更高。
2025-03-30 21:13:24
289
原创 Prometheus
若你不想以服务方式启动,也可以手动启动 Prometheus。启动之后,你可以通过浏览器访问 http://localhost:9090 来验证 Prometheus 是否成功启动。若能看到 Prometheus 的 Web 界面,就说明启动成功。执行该命令后,Prometheus 会以前台进程的形式启动,你可以在终端看到详细的日志输出。此命令会将 Prometheus 作为后台服务启动,并且在系统启动时自动运行。若安装成功,会显示出 Prometheus 相关的文件和目录。3. 手动启动(非服务方式)
2025-03-27 00:06:32
312
原创 kafka存储机制
消息读取:消费者从 Kafka 集群拉取消息时,根据指定的主题、分区和偏移量,先从偏移量索引文件中查找消息在数据文件中的位置,然后从数据文件中读取消息内容。它采用稀疏索引的方式,每隔一定数量的消息才会在索引文件中记录一条索引项,通过这种方式可以快速定位到消息在数据文件中的大致位置,然后再进行顺序查找,提高消息的读取效率。然后,消息会被追加到该分区的当前日志段的数据文件中。它可以根据时间戳快速定位到某个时间范围内的消息偏移量,进而通过偏移量索引找到消息在数据文件中的位置,方便按照时间进行消息的查询和消费。
2025-03-26 10:57:27
356
原创 shardingsphere动态添加数据源
ShardingSphere 是一个开源的分布式数据库中间件,支持在运行时动态添加数据源。上述代码展示了如何在运行时动态添加数据源。首先创建新的数据源配置,然后将其添加到现有的配置中,接着更新规则配置,最后重新初始化数据源。实际使用时,要依据具体的业务需求和 ShardingSphere 版本对代码进行调整。按照以上步骤操作,你就能在 ShardingSphere 里动态添加数据库了。ShardingSphere 动态添加数据库的 Java 代码。
2025-03-26 10:54:15
227
原创 orderby重复字段查询
例如,在商品列表页面,用户可以选择按照价格、销量、评价等不同字段进行排序,这样用户可以根据自己的偏好和当前的需求来定制数据的展示顺序,提高用户体验。例如,在电商订单处理系统中,订单可能有不同的状态,如待付款、待发货、已发货、已完成等,按照订单状态的流转顺序进行排序,有助于工作人员清晰地了解订单的处理进度。例如,在新闻资讯类应用中,通常会按照新闻的发布时间来排序,使最新的新闻排在前面,方便用户及时获取最新信息。在这个查询里,首先会按照 score 排序,当 score 相同时,会按照 name 进行排序。
2025-03-25 11:51:22
874
原创 分库分表确定分片数量
在设计 3000万数据的分库分表方案 时,需综合考虑 数据增长趋势、查询模式、硬件资源、业务容忍度 等因素。以下是分库分表的具体方案及核心逻辑分析:一、分库分表的核心原则原则 说明单表容量控制 单表建议不超过1000万行(B+树深度3~4层,查询效率较高)分片键均匀性 避免数据倾斜(如用户ID哈希分片优于按时间范围分片)扩展性预留 设计时预留2~3倍容量,避免频繁扩容跨分片查询最小化 减少跨库/跨表JOIN,优先通过分片键定位数据二、3000万数据的分库分表示例。
2025-03-25 10:57:46
344
原创 JVM起延迟任务
ScheduledExecutorService 是 Java 提供的一个更强大的定时任务执行器,支持多线程执行任务。DelayQueue 是 Java 提供的一个基于优先级队列的延迟任务队列,可用于实现延迟任务。优点:提供了丰富的任务调度和管理功能,支持分布式环境,可实现复杂的任务调度策略。缺点:Timer 是单线程的,如果一个任务执行时间过长,会影响其他任务的执行。Timer 是 Java 提供的一个简单的定时任务工具,可用于执行延迟任务。消息队列支持消息的延迟发送功能,可用于实现分布式延迟任务。
2025-03-24 12:13:18
346
原创 线上服务出问题解决JAVA
建立监控与预警机制:完善对该服务和节点的监控体系,设置合理的监控指标和预警阈值,如服务响应时间、错误率、资源使用率等,以便在问题再次出现时能够及时发现并预警,同时定期对服务的运行数据进行分析,提前发现潜在问题并进行优化。更新或回滚配置与代码:若问题是由最近的配置更改或代码更新引起的,可尝试将配置回滚到之前的正常状态,或者回滚代码版本,以确定是否是新的配置或代码引入了问题。全面测试验证:问题解决后,在测试环境和预发布环境进行充分的测试,确保服务功能正常,性能指标符合要求,且没有引入新的问题。
2025-03-24 10:38:15
325
原创 线上接口响应变慢JAVA
数据库配置优化:调整数据库的配置参数,如内存分配、缓存大小、并发连接数等,以提高数据库的性能。例如,对于频繁调用的外部服务,可以适当降低调用频率,或者设置重试次数和超时时间,以避免长时间等待。异步处理:对于一些耗时的操作,如文件上传、数据处理等,可以采用异步处理的方式,避免阻塞主线程。代码审查:对接口相关的代码进行审查,检查是否存在死循环、复杂的嵌套查询、不合理的算法等问题。SQL 优化:对慢查询的 SQL 语句进行优化,如调整查询语句的结构、添加索引、避免子查询等。
2025-03-24 10:30:34
357
原创 java巡检平台
通过定期的安全审计,及时发现并修复安全漏洞,保障应用的安全性。日志收集与存储:收集 Java 应用产生的各类日志,包括系统日志、业务日志和错误日志等,并将其存储在集中的日志管理系统中,如 Elasticsearch、Logstash 和 Kibana(ELK 栈)。报告生成与展示:巡检完成后,生成详细的巡检报告,以直观的图表和报表形式展示应用的健康状况、性能指标和存在的问题。自动化巡检任务:可以设置定期的自动化巡检任务,按照预设的规则和指标对 Java 应用进行全面检查,减少人工巡检的工作量和人为误差。
2025-03-20 18:35:03
291
原创 java编译
综上所述,这条命令的作用是:使用 JVM 运行 com.example.HeapOOM 类,设置 JVM 堆内存的初始大小和最大大小均为 10 兆字节,当程序发生内存溢出错误时,在当前目录下生成堆转储文件。当你遇到 “错误:找不到或无法加载主类 HeapOOM” 这个问题,通常是由类路径、类未编译、包名、大小写等方面的问题导致的,下面为你详细分析并给出对应的解决办法。java:这是运行 Java 程序的命令,用于启动 Java 虚拟机(JVM)来执行指定的 Java 类。
2025-03-20 18:22:05
626
原创 jstat的jvm说明
gc:显示与垃圾回收相关的堆信息,包括各个区域(新生代、老年代、永久代 / 元空间)的使用情况、垃圾回收次数和时间等。S0U、S1U:Survivor 0、Survivor 1 区的使用量(KB)。S0C、S1C:Survivor 0、Survivor 1 区的容量(KB)。S0C、S1C:Survivor 0、Survivor 1 区的容量(KB)。MCMN、MCMX:方法区(永久代 / 元空间)最小、最大容量(KB)。MC:方法区(永久代 / 元空间)的容量(KB)。
2025-03-19 23:39:49
422
原创 redis数据类型结构
元素较多或长度较长时,采用skiplist和hashtable组合编码,skiplist用于按分数排序,hashtable用于快速查找元素。应用场景:常用于统计网站的 UV(独立访客)、用户行为数据中的唯一元素数量等场景,在不需要精确计数的情况下,能大大节省内存和计算资源。应用场景:在地图应用、物流配送、基于位置的服务(LBS)等领域有广泛应用,可帮助用户快速获取与地理位置相关的信息和进行空间计算。描述:一个有序的字符串列表,元素可重复,通过索引访问元素,支持在列表两端进行插入和删除操作。
2025-03-17 14:53:24
258
原创 子账簿使用布隆过滤器
在一个大型金融系统里,存在大量的子账簿。在批量查询子账簿信息时,可能会包含一些不存在的子账簿 ID。在查询数据库之前,使用布隆过滤器对这些 ID 进行过滤,将不存在的 ID 提前排除,避免不必要的数据库查询操作。batchQuerySubLedgers 方法对批量查询的子账簿 ID 进行过滤,将布隆过滤器判断不存在的 ID 排除,然后对有效的 ID 进行查询。在子账簿系统中,布隆过滤器可以在多个场景发挥重要作用,下面以判断子账簿是否存在以及批量查询子账簿时过滤无效查询为例进行说明,并给出示例代码。
2025-03-17 14:44:53
312
原创 子账簿redis应用
在 Redis 中可以存储子账簿的各类信息,也能够存储子账簿的交易明细。可以采用 Redis 的列表(List)或哈希(Hash)数据结构来存储子账簿的交易明细。数据一致性:在高并发场景下,要确保数据的一致性,可使用 Redis 的事务或分布式锁。所属主账户 ID:明确子账簿所属的主账户,便于进行账户的层级管理。账户状态:如 “正常”“冻结”“注销” 等,控制子账簿的使用权限。子账簿 ID:作为子账簿的唯一标识,用于区分不同的子账簿。创建时间:记录子账簿的创建时刻,可用于数据统计和审计。
2025-03-17 14:33:22
318
原创 springboot如何排查死锁问题
在 Spring Boot 应用程序中排查死锁问题可以从多个角度入手,以下是具体的排查方法:利用日志信息启用 Spring Boot 日志:确保在 application.properties 或 application.yml 中配置了合适的日志级别,例如将日志级别设置为 DEBUG 可以获取更详细的执行信息。propertiesjava@Service使用 JDK 自带工具jstack。
2025-03-11 19:00:36
801
原创 @TRANSACTIONAL使用readonly时update
为了避免在只读事务中执行更新操作带来的问题,建议在编写代码时仔细区分只读操作和更新操作,并使用正确的事务配置。当在 @Transactional 注解中使用 readonly = true 声明一个只读事务,却在该事务内执行更新操作时,会产生不同的结果,这取决于具体使用的数据库和事务管理器的实现。当该方法被调用时,Spring 的事务管理器可能会抛出异常,提示在只读事务中进行了更新操作。在许多情况下,事务管理器会检测到在只读事务中进行了更新操作,并抛出异常。可能会忽略更新操作,也可能会报错。
2025-03-11 18:56:03
309
原创 transactional哪些异常不会回滚
在使用 @Transactional 注解进行事务管理时,默认情况下只有 RuntimeException 及其子类(包括 Error)引发的异常才会触发事务回滚,而受检查异常(Checked Exception)通常不会导致事务回滚。如果你希望特定的受检查异常也能触发事务回滚,可以通过 @Transactional 注解的 rollbackFor 属性来指定需要回滚的异常类型。在这个例子中,MyCheckedException 是一个自定义的受检查异常,方法抛出该异常时,事务不会回滚。
2025-03-11 18:53:09
355
原创 为啥navicat连不上mysql
检查日志文件:查看 MySQL 的错误日志文件(通常位于 /usr/local/var/mysql/*.err),查找有关数据库损坏或异常的信息。其中,root 是 MySQL 的用户名,执行该命令后,会提示你输入该用户的密码,输入正确密码并回车,即可进入 MySQL 命令行环境。原因:若 MySQL 的可执行文件路径未正确添加到系统的环境变量中,可能会导致在终端无法直接调用 MySQL 命令。原因:若 MySQL 服务未正常启动,你将无法连接到数据库服务器,自然也就无法执行 MySQL 指令。
2025-03-09 16:30:06
248
原创 线程池submit和execute区别
任务执行过程中抛出的异常会被封装在 Future 对象中,当调用 Future 的 get 方法时才会以 ExecutionException 的形式抛出,异常的实际原因可以通过 getCause 方法获取。submit 方法:适用于需要获取任务执行结果的场景,或者需要对任务进行取消、检查任务是否完成等操作的场景,例如一些需要进行复杂计算并返回结果的任务。execute 方法:适用于提交不需要返回结果的任务,例如一些简单的日志记录、数据清理等后台任务,这些任务的执行结果不需要反馈给调用者。
2025-03-01 21:58:22
323
原创 Spring发布监听
综上所述,ApplicationListener 通过 ApplicationContext 发布事件,通常不需要手动关闭,Spring 会在应用上下文关闭时自动处理,JVM 关闭时也会触发相应的清理机制。Spring 框架会管理监听器的生命周期,当 Spring 应用上下文关闭时,监听器也会随之停止工作。首先,你需要定义一个继承自 ApplicationEvent 的事件类,该类用于表示你要发布的事件。在需要发布事件的地方,通过 ApplicationContext 来发布事件。步骤 4:调用发布方法。
2025-03-01 16:39:32
232
原创 MySQL 的可重复读(REPEATABLE READ)唯一索引和普通索引加锁
当使用普通索引进行等值查询时,数据库不仅会对查询到的 id = 3 这一行记录加行锁,还会对该记录前面的间隙加间隙锁。在有记录 id 为 1、3、5 的情况下,id = 3 前面的间隙是 (1, 3),所以最终的加锁范围是 (1, 3]。为了保证事务的一致性,防止其他事务对该行数据进行写操作,数据库只会对这一行加锁,而不会对其他行或间隙加锁。FOR UPDATE WHERE id = 3 的加锁范围根据 id 列的索引类型不同而不同。– 此操作会被阻塞,直到会话 1 的事务结束。2. id 列是普通索引。
2025-02-22 22:59:57
254
原创 MySQL 的可重复读(REPEATABLE READ)临键锁机制
临键锁机制:在可重复读隔离级别下,使用普通索引进行等值查询且记录存在时,MySQL 采用临键锁机制,其目的是在保证数据一致性和避免幻读的同时,尽量减少锁的范围,以提高并发性能。对于 id = 5 的查询,会对 id = 5 这一行加行锁,同时对 (3, 5) 这个间隙加间隙锁,所以加锁范围是 (3, 5]。当执行 SELECT …repeatable read,假设是有索引,假设有记录1,3,5,select for update where id =5,为啥不锁(5,+∞),此时插入id=6。
2025-02-22 22:51:33
410
原创 spring回调解决文件和数据库@transactional事务不一致
通过 TransactionSynchronizationManager.registerSynchronization 方法注册事务同步器,在 afterCommit 方法中调用 onCommit 方法,在 afterCompletion 方法中判断事务状态,如果是回滚状态则调用 onRollback 方法。在事务方法中注册回调:在 @Transactional 注解的方法里,将磁盘操作封装成回调对象,并注册到事务中。定义回调接口:创建一个回调接口,包含事务提交和回滚时需要执行的方法。
2025-02-21 11:35:03
644
原创 100万个数选1万个随机数
生成 0~99,999 的索引列表,通过 部分洗牌算法(Fisher-Yates) 随机选取 1 万个索引。内存占用较高:需存储全部索引列表(约 400KB,100,000 个 int)。高性能需求场景(如服务端高频调用):选择 预生成随机索引(部分洗牌)。时间复杂度 O(k)~O(k log n)(依赖随机碰撞) O(k)空间复杂度 O(n/8)(约12.5KB) O(n)(约400KB)内存敏感场景(如嵌入式系统):选择 位图(BitMap)。特性 位图(BitMap) 预生成随机索引(部分洗牌)
2025-02-21 11:07:58
161
原创 MyBatis 拦截器实现批量数据分片插入
以下是使用 MyBatis 拦截器实现批量数据分片插入的完整方案,通过拦截 Executor#update 方法,将集合参数拆分成多个批次执行,避免一次性插入大量数据导致的性能问题。事务一致性:所有批次需在同一个事务中执行(推荐使用 Spring 的 @Transactional)。参数分片:若参数是集合类型,按指定批次大小(如 100 条)拆分。分批执行:循环执行每个小批次的插入操作,保持事务一致性。自动分片:无需修改业务代码,拦截器自动拆分集合参数。事务安全:所有批次在同一事务中执行,保障数据一致性。
2025-02-17 11:16:24
391
原创 EasyExcel + 消息队列(MQ) + 多线程
要实现基于 EasyExcel + 消息队列(MQ) + 多线程 的高效、平滑的 Excel 数据导入功能,核心目标是解决大文件导入时的 性能瓶颈 和 系统资源瞬时压力过大 问题。MQ 限流:通过 MQ 的 QoS(如 RabbitMQ 的 prefetchCount)控制消费者拉取速率。异步解耦:通过消息队列(MQ)将数据读取与数据处理解耦,平滑流量洪峰。流量控制:通过 MQ 的消费速率和线程池的并发数,实现分钟级平滑导入。多线程消费:消费者从 MQ 中拉取数据分片,通过线程池并发处理。
2025-02-17 09:52:42
366
原创 线程池核心线程数为0
若没有(此时线程数为0),则会创建一个非核心线程(受maximumPoolSize限制)。当第一个任务到达时,线程池检查当前运行的线程数(初始为0)。若当前线程数小于maximumPoolSize(10),线程池会按需创建新的非核心线程处理队列中的任务。非核心线程:所有创建的线程均为非核心线程(因corePoolSize=0)。若线程数已达最大值(10),则所有新任务继续在队列中等待,直到有空闲线程。创建条件:任务进入队列后,若无线程活跃,则触发创建非核心线程。线程类型:所有线程均为非核心线程。
2025-02-16 20:47:16
183
原创 Redisson和Redis+Lua解决超卖问题比较
Redisson 是 Redis 的 Java 客户端,提供分布式锁、原子操作、信号量等高级功能,通过封装 Redis 命令简化分布式场景下的并发控制。用 Lua 脚本处理核心扣减逻辑,用 Redisson 管理分布式锁控制外围流程(如订单创建)。通过编写 Lua 脚本在 Redis 服务端原子化执行库存扣减逻辑,避免客户端并发问题。超卖问题的本质是保证操作的原子性,两种方案均可实现,但需根据业务需求和团队能力权衡选择。Redis + Lua 适合高性能、高定制化场景,通过服务端原子操作避免竞争。
2025-02-16 17:13:32
376
原创 Mybatis和SpringMVC拦截器区别
在 Spring Boot 中,PaginationInterceptor 是 MyBatis-Plus 的分页插件拦截器,用于自动处理分页逻辑。它的配置方式与 Spring MVC 的 HandlerInterceptor(处理 HTTP 请求的拦截器)不同,需通过 MyBatis 的插件机制 注册,而非添加到 Web 配置中。与 Spring MVC 拦截器的区别:MyBatis 插件作用于 SQL 执行过程,而 HandlerInterceptor 作用于 HTTP 请求生命周期。
2025-02-16 17:11:06
535
原创 Mybatis拦截器
在 MyBatis 中,自定义拦截器(Interceptor)通过实现 org.apache.ibatis.plugin.Interceptor 接口并正确配置后,可以拦截 MyBatis 的核心组件(如 Executor、StatementHandler 等)的方法。实现要点:正确实现 intercept()、plugin() 和 setProperties() 方法,并通过 @Intercepts 注解指定拦截目标。执行顺序:拦截器链按配置顺序执行,支持复杂业务逻辑的切面处理。
2025-02-16 17:08:08
1189
原创 分布式实现数据库号段
分布式锁(可选):如果数据库不支持乐观锁,可使用分布式锁(如Redis或ZooKeeper)协调多个节点。若更新成功,返回新号段范围 [old_max_id + 1, old_max_id + step]。号段用完前预加载:可在号段剩余一定比例(如10%)时异步加载下一个号段,避免阻塞。监控与告警:监控号段使用情况,防止步长设置不合理导致频繁请求数据库。分布式安全:通过乐观锁、分布式锁或Redis原子操作保证一致性。号段模式核心:批量获取ID,减少数据库压力。步骤1:从数据库获取新号段(原子操作)
2025-02-16 16:50:43
547
原创 redis
使用Redisson集群模式,支持主从架构。提供了普通解锁和强制解锁两种方式。包含完整的异常处理和日志记录。基于看门狗机制的自动续期锁。配置了主从切换的容错机制。
2024-11-28 00:49:29
176
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人