<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>MacOS | 空垠尘</title><link>/zh-hant/tags/macos/</link><description>極簡純靜態 · 邊緣無界</description><generator>Hugo -- gohugo.io</generator><language>zh-Hant</language><managingEditor>Dukang Xu</managingEditor><webMaster>Dukang Xu</webMaster><copyright>© 2026 空垠尘</copyright><lastBuildDate>Fri, 25 Sep 2026 16:00:00 +0800</lastBuildDate><atom:link href="/zh-hant/tags/macos/index.xml" rel="self" type="application/rss+xml"/><item><title>Linux 維運實戰排錯與疑難雜症手冊</title><link>/zh-hant/linux-troubleshooting/</link><pubDate>Fri, 25 Sep 2026 16:00:00 +0800</pubDate><author>Dukang Xu</author><guid isPermaLink="true">/zh-hant/linux-troubleshooting/</guid><description>直擊生產環境與日常開發中最頭疼的經典疑難雜症：全面剖析 Too Many Open Files 句柄瓶頸、磁碟 Inode 耗盡、行程殭死、記憶體 OOM Killer 以及時鐘偏差的排查定位與根治方案。</description><content:encoded><![CDATA[<h2 id="引言維運排錯的系統性心智模型">引言：維運排錯的系統性心智模型</h2>
<p>在 Linux 與 macOS 的日常維運中，我們總會遇到一些讓人措手不及的「靈異現象」：</p>
<ul>
<li>磁碟明明顯示還有幾十 GB 空間，寫入檔案卻提示 <code>No space left on device</code>；</li>
<li>服務連接埠被佔用，卻查不到任何監聽行程；</li>
<li>容器或後端服務莫名其妙被系統靜默殺死，沒有任何業務日誌；</li>
<li>高併發場景下突然爆發大量 <code>Too many open files</code> 導致雪崩。</li>
</ul>
<p>排錯不僅是敲幾條指令，更是順藤摸瓜的<strong>系統性推導過程</strong>。本文匯集一線維運中最高頻的 6 類疑難雜症，給出可直接落地的排查邏輯與根治方案。</p>
<pre tabindex="0"><code class="language-mermaid" data-lang="mermaid">flowchart TD
    Issue[&#34;系統異常與服務警報&#34;] --&gt; A[&#34;1. 檔案句柄耗盡&lt;br/&gt;(Too Many Open Files)&#34;]
    Issue --&gt; B[&#34;2. 磁碟爆滿/假滿&lt;br/&gt;(Inode 耗盡 / 句柄未釋放)&#34;]
    Issue --&gt; C[&#34;3. 連接埠衝突與殭屍行程&lt;br/&gt;(Address in use / Zombie)&#34;]
    Issue --&gt; D[&#34;4. 記憶體溢出被殺&lt;br/&gt;(Kernel OOM Killer)&#34;]
    Issue --&gt; E[&#34;5. 時鐘偏差與鑑權失效&lt;br/&gt;(Clock Skew / NTP 同步)&#34;]
    Issue --&gt; F[&#34;6. macOS 環境網路阻塞&lt;br/&gt;(Homebrew 源與網路排查)&#34;]
</code></pre><hr>
<h2 id="一-徹底解決-too-many-open-files檔案句柄耗盡">一、 徹底解決 <code>Too Many Open Files</code>（檔案句柄耗盡）</h2>
<p>在 Linux 與 macOS 哲學中，「一切皆檔案」。當併發連線數或開啟的檔案數超過系統預設限制時，就會拋出 <code>Too many open files</code> 錯誤。</p>
<h3 id="1-linux-生產環境徹底調優">1. Linux 生產環境徹底調優</h3>
<h4 id="-修改系統級限制-etcsecuritylimitsconf">① 修改系統級限制 (<code>/etc/security/limits.conf</code>)</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">* soft nofile 655350
</span></span><span class="line"><span class="ln">2</span><span class="cl">* hard nofile 655350
</span></span><span class="line"><span class="ln">3</span><span class="cl">root soft nofile 655350
</span></span><span class="line"><span class="ln">4</span><span class="cl">root hard nofile 655350
</span></span></code></pre></div><h4 id="-修改-systemd-全域服務限制-etcsystemdsystemconf">② 修改 systemd 全域服務限制 (<code>/etc/systemd/system.conf</code>)</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">[Manager]</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="na">DefaultLimitNOFILE</span><span class="o">=</span><span class="s">655350</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="na">DefaultLimitNPROC</span><span class="o">=</span><span class="s">655350</span>
</span></span></code></pre></div><h4 id="-查看當前行程佔用的句柄數">③ 查看當前行程佔用的句柄數</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">ls /proc/&lt;PID&gt;/fd <span class="p">|</span> wc -l
</span></span></code></pre></div><h3 id="2-macos-開發者環境調優">2. macOS 開發者環境調優</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 查看當前限制</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">launchctl limit maxfiles
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 臨時增加限制 (當前終端機有效)</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">sudo launchctl limit maxfiles <span class="m">65536</span> <span class="m">200000</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="nb">ulimit</span> -n <span class="m">65536</span>
</span></span></code></pre></div><hr>
<h2 id="二-磁碟假滿與-inode-耗盡-no-space-left-on-device">二、 磁碟「假滿」與 Inode 耗盡 (<code>No space left on device</code>)</h2>
<pre tabindex="0"><code class="language-mermaid" data-lang="mermaid">sequenceDiagram
    autonumber
    participant App as 應用程式 (如 Nginx / Java)
    participant Disk as 磁碟檔案 (/var/log/app.log)
    participant Admin as 維運工程師

    App-&gt;&gt;Disk: 持續寫入大量日誌 (持有檔案句柄)
    Admin-&gt;&gt;Disk: rm /var/log/app.log (刪除了檔名)
    Note over Disk: 空間無法釋放！因為 App 仍持有該句柄
    Admin-&gt;&gt;App: 尋找未釋放句柄 (lsof | grep deleted) 並平滑重載
    Note over Disk: 磁碟空間瞬間恢復！
</code></pre><h3 id="場景-a檔案已被-rm-刪除但行程仍持有句柄未釋放">場景 A：檔案已被 <code>rm</code> 刪除，但行程仍持有句柄未釋放</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 1. 尋找所有已被刪除但仍被行程佔用的檔案</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">sudo lsof <span class="p">|</span> grep -i deleted
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 2. 優雅釋放空間（清空該行程對應的檔案描述符）：</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">sudo truncate -s <span class="m">0</span> /proc/&lt;PID&gt;/fd/&lt;FD&gt;
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="c1"># 或平滑重載服務：sudo systemctl reload nginx</span>
</span></span></code></pre></div><h3 id="場景-b磁碟空間充足但-inode索引節點耗盡">場景 B：磁碟空間充足，但 Inode（索引節點）耗盡</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 1. 檢查 Inode 佔用率</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">df -i
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 2. 逐級統計哪個目錄下的小檔案最多</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">find /var/spool/ -type d -exec sh -c <span class="s2">&#34;echo -n &#39;{}: &#39;; ls -1 &#39;{}&#39; | wc -l&#34;</span> <span class="se">\;</span> <span class="p">|</span> sort -n -k <span class="m">2</span>
</span></span></code></pre></div><hr>
<h2 id="三-連接埠佔用衝突與殭屍行程清理">三、 連接埠佔用衝突與殭屍行程清理</h2>
<h3 id="1-連接埠佔用排查與一秒殺死">1. 連接埠佔用排查與一秒殺死</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 1. 精準定位佔用 8080 連接埠的行程與 PID</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">sudo lsof -i :8080
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1"># 或</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">sudo ss -tulnp <span class="p">|</span> grep :8080
</span></span><span class="line"><span class="ln">5</span><span class="cl">
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="c1"># 2. 強力一鍵釋放連接埠（自動殺死佔用者）</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl">sudo fuser -k 8080/tcp
</span></span></code></pre></div><h3 id="2-殭屍行程zombie-process定位與清理">2. 殭屍行程（Zombie Process）定位與清理</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 1. 查看系統中的所有殭屍行程 (狀態為 Z)</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">ps aux <span class="p">|</span> grep <span class="s1">&#39;Z&#39;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 2. 尋找殭屍行程的父行程 PID (PPID)</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">ps -o <span class="nv">ppid</span><span class="o">=</span> -p &lt;ZOMBIE_PID&gt;
</span></span><span class="line"><span class="ln">6</span><span class="cl">
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="c1"># 3. 優雅重啟或終止父行程，讓 init/systemd 回收殭屍</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl">sudo <span class="nb">kill</span> -HUP &lt;PARENT_PID&gt;
</span></span></code></pre></div><hr>
<h2 id="四-行程靜默被殺linux-核心-oom-killer-排查">四、 行程靜默被殺：Linux 核心 OOM Killer 排查</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 1. 檢查核心是否有 OOM 擊殺紀錄</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">sudo dmesg -T <span class="p">|</span> grep -i -E <span class="s2">&#34;oom|out of memory|killed process&#34;</span>
</span></span></code></pre></div><p><strong>根治策略</strong>：</p>
<ol>
<li><strong>新增 Swap 交換分區</strong>：
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sudo fallocate -l 2G /swapfile
</span></span><span class="line"><span class="ln">2</span><span class="cl">sudo chmod <span class="m">600</span> /swapfile
</span></span><span class="line"><span class="ln">3</span><span class="cl">sudo mkswap /swapfile
</span></span><span class="line"><span class="ln">4</span><span class="cl">sudo swapon /swapfile
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="nb">echo</span> <span class="s1">&#39;/swapfile none swap sw 0 0&#39;</span> <span class="p">|</span> sudo tee -a /etc/fstab
</span></span></code></pre></div></li>
<li><strong>在 Docker / Kubernetes 中設定合理的記憶體 Limit</strong>。</li>
</ol>
<hr>
<h2 id="五-系統時鐘不同步導致-tlsssl-憑證與鑑權失效">五、 系統時鐘不同步導致 TLS/SSL 憑證與鑑權失效</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 1. 檢查當前系統時間與 NTP 同步狀態</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">timedatectl status
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 2. 設定時區並開啟 NTP 自動同步</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">sudo timedatectl set-timezone Asia/Taipei
</span></span><span class="line"><span class="ln">6</span><span class="cl">sudo timedatectl set-ntp <span class="nb">true</span>
</span></span></code></pre></div><hr>
<h2 id="六-macos-開發環境-homebrew-映像加速與復原">六、 macOS 開發環境 Homebrew 映像加速與復原</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 1. 切換為開源映像源</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="nb">export</span> <span class="nv">HOMEBREW_API_DOMAIN</span><span class="o">=</span><span class="s2">&#34;https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api&#34;</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="nb">export</span> <span class="nv">HOMEBREW_BOTTLE_DOMAIN</span><span class="o">=</span><span class="s2">&#34;https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles&#34;</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="nb">export</span> <span class="nv">HOMEBREW_BREW_GIT_REMOTE</span><span class="o">=</span><span class="s2">&#34;https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git&#34;</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="nb">export</span> <span class="nv">HOMEBREW_CORE_GIT_REMOTE</span><span class="o">=</span><span class="s2">&#34;https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git&#34;</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="c1"># 2. 恢復為官方預設源</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="nb">unset</span> HOMEBREW_API_DOMAIN
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="nb">unset</span> HOMEBREW_BOTTLE_DOMAIN
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="nb">export</span> <span class="nv">HOMEBREW_BREW_GIT_REMOTE</span><span class="o">=</span><span class="s2">&#34;https://github.com/Homebrew/brew&#34;</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="nb">export</span> <span class="nv">HOMEBREW_CORE_GIT_REMOTE</span><span class="o">=</span><span class="s2">&#34;https://github.com/Homebrew/homebrew-core&#34;</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">brew update
</span></span></code></pre></div>]]></content:encoded><category>DevOps</category><category>維運排錯</category><category>Linux</category><category>macOS</category><category>系統調優</category><category>故障排查</category></item></channel></rss>