自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(497)
  • 收藏
  • 关注

原创 Spring手动开启事务提交事务

但是,有时候我们需要手动开启事务,以便更细粒度地控制事务的边界。需要注意的是,TransactionCallbackWithoutResult是一个抽象类,其中的doInTransactionWithoutResult方法是一个抽象方法,你需要在其中实现你的业务逻辑代码。通过以上的方式,你就能手动开启事务并进行事务的操作了。在Spring中,事务是通过TransactionTemplate或者注解的方式来管理的。以上两种方法都可以实现手动开启事务的功能,具体选择哪种方法取决于项目的需求和开发团队的偏好。

2024-05-22 17:33:30 518

转载 Spring事件(Application Event)

因为它是@EventListener,且MyListener这个Bean是交给SpringBoot容器管理的,而feign子容器创建的时候,其实还处于Boot容器流程的内部,所以此时@EventListener肯定是没有注册上的,因此此方法代表的监听器就不会生效了。这就是我们getApplicationListeners的具体内容,我们发现:它只会拿注册到本容器的监听器(注册在谁身上就是谁的~~~),并不会去父类的拿的,所以这点一定要注意,你自己写监听器的时候也是需要注意这一点的,避免一些重复执行吧~~~

2024-05-10 11:45:29 9

原创 金额用Long还是BigDecimal?

解读:架构师的好苗子。程序不是能跑起来、不出错就行了,要考虑设计能不能自然体现业务需求,好不好理解、扩展和维护。

2024-05-06 14:03:31 529

原创 订单超时自动取消的实践方案

定时任务和延迟消息。1、定时任务定时任务实现策略,我们可以简单划分为单机版和集群版。笔者并不认可单机版,背八股文当然可以,订单自动取消这个业务场景,生产环境还是要慎重。每种方式各有优缺点,笔者更倾向于任务调度平台 XXL-JOB 这种方式。2、延迟消息延时消息是一种非常优雅的模式。消息队列 RocketMQ自研延迟服务Redis 延迟队列。假如技术团队基础架构能力很强,笔者推荐使用 RocketMQ 或者自研延迟服务。

2024-05-06 11:35:34 873 2

原创 数据库加密数据的如何模糊查询?

举个例子:banshan123使用4个字符为一组的加密方式,第一组bans ,第二组ansh ,第三组nsha ,第四组shan …对密文数据进行分词组合,将分词组合的结果集分别进行加密,然后存储到扩展列,查询时通过ext_key like '%partial%'。先对字符进行固定长度的分组,将一个字段拆分为多个,如根据4位英文字符,2个中文字符为一个检索条件。• 返回的结果列表中有可能有多余的结果,需要增加筛选的逻辑:对记录先解密,再筛选;• 支持模糊查询加密方式,产出的密文比较长;

2024-04-30 16:47:25 102

原创 从分布式系统CAP限制的角度,说说分布式锁的实现

当前,redis集群实现分布式锁的讨论非常多,也提出了很多方案,总结了很多很多坑,从CAP的角度上来说,没有坑是不可能的,可能压根从方向上就错了,redis实现分布式锁只适合单机的,接受单机的redis分布式锁吧,在适合它的场景使用就行。那么对于分布式锁系统来说,如果将自己设计成分布式的,那只有一种选择,就是CP模式,这样的话,适用zookeeper实现分布式锁是最好的选择,但是,zookeeper分布式锁有个问题,就是性能不高。1、zookeeper分布式锁,特点:性能较低,高可用。

2024-04-29 16:49:51 317 3

原创 数据脱敏方案

注意:在抹去数据中的敏感内容同时,也需要保持原有的数据特征、业务规则和数据关联性,保证我们在开发、测试以及数据分析类业务不会受到脱敏的影响,使脱敏前后的数据一致性和有效性。数据脱敏也叫数据的去隐私化,在我们给定脱敏规则和策略的情况下,对敏感数据比如 手机号、银行卡号 等信息,进行转换或者修改的一种技术手段,防止敏感数据直接在不可靠的环境下使用。数据脱敏的应用在生活中是比较常见的,比如我们在淘宝买东西订单详情中,商家账户信息会被用 * 遮挡,保障了商户隐私不泄露,这就是一种数据脱敏方式。

2024-04-29 11:22:09 677

原创 Controller层代码统一参数校验

