记录发现redissonBug并提交修复的历程
背景redis cluster集群模式下3主3从,用redisson,scan命令会漏扫非cluster集群下没有问题,lettuce也没有问题,只有redisson+cluster+scan才有会有问题
发现的历程搞库存重构,存放在redis的库存数据要更改名称,肯定不能用keys命令,keys会阻塞,时间复杂度是O(n)所以用scan,但发现scan总是漏扫数据,用Lettuce就没有问题,所以断定是redisson源码出现问题
找问题的历程分析源码,从scan开始,源码如下
建议debug阅读源码,不然容易混乱本地没有环境建议远程debug,在jvm启动脚本加上-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=16770 用idea连接即可远程debug
分析源码scan原理调用scan会返回一个迭代器,通过迭代器scan会从头扫到尾,直至cursorId=0源码如下
12345678910111213141516171819202122232425262728293031323334353 ...
es踩坑之deleteByQuery
背景由于es增删改操作有延迟,所以在某些业务场景如:先删除,在新增这种db下的场景就不适用于es了(es删除后在新增),毕竟db会有事务保证,所以在es层面只适合用deleteByQuery
代码场景通过canal订阅mysql的数据变动,投递到mq中,mq消费同步至es中,es做deleteByQuery的代码如下
1234567DeleteByQueryRequest request = new DeleteByQueryRequest("你的index");request.types("_doc");BoolQueryBuilder builder = QueryBuilders.boolQuery();builder.filter(QueryBuilders.termQuery("promotionId", promotionId)); // 条件一builder.filter(QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery("sh ...
lua和redis之电商库存的处理
代码先来看lua核销的代码
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889local userId = ARGV[1]local type = tostring(ARGV[2])local invalid = {}-- 循环所有的活动判断库存for kIndex = 1, #KEYS do repeat local kName = KEYS[kIndex] -- 不存在则忽略此key,并记录 if (redis.call('exists', kName) == 0) then invalid[kName] = true break end ...
学习nodeJs
参考:从浏览器到js到nodejs
你真的知道js的语法吗
作用域问题先看这段代码
1234567{ a = 1; function a() { }; a = 2; console.log(a); // 输出:2}console.log(a); // 输出:1
是不是很不解???常规思路都是输出2啊。没关系,在了解了JS块级作用域之后你就懂了
全局作用域和functionwindow为全局对象,在任何一个地方,如果一个变量a = 1(没有任何修饰,如var、let、const),那么也可以理解为window.a = 1var声明的变量的作用域在funtion中,否则在上层的function,若上层没有function,那么就会延伸到window中
eval('代码作用域'):默认eval执行的代码作用域同上。但是如果在eval之前开启严格模式use strict;那么eval里面的变量不会外溢。除非显示给外部对象赋值,如eval('window.bbb=48')
在Ecma5之前只有函数和全局作用域,也就是全局window或者f ...
从浏览器到js到nodejs
浏览器背景浏览器的历程
jsjs二十年的历程ecma5 = es5。2009年12月发布5.0,2011年6月发布5.1,成为ISO国际标准ecma6 = es6。2015年6月正式发布(简称ES2015)
javaScript大家最熟悉不过啦,他是通用的浏览器脚本语言,简称js,不过还有一个名词叫EcmaScript,他们之间是什么关系呢?原来EcmaScript是制定规范,javaScript是实现,ecma全称为 europe computer manufactures association即欧洲电脑制造商协会自从浏览器诞生到现在,浏览器脚本语言一直是Js的天下-如上图的js诞生历程,从诞生之日起就确定了他是前端开发的唯一标准,这一切都得归功于布兰登·艾奇,js发明时吸收了以下几个语言的特点
基本语法、数据结构java、C
函数的用法scheme
原型链继承self语言
而且js是单线程模型,在任何时刻js的代码只有一处在执行,这也为后面的异步通信服务端的语言nodeJs奠定了语法的基础
js = ecma规范 + webApi(dom + bom)DOM(d ...
hexo博客原理与实战
背景用一个东西之前如果不了解它的原理那就是想相当于一个搬运工,我们拒绝做搬运工那么他的原理、代码执行的流程、生命周期是什么呢?咱们带着问题一探究竟
本博客是基于hexo框架,主题butterfly构建完成的
hexo执行过程hexo 是基于nodejs
通过执行node hexo s就会生成可访问的静态文件,那么他的原理是什么呢?
首先你得了解nodeJs的npm
hexo是一个npm模块,执行node hexo s就是执行该模块
模块初始化代码
123456#!/usr/bin/env node'use strict';// hexo模块依赖了hexo-clirequire('hexo-cli')();
hexo模块依赖了hexo-cli,hexo-cli初始化代码如下
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354module.exports = entry;functi ...
java安全点safePoint以及JIT
什么是JITJust In Time(即时编译)一般程序遵循90-10原则,即运行时的90%时间里计算机是在处理其中10%的代码,java也是,jvm频繁的解释字节码也挺累的,因为还要翻译成机器码
,所以JIT的宗旨就是在运行过程当中找出热点代码并编译成二进制的机器语言(深度优化),这样就能很好的提高java的执行效率
假如Java的某个方法有1M次调用,通过jit优化此方法之后前后差100个指令,那么1M次调用,你就节省了0.1G个指令(1GHZ=10^3MHZ=10^6KHZ=10^9HZ)假设cpu处理频率为2.5GHz,优化后变为2.6GHz,相当于提升了4%的性能。如果优化的更多或者调用次数更多则性能提升的空间越大
一般都会优化哪些内容?
死代码删除如下代码,变量i是无任何意义的
1234public static void main(String[] args) { int i = 1; System.out.println("hello world");}
方法内联jit中非常重要的一环
将目标方法的方法体纳入编 ...
java内存模型和GC以及锁
让我们带着问题一探究竟一个Object对象占用几个字节,里面内容都是什么(对象占用大小)?在哪里分布呢(内存模型)?什么时候会销毁(GC)?
klass是java中,类的元信息在jvm中的表现形式,就是在c++中,类的元信息是通过klass来表示的
对象占用大小new Object();会占用多少内存呢?答案是16字节=128比特位=128bits
为什么是16字节呢?而不是17或者15? 这是因为8个字节=1byte,所以只能是8的倍数,那么是8,要么是16、24、32 那为什么是16,而不是24、32?因为这得取决于里面的内容是什么
里面内容是什么呢?对象头和数据体两大部分
1. 对象头
前面8个字节为markword,记录对象被上锁的各种状态或者垃圾回收和hashcode相关的信息默认无锁的情况如下,有锁的情况参考java锁
64位系统中(64bit)未使用:25位hashcode: 31位存储对象的System.identityHashCode(),采用延迟加载技术未使用:1位gc分带年龄: 4位偏向锁的标记:1位当前对象的锁的状态:2位25+ ...
jvmClassLoader过程及原理
classLoader加载class过程都是通过classLoader加载的class,如果已经加载过则不可以再次加载,但是可以通过不同的classLoader加载同一个class
都有哪些类加载器呢
引导类加载器=BootstrapClassloader是使用C++语言实现的,负责加载JVM虚拟机运行时所需的基本系统级别的类,如java.lang.String, java.lang.Object等等由于是C++实现的所以通过Object.class.getClassLoader() == null,无法访问
扩展类加载器=ExtClassLoader是由Bootstrap加载的此类此类加载器默认加载JAVA_HOME/jre/lib/ext/目录下的所有jar包,当然也可以加载由java.ext.dirs系统属性指定的jar包,用来加载java的扩展库,用户也可以直接使用此类加载器
应用类加载器=AppClassLoader是由AppClassLoader加载的此类此类加载器默认加载用户编写的class
双亲委派意思是多个亲戚,将加载class的任务委任给多个亲戚。以上三个类加载是 ...