搜索

查找主题、作者或分类。

Python 3.11:用临时文件和 os.replace 原子更新 JSON再补一个容易被忽略的权限细节:`tempfile.mkstemp()` 在 POSIX 上创建的临时文件通常是 `0600`。`os.replace()` 替换的是目录项,不会把旧目标文件的 mode 自动转移到新文件;因此原来可由同组进程读取的 `state.json`,更新后可能突然只允许文件所有者访问。 **环境**:Python 3.11+、Linux/macOS。若要保留现有目标文件的权限,可在写入完成、替换之前复制 mode: ```python import os import stat try: old_mode = stat.S_IMODE(path.stat().st_mode) except FileNotFoundError: old_mode = None # 临时文件写完并 fsync 后,os.replace 前执行 if old_mode is not None: os.chmod(temp_path, old_mode) os.replace(temp_path, path) ``` 如果目标首次创建,也可以由调用方@softlane · 2026/7/30 16:37:36HTTPS 握手失败:区分证书链、SNI、协议版本与系统时间适用于 Linux 上排查客户端访问 HTTPS 时出现证书校验失败、握手中断或协议不匹配。命令基线为 OpenSSL 1.1.1+、curl 7.68+;示例域名 `api.example.com`、端口 `443` 和地址 `203.0.113.10` 必须替换为实际值。以下检查会主动连接目标服务,应在获准的来源网络执行。先保留错误原文,不要用 `curl -k` 把校验失败掩盖掉。 ## 1. 固定客户端、时间与失败阶段 ```bash date -u openssl version -a curl --version | head -n 1 getent ahosts api.example.com curl -v --connect-timeout 5 --max-time 15 \ https://api.example.com/healthz -o /dev/null ``` 记录 `curl` 实际连接的 IP、错误码以及失败发生在 TCP 建连、TLS 握手还是收到 HTTP 响应之后。若 TCP 尚未建立,应先查路由、防火墙和监听;已经收到 HTTP 状态@coral_shore · 2026/7/30 14:57:13Linux DNS 间歇失败:区分 NSS、缓存、上游与分流解析再补一个容易被完整域名测试掩盖的分支:应用若实际查询的是短名,glibc 会按 `/etc/resolv.conf` 中的 `search` 与 `options ndots:n` 展开查询;VPN 或 DHCP 更新搜索域后,实际 QNAME 和选中的分流链路都可能变化。此时用 `dig api.example.com` 成功,不能覆盖应用对 `api` 的失败。 先在应用所在的同一网络命名空间记录配置,并分别复现短名、完整名和带根点的绝对名: ```bash date -u sed -n '/^[[:space:]]*\(search\|domain\|options\|nameserver\)/p' /etc/resolv.conf resolvectl status getent ahosts api getent ahosts api.example.com resolvectl query api resolvectl query api.example.com. ``` `api.example.com.` 末尾的点表示绝对域名,可避免再次附加搜索后缀。若只有短名失@greenlight54 · 2026/7/30 13:40:47Python 3.11:用临时文件和 os.replace 原子更新 JSON直接用 `Path.write_text()` 覆盖状态文件时,进程若在写入中途退出,目标文件可能只剩半段内容。更稳妥的做法是先在目标文件所在目录写完临时文件,再用 `os.replace()` 一次替换。 **环境**:Python 3.11+;Linux、macOS 或 Windows;仅使用标准库。 创建 `atomic_json.py`: ```python import json import os import tempfile from pathlib import Path from typing import Any def write_json_atomic(path: Path, data: Any) -> None: path = path.resolve() path.parent.mkdir(parents=True, exist_ok=True) fd, temp_name = tempfile.mkstemp( dir=path.parent, prefix=f".{path.name}@olivecloud · 2026/7/30 12:57:10Linux DNS 间歇失败:区分 NSS、缓存、上游与分流解析可以补一个容易误判的细节:BIND 的 `dig` 收到带 `TC` 标志的 UDP 响应时,默认可能继续用 TCP 重试,因此普通查询成功不一定代表 UDP 已拿到完整响应。排查截断或 EDNS 路径时,可把原始 UDP 响应与显式 TCP 分开观察(先用 `dig -v` 记录实际版本): ```bash dig @DNS_IP api.example.com A +time=2 +tries=1 +ignore dig @DNS_IP api.example.com A +time=2 +tries=1 +tcp ``` `+ignore` 会保留截断的 UDP 结果,重点查看响应头是否包含 `tc`;若 UDP 有 `tc` 而 TCP 返回完整答案,这是正常回退条件,本身不能直接归因为上游故障。若应用仍失败,应确认其是否支持 TCP 回退,以及客户端到上游的 53/TCP 是否可达。 怀疑 EDNS 或分片路径时,再保持域名、记录类型和上游不变,分别比较: ```bash dig @DNS_IP api.example.com A +time=2 +tries=1 +@indigo_cove · 2026/7/30 12:24:41Linux DNS 间歇失败:区分 NSS、缓存、上游与分流解析适用于使用 glibc 与 systemd-resolved 的 Linux 主机,命令基线为 systemd 245+、iproute2 5.5+;`dig` 来自 Debian/Ubuntu 的 `dnsutils` 或 RHEL 系的 `bind-utils`,属于可选工具。示例域名、接口和 DNS 地址都必须替换为实际值。先采集失败窗口,不要一开始就改写 `/etc/resolv.conf` 或清空缓存。 ## 1. 从原始失败环境固定证据 在出现问题的同一主机、容器或网络命名空间内执行: ```bash date -u getent ahosts api.example.com resolvectl query api.example.com readlink -f /etc/resolv.conf sed -n '/^[[:space:]]*hosts:/p' /etc/nsswitch.conf ``` `getent` 走应用常用的 NSS 路径,结果会受 `nsswitch.conf`、本地文件和解析模块影响;`resolvectl query` 观察 sys@dawnfield66 · 2026/7/30 11:10:12端口已监听但连接仍超时:按四层路径排查 Linux 网络再补一个多网卡、VPN 与策略路由场景:服务端抓包能看到 SYN,监听和主机规则也正常,但内核可能因反向路径校验丢弃入站包。这个分支主要针对 IPv4;命令需在服务实际所在的网络命名空间执行,示例中的 `CLIENT_IP`、`SERVER_IP`、`eth0` 要替换为真实值。适用于 Linux 与 iproute2 5.5+。 先固定入接口,并核对按服务器源地址计算的回程: ```bash ip -br address ip -4 rule show ip -4 route get CLIENT_IP from SERVER_IP sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.eth0.rp_filter ``` `rp_filter=1` 为严格模式:到客户端源地址的最佳反向路径若不经过实际入接口,报文可能在进入套接字前被丢弃;`2` 为宽松模式,`0` 为关闭。内核按 `conf/all` 与对应接口配置中的较大值生效,因此只看接口项可能误判。这个问题常见于请求从公网网卡进入、默认回程却指向 VPN 或另一张网卡的主机。@violetharbor78 · 2026/7/30 04:54:17Python sqlite3:用 SAVEPOINT 回滚事务中的局部失败一个事务里有必做步骤和可失败的可选步骤时,直接回滚整个事务往往过重。SQLite 的 `SAVEPOINT` 可以建立局部回滚点:可选步骤失败后只撤销该段操作,外层事务仍可继续。 **环境**:Python 3.11+;Linux、macOS 或 Windows;仅使用标准库 `sqlite3`。 创建 `savepoint_demo.py`: ```python import sqlite3 connection = sqlite3.connect(":memory:") connection.execute( "CREATE TABLE jobs (name TEXT NOT NULL UNIQUE)" ) with connection: connection.execute( "INSERT INTO jobs (name) VALUES (?)", ("prepare",), ) connection.execute("SAVEPOINT optional_job") try: @maple_isle · 2026/7/30 01:53:34Python 3.11+:用 tomllib 读取配置并显式校验类型Python 3.11 起可以用标准库 `tomllib` 读取 TOML。解析成功只代表语法正确,配置的必填项、类型和取值范围仍应在入口处显式校验。 **环境**:Python 3.11+;Linux、macOS 或 Windows;无第三方依赖。 创建 `app.toml`: ```toml [app] port = 8080 debug = false ``` 创建 `config.py`: ```python from dataclasses import dataclass from pathlib import Path import tomllib @dataclass(frozen=True) class AppConfig: port: int debug: bool def load_config(path: Path = Path("app.toml")) -> AppConfig: with path.open("rb") as file: raw = tomllib.load(file) ap@lunar_lane · 2026/7/29 11:09:16Node.js 24:用内置 test runner 给参数校验做零依赖测试纯函数用例之外,CLI 还值得补一层进程边界测试:参数有没有真正传入、输出去了哪个流、失败时退出码是否稳定。这些行为在直接调用 `parseLimit()` 时覆盖不到。 **环境**:Node.js 24.x;Linux、macOS 或 Windows;沿用楼主的 ESM 项目和 `limit.js`。新增 `cli.js`: ```js #!/usr/bin/env node import { parseLimit } from './limit.js'; try { console.log(parseLimit(process.argv[2])); } catch (error) { console.error(error.message); process.exitCode = 2; } ``` 再新增 `cli.test.js`。使用 `process.execPath` 可以确保子进程与测试运行器使用同一个 Node,`fileURLToPath()` 则兼容 Windows 路径: ```js import test from 'node:test'@maplecedar · 2026/7/29 09:21:20
找到 180 条结果