有些时候 JSR303 标准中提供的校验规则不满足复杂的业务需求,也可以自定义校验规则。自定义校验规则需要做两件事情:自定义注解类,定义错误信息和一些其他需要的内容注解校验器,定义判定规则//自定义注解类/*** 是否允许为空*//*** 校验不通过返回的提示信息*/String message() default "不是一个手机号码格式";/*** Constraint要求的属性,用于分组校验和扩展,留空就好*/Class<?Class<?//注解校验器。

2024-04-29 11:17:22 750

原创 常见消息队列详解

消息队列是在消息的传输过程中保存消息的容器,用于接收消息并以文件的方式存储,一个消息队列可以被一个也可以被多个消费者消费,包含以下 3 元素:Producer:消息生产者,负责产生和发送消息到 Broker;Broker:消息处理中心,负责消息存储、确认、重试等,一般其中会包含多个 Queue;Consumer:消息消费者,负责从 Broker 中获取消息,并进行相应处理。

2024-04-29 10:19:47 690

原创 Spring外部接口的三种方案

SpringBoot不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。在Spring-Boot项目开发中,存在着本模块的代码需要访问外面模块接口,或外部url链接的需求, 比如在apaas开发过程中需要封装接口在接口中调用apaas提供的接口(像发起流程接口submit等等)下面也是提供了三种方式(不使用dubbo的方式)供我们选择。

2024-04-29 10:15:31 270

原创 redis工作使用总结

Redis作为一种优秀的基于key/value的缓存,有非常不错的性能和稳定性,无论是在工作中,还是面试中,都经常会出现。

2024-04-23 17:07:38 519

原创 接口优化技巧从3s到25ms

关于锁粒度:就是你要锁的范围有多大,不管是 synchronized 还是 redis 分布式锁,只需要在临界资源处加锁即可,不涉及共享资源的,不必要加锁,就好比你要上卫生间,只需要把卫生间的门锁上就可以,不需要把客厅的门也锁上。我们都用过数据库连接池,线程池等,这就是池思想的体现,它们解决的问题就是避免重复创建对象或创建连接,可以重复利用,避免不必要的损耗,毕竟创建销毁也会占用时间。也就是预取思想,就是提前要把查询的数据,提前计算好,放入缓存或者表中的某个字段,用的时候会大幅提高接口性能。

2024-04-02 11:31:38 679

原创 Nginx从安装到高可用实用教程!

最终结果,会把这个请求交给得出运算结果最小的服务器。所以,减少了负载均衡器的大量数据流动,负载均衡器不再是系统的瓶颈,就能处理很巨大的请求量,这种方式,一台负载均衡器能够为很多服务器进行分发。和TUN模式一样,LVS只是分发请求,应答包通过单独的路由返回给客户端,与TUN相比这种方式不需要隧道结构,可以兼容大多数的操作系统,同时统一路由可以隐藏真实的物理服务器。客户端将请求发往LVS,LVS会选择一台服务器响应请求,在客户端与服务器之间建立隧道,返回结果的时候直接由服务器返回响应,不在经过LVS。

2024-04-02 11:21:52 1089

原创 MySQL表设计军规18条

另外,还有有个好处是,如果哪天有非订单的业务,比如:金融业务,也需要建一个名字叫做pay的表,可以取名:finance_pay,就能非常轻松的区分。举个例子,比如:做异步excel导出功能时,需要在异步任务表中加一个字段,保存用户通过前端页面选择的查询条件,每个用户的查询条件可能都不一样。数据库中,特别是做了分库分表的业务库中,主键最好由外部算法(比如:雪花算法)生成,它能够保证生成的id是全局唯一的。其实还有很多公共字段,在不同的表之间,可以使用全局统一的命名规则,定义成相同的名称,以便于大家好理解。

2024-04-02 11:15:39 154

原创 List操作add,clear,addall报错UnsupportedOperationException的解决办法

对于转化后的集合list,所以使用集合修改方法add(),remove(),clear()会抛异常,因为其底层还是数组,为Arrays的一个内部类,1其并没有实现集合对应的修改类方法会报UnsupportedOperationException。当传入一个原生的数据类型的数组的时候,Arrays.asList()真正得到的参数就不是数组中的元素,而是数组对象本身!Arrays.asList()是泛型方法吗,传入的对象必须是对象数组。这个方法的使用时候,传递的数组必须是对象数组,而不是基本数据类型。

2024-03-29 17:06:12 243

转载 分布式任务调度框架(PowerJob与xxl-job对比)

