视壮科技面试
1、你最熟悉的技术点是什么?
消息队列
1、架构组成
NameServer
也是一个 注册中心 ,主要提供两个功能:Broker 管理 和 路由信息管理 。说白了就是 Broker
会将自己的信息注册到 NameServer
中,此时 NameServer
就存放了很多 Broker
的信息(Broker 的路由表)
,消费者和生产者就从 NameServer
中获取路由表然后照着路由表的信息和对应的 Broker
进行通信(
生产者和消费者定期会向 NameServer
去查询相关的 Broker
的信息)
Broker启动
Consumer首次请求Broker Broker中是否有符合条件的消息 如果有
响应Consumer 等待下次Consumer的请求
如果没有DefaultMessageStore#ReputMessageService#run方法
PullRequestHoldService 来Hold连接,每个5s执行一次检查pullRequestTable有没有消 息,有的话立即推送
每隔1ms检查commitLog中是否有新消息,有的话写入到pullRequestTable
当有新消息的时候返回请求挂起consumer的请求,即不断开连接,也不返回数据
使用consumer的offset
Producer生产者
消息发布的角色,支持分布式集群方式部署。说白了就是生产者。
Consumer消费者
消息消费的角色,支持分布式集群方式部署。支持以 push 推,pull 拉两种模式对消息进行消费。同时也支持集群方式和广播方式的消费,它提供实时消息订阅机制。说白了就是消费者
2、特点
3、流程
4、高可用
5、消息类型
普通消息:
- 初始化:消息被生产者构建并完成初始化,待发送到服务端的状态。
- 待消费:消息被发送到服务端,对消费者可见,等待消费者消费的状态。
- 消费中:消息被消费者获取,并按照消费者本地的业务逻辑进行处理的过程。 此时服务端会等待消费者完成消费并提交消费结果,如果一定时间后没有收到消费者的响应,RocketMQ
会对消息进行重试处理。 - 消费提交:消费者完成消费处理,并向服务端提交消费结果,服务端标记当前消息已经被处理(包括消费成功和失败)。RocketMQ
默认支持保留所有消息,此时消息数据并不会立即被删除,只是逻辑标记已消费。消息在保存时间到期或存储空间不足被删除前,消费者仍然可以回溯消息重新消费。 - 消息删除:RocketMQ 按照消息保存机制滚动清理最早的消息数据,将消息从物理文件中删除。
定时消息:
在 4.x 版本中,只支持延时消息,默认分为 18 个等级分别为:1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
在 5.x 版本中,开始支持定时消息,在构造消息时提供了 3 个 API 来指定延迟时间或定时时间
定时生命周期
- 初始化:消息被生产者构建并完成初始化,待发送到服务端的状态。
- 定时中:消息被发送到服务端,和普通消息不同的是,服务端不会直接构建消息索引,而是会将定时消息单独存储在定时存储系统中
,等待定时时刻到达。 - 待消费:定时时刻到达后,服务端将消息重新写入普通存储引擎,对下游消费者可见,等待消费者消费的状态。
- 消费中:消息被消费者获取,并按照消费者本地的业务逻辑进行处理的过程。 此时服务端会等待消费者完成消费并提交消费结果,如果一定时间后没有收到消费者的响应,RocketMQ
会对消息进行重试处理。 - 消费提交:消费者完成消费处理,并向服务端提交消费结果,服务端标记当前消息已经被处理(包括消费成功和失败)。RocketMQ
默认支持保留所有消息,此时消息数据并不会立即被删除,只是逻辑标记已消费。消息在保存时间到期或存储空间不足被删除前,消费者仍然可以回溯消息重新消费。 - 消息删除:Apache RocketMQ 按照消息保存机制滚动清理最早的消息数据,将消息从物理文件中删除。
顺序消息
顺序消息仅支持使用 MessageType 为 FIFO 的主题,即顺序消息只能发送至类型为顺序消息的主题中,发送的消息的类型必须和主题的类型一致。和普通消息发送相比,顺序消息发送必须要设置消息组。(推荐实现
MessageQueueSelector 的方式,见下文)。要保证消息的顺序性需要单一生产者串行发送。
单线程使用 MessageListenerConcurrently 可以顺序消费,多线程环境下使用 MessageListenerOrderly 才能顺序消费
RocketMQ
在主题上是无序的、它只有在队列层面才是保证有序 的。
普通顺序 和 严格顺序 。
所谓普通顺序是指 消费者通过 同一个消费队列收到的消息是有顺序的
,不同消息队列收到的消息则可能是无顺序的。普通顺序消息在 Broker
重启情况下不会保证消息顺序性 (短暂时间) 。
一般而言,我们的 MQ
都是能容忍短暂的乱序,所以推荐使用普通顺序模式。
那么,我们现在使用了 普通顺序模式 ,我们从上面学习知道了在 Producer
生产消息的时候会进行轮询(取决你的负载均衡策略)
来向同一主题的不同消息队列发送消息。那么如果此时我有几个消息分别是同一个订单的创建、支付、发货,在轮询的策略下这 *
三个消息会被发送到不同队列* ,因为在不同的队列此时就无法使用 RocketMQ
带来的队列有序特性来保证消息有序性了。
那么,怎么解决呢?
其实很简单,我们需要处理的仅仅是将同一语义下的消息放入同一个队列(比如这里是同一个订单),那我们就可以使用 Hash 取模法
来保证同一个订单在同一个队列中就行了
RocketMQ 实现了两种队列选择算法,也可以自己实现
轮询算法
- 轮询算法就是向消息指定的 topic 所在队列中依次发送消息,保证消息均匀分布
- 是 RocketMQ 默认队列选择算法
最小投递延迟算法
每次消息投递的时候统计消息投递的延迟,选择队列时优先选择消息延时小的队列,导致消息分布不均匀,按照如下设置即可
1
producer.setSendLatencyFaultEnable(true);
继承 MessageQueueSelector 实现
1 | SendResult sendResult = producer.send(msg, new MessageQueueSelector() { |
选择队列后会与 Broker 建立连接,通过网络请求将消息发送到 Broker 上,如果 Broker 挂了或者网络波动发送消息超时此时 RocketMQ
会进行重试。 重新选择其他 Broker 中的消息队列进行发送,默认重试两次,可以手动设置。
producer.setRetryTimesWhenSendFailed
(5); 消息过大 消息超过 4k 时 RocketMQ 会将消息压缩后在发送到 Broker 上,减少网络资源的占用。 重复消费 emmm,就两个字—— 幂等
。在编程中一个幂等
操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。比如说,这个时候我们有一个订单的处理积分的系统,每当来一个消息的时候它就负责为创建这个订单的用户的积分加上相应的数值。可是有一次,消息队列发送给订单系统
FrancisQ 的订单信息,其要求是给 FrancisQ 的积分加上 500。但是积分系统在收到 FrancisQ
的订单信息处理完成之后返回给消息队列处理成功的信息的时候出现了网络波动(当然还有很多种情况,比如 Broker 意外重启等等)
,这条回应没有发送成功。 那么,消息队列没收到积分系统的回应会不会尝试重发这个消息?问题就来了,我再发这个消息,万一它又给
FrancisQ 的账户加上 500 积分怎么办呢? 所以我们需要给我们的消费者实现 幂等 ,也就是对同一个消息的处理结果,执行多少次都不变。
那么如何给业务实现幂等呢?这个还是需要结合具体的业务的。你可以使用 写入 Redis 来保证,因为 Redis 的 key 和 value
就是天然支持幂等的。当然还有使用 数据库插入法 ,基于数据库的唯一键来保证重复数据不会被插入多条。 不过最主要的还是需要
根据特定场景使用特定的解决方案 ,你要知道你的消息消费是否是完全不可重复消费还是可以忍受重复消费的,然后再选择强校验和弱校验的方式。毕竟在
CS 领域还是很少有技术银弹的说法。 而在整个互联网领域,幂等不仅仅适用于消息队列的重复消费问题,这些实现幂等的方法,也同样适用于,在其他场景中来解决重复请求或者重复调用的问题
。比如将 HTTP 服务设计成幂等的,解决前端或者 APP 重复提交表单数据的问题 ,也可以将一个微服务设计成幂等的,解决 RPC 框架自动重试导致的
重复调用问题 。 RocketMQ 如何实现分布式事务?
事务消息
事务消息是 Apache RocketMQ 提供的一种高级消息类型,支持在分布式场景下保障消息生产和本地事务的最终一致性。简单来讲,就是将本地事务(数据库的
DML
操作)与发送消息合并在同一个事务中。例如,新增一个订单。在事务未提交之前,不发送订阅的消息。发送消息的动作随着事务的成功提交而发送,随着事务的回滚而取消。当然真正地处理过程不止这么简单,包含了半消息、事务监听和事务回查等概念,下面有更详细的说明
消息重复消费如何解决?
影响消息正常发送和消费的重要原因是网络的不确定性。
引起重复消费的原因
1)ACK
正常情况下在consumer真正消费完消息后应该发送ack,通知broker该消息已正常消费,从 queue中剔除
当ack因为网络原因无法发送到broker,broker会认为词条消息没有被消费,此后会开启消息 重投机制把消息再次投递到consumer
2)消费模式
在CLUSTERING模式下,消息在broker中会保证相同group的consumer消费一次,但是针 对不同group的consumer会推送多次
解决方案
1)数据库表
处理消息前,使用消息主键在表中带有约束的字段中insert
2)Map
单机时可以使用map ConcurrentHashMap -> putIfAbsent guava cache
3)Redis
分布式锁搞起来。
如何让RocketMQ保证消息的顺序消费?
首先多个queue只能保证单个queue里的顺序,queue是典型的FIFO,天然顺序。多个queue 同时消费是无法绝对保证消息的有序性的。所以总结如下:
同一topic,同一个QUEUE,发消息的时候一个线程去发送消息,消费的时候 一个线程去消费 一个queue里的消息。
RocketMQ如何保证消息不丢失?
首先在如下三个部分都可能会出现丢失消息的情况:
Producer端
Broker端
Consumer端
1)Producer端如何保证消息不丢失
采取send()同步发消息,发送结果是同步感知的。 发送失败后可以重试,设置重试次数。默认3次。
producer.setRetryTimesWhenSendFailed(10);
集群部署,比如发送失败了的原因可能是当前Broker宕机了,重试的时候会发送到其他 Broker上。
2)Broker端如何保证消息不丢失
修改刷盘策略为同步刷盘。默认情况下是异步刷盘的。
flushDiskType = SYNC_FLUSH
集群部署,主从模式,高可用。
3)Consumer端如何保证消息不丢失
完全消费正常后在进行手动ack确认
RocketMQ的消息堆积如何处理
首先要找到是什么原因导致的消息堆积,是Producer太多了,Consumer太少了导致的还是说 其他情况,总之先定位问题(dashboard)。
然后看下消息消费速度是否正常,正常的话,可以通过上线更多consumer临时解决消息堆积 问题。
RocketMQ在分布式事务支持这块机制的底层原理?
分布式系统中的事务可以使用TCC(Try、Confirm、Cancel)、2pc来解决分布式系统中的 消息原子性
RocketMQ 4.3+提供分布事务功能,通过 RocketMQ 事务消息能达到分布式事务的最终一致
RocketMQ实现方式:
Half Message:预处理消息,当broker收到此类消息后,会存储到RMQ_SYS_TRANS_HALF_TOPIC的消息消费队列中
检查事务状态:Broker会开启一个定时任务,消费RMQ_SYS_TRANS_HALF_TOPIC队列 中的消息,每次执行任务会向消息发送者确认事务执行状态(提交、回滚、未知),如果是未
知,Broker会定时去回调在重新检查。
超时:如果超过回查次数,默认回滚消息。
也就是他并未真正进入Topic的queue,而是用了临时queue来放所谓的half message,等提交事务后才会真正的将half
message转移到topic下的queue
如果让你来动手实现一个分布式消息中间件,整体架构你会如何设计实现?
高吞吐量下如何优化生产者和消费者的性能?
1)开发
同一group下,多机部署,并行消费
单个Consumer提高消费线程个数
批量消费。消息批量拉取,业务逻辑批量处理。
2)运维
网卡调优
jvm调优
多线程与cpu调优 Page Cache
再说说RocketMQ 是如何保证数据的高容错性的?
在不开启容错的情况下,轮询队列进行发送,如果失败了,重试的时候过滤失败的Broker
如果开启了容错策略,会通过RocketMQ的预测机制来预测一个Broker是否可用
如果上次失败的Broker可用那么还是会选择该Broker的队列
如果上述情况失败,则随机选择一个进行发送
在发送消息的时候会记录一下调用的时间与是否报错,根据该时间去预测broker的可用时间
任何一台Broker突然宕机了怎么办?
Broker主从架构以及多副本策略。Master收到消息后会同步给Slave,这样一条消息就不止一
份了,Master宕机了还有slave中的消息可用,保证了MQ的可靠性和高可用性。而且Rocket MQ4.5.0开始就支持了Dlegder模式,基于raft的,做到了真正意义的HA。
2、你上家公司的是的内容?
1、负责用户限制数消息协议业务对接
2、负责优惠劵从0到1的设计
3、负责风控体系建设,抵制诈骗风险及高风险地区识别及黑白名单及ip开发
4、负责AI客服搭建
3、你彩讯公司的负责的内容体系,在项目担任了什么角色?
1、负责redis分布式组件开发、leaf分布式id组件开发
2、架构升级梳理拆分(邮箱业务/通讯录/邮箱组/用户/后台管理系统),ssm升级到springboot(升级spring包、去除application.xml配置依赖、升级mybatis、重新配置过滤器、监听器、配置加载机制、前后端分离)
在到微服务拆分(采用AKF原则 x折 值得是单元化部署、机器叠加,y折指的是服务拆分
z折基于数据拆分)分为基础组件沉淀(redis/es)、邮箱服务、用户服务、日志服务、通讯录服务等等)
升级微服务过程及CICD集成
springboot接入springCloud Alibaba过程总结
1、引入discover依赖,包扫描改造
2、feign远程调用,及fallback机制
3、feign接口调用拦截器处理
4、引入dockerfile及打包上传到docker hub镜像仓库,上私有云改造
5、k8s apply应用部署pod/svr节点(nodepod)方式。不过后面要引入ingress进行接口管理 梳理
在项目中担任了核心开发岗角色,负责对接需求及需求拆分,带有2个组员一起开发。
4、MQ对于主从架构 消息数量量大导致master是 怎么处理
1、4.5版本之前master down需要手动重启 ,slave接管读请求(改broker id为0表示主 大于0表示 slave)
2、dledger模式下自动选举, 基于raft算法采用过半机制完成自动完成选举
问止科技
CEO面试
1、自我介绍?
2、你比同龄人java优势在哪里?
3、写代码比别人强在哪里?
4、工作地点问题?
5、11月份离职到现在没工作在做什么呢
6、加班时间怎么看?
酷赛科技
1、设计一个API接口开发平台
1AppId和AppSecret
2RSASignature和MD5签名
3线下把私钥和appid给对方
4客户端接口加密
5服务端解密(黑白名单、IP地址、noconce时间戳防重方攻击、限流、敏感信息加密(国密加密)
2、广告系统设计
1、
3、消息丢失 或者消息挤压怎么处理
消息丢失:
生产者消息丢失(1、producer重试 2、rocketmq中有 本地错误表 用户计算broker的下次可用时间,筛选出可以发消息的broker
3、消息确认模式sendsync,带有消息回调)
broker防止丢失(1、多副本机制,follower和leader副本同步)
消费者端反丢失(手动确认机制,ConsumeConcurrentlyStatus.CONSUME_SUCCESS。否则我们需要返回
ConsumeConcurrentlyStatus.RECONSUME_LATER状态)
消息挤压:
首先根据dashboard确认生产和消费点位差距比较大,发现了问题之后,一般可以通过增大消费者数量,配置和messagequeue一样多就好,如果还不行,需要手动创建topic,配置足够多的messagequeue,负责讲旧的消息转投到新的topic上。
跨越速运
1、JVM 有什么?
2、垃圾回收算法,优缺点
3、索引失效案例
4、innodb和 myisam存储引擎区别
5、索引类型
6、事务消息实现原理
7、rocketmq组成架构
8、什么是最左匹配
9、联合索引
10、加班什么看法
11、优惠券设计
12、风控设计
13、netty的实现原理
14、幂等设计
15、你的优势是什么 缺点是什么(思考的深度不够)
16、架构师的特点(业务专精)
17、cap理论
18、分库分表
19、datax怎么用的
20、锁的种类
顺丰科技外包
1、前端请求到后端服务过程(经过k8s调度过程)
前端请求进入集群
用户发起请求:用户通过浏览器访问前端服务(如通过域名或IP)。
流量入口:
外部访问:请求可能先经过 Ingress(如Nginx Ingress Controller)3或直接通过 LoadBalancer/NodePort
类型的Service暴露到集群外36 -内部访问:若前端和后端在同一个集群内,请求可能直接通过 ClusterIP 类型的Service通信4—
Ingress/Service 路由与负载均衡
Ingress路由:若使用Ingress,请求会根据配置的路径(如/api)转发到后端Service9- Service负载均衡:
Service通过 Label Selector 关联后端Pod,并通过 kube-proxy 维护的iptables/ipvs规则实现流量分发34 - 负载均衡策略包括轮询(默认)、权重(weight)、IP哈希(ip_hash)等3—
Pod调度与请求处理
Pod调度:
Kubernetes调度器(Scheduler)根据资源需求、节点标签(如disk=ssd)、亲和性规则等,将Pod分配到合适的Node3 - 定向调度可通过nodeSelector或nodeName强制指定目标节点3- 后端Pod处理请求:
请求到达目标Pod后,后端服务(如Spring Boot应用)执行业务逻辑(如数据库操作)7 - 响应数据返回给前端,通常通过原路径反向传递(如Service→Ingress→用户)。
Kubernetes核心组件协作
API Server:接收并处理所有资源操作请求(如创建Service/Deployment)。
kube-proxy:维护Service的IP和端口映射规则,确保流量正确转发4- CNI插件:管理Pod的网络连通性(如Calico、Flannel)。关键配置示例
Service定义(ClusterIP类型):
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
selector:
app: backend # 关联标签为app=backend的Pod
ports:
- protocol: TCP
port: 80 # Service端口
targetPort: 8080 # Pod容器端口
type: ClusterIP
Ingress路由规则:
Yaml
复制
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
rules: - host: example.com
http:
paths:- path: /api
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 80
常见问题与优化
偶发超时:可能因网络插件异常或Pod资源不足导致,需检查集群节点状态及Pod日志 - 10- 性能优化:启用长连接、调整负载均衡策略(如最少连接数)13通过以上流程,Kubernetes实现了从请求入口到后端服务的自动化调度与高可用保障。
- path: /api
2、滑动窗口和滚动窗口区别
- 窗口分配规则
滚动窗口:窗口之间严格首尾相接,无重叠或间隔。参数仅需定义窗口大小(时间或计数)。例如,1小时的滚动窗口会每小时独立处理一次数据12。
滑动窗口:窗口按固定步长滑动,可能重叠。需定义窗口大小和滑动步长两个参数。例如,1小时窗口每5分钟滑动一次,数据可能被多个窗口覆盖24。 - 数据分配方式
滚动窗口:每个数据仅属于一个窗口。例如,8:00-9:00的数据不会出现在其他滚动窗口中23。
滑动窗口:若步长小于窗口大小,数据可能被分配到多个窗口。例如,8:55的数据同时属于[8:00-9:00)和[8:30-9:30)两个窗口[24。 - 触发计算的频率
滚动窗口:窗口结束时触发一次计算。例如,1小时窗口每小时输出一次结果29。
滑动窗口:按滑动步长触发计算,频率更高。例如,1小时窗口每5分钟触发一次,输出过去1小时的数据25。 - 应用场景
滚动窗口:适合固定周期统计,如每日订单总量、每小时PV统计25。
滑动窗口:适合实时更新需求,如股票价格实时波动监测、过去10分钟用户点击量监控210。 - 技术实现关系
滚动窗口是滑动窗口的特殊情况:当滑动步长等于窗口大小时,滑动窗口退化为滚动窗口12。
3.springboot 为什么要升级springAlibaba
- 职责单一 ,可以方便业务量上来了拓展数据
- springCloud有很多高级特性,注册中心、配置中心、服务降级熔断器等等保证在各
- springboot单体代码复杂 冗余
4.ddd中的实际用了哪几种
概念:
VO(View Object):视图对象,⽤于展⽰层(如Controller),它的作⽤是把某个指定页⾯(或组件)的所有数据封装起来。
DTO(Data Transfer
Object):数据传输对象,这个概念来源于J2EE的设计模式,原来的⽬的是为了EJB的分布式应⽤提供粗粒度的数据实体,以减少分布式调⽤的次数,从⽽提⾼分布式调⽤的性能和降低⽹络负载,但在这⾥,我泛指⽤于展⽰层与服务层之间的数据传输对象。
DO(Domain Object):领域对象,就是从现实世界中抽象出来的有形或⽆形的业务实体。
PO(Persistent Object):持久化对象,它跟持久层(通常是关系型)的形成⼀⼀对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若⼲个)就对应PO的⼀个(或若⼲个)属性。
- 腾讯云智
1、线程数是3 ,任务有10怎么设计去执行线程数?
核心线程数和最大线程数设置为3,自定义一个arrayblockqueue队列,线程拒绝策略 自定义设置()
2、setnx expire 和redission区别 ?
setnx存在死锁问题,服务部署时候会进行锁不释放的问题
3、你们项目用的redis集群是 哨兵还是 redis集群
4、redis常见的 数据类型对应的一些使用场景
在项目用到了zset和set去做产品迭代更新, 限制数的使用, zset去设置用户操作的设备数,记录这段时间近期操作的设备,如果大于限制数,设备和zset去比较.
5、为什么B+数索引数据比较快?
非叶子节点存储的 键值对是主键和指向子节点的指针,叶子节点是B+树中存储实际数据的节点。
6、无侵入代码方式使用Redis实现缓存功能
Aop注解重写
7、hashMap扩容?
1.7扩容:
1.8扩容:
扩容机制核心方法Node<K,V>[] resize()
HashMap扩容可以分为三种情况:
第一种:使用默认构造方法初始化HashMap。从前文可以知道HashMap在一开始初始化的时候会返回一个空的table,并且thershold为0。因此第一次扩容的容量为默认值DEFAULT_INITIAL_CAPACITY也就是16。同时threshold =
DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR = 12。
第二种:指定初始容量的构造方法初始化HashMap。那么从下面源码可以看到初始容量会等于threshold,接着threshold =
当前的容量(threshold) * DEFAULT_LOAD_FACTOR。
第三种:HashMap不是第一次扩容。如果HashMap已经扩容过的话,那么每次table的容量以及threshold量为原有的两倍。
这边也可以引申到一个问题HashMap是先插入还是先扩容:HashMap是先插入数据再进行扩容的,但是如果是刚刚初始化容器的时候是先扩容再插入数据。
步骤:
resize()方法表示的在进行第一次初始化的时候会进行扩容。jdk1.8 之中做的优化就是对同一个桶的位置的进行判断,该元素的位置要么停留在原始位置,要么停止在原始位置+数组大小位置上。
而1.7是重新计算hash值,根据hash 值对其进行分发。
8、redis持久化机制
启用AOF持久化
在redis.conf 配置文件中设置
appendonly yes
开启混合持久化模式
aof-use-rdb-preamble yes
重启Redis服务
redis-cli shutdown
redis-server /path/to/redis.conf
AOF 文件的重写策略
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
AOF 文件同步策略(根据需要选择)
appendfsync everysec
定期创建 RDB 快照的配置(如果需要)
save 900 1 # 900秒(15分钟)内至少有1次写操作
save 300 10 # 300秒(5分钟)内至少有10次写操作
save 60 10000 # 60秒内至少有10000次写操作
9、Threadlocal有什么优缺点 使用场景是什么? 除了有内存泄漏导致的oom还有哪些问题
数据混乱的问题 和内容泄露的问题
美的外包
1、多级缓存一致性怎么解决?
依赖redis过期监听机制,通过监听 判断key存不存在然后删除本地缓存
依赖canal 对db进行修改,然后mq发生广播消息
2、RocketMq+本地消息表 你们是怎么做的
创建订单后的时候,,会在调用阿里、微信接口后,订单标识代支付状态,写入本地消息表,写入内容为支付订单号、支付状态,消息代处理,提交事务后,通过事务同步管理器
重写aftercommit方法
发生mq消息,,如果是支付成功,那么就更新消息表为已处理,支付失败为重试,消息表状态不变。在消息息补偿,启动定时任务去刷调用三方支付的接口。默认重试次数3次超过3次人工介入。
3、GC/死锁问题/OOM实际案例问题
1、oom问题,常见的是栈内存溢出、堆外内存分配、list对象add
2、GC 的问题 ,es功能上线后,出现overhead负载的问题,慢慢拖垮服务,导致最终的级联故障。解决方法 加大堆内存
3、JDK升级 原来的CMS垃圾回收器替换为G1回收器
4、es重构做了哪些搜索优化
1、冗余字段去除
2、主备索引,定时全量索引 + 增量更新
3、加大fileSystemCache
4、替换垃圾回收器、加大XMS XMN大小
5、
__END__