<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Go工程踩坑实录 on Go Home</title>
    <link>https://blog.911015.com/go-project/</link>
    <description>Recent content in Go工程踩坑实录 on Go Home</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <atom:link href="https://blog.911015.com/go-project/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>数据库连接池配错，服务半夜挂了我背锅</title>
      <link>https://blog.911015.com/go-project/01.html</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://blog.911015.com/go-project/01.html</guid>
      <description>数据库连接池配错，服务半夜挂了我背锅 这是《Go工程踩坑实录》第1期。这个系列会记录我在真实项目里摔过的跤——不是教科书知识，是带着伤疤的经验。&#xA;凌晨2点，钉钉炸了。&#xA;服务无响应，告警群里刷屏。我眯着眼爬起来，登录服务器，敲下 netstat | grep 3306 | wc -l——输出 500+。MySQL 吐着 &amp;ldquo;Too many connections&amp;rdquo;。&#xA;我盯着那段代码看了十分钟：&#xA;db, _ := sql.Open(&amp;#34;mysql&amp;#34;, dsn) 除了数据库地址，我从没改过别的参数。&#xA;01 凌晨2点，连接池炸了 背景是一台电商服务，QPS 不高，也就 200 左右。但接口响应越来越慢，像温水煮青蛙，直到整锅沸腾。&#xA;症状很典型：&#xA;服务不报 panic，但接口延迟从 50ms 爬到 2s+ 重启后好 10 分钟，然后继续恶化 show processlist 里几百个 Sleep 状态的连接，躺着不动 排查链路是这样的：&#xA;先看代码——连接没显式 Close？不对，用的是 sql.DB 连接池，按理说会自己管。&#xA;再看 MySQL——连接数打到上限，新请求进不来。&#xA;最后看 sql.DB 参数——全默认。MaxOpenConns 是 0（无限），MaxIdleConns 是 2。&#xA;根因很蠢：高峰期并发上来，连接池疯狂开新连接。峰值过了，连接变成 Sleep，但池子只留 2 个，多余的关了。下次高峰再来，重新建——反复创建、销毁、再创建，TCP 挥手+MySQL Auth 认证（身份校验、权限检查）反复执行，这部分 CPU 开销往往比纯 TCP 握手更显著。&#xA;【配图建议：连接数增长趋势图】横轴时间，纵轴连接数，呈阶梯状上升，峰值后小幅下降又继续攀升&#xA;02 sql.</description>
    </item>
    <item>
      <title>日志级别乱打，线上排查像大海捞针</title>
      <link>https://blog.911015.com/go-project/02.html</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://blog.911015.com/go-project/02.html</guid>
      <description>日志级别乱打，线上排查像大海捞针 这是《Go工程踩坑实录》第2期。上一期聊了数据库连接池，本期说说另一个让我翻遍10G日志的坑。&#xA;线上服务报错，用户反馈下单失败。我打开日志平台，检索 level=error，结果跳出来 5000+ 条。&#xA;翻了 10 页，发现里面混着这些：&#xA;&amp;quot;error: user not found&amp;quot; —— 用户没注册，正常情况 &amp;quot;error: retry failed&amp;quot; —— 重试机制打的，最后成功了 &amp;quot;error: connection reset by peer&amp;quot; —— 网络抖动，自动恢复了 真正的根因呢？一条被埋在 Info 里的 &amp;quot;upstream circuit breaker tripped&amp;quot;。我花了 40 分钟才找到。&#xA;不是日志打少了，是噪音淹没了信号。&#xA;01 40分钟，我翻完了10G日志 背景是一个支付回调服务，偶发订单状态不同步。&#xA;症状很典型：&#xA;日志量 10G/天，Error 级别日志 5000+ 条 告警群每天被 Error 刷屏，但 90% 是&amp;quot;假错误&amp;quot; 真正的故障信号被淹没，告警疲劳导致大家习惯性忽略 排查链路是这样的：&#xA;先看 Error 日志。5000 多条，翻了几页发现全是&amp;quot;用户不存在&amp;quot;&amp;ldquo;重试失败&amp;quot;&amp;ldquo;网络抖动&amp;rdquo;——这些要么是业务正常分支，要么是自动恢复的场景。Error 级别被滥用成了垃圾桶。&#xA;再看 Warn。混合了&amp;quot;需要注意&amp;quot;和&amp;quot;可以忽略&amp;rdquo;，筛选成本极高。&#xA;最后翻 Info。翻了 20 多分钟，发现一条 &amp;quot;upstream circuit breaker tripped&amp;quot;（下游服务熔断）被当成 Info 打了——这才是根因。第三方回调服务熔断，我们自己的服务没挂，但所有通知都被静默丢弃了。这行致命的信号被夹在&amp;quot;请求接收&amp;quot;和&amp;quot;请求处理完成&amp;quot;的两千万行 Info 之间。</description>
    </item>
  </channel>
</rss>