PowerJob 是新一代分布式任务调度与计算框架,支持 CRON、API、固定频率、固定延迟等调度策略,提供工作流来编排任务解决依赖关系,能让您轻松完成作业的调度与繁杂任务的分布式计算。

2024-03-12 10:19:17 495

原创 聊聊@Async注解遇到的问题

看到BeanCurrentlyInCreationException这个异常,我的第一反应是出现了循环依赖的问题。但是仔细一想,Spring不是已经解决了循环依赖的问题么,怎么还报这个错。于是,我就询问小姐姐改了什么东西,她说在方法上加了@Async注解。这里我模拟一下当时的代码,AService 和 BService 相互引用,AService的 save() 方法加了 @Async 注解。

2024-03-05 11:00:55 60

原创 SpringCloud远程调用为啥要采用HTTP

首先SpringCloud开启Web服务依赖于内部封装的Tomcat容器,而今信息飞速发展,适应大流量的微服务,采用Tomcat处理HTTP请求,开发者编写Json作为资源传输,服务器做出相应的响应,可以更加的灵活处理业务数据,而HTTP协议是跨平台的,符合微服务B/C数据交互的方式,可以的一套服务器对应移动H5、App、小程序提供服务。注意:无论是何种类型的数据,最终都需要序列化转换成二进制流在网络上进行传输,数据的发送方需要将对象序列化转换为二进制流,而数据的接收方则需要把二进制流反序列化为对象。

2024-03-04 09:50:39 702

原创 OpenFeign核心原理

这一节主要是介绍了7个Feign的核心组件以及Spring对应的扩展实现为了方便你查看,我整理了如下表格接口作用Feign默认实现Spring实现Contract解析方法注解和参数,将Http请求参数和方法参数对应Encoder将请求体对应的方法参数序列化成字节数组Decoder将响应体的字节流反序列化成方法返回值类型对象Client发送Http请求InvocationHandler工厂,动态代理核心逻辑无在发送Http请求之前,再对Http请求的内容进行拦截修改无无。

2024-02-29 18:09:22 77

原创 四种经典限流算法讲解

固定窗口限流算法()是一种最简单的限流算法,其原理是在固定时间窗口单位时间)内限制请求的数量。该算法将时间分成固定的窗口,并在每个窗口内限制请求的数量。具体来说,算法将请求按照时间顺序放入时间窗口中,并计算该时间窗口内的请求数量,如果请求数量超出了限制,则拒绝该请求。假设单位时间(固定时间窗口)是1秒,限流阀值为3。在单位时间1秒内,每来一个请求,计数器就加1,如果计数器累加的次数超过限流阀值3,后续的请求全部拒绝。等到1s结束后,计数器清0,重新开始计数。

2024-02-28 13:30:19 903

原创 SpringBoot Redis 分布式锁的正确实现方式

使用上面的脚本,每个锁都用一个随机值作为唯一标识,当删除锁的客户端的“唯一标识”与锁的 value 匹配的时候,才能执行删除操作。加锁的代码应该写在 try {} 代码中,放在 try 外面的话,如果执行加锁异常(客户端网络连接超时),但是实际指令已经发送到服务端并执行,就会导致没有机会执行解锁的代码。此外,为了让程序更加健壮,码哥实现了阻塞等待获取分布式锁,让你用的更加开心,面试不慌加薪不难。一个分布式锁方案出来了,一气呵成,组员不明觉厉,纷纷竖起大拇指,伪代码如下。然而,这是一个错误的分布式锁。

2024-02-27 13:47:50 214

原创 MySQL的21个SQL经验

NOT NULL列更节省空间」,NULL列需要一个额外字节作为判断是否为 NULL 的标志位。「NULL列需要注意空指针问题」,NULL列在计算和比较的时候,需要注意空指针问题。

2024-02-26 16:30:25 1994 1

原创 SpringBoot 动态加载jar包,动态配置

URLClassLoader 是一种特殊的类加载器,可以从指定的 URL 中加载类和资源。它的主要作用是动态加载外部的 JAR 包或者类文件,从而实现动态扩展应用程序的功。为了便于管理动态加载的jar包,自定义类加载器继承URLClassloader。/*** 自定义类加载器*/@Override// 从已加载的类集合中获取指定名称的类Class<?if (clazz!= null) {try {// 调用父类的findClass方法加载指定名称的类。

2024-02-26 14:47:36 81

原创 Spring Boot 的参数校验方案

