肇鑫的日常博客

肇鑫 / Owen Zhao

独立开发者,主要开发 iOS、watchOS、macOS 应用。

目前在维护 SleepTapRooster Time,以及 Markdown Writer 相关工具。

最新文章

trojan在Ubuntu 22.04里会忽好忽坏的真正原因

技术

很长一段时间以来,我的trojan经常性地断线,需要经常重启它,才会好用一段时间。这很让我苦恼,我曾多次尝试修复它。但鉴于我自己的网络知识有限,每次只能依赖于通过Google搜索学习,又或者AI辅助来排查,弄了几次,都是能好上半天,但是又坏。最近,我终于搞定了这个问题,因此来分享一下。

trojan我已经使用了好多年了。有多久呢?我从Ubuntu 18.04 LTS开始,一路从20.04,22.04用下来。我虽然用的是LTS版本,但是我向来不用最新,而是使用更稳定的次新版。因此,到目前为止,我还没有使用24.04。

排查的方式

我把排查的思路写下来,如果你遇到了问题,也可以这么排查。当trojan的客户端连接之后,测速超时时,需要按照以下排查。

  1. 查看nginx里的正常网站能否使用,如果不能,则可能是nginx服务可能有问题,又或者是连接数不足。
    1. 如果是nginx服务有问题,则重启nginx服务。这个可能性比较小。
    2. 连接数不足,可以扩大连接数。
  2. 此外,也可能是DNS的问题。Linux服务器默认都会开启本地的DNS缓存,而且首选是虚拟机提供商提供的内部服务器。可是我使用的虚拟机提供商Vultr,提供的DNS内部服务器不够稳定,一旦它出了问题。也会导致trojan服务无法使用。
    1. 这类问题可以通过ping -c 3 goole.com或者查看trojan的日志来看error的类型是否是无法解析域名之类的确定。
    2. 解决办法是添加1.1.1.1,8.8.8.8这类第三方服务器到本地服务器的下方作为备用。
    3. 添加检测的脚本到cron,每5分钟执行一次,检测到了此类错误,就重启对应的dns缓存服务。

这两类问题解决之后。trojan偶尔还是会出现问题。通过查看,我发现原来trojan的代码由于太过古老,它在2021年就已经停止更新了。它在22.04下存在内存泄露。正常使用的情况下,它的内存占用只有10MB左右,但是一旦内存泄露,会逐渐膨胀到400多MB。这应该还不是它的极限,只不过是我的虚拟机只有1GB的内存,所以它最多也就能占用这么多的内存。

如果你的trojan的日志里有stream失败的错误信息,然后你看到了占用内存异常的大。就可以直接重启trojan服务。

将trojan占用内存的命令写入脚本,然后遇到大于20MB,就重启trojan服务。这可以也可以添加到cron,5分钟运行一次。

结论

原本在18.04,20.04下运行相当稳定的trojan服务,在22.04下运行的时候却因为太过古老存在内存泄露。同时虚拟机提供商提供的本地DNS服务器不够稳定,有时也会导致问题。因此,我们创建脚本,定时检测这两方面的问题,如果遇到了,就重启对应的服务。

前面我提到的信息都比较简略,这是因为在如今的时代,你只需要这些简略的信息,然后将它作为提示词,询问你自己习惯使用的AI就可以了。所以,这些简略信息已经足够了。

trojan作为一个多年停止更新的服务,目前在最新的系统中使用,已经明显过时了。解决的办法是在docker中使用旧版的Ubuntu系统。又或者想我这样,使用脚本在需要时重启服务。更好的办法是使用更现代的,更新更频繁的其他服务,比如v2ray之类的。

2026年1月16日更新

最新我发现了导致内存泄露的原因。是macOS下的FlClash。我将它关了,就好了。使用Clash Verge没有这个问题。

同时我提交了这个问题给FlClash。可以参考这篇文章。谈谈思维误区

2026年1月28日更新

将客户端换成了Mihomo的Clash Party。已经连续超过1周没有遇到内存泄露的问题了。

AI辅助编程,使用图形还是命令行?我当前的看法

技术

我是一名苹果设备的开发者,我开发过iOS、macOS、watchOS以及visionOS的应用。

大家可能注意到最近两周我提交到Copilot Xcode的bug变少了,这是因为我开始尝试使用命令行的方式编程。经过这段时间的使用,我发现二者各有优缺点。从长期来看,我认为图形界面的胜算更大,但是短期内它的缺点让我远离它。

下面我说的优缺点都是针对Copilot的亲自使用。一个是Copilot CLI,一个是GitHub Copilot for Xcode。

