自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

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

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

2024-04-02 11:31:38 649

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

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

2024-04-02 11:21:52 1068

原创 MySQL表设计军规18条

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

2024-04-02 11:15:39 124

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

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

2024-03-29 17:06:12 218

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

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

2024-03-12 10:19:17 123

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

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

2024-03-05 11:00:55 51

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

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

2024-03-04 09:50:39 695

原创 OpenFeign核心原理

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

2024-02-29 18:09:22 69

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

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

2024-02-28 13:30:19 879

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

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

2024-02-27 13:47:50 210

原创 MySQL的21个SQL经验

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

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

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

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

2024-02-26 14:47:36 76

原创 Spring Boot 的参数校验方案

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

2024-02-23 11:42:35 627

原创 什么情况会发生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 249

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

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

2024-02-23 11:30:48 261

原创 SpringBoot实现缓存预热方案

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

2024-02-23 11:22:29 863

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

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

2024-02-23 11:10:02 95

原创 Redis实现滑动窗口限流

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

2024-02-23 10:55:08 1586

原创 ThreadLocal原理解读

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

2024-02-23 10:44:31 578

原创 Redis主从复制原理

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

2024-02-23 10:19:27 735

原创 11个高可用方案

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

2024-02-23 10:15:31 807

原创 Spring 系列之 Spring Framework 中的 Bean

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

2024-02-23 10:10:51 40

原创 Java8 的 LocalDateTime使用

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

2024-02-22 15:25:22 778

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

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

2024-02-22 10:22:02 29

原创 虚拟机的内存结构

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

2024-02-21 16:29:37 69

原创 xxl-job架构原理讲解

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

2024-02-21 16:09:22 2406

原创 灵活的数据权限思路

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

2024-02-20 11:15:12 896

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

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

2024-02-20 09:58:58 53

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

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

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

原创 异步神器CompletableFuture

CompletableFuture在JDK1.8提供了一种更加强大的异步编程的api。它实现了Future接口,也就是Future的功能特性CompletableFuture也有;除此之外,它也实现了CompletionStage接口,CompletionStage接口定义了任务编排的方法,执行某一阶段,可以向下执行后续阶段。

2024-02-19 13:27:31 627

原创 Feign 第一次调用为什么会很慢?

首先要了解 Feign 是如何进行远程调用的,这里面包括,注册中心、负载均衡、FeignClient 之间的关系,微服务通过不论是 eureka、nacos 也好注册到服务端,Feign 是靠 Ribbon 做负载的,而 Ribbon 需要拿到注册中心的服务列表,将服务进行负载缓存到本地,然后 FeignClient 客户端在进行调用,大概就是这么一个过程。WeightedResponseTimeRule(权重比策略,优先选择权重比高的服务,也就是服务响应时间比较短的,响应时间越长权重比越低)

2024-02-19 11:39:28 437

原创 抛弃for循环遍历list

map:映射,他将原集合映射成为新的集合,在VO、PO处理的过程中较常见。在本例子中,原集合就是PO集合,新集合可以自定义映射为成绩集合,同时也可以对新集合进行相关操作。parallelStream:并行流,可以利用多线程进行流的操作,提升效率。除了forEach操作会改变原集合的数据,其他的操作均不会改变原集合,这点务必引起注意。filter:过滤,就是过滤器,符合条件的通过,不符合条件的过滤掉。statistics:统计,可以统计中位数,平均值,最大最小值。

2024-02-19 11:32:32 2670

原创 MySQL 8.x版本报错问题分析和解决,which is not functionally dependent on columns in GROUP BY clause;

由上面官网介绍得知,要么修改sql语句将未进行group by 的列,使用any_value() 处理;因此,继续分析原因,由于我们应用采用数据库连接池,在我们应用未重启的情况下,连接池中的连接仍然是之前建立的连接,因此将应用进行重启后,问题得到解决。我们首先通过在服务器安装MySQL客户端通过mysql 命令行登陆后,验证sql是否正常执行,经过验证是OK的。最近项目中上了新功能,同时做了数据库的备库方案,但是当应用访问备库时,出现部分分组sql查询报错。这样上面的报错问题正常应该得到解决。

