自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(25)
  • 资源 (1)
  • 收藏
  • 关注

原创 事务隔离级别MVCC实现与悲观锁乐观锁

目录四种事务的隔离级数据库默认隔离级别为什么要使用悲观锁和乐观锁悲观锁乐观锁事务的隔离级(Isolation Level),就是在数据库事务中,为保证并发数据读写的正确性。四种事务的隔离级串行读 >可重复读 >已提交读 >未提交读1、未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少2、已提交读(Read Committed...

2020-12-29 11:37:15 273

原创 Kubernetes——k8s中的概念理解

Kubernetes是一个可以移植、可扩展的开源平台,使用声明式的配置并依据配置信息自动地执行容器化应用程序的管理。在所有的容器编排工具中(类似的还有 docker swarm / mesos等),Kubernetes的生态系统更大、增长更快,有更多的支持、服务和工具可供用户选择。容器组-PodPod(容器组)是 Kubernetes 中最小的可部署单元。一个 Pod(容器组)包含了一个应用程序容器(某些情况下是多个容器)、存储资源、一个唯一的网络 IP 地址、以及一些确定容器该如何运行的选项。..

2020-12-31 16:18:53 239

原创 分布式解决方案Seata中间件安装使用

Seata 是一个需独立部署的中间件,所以先搭 Seata Server,下载地址:https://github.com/seata/seata/releases/download/v1.4.0/seata-server-1.4.0.tar.gz解压后,到 /seata/conf/ 下面的步骤修改相关配置文件修改事务日志和注册中心等配置file.conffile.conf 文件用于配置持久化事务日志的模式,目前提供 file、db、redis 三种方式。默认是file,修改文件选择 db

2020-12-30 15:19:54 182

原创 MybatisPlus乐观锁插件使用(拦截器)

从拦截器代码看得出与之前文章写的实现思路一样,拦截器会在更新操作时以查询时查到的version值为条件,并设置新的version值为version+1,这样一来如果version值存在即没有被修改就可以更新成功。 public Object intercept(Invocation invocation) throws Throwable { Object[] args = invocation.getArgs(); MappedStatement ms = (Mapp

2020-12-29 15:43:03 810

原创 多线程下集合类的选用

ArrayList,HashMap都是非线程安全的类,因此在多线程中不能使用。那么多线程下如果要使用集合或map类型怎么办呢?当然是有别的替代类,比如HashMap要选用HashTable或ConcurrentHashMap,而ArrayList则要选用Vector或CopyOnWriteArrayList。HashTable和ConcurrentHashMap两者的区别就是HashTable是完全基于synchronized锁实现的同步,而ConcurrentHashMap则是CAS+vola

2020-12-28 17:13:46 595

原创 Redis使用之PipeLine

redis的处理速度是微秒级别,而网络传输的速度是毫秒级别,远远慢于redis的处理速度。所以在使用redis时,网络速度会成为redis的一个瓶颈,节省网络传输的时间得到的收益会远高于节省命令执行时间的收益。所以对于批量操作,redis总提供了mset,mget这样的命令。今天要写得是pipeline管道操作,可以把多个命令操作打包成一个pipeline一起发送执行,redis处理完后打包结果返回。mget和pipeline不同之处:M操作是原子性的,而pipeline不是原子性的,执行时会把命令

2020-12-28 15:02:46 1054

原创 RabbitMQ的confirm、ack、transaction三个概念的理解

目录ACK (consumer acknowledgemenet)confirm (Publisher confirm)事务(transaction)使用MQ中间件时,保证消息准确发送和消费以及幂等性等问题是我们都需要考虑的。解决这些问题需要先来理解三个概念。在RabbitMQ的确认有两种,其中一个consumer acknowledgement简称为ACK,另一个叫publisher confirm这里我们简称为confirm。ACK (consumer acknowledgeme

2020-12-24 15:42:16 2181

原创 RabbitMQ确保消息准确发送的实现方案——事务或Confirm机制

前面写了手动ack的方式保证消息准确消费。那么对于生产者来说怎么来保证消息准确的发送呢?在RabbitMQ中确认并且保证消息被送达有两种方式:事务和confirm确认。需要注意的是两者不能同时使用。官方文章中这样说:处于 transactional 模式的 channel 不能再被设置成 confirm 模式,反之亦然。事务事务方式的性能是比较差的,牺牲了性能换取准确性,或许正因为这样才有了第二种confirm机制。...

2020-12-24 15:40:41 426

原创 RabbitMQ使用手动ACK签收保证消息成功消费

RabbitMQ默认acknowledge-mode为auto即自动ack模式,只要有消费者接受消息,无论消费是否成功MQ都认为消费成功。网络原因和消费者自身程序原因都有可能导致这条消息没有被正确消费处理,手动Ack的方式就可以较为严格的保证消息终被成功消费。YML配置开启手动Ack模式spring: rabbitmq: host: 127.0.0.1 port: 5672 username: guest password: guest listener

2020-12-24 10:58:48 2030

原创 浅谈Seata分布式事务管理实现原理

前面写了常见的分布式解决方案介绍。这篇文章要写的seata是阿里的分布式解决方案中间件。Seata与2PC的区别相对于2pc,seata有独立的事务管理,整体实现也分两阶段,可以看做是2pc的演变。而两种方案最大区别就是Seata支持AT,即异步事务的实现。在2PC中,第一阶段开始事务操作就会锁定资源,直到二次提交完成后释放资源,在整个过程中对于每个分支事务来说资源锁定时间都依赖其他的分支事务。而在Seata中,每一个分支事务的提交操作都可以在第一阶段自主完成,降低了锁范围提高效率。而第.

2020-12-23 16:26:36 1004

原创 分布式事务方案对比

单体应用架构向微服务的演变随之带来的分布式事务这样的问题。分布式事务其实是要对多个微服务本地事务进行管理实现一致性。实现分布式事务的方案比较多,常见的比如基于 XA 协议的 2PC和改进后的3PC,还有基于业务层的 TCC,基于事务消息 + 消息表实现的最终一致性方案,再有就是阿里的Seata中间件,下边看看各个方案的优缺点。2PC(Prepare +Commit )过程原理两段提交:第一阶段,准备阶段(Prepare phase)(投票阶段) ;第二阶段,提交阶段(commit phase

2020-12-23 15:29:08 354 1

原创 RocketMQ单机版安装启动

RocketMQ前身叫做MetaQ,在MeataQ发布3.0版本的时候改名为RocketMQ,使用Java进行开发。这篇文章不做过多介绍,主要记录安装过程步骤下载地址 https://rocketmq.apache.org/docs/quick-start/ 可以下载二进制直接使用,也可以下载源码使用maven进行自行编译后使用。RocketMQ服务端安装启动源代码编译安装编译需要maven环境unzip rocketmq-all-4.5.1-source-release.zip .

2020-12-22 15:32:39 382

原创 SpringBoot+RabbitMQ基于死信队列模型实现延迟消息

DLX(Dead Letter Exchange),死信交换器。当队列中的消息被拒绝、或者过期会变成死信,死信可以被重新发布到另一个交换器,这个交换器就是DLX,与DLX绑定的队列称为死信队列。队列中的消息在以下三种情况下会变成死信 (1)消息被拒绝(basic.reject 或者 basic.nack),并且requeue=false; (2)消息的过期时间到期了; (3)队列长度限制超过了。 当队列中的消息成为死信以后,如果队列设置了DLX那么消息会被发送到DLX。通过x-dead-letter-e

2020-12-18 18:06:13 284 1

原创 Spring中@Enable功能开关注解的实现

目录@Import注解驱动实现(@Import+@Configuration)接口驱动实现(@Import+自定义ImportSelector接口实例)自定义功能开关注解经常会用到Spring项目中@EnableXXX这种注解,都是用来启用某种功能,这种注解类似于一种开关,加了这个注解,就能使用某些功能。例如@EnableAsync、@EnableScheduling 等注解。Srping实现Enable模块驱动的方法大致分为两类,一种是注解驱动实现配置,另一种是接口驱动实现配置..

2020-12-18 11:19:10 1929

原创 initializingbean接口的用途

initializingbean接口只有一个afterPropertiesSet方法,实现了这个接口的类在初始化Bean时会执行这个方法。所以这个接口的用途就是用来实现初始化数据用的。public interface InitializingBean { void afterPropertiesSet() throws Exception;}那么就有一个疑问。static块不好用么干嘛还要多实现一个接口呢?static只能对当前类中的静态成员进行操作,加入类成员变量不能是静态的呢?

2020-12-17 18:09:03 719

原创 TaskDecorator——异步多线程中传递上下文等变量

目录TaskDecorator定义TaskDecorator实例线程池使用TaskDecorator开发中很多数据如oauth2的认证信息,日志TracerId都是在请求线程中的,如果内部使用多线程处理就存在获取不到认证信息或TraceId的问题。这时候就需要处理子线程与主线程间数据传递的问题。TaskDecorator这个问题需要使用线程的ThreadLocal和TaskDecorator来处理。官方文档中描述意思是TaskDecorator是一个执行回调方法的装饰器,主要应用于传

2020-12-17 11:38:26 15855 9

原创 基于@EnableAsync使用线程池实现多线程

相对于传统编码的方式使用多线程,在SpringBoot中提供了基于注解的更简单的实现方式:基于@EnableAsync和@Async注解配置:项目使用@EnableAsync开启异步,使用@Async 注解在service内的方法上,这样在controller层直接调用service方法时,可以实现@Async注解的方法在单独线程内运行,实现controller层调用service后即时返回,service方法异步处理的效果。一般会在@Async上注明使用的线程池。@Async 注解的方法要么就

2020-12-16 18:17:45 1131 1

原创 AtomicInteger线程安全(volatile和CAS)

volatilevolatile可以实现变量的可见性,即取值操作是线程安全的,但是变量本身在多线程的情况下仍然不是线程安全的,例如volatile int i;i++;CASCAS英文解释是比较和交换,是cpu底层的源语,是解决共享变量原子性实现方案,它定义了三个变量,内存地址值对应V,期待值E和要修改的值U.在Java中通过调用UnSafe的compareAndSet类似方式调用,底层是c,反编译后操作系统指令是cmpxchg指令。CAS操作经常被用来实现无锁数据结构。在java

2020-12-16 15:59:44 961

原创 SpringBoot动态数据源的使用

AbstractRoutingDataSourcespring中提供了一个抽象类AbstractRoutingDataSource类,通过这个类可以实现动态数据源切换,分析下这个类的代码片段。public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean { @Nullable private Map<Object, Object> targ

2020-12-15 17:09:53 461

原创 Security启用@EnableGlobalMethodSecurity实现API接口权限校验

基于token的校验方式通常是作用于一个服务或应用范围,在一个应用内继续进行更细粒度的权限校验控制,就是实现用户对某个接口的调用权限控制。@EnableGlobalMethodSecuritySecurity应用中的@Configuration实例上添加@EnableGlobalMethodSecurity 注解开启注解权限控制功能。@EnableGlobalMethodSecurity(prePostEnabled = true)其实这个注解为我们提供了prePostEnabled 、s

2020-12-14 16:13:18 576

原创 Mybatis游标Cursor查询

通常对一张表中大量数据处理时由于数据量太大都要使用分页分批查询处理,否则数据量太大会导致OOM等问题。Cursor查询适用于这种场景下可以替代分页查询的方案,Cursor实现了Closeable和Iterable接口,我们可以通过迭代器来获取数据进行处理。public interface Cursor<T> extends Closeable, Iterable<T> { boolean isOpen();//用于在取数据之前判断 Cursor 对象是否是打开状态。

2020-12-14 14:22:48 12111

原创 Spring Security OAuth2.0自定义资源服务核心配置——ResourceServer

目录ResourceServerConfigurerResourceServerConfigurerAdapter插曲:WebSecurityConfigurerAdapter和ResourceServerConfigurerAdapter对比实现ResourceServerConfigurerAdapter类重写方法自定义资源配置上一篇写了授权服务器的配置,在Spring Security OAuth2.0可以把授权服务器(AuthorizationServer)和资源服务器(Reso

2020-12-10 11:45:32 2621

原创 登录中的图片验证码功能实现

添加kaptcha依赖<dependency> <groupId>com.github.axet</groupId> <artifactId>kaptcha</artifactId> <version>0.0.9</version></dependency>自定义配置kaptcha的Producer@Configurationpublic class KaptchaConfig {

2020-12-09 08:44:09 538

原创 Spring Security OAuth2.0自定义授权服务核心配置——AuthorizationServer

AuthorizationServer是security oauth2的核心配置接口,通过这个接口我们可以自定义配置认证流程中使用哪些组件和一些访问权限设置。从UML图分析,AuthorizationServerConfigurerAdapter这个类是框架中提供的AuthorizationServer接口实现类。提供了三个方法,但是没有具体的实现。所以要配置AuthorizationServer时可以直接继承AuthorizationServerConfigurerAdapter这个类,重写三个方法,

2020-12-07 17:40:44 2331 1

原创 递归查询——目录树

逻辑首先遍历目录集合找出getParentId=-1的根目录,然后遍历父目录,设置子目录。获取子目录的这个方法时递归方法:遍历所有目录的getParentId与当前父目录id对比,一致则为该目录的子目录,放入subMenus。等到一层子目录归纳完成后,再遍历subMenus对新的子目录执行递归调用。递归条件如果存在子目录,就再按上面的逻辑查询子目录下的子目录;如果没有子目录了,就返回。public static List<CusMenu> builderTree(L..

2020-12-03 18:01:58 549

win系统erlang安装包

对应rabbitmq-3.8.9版本

2020-12-21

空空如也

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

TA关注的人

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