当前位置: 首页 > article >正文

流复制(Streaming Replication)与自动故障转移(Failover)实战:用Patroni或Repmgr搭建生产级数据库集群

更多服务器知识,尽在hostol.com

嘿,各位PostgreSQL的“掌舵人”和数据“守护神”们!咱们都知道,PostgreSQL(简称PG)以其强大的功能、稳定性和开源的特性,赢得了越来越多开发者和企业的青睐。但是,无论PG本身多么牛X,如果它只是孤零零地跑在一台服务器上,那它始终是一个“单点故障”(Single Point of Failure)。想象一下,万一这台服务器硬盘“寿终正寝”、电源“罢工不干”,或者机房网络“抖了一下”,你的核心数据库服务是不是就得跟着“歇菜”?那造成的业务中断和数据风险,简直不敢想!

“难道就没有办法让我的PG数据库像‘打不死的小强’一样坚挺吗?” 你可能会这么问。当然有!答案就是——高可用性(High Availability, HA)!通过构建一个PostgreSQL高可用集群,我们就能在主数据库发生故障时,让备份数据库(副本)迅速“上位”,接管服务,把停机时间缩短到极致,甚至让用户毫无察觉。今天,Hostol就带你深入PostgreSQL高可用的“核心秘境”,从理解基石技术——流复制(Streaming Replication)——开始,再到借助像Patroni或Repmgr这样的“智能指挥官”实现**自动故障转移(Automatic Failover)**,手把手教你搭建一个真正能扛事的“生产级”PostgreSQL数据库集群!


第一章:流复制(Streaming Replication)—— PG高可用的“奠基石”

要想实现高可用,首先得有“替补队员”吧?流复制就是为PostgreSQL培养“替补队员”(副本服务器,Standby/Replica Server)的核心技术。

1. 什么是流复制?—— 主库的“实时数字孪生”

简单来说,流复制就是主数据库(Primary Server)把它的“操作日记”——也就是**预写日志(Write-Ahead Log, WAL)**——几乎实时地、源源不断地“直播”给一个或多个副本服务器。副本服务器收到这些“日记”后,就在自己身上“重演”一遍主库所做的所有数据修改操作,从而使自己的数据状态与主库保持高度一致(或者只有非常微小的延迟)。

这就像是一位“速记员”(副本服务器)在旁边一字不差地记录下“主讲人”(主数据库)说的每一句话(数据变更),并把这些记录整理成册,使得自己手上的“讲稿副本”和主讲人的“原稿”几乎完全一样。

2. 流复制的“两种姿态”:异步 vs. 同步

  • 异步复制 (Asynchronous Replication): 这是默认且最常用的模式。主库在提交一个事务(比如INSERT, UPDATE, DELETE操作)时,它不会等待副本服务器确认收到并应用了对应的WAL日志。主库自己“搞定”就直接告诉客户端“事务成功了”。
    • 优点: 对主库的写入性能影响最小,因为不用等副本。
    • 缺点: 如果主库突然宕机,那么那些已经提交但在主库上还未来得及发送给副本的WAL日志就可能丢失,导致副本数据比主库落后一丁点(通常是毫秒到秒级),这可能造成少量数据丢失。这就是所谓的RPO(Recovery Point Objective,恢复点目标)大于零。
  • 同步复制 (Synchronous Replication): 主库在提交事务后,必须等待至少一个(或多个,可配置)“同步副本”确认已经收到(甚至已经应用)了相关的WAL日志后,才会向客户端报告“事务成功”。
    • 优点: 能保证在主库宕机时,至少有一个副本拥有所有已提交事务的数据,从而实现RPO为零(无数据丢失)。
    • 缺点: 会增加主库写操作的延迟,因为要等副本的确认。如果同步副本出现网络问题或自身故障,主库的写入也可能被阻塞。

选择哪种模式,取决于你对数据一致性和写入性能的权衡。大多数场景下,异步复制配合良好的监控和快速的故障转移,已经能满足需求。

