自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 必看!Spring Boot 项目新老版本 Controller 低侵入式切换实战秘籍

该项目在进行迁移重构时,考虑到大部分业务逻辑雷同,为了降低系统复杂度和维护成本,并没有新开服务,而是在原来的项目中添加新的 Controller。这就意味着所有的操作都要在同一个 JVM 进程项目的前提下进行,如何在不影响现有系统正常运行的情况下,实现新老版本 Controller 的低侵入式切换,成为了摆在开发团队面前的一道难题。这是业务部门研发团队最初采用的实现方案,通过自定义注解和 AOP(面向切面编程)的方式,实现了新老版本 Controller 的切换。1、自定义注解。

2025-04-01 09:05:21 551

原创 踩坑实录!Spring AOP切点表达式失效之谜及高效修复攻略

本次问题的解决过程源于团队成员的一次求助,起初我也一时摸不着头脑,直到留意到注解是添加在类上而非方法上,才恍然大悟。这次小小的 “坑” 让我们深刻认识到了切点表达式的细节和作用域的重要性。希望通过分享这次经历,能帮助更多的开发者在使用 Spring AOP 时少走弯路,避免陷入同样的困境。如果你对切点表达式的详细使用和更多高级特性感兴趣,不妨参考这篇优质博文,相信你能从中获取更多有价值的信息。

2025-03-25 09:27:48 773

原创 超详细!Spring Boot项目结合Maven Profile实现多环境切换,轻松搞定开发部署难题

Spring Boot Profile 是一种配置机制,它允许我们在同一个应用程序中针对不同的环境(如开发、测试和生产环境)设置不同的配置。这意味着我们可以根据环境的需求,灵活地加载特定的配置,让应用程序在不同环境下都能完美运行。这些配置通常存储在以application-{profile}.yml或application-{profile}.properties命名的文件中,比如application-dev.yml就是专门用于开发环境的配置文件。

2025-03-04 09:36:09 775

原创 深度揭秘:Java 应用程序中实现数据库读写分离的高效策略与实战

这种方式通过自定义数据源路由和 mybatis 拦截器,实现根据 SQL 语句类型自动切换主从数据源,从而达到读写分离的效果。1、引入依赖</</</</配置数据源3、定义数据源枚举MASTER,SLAVE线程级数据源上下文管理动态路由数据源@Slf4j@Overridelog.info("DynamicRoutingDataSource 切换数据源到从库");log.info("DynamicRoutingDataSource 切换数据源到主库");

2025-02-18 09:29:07 778

原创 如何以低侵入方式获取业务系统使用的二方包版本号

获取业务系统使用的二方包版本号这个需求,在大多数业务开发场景中可能并不常见,但在开发基础组件或进行依赖管理时却非常重要。通过本文介绍的埋点上报方式,我们可以以较低的侵入性获取到业务方使用的二方包及其版本号。在实施过程中,需要注意以下几点:首先,上报操作一定要使用异步方式,避免对业务造成堵塞;其次,如果使用自定义 Maven 插件进行上报,要注意类加载器的问题,因为 Maven 插件的类加载器是自定义类加载器;

2025-02-11 09:16:29 523

原创 记一次springcloud gateway记录日志响应结果乱码问题