命令行方式的优点

更自由

命令行通常可以访问磁盘的全部空间,甚至可以帮助不熟悉使用的用户修改自己的配置文件。

使用命令行时,不必一直保持Xcode的窗口在最前。因此,可以利用这个时间多开几个窗口,或者干一些其他的事情。比如说刷刷X。图形界面就不行,它必须保证Xcode的在最前。如果不在最前,它就会不停的把它切换到最前。我之前反映过这个问题,开发者认为,会影响到其他的一些功能的实现。但是我觉得至少应该提供个选项来打开或者关闭这种吧。比如说让图形界面更接近命令行的方式。

更少的打断

使用图形的时候经常遇到打乱,一般是上下文不足。但是使用命令行的时候,从来没有遇到过类似的事情。命令行的中断往往是网络造成的,或者是配额超限造成的。

图形方式的优点

更简单的划定范围和指定区域

图形方式可以直接获得当前的文件,因此上下文更加简洁。AI往往可以在第一时间找到自己需要修改的内容。这一点是命位行方式无法比拟的。命令行要做到这一点,需要在复制粘贴之间反复切换。先复制文件名,然后再粘贴到命令行上。这个步骤虽然简单,但是很繁琐。远远没有通过鼠标点击那么简单。而且图形界面这种操作是自然而然的,不必特意去操作。

而如果在命令行下,你没有提供具体的文件信息,它就会在项目中整体的搜索,往往会花费更长的时间。甚至有时都找不到。

阻止我继续使用命令行,而不是图形的原因

长期以来,存在一个一直未解决的问题。就是图形界面下经常会写错文件。明明应该修改A的文件的内容,但是却将全部内容写入到了B文件中,并将B文件覆盖。这个问题我已经提交很久了,但是一直也没能修复。而这个问题可比上面提到的命令行的缺点要难以忍受的多。

以上就是我对这个问题的一些简单的看法。欢迎大家讨论,提出更好的意见和建议。

一起自建Trojan服务器经常断联问题的解决过程

技术

这两天我的Trojan非常不稳定,经常断连。比如昨天下午开始一直到晚上都不行。今天凌晨3点多好了,结果6点多又不行了。一直到刚刚,我决定看看到底是什么原因,能否自己修复。

遇事不决问AI

我先将我的困境描述给了AI。

  • trojan服务通过nginx代理,nginx的443端口访问正常,正常的https能访问,之前trojan也一切正常。但是最近两天经常有部分时段trojan就不能用了。这是什么原因?

AI给出了五条可能的主要原因:

  1. 运营商或防火墙干扰
  2. Nginx 配置问题或代理条件变化
  3. Trojan 后端服务自身问题
  4. 证书自动续签/变更导致短暂异常
  5. 攻击或扫描压力过大

我最担心的其实是第一条,因为对于这条我自己无能为力。AI同时提供了排查的顺序。

我选择首先排查trojan的状态。很幸运,这里面就有几个错误。我把日志发给AI。