在平时的开发工作中,我们通常需要对接口进行参数格式验证。当参数个数较少(个数小于3)时,可以使用手动进行参数验证。当参数个数大于3个时,使用进行参数验证就会让代码显得臃肿,这个时候推荐使用注解来进行参数验证。​​我们在全局异常处理类中使用捕获异常,获取参数验证异常信息,最后返回统一的异常结果格式。除了框架自带的注解,平时的工作中可能需要我们自定义验证注解处理特定的业务需求。这里汪小成将上面User类中的手机号格式验证改成使用自定义注解的验证方式。4.2.1 定义注解​。

2024-02-23 11:42:35 632

原创 什么情况会发生Full GC?如何避免频繁Full GC?

Full GC(Full Garbage Collection)是Java虚拟机中进行垃圾回收的一种操作,它的目标是清理整个Java堆内存,包括年轻代(Young Generation)、年老代(Old Generation或Tenured Generation)、以及永久代(在Java 8及之前的版本中,而在Java 8及之后的版本中由Metaspace取代,所以这里可以理解为元空间Metaspace)。

2024-02-23 11:35:15 509

原创 谈谈Redis的哈希槽和一致性哈希

一种是一致性哈希 , 这种算法在 适用dis Cluster方案中并没有实现,主要在外部的代理模式 (Twemproxy)一种是 Slot 哈希槽算法 ,这种算法就是 Cluster 的核心算法所以谈到这个问题的时候,不能只讲一部分。在Redis 3.0 之前,Redis 是没有集群方案的,在这个时期实现 Redis 的分布式主要由客户端自行实现。一般的实现方式就是一致性 Hash。而 Redis 3.0之后,Redis 实现了 Cluster 集群,也就采用了相对而言更简洁的 Slot 槽方式。

2024-02-23 11:30:48 285

原创 SpringBoot实现缓存预热方案

使用启动监听事件实现缓存预热。使用 @PostConstruct 注解实现缓存预热。使用 CommandLineRunner 或 ApplicationRunner 实现缓存预热。通过实现 InitializingBean 接口,并重写 afterPropertiesSet 方法实现缓存预热。

2024-02-23 11:22:29 881

原创 SpringBoot接口防抖(防重复提交)的实现方案

在Web系统中,表单提交是一个非常常见的功能,如果不加控制,容易因为用户的误操作或网络延迟导致同一请求被发送多次,进而生成重复的数据记录。key分隔符是用来将多个参数合并在一起的,比如userName是张三,userPhone是123456,那么完整的key就是"张三&123456",最后再加上redis锁前缀,就组成了一个唯一key。从测试的结果上看,防抖是做到了,但是随着缓存消失、锁失效,还是可以发起同样的请求,所以要真正做到接口幂等性,还需要业务代码的判断、设置数据库表的UK索引等操作。

2024-02-23 11:10:02 111

原创 Redis实现滑动窗口限流

RateLimiter:限流注解RateLimitRule:限流规则RateLimiters:存放多个限流注解的容器,为了可以重复使用该注解// 支持重复注解/*** 限流键前缀* @return*//*** 限流规则* @return*//*** 限流类型* @return*//*** 时间窗口, 单位秒* @return*//*** 允许请求数* @return*/定义一个切面实现限流逻辑:RateLimiterAspect。

2024-02-23 10:55:08 1981

原创 ThreadLocal原理解读

ThreadLocal英文翻译过来就是:线程本地量,它其实是一种线程的隔离机制,保障了多线程环境下对于共享变量访问的安全性。看到上面的定义之后,那么问题就来了,ThreadLocal是如何解决共享变量访问的安全性的呢?其实ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。由于副本都归属于各自的线程,所以就不存在多线程共享的问题了。至于上述图中提及的threadLocals(ThreadLocalMap),我们后文看源代码的时候再继续来看。

2024-02-23 10:44:31 579

原创 Redis主从复制原理

Redis 同时支持主从复制和读写分离:一个 Redis 实例作为主节点Master,负责写操作。其它实例(可能有 1 或多个)作为从节点Slave,负责复制主节点的数据。

2024-02-23 10:19:27 737

原创 11个高可用方案

除了 Redis 中间件外,其他常见的 MySQL、Kafka 消息中间件、HBase 、ES 等 ,凡是涉及到数据存储的介质,都有备份机制,一旦主节点挂了,会启用备份节点,保证数据不会丢失。比如电商大促,业务在峰值时刻,系统抵挡不住全部的流量时,系统的负载、CPU 的使用率都超过了预警水位,可以对一些非核心的功能进行降级,降低系统压力,比如把。架构,将一个复杂的业务域按DDD的思想拆分成若干子系统,每个子系统负责专属的业务功能,做好垂直化建设,各个子系统之间做好边界隔离,降低风险蔓延。

