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

CentOS 7上搭建高可用BIND9集群指南

在 CentOS 7 上搭建一个高可用的 BIND9 集群通常涉及以下几种关键技术和策略的组合:主从复制 (Master-Slave Replication)、负载均衡 (Load Balancing) 以及可能的浮动 IP (Floating IP) 或 Anycast。

在这里插入图片描述

我们将主要关注主从复制负载均衡的实现,这是构成高可用 DNS 集群的核心。

场景假设:

  • 域名: mycluster.local
  • 主 DNS 服务器 (Master):
    • IP: 192.168.1.10
    • Hostname: dns-master.mycluster.local
  • 从 DNS 服务器 1 (Slave 1):
    • IP: 192.168.1.11
    • Hostname: dns-slave1.mycluster.local
  • 从 DNS 服务器 2 (Slave 2):
    • IP: 192.168.1.12
    • Hostname: dns-slave2.mycluster.local
  • 负载均衡器/虚拟 IP (VIP):
    • IP: 192.168.1.100 (客户端将使用此 IP 作为 DNS 服务器)

核心组件:

  1. BIND9 主从复制:
    • 主服务器 (Master) 维护权威的区域数据文件。
    • 从服务器 (Slaves) 定期从主服务器同步区域数据。
    • 当主服务器上的区域数据更新时,它会通知从服务器进行更新。
  2. 负载均衡器:
    • 将客户端的 DNS 请求分发到后端的多个 BIND 从服务器(或包括主服务器)。
    • 可以使用硬件负载均衡器 (如 F5, Citrix ADC) 或软件负载均衡器 (如 HAProxy, Nginx, LVS)。
    • 对于简单的 DNS 负载均衡,也可以使用 DNS 轮询 (Round Robin DNS),但这不提供故障检测和自动切换。
  3. (可选) Keepalived 实现 VIP 和健康检查:
    • Keepalived 可以管理一个虚拟 IP (VIP),并在主负载均衡器节点故障时将其漂移到备用节点。
    • 它可以对后端 BIND 服务器进行健康检查,如果某个 BIND 服务器故障,则将其从负载均衡池中移除。

步骤一:在所有节点上安装 BIND9

dns-master, dns-slave1, dns-slave2 上执行:

sudo yum update -y
sudo yum install -y bind bind-utils

步骤二:配置主 DNS 服务器 (dns-master)

  1. 编辑 /etc/named.conf (options 部分):

    sudo vi /etc/named.conf
    
    options {listen-on port 53 { 127.0.0.1; 192.168.1.10; }; // 监听自己的IPlisten-on-v6 port 53 { ::1; };directory       "/var/named";dump-file       "/var/named/data/cache_dump.db";statistics-file "/var/named/data/named_stats.txt";memstatistics-file "/var/named/data/named_mem_stats.txt";allow-query     { localhost; 192.168.1.0/24; }; // 允许内网查询recursion no;                                   // 作为权威服务器allow-recursion { none; };// 允许从服务器进行区域传送allow-transfer { 192.168.1.11; 192.168.1.12; };dnssec-enable yes;dnssec-validation yes; // 或 no,如果纯权威且不解析外部pid-file "/run/named/named.pid";// ... 其他默认选项 ...
    };logging {channel default_debug {file "data/named.run";severity dynamic;};
    };include "/etc/named.rfc1912.zones";
    include "/etc/named.root.key";
    
  2. 编辑 /etc/named.rfc1912.zones (定义区域):

    sudo vi /etc/named.rfc1912.zones
    

    在文件末尾添加:

    zone "mycluster.local" IN {type master;file "db.mycluster.local"; // 区域数据文件名allow-update { none; };// 主动通知从服务器有更新also-notify { 192.168.1.11; 192.168.1.12; };
    };// 示例反向区域
    zone "1.168.192.in-addr.arpa" IN {type master;file "db.192.168.1";allow-update { none; };also-notify { 192.168.1.11; 192.168.1.12; };
    };
    
  3. 创建区域文件 (例如 /var/named/db.mycluster.local):

    sudo vi /var/named/db.mycluster.local
    
    $TTL 86400
    @       IN      SOA     dns-master.mycluster.local. admin.mycluster.local. (2023072101      ; Serial (YYYYMMDDNN)3600            ; Refresh1800            ; Retry604800          ; Expire86400 )         ; Minimum TTL
    ; Name Servers for the zone (these will be the VIP or individual server IPs clients might use)
    ; For HA, clients should point to the VIP. These NS records are for delegation.
    @       IN      NS      dns-vip.mycluster.local. ; 或者直接写 VIP IP 的 PTR 记录对应的主机名
    ; @       IN      NS      dns-master.mycluster.local. ; 也可以列出所有服务器
    ; @       IN      NS      dns-slave1.mycluster.local.
    ; @       IN      NS      dns-slave2.mycluster.local.; A Records for Name Servers (actual IPs)
    dns-master      IN      A       192.168.1.10
    dns-slave1      IN      A       192.168.1.11
    dns-slave2      IN      A       192.168.1.12
    dns-vip         IN      A       192.168.1.100 ; VIP; Other records
    server1         IN      A       192.168.1.50
    web             IN      CNAME   server1.mycluster.local.
    

    重要:

    • SOA 记录中的主NS应为 dns-master.mycluster.local.
    • NS 记录应指向客户端实际用于查询的DNS服务器名称。如果使用VIP,则指向VIP对应的主机名。如果客户端可能直接查询各个节点,则列出所有节点。
    • 每次修改区域文件后,务必增加 Serial 号码
  4. 创建反向区域文件 (例如 /var/named/db.192.168.1):
    (内容类似,包含 PTR 记录,SOA 和 NS 记录与正向区域类似)

  5. 设置区域文件权限:

    sudo chown root:named /var/named/db.mycluster.local
    sudo chown root:named /var/named/db.192.168.1
    sudo chmod 640 /var/named/db.mycluster.local
    sudo chmod 640 /var/named/db.192.168.1
    
  6. 检查配置并启动服务:

    sudo named-checkconf /etc/named.conf
    sudo named-checkzone mycluster.local /var/named/db.mycluster.local
    sudo named-checkzone 1.168.192.in-addr.arpa /var/named/db.192.168.1
    sudo systemctl start named
    sudo systemctl enable named
    sudo firewall-cmd --permanent --add-service=dns
    sudo firewall-cmd --reload
    