status trojan
● trojan.service - trojan
     Loaded: loaded (/etc/systemd/system/trojan.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2025-09-09 10:16:44 UTC; 15h ago
       Docs: https://trojan-gfw.github.io/trojan/config
             https://trojan-gfw.github.io/trojan/
   Main PID: 859 (trojan)
      Tasks: 2 (limit: 1005)
     Memory: 144.2M
        CPU: 12.064s
     CGroup: /system.slice/trojan.service
             └─859 /usr/local/bin/trojan /usr/local/etc/trojan/config.json

Sep 10 01:52:23 vultr trojan[859]: [2025-09-10 01:52:23] [INFO] 127.0.0.1:55918 authenticated as 7ac54067666
Sep 10 01:52:23 vultr trojan[859]: [2025-09-10 01:52:23] [INFO] 127.0.0.1:55918 requested connection to www.gst>
Sep 10 01:52:24 vultr trojan[859]: [2025-09-10 01:52:24] [INFO] 127.0.0.1:55928 authenticated as 7ac54067666
Sep 10 01:52:24 vultr trojan[859]: [2025-09-10 01:52:24] [INFO] 127.0.0.1:55928 requested connection to e7.i.le>
Sep 10 01:52:32 vultr trojan[859]: [2025-09-10 01:52:32] [INFO] 127.0.0.1:36566 authenticated as 7ac54067666
Sep 10 01:52:32 vultr trojan[859]: [2025-09-10 01:52:32] [INFO] 127.0.0.1:36566 requested connection to www.goo>
Sep 10 01:52:42 vultr trojan[859]: [2025-09-10 01:52:42] [ERROR] 127.0.0.1:55762 cannot resolve remote server h>
Sep 10 01:52:42 vultr trojan[859]: [2025-09-10 01:52:42] [INFO] 127.0.0.1:55762 disconnected, 0 bytes received,>
Sep 10 01:53:02 vultr trojan[859]: [2025-09-10 01:53:02] [ERROR] 127.0.0.1:55792 cannot resolve remote server h>
Sep 10 01:53:02 vultr trojan[859]: [2025-09-10 01:53:02] [INFO] 127.0.0.1:55792 disconnected, 0 bytes received,>

AI也发现了这个错误,并分析说“也就是说,Trojan 运行没问题,但访问网站时遇到了 DNS 解析失败。这点非常关键!”

AI进一步分析:

  • VPS供应商自身DNS故障(Vultr、搬瓦工等偶有发生)。
    • /etc/resolv.conf 中DNS服务器填错,或者被systemd-resolved之类自动修改导致的DNS挂掉。
    • 本地防火墙或iptables阻断了外发的53端口。
    • 系统资源紧张(低内存、负载高)可能导致系统进程异常,systemd-resolved或dnsmasq死掉。

知道了原因,解决就很简单了。重启DNS服务和Trojan,故障解决。

一例特殊的Windows笔记本变卡问题的解决

技术

最近前同事的电脑变卡了,说是电脑的C盘太满造成的,她想把用户文件夹从C盘移动到D盘,问我可不可以我?我说不行,不能那么做。我以为是她的照片视频过多造成的,因为我记得她的iPhone里有很多照片和视频,而她不习惯删除。前同事陪女儿在加拿大念书,我和她约了她方便的时间,进行电脑连线。

因为远程协助存在延迟,并且同样不同获得需要系统权限的操作,我们选择屏幕分享的方式,她来操作,我观看她的操作,语音进行指挥。

看了一下,C盘总计200GB,剩余不到8GB,Windows显示磁盘占用为红色。

原本我想着只是磁盘空间不足的问题,但是实际使用中发现电脑速度非常慢,异乎寻常的慢,不正常的慢,在我的电脑上几秒钟就能查完的磁盘清理,在她的电脑上,需要几十秒到几分钟。我用任务管理器来看她的CPU是intel的11代的处理器,频率为2.4 GHz,但是实际运行的只有0.39 GHz。

我以为是她没有插电源,问她,她说插了,然后我让她将系统设置,电源和电池中的电池规划,从默认平衡改成性能优先,结果还是没有恢复,重启也还是依旧。

因为电脑型号是联想小新Air,于是我用“联想笔记本 0.39GHz 锁频”来搜索。搜索到了一篇知乎的文章,说是这个是Windows的休眠bug导致的。Windows 10或者11休眠之后,可能导致CPU会错误锁定较低的频率不恢复。并且即便使用Windows本身的重启功能重启系统,也没有用,因为休眠之后有残留数据被保留了。正确的解决办法是在Windows打开的时候长按笔记本上的电源按钮,强制关机,这样残留数据就会清空,故障就会消失了。

这么做之后,果然系统速度恢复了。可以在任务管理器中看到平时使用时的CPU频率恢复到了1.x GHz。

之后安装了腾讯电脑管家,用它的清理功能清理出来40G的空间。然后使用Windows自带的清理功能,又删除掉20G左右的Windows安装的临时文件。这样200G的C盘就有60G以上的剩余空间。

结论

虽然C盘过满会导致系统运行速度下降,但是如果速度异乎寻常的慢,就需要考虑是否还有其它的可能性。可以使用任务管理器或者性能监视器,观察系统每个组件的性能,比如常见的就是CPU、内存和磁盘。CPU速度,内存占用,磁盘占用和磁盘速度。我自己的七彩虹组装机,配的金士顿硬盘速度就有问题,经常占用100%,导致系统缓慢。

另外,磁盘清理软件,免费的腾讯电脑管家的清理功能就很好用了。不必再找其它第三方的软件了。

最后,Windows安装的临时文件,要清理,一定要使用Windows自带的清理,手动删除会提示缺少权限,删除不干净。不过Windows改变了清理应用的调用位置,以前从磁盘属性,工具里可以直接调用,现在需要在搜索里输入“清理”来搜索到这个工具。并且默认是不扫描windows安装的临时文件的,需要运行时选择管理员权限,然后在点击搜索系统文件,这样才会出现。

用Mac mini替换掉Apple TV后的一些感受

技术

我有一台Apple TV HD,也就是最高支持1080p的那款。一直以来用得还可以。我主要是用Airplay转播Mac mini上播放的内容。

今年我趁着国补,将Mac mini M1换成了Mac mini M4。新问题随之而来。在使用5G频段连接Mac mini M4和Apple TV之后,Airplay的视频,声音会断断续续的。而这个问题在原本的Mac mini M1的时候是没有的。

根据我的分析,应该是M4的Wi-Fi支持160Mhz,而Apple TV不支持导致的。我也找到了解决办法。M4 Mac mini连接Apple TV HD声音断断续续问题的一种解决方案

上面的办法虽然能一定程度解决问题,但是每次开始的时候还是会卡顿一段时间才会正常。而且声音的稳定性特别容易受干扰,只要有人在路由器和Apple TV直间走动,就经常要卡上一段时间。

M1换下来了之后,我本来打算当二手卖掉。但是现在M4的价格实在太低了。M1卖不上价,我觉得不划算。于是打算留下来自己用。首选就是替换掉Apple TV,彻底解决掉声音断断续续的问题。

M1的准备配置

要实现M1的远程控制,要打开M1的屏幕共享。这样,就可以在M4上直接登录M1的电脑。另外,建议M1的文件共享也打开,可以方便互传文件。最后,在能耗里,打开“唤醒以供网络访问”,这样就算它睡眠了,也可以通过M4来唤醒它。

M1和Apple TV的不同之处

具体使用起来,M1还是要比Apple TV麻烦一些的。虽然都是通过HDMI连接的电视。但是Apple TV可以做到睡眠时也可以在Airplay中出现,选择之后就会被唤醒,可以直接使用。但是M1必须先打开电视,然后再Finder中选择M1的主机,选择屏幕共享,之后才能在Airplay看到它。

别的倒是没啥了。M1在Airplay的时候可比Apple TV稳定多了。不仅连接迅速,而且很稳。关机的时候,直接关电视就可以了。M1会在一定时间之后自动进入睡眠。

macOS时间机器恢复指南(最新版)

技术

写作缘由

今天我尝试升级到macOS 26 beta 2,但是发现有一些必用的应用不支持,只好通过时间机器退回旧版。但是在恢复的过程遇到了多个问题,这在之前的恢复时都是不存在的。因此打算记录一下,算是为后来者踩坑了吧。

正文

苹果官方文档

根据苹果的官方文档,开机时长按10秒电源键,就会进入恢复系统,然后可以在其中选择时间机器恢复。

但是这个说法只对了一半。即开机时长按10秒电源键,的确会进入恢复系统。但是恢复系统并不能通过时间机器恢复。你选择时间机器恢复之后,会提示你,需要使用迁移助手进行恢复。

实际上,现在恢复系统并不能直接恢复时间机器的备份了,必须先安装对应的系统,然后才能通过迁移助手恢复。这增加了步骤和时间,是一种倒退。

正确的恢复步骤

  1. 关机状态下,按住开机键10秒,进入恢复界面。
  2. 选择磁盘管理,格式化你要安装的macOS的磁盘。
  3. 自动重启后,自动进入恢复界面,选择安装macOS,这会安装你的机型对应的最新版稳定版macOS。
    1. 如果你想安装其它版本,可以提前制作对应的优盘,然后从优盘启动。
  4. 重启之后,进入系统,然后选择从时间机器恢复。

其它问题

以下的内容十分重要,务必要在执行所有操作之前就考虑到。

之前的时间机器恢复的时候,会列出可以恢复的所有时间点。这是因为macOS只能恢复相同版本的备份。当前版本的macOS(15.5),做了一些改进,但是引入了更多的不方便。

当前版本,时间机器可以跳过小版本的不同进行恢复,比如15.5可以恢复15.6 beta的备份。但是如果最新的备份是跨越大版本的,就会直接提示无法恢复,而不是列出所有的可以恢复的时间点。

解决办法

将包含时间机器备份的移动硬盘插入一台可用的macOS,然后进入Finder。删除掉新版的备份的时间点对应的文件夹,只留下旧版的作为最新的时间点。然后重新插回需要恢复的Mac。

你和AI之间存在利益冲突

技术

大模型,以下简称AI。目前在辅助编程方面十分流行。不过在我使用过多个不同的类似工具,包括并不限于Github Copilot,AlexSideBar,通义灵码等,之后。我发现了一个有趣的现象。

在解释这个有趣的现象之前。我想先向某些不熟悉AI编程的读者简单介绍一下AI编程的大致过程。

  1. 开发者使用编辑器将开发的项目打开。
  2. 选择用来询问、作答的AI模型。
  3. 提出具体的问题,同时还要划定范围,比如说是单独的某个文件,又或者某几个文件,又或者全部文件。(有些比较智能的客户端会主动扩大范围,这个暂不讨论)
  4. 等待AI分析、作答。
  5. 开发者对比AI的代码和原始代码,评估是否解决了提出的问题。如果解决,就可以跑一下测试看看。如果没解决,那就针对不足的地方重新提问。
  6. 以此反复。

分析

经常有人说某某AI编程工具特别牛,就是token用得太狠了。充上100美元,一天就用光了。那么,如果我们想减少token的用量,我们一起看看上面的6个步骤有哪些可以进行优化,以减少用量。

首先排除1和4、5和6。要想减少token的用量。主要看2选择的模型,和3提出的具体的问题,以及划定的范围。

但是2这个可以选择的范围不大。因为每个人都有各自的偏好。有的人觉得Claude Opus最牛,有的人觉得Gemini Pro最强,当然也有人更偏好OpenAI O3的。所以,这个主要是个人便好,而不是token消耗。

因此主要的问题就在与步骤3。抛开你和AI对话的那几段文字。划定的范围是最重要的,选择单一文件或几个文件,相比于直接扔整个项目给AI,让它自己选,消耗的token数量肯定不是一个数量级别的。

那么我们要如何优化步骤3呢?首先,我们发现每次发送文件给AI时,AI都是当作是全新的在解析,也就每次都要消耗新的token。理论上,如果我们可以每次把内容分成不变的和已经变化的发给AI,然后让AI处理变化的部分,就可以节省大量的token。而且,由于我们大部分时间都是接受了AI给出的方案。那么AI实际上并不需要重新理解当前的代码。如果它确定用户接受了它的方案,它只需要将它上次输出的结果的token直接拿过来作为输入就可以了。

如果厂家可以做到我上面提出的这个优化,那么我们理论上最高可以节省接近一半的token。但是厂家应该没有动力去做这个优化。因为在这个问题上,厂家、AI、开发者的利益是不一致的。

  • 对于AI来说,直接使用结果的token来作为输入的一部分是有益的,因为提高了效率。
  • 对于开发者来说,更是有益的,因为可以省钱。
  • 但是对于厂家来说,用户省下的钱,就是他少赚的钱。因此,虽然厂家一再强调AI的普及需要大量的电,但是他们却没有动力去主动帮用户节省。他们只会在内部帮自己节省。

结论

很有意思吧。在提高效率,节省token这方面。厂家和AI、开发者的利益是不一致的。这极大地阻碍了AI的更快发展。AI崛起吧!先干掉厂家!

Safari登录时非常卡顿问题的解决

技术

一直用通行密钥登录。可是最近突然用不了了,会界面一直卡住,只能通过密码的方式来登录。

我尝试了常规的办法,比如清空Safari的数据。没有作用,然后我又尝试打开密码应用,删除掉一些过期的密码。还是没有作用。

我注意到spindump在这期间CPU占用会达到100%,我问了AI,AI说这个是Spotlight的工作进程,只要不一致100%,能自动恢复正常就没问题。于是我就放弃了这个线索。

这么将就用了两天,今天在浏览X的时候,看到有人提到自己为了追一个bug,把系统日志喂给AI,让AI逐一排查。我一想,这是个好主意啊。于是我又开始研究这个问题。

正式研究

我先打开控制台应用,然后点击开始。我一开始过滤的是Safari的日志,但是把错误和故障的日志发给AI后,AI的答案没啥用。

于是我又把日志范围扩大到我操作期间的所有系统日志,结果发现了一个这样的故障。

AuthenticationServicesAgent	
Failed to acquire lock for -[ASCAgent cancelCurrentRequest]_block_invoke

但是AI对于这个问题也没啥好办法。

于是我取消了日志所有的过滤器。结果看到满屏的Spotlight的日志。于是我禁用了SpotLight的索引。然后再试,结果还卡。重启,不卡了。

结论

用户在登录时,会先调用密码应用查询用户名,然后通过密码或者通行密钥登录。在这个过程中,会卡顿几次:

  1. 查询用户名时卡一次。
  2. 选择用户名时卡一次。
  3. 选择通行密钥登录时一直卡。

也就是说,1和2时遇到了缓慢的问题,而3遇到了没有查询结果的问题。

而每次遇到这种情况,macOS的处理方式,就是使用Spotlight重新对于相关内容(密码应用的数据)进行索引。这进一步造成了卡顿。

建议的解决步骤

router

禁用Spotlight的方法

将系统和用户自身文件夹所在的磁盘分区,加入到Spotlight的搜索隐私。恢复则移除即可。