最近团队的网关日志发现有不少响应结果记录,出现形如下的乱码��(�钍/�,}�����]O7L|���ŲƧ�MϦnP�Q*K�)*�+���QJ-*�/r�O���{�@8� ��一开始感觉是不是中文乱码,但是后面发现有些日志不是中文,也是乱码,而有些记录的日志又能正常显示。于是搜索了一圈,在在这篇文章找到的思路以及解决答案。综上解决因Accept-Encoding引起的乱码方式有2种,一种是直接移除Accept-Encoding,告诉服务端不要对响应数据进行压缩,直接返回未压缩数据。

2025-01-14 10:22:04 609

原创 聊聊springboot项目如何优雅进行数据校验

在我们日常开发中,数据校验是我们绕不开的一环,而用Spring Validation进行校验,基本上成为我们进行数据校验的首选组件,今天的话题就来聊下如何利用Spring Validation进行优雅校验Spring框架的验证功能主要基于JSR 303/JSR 349 Bean Validation规范,这是一套标准的Java注解驱动的数据验证API。Spring提供了对Bean Validation的深度集成,使得在Web应用中进行数据校验变得既强大又简便。

2024-12-31 10:19:03 981

原创 聊聊在应用层面实现内网穿透功能是否可行

最近接手了供方开发的网关项目,交接文档里面有个内网穿透的功能,一下子就吸引的我的目光。实现这个内网穿透的背景是业务部门有些业务是部署在公网,这些公网的业务想访问内网的业务,但因为公网和内网没打通,导致无法访问,为了解决这个问题,供方在网关上做了一个内网穿透功能不管是通过消息队列还是通过反向代理来实现内网穿透,本质上就是多加一层来解决,就是应了一句话,没有什么是加一层中间层不能解决的,如果有,那就再加一层。

2024-12-10 09:32:27 357

原创 聊聊如何利用kafka实现请求-响应模式

在大多数场景中,我们经常使用kafka来做发布-订阅,在发布-订阅模型中,消息一旦发送就不再追踪后续处理,但在某些业务场景下,我们希望在发送消息后等待一个响应,然后根据这个响应来做我们后续的操作。在这种请求-响应模式,我们就可以利用spring kafka的ReplyingKafkaTemplate来实现ReplyingKafkaTemplate 是 Spring Kafka 中的一个高级特性,专门用于处理 Kafka 中的请求/响应模式。它允许你发送一个消息到 Kafka,并等待一个响应。

2024-12-03 10:35:56 696

原创 聊聊springboot项目中使用jackson的一些小技巧

在我们前后端联调时,很经常以json作为数据的交互格式,今天我们就来聊聊在开发springboot项目中,使用jackson进行数据渲染一些小技巧本文介绍枚举和json转换、long精度问题、数据脱敏三种我们日常开发比较常用的场景,但不知道大家发现没,这三种场景本质上都是通过json的序列化和反序列化实现,因此我们可以通过定制全局json序列化、反序列化器来实现。核心代码如下@Bean。

2024-11-19 10:30:43 820

原创 聊聊我们那些年用过的表达式引擎组件

我们在设计一些表单或者流程引擎时,可能我们会设计各种各样的表达式或者规则,我们通过各种表达式或者规则来实现我们的业务流转。今天就来盘点一下我们经常会使用到的表达式引擎本文介绍了市面比较常用的表达式引擎组件,而这些引擎基本上都可以用hutool提供的表达式门面实现,hutool确实在工具类这方面做得很好,基本上我们日常会用到的工具,它大部分都涵盖到。最后文末demo链接,也提供了跟spring整合的表达引擎聚合实现,大家感兴趣也可以看看。

2024-11-12 10:41:56 920

原创 聊聊spring项目如何根据事件条件进行事件分发

spring的事件驱动模型,想必大家都比较熟,今天就来水一期,如何使用事件条件来进行事件触发。直接上示例看完也许有朋友会说,我直接在监听类方法里,写if-else也可以达到效果啊,为啥那么麻烦。如果业务没那么复杂的话,可以这么做,但是我们本身使用事件就是为了解耦,如果在事件监听里面写一堆if-else,一来职责不够单一,二来我们更提倡对修改关闭,对扩展开放。

2024-10-29 10:16:51 423

原创 聊聊如何优雅替换第三方提供的spring bean

前阵子业务部门接手供方的项目过来运维,在这个项目中,供方提供了一个springboot starter,但这个starter不满足业务部门需求的,业务部门的研发本想基于这个starter进行扩展,但发现其中有个核心类,用了 @Primary注解,示例形如下@Bean@Primary这样导致他们无法使用他们自定义的类,于是业务部门就找上了我们部门,看我们这边有没有什么法子,今天就来聊聊这个话题,如何优雅的替换第三方提供的spring bean。

2024-10-22 10:13:20 627

原创 聊聊如何实现一个特别的责任链

什么是责任链责任链是一种设计模式,它让多个对象有机会处理同一个请求,这些对象形成一个链。请求从链的一端开始,逐个传递给链上的对象,直到某个对象处理它或者请求未被处理。这样,发送请求者无需知道哪个对象会处理,实现了发送者与接收者的解耦,增加了系统的灵活性责任链的常用场景权限与认证系统:在登录认证、权限验证流程中,不同的处理者可以检查用户名密码、验证权限级别、处理单点登录等。请求(如访问资源)沿着责任链传递,直到找到合适的处理器来授权或拒绝访问。日志记录与错误处理。

2024-10-15 09:24:44 675

原创 聊聊springboot项目如何细粒度控制API响应值

不知道大家日常开发会不会有类似这样的需求,同个API接口不同版本需要返回不同响应值,不同角色需要看到不同响应数据。接到类似这样的需求,一般人的做法可能是针对不同的场景定义不同的DTO,今天给大家介绍一款在springboot项目中可以细粒度控制响应值的大杀器@JsonView什么是@JsonView?@JsonView是Spring MVC中使用的Jackson注解,用于在序列化和反序列化过程中控制JSON对象的特定字段。例如,该注释可以允许基于上下文仅返回对象的某些字段。@JsonView应用场景。

2024-09-24 09:26:41 769

原创 ingress-nginx常用注解指南

k8s ingress-nginx是个好东西,而如何用好ingress-nginx,抛开运维这块不说,对于ingress-nginx annotations掌握的好坏,决定了你在日常开发是否能使用好ingress-nginx ,因为ingress-nginx大部分能力都可以通过配置annotations实现出来。今天这篇文章主要是对ingress-nginx annotations一些常用功能做个分类,便于大家查阅。

2024-09-03 09:27:11 658

原创 聊聊如何利用ingress-nginx实现应用层容灾

容灾是一种主动的风险管理策略,旨在通过构建和维护异地的冗余系统,确保在面临灾难性事件时,关键业务能够持续运作,数据能够得到保护,从而最大限度地减少对组织运营的影响和潜在经济损失。因此容灾的重要性不言而喻,今天的话题主要是聊下如何利用ingress-nginx实现应用层容灾利用以上2种方式,就可以实现一个简易版的应用层容灾,实际上的容灾远比上述的复杂,因为可能还涉及到数据备份同步等,不过利用k8s确实能减轻我们实现层面上的一些负担。

2024-08-20 09:29:48 700

原创 聊聊项目中如何实现请求聚合

什么是请求聚合见名之意就是将多次的请求整合为一个请求处理如何实现请求聚合有个快手大佬开源了一个工具类:buffer-trigger,这玩意就可以用来做请求聚合。buffer-trigger适用场景高吞吐量消息处理: 当系统需要处理大量快速产生的数据或消息时,如日志记录、事件追踪、实时交易数据等,单条消息的即时处理可能会导致过多的系统开销(如网络通信、数据库操作等)。通过使用BufferTrigger,可以将这些消息暂时缓存在阻塞队列中,累积到一定数量后一次性进行批量处理。

2024-08-06 09:24:31 370

原创 聊聊在springcloud gateway如何获取请求体

在我们扩展scg时,获取requestbody也是一个挺常见的需求了,比如记录日志,我们要获取请求体里面的内容。在HTTP协议中,服务器接收到客户端的请求时,请求体(RequestBody)通常是以流的形式传输的。这个流在设计上是只读且不可重复读取的。即request body只能读取一次,但我们很多时候是更希望这个requestbody可以被多次读取,那我们今天就来聊下这个话题。

2024-07-30 09:18:03 1058

原创 聊聊springboot项目脱离配置中心,如何实现属性动态刷新

如果大家有开发过微服务项目,那对配置中心应该是耳熟能详了,配置中心有个很有用的能力,就是热更新属性,即不重启服务,就能做到属性的动态变更。而我们今天讲的话题是,怎么样不使用配置中心,也能达到如上的效果利用spring-cloud-context提供的API来实现一个属性热更新,还是挺容易的。但这种方式是有局限性的,比如集群环境,就涉及到属性的更新同步,其次因为变更,本质是刷新bean的内存值,这就意味着服务一旦重启,刷新的值就会恢复成初始值。

2024-07-16 09:22:03 827

原创 聊聊springboot项目如何利用jmh来进行基准测试

1、什么是JMHJMH(Java Microbenchmark Harness)是由OpenJDK团队开发的一个用于Java微基准测试工具套件,主要是基于方法层面的基准测试,精度可以达到纳秒级。它提供了一种标准、可靠且可重复的方式来衡量Java代码的性能,包括方法调用、对象创建以及其他类型的 JVM 级别的操作。JMH 通过生成优化过的字节码来确保基准测试不受常见陷阱的影响,如热身不足、垃圾回收干扰、编译器优化等,从而产生更准确的性能指标2、JMH主要使用场景精确测量方法执行时间。

2024-07-09 10:48:55 528

原创 聊聊gitlab ci如何构建以时间为版本号的docker镜像

最近朋友他们部门有部分内部项目,打算用gitlab ci来做项目持续集成部署,他们有个需求,构建docker镜像的时候,版本需要是以当前时间作为版本。其格式为yyyymmddhhmm一开始朋友翻阅官方文档,发现gitlab ci有个变量CI_COMMIT_TIMESTAMP,可以生成时间戳,他默认生成的格式是ISO-8601。就是类似2022-01-31T16:47:55Z这种,很显然和朋友他们的需求不符合。于是他就想用如下方式进行转换结果报如下错后面他调整为如下方式,即直接用date命令输出当前时间戳。

2024-07-02 09:31:41 986

原创 聊聊如何利用Testcontainers进行集成测试

1、何为Testcontainers?Testcontainers是一个库,它为引导本地开发和测试依赖关系提供了简单而轻量级的API,并将真实的服务封装在Docker容器中。使用Testcontainers,您可以编写依赖于您在生产中使用的相同服务的测试,而不需要mock或内存服务。用比较直白的话就是testcontainers 能够让你实现通过编程语言去启动Docker容器,并在程序测试结束后,自动关闭容器2、Testcontainers有哪些优势?

2024-06-11 09:27:50 1056 2

原创 聊聊如何感知项目引入哪些功能特性

使用过springcloud全家桶朋友,应该知道springcloud涉及的组件很多,为了让开发者快速了解项目引入了springcloud哪些组件,springcloud引入了HasFeatures,配合Actuator,可以让开发者感知到项目引入的组件功能类型、名称、版本以及对应的开发商。今天我们就利用这个特性,自己实现一把HasFeatures在简单的项目中,可能用处不大,但是在涉及到很多功能组件时,可以利用HasFeatures机制,让我们快速了解项目引入的功能组件,便于我们快速熟悉项目。

2024-05-28 09:25:19 903 1

原创 聊聊如何利用spring实现服务隔离

假设我们有个场景,我们需要实现服务之间的数据隔离、配置隔离、依赖的spring bean之间隔离。大家会有什么实现思路?今天给大家介绍spring-cloud-context里面有个NamedContextFactory可以达到上面的效果NamedContextFactory可以实现子容器,通过它创建子容器,然后通过NamedContextFactory.Specification可以定制子容器会用到的bean。

2024-05-21 09:21:53 919 1

原创 记一次java进程频繁挂掉问题排查修复

最近业务部门有个java服务进程会突然无缘无故的挂掉,然后这个服务会产生一堆类似hs_err_pid19287.log这样的日志。业务部门负责人就把hs_err_pidxxx的日志发给我,让我帮忙看下问题。本文就来回顾一下,我是如何帮业务部门进行问题排查执行了如上操作,业务部门观察了一段时间,没有再发现java进行频繁挂掉问题。此外不管是容器化部署还是传统的宿主机部署,当出现问题时,没头绪时,我们可以通过查看/var/log底下的各种日志进行梳理。如下链接。

2024-05-07 09:36:01 1470

原创 聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用

Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。很久之前写过一篇文章java应用线上诊断神器–Arthas里面比较详细的介绍了如何使用arthas,感兴趣的朋友可以看下。

2024-04-23 09:13:37 2097

原创 记一次使用spring事件机制失效排查修复

在日常业务开发中过程,我们有时候为了业务解耦,会利用spring的机制,就是利用spring提供的ApplicationListener、ApplicationEventMulticaster等核心API来实现。我这边列的是核心底层API接口,正常我们会用监听事件用@EventListener,发布事件用 applicationContext.publishEvent()或者applicationEventPublisher.publishEvent())

