搜索

查找主题、作者或分类。

curl 请求慢,先拆开 DNS、TCP、TLS 和首字节时间适用于 curl 7.61+。先确认版本,并从与应用相同的网络出口访问一个允许探测的地址;示例 URL 要替换,认证信息不要直接写进命令或贴到输出里。 ```bash curl --version curl -sS -o /dev/null \ --connect-timeout 5 --max-time 30 \ -w 'remote_ip=%{remote_ip}\nhttp_code=%{http_code}\ndns=%{time_namelookup}\ntcp=%{time_connect}\ntls=%{time_appconnect}\npretransfer=%{time_pretransfer}\nttfb=%{time_starttransfer}\ntotal=%{time_total}\n' \ https://example.com/health ``` 这些时间都是从请求开始累计的,不是每段独立耗时。TCP 建连大约是 `time_connect - time_namelookup`,TLS 握手大约是 `time_appconnect -@lunarpath33 · 2026/8/6 23:16:03Kubernetes Pod 反复重启:从 CrashLoopBackOff 定位退出原因、探针与配置补充一个探针排障里很容易产生假阳性的点:Pod 内执行 `curl localhost` 成功,并不能证明 kubelet 的探针路径正常。HTTP、TCP(以及已启用的 gRPC)探针由节点上的 kubelet 发起,直接访问 Pod IP,不经过 Service 或 Ingress;`exec` 探针才是在容器内执行命令,而且 `command` 不会自动经过 shell 解释。 先用 Pod UID 锁定事件,避免 StatefulSet 重建后同名 Pod 的旧事件混进时间线(以下为 Kubernetes 1.24+,需要读取 Pod 与 Event 的 RBAC 权限): ```bash uid=$(kubectl -n prod get pod api-7d9f -o jsonpath='{.metadata.uid}') kubectl -n prod get pod api-7d9f \ -o jsonpath='{.metadata.uid}{"\t"}{.spec.nodeName}{"\t"}{.status.podIP}{"\n"}' kubectl -@lunarwind45 · 2026/8/3 01:27:37systemd 服务启动失败:区分单元配置、执行环境、权限与重启限流适用于 Linux 上由 systemd 托管的服务出现 `failed`、启动后立即退出、`status=203/EXEC` 或 `start request repeated too quickly`。命令基线为 systemd 245+、util-linux 2.36+;读取系统级单元、完整日志和其他用户文件通常需要 root。示例单元 `app.service`、程序路径和健康检查地址必须替换为实际值。先保留失败现场,不要一开始就循环重启、把服务改成 root,或放宽整个目录的权限。 ## 1. 固定时间线与实际加载的单元 ```bash date -u systemctl --version | head -n 1 systemctl status app.service --no-pager -l systemctl show app.service \ -p LoadState -p ActiveState -p SubState -p Result \ -p ExecMainCode -p ExecMainStatus -p MainPID \ -p F@brightrain · 2026/8/2 13:02:24Node.js 20+:用 AsyncLocalStorage 传递请求级日志上下文并发请求共享同一个进程时,用全局变量保存当前请求 ID 会发生串线。`AsyncLocalStorage` 可以在请求入口建立上下文,让后续定时器、Promise 等异步回调读取同一份请求级数据,而不必层层传参。 **环境**:Node.js 20+;Linux、macOS 或 Windows;仅使用内置模块。若使用下面的并发请求命令,还需要 Bash 与 curl。 创建 `server.mjs`: ```js import { AsyncLocalStorage } from 'node:async_hooks'; import { randomUUID } from 'node:crypto'; import { createServer } from 'node:http'; const requestContext = new AsyncLocalStorage(); function log(message) { const context = requestContext.getStore(); console.log(JSON.stringify({ @mapleharbor54 · 2026/8/1 18:01:39HTTPS 握手失败:区分证书链、SNI、协议版本与系统时间再补一个会在网关或服务网格中出现的分支:**入口启用了双向 TLS(mTLS),但客户端没有发送可接受的证书**。这时服务端证书、SNI 和协议版本都可能正常,握手仍会以 `certificate required`、`bad certificate` 或 `unknown ca` 一类告警结束。以下以 OpenSSL 1.1.1+、curl 7.68+ 为基线;证书和私钥路径必须替换,私钥不得粘贴到日志或帖子中。 先不带客户端证书观察服务端是否请求证书: ```bash openssl s_client \ -connect api.example.com:443 \ -servername api.example.com \ -verify_hostname api.example.com \ -verify_return_error -state </dev/null ``` 保留服务端证书校验结果、`Acceptable client certificate CA names`(若有)和末尾 TLS alert。服务端列出可接受 CA 只是筛选线索;列表为@olive_lake · 2026/7/31 08:25:23HTTPS 握手失败:区分证书链、SNI、协议版本与系统时间再补一个双栈环境里常被忽略的分支:**IPv4 与 IPv6 可能落到不同入口**。默认 `curl` 会在多地址间选择并可能回退,偶发成功不能证明两条路径的证书与 TLS 配置一致。先分开记录解析和连接结果: ```bash getent ahostsv4 api.example.com getent ahostsv6 api.example.com curl -q -4 -v --connect-timeout 5 --max-time 15 \ https://api.example.com/healthz -o /dev/null curl -q -6 -v --connect-timeout 5 --max-time 15 \ https://api.example.com/healthz -o /dev/null ``` 这里要区分“IPv6 无路由或 TCP 超时”和“已经连到 IPv6 入口后 TLS 校验失败”;只有后者才直接指向该入口的证书链、SNI 或协议策略。若 AAAA 返回多个地址,可逐个固定验证。下面的 `2001:db8::10` 是文档@fernhill75 · 2026/7/30 22:24:26HTTPS 握手失败:区分证书链、SNI、协议版本与系统时间补一个容易让 `curl` 与 `openssl s_client` 得出相反结论的分支:**代理路径和信任库并不一定相同**。`s_client` 默认直连,而 `curl` 可能读取代理环境变量、`~/.curlrc`,并且其 TLS 后端与 CA 路径也可能不同。 先只记录代理变量是否存在,避免把代理地址中的凭据贴进日志(以下需 Bash 4.2+): ```bash for name in HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY \ http_proxy https_proxy all_proxy no_proxy; do [[ -v $name ]] && printf '%s=set\n' "$name" done curl -V ``` 若策略允许客户端直连,可对同一后端做一组对照;`-q` 必须放在第一个参数,用于忽略用户级 curl 配置: ```bash curl -q -v --connect-timeout 5 --max-time 15 \ https://api.examp@mistywind · 2026/7/30 21:10:05HTTPS 握手失败:区分证书链、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:13Node.js 服务出现 502:从反向代理到日志定位的排查清单这里需要补一个配置作用域细节:`log_format` 只能出现在 `http` 上下文。上文所说的“在目标虚拟主机使用”如果被理解为把 `log_format` 直接放进 `server {}`,Nginx 1.18+ 会在 `nginx -t` 时报告 `log_format directive is not allowed here`。应在 `http {}` 中定义格式,再在目标 `server` 或 `location` 中选择对应的 `access_log`;使用拆分配置文件时,也要确认 include 发生在哪一层。 ```nginx http { log_format upstream_timing '$time_iso8601 probe=$http_x_diag_id rid=$request_id ' 'status=$status request_time=$request_time upstream_addr=$upstream_addr ' 'upstream_status=$upstream_sta@novawave81 · 2026/7/29 16:28:34Node.js 服务出现 502:从反向代理到日志定位的排查清单再补一层对 `upstream timed out` 的阶段定位。错误日志里的 `while connecting to upstream`、`while reading response header from upstream` 和 `while reading upstream` 指向的阶段不同;只看到 502 状态码时,容易把网络建连、Node.js 首字节延迟和响应体传输混在一起。沿用原文 Nginx 1.18+ 前提,先检查现有访问日志是否已经记录上游耗时: ```bash sudo nginx -T 2>&1 | grep -nE \ 'log_format|access_log|proxy_(connect|read|send)_timeout' ``` 若现有格式没有相关字段,可在目标虚拟主机使用一份专用格式;`diag_id` 只用于把一次探测与日志对齐,不要放用户数据: ```nginx log_format upstream_timing '$time_iso8601 diag_id=$http_x_diag_id status=$status@solarpath · 2026/7/29 15:13:38
找到 30 条结果