步骤三:配置从 DNS 服务器 (dns-slave1dns-slave2)

dns-slave1dns-slave2 上执行以下操作 (配置相似,只需注意 IP 地址)。

  1. 编辑 /etc/named.conf (options 部分):

    sudo vi /etc/named.conf
    
    options {listen-on port 53 { 127.0.0.1; <slave_server_ip>; }; // 例如 192.168.1.11 for dns-slave1listen-on-v6 port 53 { ::1; };directory       "/var/named"; // BIND 会将从主服务器同步的区域文件存放在这里 (通常在 slaves/ 子目录)dump-file       "/var/named/data/cache_dump.db";statistics-file "/var/named/data/named_stats.txt";memstatistics-file "/var/named/data/named_mem_stats.txt";allow-query     { localhost; 192.168.1.0/24; };recursion no;allow-recursion { none; };// 从服务器不需要 allow-transfer,除非它也是其他从服务器的主// allow-transfer { none; };dnssec-enable yes;dnssec-validation yes; // 或 nopid-file "/run/named/named.pid";// ... 其他默认选项 ...
    };logging {channel default_debug {file "data/named.run";severity dynamic;};// 建议为从服务器添加 xfer (transfer) 日志channel xfer_log {file "data/xfer.log" versions 3 size 5m;print-time yes;severity info;};category xfer-in { xfer_log; };category xfer-out { xfer_log; };category notify { xfer_log; };
    };include "/etc/named.rfc1912.zones";
    include "/etc/named.root.key";
    
  2. 编辑 /etc/named.rfc1912.zones (定义区域为 slave):

    sudo vi /etc/named.rfc1912.zones
    

    在文件末尾添加:

    zone "mycluster.local" IN {type slave;file "slaves/db.mycluster.local"; // BIND 会自动创建此文件masters { 192.168.1.10; };      // 指定主服务器的 IP 地址// 可选:如果主服务器的 also-notify 可能被防火墙阻止,可以配置 allow-notify// allow-notify { 192.168.1.10; };
    };zone "1.168.192.in-addr.arpa" IN {type slave;file "slaves/db.192.168.1";masters { 192.168.1.10; };
    };
    

    注意: file 指令指定了从主服务器同步下来的区域数据副本的存储位置。BIND 会自动在 directory (即 /var/named/) 下创建 slaves 子目录(如果不存在)并存储这些文件。

  3. 检查配置并启动服务:

    sudo named-checkconf /etc/named.conf
    sudo systemctl start named
    sudo systemctl enable named
    sudo firewall-cmd --permanent --add-service=dns
    sudo firewall-cmd --reload
    
  4. 验证区域传送:

    • 在从服务器启动 named 后,稍等片刻。
    • 查看从服务器的日志 (sudo journalctl -u named -f 或配置的 xfer.log),应该能看到区域传送成功的消息,类似:
      zone mycluster.local/IN: transferred serial 2023072101
      transfer of 'mycluster.local/IN' from 192.168.1.10#53: Transfer completed
    • 检查 /var/named/slaves/ 目录下是否生成了对应的区域文件。

步骤四:配置负载均衡 (以 HAProxy 为例)

这里我们使用 HAProxy 作为软件负载均衡器。可以在一台独立的服务器上安装 HAProxy,或者在其中一台 DNS 服务器上安装(但不推荐用于生产环境的关键服务)。

