- Published on
interviewer
- 多协程ffmpeg
- sync.Once原理
- upstash redis.
- nitro server
- hono 解决差异
# 线程死锁怎么产生?怎么避免?
死锁产生的四个必要条件:
- 互斥:一个资源每次只能被一个进程使用
- 请求与保持:一个进程因请求资源而阻塞时,不释放获得的资源
- 不剥夺:进程已获得的资源,在未使用之前,不能强行剥夺
- 循环等待:进程之间循环等待着资源
避免死锁的方法:
- 互斥条件不能破坏,因为加锁就是为了保证互斥
- 一次性申请所有的资源,避免线程占有资源而且在等待其他资源
- 占有部分资源的线程进一步申请其他资源时,如果申请不到,主动释放它占有的资源
- 按序申请资源
rabbitmq消息可靠性保证?
rabbitmq事务
raocketmq的流式计算
面向SOA
简单对象访问协议(SOAP) • RESTful HTTP • Apache Thrift • Apache ActiveMQ • Java Message Service(JMS)
bilibili京东问题
github java-learning
raft
Raft 协议是一种用于实现分布式系统中的一致性的算法,它被设计为易于理解和实现。Raft 协议的目标是确保集群中的多个节点能够在状态和数据上保持一致,即便在部分节点发生故障的情况下也能维持系统的正常运行。Raft 实现了一种称为 "共识" 的机制,通过共识,集群中的所有节点最终能够同意特定的值或状态。
Raft 协议的工作过程可以概括为以下几个关键点:
1. 角色分配
Raft 协议将集群中的节点分为三种角色:Leader(领导者)、Follower(跟随者)和Candidate(候选人)。集群在任何时候只能有一个 Leader,它负责处理客户端请求和数据复制。Follower 通常处于被动接收状态,而 Candidate 用于在 Leader 故障时选举新的 Leader。
2. 领导选举
- 选举启动:当 Follower 在一定时间内没有收到来自 Leader 的消息时,它会变成 Candidate 并发起一次新的选举。
- 投票:Candidate 为自己投票,并向其他节点请求投票。如果一个节点在当前的 "选举期" 内还没有投票,则它可以投票给 Candidate。
- 选举成功:如果 Candidate 获得了集群大多数节点的投票,它就成为新的 Leader。
3. 日志复制
- 日志条目:Leader 接收来自客户端的请求,将请求作为日志条目追加到自己的日志中。
- 复制给 Follower:然后 Leader 将这些日志条目并行地复制到所有 Follower 节点上,并等待大多数 Follower 确认收到。
- 提交条目:一旦这些条目被大多数节点接收,Leader 将条目标记为已提交,并通知 Follower 提交这些条目。
4. 安全性和一致性
- 任期(Term):Raft 通过任期概念来避免旧 Leader 的干扰。每次选举都会增加任期的计数,节点在投票时检查任期,确保数据的一致性和安全性。
- 日志匹配:在日志复制过程中,Leader 会确保 Follower 的日志与自己的保持一致。如果发现不一致,Leader 会逐步回退其日志索引,直到找到一致的点,然后从那里开始重新复制。
5. 客户端交互
客户端请求通常只能通过 Leader 进行处理。如果客户端连接到的是 Follower,Follower 会重定向请求到当前的 Leader。
Raft 协议通过这些机制提供了一种相对简单且有效的方式来实现分布式系统的共识,确保了分布式系统中数据的一致性和系统的高可用性。
raft一致性
Raft 协议体现强一致性主要通过以下几个关键机制:
领导者选举与任期机制:Raft 通过任期概念(Term)来防止过时的领导者信息干扰当前的领导者和集群状态。每个任期开始时都会选举出一个新的领导者。这保证了在任何给定的任期内,最多只有一个领导者被选举出来,确保了领导者的唯一性。当节点接收到来自领导者的请求时,它们会检查请求中的任期号。如果请求的任期号小于节点的当前任期号,请求会被拒绝。这确保了只有当前任期的领导者能够影响集群状态,从而维护了一致性。
日志复制:领导者将客户端的请求作为日志条目追加到自己的日志中,然后负责将这些日志条目复制到集群中的所有跟随者。只有当大多数节点都已复制了日志条目,领导者才会将该条目标记为已提交。这种机制确保了集群中大多数节点存有相同的日志副本,进一步保证了一致性。
日志一致性检查:在日志复制过程中,领导者还负责确保自己的日志和跟随者的日志保持一致。领导者在复制新的日志条目之前,会检查跟随者的日志是否与自己的日志相匹配。如果发现不匹配,领导者会逐步减少复制的日志索引,直到找到匹配的日志条目为止。这确保了所有的跟随者最终将具有与领导者相同的日志顺序,进一步强化了数据的一致性。
提交与应用日志条目:日志条目只有在被大多数节点复制后才会被提交,这保证了即使在发生故障转移的情况下,已提交的日志条目也不会丢失,因为任何新的领导者都会包含大多数节点已复制的所有提交条目。这意味着系统的状态变更(基于日志条目的应用)只有在保证了跨集群多数节点的一致性后才会发生。
通过这些机制,Raft 协议确保了即使在网络分区、节点故障等不稳定的环境下,集群也能够维持强一致性,保证任何时刻系统状态的一致性,从而使得分布式系统作为一个整体运行,对外提供一致且可靠的服务。
rabbitmq集群
Erlang 分布式系统:RabbitMQ 节点运行在一个 Erlang 节点上,这些 Erlang 节点形成一个分布式系统。在这个系统中,节点可以直接通过 Erlang 的消息传递机制相互通信。这种通信机制是透明的,允许跨节点的进程间通信就像是同一个节点上的进程间通信一样。
队列镜像:当在 RabbitMQ 集群中配置镜像队列时,队列的主副本将位于创建队列的节点上,而其他节点可以有一个或多个镜像副本。这些副本会订阅到主副本的状态变更事件,包括消息的发布、确认和删除。
消息同步:当生产者向镜像队列发送消息时,消息首先被发送到拥有队列主副本的节点。然后,这个节点负责将消息分发到其他拥有镜像副本的节点。这通过 Erlang 的分布式消息传递系统完成,确保所有副本都有相同的消息顺序和内容。
故障转移和选举:如果持有队列主副本的节点失败,集群中的其他节点会通过一种选举机制来选出一个新的节点作为队列的主副本。这个过程同样依赖于 Erlang 的通信机制来协调和同步状态。
心跳和健康检查:RabbitMQ 节点通过发送心跳消息来检测彼此的可达性和健康状态。这些心跳也是通过 Erlang 的分布式系统机制来实现的,帮助系统及时发现和响应节点故障。
rabbitmq延迟队列
rabbitmq延迟队列的原理
使用ffmpeg解决视频时间戳错乱的问题【QS】
ffmpeg 提供了多种方式来处理和修正视频文件中的时间戳问题。虽然 -vsync 0 参数指示 ffmpeg 不对帧进行额外的同步(即,尽可能地保留源中的所有帧,包括那些可能导致时间戳问题的帧),但这并不意味着它会修正时间戳问题。相反,-vsync 参数的其他值可以用于处理不同的时间戳和帧率问题,从而间接地“修正”时间戳问题。
使用 -vsync 修正时间戳问题
-vsync 1或-vsync cfr(默认值):这会使ffmpeg生成恒定帧率(CFR)的输出,通过在必要时重复或丢弃帧来确保每个输出帧都有连续的时间戳。这对于确保输出视频与预期的帧率匹配非常有用,特别是当源视频的时间戳不连续或不规则时。-vsync 2或-vsync vfr:这允许ffmpeg生成变帧率(VFR)的输出,保持源帧的原始时间戳。这在源视频的帧率确实变化时有用,但需要确保目标播放器或设备支持 VFR 视频。-vsync drop:这指示ffmpeg丢弃在视频转码过程中多余的帧,用于避免时间戳重叠或其他同步问题。这可能有助于修正源视频中由于帧过多而导致的时间戳不连续问题。
修正不连续或不规则时间戳
如果目的是直接修正源视频中的时间戳不连续或不规则问题,可以考虑以下策略:
重新封装(不重新编码):通过使用
ffmpeg仅重新封装视频流而不重新编码,有时可以解决轻微的时间戳问题。这可以通过指定与源相同的编解码器但输出到新容器实现,例如:ffmpeg -i input.mp4 -c copy output.mp4强制恒定帧率:对于时间戳严重不连续的视频,强制将视频转码为恒定帧率(CFR)可能有助于“平滑”时间戳,并确保输出视频的播放更加平稳。这需要重新编码:
ffmpeg -i input.mp4 -r 30 -vsync cfr output.mp4在这里,
-r 30指定了希望的输出帧率为 30fps。
总的来说,ffmpeg 提供了灵活的选项来处理时间戳问题,但最佳的处理方法取决于问题的具体性质和目标视频的要求。在某些情况下,简单的重新封装就足够了;在其他情况下,则可能需要更复杂的处理,如重新编码。