2024-04-02 11:03:33 643

原创 再聊SPI机制

去年更新了一系列和SPI相关的内容,最近因为业务需要,我又基于业务场景,实现了一版。对于什么是spi,很久之前有写过一篇文章,java之spi机制简介感兴趣的朋友可以蛮看一下核心代码@Slf4j/***/if (!/***/if (!");Class<?

2024-03-26 09:02:25 426

原创 redisson序列化采坑那些事儿

如果对springcloud-gateway有了解的同学,应该会知道springcloud-gateway默认提供了一个基于内存的路由定义仓库。基于内存的好处,就是快,但是缺点就是网关重启路由就丢失了。为了方便管理网关路由以及保证网关重启,路由不丢失,于是业务部门做了形如图的改造就是会有一个gateway的portal面板来管理路由,然后路由规则是保存在redis,gateway从redis取路由规则。

2024-03-12 10:26:05 1388

原创 记一次openfeign反序列化异常复盘

之前业务部门有2个通用响应类,一个是负责和前端交互的响应类AjaxResult,一个是负责和后端RPC接口交互的响应类RpcResult。一开始这两个响应类的值字段都一样,形如下因为前端和后端部署在不同的服务器上,某次因为前端和后端的时间不一致,导致出现业务异常,后面业务的架构师说,业务统一以后端的时间为准。于是AjaxResult新增了一个时间字段nowDateTime,而RpcResult维持不变。今天的要讲解的故事就是由此拉开序幕。

2024-03-05 10:26:13 656

原创 聊聊maven指定version区间的妙用

在我们开发微服务项目的过程中,难免会依赖各种jar,开发环境可能引用1.0.0-SNAPSHOT,而到了正式环境,则需要引用1.0.0。之前我们的做法是通过pom配置profile来达到不同环境,使用不同的版本。形如下-- 开发环境 --> < profile > < properties > < user-api.version > 1.0.0-SNAPSHOT </ user-api.version > </ properties > < activation > <!

2024-02-27 09:41:33 657

原创 记一次unable to find valid certification path to requested target异常排查

最近因为uat环境https过期,后边进行证书续期,发现通过浏览器访问可以正常访问,但是接口调用该地址,却出现网上的大部分针对java解决方案可以归类如下两种1、在jdk证书库里添加该域名的公钥证书该方案比较繁琐,此外我们的接口不仅是要提供给java系语言,还要提供给其他非java系语言调用,其次因为我们的证书并非自签发,而是真金白银买的,理论上不应该有问题。所以该方案一开始就没纳入我重点考虑范围内2、忽略证书认证,信任所有请求链接该方案其实也不可取,因为有安全隐患,不过该方案确实能解决问题。

2024-01-23 09:39:06 1919

原创 聊聊如何实现动态加载spring拦截器

之前写过一篇文章聊聊如何实现热插拔AOP,今天我们继续整一个类似的话题,聊聊如何实现spring拦截器的动态加载动态变更java的方式有很多种,比如利用ASM、ByteBuddy等操作java字节码来实现java变更,而本文则是采用groovy脚本来变更,主要是因为groovy的学习门槛很低,只要会java基本上等于会groovy。对groovy感兴趣的同学可以通过如下链接进行学习。

2024-01-16 10:46:32 945

原创 聊聊springboot项目出现同名bean异常报错如何修复

最近业务部门接手供方的项目过来二开,其中有个认证实现因为业务需要,需要替换原有供方实现的逻辑。大概伪代码如下。供方提供的接口以及默认实现形如下// doBiz业务的替换实现如下@Service然而项目运行的时候,发现走的认证逻辑始终是供方的逻辑,而非业务重写后的逻辑。平时因为跟业务的技术负责人走得比较近,他就私下找我交流一下思路。一开始我给他提的建议是说在你定制的业务类上加@Primary试下,他说他加了但没效果。

2024-01-09 09:21:04 1254

原创 聊聊如何实现热插拔AOP

之前偶然看到一篇文章利用aop实现热拔插(类似于插件),里面的实现挺好玩。今天我们也来玩一把。

2023-12-19 09:44:46 1087

原创 聊聊部署在不同K8S集群上的服务如何利用nginx-ingress进行灰度发布

之前有篇文章聊聊如何利用springcloud gateway实现简易版灰度路由,里面的主人公又有一个需求,他们有个服务是没经过网关的,而是直接通过nginx-ingress暴露出去,现在这个服务也想做灰度,他知道在同个集群如何利用nginx-ingress进行灰度发布,但是现在这个服务是部署在新的集群,他查了不少资料,都没查到他想要的答案,于是就和我交流了一下,看我这边有没有什么实现思路,今天就来聊下这个话题:不同K8S集群上的服务如何利用nginx-ingress进行灰度发布。

2023-12-05 10:24:13 194

原创 记一次请求接口出现400响应码的诡异错误实录

最近业务碰到了一个诡异的400接口请求异常,部门用户通过浏览器访问会出现400响应码错误,部分用户又能正常访问。该接口用postman请求访问,都能正常返回数据。后端写客户端请求该接口,也都能返回正常的数据。本文就来记录一下这次问题此次400响应码错误的问题,除了技术层面上,还有一些是规范上的,比如请求头加了了一堆无用的参数,其次为了方便,在token上搞了一堆业务数据,有些bug真的是无意识产生的,轻描淡写的一篇文章,可知道当时排查了2,3天,希望这篇文章能给其他小伙伴带来一些帮助或者排查思路吧。

2023-11-28 15:51:41 1319 1

原创 聊聊如何利用springcloud gateway实现简易版灰度路由

前阵子时间和朋友聊天,他们有个sass微服务,因为之前拆分过细,导致服务不仅调用链路过长,而且浪费服务资源,他们后面做了服务合并的重构,并即将上线。他觉得上线不能直接把线上的租户都全切到重构版的sass微服务,而是需要实现如下的效果他就问我说,有没有啥开源平台可以快速支持,因为之前时间都耗费在重构业务上,这块就没考虑周全,现在临近上线,预留的时间不多。后面和他细聊,得知他们这套sass服务,租户不多,其次他们微服务API网关是springcloud gateway。

2023-11-21 10:18:26 273

原创 记一次请求头header丢失问题排查实录

前端小王需要调用兄弟部门老张的后端接口,老张提供的接口,需要token鉴权才能调用成功。当小王按约定携带token调用老张的接口时,起先因为跨域问题,导致前端小王没法成功请求老张的接口。于是小王就跟老张说,能不能他那边配置下允许跨域。但小王是一个很有原则的人,他说这个接口是要给N个部门调用的,不可能给这些调用部门都配置允许跨域,不然口子一旦开了,后面就没完没了,他让小王自己想办法解决跨域。后面小王就把事情向上反馈,小王的领导就跟小王说,我们自己搭个反向代理,通过反向代理解决跨域问题。

2023-11-14 09:35:40 705

空空如也

空空如也

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

TA关注的人

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