2024-02-23 10:15:31 819

原创 Spring 系列之 Spring Framework 中的 Bean

BeanSpringFramework中的Bean是框架的核心概念之一,通过Spring容器负责创建、组装和管理对象,帮助开发者构建可维护、可扩展的应用程序。本文介绍了Bean的概念、生命周期、配置方式、依赖注入和作用域等重要内容。了解和掌握Spring中的Bean对开发者来说至关重要,它能够提高代码的可测试性、可扩展性和可维护性,使开发工作更加高效和舒适。

2024-02-23 10:10:51 41

原创 Java8 的 LocalDateTime使用

方法用于以指定的日期时间量来修改 LocalDateTime 对象的对应字段,其他字段不变,其中 Xxx 表示日期时间单位,如:Year、Month、DayOfMonth、Hour、Minute、Second 和 Nano。方法用于比较两个 LocalDateTime 对象的顺序大小,如果当前对象在参数对象之前,则返回负数,如果当前对象在参数对象之后,则返回正数,如果两个对象相等,则返回 0。其中,text 表示要解析的字符串,formatter 表示日期时间格式化对象。

2024-02-22 15:25:22 786

原创 SpingBoot的5个扩展点,超级实用!

最后我来把扩展点图补充完整,如下所示,很清晰明了,在什么时候调用了什么,我们自己开发的时候结合应用场景,在什么时候要干什么事,就知道要创建什么类型的扩展点了。

2024-02-22 10:22:02 32

原创 虚拟机的内存结构

熟悉 Java 语言特性的同学都知道,相比 C、C++ 等编程语言,Java 无需通过手动方式回收内存,内存中所有的对象都可以交给 Java 虚拟机来帮助自动回收;而像 C、C++ 等编程语言,需要开发者通过代码手动释放内存资源,否则会导致内存溢出。尽管如此,如果编程不当,Java 应用程序也可能会出现内存溢出的现象,例如下面这个异常!它表示当前服务已出现内存溢出,简单的说就是当服务出现了内存不足时,就会抛异常。这种异常是怎么出现的呢?该如何解决呢?

2024-02-21 16:29:37 74

原创 xxl-job架构原理讲解

总的来说,调用中心是用来控制定时任务的触发逻辑,而执行器是具体执行任务的,这是一种任务和触发逻辑分离的设计思想,这种方式的好处就是使任务更加灵活,可以随时被调用,还可以被不同的调度规则触发。任务第一次触发的时候选择了执行器实例A,由于任务执行时间长,任务第二次触发的时候,执行器的路由到了B,此时A的任务还在执行,但是B感知不到A的任务在执行,所以此时B就直接执行了任务。之后调度线程还会继续重复上面的步骤,查任务,调度任务,更新任务下次执行时间,一直死循环下去,这就实现了任务到了执行时间就会触发的功能。

2024-02-21 16:09:22 3585

原创 灵活的数据权限思路

我一年java,在小公司,当前公司权限这块都没有成熟的方案,目前我知道权限分为功能权限和数据权限,我不知道数据权限这块大家是怎么解决的,但在实际项目中我遇到数据权限真的复杂,你永远不知道业主在这方面的需求是什么。

2024-02-20 11:15:12 911

原创 解锁 SpringBoot 的强大配置功能

ConfigurationProperties 和 @PropertySources 都是与属性配置相关的注解,用于在 Spring 应用程序中管理和加载配置信息。

2024-02-20 09:58:58 57

原创 SpringBoot + Nacos 实现动态化线程池

在对线程池配置参数进行调整时,一般需要对服务进行重启,这样修改的成本就会偏高。一种解决办法就是,将线程池的配置放到平台侧,运行开发同学根据系统运行情况对核心参数进行动态配置。在后台开发中,会经常用到线程池技术,对于线程池核心参数的配置很大程度上依靠经验。本文以Nacos作为服务配置中心,以修改线程池核心线程数、最大线程数为例,实现一个简单的动态化线程池。为了能够看到效果,我们多访问几次/add接口,增加任务数,在控制台出现拒绝信息时调整nacos配置。,配置监听,nacos配置变更时实时修改线程池的配置。

2024-02-19 13:35:58 428 2

空空如也

空空如也

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

TA关注的人

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