- 博客(79)
- 收藏
- 关注
原创 Kafka拦截器
拦截器主要用于实现clients端的定制化需求,包括消息在生产者发送到 Kafka 或者在消费者接收消息之前进行一些定制化的操作。用于在消息发送和接收的关键步骤中进行拦截和处理。可以修改消息,日志记录,统计等。由生产者拦截器和消费者拦截器组成。
2025-03-24 15:37:43
345
原创 Kafka消息自定义序列化
Kafka支持用户自定义消息序列化。若要编写一个自定义的serializer,需要完成以下3件事情。1)定义数据对象格式。2)创建自定义序列化类,实现 org.apache.kafka.common.serialization.Serializer 接口,在serializer方法中实现序列化逻辑。3)在用于构造KafkaProducer 的Properties 对象中设置 key.serializer 或 value.serializer取决于是为消息key还是 value 做自定义序列化。
2025-03-21 14:24:40
716
原创 Kafka自定义分区机制
若需要使用自定义分区机制,需要完成两件事:1)在 producer 程序中创建一个类,实现 org.apache.kafka.clients.producer.Partitioner 接口主要分区逻辑在 Partitioner.partition中实现。2)在用于构造KafkaProducer的Properties对象中设置 partitioner.class 参数。
2025-03-20 17:28:48
327
原创 Unsafe类
后当前线程就会被唤醒。另外,当其他线程调用了当前阻塞线程的interrupt 方法而中断了当前线程时, 当前线程也会返回, 而当其他线程调用了unPark 方法并且把当前线程作为参数时当前线程也会返回。boolean compareAndSwapLong(Object obj, long offset, long expect, long update):比较对象obj 中偏移量为offset 的变量的值是否与expect 相等, 相等则使用update值更新, 然后返回true,否则返回false。
2025-01-03 16:33:57
797
原创 ThreadLocalRandom
ThreadLocalRandom 类是JDK 7 在JUC 包下新增的随机数生成器,它弥补了Random类在多线程下的缺陷。
2025-01-03 10:56:09
435
原创 ThreadLocal使用
ThreadLocal提供了线程本地变量,当创建一个ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的一个本地副本。当多个线程操作这个变量时,实际操作的是自己本地内存里面的变量,从而避免了线程安全问题。
2024-12-30 11:11:02
503
原创 java内存模型
JMM 的处理器重排序规则会要求java 编译器在生成指令序列时,插入特定类型的内存屏障(memory barriers,intel 称之为 memory fence)指令,通过内存屏障指令来禁止特定类型的处理器重排序(不是所有的处理器重排序都要禁止)。JMM 属于语言级的内存模型,它确保在不同的编译器和不同的处理器平台之上通过禁止特定类型的编译器重排序和处理器重排序,为程序员提供一致的内存可见性保证。:JMM 的编译器重排序规则会禁止特定类型的编译器重排序(不是所有的编译器重排序都要禁止)。
2024-12-16 16:16:26
303
原创 并发编程整理的思维导图
链接: https://pan.baidu.com/s/1ebsa0l7Wk6AWLWA2nrS1dA 提取码: 3rvx。通过网盘分享的文件:并发编程的xmind。
2024-12-10 16:41:06
100
原创 线程(thread)
概念:线程进入该状态,一般需要等待其他线程做完一些特殊操作调用Thread.join方法调用Object.wait() 方法进入等待状态。
2024-12-06 13:57:27
425
原创 java8新特性
java8的新特性有函数式接口、接口的默认方法与静态方法、Lambda表达式、方法引用与构造器引用、Stream API、新时间日期API、减少空指针异常Optional、支持重复注解、Fork/Join 框架等。java8的优点如下:速度更快、代码更少(增加了新的语法Lambda表达式)、强大的Stream API、便于并行、最大化减少空指针异常Optional。
2024-08-22 17:28:47
1295
原创 ubuntu上部署vue项目到ngixn中+SpringBoot项目+postgresql数据库
部署vue和springboot及postgres
2024-07-26 15:41:36
983
原创 java并发编程之美-第1章 并发编程线程基础-线程通知与等待(wait/notify,notifyAll)
Object类是所有类的父类,鉴于继承机制,Java把所有类都需要的方法放到了 Obiect类里面,其中就包含通知(notify,notifyAll)与等待(wait)系列函数。
2024-07-11 16:22:45
365
原创 java并发编程之美-第1章 并发编程线程基础-线程的创建与运行
进程是操作系统进行资源分配和调度的基本单位,线程是 CPU 分配的基本单位。程序计数器用来记录线程当前要执行的指令地址。CPU一般是使用时间片轮转方式让线程轮询占用的,程序计数器是记录线程让出CPU时的执行地址的,待再次分配到时间片时线程就可以从自己私有的计数器指定地址继续执行。另外需要注意的是,如果执行的是 native 方法那么 pc计数器记录的是 undefned 地址,只有执行的是 Java 代码时 pc计数器记录的才是下一条指令的地址。栈用于存储线程的局部变量,调用栈帧。
2024-07-11 14:42:37
241
原创 计算属性computed()
若我们将同样的函数定义为一个方法而不是计算属性,两种方式在结果上确实是完全相同的,然而,不同之处在于计算属性值会基于其响应式依赖被缓存。更改快照是没有意义的,因此计算属性的返回值应该被视为只读的,并且永远不应该被更改——应该更新它所依赖的源状态以触发新的计算。它会检测到 fullName依赖于 firstName和lastName,所以当 firstName、lastName 改变时,任何依赖于 fullName的绑定都会同时更新。当你尝试修改一个计算属性时,你会收到一个运行时警告。
2024-07-05 15:11:35
358
原创 响应式ref()和reactive()
一个RefImpl的实例对象,简称ref对象或ref,ref对象的value属性是响应式的。:toRefs与toRef功能一致,但toRefs可以批量转换。:定义响应式对象(基本类型不要用它,要用ref,否则报错)。:将一个响应式对象中的每一个属性,转换为ref对象。:let 响应式对象=reactive(源对象)。:reactive定义的响应式数据是“深层次”的。:一个Proxy的实例对象,简称响应式对象。:let xxx=ref(初始值)。
2024-07-05 11:08:33
717
原创 第7章 Redis的噩梦:阻塞
Redis是典型的单线程架构,所有的读写操作都是在一条主线程中完成的。当Redis用于高并发场景时,如果出现阻塞,哪怕是很短时间,对于我们的应用来说都是噩梦。内在原因包括:不合理地使用API或数据结构、CPU饱和、持久化阻塞等。外在原因包括:CPU竞争、内存交换、网络问题等。
2024-06-28 15:15:17
541
原创 第6章 复制
复制功能,实现了相同数据的多个Redis副本。复制功能是高可用Redis的基础,满足故障恢复和负载均衡等需求。哨兵和集群都是在复制的基础上实现高可用的。
2024-06-28 10:49:51
700
原创 第4章 客户端-客户端常见异常
如果Redis当前正在执行Lua脚本,并且超过了lua-time-limit,此时Jedis调用Redis时,会收到下面的异常。如果当前Lua脚本正在执行写操作,那么script kill将不会生效。例如将普通客户端的输出缓冲区设置为1M1M60:如果使用get命令获取一个bigkey(例如3M),就会出现这个异常。3)不正常并发读写:Jedis对象同时被多个线程并发操作,可能会出现上述异常。2)Redis发生阻塞,造成tcp-backlog已满,造成新的连接失败。3)客户端与服务端网络不正常。
2024-06-27 16:52:50
384
原创 第4章 客户端-客户端案例分析
以上问题之所以能够快速定位,得益于使用客户端监控工具把一些统计数据收集上来,这样能更加直观地发现问题,如果Redis是黑盒运行,相信很难快速找到这个问题。对这个问题处理的方法相对简单,只要使用client kill命令杀掉这个连接,让其他客户端恢复正常写数据即可。服务端现象:Redis主节点内存陡增,几乎用满maxmemory,而从节点内存并没有变化(正常情况下主从节点内存使用量基本相同)。1)确实有大量写入,但是主从复制出现问题:查询了Redis复制的相关信息,复制是正常的,主从数据基本一致。
2024-06-27 16:19:29
1003
原创 第4章 客户端-客户端管理
这是基于对客户端开发的一种保护。monitor的作用很明显,如果开发和运维人员想监听Redis正在执行的命令,就可以用monitor命令,但事实并非如此美好,每个客户端都有自己的输出缓冲区,既然monitor能监听到所有的命令,一旦Redis的并发量过大,monitor客户端的输出缓冲会暴涨,可能瞬间会占用大量内存,下图展示了monitor命令造成大量内存使用。1)connected_clients:代表当前Redis节点的客户端连接数,需要重点监控,一旦超过maxclients,新的客户端连接将被拒绝。
2024-06-27 11:14:31
1296
原创 第5章 持久化-RDB和AOF
*运维提示:**对于错误格式的AOF文件,先进行备份,然后采用redis-check-aof–fix命令进行修复,修复后使用diff-u对比数据的差异,找出丢失的数据,有些可以人工修改补全。2)父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞,通过info stats命令查看latest_fork_usec选项,可以获取最近一个fork操作的耗时,单位为微秒。5)进程发送信号给父进程表示完成,父进程更新统计信息,具体见info Persistence下的rdb_*相关选项。
2024-06-26 17:10:46
1207
原创 第4章 客户端-Java客户端Jedis
客户端连接Redis使用的是TCP协议,直连的方式每次需要建立TCP连接,而连接池的方式是可以预先初始化好Jedis连接,所以每次只需要从Jedis连接池借用即可,而借用和归还操作是在本地进行的,只有少量的并发同步开销,远远小于新建TCP连接的开销。但是直连的方式也并不是一无是处,表4-1给出两种方式各自的优劣势。因此生产环境中一般使用连接池的方式对Jedis连接进行管理,如下图所示,所有Jedis对象预先放在池子中(JedisPool),每次要连接Redis,只需要在池子中借,用完了在归还给池子。
2024-06-26 16:33:25
835
原创 第4章 客户端-客户端通信协议
几乎所有的主流编程语言都有Redis的客户端(http://redis.io/clients),不考虑Redis非常流行的原因,如果站在技术的角度看原因还有两个:第一,客户端与服务端之间的通信协议是在TCP协议之上构建的。Redis是用单线程来处理多个客户端的访问,因此作为Redis的开发和运维人员需要了解Redis服务端和客户端的通信协议,以及主流编程语言的Redis客户端使用方法,同时还需要了解客户端管理的相应API以及开发运维中可能遇到的问题。依然以set hell world这条命令进行说明。
2024-06-25 10:56:02
317
原创 第3章 小功能大用处-事务与Lua
除了使用eval,Redis还提供了evalsha命令来执行Lua脚本。Redis提供了简单的事务,之所以说它简单,主要是因为它不支持事务中的回滚特性,同时无法实现命令之间的逻辑关系计算,当然也体现了Redis的“keep it simple”的特性,下一小节介绍的Lua脚本同样可以实现事务的相关功能,但是功能要强大很多。eval命令和–eval参数本质是一样的,客户端如果想执行Lua脚本,首先在客户端编写好Lua脚本代码,然后把脚本作为字符串发送给服务端,服务端会将执行结果返回给客户端,整个过程如下。
2024-06-24 10:10:17
499
原创 第3章 小功能大用处-Pipeline
例如客户端在北京,Redis服务端在上海,两地直线距离约为1300公里,那么1次RTT时间=1300×2/(300000×2/3)=13毫秒(光在真空中传输速度为每秒30万公里,这里假设光纤为光速的2/3),那么客户端在1秒内大约只能执行80次左右的命令,这个和Redis的高并发高吞吐特性背道而驰。但大部分开发人员更倾向于使用高级语言客户端中的Pipeline,目前大部分Redis客户端都支持Pipeline,第4章我们将介绍如何通过Java的Redis客户端Jedis使用Pipeline功能。
2024-06-23 02:39:01
252
原创 第3章 小功能大用处-Redis Shell
Redis提供了redis-cli、redis-server、redis-benchmark等Shell工具。
2024-06-23 02:26:54
917
原创 第3章 小功能大用处-发布订阅
Redis提供了基于“发布/订阅”模式的消息机制,此种模式下,消息发布者和订阅者不进行直接通信,发布者客户端向指定的频道(channel)发布消息,订阅该频道的每个客户端都可以收到该消息。
2024-06-22 00:40:28
686
原创 第3章 小功能大用处-Bitmaps、HyperLogLog、GEO
现代计算机用二进制(位)作为信息的基础单位,1个字节等于8位,例如“big”字符串是由3个字节组成,但实际在计算机存储时将其用二进制表示,“big”分别对应的ASCII码分别是98、105、103,对应的二进制分别是01100010、01101001和01100111,如下图所示。但Bitmaps并不是万金油,假如该网站每天的独立访问用户很少,例如只有10万(大量的僵尸用户),那么两者的对比如表3-5所示,很显然,这时候使用Bitmaps就不太合适了,因为基本上大部分位都是0。
2024-06-21 01:10:05
1052
原创 Redis开发与运维-第3章 小功能大用处-慢查询分析
Redis客户端执行一条命令分为如下4个部分:1)发送命令、2)命令排队、3)命令执行、4)返回结果需要注意,慢查询只统计步骤3)的时间,所以没有慢查询并不代表客户端没有超时问题。
2024-06-14 15:50:27
899
原创 Redis开发与运维-第2章 API的理解和使用-使用场景
第二,分页获取文章列表时,lrange命令在列表两端性能较好,但是如果列表较大,获取列表中间范围的元素性能会变差,此时可以考虑将列表做二级拆分,或者使用Redis3.2的quicklist内部编码实现,它结合ziplist和linkedlist的特点,获取列表中间范围的元素时也可以高效完成。6.1每个独立用户是否访问过网站场景:将每个独立用户是否访问过网站存放在Bitmaps中,将访问的用户记做1,没有访问的用户记做0,用偏移量作为用户的id。每个用户有属于自己的文章列表,现需要分页展示文章列表。
2024-06-14 11:20:40
418
原创 Redis开发与运维-第2章 API的理解和使用-Redis的各种类型常用命令
在Redis中,可以对列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下标的元素等。举个例子,你有两个列表 source 和 destination , source 列表有元素 a, b, c , destination 列表有元素 x, y, z ,执行RPOPLPUSH source destination 之后, source 列表包含元素 a, b , destination 列表包含元素 c, x, y, z ,并且元素 c 会被返回给客户端。
2024-06-13 10:57:26
369
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人