- 博客(55)
- 收藏
- 关注
原创 spring中父子线程共享事务
父子线程中事务共享的原理就是要让一个数据库连接在父子线程中同时使用原生jdbc中, 将数据库连接直接从父线程传递到子线程即可jdbcTemplate的使用中, 只需将同一个数据库连接同时绑定到父子线程中接口, 使用在spring中使用开启手动事务, 除了第三点的需要将数据库连接同时在父线程中绑定和在子线程中绑定之外, 还需要将事务的相关信息绑定到子线程(详细见文章内部)在spring中使用不管是配合还是调用使用声明式原理都是一样的, 都是得从在子线程中绑定父线程中的相同的事务信息和连接信息。
2025-04-25 03:20:06
618
原创 13、认识redis的集群模式(下)
在上一篇文章认识redis的cluster(1)中介绍了Redis Cluster 中两个节点之间握手的核心流程,这也是搭建 Redis Cluster 的第一步让各个 Cluster 节点之间感知到彼此的存在。我们知道, Redis Cluster中每个Master节点至少会有一个Slave节点, 所以设置 Redis Cluster 中每个节点的主从角色就是启动 Redis Cluster第二步要做的事情。
2025-04-23 11:37:13
1011
原创 12、认识redis的集群模式(上)
Redis Cluster 内部按照 slot 对数据进行切分的,每个 Master 节点只负责维护一部分 slot 以及落到这些 slot 上的 KV 数据,但是 Redis Cluster 中每个节点都有全量的 slot 信息,这样的话,客户端无论连接到哪个节点,都可以知道自己访问的 Key 落到哪个 slot 里面以及这个 slot 位于哪个节点中。继续上面的示例,在节点 A 处理完节点 B 返回的 PONG 消息之后,就已经可以正确感知到节点 B 了,并且明确知晓自己与节点 B 之间网络连接。
2025-04-23 11:34:10
854
原创 11、认识redis的sentinel
Sentinel 是 Redis 提供的高可用解决方案之一。一个 Sentinel 服务进程其实本身就是 Redis 实例,只不过这个 Redis 服务实例是以 Sentinel 模式运行的,它不对外提供读写键值对的服务,而是监控其他 Redis 服务实例是否运行正常,有点类似现实生活中监工的感觉。为了防止 Sentinel 本身出现单点问题,一般会将多个 Sentinel 实例组成一个 Sentinel 集群,一般推荐 Sentinel 集群的实例个数为奇数。
2025-04-23 11:28:27
899
原创 10、认识redis的主从复制
Redis 中的主从复制协议有多次升级,所以这里我们从 2.8 版本开始一步步介绍 Redis 主从复制协议的升级和优化过程。在 Redis 2.8 版本之前,主从复制的核心流程如下:这里简单描述一下上图的流程。首先,在从库启动之后,会根据配置主动请求主库,建立网络连接。连接完成之后,从库会向主库发送 SYNC 命令,发起数据同步的请求。
2025-04-22 14:59:28
1322
原创 9、认识redis key的过期和内存淘汰
Redis 最常见的应用场景就是缓存,我们在使用缓存的时候,一般不会存储 DB 里面全量的数据,而只用于缓存一部分 DB 热点数据,对于非热点数据,需要进行定期删除,防止 Redis 内存被撑爆,也就是我们常说“在 Redis 3.0 中,近似 LRU 算法进行了一次升级,引入了一个维护淘汰 Key 的候选池,这样可以提高筛选 Key 的精准度,使得近似 LRU 算法的效果更加接近于真正的 LRU 算法。:Redis 会按照近似 LRU 的算法,从设置了过期时间的 Key 中,选取 Key 进行淘汰。
2025-04-22 14:40:59
992
原创 8、认识redis的aof
RDB 是一个类似于快照的持久化方式,它会一次性将 Redis 内存中的全部数据写入到 RDB 文件中。AOF(Append Only File)持久化则是类似于增量的持久化,其核心思路是将 Redis 执行过的每条修改命令都保存到 AOF 文件中,从而实现持久化效果。当故障恢复的时候,Redis 可以根据 AOF 文件回放曾经执行过的每一条命令,这样的话,Redis 中的数据也就恢复到故障前的状态了。在实际生产环境中,一般会使用AOF + RDB。
2025-04-22 14:37:44
998
原创 7、认识redis的rdb
RDB全称是 Redis DatabaseRDB 持久化就像是。Redis 在重启时,可以通过加载 RDB 文件快速恢复 Redis 内存数据,但是需要说明的是,由于 RDB 持久化的快照特性,Redis 会丢失最后一次 RDB 文件到重启之间的数据,如下图所示,蓝色部分的数据在 RDB 持久化的时候已经被保存下来了,但是红色部分的数据,会因为宕机而丢失。所以需要后面介绍的另一种持久化方式,也就是。
2025-04-22 14:21:58
926
原创 6、认识redis的stream
redis 从 5.0 版本开始支持提供 stream 数据类型,它可以用来保存消息数据,进而能帮助我们实现一个带有消息读写基本功能的消息队列,并用于日常的分布式程序通信当中。其中,为了节省内存空间,在 stream 数据类型的底层数据结构中,采用了radix tree和listpack两种数据结构来保存消息。listpack 是一个紧凑型列表,在保存数据时会非常节省内存;radix tree,这个数据结构的最大特点是适合保存具有相同前缀的数据,从而实现节省内存空间的目标,以及支持范围查询。
2025-04-21 11:38:30
802
原创 5、认识redis的zset集合
Zset,即有序集合(Sorted Set),是 Redis 提供的一种复杂数据类型。Zset 是 set 的升级版,它在 set 的基础上增加了一个权重参数 double类型的分数值(即score),使得集合中的元素能够按 score 进行有序排列。zset的listpack结构当满足以下两个条件时, zset采用listpack结构存储数据存储结构如下两个条目为一组, 分别存储实际值和score, 同时listpack也支持查询步长+1的跨越条目查询, listpack本身是无序的,但默认最多只会存储
2025-04-21 11:21:55
1042
原创 4、认识redis的set集合
在 Java 里面,HashSet 底层是用 HashMap 实现的。在 Redis 里面也是类似的,Redis 里面的 Hash 底层结构是 dict,Set 底层的结构也是 dict。但是,在元素都是整数值的时候,Set 可以用一种更省空间的方式来存数据,这种省空间的方式就是这一节要说的 intset。元素都是整数类型这个 Set 里面的元素个数,要少于配置指定的这个值,这个值默认是 512一旦这个 Set 集合不满足这两个条件,就会切换成 dict 作为底层存储。
2025-04-21 11:19:13
632
原创 3、认识redis的hash
dict使用key-value形式存储数据结构, hash使用的hashDictType只能存储字符串(sds结构)redis的hash集合在7.0版本之前value使用的是ziplist和dict存储数据,在7.0及以后就是listpack+dict结构默认ziplist(listpack)单个元素大于64字节或者hash中元素大于512个会转为dictdict使用两个数组来完成存储和rehash动作, 采用头插法转移数据。
2025-04-21 11:15:05
1052
原创 2、认识redis的list
quicklist 是一个类似于 Java 里面 LinkedList 的双向链表,大概结构如下图所示:quicklist 里面的节点是 quicklistNode 类型,quicklistNode 里面维护了 next、prev 指针,指向前后两个 quicklistNode 节点;然后还有一个 entry 指针,指向了一个 listpack 实例。真正的元素是存储在这个 listpack 里面的,那就是说,多个元素存储在一个 quicklistNode 里面。
2025-04-21 11:05:57
509
原创 1、认识redis的string
前面介绍了string的结构类型, 那么Redis 为什么不用 C 语言的字符串,而非要自己搞一个出来呢?第一个原因是“安全的二进制存储”,在有的场景里面,我们在字符串里可能需要存\0这种特殊字符。比如说,\0这种数据,如下:如果直接用 C 语言字符串的话,\0表示字符串结尾,那我就会认为是到 Hello 字符串就完了,对不对?为了要存\0这种特殊字符,sds 就不再把\0当作字符串的结尾,而是明确地记录字符串的长度,比如说存个 length 字段,我就知道到第一个\0的时候,字符串还没结束。
2025-04-21 10:53:46
747
原创 8.spring对logback的支持
本节以logback为背景介绍的spring自动装配了监听器, 监听ApplicationEvent事件, 在springboot启动周期中对日志做了一些扩展在springboot启动初期(ApplicationStartingEvent事件), 实例化了对象在环境准备完成后(ApplicationEnvironmentPreparedEvent事件), 对logback容器做了初始化并启动springboot对日志slf4j的实现默认顺序为, 确保其中有。
2025-02-24 11:32:16
825
原创 7.encoder与layout以及convert
上一篇文章介绍过, 在中可以注入Encoder和layoutLayout 主要用于格式化日志文本(如 PatternLayout),适用于控制台日志输出。Encoder 负责将日志编码(通常是字符或二进制),适用于文件、远程日志等场景。下面是对Encoder和layout的注入方法可以看出设置的layout实际也是被包装到endoer中了(LayoutWrappingEncoder), 整体看也就是只需一个encoder就行了。
2025-02-20 20:11:38
1045
原创 6.appender
前一篇文章介绍了appender、conversionRule、root和logger节点的解析, 为的是为本篇详细介绍它们的原理做铺垫, 日志打印也是主要围绕这几个对象开展的appender主要分为UnsynchronizedAppenderBase和AppenderBase两大类, 前一种代表了异步添加日志, 后一种代表了同步添加日志, 一般我们使用的是UnsynchronizedAppenderBase, 效率更高, 同一个线程中日志还是有序的。appender可以通过<filter>
2025-02-11 22:21:46
1025
原创 5.modelHandler处理model
前面的文章主要介绍了logback将logback.xml中的节点路径解析成一个个的model,最后在DefaultProcessor中使用modelHandler对model进行处理,本节将介绍几个常用标签节点的modelHandler解析的详细过程本节就介绍了几个核心日志节点的modelHandler,下一节讲重点介绍下appender和logger(root)相关的标签configuration标签是logback.xml配置文件的顶层标签,支持四个属性,如下。
2025-01-20 11:54:34
657
原创 4.JoranConfigurator解析logbak.xml
上一篇介绍了logback模块解析logback.mxl文件的入口,我们可以手动指定logback.xml文件的位置,也可以使用其它的名字,本节我们继续讨论logback是如何解析logback.xml文件的。JoranConfigurator是logback框架用来解析配置文件的核心类(logback.xml配置文件)logback.xml文件中每个节点都会被解析成一个saxEvent,解析过程中借助解析器上下文SaxEventInterpretationContext保存相关信息。
2025-01-19 18:47:41
1263
原创 3.解析logback.xml配置文件入口
前面介绍了slf4j相关的知识点,提到了实现模块是通过进行自定义日志框架的,本节就来介绍logback的默认的日志上下文是loggerContext使用spi获取到进行初始化,如果存在(默认不存在),并且执行后的返回值为则解析完成使用默认的进行初始化,其中比较核心,是logback用来解析logback.xml的配置类,解析成功后会返回,直接终端后面的配置类解析;默认的三个配置类如下可以通过环境参数。
2025-01-18 15:54:12
1041
原创 2.slf4j入口
slf4j提供了操作日志的门面日志初始化入口实可以通过-Dslf4j.provider=SLF4JServiceProvider的类全路径来指定日志最终使用的slf4j实现通过spi加载了对象初始化后,通过它得到具体的Logger对象。
2025-01-16 11:45:01
995
原创 1.认识slf4j
slf4j官网:https://www.slf4j.org/slf4jgithub地址:https://github.com/qos-ch/slf4jlogback官网文档:https://logback.qos.ch/manual/introduction.htmllogback项目地址:https://github.com/qos-ch/logback。
2025-01-15 22:44:54
927
原创 19.springcloud_openfeign之案例
前面已经介绍完了feign的基本功能以及springcloud_openfeign的扩展功能, 本节我们将介绍springcloud_openfeign的使用案例feign框架本身较为简单, 但是扩展点是非常多的, 使用者可以几乎对每一个功能点做定制化;利用springcloud的父子容器特性将每个feign接口(客户端)隔离成单独的子容器,有点类似类加载器的隔离;这里不同于spring的作用域的隔离机制写通用并且扩展性强的代码是非常重要的, 同时也需要一定的技术功底。
2024-12-30 00:00:16
865
原创 18.springcloud_openfeign之扩展组件二
通过前面的学习, 我们知道了springcloud_openfeign的注解, 使用@Import注解引入了对象, FeignClientsRegistrar是个类型的对象在registerBeanDefinitions方法中会将和封装成注入到容器中自动装配引入了类, 它将注入到容器中的注入到了创建的对象中, 而FeignClientFactory是springcloud的父子容器工厂, 它会将注入的对象按照容器名称添加到不容的子容器中(**dafult.**开头的会注册到所有子容器中),并且会将。
2024-12-27 15:14:57
1216
原创 17.springcloud_openfeign之扩展组件一
前面介绍了springcloud_openfeign可以从父子容器中获取对应的组件从而构建对象, 现在的企业级开发中, 一般我们都使用的springboot, 而springboot是约定大于配置的, 那么它提供的一套默认配置是什么呢, 本节我们就来认识一下。约定大于配置(Convention Over Configuration) 是 Spring Boot 的核心设计理念之一,它的主要目的是减少开发者的配置负担,让开发者专注于业务逻辑的实现,而非繁杂的配置。基本含义约定大于配置(Convention O
2024-12-20 00:14:30
861
原创 16.springcloud_openfeign之父子容器
在前面springcloud_openfeign的文章中了解到在扫描到满足条件的feign接口后会生成并注入到spring上下文容器, 并且在中构建时会从父子容器中获取相关的组件设置给它, 那么注入到容器中时怎么选择容器, 以及使用时是怎么从容器中获取的呢??, 本节我们就来了解一下springcloud中的父子容器, 以及springcloud_openfeign是怎么使用父子容器的。spring的容器基对象默认支持父子容器结构, 通过getParent方法获取父容器对象。在它的一级抽象实现类。
2024-12-17 00:44:54
944
原创 15.springcloud_openfeign之FeignClientFactoryBean
在上一篇中我们介绍了通过注解扫描并注册每个标识的接口对应的到spring容器中, 本节我们来了解一下这个类的具体内容。本节主要介绍了springcloud_openfeign如何根据注解和以及父子容器来构建Feign.Builder对象, 并处理Target需要的url, 最后通过Feign.Builder#target构建feign接口的代理对象。本文没有具体介绍其中父子容器的相关细节, 以及配置的一些具体内容, 这些将会在后面的文章中介绍到通过@Import注解给spring容器注入了。
2024-12-13 01:38:01
744
原创 14.springcloud_openfeign之注入FeignClientFactoryBean到spring
在目前这个spring大行其道的环境下, 一个优秀的框架除了本身质量过硬之外, 都会向spring靠拢, 要不就是spring纳入麾下主动集成, 要不就是自己实现和spring的整合, feign框架就是spring主动集成的。框架地址版本约定。
2024-12-10 03:45:02
1239
原创 12.异步请求AsynchronousMethodHandler
feign异步请求有单独的入口类AsyncFeign, 它使用重写了实际请求, 处理响应等部分使用者自定义线程池替换默认的feign的异步模块基本上全部由实现的, 大家可以多花点时间去了解一下juc下这个使用频次很高的工具类。
2024-12-02 23:54:38
852
原创 11.feign对logger的支持
优秀的框架少不了在关键部位打印一些日志供使用人员排查问题。feign框架在执行请求前后都埋点了打印日志的代码, 当用户设置不同的日志等级会打印不同阶段的日志, 同时允许使用者自定义日志级别和日志框架;feign默认的日志实现是NoOpLogger, 也就是不打印日志feign默认的日志级别是, 也就是不打印日志feign框架默认自定义了一套日志等级, 分以下几个级别NONE, 不打印日志BASIC, 记录请求方法、URL、响应状态码和执行时间HEADERS。
2024-12-02 11:14:17
716
原创 10.请求拦截和响应拦截
优秀的设计总是少不了丰富的扩展点, 比如spring可以自动装配, aop扩展, web模块也有拦截器, 甚至对servlet的过滤器都有封装;再比如netty、doubbo等等都支持在数据流入流出都允许用户自定义扩展点实现定制化处理, 咱们的feign框架也同样如此, 在可以定制化组件的同时, 也允许我们对发起请求之前和接受请求之后根据扩展点实现个性化的处理。请求拦截器需要实现接口, 它在真正使用客户端执行调用前执行, 可以用它来处理请求头, 打印日志啥的。
2024-12-01 14:29:03
1376
原创 9.编解码器
对于参数, feign默认只支持String类型和字节数组byte[], feign默认是不支持传递自定义java bean对象的, 但是feign允许我们对参数进行自定义编解码jacksonfeign默认提供了对jackson的扩展包gav如下
2024-11-30 13:38:43
1104
原创 4.MethodMetadata、RequestTemplate等模板
在contracts解析接口一文中有介绍过通过方法将目标接口类解析成对象, 从类名可以看出它是方法元数据, 其实可以看做是目标调用方法的模板, 与spring中的, mybatis中的功能类似。feign框架在启动的时候会指定Contracts类型,Contracts会添加注解解析器, 来约定如何解析一些注解(包括类,方法,参数中的)然后使用Contracts解析目标接口, 生成一个代表方法元数据的对象作为方法解析后的元数据对象, 它包含了如下重要属性, 等其它属性…方法唯一标识。
2024-11-29 16:34:42
1314
原创 2.mybatis整体配置
在介绍【mybatis基础操作】一文中开头提到过这么一个代码片段其中是用来加载配置文件解析成Reader流。大家可以把这个方法当做工具类来使用, 它还有很多重载方法, 比较丰富。注意这句代码, 它是解析配置文件的关键。在了解这行代码之前我们先来看一下的dtd文件!, settings?, plugins?, mappers?)>这是开头一段代码, 定义了元素的合法结构和可以配置的属性们以及它们的顺序configuration: 这是 MyBatis 主配置元素的名称。
2024-11-27 00:14:45
848
原创 8.Feign与ReflectiveFeign
这里我们学习一下这种抽象类的设计意图/*** 子类实例*/BaseBuilder设计成了抽象一个父类, 它希望子类以链式调用的方式设置一些属性值所以要借助B thisB举个例子链式调用这里是先调用父类的name方法, 然后需要强转到子类, 再调用子类的gender方法;那如果我的调用顺序是 parent.name -> child.gender -> parent.age -> child.address呢, 那么调用链将会是如下样子。
2024-11-26 23:54:14
872
原创 7.同步请求SynchronousMethodHandler
是同步请求的核心类, 与内聚在同一个类中, 实现的接口也是都内聚在和上实现接口的invoke方法, 依赖组件构建请求模板并填充参数通过依赖的Client组件进行接口请求, 在请求前会先执行请求拦截器, 并对http请求的url进行@QueryMap参数的填充通过依赖的组件处理返回后的结果, 用户可以在的响应处理中添加额外的责任链节点(响应拦截器)做特殊的处理当请求失败后, 直接重试, 当处理响应结果失败后, 如果抛出重试异常, 也会进入重试重试可以由服务端返回的响应头。
2024-11-25 00:00:02
926
原创 6.结果处理组件之ResponseHandler
Feign通过来处理响应的结果主要通过响应责任链来处理响应结果, 我们可以自定义其中的节点拦截器做自定义的事情责任链中默认添加了一个节点, 用来真正处理返回结果如果方法返回类型是Response, 那么根据返回的数据长度是否为空或者大于8k, 如果满足, 直接返回Response, 如果小于8k, 重新构建新的Response返回, 并关闭响应流;这里重新构建是因为流只能读取一次, 如果关闭了就读取不到了如果状态码是404, 并且设置dismiss404为true, 那么将忽略异常。
2024-11-24 19:59:12
945
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人