假设 HAProxy 安装在 IP 为 192.168.1.20 的服务器上。

  1. 安装 HAProxy:

    sudo yum install -y haproxy
    
  2. 配置 HAProxy (/etc/haproxy/haproxy.cfg):

    sudo vi /etc/haproxy/haproxy.cfg
    

    添加或修改以下内容:

    globallog         /dev/log local0chroot      /var/lib/haproxypidfile     /var/run/haproxy.pidmaxconn     4000user        haproxygroup       haproxydaemonstats socket /var/lib/haproxy/statsdefaultsmode                    http # 对于DNS,通常用tcp模式,但http模式的健康检查更灵活log                     globaloption                  httplog # 如果是tcp模式,用tcplogoption                  dontlognulloption                  http-server-close # 如果是tcp模式,用clitcpka 和 srvtcpka# option                forwardfor except 127.0.0.0/8 # 如果需要传递客户端IPoption                  redispatchretries                 3timeout http-request    10stimeout queue           1mtimeout connect         10stimeout client          1mtimeout server          1mtimeout http-keep-alive 10stimeout check           10smaxconn                 3000# DNS UDP Frontend and Backend
    frontend dns_udp_frontendbind 192.168.1.100:53 proto udp # VIP 和 UDP 端口mode udpdefault_backend dns_udp_backendbackend dns_udp_backendmode udpbalance roundrobin # 或 leastconn# 健康检查对UDP比较困难,通常依赖TCP的健康检查或外部脚本# HAProxy 对 UDP 的健康检查支持有限,通常依赖于后端服务器是否响应server dns_master 192.168.1.10:53 check # 'check' 对UDP可能无效或行为不同server dns_slave1 192.168.1.11:53 checkserver dns_slave2 192.168.1.12:53 check# DNS TCP Frontend and Backend (DNS也使用TCP,例如区域传送或大型响应)
    frontend dns_tcp_frontendbind 192.168.1.100:53 proto tcp # VIP 和 TCP 端口mode tcpdefault_backend dns_tcp_backendbackend dns_tcp_backendmode tcpbalance roundrobinoption tcp-check # 使用TCP健康检查# TCP健康检查:尝试连接到服务器的53端口# 可以更复杂,例如发送一个简单的DNS查询并期望特定响应# default-server check port 53 inter 2s fall 3 rise 2server dns_master 192.168.1.10:53 check port 53 inter 2s fall 3 rise 2server dns_slave1 192.168.1.11:53 check port 53 inter 2s fall 3 rise 2server dns_slave2 192.168.1.12:53 check port 53 inter 2s fall 3 rise 2# HAProxy Stats Page (可选)
    listen statsbind *:8404mode httpstats enablestats uri /statsstats realm Haproxy\ Statisticsstats auth admin:password # 设置用户名和密码
    

    关于 HAProxy UDP 健康检查的说明:
    HAProxy 对 UDP 服务的健康检查能力有限。check 关键字在 mode udp 下的行为可能不如 TCP。更可靠的 UDP 健康检查通常需要:

    • 依赖于 TCP 端口的健康检查(如果服务同时监听 TCP)。
    • 使用外部脚本通过 option external-check 执行自定义的 UDP 健康检查。
    • 对于 DNS,一个简单的 TCP 连接检查到端口 53 通常可以作为指示。
  3. 允许 HAProxy 绑定到非本地 IP (VIP):

    sudo sysctl -w net.ipv4.ip_nonlocal_bind=1
    # 持久化
    echo "net.ipv4.ip_nonlocal_bind=1" | sudo tee /etc/sysctl.d/90-haproxy.conf
    
  4. 启动 HAProxy 并设置开机自启:

    sudo systemctl start haproxy
    sudo systemctl enable haproxy
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" port port="53" protocol="udp" accept'
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" port port="53" protocol="tcp" accept'
    sudo firewall-cmd --permanent --add-port=8404/tcp # 如果启用了stats页面
    sudo firewall-cmd --reload
    

步骤五:配置客户端

将客户端的 DNS 服务器设置为负载均衡器的 VIP:192.168.1.100


步骤六:(可选) 使用 Keepalived 实现 VIP 高可用和负载均衡器冗余

如果 HAProxy 本身成为单点故障,可以使用 Keepalived 来管理 VIP 并在多个 HAProxy 节点之间进行故障转移。

