- 分布式ID的实现:
1.mysql 依赖自增字段 replace into后在执行SELECT LAST_INSERT_ID();
优点:实现简单,id有序递增
缺点:生成id有序(安全性),大量访问性能差
2.redis incr
优点:实现简单,id有序递增
缺点(安全性)
3.算法1:jdk自带uuid,只需一行代码,但占用空间多且无序
4.算法2:基于雪花算法(依赖时间,若服务器时间回拨,可能重复)改良版(团leaf),有序递增,生成速度快 - redisson
引入watch dog 。每隔十秒,判断持锁的是否是当前线程,若是续期30秒
分布式事务主要有以下几种实现方式:
1. 两阶段提交(2PC)
两阶段提交是分布式事务中最经典的解决方案之一,它将事务的提交过程分为两个阶段:准备阶段和提交阶段。
- 准备阶段:事务协调者询问所有的参与者是否准备好提交事务,参与者执行事务操作,并将数据写入到redo和undo日志中,然后响应协调者它是否准备好。
- 提交阶段:如果所有的参与者都准备好了,协调者发送提交请求,参与者完成事务提交,并释放事务占用的资源;如果有任何一个参与者没有准备好,协调者发送中断请求,所有的参与者都要回滚事务。
2. 三阶段提交(3PC)
三阶段提交是对两阶段提交的改进,增加了一个预提交阶段,减少了阻塞范围,提高了系统的可用性。
- 预提交阶段:协调者询问参与者是否可以执行事务,并让参与者准备执行事务。
- 准备阶段:参与者准备数据,锁定资源,然后响应协调者它已经准备好。
- 提交阶段:协调者根据参与者的反馈决定是否提交事务,然后通知所有参与者提交或回滚。
3. TCC(Try-Confirm-Cancel)
TCC是一种补偿性事务模型,它将业务操作分为三个步骤:尝试(Try)、确认(Confirm)和取消(Cancel)。
- 尝试(Try):检查所有的业务条件,预留必要的业务资源。
- 确认(Confirm):正式完成业务操作,使用预留的资源。
- 取消(Cancel):如果业务操作执行失败,释放预留的资源,回滚操作。
4. 本地消息表
本地消息表是一种通过数据库来保证分布式事务一致性的方法。业务操作和消息发送放在同一个本地事务中,确保它们要么都成功,要么都失败。
- 操作步骤:首先执行业务操作,然后将需要发送的消息写入到本地消息表中,最后通过定时任务或者事件触发机制,将消息发送到消息队列中,其他服务通过订阅消息队列来完成后续操作。
5. 最终一致性(BASE)
最终一致性是一种弱一致性模型,它允许系统在一段时间内处于不一致状态,但保证最终达到一致状态。
- 实现方式:通过异步消息、事件驱动、定时任务等方式,逐步使系统中的各个副本达到一致状态。
每种分布式事务的实现方式都有其适用场景和优缺点,选择合适的方案需要根据具体的业务需求和系统特点综合考虑。
定时轮询异常并补偿
实现方式
- 记录异常信息:在执行操作时,如果遇到异常或失败,将这些异常信息记录到一个专门的存储系统中,如数据库表、日志文件等。
- 定时轮询:通过定时任务定期检查存储异常信息的系统,识别出那些需要被重新处理的异常。
- 执行补偿操作:对于每一个需要补偿的异常,执行相应的补偿逻辑,如重试失败的操作、发送未成功发送的消息等。
- 更新异常信息:补偿操作完成后,更新异常信息的状态,如标记为已处理,或记录重试次数等。
优点
- 提高可靠性:通过补偿机制,增加了操作成功的机会,提高了系统的可靠性。
- 灵活性高:可以根据业务需求灵活设置轮询的频率和补偿策略,适应不同的业务场景。
- 减少即时压力:将异常处理和补偿操作延后执行,可以减少系统在高峰时期的压力。
缺点
- 实时性差:由于是定时处理,无法做到实时补偿,可能会导致业务延迟。
- 增加系统复杂度:需要额外开发和维护定时任务和补偿逻辑,增加了系统的复杂度。
- 资源消耗:定时轮询和处理异常信息会占用系统资源,特别是在异常信息量大时,对数据库等存储系统的压力较大。
定时轮询异常并进行补偿是一种有效的策略,尤其适用于那些可以容忍一定延迟,但需要确保操作最终完成的场景。通过合理设计轮询频率和补偿策略,可以在保证系统稳定性和一致性的同时,最大限度地减少对系统性能的影响。
full gc的处理sop
看是单台机器full gc,还是多台。
单台可以先禁用问题机器防止影响服务,
多台可以采用安全重启的方式恢复线上正常,保留一台机器用于问题定位排查。
分析原因及解决方法
-
常见原因1:MetaSpace占满导致full gc,日志中可以看到Metadata GC Threshold字样。该问题常见于反射、字节码增强等技术的使用。
解决:-XX:MaxMetaspaceSize=调高上限,通过日志观察增长最快的类;
jmap -histo ${PID} | awk '{print$4}'| sed 's/\(.*\)[\._]\(.*\)/\1/g'| sort | uniq -c | sort -nrk1
总结:先扩大元数据空间缓解问题,再通过分析类加载定位根因 -
原因2:CMS GC频繁
young gc晋升失败。old区由于剩余空间过小或碎片太多导致cms gc
**解决:**降低CMS GC触发阈值保证足够的晋升空间;增大Survivor区
总结:避免出现young gc晋升失败 -
原因3:分代配置不合理
常见问题:
MaxTenuringThreshold(最大年龄0-15)过小,young还没来的及过期就晋升了;survivor过小无法容纳存货对象,导致提前晋升;young去过小,eden区被快速填充,影响每次young gc规模、缩短了对象GC cycle的累加周期,进而间接影响了每次Young GC的晋升规模。
解决:Young区空间不小于整个堆的50
总结 延长Young GC发生间隔,尽量避免无效对象晋升 -
原因4:
在分代配置合理的情况下,该现象说明Old区存在大量缓存对象,且缓存失效周期远超过15次Young GC的周期。
总结 通过对比Old区的类直方图,找出主要增长的对象,进一步定位对象增长的主要原因 -
原因5:显示system.gc()
总结 确认是否有脚本或者通过Scalpel触发Full GC,若无则利用工具跟踪System.gc()的调用栈
%搜索值%,正常来说会索引失效,但是如果搜索的字段都在二级索引上,满足覆盖索引,优化器会进行优化,只需要遍历联合索引数,查询会比主键索引树快。