Tomcat实现分布式session
tomcat实现分布式sessiontomcat-redis-session-manager
使用Copy the following files into the TOMCAT_BASE/lib directory:
123tomcat-redis-session-manager-VERSION.jarjedis-2.5.2.jarcommons-pool2-2.2.jar
配置 TOMCAT_HOME/conf/context.xml
12345<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" /><Manager className="com.radiadesign.catalina.session.RedisSessionManager" host="localhost" port="6379" databas ...
Tomcat Lifecycle
LifeCycleLifeCycle 相关类LifeCycle 接口中的状态扭转注释,如下:
12345678910111213141516171819202122232425262728* start()* -----------------------------* | |* | init() |* NEW -»-- INITIALIZING |* | | | | ------------------«-----------------------* | | |auto | | |* | | \|/ start() \|/ \|/ auto auto stop() |* | | INITIALIZE ...
Tomcat启动流程
tomcat 启动启动流程1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981 ...
布隆过滤器
布隆过滤器what布隆过滤器(Bloom Filter).是一个很长的 二进制向量 和 一系列随机映射 函数.
之所以叫 filter,是在缓存之前,把不存在的 key 给拦截掉.
本质是 一个位数组: 位数组 就是 数组 的 每个元素 都只占用 1 bit,并且每个元素只能是 0 或 1.
用于判断: 某个元素 一定不存在 或者 可能存在 于 一个集合中.
布隆过滤器除了一个位数组,还有 K 个哈希函数.
插入一个元素加入布隆过滤器:使用 K 个 哈希函数 对元素值 进行 K 次计算,得到 K 个哈希值.根据得到的哈希值,在 位数组中 把对应下标的值置为 1.
查询当查询 w 是否存在时,可以再通过这 k 个 哈希函数,如果算出来所在的位置均为1,则表示 w 可能存在(注意是可能存在),否则一定不存在.
优缺点1.优点空间效率 和 查询时间 都远远超过一般的算法.
2.缺点有一定的 误识别率 和 删除困难
数组的容量即使再大,也是有限的.
随着元素的增加,插入的元素就会越多,位数组中被置为 1 的位置因此也越多.
这就会造成一种情况:当一个不在布隆过滤器中的元素,经过同样规则的哈希计 ...
Redis实现分布式锁
Redis实现分布式锁要考虑的点
互斥(独占,只能有一个客户端获取锁)
不能死锁
容错(只要大部分 redis 节点创建了这把锁就认为成功获取到锁)
支持重入,超时获取锁等特性
redis实现分布式锁1.使用set1.1.加锁1SET key randomValue NX PX 30000
NX: (not exists)表示只有 key 不存在的时候才会设置成功.(如果此时 redis 中存在这个 key,那么设置失败,返回 nil)PX 30000: 30s 后 key 失效,意味着 30s 后锁自动释放.
随机数 randomValue 可以使用 时间戳 + 客户端编号 的方式 生成随机数.
1.2.释放锁123456-- 删除锁的时候,找到 key 对应的 value,跟自己传过去的 value 做比较,如果是一样的才删除.保证解的是自己加的锁if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1])else return 0e ...
Dubbo心跳机制
Dubbo心跳机制Dubbo 默认客户端和服务端都会发送心跳报文,用来保持 TCP 长连接状态.
在客户端和服务端,Dubbo 都会开启一个线程 循环扫描 并 检测连接是否超时.
在服务端发现超时则会主动关闭客户端连接.
在客户端发现超时则会主动重新创建连接.
默认心跳检测时间是 60 秒.
原理provider 心跳默认是在 heartbeat(一分钟)内如果没有读消息或写消息,就会发送心跳请求消息,如果连着3次(180s)没有读消息,provider会关闭channel.
consumer 端的心跳默认是在 一分钟 内如果没有读消息或写消息,就会发送心跳请求消息,如果连着3次(三分钟)没有读消息,consumer会进行重连.
开启定时任务provider 在启动 netty时,在 HeaderExchangeServer 的构造方法中,会通过 startHeatbeatTimer() 启动心跳定时任务.consumer 在 HeaderExchangeClient 的构造方法里,同样通过 startHeatbeatTimer() 启动心跳定时任务.
1234567891011121 ...
Zookeeper Watcher机制
watcher流程三个过程:client 注册 Watcherserver 处理 Watcherclient 回调 Watcher
client 注册 Watcherzk client 可以通过 new ZooKeeper(),getData(),getChildren(), exist() 传入 watcher对象 来 注册 Watcher.
比如对于 getData()时注册watcher的操作.实际上 client 就是把 watcher 对象 存到 DataWatchRegistration 里,再创建 Packet,存入 outgoingQueue,等待 SendThread 线程取出来发给 server.
123456789101112131415161718192021222324252627282930313233// 1.创建ZooKeeper对象时注册Watcher- new ZooKeeper()传入Watcher,会回调Watcher.process()方法 - ZooKeeper中会创建ZKWatchManager - watchManager.d ...
Hotspot编译
hotspot8编译参照xiaguang的博客,帮我踩了很多坑,虽然编译过程中还是遇到了一点小问题.
修改 ubuntu18 adp 源1sudo vi /etc/apt/sources.list
最好搜索一下最新的国内源
12345678910deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiversedeb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiversedeb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiversedeb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted univers ...
Zookeeper实现分布式锁
zk实现分布式锁zk实现分布式锁的两种方式如果要自己通过 zookeeper 的原生 api 实现一个分布式独占锁的话,有两种方式:
方式1: 创建临时节点,创建失败的client注册watcher所有需要获取锁的 client 都尝试到 zk 上创建同一个临时节点.创建成功则表示成功获取锁;若创建失败,则对这个节点注册 watcher.
若获得锁的 client 释放锁(自己 delete 掉节点) 或 宕机(zk 会自动移除掉该临时节点),
其他 client 会收到 watcher 通知,再尝试去抢锁.
这种方式的问题: 很明显竞争很大.在节点失效瞬间,如果争锁的 client 较多,会有大量 client 接收 watcher 通知.
方式2: 基于临时顺序节点创建锁1.每个 client 都在 zk 同一个父节点上创建一个 临时顺序节点2.然后每个 client 获取到父节点下的所有节点并排序,判断自己是否是顺序最小的那个节点2.1.如果是,加锁成功2.2.如果不是,加锁失败.注册 watcher,只用监听自己之前的那个节点即可.
释放锁1.client1 删除自己的临时顺序 ...
Dubbo Provider处理请求
服务端接收并响应请求流程provider处理请求流程
123456789101112- NettyServerWorker线程接收请求 - ByteToMessageDecoder.channelRead() - ByteToMessageDecoder.callDecode() - NettyCodecAdapter.InternalDecoder.decode() - DubboCountCodec.decode()解码 - fireChannelRead(ctx, out, size) - NettyServerHandler.channelRead() - AbstractPeer.received() - MultiMessageHandler.received() - HeartbeatHandler.received() ...