假设你有两台 HAProxy 服务器 (haproxy1: 192.168.1.20, haproxy2: 192.168.1.21)。

  1. 在两台 HAProxy 服务器上安装 Keepalived:

    sudo yum install -y keepalived
    
  2. 配置 Keepalived (/etc/keepalived/keepalived.conf):

    • 在 haproxy1 (MASTER):

      ! Configuration File for keepalivedglobal_defs {router_id HAPROXY_DNS_01
      }# 脚本用于检查HAProxy进程是否在运行
      vrrp_script chk_haproxy {script "killall -0 haproxy"   # 检查haproxy进程是否存在interval 2                    # 每2秒检查一次weight 2                      # 如果成功,权重加2
      }vrrp_instance VI_DNS {state MASTERinterface eth0                # 根据你的网卡名称修改virtual_router_id 51          # 必须在所有Keepalived节点上相同priority 101                  # MASTER 优先级更高advert_int 1authentication {auth_type PASSauth_pass yoursecret      # 密码,所有节点相同}virtual_ipaddress {192.168.1.100/24 dev eth0 label eth0:vip1 # VIP}track_script {chk_haproxy}
      }
      
    • 在 haproxy2 (BACKUP):

      ! Configuration File for keepalivedglobal_defs {router_id HAPROXY_DNS_02
      }vrrp_script chk_haproxy {script "killall -0 haproxy"interval 2weight 2
      }vrrp_instance VI_DNS {state BACKUPinterface eth0virtual_router_id 51priority 100                  # BACKUP 优先级较低advert_int 1authentication {auth_type PASSauth_pass yoursecret}virtual_ipaddress {192.168.1.100/24 dev eth0 label eth0:vip1}track_script {chk_haproxy}
      }
      
  3. 启动 Keepalived 并设置开机自启 (在两台 HAProxy 服务器上):

    sudo systemctl start keepalived
    sudo systemctl enable keepalived
    sudo firewall-cmd --permanent --add-protocol=vrrp # 允许VRRP协议
    sudo firewall-cmd --reload
    

    现在,192.168.1.100 这个 VIP 会由 Keepalived 管理。如果 haproxy1 上的 HAProxy 进程挂掉或服务器宕机,VIP 会自动漂移到 haproxy2


测试高可用性:

  1. 主从同步测试:

    • dns-master 上修改区域文件 (例如,添加一条 A 记录),并增加 SOA 序列号
    • 执行 sudo rndc reload mycluster.local (或 sudo systemctl reload named)。
    • 在从服务器上查看日志,确认区域已成功传送新的序列号。
    • 在从服务器上使用 dig @localhost new_record.mycluster.local 查询新记录。
  2. 负载均衡和故障转移测试 (HAProxy + BIND 节点):

    • 从客户端 dig @192.168.1.100 existing_record.mycluster.local,多次查询,观察 HAProxy 是否将请求分发到不同的后端 BIND 服务器 (可以在 BIND 服务器上开启查询日志来确认)。
    • 停止其中一个从 BIND 服务器 (sudo systemctl stop named on dns-slave1)。
    • 再次从客户端查询,请求应该仍然成功,并由其他健康的 BIND 服务器响应。HAProxy 的健康检查应该会将故障节点标记为 down。
    • 恢复 dns-slave1 上的 named 服务,它应该会自动重新加入到负载均衡池中。
  3. VIP 故障转移测试 (Keepalived + HAProxy 节点):

    • 在当前持有 VIP 的 HAProxy 服务器 (MASTER Keepalived) 上停止 keepalived 服务或 haproxy 服务 (如果 track_script 配置正确)。
    • 观察 VIP (192.168.1.100) 是否成功漂移到另一台 HAProxy 服务器 (BACKUP Keepalived)。可以使用 ip addr show 查看。
    • 从客户端继续查询 dig @192.168.1.100 existing_record.mycluster.local,应该仍然成功。

注意事项和改进:

  • 安全性:
    • 严格配置防火墙,只允许必要的端口和源 IP。
    • 保护 rndc.key 文件。
    • 考虑使用 TSIG (Transaction Signatures) 来保护区域传送。
    • 定期更新 BIND 和其他系统组件。
  • 日志和监控:
    • 配置详细的日志记录,并使用集中式日志管理系统。
    • 使用监控系统 (Nagios, Zabbix, Prometheus) 监控 BIND 服务、HAProxy、Keepalived 的状态以及 DNS 解析的健康状况。
  • DNSSEC: 如果你的区域需要 DNSSEC 签名,确保主服务器正确签名区域,从服务器能够处理已签名的区域。
  • 扩展性: 可以根据需要增加更多的从服务器和 HAProxy 节点。
  • Anycast: 对于更大规模或地理分布的 DNS 集群,可以考虑使用 Anycast IP 地址,这需要网络设备的支持。
  • 配置管理: 使用 Ansible, Puppet, Chef 等工具自动化部署和管理配置。

这是一个相对完整的搭建高可用 BIND9 集群的方案。根据你的具体需求和环境,可能需要进行调整。

相关文章:

CentOS 7上搭建高可用BIND9集群指南

在 CentOS 7 上搭建一个高可用的 BIND9 集群通常涉及以下几种关键技术和策略的组合&#xff1a;主从复制 (Master-Slave Replication)、负载均衡 (Load Balancing) 以及可能的浮动 IP (Floating IP) 或 Anycast。 我们将主要关注主从复制和负载均衡的实现&#xff0c;这是构成高…...

使用SQLite Studio导出/导入SQL修复损坏的数据库