3. 配置流复制的关键“开关”(postgresql.conf, pg_hba.conf, recovery.conf/standby.signal

搭建流复制,主要涉及修改以下几个地方的配置:

在主数据库服务器上:

  • postgresql.conf
    • wal_level = replica (或更高,如logical):必须设置为这个级别或更高,PG才会产生足够的WAL信息供复制使用。
    • max_wal_senders = 10 (示例值):允许同时连接到主库进行WAL流式传输的副本数量(或WAL发送进程数量)。
    • wal_keep_segments = 64 (示例值,老版本PG):在pg_wal目录(老版本是pg_xlog)中保留的旧WAL段文件的最小数量。如果副本落后太多,主库又清掉了它需要的WAL段,复制就会中断。 (注意: 新版本PG更推荐使用下面的“复制槽”)
    • archive_mode = onarchive_command = '...':强烈建议同时配置WAL归档。这样即使wal_keep_segments不够用,或者副本长时间离线,它也能从归档位置获取所需的WAL文件来追赶。
  • pg_hba.conf (主机访问控制文件): 需要添加规则,允许副本服务器以特定的复制用户连接到主库的replication“数据库”。 # TYPE DATABASE USER ADDRESS METHOD host replication your_repl_user replica_server_ip/32 md5 # or scram-sha-256

在副本数据库服务器上:

  • (对于PG 11及更早版本)创建一个recovery.conf文件在数据目录下,内容大致如下: [recovery.conf 内容示例 - 老版本PG] standby_mode = 'on' primary_conninfo = 'host=primary_server_ip port=5432 user=your_repl_user password=your_repl_password application_name=my_standby1' # restore_command = 'cp /path/to/archived_wals/%f "%p"' # 如果配置了WAL归档 # primary_slot_name = 'my_standby1_slot' # 如果使用了复制槽
  • (对于PG 12及更新版本)不再使用recovery.conf。你需要在数据目录下创建一个空的standby.signal文件,然后把primary_conninfoprimary_slot_name(如果用槽)等参数直接写入postgresql.conf文件,或者更推荐的是写入由postgresql.auto.conf管理的配置中(通常通过ALTER SYSTEM命令设置,或者在初始化副本时由pg_basebackup工具自动生成)。restore_command也移到了postgresql.conf中。

4. “复制槽” (Replication Slots) —— 防止WAL日志“失联”的保险丝

这是一个非常重要的特性!复制槽由副本在主库上创建。只要复制槽存在,主库就不会删除该副本尚未消费的WAL日志,即使副本长时间离线。这比单纯依赖wal_keep_segments更可靠,能有效防止因副本落后太多而导致的复制中断和需要全量重建副本的麻烦。但也要注意监控复制槽的状态,如果副本永久下线,记得在主库上删除对应的复制槽,否则主库磁盘可能会被旧的WAL日志撑满。


第二章:自动故障转移 —— 当“主讲人”突然“晕倒”时

流复制解决了数据冗余的问题,我们有了“热乎”的副本。但如果主库真的不幸宕机了(比如硬件故障、操作系统崩溃),怎么办?

我们可以手动操作:登录到一台最新的副本服务器,执行pg_ctl promote (老版本用trigger_file) 将其提升为新的主库,然后修改所有应用的数据库连接字符串指向这个新主库,再让其他副本也指向这个新主库……天哪,如果这事儿发生在凌晨三点,等你睡眼惺忪地做完这一套,业务可能已经中断了半天了!

所以,我们需要一个“智能调度系统”,能够:

  1. 自动检测主库是否真的“挂了”。
  2. 在确认主库故障后,从众多副本中自动选举一个最合适的“继任者”。
  3. 自动将“继任者”提升为新的主库。
  4. 自动通知其他副本“换大哥了”,让它们开始从新主库复制数据。
  5. (理想情况下)还能自动更新应用的数据库连接指向,或者通过某种方式(如VIP漂移、DNS更新)让应用无感知地连到新主库。

这就是“自动故障转移”的魅力!而Patroni和Repmgr就是能帮我们实现这套复杂逻辑的两位“大内总管”。


第三章:认识“大内总管” —— Patroni 与 Repmgr

这两位都是PostgreSQL社区广泛使用的开源HA管理工具。

1. Patroni:云原生时代的“民主选举委员会主席”

  • 特点: Python编写,非常灵活和强大。它依赖一个分布式配置存储(DCS),比如etcd、Consul、ZooKeeper,甚至是Kubernetes API,来进行集群成员管理、领导者选举(Leader Election)、配置共享和状态同步。
  • 工作方式: Patroni在每个PG节点上运行一个守护进程,这些进程通过DCS进行通信和协调。DCS就像是它们的“联合国安理会”,大家在这里投票选出“带头大哥”(主库)。如果主库失联,其他节点会通过DCS重新选举。Patroni还会动态管理PostgreSQL的配置文件(postgresql.conf),确保复制等设置正确。
  • 优点: 功能全面,高度可定制(通过回调脚本可以实现非常复杂的故障转移逻辑,如VIP管理、通知等),与Kubernetes等云原生环境集成良好,社区活跃。
  • 缺点: 依赖外部DCS,增加了架构的复杂度。配置相对Repmgr可能稍复杂一些。
  • 把它想象成: 一个由各成员节点组成的“议会”,通过一个高度可靠的“中央选举系统”(DCS)来民主选举和罢免“总统”(主库),并自动处理权力交接。

2. Repmgr:传统运维的“忠诚卫队长”

  • 特点: C语言编写(守护进程repmgrd)配合SQL脚本,更侧重于PostgreSQL自身的管理。它在每个PG实例中创建自己的元数据表来存储集群信息。
  • 工作方式: repmgrd守护进程在每个节点上运行,监控本地PG实例和主库的状态。当主库故障时,它会根据配置(比如是否有见证服务器Witness Server来帮助判断、选举策略等)来决定是否执行故障转移,并协调副本的提升和重新指向。
  • 优点: 相对Patroni来说,不强制依赖外部的DCS(虽然推荐使用见证服务器来避免脑裂),对于一些不想引入额外组件的简单环境,可能更容易上手。有清晰的命令行工具进行管理。
  • 缺点: 在某些复杂场景下的灵活性和自动化程度可能不如Patroni。对PostgreSQL版本的依赖可能更紧密一些。
  • 把它想象成: 一支经验丰富、纪律严明的“皇家卫队”,当“国王”(主库)出意外时,他们会按照既定的“王位继承法”(配置和选举逻辑)迅速拥立“王储”(最优副本)登基。

如何选择?

  • 如果你追求与Kubernetes等云原生生态的深度集成,需要非常灵活的定制能力,并且不介意引入etcd/Consul等DCS组件,那么Patroni可能是更好的选择。
  • 如果你的环境相对简单,或者你更倾向于一个轻量级、对外部依赖较少的方案,并且主要依赖PostgreSQL自身机制,那么Repmgr可能更适合你。

(由于篇幅限制,我们下面以**Patroni配合etcd**的思路,简要介绍一下搭建HA集群的核心步骤和考量,Repmgr的思路有共通之处,但具体命令和配置会有所不同。)


第四章:实战演练 —— 用Patroni打造“打不死”的PG集群(概念流程)

搭建一个完整的生产级Patroni集群是个细致活,这里我们主要梳理核心步骤和思想。

假设环境: 你有至少三台服务器(一台做主,一台做备,一台可以做纯etcd节点,或者也跑PG作为第三个副本兼顾仲裁)。一个etcd集群(通常至少3个节点保证高可用)。

  1. 基础准备:所有节点安装PostgreSQL和Patroni 确保所有预期的PG节点上都安装了相同大版本的PostgreSQL,以及Patroni和它所依赖的Python库(如psycopg2-binary, python-etcd等)。
  2. 配置etcd集群(如果还没有的话) Patroni需要一个稳定运行的etcd集群(或Consul/ZooKeeper)来存储集群状态和进行领导者选举。etcd自身的HA部署也很重要。
  3. 为每个PG节点编写Patroni配置文件 (patroni.yml) 这是Patroni的核心。每个节点上的patroni.yml内容大部分相同,但会有一些节点特定的配置(比如节点名)。关键配置项包括: # patroni.yml 示例片段 scope: my_pg_cluster # 集群名称,所有节点必须一致 namespace: /service/ # 在DCS中存储此集群信息的基础路径 # PostgreSQL相关配置 (Patroni会用这些信息来初始化和管理PG) bootstrap: dcs: postgresql: use_pg_rewind: true # 推荐开启,方便旧主库恢复后快速作为新副本加入 # ...其他bootstrap参数... # initdb的参数,或者pg_basebackup的参数等 # Patroni会负责初始化第一个节点(主库),其他节点会自动从主库做pg_basebackup # DCS连接信息 (以etcd为例) etcd: hosts: etcd1_ip:2379,etcd2_ip:2379,etcd3_ip:2379 # 你的etcd集群地址 # ttl: 30 # loop_wait: 10 # PostgreSQL本地配置 postgresql: listen: '0.0.0.0:5432' # PG监听的地址和端口 connect_address: 'this_node_ip:5432' # 本节点对外的连接地址 data_dir: /var/lib/postgresql/14/main # PG数据目录 # Patroni会管理postgresql.conf和pg_hba.conf的部分内容 # 你可以在这里指定一些你想让Patroni设置的PG参数 parameters: max_connections: '100' # ... 其他PG参数 ... authentication: replication: username: your_repl_user password: your_repl_password # 实际生产中用更安全的方式管理密码 # ... 其他用户的认证规则 ... # REST API配置 (Patroni自身提供API供管理和监控) restapi: listen: '0.0.0.0:8008' connect_address: 'this_node_ip:8008' # ...可选的认证配置... # 回调脚本 (可选,用于在特定事件发生时执行自定义操作,如VIP漂移、发通知等) # watchdog: # mode: automatic # device: /dev/watchdog # safety_margin: 5
  4. 启动Patroni服务 在所有节点上,用类似patroni /path/to/patroni.yml的方式启动Patroni服务(通常会把它配置成系统服务,如systemd unit)。Patroni启动后,会连接到DCS,进行领导者选举。第一个成功初始化(或已存在主库)的集群,会有一个节点成为主(Leader),其他节点会自动配置为从该主库进行流复制的副本(Replica)。
  5. 监控集群状态 可以使用patronictl -c /path/to/patroni.yml list命令查看集群状态,哪个是主,哪些是备,复制延迟等。
  6. 模拟与测试故障转移! 这是**最最最重要**的一步!搭建好集群不是结束,而是开始!你必须反复测试各种故障场景:
    • 手动停止主库的PostgreSQL服务:sudo systemctl stop postgresql。观察Patroni是否能自动将一个副本提升为新主。
    • 模拟主库网络故障:用防火墙断开主库与DCS及副本的网络连接。
    • 测试手动切换(Switchover):使用patronictl switchover命令进行计划内的主备切换。
    在每次测试后,都要验证数据一致性、应用是否能自动连接到新主库、旧主库恢复后是否能正确作为新副本加入集群等。

应用如何连接到“永远的主库”?

既然主库可能随时“漂移”,应用总不能写死一个IP吧?常用方案有:

  • VIP (虚拟IP) + Keepalived/Corosync+Pacemaker: Patroni可以通过回调脚本,在主库上激活一个VIP,在故障转移后将VIP漂移到新主库上。应用始终连接这个VIP。
  • DNS更新: 通过Patroni回调脚本,在故障转移后更新内部DNS记录,让应用通过一个固定的域名连接。但DNS缓存可能导致切换不及时。
  • 负载均衡器/连接代理: 在应用和PG集群之间放一个像HAProxy、PgBouncer(配置为会话模式并能感知主库变化)这样的中间件。它们负责探测当前哪个是主库,并将连接路由过去。Patroni的REST API可以帮助这些中间件获取当前主库信息。
  • Kubernetes环境: 如果PG跑在K8s里,Patroni可以更新K8s的Service和Endpoints,让应用通过Service名访问主库。


生产级HA集群的“必修课”:

  • 数据一致性与复制模式: 仔细权衡异步与同步复制对你的业务RPO和性能的影响。Patroni支持配置同步复制。
  • 网络延迟是天敌: 主库、副本、DCS节点之间的网络必须低延迟、高可靠。跨地域部署时尤其要注意。
  • 备份策略不能丢: HA集群主要解决的是服务可用性问题,不是数据备份问题!你仍然需要定期对数据库进行物理备份(如pg_basebackup)和逻辑备份(pg_dump),并确保备份在异地存储。
  • 监控!监控!监控! 不仅要监控PostgreSQL本身,还要监控Patroni服务状态、DCS集群健康、复制延迟、磁盘空间、VIP状态等等。
  • 理解“脑裂”(Split-Brain)并避免它: 当网络分区导致集群成员无法互相通信时,可能出现多个节点都以为自己是主库的情况,这就是“脑裂”,非常危险。DCS(如etcd的Raft协议)和Patroni的领导者选举机制,以及repmgr的见证服务器和仲裁逻辑,都是为了最大限度地避免这种情况。确保你的DCS集群本身是高可用的!
  • 定期演练: 不要等真的出事了才发现HA配置有问题。定期进行故障转移演练,就像消防演习一样,能让你在真正灾难来临时从容应对。


呼~PostgreSQL的高可用集群,是不是感觉像是在构建一个精密的“星际舰队”?从流复制这个“引擎核心”,到Patroni/Repmgr这些“智能导航与指挥系统”,再到VIP、负载均衡这些“对接港口”,每一个环节都至关重要。搭建和维护一套生产级的PG高可用集群,确实是对运维人员技术和经验的极大考验。但一旦成功,它为你带来的那种“数据永不眠,服务永不歇”的安心感,绝对是无与伦比的!Hostol希望这篇“高可用进阶指南”能为你点亮通往更稳定、更可靠数据库架构的道路。记住,理论与实践相结合,不断测试与优化,才能真正驾驭这头强大的“大象”!

相关文章:

流复制(Streaming Replication)与自动故障转移(Failover)实战:用Patroni或Repmgr搭建生产级数据库集群

更多服务器知识,尽在hostol.com 嘿,各位PostgreSQL的“掌舵人”和数据“守护神”们!咱们都知道,PostgreSQL(简称PG)以其强大的功能、稳定性和开源的特性,赢得了越来越多开发者和企业的青睐。但…...

OpenGL Chan视频学习-10 Dealing with Errors in OpenGL

bilibili视频链接: 【最好的OpenGL教程之一】https://www.bilibili.com/video/BV1MJ411u7Bc?p5&vd_source44b77bde056381262ee55e448b9b1973 函数网站: docs.gl 说明: 1.之后就不再单独整理网站具体函数了,网站直接翻译会…...

美团启动618大促,线上消费节被即时零售传导到线下了?

首先,从市场推广与消费者吸引的角度来看,美团通过联合众多品牌开展大规模促销活动,并发放高额优惠券包,旨在吸引更多消费者参与购物。这种策略有助于提高平台的活跃度和交易量,同时也能够增强用户粘性。对于消费者而言…...

搭建 Select 三级联动架构-东方仙盟插件开发 JavaScript ——仙盟创梦IDE

三级级联开卡必要性 在 “东方仙盟” 相关插件开发中,使用原生 HTML 和 JavaScript 实现三级联动选择(如村庄 - 建筑 - 单元的选择)有以下好处和意义,学校管理: 对游戏体验的提升 增强交互性:玩家能够通…...

服务器如何配置防火墙管理端口访问?

配置服务器防火墙来管理端口访问,是保障云服务器安全的核心步骤。下面我将根据你使用的不同操作系统(Linux: Ubuntu/Debian/CentOS;Windows Server)介绍常用防火墙配置方法。 ✅ 一、Linux 防火墙配置(UFW / firewalld…...

Webhook入门

主要参考资料: 深入解析 Webhook:从原理到实践的全面指南: https://blog.csdn.net/weixin_43114209/article/details/144250750 目录 简介Webhook 与传统 API 调用的区别与轮询 (Polling) 的对比典型工作流程 简介 简单来说,Webhook 是一种“…...

LangChain整合Milvus向量数据库实战:数据新增与删除操作

导读:在AI应用开发中,向量数据库已成为处理大规模语义搜索和相似性匹配的核心组件。本文通过详实的代码示例,深入探讨LangChain框架与Milvus向量数据库的集成实践,为开发者提供生产级别的向量数据管理解决方案。 文章聚焦于向量数…...

LSTM+Transformer混合模型架构文档

LSTMTransformer混合模型架构文档 模型概述 本项目实现了一个LSTMTransformer混合模型,用于超临界机组协调控制系统的数据驱动建模。该模型结合了LSTM的时序建模能力和Transformer的自注意力机制,能够有效捕捉时间序列数据中的长期依赖关系和变量间的复…...

Symbol、Set 与 Map:新数据结构探秘

Symbol、Set 与 Map:新数据结构探秘 引言 ECMAScript 6 (ES6) 引入了三种强大的数据结构:Symbol、Set 与 Map,它们解决了 JavaScript 开发中的特定痛点,为我们提供了更多工具来处理复杂的数据操作。 Symbol:唯一标识…...

Spring Boot+Activiti7入坑指南初阶版

介绍  Activiti 是一个轻量级工作流程和业务流程管理 (BPM) 平台,面向业务人员、开发人员和系统管理员。其核心是一个超快且坚如磐石的 Java BPMN 2 流程引擎。它是开源的,并根据 Apache 许可证分发。Activiti 可以在任何 Java 应用程序、服务器、集群或云中运行。它与 Spri…...

如何在 Odoo 18 中创建 PDF 报告

如何在 Odoo 18 中创建 PDF 报告 Qweb 是 Odoo 强大的模板引擎,旨在轻松将 XML 数据转换为 HTML 文档。其功能特性包括基于属性的自定义、条件逻辑、动态内容插入及多样化的报告模板选项。这种多功能性使 Qweb 成为制作个性化、视觉吸引力强的报告、电子邮件和文档…...

【ROS2实体机械臂驱动】rokae xCoreSDK Python测试使用

【ROS2实体机械臂驱动】rokae xCoreSDK Python测试使用 文章目录 前言正文配置环境下载源码配置环境变量测试运行修改点说明实际运行情况 参考 前言 本文用来记录 xCoreSDK-Python的调用使用1。 正文 配置环境 配置开发环境,这里使用conda做python环境管理&…...

c/c++的opencv椒盐噪声

在 C/C 中实现椒盐噪声 椒盐噪声(Salt-and-Pepper Noise),也称为脉冲噪声(Impulse Noise),是数字图像中常见的一种噪声类型。它的特点是在图像中随机出现纯白色(盐)或纯黑色&#x…...

C++ TCP程序增加TLS加密认证

TCP为什么要增加TLS TCP程序添加TLS主要是为了解决TCP协议本身的安全缺陷。TCP作为传输层协议,虽然提供了可靠的数据传输,但它是明文传输,存在几个关键的安全问题: 数据泄露风险:TCP传输的数据完全暴露在网络中,任何能够监听网络流量的人都可以直接读取传输内容。这对于…...

构建一个“论文检索 + 推理”知识库服务,支持用户上传 PDF/LATEX 源码后,秒级检索并获得基于内容的问答、摘要、引用等功能

文章目录 1 总体目标 / Overall Goal2 数据管线 / Data Pipeline3 检索策略 / Retrieval Strategy4 服务切分 / Service Decomposition5 Agent & Prompt 设计 / Agent & Prompt6 核心功能 / Core Features7 评测与监控 / Evaluation & Monitoring8 面试亮点 / Inte…...

VLC-QT 网页播放RTSP

先看效果图,代码在文章末尾,包含源码,vlc-qt完整的库 环境说明:VS 2017 QTQt5.13.0 MSVC2017 32位 将vlc_install 目录下的bin,include,lib里所有的东西分别放在qt目录下 bin -> C:\Qt\Qt5.13.0\5.13.0\msvc2017\bin include->C:\Qt\Qt5.13.0\5.13.0\msvc201…...

for(auto a:b)和for(auto a:b)的区别

#include<iostream> using namespace std; int main() {string s( "hello world" );for (auto c:s)c t ;cout<<s<<endl; //结果为hello worldfor (auto &c:s)c t ;cout<<s<<endl; //结果为ttttttttttt }for(auto a:b)中b为一…...

第2章-12 输出三角形面积和周长(走弯路解法)

本题要求编写程序&#xff0c;根据输入的三角形的三条边a、b、c&#xff0c;计算并输出面积和周长。注意&#xff1a;在一个三角形中&#xff0c; 任意两边之和大于第三边。三角形面积计算公式&#xff1a;areas(s−a)(s−b)(s−c)​&#xff0c;其中s(abc)/2。 import math de…...

Caddy如何在测试环境中使用IP地址配置HTTPS服务

前言 在开发和测试环境中&#xff0c;我们经常需要搭建HTTPS服务进行测试。但通常Let’s Encrypt等证书颁发机构要求使用有效域名&#xff0c;不直接支持IP地址。本文将详细介绍如何使用Caddy在测试环境中通过IP地址配置HTTPS服务&#xff0c;使用自签名证书解决这一问题。 环…...

shell中与>和<相关的数据流重定向操作符整理

shell中与>和<相关的数据流重定向操作符整理 输出重定向操作符>>>2>2>>&> 或 >&&>> 输入重定向操作符<<<<<< 组合重定向2>&1 文件描述符相关重定向[n]< file 和 [n]> file>&- 和 <&…...

【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix

【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix 文章目录 【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix一、资料准备1.去畸变影像2.相机文件3.外方位元素二、创建工程1.新建工程2.导入照片3.编辑相机文件4.编辑外方位元素文件,导入外方位元…...

创建型设计模式之Prototype(原型)

创建型设计模式之Prototype&#xff08;原型&#xff09; 摘要&#xff1a; Prototype&#xff08;原型&#xff09;设计模式通过复制现有对象来创建新对象&#xff0c;避免重复初始化操作。该模式包含Prototype接口声明克隆方法、ConcretePrototype实现具体克隆逻辑&#xff…...

JNI开发流程

一. 引言 最近在做一个自己的项目&#xff0c;就是基于FastDDS封装一套JAVA库&#xff0c;让android和java应用可以使用dds的功能。 由于FastDDS是使用C编写的开源库&#xff0c;因此java的类库想要调用FastDDS的接口&#xff0c;需要额外编写一个JNI层的动态库对FastDDS的接口…...

STM32G4 电机外设篇(二) VOFA + ADC + OPAMP

目录 一、STM32G4 电机外设篇&#xff08;二&#xff09; VOFA ADC OPAMP1 VOFA1.1 VOFA上位机显示波形 2 ADC2.1 用ADC规则组对板载电压和电位器进行采样 3 OPAMP&#xff08;运放&#xff09;3.1 结合STM32内部运放和ADC来完成对三相电流的采样3.2 运放电路分析 附学习参考…...

RAG应用:交叉编码器(cross-encoder)和重排序(rerank)

文章目录 Sentence Transformers交叉编码器交叉编码器使用示例检索和重排序Sentence Transformers Sentence Transformers 支持两种类型的模型: Bi-encoders 和 Cross-encoders。Bi-encoders 更快更可扩展,但 Cross-encoders 更准确。虽然两者都处理类似的高水平任务,但何时…...

微服务难题?Nacos服务发现来救场

文章目录 前言1.什么是服务发现2.Nacos 闪亮登场2.1 服务注册2.2 服务发现 3.Nacos 的优势3.1 简单易用3.2 高可用3.3 动态配置 4.实战演练4.1安装 Nacos4.2 服务注册与发现示例代码&#xff08;以 Spring Boot 为例&#xff09; 总结 前言 大家好&#xff0c;我是沛哥儿。今天…...

C# 结合PaddleOCRSharp搭建Http网络服务

Windows打开端口&#xff1a; 控制面板 > 系统和安全 > 防火墙> 高级设置 → 入站规则 → 右侧选择 → 新建规则 → 端口 → 协议类型 TCP→ 端口 using System; using System.Drawing; using System.IO; using System.Net; using System.Text; using System.Threadi…...

【连接器专题】SD卡座规格书审查需要审哪些方面?

在审查SD卡座规格书时,我们需要考虑哪些方面? 首先在拿到一份SD卡座的详细规格书时,一般供应商给到的规格书中包括了一些基础信息、产品图纸信息、技术参数信息,同时有些供应商会给出产品可靠性测试报告。因此我们会从这几个要素去看规格书。 基础信息 基础信息一般会给变更…...

JS手写代码篇---手写节流函数

8、节流函数 什么是节流函数&#xff1f; 指规定一个单位时间&#xff0c;在这个单位时间内&#xff0c;只能有一次触发事件的回调函数执行&#xff0c;如果在同一个单位时间内某事件被触发多次&#xff0c;只有一次能生效。 与防抖函数有什么区别&#xff1f; 防抖函数是延…...

UE5 C++动态调用函数方法、按键输入绑定 ,地址前加修饰符

UE5 C动态调用函数方法、按键输入绑定 &#xff0c;地址前加修饰符&&#xff0c;这个符号忘记输入的话&#xff0c;编译一直报错不通过 void ASnakeHead::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { Super::SetupPlayerInputComponent(PlayerIn…...