2024-01-31 15:48:16 339

原创 SpringBoot 结合 liteflow 规则引擎使用

在日常的开发过程中,经常会遇到一些串行或者并行的业务流程问题,而业务之间不必存在相关性。在这样的场景下,使用策略和模板模式的结合可以很好的解决这个问题,但是使用编码的方式会使得文件太多,在业务的部分环节可以这样操作,在项目角度就无法一眼洞穿其中的环节和逻辑。在本文中,将引入规则引擎从全局角度来解决这个问题,这就是今天要介绍的主角liteflow。

2024-01-30 18:02:25 917

原创 接口防刷方案

本文为描述通过Interceptor以及Redis实现接口访问防刷Demo咋说呢就是通过自定义注解中定义 x 秒内 y 次访问次数,禁用时长为 z 秒自定义注解 + 在需要进行防刷处理的各个接口方法上在拦截器中通过反射获取到各个接口中的x, y, z值即可达到我们想要的接口自由目的下面做个实现声明自定义注解Controlller中方法中使用Interceptor处逻辑修改(最重要是通过反射判断此接口是否需要进行防刷处理,以及获取到x, y, z的值)/**

2024-01-16 17:35:31 869

原创 过滤器Filter和拦截器Interceptor

这是因为我们在注册过滤器Filter的时候,使用的是new LoginAuthFilter的方式,过滤器是Servlet规范的一部分,而不是Spring框架的组件,需要通过new 关键字创建实例。但是如果你的注册过滤器的类LoginAuthConfig中,还是通过new LoginAuthFilter方法而不是@Autowired注入LoginAuthFilter,你会发现在拦截请求进入LoginAuthFilter中的时候,testServiceImp的bean还是为null。这是我产生的第二个疑问。

2024-01-16 09:35:21 751

原创 并发编程的12条规范

SimpleDateFormat 是线程不安全的类,因为它内部维护了一个 Calendar 实例,而 Calendar 不是线程安全的。因此,在多线程环境下,如果多个线程共享一个 SimpleDateFormat 实例,可能会导致并发问题。如果需要在多线程环境下使用,可以通过加锁的方式来确保线程安全。try {// 启动多个线程来同时解析日期i < 5;i++) {

2024-01-15 15:36:49 897

原创 是否还在 Docker 中跑 MySQL?

容器的定义:容器是为了解决“在切换运行环境时,如何保证软件能够正常运行”这一问题。认真分析大家的各种观点,发现赞同者仅仅是从容器优势的角度来阐述 MySQL 需要容器化,几乎没有什么业务场景进行验证自己的观点;反过来再看反对者,他们从性能、数据安全等多个因素进行阐述 MySQL不需要容器化,也举证了一些不适合的业务场景。下面,我们就聊一下 Docker 不适合跑 MySQL 的 N 个原因!不要将数据储存在容器中,这也是 Docker 官方容器使用技巧中的一条。容器随时可以停止、或者删除。

2024-01-03 17:45:06 525

原创 微信防止重复支付方案

支付的话,一般是走支付网关(支付中心),然后支付中心与第三方支付渠道(微信、支付宝、银联)交互。支付成功以后,异步通知支付中心,支付中心更新自身支付订单状态,再通知业务应用,各业务再更新各自订单状态。这个过程中经常可能遇到的问题是掉单,无论是超时未收到回调通知也好,还是程序自身报错也好。总之由于各种各样的原因,没有如期收到通知并正确的处理后续逻辑等等,都会造成用户支付成功了,但是服务端这边订单状态没更新。这个时候有可能产生投诉,或者用户重复支付。

2024-01-03 17:39:59 621

原创 Nacos、OpenFeign、Ribbon、loadbalancer组件工作的原理

到这,就把Nacos、OpenFeign、Ribbon、loadbalancer等组件协调工作的原理讲完了,其实就是各个组件会预留一些扩展接口,这也是很多开源框架都会干的事,当第三方框架去适配的,只要实现这些接口就可以了。最后画一张图来总结一下上述组价的工作的原理。

2024-01-02 09:56:35 1199

空空如也

空空如也

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

TA关注的人

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