- 博客(126)
- 收藏
- 关注
原创 绝对全网首发,利用Disruptor EventHandler实现在多线程下顺序性执行任务
可以给事件定义一个hash函数,根据哈希取余的槽位下标和当前处理器的下标比较,判断出此事件是否应被当前的处理器处理,不该其处理的事件直接pass,避免重复消费。这两个处理器,那么每个任务只会被其中一个处理器处理,这两处理器的处理时间总数加起来是这4个事件。,这两个处理器都会去这4个事件,也就是每个事件会被处理两次,每个处理器处理一次;也就是说,假设任务队列中有a、b、c、d三个事件,disruptor有两种任务处理器,一个是。可以彼此独立消费同一个队列中的任务,定义的哈希函数接口和统一的基础父类。
2024-06-20 22:38:11 557 1
原创 利用单线程池实现多线程并发顺序消费消息
在某些场景下,我们需要保证消费消息的顺序性,可能要使用单线程处理任务。这个在消息数量较少时,还是一个可行的方案,但在大量的数据消息情况下,单线程就显得力不从心了,所以这时候需要引入多线程。
2024-06-20 22:36:44 433
原创 Spring Boot中的各种事件
spring boot 各种事件贯穿整个启动的生命周期,读懂了这些时间也差不多理解了springboot的启动流程。接口表示springboot程序准备开始启动,这是最早的事件触发方法,它将触发。的方法定义很讲究,方法从上到下的顺序也正好是各事件触发的顺序。定义了spring启动过程中各个事件被触发的顶层方法。接口的唯一具体实现类是。
2024-06-14 23:17:50 680 4
原创 WebMvcConfigurer配置不当导致鉴权失败
这样导致springboot中springmvc的自动配置全部失效,这方面所有的配置都得自己手动配置,而我们项目中的公用基础依赖的鉴权是又要依赖spring mvc的自动配置,线程上下文中无法注入session信息,导致接口调用时鉴权失败。公司是公用同一套基础依赖,所以我也为自己的项目配置了一个拦截器,我在启动项目后我请求了项目中的一个接口,session鉴权通过,没有出现他那种情况。这个注解,我一般都不加Enable注解,springboot中一般不需要。开头的注解,我推测应该是这个注解有问题。
2024-06-14 14:06:39 644 1
原创 Mysql常用的数据备份工具
mysqlbackup: mysql enterprise的商业备份工具,功能相对完善,适合生产环境,但是商业收费软件、互联网行业使用较少。mysqldump: mysql自带的简易数据库备份工具,只能全量备份,且是单线程备份,对于大数据量的备份不太合适。mysqlpump: mysql自带的简易数据库备份工具,也只能全量备份,但可以多线程并行备份。mysqlimport: mysql自带的结构化文本数据导入工具,和。xtrabackup: 开源的功能完备的数据库备份软件。
2024-06-07 12:53:51 321
原创 史上最易懂的mysql锁 、mvvc分析
现在有一个表stu,其中的age字段有索引,现在针对age字段做锁实验。stu表中目前有如下这些数据,间隙锁间隙锁和间隙锁之间是兼容的,即可以同时同一个区间加锁,不会有锁竞争。插入意向锁和插入意向锁(也是一种间隙锁)之间是兼容的,只要不是唯一索引(包括主键)冲突,可以直接插入,不会有锁竞争。间隙锁和插入意向锁之间有锁竞争,但只有在先有间隙锁再申请插入意向锁时才会不兼容,有锁竞争;反之在先有插入意向锁再申请间隙锁是不会有锁竞争的,是兼容的。
2024-06-07 00:05:22 393
原创 MySQL的PrepareStatement真的是预编译语句么?
通过使用 PreparedStatement,可以预编译 SQL 语句,并且在执行时可以重复使用这个预编译的语句,这样可以提高执行效率并且增强安全性(特别是防止 SQL 注入攻击)。:是否启用PrepareStatement缓存,默认值是false,相同sql就不再构建新的PrepareStatement对象。:PrepareStatement缓存的最大数量,默认值是25,超过这个数字就抛弃老的prepStmt。: 可以缓存的prepStmt对应sql的最大字符长度,默认值256,超过这个上线就不缓存。
2024-06-05 15:22:29 521
原创 深入浅出mysql海量数据批量更新插入、批量查询
这个参数后的抓包截图,jdbc客户端重写了sql语句,它把多个sql语句用分号分隔连接在一起,形成一个大sql脚本, 然后将这个sql脚本一次性发送到server端,最后接收到了大量的response响应。mysql提供了批量写入的方法,将大批量的sql脚本一批次发送到服务端,减少IO次数,然后统一一次执行sql。理论上,上面的sql是批量提交到mysql server统一执行的,但在默认情况下实际上它还是一条条执行命令,要真正的批量执行sql,需要在jdbc连接url加上。,重启项目再执行接口。
2024-06-05 12:15:55 2027 1
原创 深入浅出feign 、ribbion中的重试相关配置
feign、ribbion,这两个组件是spring cloud 远程调用最常用的两个组件。这两个组件分别有各自的重试机制和默认配置。
2024-06-03 23:34:53 1965
原创 深入理解mysql中的各种超时属性
连接超时: 登录超时: Socket网络超时,即读超时: sql执行超时:spring事务超时:innodb锁等待超时:mysql server网络回包写超时(针对大量数据查询的sql)
2024-06-03 13:21:51 1995
原创 深入理解feign远程调用的各种超时参数
2) 同时使用了feign和ribbion组件,(1)若没有任何人为配置超时时间,远程调用使用ribbion的默认超时时间,连接超时、读超时都是1秒钟;(2)若同时主动配置了feign 、ribbion的超时时间,则使用feign的超时时间;(3)若只主动配置了feign超时时间,则使用feign超时时间;(4)若只主动配置了ribbon超时时间,则使用ribbion超市时间。1)只使用feign组件,不使用ribbion组件,其默认的连接超时是10s,读超时是60s;
2024-06-02 23:47:34 2214
原创 记一次线上数据库连接超时异常问题
以我对这项目的了解度,我马上就想到了这段时间有一两个定时任务,这两个定时任务都是多线程任务,并且有量的查询和写入数据,但之前都是20分钟左右跑完数据,一般会在这此事故发生段之前就执行完。看下xxl-job的执行日志,确实是在我预先的时间就开始跑任务,但是服务应用的日志却又发现在事故发生时还有定时任务在处理中,并且也都失败了,还进行了事务回滚。所以增加连接池的数据数是个可行的方案。查看了下,数据库的最大总连接数、单用户最大连接数,结果如下图所示,八千多的连接上限,我想我的项目实时的连接数还不至于这么大。
2024-06-02 23:25:37 521
原创 解决wireshark无法抓取mysql数据报文
所以默认情况下,我的每个mysql connection都是加密的,wireshark肯定是没办法抓取数据包的。这三个参数是否被显式设值 如果这三个参数有被显式设值,就用这三个中的一个参数。而在我之前用的连接url中这四个参数显然都没被显式设值,所以最终的sslMode的值是。但用公司测试环境的数据库就能抓取到mysql数据报文,观察了下公司的数据库就只发现连接url上多了。这个参数,死马当活马医,我在本地数据库连接上也加了这参数,果然可以抓取mysql数据包文了。方法有对ssl加密参数相关的初始化逻辑。
2024-05-30 17:50:13 546 1
原创 我给线程池管理框架hippo4j找bug
中包含虚拟机参数,而虚拟机参数要放在jar包名之前才会生效,所以此时的虚拟机参数是不生效的。不同项目中有相同的线程池名词,这个应该是是常见现象,不知道为啥这里直接抛出异常报错。这三级的,实际上当你注册线程池时,不能和现有的任何。上面的tpId是线程池名字,上边的查询条件并没有加。参数,作者想打印gc日志并开启日志轮转,本人用。之后,而只有项目参数才放在jar包名之后。hippo4j的官方文档说,线程池管理是分。名字相同(即使是不同租户、不同项目)。方法就做了这种奇怪的判断逻辑。文件中,让我们去看看这个。
2024-05-30 16:34:07 405
原创 java微服在使用nacos注册中心时,ribbon负载均衡时给部分feign client使用静态serverList
我看很多贴子都是针对eureka环境下,做静态serverList配置,目前国内大部分都用Nacos,所以便研究了一下。listOfServers:表示你的微服务实例的’ ip地址+端口’的列表,多个实例用逗号分隔,NIWSServerListClassName:表示ServerList的类名,这个只能用。ConfigurationBasedServerList的核心方法就是derive。, 表示使用静态配置的服务列表,而不适用动态服务发现。micore-service-x: 表示你的微服务名。
2024-05-24 23:57:23 337
原创 mysql驱动版本变更导致查询数据结果一直是空
最近接手了一个已离职同事的java项目,这个项目中原来使用了自己的mysql驱动版本,并未使用公司公共依赖中的版本号。我想为了统一版本号,就将当前项目中pom文件中mysql的版本号verson给去除了。没怎么自测,就直接发到生产环境了,结果没多久就有测试人员告诉了说,有接口报错。其主逻辑sql如下后面发现不止这个接口查询结果为空,其他好几个接口的查询结果都未空。我用同样的sql语句在navicat中能查出结果,我开始怀疑我是不是连错数据库了,是不是连接到开发环境中的数据库。我使用。
2024-05-24 23:46:06 959
原创 使用回退流PushbackInputStream,在http客户端拦截器中检测http响应是否是文本格式并打印响应内容
在拦截器中的输入出入流一般都是有状态的,只能读写一次,在读/写后再次尝试读写直接抛出异常。那么如果我们在拦截器中直接读取出IO流中的参数,那么实际的业务方就没法用这个流数据了、业务方会出翔IO异常。这里我们需要一种读取了部分I/O流数据还能回退到起始点的I/O流,幸运的是还有这种流,它就是。而且一般会有这种需求,只打印文本参数、而不打印如文件、图片这类二进制流,毕竟二进制流打印出来也看不懂、没啥意义。我在ok http3中发现他是通过读取流中的前16个UTF-8字符来判断的。
2024-05-16 17:39:28 294
原创 一次线上SQL调优,从一分钟到一秒以内的极限操作
为了进一步提高查询速度,我又将索引类型改为了哈希索引,本以为哈希索引会提高查询速度,最终的结果却是两者速度差不多。此次优化后,sql查询变得简单了,相当于只查主表数据,外加每条主数据执行下几个count计算,优化后的sql查询用时在42秒左右。具体问题具体分析,需求中只会用到连表的分组统计count进行排序,并没有使用连表数据的具体数据,其实这里是不需要连表的,我们可以使用子查询去计算count,从而避免连表生成大笛卡尔集。此时已经大致达成了本次优化目标,不久后随着数据量的上涨,这个查询又变得很慢了。
2024-05-16 16:55:55 448
原创 生产环境一些十分有用的JVM参数
这两个参数一般一起使用,当发生内存溢出错误时自动生成HeapDumpPath指定路径下的转储文件。表示日志文件生成时间戳的占位符,这两个占位符可以帮助我们快速定位某个应用某个时间段的gc文件在哪儿。:打印更详细的gc信息,如内存分区信息(新生代、老年代等)、堆信息(堆总大小、已使用大小等)这三个参数一般同时使用,用来防止单个GC日志文件过,同时减少GC日志文件的总大小。: 堆转储文件位置,堆转储文件对于没有打印日志时的故障分析非常重要。:当发发生堆内存溢出时,自动生成堆转储文件。即在后再退出虚拟机。
2024-04-12 15:50:53 485
原创 记一次生产环境Java堆内存溢出问题排查思路
先将转储文件从服务器下载下来,打开Visual VM,点击右上角的Load Snapshot,将这个转储文件加载到Visual VM中。
2024-04-12 11:16:11 1447 1
原创 centos上安装并持久化配置LVS
1)系统版本:centos7.82)虚拟机:3个centos虚拟机,(其中一个做Director Server,另外两个做Real Server)3) LVS大致有NAT ,DR ,Tun这三种模式,这里搭建一个典型的DR模式的LVS。
2023-12-02 01:17:03 714
原创 低权限(无权限)时如何在mysql客户端控制台的大量输出中快速定位mysql死锁或慢sql
(注意是mysql的客户端中使用kill,不是linux的shell终端中,linux的kill命令只能杀进程而无法杀线程,这里输出的这个390033是mysql的一个线程id,只能在mysql的客户端中起作用)这个命令的输出信息太多了,我们公司很多个库都部署在同一个mysql实例中,所以其他库的进程信息也输出到控制台了。查看mysql的查看死锁的方式很多,但很多时候我们普通开发者的权限比较低,无法执行某命令。此时将mysql的进程信息输出到mysql 你就可以使用grep命令过滤出你需要的死锁信息了。
2023-11-22 23:29:47 236
原创 netty的NioEventLoopGroup的创建过程
EventLoopGroup是一个事件循环组,它管理着多个EventLoop,每个EventLoop都可以看成一个线程池(一般是单个线程,netty的几乎所有EventLoop实现类都是但线程池).一个EventLoopGroup上会注册多个Channel,实际上它会根据内部EventExecutorChooser的算法,将一个Channel注册到其内部管理的一个具体的EventLoop,此EventLoop线程池处理这个Channel的所有IO事件和业务任务,而其他EventLoop线程池不能处理.
2022-05-31 23:44:48 498
原创 Spring容器refresh方法执行流程
spring启动过程onfresh主流程refresh{ // Prepare this context for refreshing. // Prepare this context for refreshing, setting its startup date and active flag as well as performing any initialization of property sources. // 设置其启动日期和活动标志以及各种任何属性来源的初始化。 初始化
2022-05-27 03:36:13 405
原创 Jackson配置大全
jackson支持以下格式Avro, BSON, CBOR, CSV, Smile, (Java) Properties, Protobuf, TOML, XML or YAML;1.基础注解注解用法@JsonProperty用于属性,把属性的名称序列化时转换为另外一个名称。示例:@JsonProperty("birth_date") private Date birthDate@JsonIgnore可用于字段、getter/setter、构造函数参数上,作用相同,都会对
2022-03-30 14:48:27 6210
原创 forkjoinpool源码分析
ForkJoinPool是用于执行ForkJoinTask任务的ExecutorService。 ForkJoinPool不仅提供了来自非ForkJoinTask任务提交的入口,另外还提供相关的管理和监控。ForkJoinPool与其他类型的ExecutorService的不同之处主要在于,它采用了工作窃取算法:池中的所有线程都会尝试查找并执行池中的任务或由其他活动任务所创建的任务(如果不存在,则需要阻塞等待) 。当大量任务产生其他子任务时(大多数ForkJoinTask就是如此)及外部提交者向池中提交大
2022-01-10 11:46:37 1838
翻译 在 Spring Boot 使用Bean Validation 完全指南
1 前言Bean Validation是 Java 生态圏中实现Bean校验规范的事实上的标准。 它与 Spring 和 Spring Boot 能很好地集成在一起。但是,也存在一些问题。 本教程详细介绍了所有主要的校验用例和每个用例的代码示例。代码示例他的文章附有 GitHub 上的工作代码示例。2 使用 Spring Boot Validation StarterSpring Boot 的 Bean Validation 支持起步依赖starter,我们可以将其包含到我们的项目中(在Gr
2021-11-20 20:05:15 2620
翻译 在Spring Bean 生命周期中加入钩子函数
1 前言提供一个控制反转功能是 Spring框架的核心功能之一。 Spring 在其应用程序上下文中组织并 并管理这些beans的生命周期。 在本教程中,我们将研究这些 bean 的生命周期以及我们如何加入这些钩子函数。代码示例他的文章附有 GitHub 上的工作代码示例。2 什么是 Spring Bean?让我们从基础开始。 在创建、编排和销毁方面受 Spring 的 ApplicationContext控制的每个对象都称为 Spring Bean。定义 Spring bean 最常见的方
2021-11-13 21:06:36 1149
原创 使用@AutoConfigureBefore @AutoConfigureAfter注解指定bean实例化先后顺序为啥没效果?
@AutoConfigureBefore @AutoConfigureAfter 是针对自动配置类的,如果直接在一个在启动类的子包下的javabean上使用此注解是不生效的。这个注解应该放置在启动类无法扫描到的地方,另外还要在classpath目录下建一个文件META-INF/spring.factories,在这个文件中指定自动配置类的全路径。如何保证一个配置类不会被springboot项目启动后扫描到,在启动类的上层父包中建一个配置类吗?类似于上面附图这样的结构吗?这项目结构也太奇怪了,对于我这种
2021-08-17 22:22:15 1263 3
原创 公共dto打包时按条件导出实现feignclient接口的bean,解决feign.Feign$Builder类找不到的问题
不同的微服务之间相互调用,不可避免会使用到feign client。为了统一处理参数和请求地址等变化,我们一般会将这些API服务的请求参数dto、响应dto及Feign接口封装在一个公共的dto项目中(为了防止jar包冲突和依赖传递,这里的feign stater包的作用域是provided),调用方引入这个项目jar包,就可以直接使用这些相关api服务。有的项目本身可能不需要Feign接口,只需要请求参数dto、响应dto,因此他们在自己的项目中没有引入feign starter这个jar包,但在公共的d
2021-05-24 17:34:42 789
原创 spring security使用自定义的的AuthenticationFilter时,要限制session个数,禁止多端同时登录
在WebSecurityConfigurerAdapter#configure(HttpSecurity)方法中配置session管理没有效果,因为我们使用了自己的AuthenticationFilter,只能手动给LoginFilter配置SessionAuthenticationStrategy。@Configurationpublic class CustomFilterSecurityConfig extends WebSecurityConfigurerAdapter { //ses
2021-04-14 19:27:33 1412 6
原创 spring security 用JPA进行安全管理中使用自定义的UserDetails时,maximumSessions()无法限制Session数
这是我自定义的UserDetails,这个user对象会保存到数据库。//自定义的User@Entity(name = "t_user")public class User implements UserDetails, CredentialsContainer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username;
2021-04-14 14:59:26 662
原创 spring security 使用自定义的AuthenticationFilter,提示Invalid remember-me cookie,自动登录失败的解决方法
spring security 在使用自定义的AuthenticationFilter时,提示Invalid remember-me cookie,自动登录失败的解决方法后台日志报错提示Invalid remember-me cookie: Cookie token[2] contained signature ‘1706b276eae214cc837865d3c508cf01’ but expected ‘84908c8a60e515d544d96550496f0daf’我自定义了一个Login
2021-04-14 02:31:01 862
原创 Spring Bean生命周期简图
流程图getBean大致调用栈 Aware Group1 BeanNameAware BeanClassLoaderAware BeanFactoryAware Aware Group2 EnvironmentAware EmbeddedValueResolverAware //该接口能够获取Spring EL解析器,用户的自定义注解需要支持spel表达式的时候可
2021-03-17 15:05:08 218 3
原创 原子更新引用AtomicReference实现原理分析
1 前言原子更新基本类型只能更新单个变量,而原子更新引用类型可以原子更新多个变量。Atomic包提供了以下3个类。AtomicReference:原子更新引用类型。AtomicReferenceFieldUpdater:原子更新引用类型里的字段。AtomicMarkableReference:原子更新带有标记位的引用类型(可以原子更新一个布尔类型的标记位和引用类型。)。现在先来看看AtomicReference是如何实现的(基于JDK1.8)2 实现过程分析主要字段private sta
2020-06-28 03:11:54 1484 5
原创 原子数组AtomicIntegerArray实现原理简析
1 前言JDK官方提供了3个原子数组,它们提供了原子更新数组中元素的能力,它们主要借助Unsafe类实现其核心功能。AtomicIntegerArray:原子更新整型数组里的元素AtomicLongArray:原子更新长整型数组里的元素。AtomicReferenceArray:原子更新引用类型数组里的元素。在分析原子数组之前,我们先来了解Java对象的内存布局,Java对象由对象头和实例数据两部分组成。下图中MarkWord包含对象的hashCode、锁信息、垃圾回收的分代信息
2020-06-21 02:17:45 1104
原创 交换者Exchanger完全解析
1 前言Exchanger(交换者)是一个用于线程间协作的工具类, 它可以在配对线程中配对并交换数据。每个线程都可以在exchange入口方法上携带数据,然后与相应的线程进行匹配,并在返回时接收配对线程的数据。它提供一个同步点,在这个同步点,两个线程可以交换彼此的数据。这两个线程通过exchange方法交换数据,如果第一个线程先执行exchange()方法,它会一直等待第二个线程也执行...
2020-06-01 01:58:00 1072
原创 多线程数据交换工具Exchanger完全解析
1 前言Exchanger(交换者)是一个用于线程间协作的工具类, 它可以在配对线程中配对并交换数据。每个线程都可以在exchange入口方法上携带数据,然后与相应的线程进行匹配,并在返回时接收配对线程的数据。它提供一个同步点,在这个同步点,两个线程可以交换彼此的数据。这两个线程通过exchange方法交换数据,如果第一个线程先执行exchange()方法,它会一直等待第二个线程也执行exchange方法,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方。交换器可能在遗
2020-06-01 01:50:35 821
原创 信号量Semaphore深入解读
1 简介Semaphore可翻译为信号量,它维护一组许可证, 每次尝试获取许可证时都将阻塞等待直到可获取,它才能获取到并解除阻塞状态。 Semaphore可以控制一些物理或逻辑资源的访问或使用,它常常用于限制线程数目。在实际开发中,可用作流量控制,特别对于一些公共资源有限的应用场景,如数据库连接,或是一些其他限流的缓存池。(基于JDK1.8)2 示例这是一个使用信号量控制对缓存池缓存中items访问的示例。public class SemaphoreDemo { static class P
2020-05-25 01:26:47 426
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人