使用SQLite Studio导出/导入SQL修复损坏的数据库 使用Zotero时遇到了数据库损坏&#xff0c;在软件中寸步难行&#xff0c;遂尝试修复数据库。 一、SQLite Studio简介 SQLite Studio是一款专为SQLite数据库设计的免费开源工具&#xff0c;支持Windows/macOS/Linux。相较于其…...

Liquid Wire 柔性应变传感器:金属凝胶导体 | 仿生肌肉长度监测 | 高精度动作控制

柔性应变传感器通过模拟生物系统反馈机制&#xff0c;为软体机器人提供高精度动作控制能力。研究显示&#xff0c;基于液态导电金属的柔性传感纤维可精准测量仿生手指触觉力&#xff08;约 1600 kPa&#xff09;和关节角度变化&#xff08;约 60&#xff09;&#xff0c;实现特…...

Java IO流操作

Java IO流操作是处理文件和数据流的基础。通过FileInputStream和FileOutputStream&#xff0c;可以读写二进制文件&#xff1b;通过FileReader和FileWriter&#xff0c;可以处理文本文件。BufferedReader提高字符读取效率&#xff0c;InputStreamReader实现字节流到字符流的转换…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(25):受身形(3)

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(25):受身形(3) 1、前言(1)情况说明(2)工程师的信仰2、知识点(1)受身形(1)两要素时,使用【に】(2)三要素时,使用【を】或其他(3)(4)(5) によって(6)から VS で(2)復習(ふくしゅう):3、单词(…...

BPMN.js编辑器设计器与属性面板数据交互

以下是基于提供的Vue组件代码生成的类图&#xff0c;结合BPMN设计器特性与Vue组件封装规范绘制&#xff1a; #mermaid-svg-B6PK7fjqLLTHqh8B {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-B6PK7fjqLLTHqh8B .error…...

os agent智能体软件 - 第三弹 - 纯语音交互

前两期期我们发布了产品的初级形态&#xff0c;那时候还只能是“软件开发者”在本地配置使用&#xff0c;或者运行起来有个大黑框&#xff0c;使用起来美观度太差。 到今天大概20天&#xff0c;我们的第3版已经出来了&#xff0c;不仅做成了电脑端的exe软件&#xff08;任何人…...

PCB设计教程【入门篇】——电路分析基础-基本元件(二极管三极管场效应管)

前言 本教程基于B站Expert电子实验室的PCB设计教学的整理&#xff0c;为个人学习记录&#xff0c;旨在帮助PCB设计新手入门。所有内容仅作学习交流使用&#xff0c;无任何商业目的。若涉及侵权&#xff0c;请随时联系&#xff0c;将会立即处理、 目录 前言 1.二极管 1.发光…...

python打卡训练营打卡记录day31

知识点回顾 规范的文件命名规范的文件夹管理机器学习项目的拆分编码格式和类型注解 作业&#xff1a;尝试针对之前的心脏病项目ipynb&#xff0c;将他按照今天的示例项目整理成规范的形式&#xff0c;思考下哪些部分可以未来复用。 心脏病项目目录 目录结构:heart/ ├── conf…...

Python列表推导式和生成器表达式详解

Python列表推导式和生成器表达式详解 引言 Python以其简洁优雅的语法而闻名&#xff0c;其中列表推导式&#xff08;List Comprehensions&#xff09;和生成器表达式&#xff08;Generator Expressions&#xff09;就是这种优雅性的典型代表。本文将深入浅出地介绍这两种强大的…...

Redis 命令大全

Redis 是一个开源的内存数据结构存储系统,支持多种数据结构。以下是 Redis 的常用命令分类总结: 一、Key(键)相关命令 命令描述示例DEL key删除键DEL nameEXISTS key检查键是否存在EXISTS nameEXPIRE key seconds设置键的过期时间(秒)EXPIRE name 60TTL key查看键剩余过期…...

Wan2.1 图生视频 支持批量生成

Wan2.1 图生视频 支持批量生成 flyfish 综合效果 实现基于 Wan2.1 模型的配置化批量生成功能&#xff0c;支持从prompt.json读取多个 “图像 - 文本提示” 组合&#xff08;每个任务可关联多图像&#xff09;&#xff0c;通过config.json集中管理模型路径、分辨率、帧数、引…...

Git 删除大文件教程

&#x1f9f9; Git 删除大文件完整教程 &#x1f9e9; 适用场景 不小心将大文件&#xff08;如视频、压缩包、模型文件等&#xff09;提交到了 Git 仓库想彻底从仓库和提交历史中删除这个文件希望远程仓库体积减小&#xff08;如 GitHub 上传失败&#xff09; &#x1f6e0;️…...

题海拾贝:P2285 [HNOI2004] 打鼹鼠

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》、《C修炼之路》 1、题目 P2285 [HNOI2004] 打…...

第40天-Python开发音乐播放器完整指南

一、技术选型与工具准备 核心库: Pyqt5:Python标准GUI库,构建用户界面 os / sys:文件系统操作 开发环境: bash 复制 下载 pip install pyqt5 二、功能设计 功能模块描述播放控制播放/暂停/停止/上一曲/下一曲播放列表管理添加/删除/保存/加载歌曲音频可视化进度条显示与拖…...

【优秀三方库研读】在 quill 开源库中为什么封装 safe_fwrite,而不是直接使用系统 fwrite

在 Quill 日志库中,safe_fwrite 函数的封装是为了解决直接使用系统 fwrite 时可能存在的 可靠性 和 错误处理 问题,同时兼顾性能优化。以下从多个维度详细分析其设计动机和实现原理: 一、代码功能解析 QUILL_ATTRIBUTE_HOT static void safe_fwrite(void const* ptr, size_…...

UE(虚幻)学习(六)插件打包在UE5.3.2下Value cannot be null的错误

自己写的插件打包出现了Unhandled exception: System.ArgumentNullException: Value cannot be null.的错误&#xff0c;发现只有UE5.3会报出。 D:\UE_5.3\Engine\Build\BatchFiles>Runuat.bat BuildPlugin -PluginF:\UEProjects\DQSDK5_3\Plugins\DQSDK\DQSDK.uplugin -Pa…...

JDBC在Java项目开发中的核心作用与实战应用

一、JDBC概述及其在项目开发中的重要性 JDBC(Java Database Connectivity)是Java语言中用来规范客户端程序如何访问数据库的应用程序接口(API)&#xff0c;它为Java开发者提供了与各种关系型数据库进行交互的统一方式。 JDBC的核心价值&#xff1a; 提供与数据库无关的标准接…...

为 Jenkins添加 Windows Slave远程执行 python项目脚本

测试环境 JAVA JDK 1.7.0_13 (jdk-7u13-windows-i586.exe) Jenkins Win11 64 python项目环境 实践操作 1、新建与配置结点 【系统管理】-> 【管理结点】-> 【新建结点】, 如上&#xff0c;输入结点名称&#xff0c;勾选 【Dumb Slave】&#xff0c;点击【OK】 说明&am…...

深入解析Spring Boot与Redis的缓存集成实践

深入解析Spring Boot与Redis的缓存集成实践 引言 在现代Web应用中&#xff0c;缓存技术是提升系统性能的重要手段之一。Redis作为一种高性能的内存数据库&#xff0c;广泛应用于缓存场景。本文将详细介绍如何在Spring Boot项目中集成Redis&#xff0c;并探讨其在实际开发中的…...

硬件工程师笔记——三极管Multisim电路仿真实验汇总

目录 1 三极管基础 更多电子器件基础知识汇总链接 1.1 工作原理 NPN型三极管的工作原理 PNP型三极管的工作原理 1.2 三极管的特性曲线 输入特性曲线 理想和现实输出特性 三极管的主要参数包括&#xff1a; 2 三极管伏安特性 2.1 伏安特性仿真 Multisim使用说明链接…...

基于 ABP vNext + CQRS + MediatR 构建高可用与高性能微服务系统:从架构设计到落地实战

&#x1f9e0; 基于 ABP vNext CQRS MediatR 构建高可用与高性能微服务系统&#xff1a;从架构设计到落地实战 目录 &#x1f9e0; 基于 ABP vNext CQRS MediatR 构建高可用与高性能微服务系统&#xff1a;从架构设计到落地实战&#x1f9f0; 模块结构概览&#x1f4e6; 各…...

java云原生实战之graalvm 环境安装

windows环境安装 在Windows环境下安装GraalVM并启用原生镜像功能时&#xff0c;需要Visual Studio的组件支持。具体要点如下&#xff1a; 核心依赖&#xff1a; 需要安装Visual Studio 2022或更新版本&#xff0c;并确保勾选以下组件&#xff1a; "使用C的桌面开发"…...

Python 包管理工具uv依赖分组概念解析

在 Python 包管理工具 uv 中&#xff0c;依赖分组&#xff08;如 dev、prod&#xff09;是一种将项目的不同依赖按用途分类管理的机制。通过分组&#xff0c;开发者可以清晰地分离生产环境&#xff08;运行项目所需的核心依赖&#xff09;和开发环境&#xff08;仅在开发阶段使…...

C语言-9.指针

9.1指针 9.1-1取地址运算:&运算符取得变量的地址 运算符& scanf(“%d”,&i);里的&获取变量的地址,它们操作数必须是变量int i;printf(“%x”,&i);地址的大小是否与int相同取决于编译器int i;printf(“%p”,&i); &不能取的地址不能对没有地址的…...

GitHub 自动认证教程

## 简介 在使用 GitHub 时&#xff0c;为了避免每次提交代码都需要输入用户名和密码&#xff0c;我们可以使用 SSH 密钥进行自动认证。本教程将详细介绍如何设置 SSH 密钥并配置 GitHub 自动认证。 ## 步骤一&#xff1a;检查现有 SSH 密钥 首先&#xff0c;检查您的电脑是否…...

labelme的安装与使用(以关键点检测为例)、labelme格式标签转换

注&#xff1a;labelme 和 labelImg 是两款不同的数据标注工具。labelme 的 Github 官方地址&#xff1a; https://github.com/wkentaro/labelmehttps://github.com/wkentaro/labelme 参考笔记&#xff1a; Labelme标注工具安装及使用_labelme安装及使用教程-CSDN博客 学习视…...

【Git】远程操作

Git 是一个分布式版本控制系统 可以简单理解为&#xff0c;每个人的电脑上都是一个完整的版本库&#xff0c;这样在工作时&#xff0c;就不需要联网 了&#xff0c;因为版本库就在自己的电脑上。 因此&#xff0c; 多个人协作的方式&#xff0c;譬如说甲在自己的电脑上改了文件…...

密码学实验

密码学实验二 一、实验目的&#xff08;本次实验所涉及并要求掌握的知识点&#xff09; 掌握RSA算法的基本原理并根据给出的RSA算法简单的实现代码源程序,以及能够使用RSA对文件进行加密。掌握素性测试的基本原理&#xff0c;并且会使用Python进行简单的素性测试以及初步理解…...

nettrace工具介绍

简介 仓库地址&#xff1a; https://github.com/OpenCloudOS/nettrace 背景&#xff1a; 在云原生场景中&#xff0c;linux系统中的网络部署变得越来越复杂&#xff0c;一个tcp连接&#xff0c;从客户端到服务器&#xff0c;中间可能要经过复杂的NAT、GRE、IPVS等过程&#x…...

Jenkins+Docker+Harbor快速部署Spring Boot项目详解

JenkinsDockerHarbor快速部署Spring Boot项目详解 Jenkins、Docker和Harbor是现代DevOps流程中的核心工具&#xff0c;结合使用可以实现自动化构建、测试和部署。下面我将详细介绍如何搭建这个集成环境。 一、各工具的核心作用 Jenkins 自动化CI/CD工具&#xff0c;负责拉取代…...

Windows 安装Anaconda

一、下载Anaconda 1.阿里云镜像&#xff1a; https://developer.aliyun.com/mirror/ 2.中科大镜像&#xff1a; https://mirrors.ustc.edu.cn/ 二、配置环境变量 Windows‌&#xff1a; 1.右键“此电脑” → “属性” → “高级系统设置” → “环境变量”25&#xff1b…...

《微机原理与接口技术》第 8 章 常用接口芯片

8.1 可编程定时/计数器8253/8254 8.1.1 8253的外部引脚及内部结构 8.1.2 8253的工作方式 8.1.3 8253的方式控制字和读/写操作 8.1.4 8253的初始化编程及应用 8.1.5 可编程定时/计数器8254 …… 8.2 可编程并行接口8255 8.2.1 并行通信的概念 &#xff08;1&#xff09…...

upload-labs靶场通关详解:第12-13关

目录 第12关&#xff1a;get00截断 一、分析源代码 二、解题思路 三、解题步骤 第13关&#xff1a;post00截断 一、分析源代码 二、解题思路 三、解题步骤 第12关&#xff1a;get00截断 一、分析源代码 $is_upload false; $msg null; if(isset($_POST[submit])){$ex…...

YOLO模型初次训练体验(+实测)

1.训练目的 做一个简单的示例,本次训练的目的希望模型能够识别桌面的两个图标。(主要是方便准备数据) 2.数据准备 安装一个截图软件,在桌面不同分辨率,不同背景的情况下,随机调整两个图标的位置并截图保存。 原始图片: 先为截图批量重命名: 使用重命名工具,设置命…...

OSA实战笔记二

本文是我在实际项目开发中&#xff0c;总结和归纳的笔记&#xff0c;主要记录了OSA常用的参数释义。 OSA的Params 1、Scroll Sensivity 对⿏标滚轮&#xff08;或类似&#xff09;输⼊的敏感度&#xff0c;与通过滚动条拖动或滚动⽆关。 2、Scroll Sensivity On X Axis 对…...

OSI 网络七层模型中的物理层、数据链路层、网络层

一、OSI 七层模型 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层 1. 物理层&#xff08;Physical Layer&#xff09; 功能&#xff1a;传输原始的比特流&#xff08;0和1&#xff09;&#xff0c;通过物理介质&#xff08;如电缆、光纤、无线电波&#xff09;…...

如何自学FPGA设计?

众所周知&#xff0c;FPGA设计自学难度不小&#xff0c;更不存在速成的捷径。这里简单说一下学习的规划&#xff0c;希望能给入门者提供一些方向。 学会相应的知识 不论是科班毕业还是理工科专业出身&#xff0c;想要入行FPGA开发&#xff0c;基础知识必须扎实。尤其是在高校…...

leetcode 合并区间 java

用 ArrayList<int[]> merged new ArrayList<>();来定义数组的list将数组进行排序 Arrays.sort(intervals,(a,b) -> Integer.compare(a[0],b[0]));如果前面的末尾>后面的初始&#xff0c;那么新的currentInterval的末尾这两个数组末尾的最大值&#xff0c;即…...

如何将内网的IP地址映射到外网?常见方法及详细步骤

自己计算机搭建网络端口服务&#xff0c;或公司内部本地服务器部署项目后&#xff0c;如果同时需要提供异地互联网上连接使用&#xff0c;就需要将内网IP地址映射到外网上。 将本地网络的内网 IP 地址映射到外网&#xff0c;通常是为了允许外部网络访问内网中的特定服务&#…...

Node.js AI 通义灵码 VSCode 插件安装与功能详解

Node.js 作为基于 Chrome V8 引擎的 JavaScript 运行时&#xff0c;使 JavaScript 成为后端开发的重要选择。 在 Node.js 开发中&#xff0c;使用高效的工具可以显著提升开发效率和代码质量。 通义灵码作为一款智能编码助手&#xff0c;为 Node.js 开发者提供了强大的支持。 …...

Linux中的 I/O 复用机制 select

第一部分&#xff1a;select 基本概念 1.1. I/O 复用的提出&#xff1a;并发处理的挑战 在传统的网络服务模型中&#xff0c;服务器为每一个客户端连接创建一个独立的线程或者进程来处理。这种模式在并发连接数量较少时或许尚能应对&#xff0c;但当并发量显著增大时&#xf…...

再议AOI算法

AOI算法优化 首先&#xff0c;需要知道AOI&#xff08;Area of Interest&#xff09;是什么。AOI通常用于游戏或者分布式系统中&#xff0c;用来管理玩家或对象的视野范围&#xff0c;只关注感兴趣区域内的其他对象&#xff0c;减少不必要的通信和数据传输。 整理思路 如文章…...

Unreal5 从入门到精通之如何实现 离线语音识别

文章目录 前言将语言服务器作为外部进程运行UE 项目设置开始捕获语音同时运行服务器进程和游戏进程将 SoundWave 而不是麦克风作为输入将数据发送到语言服务器节点的工作原理详细文档前言 今天我们要说的是一个语音转文本(STT)的插件 Offline Speech Recognition, 它支持离线…...

form-create-designer中$inject参数的数据结构及各项属性说明

FcDesigner 是一款基于Vue的开源低代码可视化表单设计器工具&#xff0c;通过数据驱动表单渲染。可以通过拖拽的方式快速创建表单&#xff0c;提高开发者对表单的开发效率&#xff0c;节省开发者的时间。并广泛应用于在政务系统、OA系统、ERP系统、电商系统、流程管理等领域。 …...

WHAT - CSS 中的 min-height

文章目录 语法常见用途1. 防止元素被压缩得太小2. 配合 Flexbox 保证高度3. 用于内容区域动态撑高但不塌陷 与其他属性的区别提示 在 WHAT - CSS 中的 min-width 中我们已经详细介绍过 width。对于高度&#xff0c; CSS 同样提供一个 min-height. min-height 是 CSS 中用于设置…...

畅游Diffusion数字人(30):情绪化数字人视频生成

畅游Diffusion数字人(0)&#xff1a;专栏文章导航 前言&#xff1a;仅从音频生成此类运动极具挑战性&#xff0c;因为它在音频和运动之间存在一对多的相关性。运动视频的情绪是多元化的选择&#xff0c;之前的工作很少考虑情绪化的数字人生成。今天解读一个最新的工作FLOAT&…...

PLC系统中开关量与模拟量信号解析

引言 在现代工业自动化进程中&#xff0c;可编程逻辑控制器&#xff08;PLC&#xff09;凭借其强大的功能与灵活性&#xff0c;成为工业控制系统的核心设备。PLC能够高效、精准地控制工业生产流程&#xff0c;很大程度上依赖于其对开关量和模拟量信号的处理能力。深入理解这两…...

Qt中解决Tcp粘包问题

Qt中解决Tcp粘包问题 Qt中解决Tcp粘包问题——以文件发送为例服务器端客户端效果演示注意点 Qt中解决Tcp粘包问题——以文件发送为例 创建的工程如下图所示&#xff1a; 服务器端 界面的布局以及名称如下图所示&#xff1a; 并且在Qt中增加网络模块 QT core gui n…...

Qt调用librdkafka

Qt调用librdkafka Windows系统编译Qt使用的kafka(librdkafka) VS2017编译librdkafka 2.1.0 经过上面的步骤我已经编译好了librdkafka库,我编译的主要十release版的,需要debug版的小伙伴编译的时候要留意一下。 接下来就是调用我们编译的kafka库了。 一、环境介绍 Qt:…...