<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>向阳哌小站</title><description>天晴了，太阳就会出来的。</description><link>https://fuwari.vercel.app/</link><language>zh_CN</language><item><title>Windows to USB 迁移笔记</title><link>https://fuwari.vercel.app/posts/windows-to-usb-%E8%BF%81%E7%A7%BB%E7%AC%94%E8%AE%B0/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/windows-to-usb-%E8%BF%81%E7%A7%BB%E7%AC%94%E8%AE%B0/</guid><pubDate>Tue, 19 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;准备切 Linux，但又怕一刀切翻车，于是先把原来的 Windows 克隆到外置 NVMe 里，当成过渡系统和应急 fallback。&lt;/p&gt;
&lt;p&gt;先说结论：&lt;br /&gt;
&lt;strong&gt;成功从 USB 外置 NVMe 启动，原来的软件、配置、文件基本都还在。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;但是过程并不是克隆完就能跑，中间踩了几个坑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;克隆后无法启动：&lt;code&gt;0xc000000e&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;修完引导后蓝屏：&lt;code&gt;0x0000007B&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;能进系统后，关机/重启时 USB 硬盘盒提前断开&lt;/li&gt;
&lt;li&gt;RTL9210 硬盘盒能用，但不太适合长期 Windows-to-USB&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;0. 前情提要&lt;/h2&gt;
&lt;p&gt;我这次用的是 RTL9210 芯片的 NVMe USB 硬盘盒。&lt;/p&gt;
&lt;p&gt;普通当移动硬盘没啥问题，但拿来跑 Windows 系统盘就有点边缘了。&lt;/p&gt;
&lt;p&gt;因为 Windows-to-USB 启动时，不是“系统启动后再识别移动硬盘”，而是启动早期就要靠 USB 控制器、UASP/USBSTOR、桥接芯片、NVMe 驱动一路把系统盘读出来。&lt;/p&gt;
&lt;p&gt;这条链路里只要有一环加载晚了，就会炸。&lt;/p&gt;
&lt;p&gt;所以先叠甲：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这不是万能教程，只是一次实战记录。&lt;br /&gt;
命令里的盘号和盘符一定要按自己机器实际情况改，别无脑复制。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;1. 目标&lt;/h2&gt;
&lt;p&gt;我的目标很简单：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;把当前内置盘里的 Windows 克隆到外置 NVMe；&lt;/li&gt;
&lt;li&gt;保留软件、配置、个人文件；&lt;/li&gt;
&lt;li&gt;外置盘可以独立启动；&lt;/li&gt;
&lt;li&gt;内置盘腾出来装 Linux；&lt;/li&gt;
&lt;li&gt;Windows 作为过渡和救命环境。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以这里不适合重装系统。&lt;br /&gt;
重装当然干净，但软件、注册表、授权、工作环境这些东西搬起来太痛苦。&lt;/p&gt;
&lt;p&gt;因此路线就是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;克隆现有系统，而不是重装
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 第一坑：克隆后无法启动 0xc000000e&lt;/h2&gt;
&lt;p&gt;克隆完第一次启动，直接报：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0xc000000e
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;大概意思是 Windows Boot Manager 找不到要启动的系统。&lt;/p&gt;
&lt;p&gt;一般是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;BCD 还指着原来的内置盘；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;外置盘 EFI 分区没写好；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;引导文件没生成完整。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;解决方式：进 WinPE 或 Windows 安装 U 盘。&lt;/p&gt;
&lt;p&gt;安装界面按：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Shift + F10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打开命令行。&lt;/p&gt;
&lt;p&gt;先用 &lt;code&gt;diskpart&lt;/code&gt; 找外置盘：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diskpart
list disk
select disk 1
list vol
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里 &lt;code&gt;disk 1&lt;/code&gt; 只是示例，别照抄。&lt;/p&gt;
&lt;p&gt;找到两个分区：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;EFI 分区：FAT32，一般 100MB 到 300MB；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Windows 分区：NTFS，里面有 &lt;code&gt;Windows&lt;/code&gt;、&lt;code&gt;Users&lt;/code&gt;、&lt;code&gt;Program Files&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;假设 EFI 是卷 2，Windows 是卷 4：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select vol 2
assign letter=S

select vol 4
assign letter=W

exit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;确认 &lt;code&gt;W:&lt;/code&gt; 真的是外置 Windows：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dir W:\Windows
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后重建 UEFI 启动文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bcdboot W:\Windows /s S: /f UEFI
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这一步做完，&lt;code&gt;0xc000000e&lt;/code&gt; 解决。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 第二坑：能引导，但蓝屏 0x7B&lt;/h2&gt;
&lt;p&gt;修完 BCD 后，Windows Boot Manager 能进了，但系统启动阶段蓝屏：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0x0000007B
INACCESSIBLE_BOOT_DEVICE
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个报错就很典型了：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;引导找到了 Windows，但 Windows 内核启动后找不到自己的系统盘。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;原因也很好理解：&lt;br /&gt;
原系统本来是从内置 NVMe/SATA 启动的，现在被我丢到了 USB 外置盘。&lt;br /&gt;
USB / UASP / 存储相关驱动如果没有在启动早期加载，系统自然就找不到自己了。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 离线改注册表&lt;/h2&gt;
&lt;p&gt;再次进入 WinPE 或安装 U 盘命令行。&lt;/p&gt;
&lt;p&gt;假设外置 Windows 分区还是 &lt;code&gt;W:&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;先备份注册表：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;copy W:\Windows\System32\Config\SYSTEM W:\SYSTEM.bak
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;加载外置系统的 SYSTEM 注册表：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reg load HKLM\OFFSYS W:\Windows\System32\Config\SYSTEM
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;看当前 ControlSet：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reg query HKLM\OFFSYS\Select
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我这里是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Current        0x1
Default        0x1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;所以后面改的是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ControlSet001
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你那里不是 &lt;code&gt;0x1&lt;/code&gt;，就按实际情况改。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 设置 BootDriverFlags&lt;/h2&gt;
&lt;p&gt;关键命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reg add HKLM\OFFSYS\ControlSet001\Control /v BootDriverFlags /t REG_DWORD /d 20 /f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的 &lt;code&gt;20&lt;/code&gt; 是十进制，也就是十六进制 &lt;code&gt;0x14&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;作用就是让 Windows 更早加载 USB 存储相关驱动。&lt;br /&gt;
从内置盘克隆到 USB 后，这一步很关键。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 强制存储驱动早期启动&lt;/h2&gt;
&lt;p&gt;继续执行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reg add HKLM\OFFSYS\ControlSet001\Services\USBXHCI /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\USBHUB3 /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\UASPStor /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\USBSTOR /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\disk /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\partmgr /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\mountmgr /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\volmgr /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\storport /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\stornvme /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\storahci /v Start /t REG_DWORD /d 0 /f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;有些服务项可能不存在，报错也不一定有问题，继续就行。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 处理 StartOverride&lt;/h2&gt;
&lt;p&gt;有些驱动就算 &lt;code&gt;Start=0&lt;/code&gt;，也可能被 &lt;code&gt;StartOverride&lt;/code&gt; 覆盖掉。&lt;/p&gt;
&lt;p&gt;所以继续补一刀：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reg add HKLM\OFFSYS\ControlSet001\Services\USBXHCI\StartOverride /v 0 /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\USBHUB3\StartOverride /v 0 /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\UASPStor\StartOverride /v 0 /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\USBSTOR\StartOverride /v 0 /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\stornvme\StartOverride /v 0 /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\ControlSet001\Services\storahci\StartOverride /v 0 /t REG_DWORD /d 0 /f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;顺手关掉快速启动：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reg add &quot;HKLM\OFFSYS\ControlSet001\Control\Session Manager\Power&quot; /v HiberbootEnabled /t REG_DWORD /d 0 /f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后卸载离线注册表：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reg unload HKLM\OFFSYS
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再重建一次引导：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bcdboot W:\Windows /s S: /f UEFI
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重启。&lt;/p&gt;
&lt;p&gt;这次成功进系统。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;8. 进系统后先检查&lt;/h2&gt;
&lt;p&gt;进系统后别急着开香槟，先确认自己没有启动错盘。&lt;/p&gt;
&lt;p&gt;PowerShell：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Get-Partition -DriveLetter C | Get-Disk
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者打开磁盘管理：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diskmgmt.msc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;确认当前 &lt;code&gt;C:&lt;/code&gt; 确实在外置 NVMe 上。&lt;/p&gt;
&lt;p&gt;然后建议跑一遍：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sfc /scannow
DISM /Online /Cleanup-Image /RestoreHealth
chkdsk C: /scan
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;9. 第三坑：能开机，但关机/重启抽风&lt;/h2&gt;
&lt;p&gt;系统能进以后，我又遇到一个新问题：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;开机正常，但关机或重启时，USB 硬盘盒显示已经断开，系统还卡在关机流程里。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对普通移动硬盘来说，这可能只是掉盘。&lt;br /&gt;
但对系统盘来说，这就很刺激了。&lt;/p&gt;
&lt;p&gt;Windows 还没关完，根文件系统先没了。&lt;br /&gt;
属于是系统自己把自己脚下的地板拆了。&lt;/p&gt;
&lt;p&gt;如果已经卡死，硬盘灯也不闪，可以长按电源强制关机。&lt;br /&gt;
下次开机后先跑：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chkdsk C: /scan
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不放心再跑：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sfc /scannow
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ChatGPT说要关闭快速启动，关闭 USB 选择性暂停、磁盘空闲休眠、PCIe 链路省电，这堆东西我日常就关了，你没关的话出问题了可以考虑一下是不是这些问题&lt;/p&gt;
&lt;p&gt;ChatGPT还说要把磁盘驱动器的电源策略改成快速删除，但是这个东西是系统盘，需要重启生效，但是可但是改这个就是为了解决重启失败的问题，闭环了。 &lt;s&gt;遇到困难睡大觉！&lt;/s&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;10. RTL9210 还值得继续折腾吗？&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;遇到困难摆大烂！&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果只是迁 Linux 前的过渡，不值得继续死磕。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;现在它已经完成核心任务了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;能启动；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;能进原系统；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;软件和文件基本都在；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Linux 迁移期间能当 fallback。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;剩下的关机/重启问题，更像是硬盘盒固件、USB 控制器、线材、电源管理的兼容性问题。&lt;/p&gt;
&lt;p&gt;真要继续查，可能还得折腾：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;刷 RTL9210 固件；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;换硬盘盒；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;测 UASP / USBSTOR 差异；&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但我只是临时用，不想和它过一辈子。 &lt;s&gt;你就说能不能用！&lt;/s&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;11. 我的最终策略&lt;/h2&gt;
&lt;p&gt;这个外置 Windows 我最后定位为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;临时工作环境
过渡系统
应急 fallback
不是长期主系统
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;所以后续使用原则也很简单：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;不睡眠；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不休眠；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不开快速启动；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不开 BitLocker；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不把唯一重要数据放这里；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;工作文件及时同步到云盘 / Git / NAS；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;异常关机后跑 &lt;code&gt;chkdsk C: /scan&lt;/code&gt;；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;尽快迁完 Linux。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;这次 Windows-to-USB 的关键路径：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;克隆系统
修 EFI / BCD
解决 0xc000000e
解决 0x7B
关闭快速启动和省电
确认能启动
能用就收手
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最关键的修复命令是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reg add HKLM\OFFSYS\ControlSet001\Control /v BootDriverFlags /t REG_DWORD /d 20 /f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以及把 USB、UASP、NVMe、磁盘相关驱动改成启动早期加载。&lt;/p&gt;
&lt;p&gt;Windows-to-USB 不是不能用，但它不是普通克隆工具点一下就能稳定跑的场景。&lt;br /&gt;
它更像是一个“能跑，但要理解启动链路”的偏门玩法。&lt;/p&gt;
&lt;p&gt;如果长期用，建议认真选硬盘盒、固件、线材和接口。&lt;br /&gt;
如果只是像我一样迁 Linux 前留个后路，那就别追求完美：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;能启动、能工作、数据有备份，就可以收手了。&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;尾声：脚本&lt;/h2&gt;
&lt;p&gt;敲那一堆&lt;code&gt;reg add&lt;/code&gt;我人有点麻，放结尾的目的是让一步步照着做的你也麻一遍， &lt;s&gt;不能只有我一个人难受&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;使用方法：&lt;/p&gt;
&lt;p&gt;如果你的外置 Windows 分区是 &lt;code&gt;W:&lt;/code&gt;，EFI 分区是 &lt;code&gt;S:&lt;/code&gt;，完整流程就是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fix-usbstor-0x7b.bat W:
bcdboot W:\Windows /s S: /f UEFI
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;fix-usbstor-0x7b.bat:&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@echo off
setlocal EnableExtensions EnableDelayedExpansion

REM ============================================================
REM  fix-usb-boot-driver.bat
REM
REM  Purpose:
REM    Fix Windows cloned-to-USB INACCESSIBLE_BOOT_DEVICE / 0x7B
REM    by enabling USB / UASP / storage drivers for early boot.
REM
REM  Usage:
REM    fix-usb-boot-driver.bat W:
REM
REM  Example:
REM    If your external Windows partition is W:
REM      fix-usb-boot-driver.bat W:
REM
REM  Run from WinPE / Windows Setup command prompt.
REM ============================================================

if &quot;%~1&quot;==&quot;&quot; (
    echo Usage: %~nx0 ^&amp;lt;WindowsDrive^&amp;gt;
    echo Example: %~nx0 W:
    exit /b 1
)

set &quot;WINDRV=%~1&quot;

REM Remove trailing backslash if present
if &quot;%WINDRV:~-1%&quot;==&quot;\&quot; set &quot;WINDRV=%WINDRV:~0,-1%&quot;

set &quot;SYSTEM_HIVE=%WINDRV%\Windows\System32\Config\SYSTEM&quot;

echo.
echo Target Windows drive: %WINDRV%
echo SYSTEM hive: %SYSTEM_HIVE%
echo.

if not exist &quot;%SYSTEM_HIVE%&quot; (
    echo ERROR: Cannot find SYSTEM hive.
    echo Please make sure %WINDRV% is the offline Windows partition.
    exit /b 1
)

echo Backing up SYSTEM hive...
copy &quot;%SYSTEM_HIVE%&quot; &quot;%WINDRV%\SYSTEM.bak&quot; &amp;gt;nul
if errorlevel 1 (
    echo ERROR: Failed to back up SYSTEM hive.
    exit /b 1
)

echo Loading offline SYSTEM hive...
reg load HKLM\OFFSYS &quot;%SYSTEM_HIVE%&quot;
if errorlevel 1 (
    echo ERROR: Failed to load offline SYSTEM hive.
    echo If HKLM\OFFSYS is already loaded, run:
    echo   reg unload HKLM\OFFSYS
    exit /b 1
)

REM ------------------------------------------------------------
REM Detect Current ControlSet
REM ------------------------------------------------------------

set &quot;CURRENT_HEX=&quot;

for /f &quot;tokens=3&quot; %%A in (&apos;reg query HKLM\OFFSYS\Select /v Current 2^&amp;gt;nul ^| find /i &quot;Current&quot;&apos;) do (
    set &quot;CURRENT_HEX=%%A&quot;
)

if &quot;%CURRENT_HEX%&quot;==&quot;&quot; (
    echo ERROR: Failed to detect Current ControlSet.
    reg unload HKLM\OFFSYS &amp;gt;nul 2&amp;gt;&amp;amp;1
    exit /b 1
)

REM Convert hex-like value, for example 0x1, to decimal
set /a CURRENT_NUM=%CURRENT_HEX%

if &quot;%CURRENT_NUM%&quot;==&quot;1&quot; (
    set &quot;CONTROLSET=ControlSet001&quot;
) else if &quot;%CURRENT_NUM%&quot;==&quot;2&quot; (
    set &quot;CONTROLSET=ControlSet002&quot;
) else if &quot;%CURRENT_NUM%&quot;==&quot;3&quot; (
    set &quot;CONTROLSET=ControlSet003&quot;
) else if &quot;%CURRENT_NUM%&quot;==&quot;4&quot; (
    set &quot;CONTROLSET=ControlSet004&quot;
) else (
    echo ERROR: Unsupported ControlSet number: %CURRENT_NUM%
    reg unload HKLM\OFFSYS &amp;gt;nul 2&amp;gt;&amp;amp;1
    exit /b 1
)

echo Detected Current: %CURRENT_HEX%
echo Using: HKLM\OFFSYS\%CONTROLSET%
echo.

REM ------------------------------------------------------------
REM Enable boot-time USB / storage driver loading
REM ------------------------------------------------------------

echo Setting BootDriverFlags...
reg add HKLM\OFFSYS\%CONTROLSET%\Control /v BootDriverFlags /t REG_DWORD /d 20 /f

echo.
echo Setting storage driver Start values...

reg add HKLM\OFFSYS\%CONTROLSET%\Services\USBXHCI /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\USBHUB3 /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\UASPStor /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\USBSTOR /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\disk /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\partmgr /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\mountmgr /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\volmgr /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\storport /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\stornvme /v Start /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\storahci /v Start /t REG_DWORD /d 0 /f

echo.
echo Setting StartOverride values...

reg add HKLM\OFFSYS\%CONTROLSET%\Services\USBXHCI\StartOverride /v 0 /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\USBHUB3\StartOverride /v 0 /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\UASPStor\StartOverride /v 0 /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\USBSTOR\StartOverride /v 0 /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\stornvme\StartOverride /v 0 /t REG_DWORD /d 0 /f
reg add HKLM\OFFSYS\%CONTROLSET%\Services\storahci\StartOverride /v 0 /t REG_DWORD /d 0 /f

echo.
echo Disabling Fast Startup / Hiberboot...
reg add &quot;HKLM\OFFSYS\%CONTROLSET%\Control\Session Manager\Power&quot; /v HiberbootEnabled /t REG_DWORD /d 0 /f

echo.
echo Unloading offline SYSTEM hive...
reg unload HKLM\OFFSYS
if errorlevel 1 (
    echo WARNING: Failed to unload HKLM\OFFSYS.
    echo You may need to run this manually:
    echo   reg unload HKLM\OFFSYS
    exit /b 1
)

echo.
echo Done.
echo SYSTEM hive backup saved as:
echo   %WINDRV%\SYSTEM.bak
echo.
echo Next recommended command, if your EFI partition is S::
echo   bcdboot %WINDRV%\Windows /s S: /f UEFI
echo.

exit /b 0
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Tailscale续集-自建Headscale&amp;Derp</title><link>https://fuwari.vercel.app/posts/tailscale%E7%BB%AD%E9%9B%86-%E8%87%AA%E5%BB%BAheadscalederp/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/tailscale%E7%BB%AD%E9%9B%86-%E8%87%AA%E5%BB%BAheadscalederp/</guid><pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;上回折腾了自建 Derper，这回干脆把控制平面也一起迁出来：&lt;code&gt;Headscale + Headplane + 自建 DERP&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;简单来说：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Headscale&lt;/code&gt;：Tailscale 控制平面的开源实现，负责设备注册、密钥交换、ACL、DNS 等。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Headplane&lt;/code&gt;：Headscale 的 Web 管理面板，用起来更接近官方 Tailscale 控制台。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DERP/Derper&lt;/code&gt;：当 P2P 打洞失败时的中继保底，也可辅助 NAT 穿透。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;需要先说明的是，DERP 并不是“明文代理”。Tailscale 的 DERP 只转发已经加密的 WireGuard 数据包，中继节点本身看不到业务流量内容；客户端会从控制平面拿到 DERP Map，再根据延迟等信息选择可用中继。&lt;/p&gt;
&lt;p&gt;但是 DERP 也不是普通 Web 服务。&lt;code&gt;derper&lt;/code&gt; 会在 TLS 内做协议切换，不兼容许多普通 HTTP 反代，所以不要把 DERP 直接丢到 Nginx/Caddy 这种七层 HTTP 反代后面。DERP 的 TCP 端口可以用 Docker 映射，STUN 的 UDP 3478 也必须单独放通。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;0. Pre 检测&lt;/h2&gt;
&lt;p&gt;先把几个鸡生蛋、蛋生鸡的问题排掉，不然后面会很痛苦。&lt;/p&gt;
&lt;h3&gt;0.1 域名与端口&lt;/h3&gt;
&lt;p&gt;本文使用两个域名：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;derp.example.net       # DERP 中继
tailscale.example.net  # Headscale + Headplane
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;公网侧需要放通：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;8443/tcp   # DERP TLS 入口，Docker 映射到容器内 443
3478/udp   # STUN
443/tcp    # Headscale / Headplane，由 Caddy 反代
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意：&lt;code&gt;DERPPort&lt;/code&gt; 可以非标端口，本文用 &lt;code&gt;8443&lt;/code&gt;；&lt;code&gt;STUNPort&lt;/code&gt; 是 UDP，不能靠普通 HTTP 反代解决。&lt;/p&gt;
&lt;h3&gt;0.2 创建 Docker 网络&lt;/h3&gt;
&lt;p&gt;本文里 DERP 和 Headscale 分开网络，Headscale/Headplane 接到 Caddy 所在网络：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker network create derper_network || true
docker network create caddy_network || true
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;0.3 证书文件准备&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;derper -certmode manual&lt;/code&gt; 对证书文件名比较挑剔。建议证书目录里至少准备：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;derp.example.net.crt
derp.example.net.key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果用的&lt;code&gt;acme.sh&lt;/code&gt;管理，用如下命令安装：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;acme.sh --install-cert \  
-d derp.example.net \  
--fullchain-file /path/to/certs/derp.example.net/derp.example.net.crt \  
--key-file /path/to/certs/derp.example.net/derp.example.net.key \  
--reloadcmd &quot;docker restart derp&quot;
# 也可以使用docker compose -f &quot;/path/to/compose.yml&quot; restart
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你的证书管理器导出的是 &lt;code&gt;fullchain.pem&lt;/code&gt; 和 &lt;code&gt;privkey.pem&lt;/code&gt;，可以软链接一份：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p ./certs/derp.example.net

ln -sf /path/to/fullchain.pem ./certs/derp.example.net/derp.example.net.crt
ln -sf /path/to/privkey.pem   ./certs/derp.example.net/derp.example.net.key

chmod 600 ./certs/derp.example.net/derp.example.net.key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你直接挂 1Panel、宝塔、Certd 这类面板的证书目录，也请确认容器内看到的文件名符合这个规则。&lt;/p&gt;
&lt;h3&gt;0.4 文件服务器存 DERP Map&lt;/h3&gt;
&lt;p&gt;我这里让 Headscale 从文件服务器拉 DERP Map。这样后续加节点、删节点，不需要每次进容器改配置。&lt;/p&gt;
&lt;p&gt;这里有一个坑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;headscale.derp.urls&lt;/code&gt; 适合放外部 URL，内容是 JSON DERP Map。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;headscale.derp.paths&lt;/code&gt; 适合放本地文件，内容是 YAML DERP Map。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以如果你要放到文件服务器，建议使用 JSON：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;Regions&quot;: {
    &quot;901&quot;: {
      &quot;RegionID&quot;: 901,
      &quot;RegionCode&quot;: &quot;derp&quot;,
      &quot;RegionName&quot;: &quot;MY DERP&quot;,
      &quot;Nodes&quot;: [
        {
          &quot;Name&quot;: &quot;901a&quot;,
          &quot;RegionID&quot;: 901,
          &quot;HostName&quot;: &quot;derp.example.net&quot;,
          &quot;DERPPort&quot;: 8443,
          &quot;STUNPort&quot;: 3478,
          &quot;STUNOnly&quot;: false
        }
      ]
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;保存到文件服务器，比如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://assets.example.net/tailscale/derpmap.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;先在服务器上测一下能否访问：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -fsSL https://assets.example.net/tailscale/derpmap.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果这里访问失败，后面 Headscale 可能启动后没有可用 DERP，甚至直接报 &lt;code&gt;initial DERPMap is empty&lt;/code&gt; 一类错误。&lt;/p&gt;
&lt;p&gt;如果你不想依赖文件服务器，也可以用本地 YAML：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;regions:
  901:
    regionid: 901
    regioncode: derp
    regionname: My DERP
    nodes:
      - name: 901a
        regionid: 901
        hostname: derp.example.net
        derpport: 8443
        stunport: 3478
        stunonly: false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后在 Headscale 配置中使用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;derp:
  urls: []
  paths:
    - /etc/headscale/derp.yaml
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;0.5 确保能连回服务器&lt;/h3&gt;
&lt;p&gt;自建控制平面最怕“服务在服务器上，但服务器自己访问不了自己的公网域名”。&lt;/p&gt;
&lt;p&gt;后续至少要确认：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -I https://tailscale.example.net
openssl s_client -connect derp.example.net:8443 -servername derp.example.net &amp;lt;/dev/null
curl -vk https://derp.example.net:8443/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果服务器自身访问 &lt;code&gt;tailscale.example.net&lt;/code&gt; 或 &lt;code&gt;derp.example.net&lt;/code&gt; 会走错线路，建议先解决 DNS、回源、云防火墙、NAT 回环问题。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;1. 启动 DERP&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;docker-compose.yml&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  derp:
    image: sparanoid/derp:edge
    container_name: derp
    restart: always
    init: true
    ports:
      - &quot;8443:443&quot;
      - &quot;3478:3478/udp&quot;
      # DERPPort 可以通过 Docker 端口映射改成非标端口
      # STUNPort 是 UDP，需要公网直接放通
    volumes:
      - ./certs/derp.example.net:/app/certs:ro
      # certdir 内建议包含：
      # derp.example.net.crt
      # derp.example.net.key

      - /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
      # 后续开启 -verify-clients=true 时使用
      # 需要宿主机运行 tailscaled，并且已经加入对应 tailnet

	command: sh -c &quot;
      derper \
        -hostname derp.example.net \
        -certdir /app/certs \
        -certmode manual \
        - verify-clients false \
        -home blank&quot;

    # 一些可选启动参数：
    # -verify-clients true 启用客户端验证，防止DERP被偷，需要配合Tailscale使用，且需要挂载Tailscale的套接字文件
    # -home blank 访问DERP返回空白界面，简单防止DERP服务被扫。
    # -home https://xxx.com 访问DERP跳转指定URL

    networks:
      - derper_network

networks:
  derper_network:
    external: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;启动：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose up -d
docker logs -f derp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -vk https://derp.example.net:8443/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果 &lt;code&gt;-home blank&lt;/code&gt; 生效，浏览器访问可能就是空白页，这不是坏事。主要看 TLS 是否正常、容器日志是否正常。&lt;/p&gt;
&lt;p&gt;再次强调：本文没有把 DERP 走 Caddy HTTP 反代。DERP 不是普通 WebSocket/HTTP 服务，不建议这么玩。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 启动 Headscale + Headplane&lt;/h2&gt;
&lt;p&gt;目录结构大概这样：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.
|-- compose.yml
|-- headplane-config
|   `-- config.yaml
|-- headplane-data
|-- headscale-config
|   |-- config.yaml
|   `-- dns_records.json
`-- headscale-data
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;先初始化 &lt;code&gt;dns_records.json&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p headscale-config headscale-data headplane-config headplane-data
echo &quot;[]&quot; &amp;gt; headscale-config/dns_records.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;后续如果需要添加自定义的dns records，可以在web console配置，但需要重启headscale才能生效，而新增主机的magic dns则不受影响
容器内需要挂载docker socket才能重启，但出于安全考虑，不建议这种做法&lt;/p&gt;
&lt;h3&gt;2.1 Headscale 配置&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;./headscale-config/config.yaml&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server_url: https://tailscale.example.net
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 0.0.0.0:9090
grpc_listen_addr: 0.0.0.0:50443
grpc_allow_insecure: false

noise:
  private_key_path: /var/lib/headscale/noise_private.key

prefixes:
  v4: 100.64.0.0/10
  v6: fd7a:115c:a1e0::/48

allocation: sequential

derp:
  server:
    enabled: false
    region_id: 901
    region_code: &quot;derp&quot;
    region_name: &quot;My DERP&quot;
    verify_clients: true
    stun_listen_addr: &quot;0.0.0.0:3478&quot;
    private_key_path: /var/lib/headscale/derp_server_private.key

  urls:
    - https://assets.example.net/tailscale/derpmap.json

  paths: []
  auto_update_enabled: true
  update_frequency: 24h

disable_check_updates: false
ephemeral_node_inactivity_timeout: 30m

database:
  type: sqlite
  debug: false
  gorm:
    prepare_stmt: true
    parameterized_queries: true
    skip_err_record_not_found: true
    slow_threshold: 1000
  sqlite:
    path: /var/lib/headscale/db.sqlite
    write_ahead_log: true
    wal_autocheckpoint: 1000

acme_url: https://acme-v02.api.letsencrypt.org/directory
acme_email: &quot;&quot;
tls_letsencrypt_hostname: &quot;&quot;
tls_letsencrypt_cache_dir: /var/lib/headscale/cache
tls_letsencrypt_challenge_type: HTTP-01
tls_letsencrypt_listen: &quot;:http&quot;
tls_cert_path: &quot;&quot;
tls_key_path: &quot;&quot;

log:
  level: info
  format: text

policy:
  mode: database
  path: &quot;&quot;

dns:
  magic_dns: true
  base_domain: tailnet.example.net
  override_local_dns: true
  nameservers:
    global:
      - 1.1.1.1
      - 1.0.0.1
      - 2606:4700:4700::1111
      - 2606:4700:4700::1001
  split: {}
  search_domains: []
  extra_records: []
  extra_records_path: /etc/headscale/dns_records.json

unix_socket: /var/run/headscale/headscale.sock
unix_socket_permission: &quot;0770&quot;

logtail:
  enabled: false

randomize_client_port: false

taildrop:
  enabled: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里 &lt;code&gt;server_url&lt;/code&gt; 必须是客户端能访问到的公网 HTTPS 地址。&lt;br /&gt;
&lt;code&gt;base_domain&lt;/code&gt; 不要和 &lt;code&gt;server_url&lt;/code&gt; 完全一样，MagicDNS 用它生成类似 &lt;code&gt;hostname.tailnet.example.net&lt;/code&gt; 的域名。&lt;/p&gt;
&lt;h3&gt;2.2 Headplane 配置&lt;/h3&gt;
&lt;p&gt;生成一个 32 字符的 cookie secret：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;openssl rand -hex 16
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;./headplane-config/config.yaml&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;host: &quot;0.0.0.0&quot;
port: 3000

# 不要带 /admin
base_url: &quot;https://tailscale.example.net&quot;

cookie_secret: &quot;替换成 openssl rand -hex 16 生成的值&quot;
cookie_secure: true
cookie_max_age: 86400

data_path: &quot;/var/lib/headplane&quot;

headscale:
  url: &quot;http://headscale:8080&quot;
  public_url: &quot;https://tailscale.example.net&quot;
  config_path: &quot;/etc/headscale/config.yaml&quot;
  config_strict: true
  dns_records_path: &quot;/etc/headscale/dns_records.json&quot;

integration:
  agent:
    enabled: false
    pre_authkey: &quot;&quot;

  docker:
    enabled: true
    container_label: &quot;me.tale.headplane.target=headscale&quot;
    socket: &quot;unix:///var/run/docker.sock&quot;

  kubernetes:
    enabled: false
    validate_manifest: true
    pod_name: &quot;headscale&quot;

  proc:
    enabled: false

# 不配置 OIDC 时，Headplane 登录依赖 Headscale API Key
# oidc:
#   enabled: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Headplane 的 Docker 部署方式要求配置文件和数据目录持久化；如果要让它在 UI 里管理 DNS、ACL 等配置，还需要挂载 Headscale 配置文件和 Docker socket。官方文档也说明了 Docker 模式、&lt;code&gt;/admin&lt;/code&gt; 访问路径和 API key 登录方式。(&lt;a href=&quot;https://headplane.net/install/docker&quot;&gt;Headplane&lt;/a&gt;)&lt;/p&gt;
&lt;h3&gt;2.3 Docker Compose&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;docker-compose.yml&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  headplane:
    image: ghcr.io/tale/headplane:0.6.2
    container_name: headplane
    restart: unless-stopped
    volumes:
      - &quot;./headplane-config/config.yaml:/etc/headplane/config.yaml&quot;
      # This should match headscale.config_path in your config.yaml
      - &quot;./headscale-config/config.yaml:/etc/headscale/config.yaml&quot;

      # If using dns.extra_records in Headscale (recommended), this should
      # match the headscale.dns_records_path in your config.yaml
      - &quot;./headscale-config/dns_records.json:/etc/headscale/dns_records.json&quot;

      # Headplane stores its data in this directory
      - &quot;./headplane-data:/var/lib/headplane&quot;

      # If you are using the Docker integration, mount the Docker socket
      - &quot;/var/run/docker.sock:/var/run/docker.sock:ro&quot;
      - &quot;/etc/localtime:/etc/localtime:ro&quot;
    networks:
      - caddy_network

  headscale:
    image: headscale/headscale:0.28.0
    restart: unless-stopped
    container_name: headscale
    # 这里可以先映射端口，测试访问成功后再配置caddy路由
    # ports:
    #   - &quot;127.0.0.1:8080:8080&quot;
    #   - &quot;127.0.0.1:9090:9090&quot;
    volumes:
      - &quot;./headscale-data:/var/lib/headscale&quot;
      - &quot;./headscale-config:/etc/headscale&quot;
      - &quot;/etc/localtime:/etc/localtime:ro&quot;
    command: serve
    healthcheck:
      test: [&quot;CMD&quot;, &quot;headscale&quot;, &quot;health&quot;]
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - caddy_network

networks:
  caddy_network:
    external: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;启动：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose up -d
docker logs -f headscale
docker logs -f headplane
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;检查健康状态：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it headscale headscale health
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也可以从公网访问：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -I https://127.0.0.1:8080/health
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Headscale 官方文档也建议先确认公网 health endpoint 可访问，再继续注册节点。(&lt;a href=&quot;https://headscale.net/stable/usage/getting-started/&quot;&gt;Headscale&lt;/a&gt;)&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 配置 Caddy 路由&lt;/h2&gt;
&lt;p&gt;我的 Caddy 是统一的 wildcard 入口，所以只加一个 matcher：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@tailscale {
  host tailscale.example.net
}

handle @tailscale {
  route {
    # Headplane 默认在 /admin
    @admin path /admin*
    handle @admin {
      reverse_proxy headplane:3000
      header {
        Access-Control-Allow-Origin  *
        Access-Control-Allow-Headers *
        Access-Control-Allow-Methods GET, POST, OPTIONS
      }
    }

    # 其余全部路由到 Headscale
    handle {
      reverse_proxy headscale:8080
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你不是 wildcard Caddyfile，也可以单独写：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tailscale.example.net {
  encode zstd gzip

  @admin path /admin*
  handle @admin {
    reverse_proxy headplane:3000
  }

  handle {
    reverse_proxy headscale:8080
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意：这里只代理 &lt;code&gt;tailscale.example.net&lt;/code&gt;。&lt;br /&gt;
&lt;code&gt;derp.example.net:8443&lt;/code&gt; 不要走这个 Caddy HTTP 反代。&lt;/p&gt;
&lt;p&gt;重载 Caddy：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it caddy caddy reload --config /etc/caddy/Caddyfile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也可以直接&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose down &amp;amp;&amp;amp; docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 部署与接入客户端&lt;/h2&gt;
&lt;h3&gt;4.1 生成 Headplane 访问密钥&lt;/h3&gt;
&lt;p&gt;进入 Headscale 容器，生成 API Key：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it headscale headscale apikeys create --expiration 999d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后打开：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://tailscale.example.net/admin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;粘贴 API Key 登录。&lt;/p&gt;
&lt;p&gt;不配置 OIDC 的情况下，Headplane 不是传统“用户名 + 密码”的永久账户体系，而是靠 Headscale API Key 登录。想要更像正常后台账号，需要后续单独接 OIDC。&lt;/p&gt;
&lt;h3&gt;4.2 创建 Headscale 用户&lt;/h3&gt;
&lt;p&gt;如果不想在 Web Console 里创建，也可以 CLI 创建：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it headscale headscale users create username
docker exec -it headscale headscale users list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Headscale 0.28 以后不要再按老教程写 &lt;code&gt;namespace&lt;/code&gt; 了，直接用 &lt;code&gt;users&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;4.3 Web Console 配置&lt;/h3&gt;
&lt;p&gt;进入 Headplane 后，建议先做这些：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;配置 Tailnet Name&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;打开 MagicDNS（可选）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;确认 DNS Base Domain 不和 &lt;code&gt;tailscale.example.net&lt;/code&gt; 冲突&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;确认 DERP Map 能看到 &lt;code&gt;My DERP&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;创建 Pre-auth Key&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果你只是个人使用，Pre-auth Key 可以选：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Reusable:   按需开启
Ephemeral:  一般关闭
Expiration: 按需设置
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 命令行生成 Pre-auth Key&lt;/h3&gt;
&lt;p&gt;也可以 CLI 生成。先看用户 ID：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it headscale headscale users list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后创建：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it headscale headscale preauthkeys create --user &amp;lt;USER_ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果需要复用、调整有效期等参数，先看当前版本帮助：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it headscale headscale preauthkeys create --help
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.5 Linux 客户端加入&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo tailscale up \
  --login-server=&quot;https://tailscale.example.net&quot; \
  --authkey=&quot;你的 preauthkey&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果之前已经登录过官方 Tailscale 或其他 Headscale，建议加 &lt;code&gt;--reset&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo tailscale up --reset \
  --login-server=&quot;https://tailscale.example.net&quot; \
  --authkey=&quot;你的 preauthkey&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你不想让 Headscale 接管 DNS：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo tailscale up --reset \
  --login-server=&quot;https://tailscale.example.net&quot; \
  --authkey=&quot;你的 preauthkey&quot; \
  --accept-dns=false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你打开了 MagicDNS，就不要加 &lt;code&gt;--accept-dns=false&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;4.6 Windows 客户端加入&lt;/h3&gt;
&lt;p&gt;管理员 PowerShell：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tailscale up --login-server=&quot;https://tailscale.example.net&quot; --authkey=&quot;你的 preauthkey&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果旧状态干扰：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tailscale up --reset --login-server=&quot;https://tailscale.example.net&quot; --authkey=&quot;你的 preauthkey&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.7 检查 DERP 是否生效&lt;/h3&gt;
&lt;p&gt;客户端执行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tailscale netcheck
tailscale debug derp-map
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;看输出里是否有类似：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;My DERP
derp.example.net
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再找另一个节点测试：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tailscale ping &amp;lt;对端节点名或 100.x 地址&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果直连成功，会显示 direct；如果走中继，会显示 DERP。DERP 是保底，不是目标。能直连当然优先直连，不能直连时再走自建中继。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 开启防偷&lt;/h2&gt;
&lt;p&gt;DERP 不开验证的话，只要别人拿到你的 DERP Map，就可能把你的中继当公共节点用。 &lt;s&gt;小机器带宽本来就贵，不能当赛博慈善家。&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;防偷有两种思路。&lt;/p&gt;
&lt;h3&gt;5.1 方案一：Headscale &lt;code&gt;/verify&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这是我更推荐给 &lt;code&gt;Headscale + Derper&lt;/code&gt; 的方式。Headscale 文档里提到，第三方 derper 可以通过 &lt;code&gt;-verify-client-url&lt;/code&gt; 指向 Headscale 的 &lt;code&gt;/verify&lt;/code&gt; 端点，由 Headscale 判断客户端是否属于本 Tailnet；&lt;code&gt;-verify-client-url-fail-open&lt;/code&gt; 控制 Headscale 不可达时是放行还是拒绝，默认行为偏宽松，强迫症可以关掉。(&lt;a href=&quot;https://headscale.net/stable/ref/derp/&quot;&gt;Headscale&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;s&gt;当然我是懒狗，多derp单headscale，所有derp用一套配置CtrlCV更省事，我用的第二套，&lt;/s&gt; &lt;strong&gt;第一套我没测&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;修改 DERP 的启动参数：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;command:
  - derper
  - -hostname
  - derp.example.net
  - -certdir
  - /app/certs
  - -certmode
  - manual
  - -verify-client-url
  - https://tailscale.example.net/verify
  - -verify-client-url-fail-open=false
  - -home
  - blank
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后重启：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose up -d
docker logs -f derp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;确保 derp 容器能访问：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it derp wget -qO- https://tailscale.example.net/health
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果容器访问自己的公网域名不通，先修 DNS/NAT 回环/防火墙，不要急着怪 Headscale。&lt;/p&gt;
&lt;h3&gt;5.2 方案二：&lt;code&gt;-verify-clients=true&lt;/code&gt; + 本机 tailscaled&lt;/h3&gt;
&lt;p&gt;如果你想沿用传统方式，也可以让 derper 通过本机 &lt;code&gt;tailscaled.sock&lt;/code&gt; 判断客户端身份。&lt;/p&gt;
&lt;p&gt;前提：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;DERP 宿主机安装并运行 Tailscale 客户端。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;这个 Tailscale 客户端已经加入你的 Headscale tailnet。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;derper 容器挂载 &lt;code&gt;/var/run/tailscale/tailscaled.sock&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;启动参数打开 &lt;code&gt;-verify-clients=true&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;修改：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;volumes:
  - ./certs/derp.example.net:/app/certs:ro
  - /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock

command: sh -c &quot;
  derper \
	-hostname derp.example.net \
	-certdir /app/certs \
	-certmode manual \
	- verify-clients true \
	-home blank&quot;

# 一些可选启动参数：
# -verify-clients true 启用客户端验证，防止DERP被偷，需要配合Tailscale使用，且需要挂载Tailscale的套接字文件
# -home blank 访问DERP返回空白界面，简单防止DERP服务被扫。
# -home https://xxx.com 访问DERP跳转指定URL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tailscale 官方 derper README 里也提醒了：如果使用 &lt;code&gt;--verify-clients&lt;/code&gt;，同机需要运行 &lt;code&gt;tailscaled&lt;/code&gt;，并且客户端需要对 derper 旁边的 tailscaled 可见。(&lt;a href=&quot;https://github.com/tailscale/tailscale/blob/main/cmd/derper/README.md&quot;&gt;GitHub&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;重启后再次测试：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose up -d
tailscale status
tailscale netcheck
tailscale debug derp-map
tailscale ping &amp;lt;对端节点&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;常见坑&lt;/h2&gt;
&lt;h3&gt;1. Headscale 启动失败：DERPMap 为空&lt;/h3&gt;
&lt;p&gt;检查：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -fsSL https://assets.example.net/tailscale/derpmap.json
docker logs headscale
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果使用 &lt;code&gt;urls&lt;/code&gt;，外部 DERP Map 应为 JSON；如果使用 &lt;code&gt;paths&lt;/code&gt;，本地 DERP Map 应为 YAML。不要混。&lt;/p&gt;
&lt;h3&gt;2. DERP 网页能打开，但客户端不用它&lt;/h3&gt;
&lt;p&gt;检查 DERP Map 里的端口：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;DERPPort&quot;: 8443,
&quot;STUNPort&quot;: 3478
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再检查云防火墙、安全组、本机防火墙是否都放通了 &lt;code&gt;8443/tcp&lt;/code&gt; 和 &lt;code&gt;3478/udp&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;3. &lt;code&gt;tailscale netcheck&lt;/code&gt; 过了，但实际还是连不上&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;netcheck&lt;/code&gt; 只能说明一部分网络状态正常，不代表所有路径都完全可用。继续看：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tailscale debug derp-map
tailscale ping &amp;lt;peer&amp;gt;
tailscale status
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;必要时看客户端日志。&lt;/p&gt;
&lt;h3&gt;4. Headplane 登录不了&lt;/h3&gt;
&lt;p&gt;先重新生成 API Key：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it headscale headscale apikeys create --expiration 999d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再确认 Headplane 配置中的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;headscale:
  url: &quot;http://headscale:8080&quot;
  public_url: &quot;https://tailscale.example.net&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;url&lt;/code&gt; 是容器内访问 Headscale 的地址；&lt;code&gt;public_url&lt;/code&gt; 是浏览器和用户看到的公网地址。&lt;/p&gt;
&lt;h3&gt;5. MagicDNS 打开后系统 DNS 被改乱&lt;/h3&gt;
&lt;p&gt;客户端加入时可以临时禁用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tailscale up --reset \
  --login-server=&quot;https://tailscale.example.net&quot; \
  --authkey=&quot;你的 preauthkey&quot; \
  --accept-dns=false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;等 Headscale 的 DNS 配置确认没问题后再打开。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;至此，控制平面和中继平面都迁到了自己手里：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;客户端
  ↓
tailscale.example.net
  ↓
Headscale 控制平面
  ↓
下发 DERP Map / DNS / ACL

客户端 A ←→ 客户端 B
  ↳ 能直连就直连
  ↳ 不能直连就走 derp.example.net:8443
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这套方案的优点很明显：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;不依赖 Tailscale 官方控制台&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;自己管理用户、设备、DNS、ACL&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DERP 节点位置可控，延迟更低&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;开启 verify 后，不容易被人白嫖中继&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点也同样明显：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;证书、端口、DNS、配置都要自己维护&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DERP/Headscale 都是关键基础设施，挂了就会影响新连接和中继&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;配置文件格式和版本变化比较快，升级前要看 release note&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不过折腾嘛，本来就是这样：&lt;br /&gt;
先把能跑的跑起来，再把跑起来的修到好用。&lt;/p&gt;
</content:encoded></item><item><title>打油诗一首</title><link>https://fuwari.vercel.app/posts/%E6%89%93%E6%B2%B9%E8%AF%97%E4%B8%80%E9%A6%96/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%89%93%E6%B2%B9%E8%AF%97%E4%B8%80%E9%A6%96/</guid><pubDate>Tue, 12 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;早闻丙午事端丰，特战风起湾未静&lt;br /&gt;
喵吠狸犬多忘事，朗朗乾坤几日清！&lt;br /&gt;
桑梓花残春柳晚，普书股期汇零丁&lt;br /&gt;
莫问国是皆有常，是非自有后人评&lt;br /&gt;
搞罢青衫仍一笑，苟且收拾再前行&lt;/p&gt;
</content:encoded></item><item><title>HomeLab局域网打洞从精通到入门</title><link>https://fuwari.vercel.app/posts/homelab%E5%B1%80%E5%9F%9F%E7%BD%91%E6%89%93%E6%B4%9E%E4%BB%8E%E7%B2%BE%E9%80%9A%E5%88%B0%E5%85%A5%E9%97%A8/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/homelab%E5%B1%80%E5%9F%9F%E7%BD%91%E6%89%93%E6%B4%9E%E4%BB%8E%E7%B2%BE%E9%80%9A%E5%88%B0%E5%85%A5%E9%97%A8/</guid><pubDate>Sat, 02 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;铜缆（10GbE以下）&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;导引丝（可选）
&lt;ul&gt;
&lt;li&gt;其实就是铁丝&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;网线钳
&lt;ul&gt;
&lt;li&gt;随便买一个，都差不多&lt;/li&gt;
&lt;li&gt;剥线刀可以用自带的，不过单独小巧的更好用一些&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;水晶头
&lt;ul&gt;
&lt;li&gt;CAT-5E头子是平齐的，线很容易歪&lt;/li&gt;
&lt;li&gt;CAT-6头子是一上一下交错的&lt;/li&gt;
&lt;li&gt;邪修：CAT-5E线用CAT-6水晶头好打，省手（别问能不能过福禄克，问就是不能）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;T568B线序走天下，6202年了不分直连线交叉线了&lt;/li&gt;
&lt;li&gt;没啥搜索关键字，网线贵在铜上&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;光纤&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;40GbE/56G-iB以下：单纤/双纤
&lt;ol&gt;
&lt;li&gt;前情提要
&lt;ul&gt;
&lt;li&gt;常见的ETH模块是单模/多模双纤LC-LC，BIDI模块是单模单纤LC，光猫上那个是单模单纤SC，当然也有别的，其他的接头几乎不太家用，反正我没玩过&lt;/li&gt;
&lt;li&gt;以我手头一颗万兆光模块举例，SFP+ 10G 850nm 300M DDM LC，分别代表：
&lt;ul&gt;
&lt;li&gt;SFP+：接网卡交换机等设备的物理接口类型&lt;/li&gt;
&lt;li&gt;10G：最大支持到10GbE带宽&lt;/li&gt;
&lt;li&gt;850nm：光的波长&lt;/li&gt;
&lt;li&gt;300M：最大传输距离300米&lt;/li&gt;
&lt;li&gt;DDM：支持数字诊断监控，一般不用管&lt;/li&gt;
&lt;li&gt;LC：光纤物理接口类型&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;过墙方式
&lt;ul&gt;
&lt;li&gt;导引丝（就是一根铁丝）先过去，会省很多事情&lt;/li&gt;
&lt;li&gt;&lt;s&gt;带着接头穿弱电管会非常痛苦，如果相信大力出奇迹的话可以尝试&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;首当其冲是熔接，自动熔纤机800左右一台，效果最佳。&lt;strong&gt;熔接只支持单模光纤&lt;/strong&gt;，多模尾纤的纤芯是塑料，支持熔接多模光纤的设备不是这个价。搜索关键字&quot;光纤熔接机&quot;，&lt;strong&gt;不是&lt;/strong&gt;&quot;熔纤机&quot;&lt;/li&gt;
&lt;li&gt;其次是成端（研磨）,SC大方头的比较便宜，几百块就能买到，兼容LC小方头的机器就贵一些，但是体型小巧，相较熔纤机上手简单(存疑)，反正没有无法重新穿线且必须弱电箱里面狭小空间成端的需求不建议考虑&lt;/li&gt;
&lt;li&gt;第三种是冷接，容易断，耗材还贵，除非量太小否则不建议考虑 &lt;s&gt;（量太小要不还是成品纤大力出奇迹吧）&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;法兰头（类似RJ-45的对接头）很便宜，尾纤批发百来根也很便宜，可以用尾纤大力出奇迹过墙，然后一个一个一个对接起来&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;多纤MPO
&lt;ol&gt;
&lt;li&gt;前情提要
&lt;ul&gt;
&lt;li&gt;MPO接口是4组8根光纤&lt;/li&gt;
&lt;li&gt;剪开之后很难熔接，很难成端（激光笔一根一根对接倒是能搞，就是费手）&lt;/li&gt;
&lt;li&gt;主流MPO光模块大体分为以下两种：
&lt;ul&gt;
&lt;li&gt;PSM：并行光模块，可以直接拆分&lt;/li&gt;
&lt;li&gt;WDM：波分复用模块，需要通过波分盒子拆分&lt;/li&gt;
&lt;li&gt;其余的我还没玩到，欢迎大佬指教&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;我从最开始玩光到现在，基本用的都是PSM模块，配合MPO-4LCLC转接线，LC过墙就又回到了上面的问题
&lt;ul&gt;
&lt;li&gt;搜索关键字：&quot;MPO-4LC&quot;，&quot;QSFP+ SR4&quot;，&quot;QSFP28 SR4&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;新的问题也出现了。PSM模块使用MPO接口，过墙熔接/成端比较麻烦，耗材使用量大不说，打的洞也越来越挤，MPO-4LCLC线也不便宜，然后就开始考虑CWDM模块了。这里提供两个低成本方案：
&lt;ol&gt;
&lt;li&gt;光模块
&lt;ul&gt;
&lt;li&gt;CWDM LR4 10km模块，LC-LC接头，波长1271nm、1291nm、1311nm、1331nm，购物平台关键字&quot;40G LR4 10km&quot;&lt;/li&gt;
&lt;li&gt;CWDM CLR4 10km模块，LC-LC接头，波长1271nm、1291nm、1311nm、1331nm，购物平台关键字&quot;100G CLR4 10km&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;波分盒子
&lt;ul&gt;
&lt;li&gt;6通，分别为1271nm-1371nm，运营商终端布线非常常用，所以价格低廉，购物平台关键字&quot;cwdm&quot;或&quot;cwdm盒子&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;优势：
&lt;ul&gt;
&lt;li&gt;不用MPO线缆，可以复用原有的LC-LC布线 &lt;s&gt;（多模纤短距离能跑单模光，单模纤跑不了多模光）&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;比起SR4方案，CLR4的拆分不在交换机侧，而是在对端任意点位，更加灵活&lt;/li&gt;
&lt;li&gt;走弱电管好走很多，熔接还是成端都更省手省耗材&lt;/li&gt;
&lt;li&gt;可以拉到很远的地方（HomeLab大概率用不到）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;劣势：
&lt;ul&gt;
&lt;li&gt;得买单独的波分盒子，没比MPO-4LC转接线便宜多少&lt;/li&gt;
&lt;li&gt;需要使用彩光模块，而不是通用的SFP+/SFP28 ETH模块，一般买波分盒子会送一套&lt;/li&gt;
&lt;li&gt;波分配套彩光模块有6颗，1351nm和1371nm的两颗模块多出来了用不上，会有些浪费。 &lt;s&gt;买两套多出来的可以当正常光模块两两对插&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;LR模块比SR模块更费电&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;CWDM
&lt;ol&gt;
&lt;li&gt;注意：&lt;strong&gt;不要把你的ETH信号给到运营商波分！不要把你的波分接到运营商波分下面！入户纤不能走波分复用！不要通过桥接的光猫倒灌VLAN ID给运营商！&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;实施方案：
&lt;ul&gt;
&lt;li&gt;G657B3裸芯（抗弯折性能最好）&lt;/li&gt;
&lt;li&gt;顺墙角，玻璃胶糊死，可以在无弱电管的地方不凿墙拉一根线&lt;/li&gt;
&lt;li&gt;一边一个CWDM盒子，单芯能跑多路（3-6路）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;优势：比起vlan交换机，每一路带宽独立，且波分盒子不耗电&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>NewAPI大模型网关</title><link>https://fuwari.vercel.app/posts/newapi%E5%A4%A7%E6%A8%A1%E5%9E%8B%E7%BD%91%E5%85%B3/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/newapi%E5%A4%A7%E6%A8%A1%E5%9E%8B%E7%BD%91%E5%85%B3/</guid><pubDate>Sat, 24 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;大模型token好贵，得想点办法了。&lt;/p&gt;
&lt;p&gt;前提条件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OpenRouter有每天的免费额度&lt;/li&gt;
&lt;li&gt;注册不需要手机号，邮箱就行（主打匿名隐私，面向web3用户，支持区块链支付）&lt;/li&gt;
&lt;li&gt;单ip通过多账号高频请求会风控，但是风控似乎“全部”通过Cloudflare实现&lt;/li&gt;
&lt;li&gt;Cloudflare Worker “似乎”是白名单（好人不封自己）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;理论存在，实践开始！&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;目标1：需要无限的临时邮箱&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;各种临时邮箱api，曾经（2025年初）可以，但目前版本多数已被封禁&lt;/li&gt;
&lt;li&gt;谷歌、微软、苹果等主流邮箱服务商（测试通过）&lt;/li&gt;
&lt;li&gt;谷歌无限邮（免费，但反人机机制较强）、微软Outlook（朋友测试过，需要吃Azure的一坨）、iCloud+（随机无限生成，自动转发，但需要iCloud高级订阅）&lt;/li&gt;
&lt;li&gt;如有其余方案欢迎补充&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;目标2：自动化注册（由于平台相关规定，不建议进行）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;selenium自动操作，imap读取邮件&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;目标3：Cloudflare Worker 提升访问稳定性，而非规避平台规则&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Calcium-Ion/new-api-worker&quot;&gt;Calcium-Ion/new-api-worker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;或者自己让AI给你搓一个代理脚本（但是有现成的干嘛还要写）&lt;/li&gt;
&lt;li&gt;使用量太大可能收费，但cloudflare worker的免费计划不需要绑定银行卡，且cloudflare注册也符合开头的“前提条件”（我是不会告诉你new-api的上级路由也可以是new-api，不仅限于OpenRouter的）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;术式展开完成。&lt;/p&gt;
&lt;p&gt;注：本文所有技术方案仅适用于个人开发者的合法测试与学习，严禁用于批量注册账号、套取平台免费额度进行牟利等违规操作。使用任何平台服务前，请仔细阅读并遵守其用户协议，违规操作可能导致账号封禁等后果。（AI生成水印）&lt;/p&gt;
</content:encoded></item><item><title>秋风日记-2025Q4</title><link>https://fuwari.vercel.app/posts/%E7%A7%8B%E9%A3%8E%E6%97%A5%E8%AE%B0-2025q4/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E7%A7%8B%E9%A3%8E%E6%97%A5%E8%AE%B0-2025q4/</guid><pubDate>Sun, 02 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;!!! 本文为个人交易复盘记录，不构成任何投资建议，股市有风险，投资需谨慎。&lt;br /&gt;
!!! 科创板权限在第一期暂未开通，使用父亲账户代持、代为交易，仅为个人操作记录，代持存在账户安全、权益归属等风险，不建议他人模仿。&lt;/p&gt;
&lt;h3&gt;前言&lt;/h3&gt;
&lt;p&gt;新入行金融交易 2 年许，略有所感，记录交易日记。目前主要进行股票交易，持有少量离岸避险外汇资产，并对期货略有了解，但未尝试下场交易。&lt;/p&gt;
&lt;p&gt;风格上，我个人偏向基本面交易，对技术面各种手法鲜少理解，但也有一些自身考量和感想，在此记录经历。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;晶科能源（SH688223）&lt;/h3&gt;
&lt;h4&gt;一、核心交易信号&lt;/h4&gt;
&lt;h6&gt;1. 政策信号：工信部整治行业内卷，头部企业受益&lt;/h6&gt;
&lt;ul&gt;
&lt;li&gt;核心结论：工信部明确通过技术标准、能效门槛引导光伏落后产能出清，晶科能源工艺能效排名前列，预期市占率和利润提升&lt;/li&gt;
&lt;li&gt;关键背景：9月9日工信部部长李乐成点名光伏行业“非理性竞争”，2025年上半年光伏组件价格暴跌导致全行业巨亏（头部企业合计亏损超千亿元）&lt;/li&gt;
&lt;li&gt;引用内容：
&lt;ul&gt;
&lt;li&gt;9月9日，&lt;strong&gt;工业和信息化部部长&lt;/strong&gt;李乐成在国务院新闻办公室的&lt;strong&gt;发布会&lt;/strong&gt;上以&lt;strong&gt;近乎警示的口吻&lt;/strong&gt;，对新能源汽车、光伏等重点行业近期出现的“非理性竞争”提出严正关注，并表示工信部会同相关部门已经依法依规&lt;strong&gt;开展治理工作&lt;/strong&gt;，取得初步成效。&lt;/li&gt;
&lt;li&gt;工信部对光伏与储能领域“非理性竞争”的点名与整治，把行业长期积累的结构性问题推到台前。2025年上半年，光伏组件价格断崖式下跌导致全行业巨亏，头部企业合计亏损超千亿元；储能环节同样陷入毛利率持续走低、项目回报率恶化的困局。规模化扩张之后的行业阵痛正在显现：同质化产品过剩、低价中标横行、地方政府与企业被锁入“保就业、保税收”的路径依赖。&lt;/li&gt;
&lt;li&gt;这种中央与地方的张力意味着，治理不能依赖“一刀切”。对光伏，&lt;strong&gt;应通过技术标准和能效门槛引导落后产能出清&lt;/strong&gt;；对储能，应建立项目全生命周期经济性评估与强制安全标准，防止劣质系统抢占市场。更重要的是，治理需要透明化，例如定期公布光储项目招标价格、质量抽检结果，让市场和公众监督地方执行力。只有在制度透明和配套机制支撑下，治理信号才能真正落地。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;参考来源：&lt;a href=&quot;https://news.bjx.com.cn/html/20250911/1460500.shtml&quot;&gt;光储急刹车：反内卷、去产能与创新突围-北极星储能网&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h6&gt;2. 期市与股市联动信号：原材料上涨滞后于股市预期&lt;/h6&gt;
&lt;ul&gt;
&lt;li&gt;核心结论：工业硅期货反弹但股市持续下跌，工业硅期货反弹与股市下跌形成背离，股市或有大幅上涨&lt;/li&gt;
&lt;li&gt;关键数据：
&lt;ul&gt;
&lt;li&gt;工业硅连续（SI0001）：9月9日最低8215 → 9月18日最高9310&lt;/li&gt;
&lt;li&gt;晶科能源（688223）：9月8日最高6.14 → 9月18日开盘5.46（最高5.52/最低5.29）→ 9月23日开盘5.18（最高5.20/最低5.01）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h6&gt;3. 业绩信号：三季报亏损超预期，触发止盈清仓&lt;/h6&gt;
&lt;ul&gt;
&lt;li&gt;核心结论：10月30日三季报未扭亏，不符合预期，决定止盈清仓&lt;/li&gt;
&lt;li&gt;关键业绩：
&lt;ul&gt;
&lt;li&gt;前三季度：营收479.86亿元（同比-33.14%），归母净利润亏损39.2亿元（同比-422.67%）&lt;/li&gt;
&lt;li&gt;第三季度：营收161.55亿元（同比-34.11%），归母净利润亏损10.12亿元（同比-6900.55%）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;引用内容：
&lt;ul&gt;
&lt;li&gt;报告显示，前三季度，晶科能源营收为479.86亿元，同比下降33.14%；归母净利润亏损39.2亿元，较2024年同期的12.15亿元，同比下降422.67%。&lt;/li&gt;
&lt;li&gt;其中，第三季度，该公司实现营收161.55亿元，同比下降34.11%；归母净利润亏损10.12亿元，同比降幅高达6900.55%。基本每股收益为-0.1元，同比下降10100%。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;参考来源：&lt;a href=&quot;https://www.sohu.com/a/949454459_122306020&quot;&gt;Q3净利狂降6900%，晶科能源“越卖越亏”？&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;二、持仓记录与盈利情况&lt;/h4&gt;
&lt;h6&gt;第一期交易（止盈位6.80 / 止损位5.00）&lt;/h6&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;日期&lt;/th&gt;
&lt;th&gt;交易类型&lt;/th&gt;
&lt;th&gt;价格&lt;/th&gt;
&lt;th&gt;数量&lt;/th&gt;
&lt;th&gt;金额&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2025.09.18 09:25&lt;/td&gt;
&lt;td&gt;证券买入&lt;/td&gt;
&lt;td&gt;5.4600&lt;/td&gt;
&lt;td&gt;7056&lt;/td&gt;
&lt;td&gt;38531.15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025.09.18 09:34&lt;/td&gt;
&lt;td&gt;证券买入&lt;/td&gt;
&lt;td&gt;5.4400&lt;/td&gt;
&lt;td&gt;3745&lt;/td&gt;
&lt;td&gt;20378.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025.09.22 14:45&lt;/td&gt;
&lt;td&gt;证券买入&lt;/td&gt;
&lt;td&gt;5.2000&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;52005.72&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025.09.23 10:11&lt;/td&gt;
&lt;td&gt;证券卖出&lt;/td&gt;
&lt;td&gt;5.0500&lt;/td&gt;
&lt;td&gt;10400&lt;/td&gt;
&lt;td&gt;52487.96&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025.09.25 09:31&lt;/td&gt;
&lt;td&gt;证券买入&lt;/td&gt;
&lt;td&gt;5.3600&lt;/td&gt;
&lt;td&gt;12300&lt;/td&gt;
&lt;td&gt;65935.25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025.09.25 09:37&lt;/td&gt;
&lt;td&gt;证券买入&lt;/td&gt;
&lt;td&gt;5.4600&lt;/td&gt;
&lt;td&gt;3000&lt;/td&gt;
&lt;td&gt;16385.16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025.09.26 10:12&lt;/td&gt;
&lt;td&gt;证券买入&lt;/td&gt;
&lt;td&gt;5.3900&lt;/td&gt;
&lt;td&gt;6380&lt;/td&gt;
&lt;td&gt;34393.54&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025.10.09 11:25&lt;/td&gt;
&lt;td&gt;证券卖出&lt;/td&gt;
&lt;td&gt;5.8000&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;57964.62&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025.10.09 14:34&lt;/td&gt;
&lt;td&gt;证券卖出&lt;/td&gt;
&lt;td&gt;5.8000&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;57964.62&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;科创板权限暂未开通，父亲账户代持，未清仓&lt;/td&gt;
&lt;td&gt;代持持有&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;12081&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;本期最终结算盈利：13000元&lt;/li&gt;
&lt;/ul&gt;
&lt;h6&gt;第二期交易（止盈位5.90 / 止损位5.10）&lt;/h6&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作类型&lt;/th&gt;
&lt;th&gt;成交日期&lt;/th&gt;
&lt;th&gt;价格(元)&lt;/th&gt;
&lt;th&gt;数量(股)&lt;/th&gt;
&lt;th&gt;发生金额(元)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;证券买入&lt;/td&gt;
&lt;td&gt;2025.10.27 11:21&lt;/td&gt;
&lt;td&gt;5.4300&lt;/td&gt;
&lt;td&gt;30000&lt;/td&gt;
&lt;td&gt;162923.69&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;证券卖出&lt;/td&gt;
&lt;td&gt;2025.10.29 15:00&lt;/td&gt;
&lt;td&gt;5.8200&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;58162.44&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;证券卖出&lt;/td&gt;
&lt;td&gt;2025.10.30 09:42&lt;/td&gt;
&lt;td&gt;5.8900&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;58861.98&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;证券卖出&lt;/td&gt;
&lt;td&gt;2025.10.30 14:44&lt;/td&gt;
&lt;td&gt;5.8500&lt;/td&gt;
&lt;td&gt;9000&lt;/td&gt;
&lt;td&gt;52616.01&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;证券卖出&lt;/td&gt;
&lt;td&gt;2025.10.31 10:31&lt;/td&gt;
&lt;td&gt;5.9400&lt;/td&gt;
&lt;td&gt;1000&lt;/td&gt;
&lt;td&gt;5931.96&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;买入原因：工信部重申反内卷；十五五会议在即（预期重提碳中和承诺）；股价触底反弹&lt;/li&gt;
&lt;li&gt;卖出原因：接近止盈位；三季报业绩下滑不及预期&lt;/li&gt;
&lt;li&gt;本期最终结算盈利：12648.70元&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;三、成果反思与改进方向&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;本次交易亮点&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;基本面判断准确，是两期交易盈利的核心原因&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;存在的不足&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;选股不够精准：隆基绿能涨幅高于晶科能源，但因对两家公司工艺细节研判不足，最终选择投资晶科能源&lt;/li&gt;
&lt;li&gt;未分散持仓：在无法判断具体工艺的情况下，未分散持仓，反而选择依赖AI工具决策&lt;/li&gt;
&lt;li&gt;技术面分析欠缺：
&lt;ol&gt;
&lt;li&gt;股市与期市信号滞后时间预估错误，未能规避9月18-23日下跌&lt;/li&gt;
&lt;li&gt;买入时机不当，止损位设置不合理，9月23日认损卖出后股价反弹&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;后续改进措施&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;个股研究：减少对AI工作流的依赖，人工深入研究选股范围内个股的核心信息&lt;/li&gt;
&lt;li&gt;技术面提升：加强MACD、成交量、实时价格曲线的综合判读，避免盲目交易&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h3&gt;华立科技（SZ301011）&lt;/h3&gt;
&lt;h4&gt;一、核心交易信号&lt;/h4&gt;
&lt;h6&gt;1. 热门游戏版本更新和股价关联&lt;/h6&gt;
&lt;ul&gt;
&lt;li&gt;核心结论：作为街机游戏设备头部厂商，其中最热门产品“舞萌DX”和“中二节奏”的月度更新，在&lt;code&gt;T-2&lt;/code&gt;到&lt;code&gt;T+2&lt;/code&gt;个交易日内，过去2年时间里，超过8成会出现股价上涨&lt;br /&gt;
&lt;em&gt;&lt;strong&gt;注：该结论为个人观察总结，未经过严格量化验证&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;引用内容：
&lt;ul&gt;
&lt;li&gt;中二节奏本次更新时间：2025年10月30日&lt;/li&gt;
&lt;li&gt;舞萌DX本次更新时间：2025年11月5日 10：00&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;参考来源：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s/raNqR1KotKr4MPm1StqhUA&quot;&gt;中二节奏丨10月更新情报！&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s/NJNFkcmUy2rIpQQhgDSMIQ&quot;&gt;舞萌DX丨11月更新情报！&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;二、持仓记录与盈利情况&lt;/h4&gt;
&lt;h6&gt;第一期交易（止盈位无 / 止损位无）&lt;/h6&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;交易类型&lt;/th&gt;
&lt;th&gt;成交日期&lt;/th&gt;
&lt;th&gt;价格(元)&lt;/th&gt;
&lt;th&gt;数量(股)&lt;/th&gt;
&lt;th&gt;发生金额(元)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;证券买入&lt;/td&gt;
&lt;td&gt;2025.10.27 13:56&lt;/td&gt;
&lt;td&gt;26.6700&lt;/td&gt;
&lt;td&gt;1000&lt;/td&gt;
&lt;td&gt;26675.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;证券卖出&lt;/td&gt;
&lt;td&gt;2025.10.28 09:37&lt;/td&gt;
&lt;td&gt;26.9900&lt;/td&gt;
&lt;td&gt;1000&lt;/td&gt;
&lt;td&gt;26971.50&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;本期最终结算盈利：296.50元&lt;/li&gt;
&lt;/ul&gt;
&lt;h6&gt;第二期交易（止盈位无 / 止损位无）&lt;/h6&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;交易类型&lt;/th&gt;
&lt;th&gt;成交日期&lt;/th&gt;
&lt;th&gt;价格(元)&lt;/th&gt;
&lt;th&gt;数量(股)&lt;/th&gt;
&lt;th&gt;发生金额(元)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;证券买入&lt;/td&gt;
&lt;td&gt;2025.10.29 13:00&lt;/td&gt;
&lt;td&gt;26.3600&lt;/td&gt;
&lt;td&gt;1500&lt;/td&gt;
&lt;td&gt;39545.35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;证券卖出&lt;/td&gt;
&lt;td&gt;2025.10.31 10:31&lt;/td&gt;
&lt;td&gt;25.7810&lt;/td&gt;
&lt;td&gt;1500&lt;/td&gt;
&lt;td&gt;38646.42&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;本期最终结算亏损：898.93元&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;三、成果反思与改进方向&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;本次交易亮点&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一期交易把握正确，借助更新公告发布后热点形势赚取盈利&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;存在的不足&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;量化支撑缺失：未通过 “信号强度量化公式”（核心维度：历史上涨概率、剔除创业板指beta波动后的上涨概率、游戏门店渗透率加权）计算信号有效性，仅靠 “过去 8 成上涨” 的模糊结论建仓，导致第二期在 “中二节奏热度较低” 时仍加仓，放大亏损。&lt;/li&gt;
&lt;li&gt;事件影响优先级未厘清：没有分清公告发布和游戏更新两个事件，哪个对股价影响较大。&lt;/li&gt;
&lt;li&gt;试仓比例失控：已知 “中二节奏热度低于舞萌 DX”，但两期试仓占比仍达 4.37%、6.38%，远超 “单一试错信号≤3%” 的合理上限，导致单次亏损（898.93 元）覆盖了前期盈利，并同时造成后续舞萌DX的试验性建仓如遵循试错信号的持仓比例，将极难覆盖前期亏损。&lt;/li&gt;
&lt;li&gt;违反了个人交易原则：任何一次建仓前都应当设置止盈位和止损位&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;后续改进措施&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;个股研究：减少主观判断占比，增加量化计算占比&lt;/li&gt;
&lt;li&gt;原则底线：坚守止盈止损底线，确保资金流动性充足，避免被“套牢”影响后续交易&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;本次交易还未结束，将按照“更新的&lt;code&gt;T-2&lt;/code&gt;到&lt;code&gt;T+2&lt;/code&gt;个交易日内，会出现股价上涨”这一核心结论，削减持仓比例，对“舞萌DX更新”这一信号继续进行交易，验证结论正确与否。同时锻炼个人心态，避免因担心错过信号仓促下单交易。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h3&gt;后续工作&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;逐步完成个人交易原则的体系化记录。&lt;/li&gt;
&lt;li&gt;加强技术面交易方法的学习，避免在日线乃至分钟线交易时手足无措的现象。&lt;/li&gt;
&lt;li&gt;搭建量化交易工具的前期框架，对tick级Level1行情进行本地持久化存储，并加入可以辅助完成判断的工具（如事件关联性检测）。&lt;/li&gt;
&lt;li&gt;如有能力，进一步在云原生的高可用架构下，完成私人AIGC工作流对互联网可信信息源的自动判读整合，实现交易信号研读从人工到自动的转变。&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>简记vLLM部署bge-m3和bge-reranker</title><link>https://fuwari.vercel.app/posts/%E7%AE%80%E8%AE%B0vllm%E9%83%A8%E7%BD%B2bge-m3%E5%92%8Cbge-reranker/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E7%AE%80%E8%AE%B0vllm%E9%83%A8%E7%BD%B2bge-m3%E5%92%8Cbge-reranker/</guid><pubDate>Tue, 30 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;概述&lt;/h3&gt;
&lt;p&gt;本配置用于部署一个基于 Docker 的多服务 API 系统，包含 New API 主服务、Redis 缓存、MySQL 数据库以及两个 GPU 加速的文本处理模型（bge-m3 和 bge-reranker-v2-m3）。主要用于提供文本嵌入和重排序功能，支持多语言处理，为开发者提供统一的 Jina AI 格式接口。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;懒狗快捷指南&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;services:
  new-api:
    image: calciumion/new-api:latest
    container_name: new-api
    restart: always
    command: --log-dir /app/logs
    networks:
      - vllm_network
#      - caddy_network
    ports:
      - &quot;3443:3000&quot;
    volumes:
      - ./new-api/data:/data
      - ./new-api/logs:/app/logs
    environment:
      - SQL_DSN=root:123456@tcp(mysql:3306)/new-api  # 指向mysql服务
      - REDIS_CONN_STRING=redis://redis
      - TZ=Asia/Shanghai
    #      - SESSION_SECRET=random_string  # 多机部署时设置，必须修改这个随机字符串！！！！！！！
    #      - NODE_TYPE=slave  # 多机部署的从节点取消注释
    #      - SYNC_FREQUENCY=60  # 如需定期同步数据库，取消注释
    #      - FRONTEND_BASE_URL=https://your-domain.com  # 多机部署带前端URL时取消注释

    depends_on:
      - redis
      - mysql
      - bge-m3
      - bge-reranker
    healthcheck:
      test: [&quot;CMD-SHELL&quot;, &quot;wget -q -O - http://localhost:3000/api/status | grep -o &apos;\&quot;success\&quot;:\\s*true&apos; | awk -F: &apos;{print $$2}&apos;&quot;]
      interval: 30s
      timeout: 10s
      retries: 3

  redis:
    image: redis:latest
    container_name: redis
    networks:
      - vllm_network
    restart: always

  mysql:
    image: mysql:8.2
    container_name: mysql
    networks:
      - vllm_network
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 123456  # 确保与SQL_DSN中的密码一致
      MYSQL_DATABASE: new-api
    volumes:
      - ./new-api/mysql_data:/var/lib/mysql
    # ports:
    #   - &quot;3306:3306&quot;  # 如需从Docker外部访问MySQL，取消注释

#volumes:
#  mysql_data:

  # bge-m3 专用容器 - 使用 GPU 0
  bge-m3:
    image: vllm/vllm-openai:latest # 当前版本0.10.1
    container_name: bge-m3
    runtime: nvidia
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
#              count: 1
              capabilities: [gpu]
              device_ids: [&apos;0&apos;]  # 明确指定使用 GPU 0
#    ports:
#      - &quot;8000:8000&quot;
    volumes:
      - ./vllm/bge-m3/.cache/huggingface:/root/.cache/huggingface
      - ./vllm/bge-m3/models:/app/models
    networks:
      - vllm_network
    environment:
      - http_proxy=http://localhost:xxxxx # 改成你的代理端口
      - https_proxy=http://localhost:xxxxx # 改成你的代理端口
      - HUGGING_FACE_HUB_TOKEN=hf_xxxxxx # 改成你的token
#      - CUDA_VISIBLE_DEVICES=0  # 明确指定使用 GPU 0
    ipc: host
    command: &amp;gt;
      --model BAAI/bge-m3
      --api-key sk-xxxxxx
      --host 0.0.0.0
      --port 8000
      --tensor-parallel-size 1
      --gpu-memory-utilization 0.8
      --max-model-len 8192
    # 上面command字段不能有注释，api-key随便生成一个就行
    restart: unless-stopped
    healthcheck:
      test: [&quot;CMD&quot;, &quot;curl&quot;, &quot;-f&quot;, &quot;http://localhost:8000/health&quot;]
      interval: 30s
      timeout: 10s
      retries: 3

  # bge-reranker-v2-m3 专用容器 - 使用 GPU 1
  bge-reranker:
    image: vllm/vllm-openai:latest # 当前版本0.10.1
    container_name: bge-reranker
    runtime: nvidia
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
#              count: 1
              capabilities: [gpu]
              device_ids: [&apos;1&apos;]  # 明确指定使用 GPU 1
#    ports:
#      - &quot;8001:8000&quot;  # 使用不同外部端口
    volumes:
      - ./vllm/bge-reranker/.cache/huggingface:/root/.cache/huggingface
      - ./vllm/bge-reranker/models:/app/models
    networks:
      - vllm_network
    environment:
      - http_proxy=http://localhost:xxxxx # 改成你的代理端口
      - https_proxy=http://localhost:xxxxx # 改成你的代理端口
      - HUGGING_FACE_HUB_TOKEN=hf_xxxxxx # 改成你的token
#      - CUDA_VISIBLE_DEVICES=1  # 明确指定使用 GPU 1
    ipc: host
    command: &amp;gt;
      --model BAAI/bge-reranker-v2-m3
      --api-key sk-xxxxx
      --host 0.0.0.0
      --port 8000
      --tensor-parallel-size 1
      --gpu-memory-utilization 0.8
      --max-model-len 8192
    # 上面command字段不能有注释，api-key随便生成一个就行
    restart: unless-stopped
    healthcheck:
      test: [&quot;CMD&quot;, &quot;curl&quot;, &quot;-f&quot;, &quot;http://localhost:8000/health&quot;]
      interval: 30s
      timeout: 10s
      retries: 3

networks:
  vllm_network:
    external: true

&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h3&gt;Q&amp;amp;A&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;1. 多卡部署为什么会报错？&lt;/strong&gt;
vLLM 在多 GPU 环境下需要正确配置 tensor-parallel-size 参数。如果配置不当（如 tensor-parallel-size 与实际 GPU 数量不匹配），会导致模型加载失败或性能问题。建议单卡单模型部署，通过 device_ids 明确指定 GPU 设备。
&lt;s&gt;（其实你根本不需要多卡跑这种小模型，爱折腾请自便）&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. New API 的重排序接口采用什么格式？&lt;/strong&gt;
New API 统一采用 Jina AI 的重排序格式作为标准响应格式。所有其他供应商（Xinference、Cohere 等）的响应都会被转换为 Jina AI 格式，确保开发者获得一致的接口体验。
&lt;strong&gt;所以Rerank模型配置时请使用Jina渠道&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. &quot;Model does not support matryoshka representation&quot; 错误是什么意思？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Matryoshka 表示法&lt;/strong&gt;：一种允许嵌入模型输出可变维度向量的技术（如 OpenAI 的 text-embedding-3 系列）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;bge-m3 限制&lt;/strong&gt;：BAAI/bge-m3 是固定输出维度模型（1024 维），不支持 dimensions 参数&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解决方案&lt;/strong&gt;：移除&lt;strong&gt;客户端&lt;/strong&gt;请求中的 dimensions 参数，使用模型默认的输出维度&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;4. 如何测试嵌入功能？&lt;/strong&gt;
使用以下 curl 命令测试（替换为实际地址和 API Key）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl https://your-server/v1/embeddings \
  -H &quot;Content-Type: application/json&quot; \
  -H &quot;Authorization: Bearer YOUR_API_KEY&quot; \
  -d &apos;{
    &quot;input&quot;: &quot;The food was delicious and the waiter...&quot;,
    &quot;model&quot;: &quot;BAAI/bge-m3&quot;,
    &quot;encoding_format&quot;: &quot;float&quot;
  }&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;5. 如何测试重排序功能？&lt;/strong&gt;
使用以下 curl 命令测试（替换为实际地址和 API Key）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl https://your-server/v1/rerank \
  -H &quot;Content-Type: application/json&quot; \
  -H &quot;Authorization: Bearer YOUR_API_KEY&quot; \
  -d &apos;{
    &quot;model&quot;: &quot;BAAI/bge-reranker-v2-m3&quot;,
    &quot;query&quot;: &quot;Organic skincare products&quot;,
    &quot;top_n&quot;: 3,
    &quot;documents&quot;: [&quot;文档1&quot;, &quot;文档2&quot;, &quot;文档3&quot;]
  }&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;6. 健康检查失败怎么办？&lt;/strong&gt;
检查服务日志确认模型是否正常加载，确保：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GPU 驱动和 nvidia-container-runtime 已正确安装&lt;/li&gt;
&lt;li&gt;模型文件已正确下载到指定目录&lt;/li&gt;
&lt;li&gt;网络代理配置（如需要）正确无误&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;docker logs new-api
docker logs bge-m3
docker logs bge-reranker
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;p&gt;本文内容由AI辅助编写、主要代码由人工完成、已人工测试可用性，部署平台是&lt;code&gt;Epyc7532&lt;/code&gt; 和 &lt;code&gt;Nvidia-Tesla-T10 16GB&lt;/code&gt;，内存实际占用&lt;code&gt;3.8GB&lt;/code&gt;，显存实际占用&lt;code&gt;2568MB&lt;/code&gt;，请确保资源充足&lt;/p&gt;
</content:encoded></item><item><title>基于网盘部署下载站的一些想法</title><link>https://fuwari.vercel.app/posts/%E5%9F%BA%E4%BA%8E%E7%BD%91%E7%9B%98%E9%83%A8%E7%BD%B2%E4%B8%8B%E8%BD%BD%E7%AB%99%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E5%9F%BA%E4%BA%8E%E7%BD%91%E7%9B%98%E9%83%A8%E7%BD%B2%E4%B8%8B%E8%BD%BD%E7%AB%99%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95/</guid><pubDate>Wed, 10 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;背景：流量费血妈贵，交不起了，打算找点羊毛薅&lt;/p&gt;
&lt;hr /&gt;
&lt;h5&gt;一、Openlist解决网盘认证&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Alist似了喵，Alist被卖掉了喵&lt;/strong&gt;
&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/%E5%9F%BA%E4%BA%8E%E7%BD%91%E7%9B%98%E9%83%A8%E7%BD%B2%E4%B8%8B%E8%BD%BD%E7%AB%99%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95-01.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;li&gt;由于部分网盘监管较为严格，禁止多IP同时下载，而下载站如果不使用重定向，流量流经服务器，就失去了意义，所以暂时选择移动云盘（据传三大运营商对此管理力度不大）&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://doc.oplist.org/guide/drivers/139&quot;&gt;中国移动云盘 - OpenList 文档&lt;/a&gt;自己配置，懒得写&lt;/li&gt;
&lt;li&gt;先说结论
&lt;ul&gt;
&lt;li&gt;登陆站点后台，导航到 &lt;code&gt;设置&lt;/code&gt;&amp;gt;&lt;code&gt;全局&lt;/code&gt; 下，关闭 &lt;code&gt;签名所有&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;导航到 &lt;code&gt;存储&lt;/code&gt;，编辑资源所在的存储，关闭 &lt;code&gt;启用签名&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;导航到 &lt;code&gt;元信息&lt;/code&gt;，确保资源所在路径没有设置元信息&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;附带原方案链接：&lt;a href=&quot;https://github.com/AlistGo/alist/discussions/6024&quot;&gt;Alist外链问题求助 · AlistGo/alist · Discussion #6024&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h5&gt;二、重写路径&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;首先确保存储后端支持重定向，具体请在文档中&lt;code&gt;默认使用的存储方式&lt;/code&gt;中查询，并确保配置中确实开启重定向~~（要不然血妈贵的流量费账单又会找上你）~~&lt;/li&gt;
&lt;li&gt;如：&lt;a href=&quot;https://doc.oplist.org/guide/drivers/139#%E9%BB%98%E8%AE%A4%E4%BD%BF%E7%94%A8%E7%9A%84%E4%B8%8B%E8%BD%BD%E6%96%B9%E5%BC%8F&quot;&gt;中国移动云盘 - OpenList 文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;众所周知，Openlist的默认路由，/d代表直链，/p代表代理：&lt;a href=&quot;https://github.com/AlistGo/alist/blob/6a90b1d40aae342440614d1543790b2ee2d327f7/server/router.go#L26&quot;&gt;router.go - AlistGo/alist&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;众所周知，Openlist默认端口5244，且没有SSL&lt;/li&gt;
&lt;li&gt;放一下我对Caddyfile&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;*.sunnypai.top {
  tls /caddy/certs/sunnypai.top/cert.pem /caddy/certs/sunnypai.top/cert.key

  # openlist netdrive
  @openlist {
    host openlist.sunnypai.top
  }
  handle @openlist {
    reverse_proxy openlist:5244  {
        header_up Host {http.request.host}
        header_up X-Real-IP {http.request.remote}
        header_up X-Forwarded-For {http.request.remote}
        header_up X-Forwarded-Proto {http.request.scheme}
        header_up X-Forwarded-Host {http.request.host}
        header_up Range {http.request.header.Range}
        header_up If-Range {http.request.header.If-Range}
    }
  }


  # netdisk mirror source
  @mirror-cn-ningbo-01 {
    host dl-cn-ningbo-01.sunnypai.top
  }
  handle @mirror-cn-ningbo-01 {
    redir https://openlist.sunnypai.top/d{path} temporary
  }
  
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;其中第一块匹配openlist主服务，第二块匹配直链。如果不用主服务，可以简化为：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;*.sunnypai.top {
  tls /caddy/certs/sunnypai.top/cert.pem /caddy/certs/sunnypai.top/cert.key

  # openlist netdrive
  @openlist {
    host openlist.sunnypai.top
  }
  handle @openlist {
    reverse_proxy openlist:5244/d{path}  {
        header_up Host {http.request.host}
        header_up X-Real-IP {http.request.remote}
        header_up X-Forwarded-For {http.request.remote}
        header_up X-Forwarded-Proto {http.request.scheme}
        header_up X-Forwarded-Host {http.request.host}
        header_up Range {http.request.header.Range}
        header_up If-Range {http.request.header.If-Range}
    }
  }

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时逻辑为，客户端请求-&amp;gt;caddy-&amp;gt;openlist直链地址-&amp;gt;返回网盘cdn重定向地址
7. 另外，使用&lt;code&gt;dl-cn-ningbo-01.sunnypai.top&lt;/code&gt;，而非&lt;code&gt;dl.cn-ningbo-01.sunnypai.top&lt;/code&gt;的原因不是caddy匹配器(&lt;code&gt;matcher&lt;/code&gt;)无法精确匹配，是通配符证书(&lt;code&gt;wildcard certs&lt;/code&gt;)只能匹配下一级子域名（这里是三级域名），无法匹配到四级域名&lt;code&gt;dl.&lt;/code&gt;，我懒得申请签发新证书&lt;/p&gt;
&lt;hr /&gt;
&lt;h5&gt;三、成果展示&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;请求 URL:
GET http://dl-cn-ningbo-01.sunnypai.top/test_20250910_101555.txt
重定向 URL:
GET https://dl-cn-ningbo-01.sunnypai.top/test_20250910_101555.txt
重定向 URL:
GET https://openlist.sunnypai.top/d/test_20250910_101555.txt
重定向 URL:
GET https://hcyykj-eos-hhht5-01.eos.huhehaote-8.cmecloud.cn/ff95dc4f93c74d699b5b49a31224cd71086?response-content-disposition=attachment%3B%20filename%2A%3DUTF-8%27%27test_20250910_101555.txt&amp;amp;X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;amp;X-Amz-Date=20250910T050203Z&amp;amp;X-Amz-SignedHeaders=host&amp;amp;X-Amz-Expires=900&amp;amp;X-Amz-Credential=REDACTED_ACCESS_KEY%2F20250910%2Fdefault%2Fs3%2Faws4_request&amp;amp;t=2&amp;amp;u=REDACTED_USER_ID&amp;amp;ot=personal&amp;amp;oi=REDACTED_USER_ID&amp;amp;f=REDACTED_FILE_HASH&amp;amp;X-Amz-Signature=REDACTED_SIGNATURE

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;以上结果来自Apifox&lt;/code&gt;&lt;/p&gt;
</content:encoded></item><item><title>生命小记</title><link>https://fuwari.vercel.app/posts/%E7%94%9F%E5%91%BD%E5%B0%8F%E8%AE%B0/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E7%94%9F%E5%91%BD%E5%B0%8F%E8%AE%B0/</guid><pubDate>Sun, 07 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;        早上刚起床，想到过世的外公在生前陪伴我的时光，泪水止不住涌了出来。泪光中，我想到了故去的爷爷奶奶，逝去的友人，又想到了梦中在世的亲朋好友突然离去，然后骤然想到我自己：&lt;br /&gt;
        生命，多么有趣的东西啊！即使如今的科技已经能上九天下五洋，生命的神秘依旧霸占着他那一隅之地，没人说得清生命是什么、意识从何而来。但，我在活着，我也曾活过。&lt;br /&gt;
        真的吗？似乎在提出这样的问题时，答案已经不言自明了。但是，亲朋旧友们真的已经阴阳两隔吗？已经逝去的人，如果还在被活着的人铭记，记得音容笑貌，记得点点滴滴，那他真的逝去了吗？&lt;br /&gt;
        “人有三次死亡。”通常意义上的死亡是生理的或社会的，但如果信息的他还被人铭记，那么在未来奇迹般的、先知梦境也无法描绘的技术下，靠着信息逆转死亡，也似乎并不是幻想？&lt;br /&gt;
        我们造出了有意识的机器，教会他们看世界，教导他们学习整个文明创造的知识。教会他们如何行走，也教导他们如何分辨是非善恶。机器是这样，人又何尝不是？当我知道了一个人在面对一件事时是什么反应，会说什么话、怎样遣词造句，会做什么动作，甚至表情、眼神，那么自回归地，意识也在涌现中出现了。&lt;br /&gt;
        那么，我是谁？&lt;br /&gt;
        我是我，我也不是我。我在成长，也是在被外部异化。在这个一切都在自发地趋于混乱的世界，意识从活着的那一刻就在不断地被外界微调着。这时候也只有时间能证明“我永远是我自己”这样大家从不会在意的事实。&lt;br /&gt;
        “我从哪里来？”从古至今的哲学家似乎都倾向给出一个模棱两可地不存在的答案，但我更愿意相信：我是从信息的涌现中来，从高度编码的基因、随机的不可控的外部环境，涌现出最早的智能，又在出生后被的教育中不断微调，变得更加复杂混乱，但智能却越来越高级。&lt;br /&gt;
        “我到哪里去？”终点站是人人都能看见的，在最高度的混乱下意识的崩溃，信息被所有人遗忘，也就是死亡。这是注定的，没有任何生命能逃离的命运。但在活着的时候做什么，这是自己能够决定的，&lt;br /&gt;
吗？&lt;br /&gt;
        为了生存下去，人们吃喝拉撒；为了碎银几两，人们饱经沧桑；为了取悦自己，人们灯红酒绿；为了取悦他人，人们委曲求全……这些行为都不是意识能够决定的，这是意识的基石——肉体的生命所能决定的。在这些得到满足后，才能在最后微不足道的时间让意识决定一些对存在“无关紧要”的事情。&lt;br /&gt;
        我们生活的世界，所拥有的奇迹之多，绝非远古先知梦境所能构想。这些生理的、心理的，最基础的需求，只需要越来越短的时间就能得到基本的满足。几个小时的工作就足以换取衣食无忧的碎银几两，互联网又有着数不胜数的娱乐信息。但如果沉溺于最基础的娱乐，意识就再也无法留下任何信息，那么这就是信息层面的第三次死亡提前到来。&lt;br /&gt;
        我们所生活的世界，所拥有灾祸之恐怖，也非天启所能描绘。“高中是人一生中智商的顶峰”，似乎在调侃大学生不务正业，但我觉得也是对第三次信息性死亡的提前宣判；而在不稳定的工作中，“废宅”得顾不上家人也没有朋友，这又宣判了不被在意的第二次社会性死亡；最后，在沉重的负担下，绝望中迎接生理性死亡。这是先人们无论如何也无法想象的严酷刑罚，但这已经来到了现实成为常态。&lt;br /&gt;
        我接受死亡，我接受任何时间任何地点到来的生理性死亡，也接受可能的被亲朋好友遗忘。今天我要做的每一件事都随心所欲不留遗憾，即使明天突然死掉也不后悔。这样的一天天不断累积，在时间里我成为了我，我没有后悔也没有遗憾，活好每一天，也正视永恒的长眠。&lt;br /&gt;
        生前何须久睡？死后必将长眠。承托亲朋旧友生命之重，一片泪光中，落下笔痕。&lt;/p&gt;
</content:encoded></item><item><title>OpensuseLeap安装Docker</title><link>https://fuwari.vercel.app/posts/opensuseleap%E5%AE%89%E8%A3%85docker/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/opensuseleap%E5%AE%89%E8%A3%85docker/</guid><pubDate>Wed, 03 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;安装命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;zypper install docker docker-compose gnome-keyring libsecret
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后可以去&lt;code&gt;systemd&lt;/code&gt;配置文件改&lt;code&gt;env&lt;/code&gt;配代理，也可以去&lt;code&gt;/etc/sysconfig/docker&lt;/code&gt;添加代理&lt;code&gt;env&lt;/code&gt;的&lt;code&gt;kv pair&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;！！！&lt;strong&gt;不是&lt;/strong&gt;一些教程里的！！！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;zypper install docker python3-docker-compose
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;会报错：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;localhost:~ # docker version
Client:
 Version:           28.3.3-ce
 API version:       1.51
 Go version:        go1.24.5
 Git commit:        bea959c7b
 Built:             Tue Jul 29 12:00:00 2025
 OS/Arch:           linux/amd64
 Context:           default

Server:
 Engine:
  Version:          28.3.3-ce
  API version:      1.51 (minimum version 1.24)
  Go version:       go1.24.5
  Git commit:       bea959c7b
  Built:            Tue Jul 29 12:00:00 2025
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.7.27
  GitCommit:        05044ec0a9a75232cad458027ca83437aae3f4da
 runc:
  Version:          1.2.6
  GitCommit:        v1.2.6-0-ge89a29929c77
 docker-init:
  Version:          0.2.0_catatonit
  GitCommit:
localhost:~ # docker run --rm hello-world
Unable to find image &apos;hello-world:latest&apos; locally
docker: error getting credentials - err: exit status 1, out: `GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.secrets was not provided by any .service files`

Run &apos;docker run --help&apos; for more information
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Linux 配置 zram 优先 + sdb 次级 swap</title><link>https://fuwari.vercel.app/posts/linux-%E9%85%8D%E7%BD%AE-zram-%E4%BC%98%E5%85%88--sdb-%E6%AC%A1%E7%BA%A7-swap/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/linux-%E9%85%8D%E7%BD%AE-zram-%E4%BC%98%E5%85%88--sdb-%E6%AC%A1%E7%BA%A7-swap/</guid><pubDate>Thu, 28 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;一、安装并配置 zram（高优先级）&lt;/h2&gt;
&lt;h3&gt;1. 安装 zram 工具&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install zram-tools
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 配置 zram 核心参数&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 设置压缩算法为 zstd（高效平衡压缩率与速度）
# 设置容量为物理内存的 60%
echo -e &quot;ALGO=zstd\nPERCENT=60&quot; | sudo tee -a /etc/default/zramswap

# 设置 zram 优先级为 100（最高，确保优先使用）
echo &quot;PRIORITY=100&quot; | sudo tee -a /etc/default/zramswap
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 重启 zram 服务生效&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl restart zramswap.service
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;二、配置 sdb 为次级 swap（低优先级）&lt;/h2&gt;
&lt;h3&gt;1. 格式化 sdb 为 swap 分区（注意：会清空数据）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo mkswap /dev/sdb
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 获取 sdb 的 UUID（用于开机自动挂载）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo blkid /dev/sdb  # 记录输出中的 UUID 值
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 配置 fstab 实现开机自动挂载（优先级 50）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 替换下方 &quot;你的sdb的UUID&quot; 为实际 UUID
sudo tee -a /etc/fstab &amp;lt;&amp;lt; EOF
UUID=你的sdb的UUID none swap defaults,pri=50 0 0
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 临时启用 sdb swap（立即生效，无需重启）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo swapon -p 50 /dev/sdb
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;三、验证配置是否生效&lt;/h2&gt;
&lt;p&gt;查看当前 swap 设备及优先级（确保 zram 优先级 100 &amp;gt; sdb 优先级 50）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo swapon -s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;预期输出示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Filename                                Type            Size    Used    Priority
/dev/zram0                              partition       8388604 0       100
/dev/sdb                                partition       10485756 0      50
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、调整系统 swap 策略（更积极使用 zram）&lt;/h2&gt;
&lt;p&gt;在 &lt;code&gt;/etc/sysctl.d/&lt;/code&gt; 目录下新建一个专属配置文件（例如 &lt;code&gt;99-zram-tweaks.conf&lt;/code&gt;，文件名以 &lt;code&gt;99-&lt;/code&gt; 开头可确保优先级，避免被系统默认配置覆盖），集中管理 &lt;code&gt;vm.swappiness&lt;/code&gt; 和 &lt;code&gt;vm.vfs_cache_pressure&lt;/code&gt; 等参数。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;在 /etc/sysctl.d/ 下创建新配置文件&lt;/strong&gt;&lt;br /&gt;
新建一个专属配置文件（例如 &lt;code&gt;99-zram-tweaks.conf&lt;/code&gt;），添加所需参数：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;sudo tee /etc/sysctl.d/99-zram-tweaks.conf &amp;lt;&amp;lt; EOF
# 更积极将非活跃数据移入 zram
vm.swappiness=60
# 降低缓存回收倾向，保留有用的文件系统缓存
vm.vfs_cache_pressure=40
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;使配置立即生效&lt;/strong&gt;&lt;br /&gt;
无需重启，执行以下命令加载新配置：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;sudo sysctl --system
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、验证配置是否生效&lt;/h2&gt;
&lt;p&gt;执行以下命令检查参数是否正确加载：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 查看 vm.swappiness 当前值
sysctl vm.swappiness
# 查看 vm.vfs_cache_pressure 当前值
sysctl vm.vfs_cache_pressure
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;若输出结果与你配置的 &lt;code&gt;60&lt;/code&gt; 和 &lt;code&gt;40&lt;/code&gt; 一致，说明配置已生效；重启系统后再次检查，值仍不变则表示&lt;strong&gt;永久生效&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;配置效果&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;系统优先使用 zram（内存压缩 swap，速度快），当 zram 占满后使用 sdb（磁盘 swap，容量兜底）&lt;/li&gt;
&lt;li&gt;更积极地将非活跃数据转移到 zram，平衡内存使用与性能&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>简记Debian13配置vnc+openbox无头图形化窗管</title><link>https://fuwari.vercel.app/posts/debian13%E9%85%8D%E7%BD%AEvncopenbox%E6%97%A0%E5%A4%B4%E5%9B%BE%E5%BD%A2%E5%8C%96%E7%AA%97%E7%AE%A1/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/debian13%E9%85%8D%E7%BD%AEvncopenbox%E6%97%A0%E5%A4%B4%E5%9B%BE%E5%BD%A2%E5%8C%96%E7%AA%97%E7%AE%A1/</guid><pubDate>Wed, 27 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;ol&gt;
&lt;li&gt;更新系统&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade -y
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;安装软件包&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install -y openbox tightvncserver xserver-xorg-core
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;添加普通用户&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;adduser vncuser # 使用adduser命令，自动创建家目录
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;添加root权限（可选），切换到&lt;code&gt;vncuser&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;sudo usermod -aG sudo vncuser # 按需添加sudo权限
su - vncuser # 切换到该用户操作
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;设置vnc密码&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;vncpasswd # 上限8位
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;配置 VNC 启动脚本&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;nano ~/.vnc/xstartup
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;编辑配置：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/sh
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
[ -r $HOME/.Xresources ] &amp;amp;&amp;amp; xrdb $HOME/.Xresources
exec openbox-session  # 直接启动openbox，无冗余命令
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;添加执行权限：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;chmod +x ~/.vnc/xstartup
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;自启动服务配置&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;sudo nano /etc/systemd/system/vncserver@.service
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;编辑systemd&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=TightVNC Server on :%i
After=network.target

[Service]
Type=forking
User=vncuser
Group=vncuser
ExecStart=/usr/bin/vncserver -depth 24 -geometry 1024x768 :%i
ExecStop=/usr/bin/vncserver -kill :%i

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;启用服务（以 display :1 为例）：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl daemon-reload
sudo systemctl enable vncserver@1.service
sudo systemctl start vncserver@1.service
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;创建缺失的&lt;code&gt;.Xauthority&lt;/code&gt;文件&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# 手动创建.Xauthority文件（空文件即可，VNC会自动写入内容）
touch ~/.Xauthority

# 设置正确权限（确保属于当前用户）
chmod 600 ~/.Xauthority
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>回忆录-CreNeXT2024</title><link>https://fuwari.vercel.app/posts/%E5%9B%9E%E5%BF%86%E5%BD%95-crenext2024/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E5%9B%9E%E5%BF%86%E5%BD%95-crenext2024/</guid><pubDate>Tue, 05 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;致青春，致2024——&lt;/p&gt;
&lt;p&gt;事情还要从2024年2月说起。那时候我中专刚刚“毕业”，处在家里蹲的情况，一方面长吁短叹升学难就业难，另一方面又在抱怨家里长辈难以沟通，行事倔强，自己的精神状态也十分恍惚。当时还深陷“升学”的庞氏骗局，另一方面又对反自学且脱离实际的课本内容嗤之以鼻。就在这样矛盾又迷茫的心态下度过一天又一天。&lt;/p&gt;
&lt;p&gt;就在那时，记得很清楚，&lt;code&gt;Hexo|Hugo博客交流群&lt;/code&gt;里有一人发布了一个招募链接，说是要建一个面向Z世代创造者的社区，抱着好奇的心理点了进去，还要填一个申请表，稀里糊涂地填完又稀里糊涂进去，发现一共还没到10个人，然后稀里糊涂地成为了社区早期的联合创始人之一（也没有NGO注册，更偏向经验交流）。&lt;/p&gt;
&lt;p&gt;几天以后，随着交流深入，和Marvin和Peter，也就是社区最早的两名发起人，逐渐熟络起来。Marvin当时16周岁，Peter高三即将高考，每天都有很热烈的讨论，人也越来越多。规定了新成员加入是申请制，在飞书投票，根据有没有运营&lt;code&gt;个人IP&lt;/code&gt;的意识以及对&lt;code&gt;创造一些与众不同的东西&lt;/code&gt;的热情来审核，我也了解了大家是一群“不走寻常路”的Hacker们。在这里没有对工作对学历的歧视，每个人都能畅所欲言。我忽然找到了志同道合的一群人。&lt;/p&gt;
&lt;p&gt;当时恰逢AI热，ChatGPT和Kimi爆火，大家对AI Product的方向，以及商业化路径聊了很多。由于我当时对这方面理解不深，我自告奋勇接下了整理聊天记录的任务。每天对着群消息截取话题，然后整理大家想法的矛盾点和最终达成的共识。也感谢Marvin和Peter对我的信任，我在整理这些纪要中对这一行业了解了许多，也为后续的数字游民生活打下了坚实的基础。不过我也要向社区里每个人道歉，我辜负了大家的信任，一共也没坚持超过两个月就放弃了。当时社区已经有50多人，每天聊天记录数千条，人力已经无法完成整理了。后面由于我对Coding一无所知，根本无法胜任用AI完成整理的任务。现在回想当时的技术发展情况，才发现这项任务十分艰巨，几乎无法实现。（没有Reasoning Model，没有完善的RAG和Rerank机制，更没有现在的Agent2Agent、MCP等基础设施构想）&lt;/p&gt;
&lt;p&gt;时间来到4月14日，当时在北京和朋友们庆祝完生日，第二天发现社区即将举行第一次线下活动，由&lt;code&gt;智谱AI Z计划&lt;/code&gt;赞助，在那里和大家举办了一场茶话会，深入地交流了对投资、对Web3、对AIGC的看法，我蓦然发现，我原来在几个月的时间里学到了这么多东西，也并非一无是处！大家还一起拍了一张照片：（我在左3）
&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/%E5%9B%9E%E5%BF%86%E5%BD%95-CreNeXT2024-01.jpg&quot; alt=&quot;回忆录-CreNeXT2024-01.jpg (1024×768)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这也是社区活动最频繁的一段时间。后面的3个月里，我没有坚持人工整理聊天记录，而是试图使用AI实现这一任务，但最后也没完成。也不知因为Marvin被AdventureX拉去帮忙，还是Peter忙于高考，又或许是没人整理纪要导致发言积极性不佳，总之社区内活跃度一天不如一天。随着一天又一天的挣扎，我也发现在Coding这一领域我似乎没有敏锐的直觉和过人的天分，甚至依旧是一窍不通，总之整理聊天记录的任务最终也没有完成。&lt;/p&gt;
&lt;p&gt;七月流火，听说Peter和Marvin在AdventureX，也是中国首届黑客松 &lt;em&gt;(Hackerthon)&lt;/em&gt; 中争取到了一个展位，我也自告奋勇前往杭州帮忙。也许是又菜又爱玩，那时候我和刚刚高考完的Peter制定了CreNeXT社区的字体规范（中文使用&lt;code&gt;苹方&lt;/code&gt;，英文使用&lt;code&gt;Dosis&lt;/code&gt;。）也感谢PiggyCBH在设计上的帮助，我们才能如期完成海报和周边纪念挂件的制作。也感谢我的一个非社区成员的朋友，Ruabbit，才能以低廉的可以接受的成本将设计生产出来，变成现实。7月14日，也是AdventureX的前一天，社区几名成员在杭州玉鸟集小聚，我带去了制作的海报和纪念品，Deeptalk后，次日来到了AdventureX会场。&lt;/p&gt;
&lt;p&gt;玉鸟集小聚：
&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/%E5%9B%9E%E5%BF%86%E5%BD%95-CreNeXT2024-02.jpg&quot; alt=&quot;回忆录-CreNeXT2024-02.jpg (1024×768)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;AdventureX闭幕式：
&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/%E5%9B%9E%E5%BF%86%E5%BD%95-CreNeXT2024-03.jpg&quot; alt=&quot;回忆录-CreNeXT2024-03.jpg (1024×768)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;当时开幕式合作方路演时，我热情地想要帮忙，但由于Peter的一句“我不在展位就是帮忙”，感觉到了一种不信任，也在此后对CreNeXT开始失望。后面社区也不是那么活跃，我忙于自己的事情，也渐渐淡忘了社区。&lt;/p&gt;
&lt;p&gt;后续回归了平淡(?)的生活。我在年底前往泰国旅居度假，感受自然，看GAIA主题艺术展，又在旅途结束，圣诞节前后，和&lt;code&gt;Stable Diffusion Thailand&lt;/code&gt;社区成员对图像、视频、空间智能生成的技术前沿进行了愉快的讨论。这也是2025年AIGC的热点方向。也是在这时候，CreNeXT在深圳少数派举行了最后一次活动，也永远停留在了2024。没能参加到这一场活动，十分遗憾。&lt;/p&gt;
&lt;p&gt;当时我甚至没了解到CreNeXT“毕业”的信息。直到2025年7月23日，第二次AdventureX上遇到Peter，才在他的口中听到这一“噩耗”。当然，众所周知的，AdventureX 2025发生了诸多糟糕的公关事件，发起人Ryan的独断专行，违背&lt;code&gt;Hackerthon&lt;/code&gt;的&lt;code&gt;Hacking&lt;/code&gt;精神的诸多行为，我也不一一赘述了，不知AdventureX是否会有3rd. Hacking，但回顾过往，我还是对大家对我的包容和帮助表示感谢。正是有了大家，我才能坚定地在数字游民的道路上走下去；也正是有了CreNeXT这一平台，我才能摆脱当时糟糕的状态，才能认识大家，也才有了今天的我。&lt;/p&gt;
&lt;p&gt;最后引用CreNeXT成员Jason的一句话：“假如你现在没认为两年前的自己是个傻逼，那就说明你在这两年里没有丝毫进步。”&lt;/p&gt;
&lt;p&gt;两年前的我真是个傻逼！感谢陪伴，致迷茫的青春——&lt;/p&gt;
&lt;p&gt;Sunny Pai
Aug. 5th, 2025&lt;/p&gt;
</content:encoded></item><item><title>Alist-encrypt薅羊毛第二弹(事故)</title><link>https://fuwari.vercel.app/posts/alist-encrypt%E8%96%85%E7%BE%8A%E6%AF%9B%E7%AC%AC%E4%BA%8C%E5%BC%B9%E4%BA%8B%E6%95%85/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/alist-encrypt%E8%96%85%E7%BE%8A%E6%AF%9B%E7%AC%AC%E4%BA%8C%E5%BC%B9%E4%BA%8B%E6%95%85/</guid><pubDate>Fri, 18 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在Alist Encrypt使用过程中又遇到了新的问题，在这里先引用先前的一篇部署文章：&lt;br /&gt;
&lt;a href=&quot;https://www.sunnypai.top/posts/alist-encrypt%E5%85%A8%E8%87%AA%E5%8A%A8%E8%96%85%E7%BD%91%E7%9B%98%E7%BE%8A%E6%AF%9B/&quot;&gt;Alist-encrypt全自动薅网盘羊毛 - 向阳哌小站&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;新的问题是这样的：&lt;br /&gt;
增量备份的测试中并无异常，但全量备份会直接报错终止，只能加密并上传少数几个文件，多数文件依旧无法上传。&lt;/p&gt;
&lt;p&gt;究其原因，主要是因为Alist挂载网盘存储后端，会有非官方客户端的限制。这一点可以通过本地加密后使用官方客户端推送到云端解决。&lt;/p&gt;
&lt;p&gt;但在使用Alist Encrypt的本地加解密功能时遇到了新的问题：我的文件总数高达39万个，而Alist Encrypt开发者限制了单次处理10000个文件。通过沟通得知10000这一数字是他随意设置，并未经过精心设计，于是我萌生了修改代码的念头。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/Alist-encrypt%E8%96%85%E7%BE%8A%E6%AF%9B%E7%AC%AC%E4%BA%8C%E5%BC%B9(%E4%BA%8B%E6%95%85)01.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我假设了500MB/s的IO（来自HDD阵列或SSD平均读写），又选择了10MB/文件的平均值（来自我NAS的个人文件统计），附加90%的SLA预设得到的2h24min日停机时长，按每次抢修45分钟的中小事故预设值得出平均每天停机4次，从而得出5.4h的单次uptime，于是取整设置了100万的文件数量，兴致满满准备提交PR，结果本以为一次能成功的测试出现了大问题，运行中途随机时间点报错找不到文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@@finish filePath /home/dev/projects/alist-encrypt/test/0626332.txt /home/dev/projects/testout/.temp/0626332.txt
Error: ENOENT: no such file or directory, rename &apos;/home/dev/projects/testout/.temp/0626332.txt&apos; -&amp;gt; &apos;/home/dev/projects/testout/0626332.txt&apos;
    at Object.renameSync (node:fs:1021:11)
    at ReadStream.&amp;lt;anonymous&amp;gt; (/home/dev/projects/alist-encrypt/node-proxy/src/utils/convertFile.ts:91:12)
    at ReadStream.emit (node:events:530:35)
    at endReadableNT (node:internal/streams/readable:1698:12)
    at processTicksAndRejections (node:internal/process/task_queues:90:21)
@@finish filePath /home/dev/projects/alist-encrypt/test/0626333.txt /home/dev/projects/testout/.temp/0626333.txt
@@finish filePath /home/dev/projects/alist-encrypt/test/0626334.txt /home/dev/projects/testout/.temp/0626334.txt
[ERROR] 04:39:49 Error: ENOENT: no such file or directory, rename &apos;/home/dev/projects/testout/.temp/0626332.txt&apos; -&amp;gt; &apos;/home/dev/projects/testout/0626332.txt&apos;
@@finish filePath /home/dev/projects/alist-encrypt/test/0626335.txt /home/dev/projects/testout/.temp/0626335.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;更换平台和算法（AES-CTR和RC4）测得如下结果：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;测试环境&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;文件系统&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;加密算法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;完成数1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;完成数2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;性能对比&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12900 台式机（USSD）&lt;/td&gt;
&lt;td&gt;EXT4&lt;/td&gt;
&lt;td&gt;AES-CTR&lt;/td&gt;
&lt;td&gt;26万&lt;/td&gt;
&lt;td&gt;62万&lt;/td&gt;
&lt;td&gt;延迟分配缓解竞争&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;RC4&lt;/td&gt;
&lt;td&gt;37万&lt;/td&gt;
&lt;td&gt;100万&lt;/td&gt;
&lt;td&gt;轻量算法减少I/O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EPYC7282 服务器（RAIDZ0）&lt;/td&gt;
&lt;td&gt;ZFS&lt;/td&gt;
&lt;td&gt;AES-CTR&lt;/td&gt;
&lt;td&gt;5万&lt;/td&gt;
&lt;td&gt;7万&lt;/td&gt;
&lt;td&gt;COW 增加竞争概率&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;RC4&lt;/td&gt;
&lt;td&gt;2万&lt;/td&gt;
&lt;td&gt;4万&lt;/td&gt;
&lt;td&gt;低延迟暴露问题&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;一开始，“性能越好出错越早结果越糟糕”的奇怪现象让我进入了思维惯性，一番思索也没想清楚具体原因&lt;/p&gt;
&lt;p&gt;询问他人并借助人工智能工具分析后才得出初步结论：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;根本原因&lt;/strong&gt;：Node.js 的异步 I/O 模型与文件系统特性共同作用，导致高并发文件操作时出现 &lt;strong&gt;竞态条件（Race Condition）&lt;/strong&gt;，表现为 &quot;文件存在但报错 &lt;code&gt;ENOENT&lt;/code&gt;&quot;。具体表现为：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;文件状态不一致&lt;/strong&gt;：异步操作未正确同步，导致文件创建、写入、重命名等步骤的执行顺序不可控。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;文件系统行为差异&lt;/strong&gt;：EXT4 的延迟分配与 ZFS 的写时复制（COW）特性，放大了不同硬件环境下的竞态窗口。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;关掉兴冲冲写好准备提交的PR，深深叹了一口气，薅羊毛的路任重而道远啊！&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;现象解读：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;EXT4 表现更好&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;延迟分配机制将数据暂存内存，&lt;strong&gt;缩短了文件操作的可见性延迟&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;USB的高延迟意外成为 &quot;天然并发限制器&quot;，变相降低了竞态概率。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ZFS 表现更差&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;写时复制（COW）和事务组提交机制导致 &lt;strong&gt;元数据更新延迟更高&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;NVMe 的低延迟特性反而让竞态窗口更易被触发（操作速度 &amp;gt; 同步速度）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>卜算子·一夜奇迹未见</title><link>https://fuwari.vercel.app/posts/%E5%8D%9C%E7%AE%97%E5%AD%90%E4%B8%80%E5%A4%9C%E5%A5%87%E8%BF%B9%E6%9C%AA%E8%A7%81/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E5%8D%9C%E7%AE%97%E5%AD%90%E4%B8%80%E5%A4%9C%E5%A5%87%E8%BF%B9%E6%9C%AA%E8%A7%81/</guid><pubDate>Wed, 12 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;看到BiliBili某位VUP的粉丝因为沉迷看直播而考试挂科，有感而发作此篇。&lt;/p&gt;
&lt;p&gt;《卜算子·一夜奇迹未见》
（用一支笔点燃长夜，悬半窗朧月待破晓，终未见通宵苦读的奇迹）&lt;/p&gt;
&lt;p&gt;昔迷掌上欢，未觉流光短。
朧月西沉日跃山，方悟韶华浅。
卷帙积成丘，挂科垒作山。
哈基岚苦笑倚杆，夜阑泪不干。&lt;/p&gt;
</content:encoded></item><item><title>Grafana+Prometheus监控</title><link>https://fuwari.vercel.app/posts/grafanaprometheus%E7%9B%91%E6%8E%A7/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/grafanaprometheus%E7%9B%91%E6%8E%A7/</guid><pubDate>Sat, 21 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;记一下Prometheus+Grafana部署&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  grafana:
    image: grafana/grafana-enterprise
    container_name: grafana
    restart: unless-stopped
    environment:
     - GF_SERVER_ROOT_URL=https://grafana.sunnypai.top/
    networks:
      - caddy_network
      - grafana_network
#    ports:
#     - &apos;3000:3000&apos;
    volumes:
     - ./grafana:/var/lib/grafana

  pushgateway:
    image: prom/pushgateway:v1.10.0
    container_name: pushgateway
    command: --persistence.file=/pushgateway/pushgateway.data
    restart: unless-stopped
    networks:
      - grafana_network
#    ports:
#      - 9091:9091
    volumes:
      - ./pushgateway:/pushgateway

  prometheus:
    image: prom/prometheus:v3.0.1
    container_name: prometheus
    command: --config.file=/etc/prometheus/prometheus.yml
    user: 0:0
    restart: unless-stopped
    networks:
      - grafana_network
#    ports:
#      - 9090:9090
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
      - ./prometheus/alerts/:/etc/prometheus/rules.d/
      - ./prometheus/data/:/prometheus

  alertmanager:
    image: prom/alertmanager:v0.27.0
    container_name: alertmanager
    command: --config.file=/etc/alertmanager/alertmanager.yml
    networks:
      - grafana_network
#    ports:
#      - 9093:9093
    restart: unless-stopped
    volumes:
      - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml

  node-exporter:
    image: &quot;prom/node-exporter:v1.3.1&quot;
    container_name: node-exporter
#    ports:
#      - &apos;9100:9100&apos;
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
      - /etc/hostname:/etc/hostname:ro
    restart: unless-stopped
    networks:
      - grafana_network
    command:
      - &apos;--path.procfs=/host/proc&apos;
      - &apos;--path.sysfs=/host/sys&apos;
      - &apos;--path.rootfs=/rootfs&apos;

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:v0.45.0
    container_name: cadvisor
#    ports:
#      - &quot;8080:8080&quot;
    networks:
      - grafana_network
    volumes:
      - &quot;/:/rootfs:ro&quot;
      - &quot;/var/run:/var/run:ro&quot;
      - &quot;/sys:/sys:ro&quot;
      - &quot;/var/lib/docker/:/var/lib/docker:ro&quot;
      - &quot;/dev/disk/:/dev/disk:ro&quot;
    privileged: true
    devices:
      - &quot;/dev/kmsg&quot;
    restart: unless-stopped

  blackbox-exporter:
    image: prom/blackbox-exporter:v0.25.0
    container_name: blackbox-exporter
#    ports:
#      - &quot;9115:9115&quot;
    networks:
      - grafana_network
    volumes:
      - &quot;./blackbox:/config&quot;
    command:
      - &quot;--config.file=/config/blackbox.yml&quot;
    restart: unless-stopped

networks:
  caddy_network:
    external: true
  grafana_network:
    external: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;容器的作用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Grafana: 图形化WebUI&lt;/li&gt;
&lt;li&gt;Prometheus: 数据源聚合&lt;/li&gt;
&lt;li&gt;pushgateway: 边缘节点数据采集&lt;/li&gt;
&lt;li&gt;alertmanager: 告警通知&lt;/li&gt;
&lt;li&gt;node-exporter: 节点探针&lt;/li&gt;
&lt;li&gt;cAdvisor: 容器状态监控&lt;/li&gt;
&lt;li&gt;blackbox-exporter: Web服务状态监控&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;边缘节点相关配置未完待续……&lt;/p&gt;
&lt;p&gt;2025年8月4日更新：Grafana+Prometheus对内存占用太恐怖了，拆了跑路了，没有后续了&lt;/p&gt;
</content:encoded></item><item><title>无糖柠檬茶</title><link>https://fuwari.vercel.app/posts/%E6%97%A0%E7%B3%96%E6%9F%A0%E6%AA%AC%E8%8C%B6/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%97%A0%E7%B3%96%E6%9F%A0%E6%AA%AC%E8%8C%B6/</guid><pubDate>Sat, 21 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;我喜欢无糖柠檬茶。&lt;/p&gt;
&lt;p&gt;刚入口，舌尖接触是浓郁的酸，是柠檬的味道；&lt;/p&gt;
&lt;p&gt;初下咽，茶叶的苦和柠檬的涩，淡淡残余口中；&lt;/p&gt;
&lt;p&gt;过一会，柠檬的清香夹杂茶汤，回味余音绕梁。&lt;/p&gt;
&lt;p&gt;放久了，淡淡的柠檬清香转化为苦涩，就丧失了美味。&lt;/p&gt;
&lt;p&gt;就像生活，人生苦短，及时行乐，勇敢的人先享受世界。&lt;/p&gt;
&lt;p&gt;——记2024&lt;/p&gt;
</content:encoded></item><item><title>自建tailscale-derper踩坑日记</title><link>https://fuwari.vercel.app/posts/%E8%87%AA%E5%BB%BAtailscale-derper%E8%B8%A9%E5%9D%91%E6%97%A5%E8%AE%B0/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E8%87%AA%E5%BB%BAtailscale-derper%E8%B8%A9%E5%9D%91%E6%97%A5%E8%AE%B0/</guid><pubDate>Sat, 21 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;这是一篇踩坑记录，关于tailscale derper的。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://localhost:4321/posts/%E8%87%AA%E5%BB%BAtailscale-derper%E8%B8%A9%E5%9D%91%E6%97%A5%E8%AE%B0/#%E9%83%A8%E7%BD%B2%E6%B5%81%E7%A8%8B&quot;&gt;&lt;strong&gt;懒狗快捷指南：&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h5&gt;引言（和主题关系不大，不想看直接跳过）：&lt;/h5&gt;
&lt;p&gt;众所周知，中国大陆的网络环境，ISP几乎不提供公网ipv4地址，而云服务器的流量价格是海外同类产品的数倍乃至十数倍：以阿里云为例，流量价格为500CNY/TB（ECS共享流量包），而AWS的价格则是5USD/TB（lightsail实例），虽然大陆也有一些“大带宽”云服务器，例如雨云和物语云，但SLA保证远低于头部厂商。&lt;/p&gt;
&lt;p&gt;（你也不想在需要编译软件时，打开vscode remote-ssh时，提示个连接超时吧？）&lt;/p&gt;
&lt;h3&gt;选择 tailscale 原因：&lt;/h3&gt;
&lt;p&gt;废话不多说，有以下几点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;使用P2P打洞，流量不流经中转服务器节点&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;相较于同样P2P的zerotier，部署简便开箱即用&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;跨平台（Windows、Linux、iOS、Android、MacOS）乃至对集群环境（Kubernetes、AWS等）兼容性好&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;打洞失败有官方中继可用，无需额外支出&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但是随着设备越来越多、流量越来越大，官方中继已经难以满足使用需求，具体问题有延迟过高(~300ms)、带宽较小(~1Mbps)。经查询后了解到具有自建中转的做法，可以极大的提升中国大陆内和跨境数据传输的体验。&lt;/p&gt;
&lt;h3&gt;软件架构：&lt;/h3&gt;
&lt;p&gt;tailscale分为控制平面和数据平面，是“半个零信任”的架构。控制平面负责身份认证，数据平面负责打洞和中继。这两者都有官方开源的自建方案：Headscale和Derper。&lt;/p&gt;
&lt;p&gt;Headscale私有化了控制平面，在具有较高的安全性需求的环境可以考虑使用，而Derper则是私有化的数据平面节点，具体节点则由tailscale客户端选择。由于我是个人使用，因此只做了derper的自建。&lt;/p&gt;
&lt;h3&gt;部署踩坑：&lt;/h3&gt;
&lt;p&gt;derper是使用golang（go语言）编写的。为了操作简便，我使用docker部署。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The DERP protocol does a protocol switch inside TLS from HTTP to a custom bidirectional binary protocol. It is thus incompatible with many HTTP proxies. Do not put &lt;code&gt;derper&lt;/code&gt; behind another HTTP proxy. &lt;a href=&quot;https://github.com/tailscale/tailscale/tree/main/cmd/derper#guide-to-running-cmdderper&quot;&gt;*tailscale/cmd/derper&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;这是derper的第一个坑点：&lt;/h4&gt;
&lt;p&gt;你会在网上找到很多教程，其中写着通过各种代理：Nginx、Caddy……&lt;br /&gt;
注意：&lt;strong&gt;Derper是Tailscale自研的协议，虽然一样使用HTTP/TLS，端口也是80/443，但通过WEB代理会拒绝连接。&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;然后就到了第二个坑点：&lt;/h4&gt;
&lt;p&gt;Derper有官方的域名部署，还有通过ip derper部署的方式，即使用 &lt;code&gt;&quot;InsecureForTests&quot;: true&lt;/code&gt; 这一测试环境使用的ACL配置项，跳过TLS验证和域名验证。&lt;/p&gt;
&lt;p&gt;例如这个项目：&lt;a href=&quot;https://github.com/yangchuansheng/ip_derper&quot;&gt;yangchuansheng/ip_derper&lt;/a&gt; ，是ip derper常用的docker项目。我尝试使用非标端口进行部署，一开始测试通过，但在使用大约2-3小时后，自建derper在客户端使用&lt;code&gt;tailscale netcheck&lt;/code&gt;命令测试通过，但无论如何都无法实现连接，已经建立的连接也被强制中断，包括打洞和中继。报错在这里我没有保存，&lt;strong&gt;我个人也不推荐使用ip derper搭建&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;s&gt;我在这里卡了两天时间，查了几十篇教程和文档，你要是愿意搞不舍得买个域名的钱请自行折腾。&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;另一种则是tailscale官方的使用域名搭建。你可以选择开放80&amp;amp;443端口给它，内置的acme会获取letsencrypt证书。但由于我的80/443被其余web服务占用，我使用了manual方式。&lt;/p&gt;
&lt;h4&gt;接下来来到了第三个坑点：&lt;/h4&gt;
&lt;p&gt;derper程序不会识别 &lt;code&gt;cert.pemcert.key&lt;/code&gt; 这样的证书文件，所以直接绑定到通配符证书目录不可用，而是需要&lt;strong&gt;重命名为&lt;/strong&gt;&lt;code&gt;example.com.crt&lt;/code&gt;&lt;strong&gt;和&lt;/strong&gt;&lt;code&gt;example.com.key&lt;/code&gt;，再进行使用。以及如果docker或容器内使用的不是root用户，还需要重新&lt;strong&gt;配置证书权限&lt;/strong&gt;。&lt;/p&gt;
&lt;h4&gt;最后一个坑点是我踩了最长时间才爬出来的：&lt;/h4&gt;
&lt;p&gt;我选择的是 &lt;a href=&quot;https://github.com/fredliang44/derper-docker&quot;&gt;fredliang44/derper-docker&lt;/a&gt; 这个项目，按照README使用 &lt;code&gt;DERP_ADDR=&apos;:8443&apos;&lt;/code&gt; 配置项进行自定义端口，但启动时会出现神秘报错：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Attaching to derper
derper  | 2024/12/21 04:41:12 no config path specified; using /var/lib/derper/derper.key
derper  | 2024/12/21 04:41:12 derper: serving on &quot;:8443&quot; with TLS
derper  | 2024/12/21 04:41:12 derper: listen tcp: lookup tcp/8443&quot;: unknown port
derper exited with code 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不管使用default bridge、custom bridge 还是 host 网络，均无法访问。macvlan模式由于tailscale官方文档要求禁止部署在防火墙后，而我又没有自己的公网ip池，因此无法使用。&lt;/p&gt;
&lt;p&gt;一开始怀疑是镜像问题，后面尝试重新构建docker image，甚至连带golang依赖也重新构建了，均无法运行。换了其余好几个版本的镜像也是一样的报错，才意识到可能是第三方教程和官方README的问题：他们不约而同的选择了 &lt;code&gt;ENV&lt;/code&gt; 定义非标端口，而这一配置项会被翻译成官方二进制文件的 &lt;code&gt;-a&lt;/code&gt; 参数。而在容器内测试使用这一参数时，无法识别这一命令……&lt;/p&gt;
&lt;p&gt;所以，即使想使用非标端口，也请删除这一ENV，然后&lt;strong&gt;使用&lt;/strong&gt; &lt;code&gt;-p &amp;lt;custom_port&amp;gt;:443&lt;/code&gt; &lt;strong&gt;这样的形式，在bridge network实现部署&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;部署流程：&lt;/h3&gt;
&lt;p&gt;好吧，今天又说了太多废话。下面直接放配置文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  derper:
    container_name: derper
    environment:
#      - DERP_ADDR=&quot;:8443&quot; # 这里不要加，会启动失败
      - DERP_DOMAIN=derp.sunnypai.top
      - DERP_CERT_MODE=manual
      - DERP_CERT_DIR=/app/certs
      - DERP_HTTP_PORT=-1
# 这里如果不使用非标端口，直接删掉ports部分配置，使用host
#    network_mode: host
    ports:
      - 8443:443
      - 3478:3478/udp
    volumes:
      - /root/AppData/derper/certs/derp.sunnypai.top:/app/certs
      - /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
    image: fredliang/derper:latest
    restart: unless-stopped
    networks:
      - derper_network

networks:
  derper_network:
    external: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果不使用非标端口，也可以使用letsencrypt配置证书，这边建议看其余教程，&lt;em&gt;&lt;s&gt;我懒得测试&lt;/s&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;然后在控制平面的Access Controls文件中添加这些内容：（请注意缩进）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;	// 增加下方这部分
	&quot;derpMap&quot;: {
		&quot;Regions&quot;: {
			&quot;912&quot;: { // 这个节点里面的912随便填，900以上即可
				&quot;RegionID&quot;:   912,
				// 这里可以改名，code和name不要求一致
				&quot;RegionCode&quot;: &quot;derper_self&quot;,
				&quot;RegionName&quot;: &quot;Derper Self&quot;,
				&quot;Nodes&quot;: [
					{
						&quot;Name&quot;:     &quot;derper_self&quot;,
						&quot;RegionID&quot;: 912,
						&quot;DERPPort&quot;: 8443, // 更换为自己的端口号
						&quot;STUNPort&quot;: 3478,

						&quot;HostName&quot;: &quot;example.com&quot;, // 此 HostName 参数填写自己的域名

						&quot;InsecureForTests&quot;: false, // 测试时可以先写成true
					},
				],
			},
		},
	},
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后重启全部客户机节点，即可实现自建derper部署。&lt;/p&gt;
&lt;p&gt;半天后追加：&lt;/p&gt;
&lt;p&gt;高峰期2%~3%丢包率，平均延迟75ms，最长279ms，使用酒店wifi，到路由延迟5-10ms，效果很棒！&lt;br /&gt;
欢迎搭建成功的朋友们评论留言使用体验！&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;感谢来自 &lt;a href=&quot;https://blog.kiyoi.xyz/&quot;&gt;Kiyoi&lt;/a&gt; 的支持。&lt;/p&gt;
</content:encoded></item><item><title>记一次证书失效错误</title><link>https://fuwari.vercel.app/posts/%E8%AE%B0%E4%B8%80%E6%AC%A1%E8%AF%81%E4%B9%A6%E5%A4%B1%E6%95%88%E9%94%99%E8%AF%AF/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E8%AE%B0%E4%B8%80%E6%AC%A1%E8%AF%81%E4%B9%A6%E5%A4%B1%E6%95%88%E9%94%99%E8%AF%AF/</guid><pubDate>Wed, 18 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;刚刚收到了来自GXDE OS Team的证书过期警告。&lt;/p&gt;
&lt;p&gt;我还挺疑惑：我都配置了证书自动获取工作流和自动同步工作流了啊，为什么还会过期？&lt;br /&gt;
我使用的是Certd自动获取证书、inotify监听默认证书存储路径，然后 &lt;code&gt;rsync -avh --delete &amp;lt;src&amp;gt; &amp;lt;dst&amp;gt;&lt;/code&gt; ，按理来说不应该出现失效的问题啊&lt;br /&gt;
随后我进入web console确认，Certd也没有问题，正常更新证书：&lt;br /&gt;
&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/%E8%AE%B0%E4%B8%80%E6%AC%A1%E8%AF%81%E4%B9%A6%E5%A4%B1%E6%95%88%E9%94%99%E8%AF%AF01.png&quot; alt=&quot;&quot; /&gt;既然正常更新，那么应该正常工作。随后又尝试重启caddy，依旧无效。&lt;br /&gt;
忽然我意识到，这两者之间使用的是一共inotify脚本同步，那是不是这个脚本没有正确运行呢？&lt;/p&gt;
&lt;p&gt;查看脚本对应的日志，发现了大量的错误，表示脚本无法启动：&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/%E8%AE%B0%E4%B8%80%E6%AC%A1%E8%AF%81%E4%B9%A6%E5%A4%B1%E6%95%88%E9%94%99%E8%AF%AF02.png&quot; alt=&quot;&quot; /&gt;systemd默认的root权限依旧denied？带着好奇我查看了文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@sunnypai-superserver:/ # ls -al /AppData/Certd/sync.sh
-rw-r--r-- 1 root root 354 九月   18 12:04 /AppData/Certd/sync.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;赫然发现，没有x权限……&lt;/p&gt;
&lt;p&gt;再回想当时测试时的操作：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# sudo bash sync.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;好吧，教训+1&lt;/p&gt;
</content:encoded></item><item><title>小城乐章-掠过秋天的湖光</title><link>https://fuwari.vercel.app/posts/%E5%B0%8F%E5%9F%8E%E4%B9%90%E7%AB%A0-%E6%8E%A0%E8%BF%87%E7%A7%8B%E5%A4%A9%E7%9A%84%E6%B9%96%E5%85%89/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E5%B0%8F%E5%9F%8E%E4%B9%90%E7%AB%A0-%E6%8E%A0%E8%BF%87%E7%A7%8B%E5%A4%A9%E7%9A%84%E6%B9%96%E5%85%89/</guid><pubDate>Mon, 07 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;秋高气爽艳阳天，乘兴而去，至故乡公园，街角一隅，聆听小城乐章，兴之至时摄此片，辅作文以记。&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;湖光冷翠，秋意微凉&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/%E5%B0%8F%E5%9F%8E%E4%B9%90%E7%AB%A0-%E6%8E%A0%E8%BF%87%E7%A7%8B%E5%A4%A9%E7%9A%84%E6%B9%96%E5%85%8901.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;湖面静谧无波，树木的倒影模糊而克制。蓝天无云，仿佛涂抹在画布上的一片纯色，空旷与寂静在空气中蔓延。一艘小船独自漂浮，人在其中似有若无，仿佛消失于景致之中。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;柳枝轻垂，风起无声&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/%E5%B0%8F%E5%9F%8E%E4%B9%90%E7%AB%A0-%E6%8E%A0%E8%BF%87%E7%A7%8B%E5%A4%A9%E7%9A%84%E6%B9%96%E5%85%8902.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;垂柳低垂，仿佛无力地伏在湖面之上。风轻拂过，湖水微动，波澜不惊。岸边的几叶扁舟，如同点缀在这静止画面中的细节，人与景物没有主次之分，彼此融入秋天的底色。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;长道无言，金叶落寞&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/%E5%B0%8F%E5%9F%8E%E4%B9%90%E7%AB%A0-%E6%8E%A0%E8%BF%87%E7%A7%8B%E5%A4%A9%E7%9A%84%E6%B9%96%E5%85%8903.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;林荫小道延伸向远处，秋叶铺满两旁，偶有行人从中穿过，步伐缓慢而轻盈。阳光斜洒在地面，色彩克制，行人隐没在影子与阳光的交替中，秋的气息寡淡却不失温度。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;灰绿交织，静默一角&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/%E5%B0%8F%E5%9F%8E%E4%B9%90%E7%AB%A0-%E6%8E%A0%E8%BF%87%E7%A7%8B%E5%A4%A9%E7%9A%84%E6%B9%96%E5%85%8904.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;城市建筑在阳光下依然冷峻，树木的绿意点缀其中，却似乎只是无言的陪衬。车流安静地行进，生活的喧嚣在远方，留给眼前的只剩一片空旷与宁静。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;红叶如火，寂寥无声&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/%E5%B0%8F%E5%9F%8E%E4%B9%90%E7%AB%A0-%E6%8E%A0%E8%BF%87%E7%A7%8B%E5%A4%A9%E7%9A%84%E6%B9%96%E5%85%8905.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;街角的红藤依山而上，火红色在深秋的阳光下显得格外明亮，却不见炙热，反而透出一股冷清。停车场空旷，山坡上的建筑与红叶形成沉默的对峙，一如小城的日常，平静且疏离。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;街道尽头，秋意渐深&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/%E5%B0%8F%E5%9F%8E%E4%B9%90%E7%AB%A0-%E6%8E%A0%E8%BF%87%E7%A7%8B%E5%A4%A9%E7%9A%84%E6%B9%96%E5%85%8906.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;深秋的光线铺满街道，偶有人影走过，影子拉长而模糊。远处的红叶如同秋天最后的宣告，却也显得克制而低调。整座城市仿佛沉睡在秋天的微凉中，秋风划过，却无人察觉。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;配乐：&lt;a href=&quot;https://assets.blog.edge.sunnypai.top/%E5%B0%8F%E5%9F%8E%E4%B9%90%E7%AB%A0-%E6%8E%A0%E8%BF%87%E7%A7%8B%E5%A4%A9%E7%9A%84%E6%B9%96%E5%85%8907.mp3&quot;&gt;小城乐章-掠过秋天的湖光&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;版权声明&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;标题: &lt;em&gt;小城乐章-掠过秋天的湖光&lt;/em&gt;&lt;br /&gt;
作者: SunnyPai&lt;br /&gt;
版权所有 © 2024 SunnyPai。&lt;/p&gt;
&lt;p&gt;本作品（包含照片和音乐）依据 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 (CC BY-NC-SA 4.0) 授权。&lt;/p&gt;
&lt;p&gt;允许共享：可以自由复制、分发和传播本作品。&lt;br /&gt;
允许演绎：可以改编、转换或再创作本作品，但必须基于相同的许可协议。&lt;br /&gt;
非商业性使用：不能将本作品用于商业目的。&lt;br /&gt;
署名：您必须给予适当的署名，注明来源，并提供协议链接。&lt;/p&gt;
&lt;p&gt;如需进行超出该许可范围的使用，需联系作者获取许可。&lt;/p&gt;
</content:encoded></item><item><title>Alist-encrypt全自动薅网盘羊毛</title><link>https://fuwari.vercel.app/posts/alist-encrypt%E5%85%A8%E8%87%AA%E5%8A%A8%E8%96%85%E7%BD%91%E7%9B%98%E7%BE%8A%E6%AF%9B/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/alist-encrypt%E5%85%A8%E8%87%AA%E5%8A%A8%E8%96%85%E7%BD%91%E7%9B%98%E7%BE%8A%E6%AF%9B/</guid><pubDate>Mon, 30 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;近期本地服务器架构经常变动，引发了我对个人数据安全性的担忧。因此一番寻找后，综合考量价格和性能，选择了189网盘作为云备份提供商。&lt;/p&gt;
&lt;h3&gt;加密方案&lt;/h3&gt;
&lt;p&gt;由于有一些隐私文件，因此不便于直接上传到网盘。在仔细阅读 &lt;a href=&quot;https://alist.nn.ci/&quot;&gt;alist文档&lt;/a&gt; 后，找到了一个为alist的webdav提供加密的项目：alist-encrypt&lt;/p&gt;
&lt;p&gt;这个项目不仅限于可以为alist提供加密，也可以为标准webdav接口提供加密。直接上传到encrypt目录就可以自动完成加密&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/Alist-encrypt%E5%85%A8%E8%87%AA%E5%8A%A8%E8%96%85%E7%BD%91%E7%9B%98%E7%BE%8A%E6%AF%9B01.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;存储配置&lt;/h3&gt;
&lt;p&gt;alist部署和添加存储的教程这里就不再提供。由于服务商接口变动较为频繁，请以官方文档为准。同时该方案无高可用性保证、分享时请遵循服务商EULA，避免不合理的挤占带宽或服务器资源。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://alist.nn.ci/guide/install/script.html&quot;&gt;[安装教程] https://alist.nn.ci/guide/install/script.html&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://alist.nn.ci/guide/drivers/&quot;&gt;[添加存储教程] https://alist.nn.ci/guide/drivers/&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/traceless/alist-encrypt&quot;&gt;[配置加密教程] https://github.com/traceless/alist-encrypt&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;加密配置&lt;/h3&gt;
&lt;p&gt;alist-encrypt 项目提供了两种部署方式：node.js 和 docker，并给出了docker compose文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;version: &apos;3&apos; #新版本docker compose可以省略version选项
services:
  alist-encrypt:
    image: prophet310/alist-encrypt:beta #beta标签不提供arm版本，arm请使用:beta-1.1
    restart: unless-stopped
    hostname: alist-encrypt
    container_name: alist-encrypt
    volumes:
      - ./alist-encrypt:/node-proxy/conf
    environment:
      TZ: Asia/Shanghai
      ALIST_HOST: 192.168.31.254:5254        # 建议加个设置项，修改为自己的ip和端口
    ports:
      - 5344:5344
    network_mode: bridge
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;docker compose up -d&lt;/code&gt; 启动后，输入&lt;a&gt;ip:5344/public/index.html&lt;/a&gt;进入web管理面板，默认账号admin密码123456&lt;/p&gt;
&lt;p&gt;路径填写alist网盘的绝对路径，endpoint的/dav不需要写；多个路径使用英文逗号隔&lt;br /&gt;
具体配置见文章开头的图片&lt;/p&gt;
&lt;h3&gt;自动化配置&lt;/h3&gt;
&lt;p&gt;首先安装所需使用的包：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get -y install inotify-tools rclone
sudo -v ; curl https://rclone.org/install.sh | sudo bash
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;p&gt;将alist-encrypt服务的dav endpoint保存到rclone：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rclone config #用本地目录的拥有者的身份配置
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;rclone配置文件储存在当前用户的家目录中，因此切换用户后无法读取对应的配置&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;为了便于本地NAS向网盘推送备份，我写了一个脚本以便本地目录出现变动后向网盘自动同步：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
inotifywait -m -r -e modify,create,delete /AppData/alist/local-drive |
while read path action file; do
    rclone sync /path/to/local/dir alist-encrypt:/remote/dir/encrypt --verbose --progress --delete-excluded
done
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注：仅限于Linux和部分Unix系统，inotify基于inode实现文件系统级监听服务&lt;br /&gt;
另：若目录过于庞大，例如超过524288个子目录，则inotify无法完成监听，需要额外配置以增大监听目录数量限制（我更建议使用其他方式实现）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;find /path/to/local/dir -type d | wc -l #查看需要监听的目录的子目录数量
cat /proc/sys/fs/inotify/max_user_watches #查看inotify的监听目录限制
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;大多数情况下，默认限制足够使用&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;find /AppData/alist/local-drive/ -type d | wc -l
cat /proc/sys/fs/inotify/max_user_watches

16371
751311
---
du -sh /AppData/alist/local-drive/
3.2T    /AppData/alist/local-drive/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这是我的个人存储，3.2TB只有16371个子目录，距离我的默认限制751311还有数十倍的差距，因此在PB级以下基本无需担心&lt;/p&gt;
&lt;h1&gt;当然要是本地几PB的容量，也不需要薅网盘羊毛了吧（碎碎念）&lt;/h1&gt;
&lt;hr /&gt;
&lt;p&gt;最后则是自动化运行，使用systemd守护进程实现&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=Alist Encrypted Drive Sync Service
After=network.target

[Service]
Type=simple
ExecStart=/path/to/inotify-sync.sh
StandardOutput=append:/var/log/alist-sync.log
StandardError=append:/var/log/alist-sync.log
Restart=always
RestartSec=5
User=root
# 设置环境变量
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# 如果需要更多变量，可以使用多个 Environment= 行
# Environment=VAR_NAME=value

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在目录发生变动后，rclone就会自动开始同步&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;更新：关于优先级和资源限制的配置 (Nov. 30th, 2024)&lt;/h4&gt;
&lt;p&gt;由于该systemd进程默认没有资源限制，在新增巨量小文件时会占用大量内存和CPU资源，导致系统宕机&lt;/p&gt;
&lt;p&gt;因此需要使用 &lt;code&gt;Nice&lt;/code&gt; 和 &lt;code&gt;MemoryLimit&lt;/code&gt; 来限制该服务的资源使用&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=Alist Encrypted Drive Sync Service
After=network.target

[Service]
Type=simple
Nice=10 # -20 至 19 之间，默认是0，数字越大优先级越低
MemoryLimit=5G # 可以更换K M G T等单位

ExecStart=/path/to/inotify-sync.sh
StandardOutput=append:/var/log/alist-sync.log
StandardError=append:/var/log/alist-sync.log
Restart=always
RestartSec=5
User=root
# 设置环境变量
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# 如果需要更多变量，可以使用多个 Environment= 行
# Environment=VAR_NAME=value

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>简记immich初体验</title><link>https://fuwari.vercel.app/posts/%E7%AE%80%E8%AE%B0immich%E5%88%9D%E4%BD%93%E9%AA%8C/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E7%AE%80%E8%AE%B0immich%E5%88%9D%E4%BD%93%E9%AA%8C/</guid><pubDate>Sun, 18 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;从大概半年前我就在关注immich了，不过因为服务器架构频繁变动，因此没有去动手部署。目前已经基本定型（其实是没精力折腾了），因此开始部署一些“家庭必备”小服务。&lt;/p&gt;
&lt;h3&gt;GPU Support&lt;/h3&gt;
&lt;p&gt;PVE，IOMMU，禁用nouveau，直通显卡，ubuntu（其他发行版也可），Nvidia-driver，CUDA，CUDNN，老生常谈的事情了，这里不再赘述&lt;br /&gt;
随后需要为docker启用GPU支持，docker安装，nvidia-container-toolkit，随手丢个链接：&lt;a href=&quot;https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html&quot;&gt;https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html&lt;/a&gt;&lt;br /&gt;
需要时请查阅最新版文档，旧版本不一定生效（痛骂NoVideo）&lt;/p&gt;
&lt;h3&gt;Docker Compose&lt;/h3&gt;
&lt;h4&gt;懒狗快捷指南：&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;#section1&quot;&gt;docker-compose.yml&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;#section2&quot;&gt;hwaccel.ml.yml&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;#section3&quot;&gt;hwaccel.transcoding.yml&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;#section4&quot;&gt;.env&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;具体实现：&lt;/h4&gt;
&lt;p&gt;接下来的四个文件是按照官网说明编写的，但运行时出现了问题，&lt;strong&gt;不要直接复制粘贴！！！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker-compose.yml&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#
# WARNING: Make sure to use the docker-compose.yml of the current release:
#
# https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
#
# The compose file on main may not be compatible with the latest release.
#

name: immich

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    extends:
      file: hwaccel.transcoding.yml
      service: nvenc # Set to &apos;nvenc&apos; for Nvidia GPU-based hardware transcoding
      #   service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
    volumes:
      # Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - .env
    ports:
      - 2283:3001
    depends_on:
      - redis
      - database
    restart: always
    healthcheck:
      disable: false

  immich-machine-learning:
    container_name: immich_machine_learning
    # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag.
    # Example tag: ${IMMICH_VERSION:-release}-cuda
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-cuda # Adding -cuda to enable CUDA support
    extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration
      file: hwaccel.ml.yml
      service: cuda # Set to &apos;cuda&apos; for Nvidia GPU-based machine learning acceleration
      #   service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable
    volumes:
      - model-cache:/cache
    env_file:
      - .env
    restart: always
    healthcheck:
      disable: false

  redis:
    container_name: immich_redis
    image: docker.io/redis:6.2-alpine@sha256:e3b17ba9479deec4b7d1eeec1548a253acc5374d68d3b27937fcfe4df8d18c7e
    healthcheck:
      test: redis-cli ping || exit 1
    restart: always

  database:
    container_name: immich_postgres
    image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: &apos;--data-checksums&apos;
    volumes:
      # Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    healthcheck:
      test: pg_isready --dbname=&apos;${DB_DATABASE_NAME}&apos; --username=&apos;${DB_USERNAME}&apos; || exit 1; Chksum=&quot;$$(psql --dbname=&apos;${DB_DATABASE_NAME}&apos; --username=&apos;${DB_USERNAME}&apos; --tuples-only --no-align --command=&apos;SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database&apos;)&quot;; echo &quot;checksum failure count is $$Chksum&quot;; [ &quot;$$Chksum&quot; = &apos;0&apos; ] || exit 1
      interval: 5m
      start_interval: 30s
      start_period: 5m
    command: [&quot;postgres&quot;, &quot;-c&quot;, &quot;shared_preload_libraries=vectors.so&quot;, &quot;-c&quot;, &apos;search_path=&quot;$$user&quot;, public, vectors&apos;, &quot;-c&quot;, &quot;logging_collector=on&quot;, &quot;-c&quot;, &quot;max_wal_size=2GB&quot;, &quot;-c&quot;, &quot;shared_buffers=512MB&quot;, &quot;-c&quot;, &quot;wal_compression=on&quot;]
    restart: always

volumes:
  model-cache:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;h6 id=&quot;section2&quot;&amp;gt;hwaccel.ml.yml&amp;lt;/h6&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Configurations for hardware-accelerated machine learning

# If using Unraid or another platform that doesn&apos;t allow multiple Compose files,
# you can inline the config for a backend by copying its contents
# into the immich-machine-learning service in the docker-compose.yml file.

# See https://immich.app/docs/features/ml-hardware-acceleration for info on usage.

services:
  armnn:
    devices:
      - /dev/mali0:/dev/mali0
    volumes:
      - /lib/firmware/mali_csffw.bin:/lib/firmware/mali_csffw.bin:ro # Mali firmware for your chipset (not always required depending on the driver)
      - /usr/lib/libmali.so:/usr/lib/libmali.so:ro # Mali driver for your chipset (always required)

  cpu: {}

  cuda:
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities:
                - gpu

  openvino:
    device_cgroup_rules:
      - &apos;c 189:* rmw&apos;
    devices:
      - /dev/dri:/dev/dri
    volumes:
      - /dev/bus/usb:/dev/bus/usb

  openvino-wsl:
    devices:
      - /dev/dri:/dev/dri
      - /dev/dxg:/dev/dxg
    volumes:
      - /dev/bus/usb:/dev/bus/usb
      - /usr/lib/wsl:/usr/lib/wsl
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;h6 id=&quot;section3&quot;&amp;gt;hwaccel.transcoding.yml&amp;lt;/h6&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Configurations for hardware-accelerated transcoding

# If using Unraid or another platform that doesn&apos;t allow multiple Compose files,
# you can inline the config for a backend by copying its contents
# into the immich-microservices service in the docker-compose.yml file.

# See https://immich.app/docs/features/hardware-transcoding for more info on using hardware transcoding.

services:
  cpu: {}

  nvenc:
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities:
                - gpu
                - compute
                - video

  quicksync:
    devices:
      - /dev/dri:/dev/dri

  rkmpp:
    security_opt: # enables full access to /sys and /proc, still far better than privileged: true
      - systempaths=unconfined
      - apparmor=unconfined
    group_add:
      - video
    devices:
      - /dev/rga:/dev/rga
      - /dev/dri:/dev/dri
      - /dev/dma_heap:/dev/dma_heap
      - /dev/mpp_service:/dev/mpp_service
      #- /dev/mali0:/dev/mali0 # only required to enable OpenCL-accelerated HDR -&amp;gt; SDR tonemapping
    volumes:
      #- /etc/OpenCL:/etc/OpenCL:ro # only required to enable OpenCL-accelerated HDR -&amp;gt; SDR tonemapping
      #- /usr/lib/aarch64-linux-gnu/libmali.so.1:/usr/lib/aarch64-linux-gnu/libmali.so.1:ro # only required to enable OpenCL-accelerated HDR -&amp;gt; SDR tonemapping

  vaapi:
    devices:
      - /dev/dri:/dev/dri

  vaapi-wsl: # use this for VAAPI if you&apos;re running Immich in WSL2
    devices:
      - /dev/dri:/dev/dri
    volumes:
      - /usr/lib/wsl:/usr/lib/wsl
    environment:
      - LD_LIBRARY_PATH=/usr/lib/wsl/lib
      - LIBVA_DRIVER_NAME=d3d12
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;h6 id=&quot;section4&quot;&amp;gt;.env&amp;lt;/h6&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# You can find documentation for all the supported env variables at https://immich.app/docs/install/environment-variables

# The location where your uploaded files are stored
UPLOAD_LOCATION=/AppData/immich/library
# The location where your database files are stored
DB_DATA_LOCATION=/AppData/immich/postgres

# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
# TZ=Etc/UTC

# The Immich version to use. You can pin this to a specific version like &quot;v1.71.0&quot;
IMMICH_VERSION=release

# Connection secret for postgres. You should change it to a random password
# Please use only the characters `A-Za-z0-9`, without special characters or spaces
DB_PASSWORD=postgres

# The values below this line do not need to be changed
###################################################################################
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;p&gt;通过查看日志发现了问题：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;                             RuntimeError:
                             /onnxruntime_src/onnxruntime/core/providers/cuda/cu
                             da_call.cc:123 std::conditional_t&amp;lt;THRW, void,
                             onnxruntime::common::Status&amp;gt;
                             onnxruntime::CudaCall(ERRTYPE, const char*, const
                             char*, ERRTYPE, const char*, const char*, int)
                             [with ERRTYPE = cudaError; bool THRW = true;
                             std::conditional_t&amp;lt;THRW, void, common::Status&amp;gt; =
                             void]
                             /onnxruntime_src/onnxruntime/core/providers/cuda/cu
                             da_call.cc:116 std::conditional_t&amp;lt;THRW, void,
                             onnxruntime::common::Status&amp;gt;
                             onnxruntime::CudaCall(ERRTYPE, const char*, const
                             char*, ERRTYPE, const char*, const char*, int)
                             [with ERRTYPE = cudaError; bool THRW = true;
                             std::conditional_t&amp;lt;THRW, void, common::Status&amp;gt; =
                             void] CUDA failure 100: no CUDA-capable device is
                             detected ; GPU=30355 ; hostname=f0cdef844009 ;
                             file=/onnxruntime_src/onnxruntime/core/providers/cu
                             da/cuda_execution_provider.cc ; line=280 ;
                             expr=cudaSetDevice(info_.device_id);



                             The above exception was the direct cause of the
                             following exception:

                             ╭─────── Traceback (most recent call last) ───────╮
                             │ /usr/src/app/main.py:152 in predict             │
                             │                                                 │
                             │   149 │   │   inputs = text                     │
                             │   150 │   else:                                 │
                             │   151 │   │   raise HTTPException(400, &quot;Either  │
                             │ ❱ 152 │   response = await run_inference(inputs │
                             │   153 │   return ORJSONResponse(response)       │
                             │   154                                           │
                             │   155                                           │
                             │                                                 │
                             │ /usr/src/app/main.py:175 in run_inference       │
                             │                                                 │
                             │   172 │   │   response[entry[&quot;task&quot;]] = output  │
                             │   173 │                                         │
                             │   174 │   without_deps, with_deps = entries     │
                             │ ❱ 175 │   await asyncio.gather(*[_run_inference │
                             │   176 │   if with_deps:                         │
                             │   177 │   │   await asyncio.gather(*[_run_infer │
                             │   178 │   if isinstance(payload, Image):        │
                             │                                                 │
                             │ /usr/src/app/main.py:169 in _run_inference      │
                             │                                                 │
                             │   166 │   │   │   except KeyError:              │
                             │   167 │   │   │   │   message = f&quot;Task {entry[&apos; │
                             │       output of {dep}&quot;                          │
                             │   168 │   │   │   │   raise HTTPException(400,  │
                             │ ❱ 169 │   │   model = await load(model)         │
                             │   170 │   │   output = await run(model.predict, │
                             │   171 │   │   outputs[model.identity] = output  │
                             │   172 │   │   response[entry[&quot;task&quot;]] = output  │
                             │                                                 │
                             │ /usr/src/app/main.py:213 in load                │
                             │                                                 │
                             │   210 │   │   return model                      │
                             │   211 │                                         │
                             │   212 │   try:                                  │
                             │ ❱ 213 │   │   return await run(_load, model)    │
                             │   214 │   except (OSError, InvalidProtobuf, Bad │
                             │   215 │   │   log.warning(f&quot;Failed to load {mod │
                             │       &apos;{model.model_name}&apos;. Clearing cache.&quot;)   │
                             │   216 │   │   model.clear_cache()               │
                             │                                                 │
                             │ /usr/src/app/main.py:188 in run                 │
                             │                                                 │
                             │   185 │   if thread_pool is None:               │
                             │   186 │   │   return func(*args, **kwargs)      │
                             │   187 │   partial_func = partial(func, *args, * │
                             │ ❱ 188 │   return await asyncio.get_running_loop │
                             │   189                                           │
                             │   190                                           │
                             │   191 async def load(model: InferenceModel) -&amp;gt;  │
                             │                                                 │
                             │ /usr/local/lib/python3.11/concurrent/futures/th │
                             │ read.py:58 in run                               │
                             │                                                 │
                             │ /usr/src/app/main.py:200 in _load               │
                             │                                                 │
                             │   197 │   │   │   raise HTTPException(500, f&quot;Fa │
                             │   198 │   │   with lock:                        │
                             │   199 │   │   │   try:                          │
                             │ ❱ 200 │   │   │   │   model.load()              │
                             │   201 │   │   │   except FileNotFoundError as e │
                             │   202 │   │   │   │   if model.model_format ==  │
                             │   203 │   │   │   │   │   raise e               │
                             │                                                 │
                             │ /usr/src/app/models/base.py:53 in load          │
                             │                                                 │
                             │    50 │   │   self.download()                   │
                             │    51 │   │   attempt = f&quot;Attempt #{self.load_a │
                             │       else &quot;Loading&quot;                            │
                             │    52 │   │   log.info(f&quot;{attempt} {self.model_ │
                             │       &apos;{self.model_name}&apos; to memory&quot;)           │
                             │ ❱  53 │   │   self.session = self._load()       │
                             │    54 │   │   self.loaded = True                │
                             │    55 │                                         │
                             │    56 │   def predict(self, *inputs: Any, **mod │
                             │                                                 │
                             │ /usr/src/app/models/clip/visual.py:62 in _load  │
                             │                                                 │
                             │   59 │   │   self.mean = np.array(self.preproce │
                             │   60 │   │   self.std = np.array(self.preproces │
                             │   61 │   │                                      │
                             │ ❱ 62 │   │   return super()._load()             │
                             │   63 │                                          │
                             │   64 │   def transform(self, image: Image.Image │
                             │   65 │   │   image = resize_pil(image, self.siz │
                             │                                                 │
                             │ /usr/src/app/models/base.py:79 in _load         │
                             │                                                 │
                             │    76 │   │   )                                 │
                             │    77 │                                         │
                             │    78 │   def _load(self) -&amp;gt; ModelSession:      │
                             │ ❱  79 │   │   return self._make_session(self.mo │
                             │    80 │                                         │
                             │    81 │   def clear_cache(self) -&amp;gt; None:        │
                             │    82 │   │   if not self.cache_dir.exists():   │
                             │                                                 │
                             │ /usr/src/app/models/base.py:111 in              │
                             │ _make_session                                   │
                             │                                                 │
                             │   108 │   │   │   case &quot;.armnn&quot;:                │
                             │   109 │   │   │   │   session: ModelSession = A │
                             │   110 │   │   │   case &quot;.onnx&quot;:                 │
                             │ ❱ 111 │   │   │   │   session = OrtSession(mode │
                             │   112 │   │   │   case _:                       │
                             │   113 │   │   │   │   raise ValueError(f&quot;Unsupp │
                             │   114 │   │   return session                    │
                             │                                                 │
                             │ /usr/src/app/sessions/ort.py:28 in __init__     │
                             │                                                 │
                             │    25 │   │   self.providers = providers if pro │
                             │    26 │   │   self.provider_options = provider_ │
                             │       self._provider_options_default            │
                             │    27 │   │   self.sess_options = sess_options  │
                             │       self._sess_options_default                │
                             │ ❱  28 │   │   self.session = ort.InferenceSessi │
                             │    29 │   │   │   self.model_path.as_posix(),   │
                             │    30 │   │   │   providers=self.providers,     │
                             │    31 │   │   │   provider_options=self.provide │
                             │                                                 │
                             │ /opt/venv/lib/python3.11/site-packages/onnxrunt │
                             │ ime/capi/onnxruntime_inference_collection.py:43 │
                             │ 2 in __init__                                   │
                             │                                                 │
                             │    429 │   │   │   │   │   self.disable_fallbac │
                             │    430 │   │   │   │   │   return               │
                             │    431 │   │   │   │   except Exception as fall │
                             │ ❱  432 │   │   │   │   │   raise fallback_error │
                             │    433 │   │   │   # Fallback is disabled. Rais │
                             │    434 │   │   │   raise e                      │
                             │    435                                          │
                             │                                                 │
                             │ /opt/venv/lib/python3.11/site-packages/onnxrunt │
                             │ ime/capi/onnxruntime_inference_collection.py:42 │
                             │ 7 in __init__                                   │
                             │                                                 │
                             │    424 │   │   │   │   │   print(f&quot;EP Error {e} │
                             │    425 │   │   │   │   │   print(f&quot;Falling back │
                             │    426 │   │   │   │   │   print(&quot;************* │
                             │ ❱  427 │   │   │   │   │   self._create_inferen │
                             │    428 │   │   │   │   │   # Fallback only once │
                             │    429 │   │   │   │   │   self.disable_fallbac │
                             │    430 │   │   │   │   │   return               │
                             │                                                 │
                             │ /opt/venv/lib/python3.11/site-packages/onnxrunt │
                             │ ime/capi/onnxruntime_inference_collection.py:48 │
                             │ 3 in _create_inference_session                  │
                             │                                                 │
                             │    480 │   │   │   disabled_optimizers = set(di │
                             │    481 │   │                                    │
                             │    482 │   │   # initialize the C++ InferenceSe │
                             │ ❱  483 │   │   sess.initialize_session(provider │
                             │    484 │   │                                    │
                             │    485 │   │   self._sess = sess                │
                             │    486 │   │   self._sess_options = self._sess. │
                             ╰─────────────────────────────────────────────────╯
                             RuntimeError:
                             /onnxruntime_src/onnxruntime/core/providers/cuda/cu
                             da_call.cc:123 std::conditional_t&amp;lt;THRW, void,
                             onnxruntime::common::Status&amp;gt;
                             onnxruntime::CudaCall(ERRTYPE, const char*, const
                             char*, ERRTYPE, const char*, const char*, int)
                             [with ERRTYPE = cudaError; bool THRW = true;
                             std::conditional_t&amp;lt;THRW, void, common::Status&amp;gt; =
                             void]
                             /onnxruntime_src/onnxruntime/core/providers/cuda/cu
                             da_call.cc:116 std::conditional_t&amp;lt;THRW, void,
                             onnxruntime::common::Status&amp;gt;
                             onnxruntime::CudaCall(ERRTYPE, const char*, const
                             char*, ERRTYPE, const char*, const char*, int)
                             [with ERRTYPE = cudaError; bool THRW = true;
                             std::conditional_t&amp;lt;THRW, void, common::Status&amp;gt; =
                             void] CUDA failure 100: no CUDA-capable device is
                             detected ; GPU=30355 ; hostname=f0cdef844009 ;
                             file=/onnxruntime_src/onnxruntime/core/providers/cu
                             da/cuda_execution_provider.cc ; line=280 ;
                             expr=cudaSetDevice(info_.device_id);


[08/18/24 10:37:48] INFO     Shutting down due to inactivity.
[08/18/24 10:37:48] INFO     Shutting down
[08/18/24 10:37:48] INFO     Waiting for application shutdown.
[08/18/24 10:37:49] INFO     Application shutdown complete.
[08/18/24 10:37:49] INFO     Finished server process [51638]
[08/18/24 10:37:49] ERROR    Worker (pid:51638) was sent SIGINT!
[08/18/24 10:37:49] INFO     Booting worker with pid: 56010
[08/18/24 10:37:53] INFO     Started server process [56010]
[08/18/24 10:37:53] INFO     Waiting for application startup.
[08/18/24 10:37:53] INFO     Created in-memory cache with unloading after 300s
                             of inactivity.
[08/18/24 10:37:53] INFO     Initialized request thread pool with 16 threads.
[08/18/24 10:37:53] INFO     Application startup complete.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;根据报错可以发现：没有支持CUDA的设备，即容器的GPU支持配置有误&lt;br /&gt;
因此修改配置文件：&lt;/p&gt;
&lt;p&gt;&amp;lt;h6 id=&quot;section1&quot;&amp;gt;docker-compose.yml&amp;lt;/h6&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Configurations for hardware-accelerated transcoding

# If using Unraid or another platform that doesn&apos;t allow multiple Compose files,
# you can inline the config for a backend by copying its contents
# into the immich-microservices service in the docker-compose.yml file.

# See https://immich.app/docs/features/hardware-transcoding for more info on using hardware transcoding.

services:
  cpu: {}

  nvenc:
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities:
                - gpu
                - compute
                - video

  quicksync:
    devices:
      - /dev/dri:/dev/dri

  rkmpp:
    security_opt: # enables full access to /sys and /proc, still far better than privileged: true
      - systempaths=unconfined
      - apparmor=unconfined
    group_add:
      - video
    devices:
      - /dev/rga:/dev/rga
      - /dev/dri:/dev/dri
      - /dev/dma_heap:/dev/dma_heap
      - /dev/mpp_service:/dev/mpp_service
      #- /dev/mali0:/dev/mali0 # only required to enable OpenCL-accelerated HDR -&amp;gt; SDR tonemapping
    volumes:
      #- /etc/OpenCL:/etc/OpenCL:ro # only required to enable OpenCL-accelerated HDR -&amp;gt; SDR tonemapping
      #- /usr/lib/aarch64-linux-gnu/libmali.so.1:/usr/lib/aarch64-linux-gnu/libmali.so.1:ro # only required to enable OpenCL-accelerated HDR -&amp;gt; SDR tonemapping

  vaapi:
    devices:
      - /dev/dri:/dev/dri

  vaapi-wsl: # use this for VAAPI if you&apos;re running Immich in WSL2
    devices:
      - /dev/dri:/dev/dri
    volumes:
      - /usr/lib/wsl:/usr/lib/wsl
    environment:
      - LD_LIBRARY_PATH=/usr/lib/wsl/lib
      - LIBVA_DRIVER_NAME=d3d12
root@ai-p100:/AppData/immich/immich-app# cat .env
# You can find documentation for all the supported env variables at https://immich.app/docs/install/environment-variables

# The location where your uploaded files are stored
UPLOAD_LOCATION=/AppData/immich/library
# The location where your database files are stored
DB_DATA_LOCATION=/AppData/immich/postgres

# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
# TZ=Etc/UTC

# The Immich version to use. You can pin this to a specific version like &quot;v1.71.0&quot;
IMMICH_VERSION=release

# Connection secret for postgres. You should change it to a random password
# Please use only the characters `A-Za-z0-9`, without special characters or spaces
DB_PASSWORD=postgres

# The values below this line do not need to be changed
###################################################################################
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
root@ai-p100:/AppData/immich/immich-app# cat docker-compose.yml
name: immich

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    extends:
      file: hwaccel.transcoding.yml
      service: nvenc
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - .env
    ports:
      - 2283:3001
    depends_on:
      - redis
      - database
    restart: always
    healthcheck:
      disable: false
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu, compute, video]

  immich-machine-learning:
    container_name: immich_machine_learning
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-cuda
    extends:
      file: hwaccel.ml.yml
      service: cuda
    volumes:
      - model-cache:/cache
    env_file:
      - .env
    restart: always
    healthcheck:
      disable: false
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

  redis:
    container_name: immich_redis
    image: docker.io/redis:6.2-alpine@sha256:e3b17ba9479deec4b7d1eeec1548a253acc5374d68d3b27937fcfe4df8d18c7e
    healthcheck:
      test: redis-cli ping || exit 1
    restart: always

  database:
    container_name: immich_postgres
    image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: &apos;--data-checksums&apos;
    volumes:
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    healthcheck:
      test: pg_isready --dbname=&apos;${DB_DATABASE_NAME}&apos; --username=&apos;${DB_USERNAME}&apos; || exit 1; Chksum=&quot;$$(psql --dbname=&apos;${DB_DATABASE_NAME}&apos; --username=&apos;${DB_USERNAME}&apos; --tuples-only --no-align --command=&apos;SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database&apos;)&quot;; echo &quot;checksum failure count is $$Chksum&quot;; [ &quot;$$Chksum&quot; = &apos;0&apos; ] || exit 1
      interval: 5m
      start_interval: 30s
      start_period: 5m
    command: [&quot;postgres&quot;, &quot;-c&quot;, &quot;shared_preload_libraries=vectors.so&quot;, &quot;-c&quot;, &apos;search_path=&quot;$$user&quot;, public, vectors&apos;, &quot;-c&quot;, &quot;logging_collector=on&quot;, &quot;-c&quot;, &quot;max_wal_size=2GB&quot;, &quot;-c&quot;, &quot;shared_buffers=512MB&quot;, &quot;-c&quot;, &quot;wal_compression=on&quot;]
    restart: always

volumes:
  model-cache:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中区别就是：添加了以下字段：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;具体配置&lt;/h3&gt;
&lt;p&gt;首先是照片上传，移动端几乎全平台支持，直接下载App然后授权访问相册就可以了&lt;br /&gt;
PC稍微麻烦些，需要安装node.js后安装immich-cli，具体请查阅文档&lt;br /&gt;
immich-cli需要node.js版本在20.0以上，所以如果发行版的软件源较为老旧，请换更新的&lt;code&gt;nodesource&lt;/code&gt;源&lt;/p&gt;
&lt;p&gt;然后是备份，不要直接备份数据库目录，具体的先挖个坑，暂时懒得写QwQ&lt;/p&gt;
</content:encoded></item><item><title>幸福的良定义</title><link>https://fuwari.vercel.app/posts/%E5%B9%B8%E7%A6%8F%E7%9A%84%E8%89%AF%E5%AE%9A%E4%B9%89/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E5%B9%B8%E7%A6%8F%E7%9A%84%E8%89%AF%E5%AE%9A%E4%B9%89/</guid><pubDate>Sun, 02 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;引言&lt;/h3&gt;
&lt;p&gt;在中国，主流价值观通常引导着人们按照一种固定的轨迹生活：上学、上班、结婚生子、养家糊口、颐养天年，还得帮孩子带孙子。这种按部就班的生活模式已经深深植根于我们的文化中，被视为成功和幸福的标志。然而，幸福的定义是否真的如此单一？被指配的幸福是不是我们真正需要的幸福？&lt;/p&gt;
&lt;h3&gt;按部就班的生活方式&lt;/h3&gt;
&lt;p&gt;从小，我们就被灌输了“努力读书考好成绩，上好的大学，找一份稳定的工作，然后结婚生子，抚养孩子直至退休”的生活方式是通往幸福的唯一道路。你我之中许多人也在为了成为“别人家的孩子”而努力。然而，这种模式真的适合每个人吗？又有许多人在这个过程中迷失了自己。直到年老体衰，发起一句感叹：“这辈子都白活了！”对于一些人来说，这种生活方式可能是一种束缚，而非实现自我价值的途径。&lt;/p&gt;
&lt;h3&gt;按部就班生活方式的负面影响&lt;/h3&gt;
&lt;p&gt;近年来，学生自杀率急剧上升，已成为普遍现象，有的高级中学甚至设置了惊人的“5%-10%”的自杀指标。学生在巨大的学业压力下，选择结束自己的生命，这是按部就班生活方式带来的严重后果之一。&lt;/p&gt;
&lt;p&gt;此外，许多年轻人虽然找到了工作，但却背负着沉重的债务，成为了所谓的“负债打工族”。这些人即使工资全部收入仍不足以覆盖在大城市的房租、水电、吃穿用度等基本开销。他们自嘲自己的生活，感到迷茫和无力改变。&lt;/p&gt;
&lt;p&gt;通过数据和分析可以进一步证明大城市打工者在某些情况下最后结余可能是负数的观点：&lt;a href=&quot;%5Bhttps://www.thepaper.cn/newsDetail_forward_18759533%5D(https://www.thepaper.cn/newsDetail_forward_18759533)&quot;&gt;1&lt;/a&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;消费支出与可支配收入的对比&lt;/strong&gt;：北京和上海的生活成本居全国之首，虽然这两个城市的居民可支配收入也相对较高，但高昂的生活成本可能会消耗掉大部分收入。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;人均存款与生活成本&lt;/strong&gt;：北京人均存款超过20万元，上海超过17万元。然而，如果考虑房贷等大额支出，这些存款可能不足以支撑一年的生活费用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;最低工资与消费水平&lt;/strong&gt;：通过计算最低工资与平均消费水平的对比，展示了如果只赚最低工资，在大城市生活可能会非常困难。例如，如果只赚最低工资，上海打工人可能是最需要节衣缩食的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;住房开支&lt;/strong&gt;：北京和上海的住房平均开支每年大约1.5万元，月租1000-1500元可能需要与他人合租，这对于收入较低的打工者来说是一个重大的开支。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特殊情况下的财务压力&lt;/strong&gt;：如果遇到突发状况，如失业或收入大幅减少，打工者的积蓄可能不足以支撑他们的生活，导致结余为负。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;不仅如此，城市中的留守老人问题也日益严重。许多老人在完成了养育子女的责任后，长期无法见到自己的子女，还需要帮忙带孙子，压抑的情绪蔓延到孙辈，造成了代际间的情感隔阂和精神压力。这些具体示例表明，按部就班的生活方式并非总能带来幸福，反而可能导致诸多问题。&lt;/p&gt;
&lt;p&gt;按部就班生活的终点也未必如人们所描绘的那般美好。近年来，中国互联网行业受到了多方面因素的影响，导致就业市场的降温和技术工人面临更大的挑战。除了监管力度的加大，后疫情时代的高杠杆问题也加剧了市场的不景气。许多互联网公司对员工上网行为的监控愈发严格，通过硬件、软件和网络构成的闭环来维护公司的安全和效率，这使得员工的隐私被大幅度侵蚀，工作压力也随之增加。在这种高压环境下，许多互联网从业者，尤其是95后，选择离开这些大厂，原因有的是攒够钱，但更多的是由于公司侵犯人权，要求员工“承认”自己没有做过的侵犯公司利益的事情，从而实现无责解雇甚至倒追回工资。996工作制带来的巨大压力也是促使员工选择离职的一个重要因素。&lt;a href=&quot;%5Bhttps://www.thepaper.cn/newsDetail_forward_10995061%5D(https://www.thepaper.cn/newsDetail_forward_10995061)&quot;&gt;2&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;原生家庭的影响&lt;/h3&gt;
&lt;p&gt;原生家庭在一个人的成长过程中起着至关重要的作用。家庭给予的自由度和思维灵活度，对一个人未来的发展有着深远的影响。控制欲强的家庭往往会剥夺孩子的自主性，导致他们在成年后缺乏独立思考和决策的能力。这样的家庭悲剧案例屡见不鲜，孩子被迫按照父母的意愿生活，最终失去了自我，甚至酿成悲剧。例如：&lt;a href=&quot;%5Bhttps://www.thepaper.cn/newsDetail_forward_1665530%5D(https://www.thepaper.cn/newsDetail_forward_1665530)&quot;&gt;4&lt;/a&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;李鑫的故事&lt;/strong&gt;：2017年2月23日，16岁的大连女孩李鑫留下一封信后离家出走，直接原因是父亲频繁催促她做作业。她最终登上南下的列车，到达广州，打算找份工作。18天后，她的父亲李国连在广州找到了她。李国连表示，最大的遗憾是与女儿沟通太少。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;秦杰的经历&lt;/strong&gt;：13岁的青海少年秦杰因为家人管得太严，第一次离家出走。他曾多次离家，最长一次离家一年。2012年高考后，他再次离家，此后没有再回家。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;蒋超的遭遇&lt;/strong&gt;：安徽的蒋超因为童年时期父亲的长期打骂，形成了内向自卑的性格。15岁时，他离家出走，前往安徽铜陵，半年后被父亲找回。大三时，蒋超辍学，之后在多个城市工作，很少回家。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;相反，那些能够继承父辈资源并发扬自己兴趣的孩子，通常能在自由和信任的环境中成长，实现自我价值和家庭的共同进步。我们需要反思，是否应当给予孩子更多的自由和信任，让他们有机会按照自己的意愿去探索和成长。&lt;/p&gt;
&lt;h3&gt;未来趋势与AI影响&lt;/h3&gt;
&lt;p&gt;随着人工智能（AI）技术的迅速发展，许多传统的工作和生活方式变得不再必要。AI可以帮助人们在30天内速成一项技能，完成具体任务，释放了大量的时间和精力。这意味着，我们不再需要按照过去那种按部就班的方式生活，可以有更多的选择去追求自己的兴趣和梦想。&lt;/p&gt;
&lt;p&gt;单一领域精通的人才已经饱和，而跨领域结合的人才仍有空缺。这种转变呼唤我们重新思考生活和工作的意义，不再局限于传统的职业路径，而是寻找更多元化的发展方向和自我实现的途径。&lt;/p&gt;
&lt;h3&gt;重新定义幸福&lt;/h3&gt;
&lt;p&gt;我们需要重新定义幸福。根据马斯洛需求层次理论，人在满足基本的生理和安全需求后，会追求更高层次的归属感、尊重和自我实现。幸福并不是一种被指配的状态，而是一种由自己定义和追求的目标。每个人都有权利根据自己的兴趣和价值观去定义幸福，并在不能重来的人生中勇敢追寻。&lt;/p&gt;
&lt;p&gt;自我价值的实现和精神生活的满足，正变得越来越重要。我们需要鼓励自己和他人去探索内心的真实需求，追求那些能够带来真正满足的目标，而不仅仅是遵循社会的期望和传统的轨迹。&lt;/p&gt;
&lt;h3&gt;结论&lt;/h3&gt;
&lt;p&gt;按部就班的生活并非唯一的选择，幸福需要由自己定义。学生自杀、自嘲型负债打工族、城市留守老人等具体示例，揭示了传统生活方式的诸多弊端。原生家庭的束缚，未来AI的发展，都在呼唤我们重新思考自己的生活方式。我们需要勇敢追寻自己的幸福，定义自己的生活，实现自我价值，过上真正属于自己的幸福生活。&lt;/p&gt;
&lt;p&gt;不过第一步，就从给幸福一个良定义做起吧。&lt;/p&gt;
&lt;h4&gt;参考文献&lt;/h4&gt;
</content:encoded></item><item><title>简记一次输入法安装</title><link>https://fuwari.vercel.app/posts/%E7%AE%80%E8%AE%B0%E4%B8%80%E6%AC%A1%E8%BE%93%E5%85%A5%E6%B3%95%E5%AE%89%E8%A3%85/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E7%AE%80%E8%AE%B0%E4%B8%80%E6%AC%A1%E8%BE%93%E5%85%A5%E6%B3%95%E5%AE%89%E8%A3%85/</guid><pubDate>Wed, 29 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;刚刚折腾了一下Linux下安装中文输入法的事情，特此记录一下遇到的小问题和解决方案。&lt;/p&gt;
&lt;h3&gt;操作系统信息&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sunnypai@localhost:~&amp;gt; screenfetch
sunnypai@localhost.localdomain
OS: openSUSE 20240523
Kernel: x86_64 Linux 6.9.1-1-default
Uptime: 1h 27m
Packages: 2238
Shell: bash 5.2.26
Resolution: 2240x1400
DE: KDE
WM: KWin
GTK Theme: Breeze-Dark [GTK2], Breeze [GTK3]
Icon Theme: breeze-dark
Disk: 138G / 2.7T (6%)
CPU: Genuine Intel 0000 @ 12x 4.6GHz [35.0°C]
GPU: Mesa Intel(R) Graphics (ADL GT2)
RAM: 4719MiB / 15716MiB
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;安装方式&lt;/h3&gt;
&lt;p&gt;YaST2 搜索fcitx5，取消选择 systemd-inputmethod-generator，自动安装&lt;/p&gt;
&lt;h3&gt;遇到的问题&lt;/h3&gt;
&lt;p&gt;系统设置里找不到输入法选项，在配置页面里选择的 &quot;Keyboard - Chinese&quot; Layout 无法工作。&lt;br /&gt;
&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/%E7%AE%80%E8%AE%B0%E4%B8%80%E6%AC%A1%E8%BE%93%E5%85%A5%E6%B3%95%E5%AE%89%E8%A3%8501.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;解决方案&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://assets.blog.edge.sunnypai.top/%E7%AE%80%E8%AE%B0%E4%B8%80%E6%AC%A1%E8%BE%93%E5%85%A5%E6%B3%95%E5%AE%89%E8%A3%8502.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;搜索输入法前取消选中 &quot;Only Show Current Language&quot;，之后搜索并添加Pinyin&lt;br /&gt;
随后重启框架&lt;/p&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;该问题只会出现在语言设置为非中文并需要安装中文输入法时
猜测在使用简体中文系统语言时试图安装非中文输入法也会有类似问题&lt;/p&gt;
</content:encoded></item><item><title>简记一次扫盘经历</title><link>https://fuwari.vercel.app/posts/%E7%AE%80%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%89%AB%E7%9B%98%E7%BB%8F%E5%8E%86/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E7%AE%80%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%89%AB%E7%9B%98%E7%BB%8F%E5%8E%86/</guid><pubDate>Wed, 06 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;简记一次新装SATA机械盘并使用Linux扫盘
A simple note on installing a SATA hard drive and using Linux to check the health statements&lt;/p&gt;
&lt;h3&gt;安装硬盘&lt;/h3&gt;
&lt;h4&gt;Install hard drive&lt;/h4&gt;
&lt;p&gt;硬盘是安装在我的&lt;code&gt;RD452X&lt;/code&gt;机架服务器上的。前面板有12个盘位，使用SFF8643转$4 \times SATA$线缆连接主板至硬盘背板。
The HDD disk is installed on my &lt;code&gt;RD452X&lt;/code&gt; rack server. There are 12 disk bays on the front panel, using an SFF8643 to $4 \times SATA$ cable that connects the motherboard to the backplane.&lt;/p&gt;
&lt;p&gt;随后，发现上电后无法开机，尝试将背板断电并移除数据线缆、重新插拔PCIe设备和内存条，均无法开机，主板指示灯正常。
After powering up, the device failed to turn on. Despite attempts to power down the backplane, remove data cables, and re-plug PCIe devices and memory sticks, the device remained unresponsive. The motherboard indicator lights appeared normal.&lt;/p&gt;
&lt;p&gt;使用RJ45线缆连接Management口和路由器以太网口、在DHCP客户端中查询到地址后，使用另一台计算机成功连接到BMC，并使用带外管理成功启动服务器。初步诊断原因为插拔转接线缆时由于&lt;strong&gt;用力过大&lt;/strong&gt;，导致前面板的线缆接口松脱。
After connecting the Management port and Ethernet port of the router with an RJ45 cable and querying the address in the DHCP client, another computer successfully connected to the BMC. The server was then successfully started using out-of-band management. The initial diagnosis suggests that the cable connector on the front panel became loose due to &lt;strong&gt;excessive force&lt;/strong&gt; when plugging and unplugging the adapter cable.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;教训：暴力无法解决问题，大力导致的不会是奇迹。
Lesson: Violence does not solve problems, and what is achieved by violence will not be miraculous.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;安装ddrescue&lt;/h3&gt;
&lt;h4&gt;Install ddrescue&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;dnf install epel-release
dnf install ddrescue
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;扫盘&lt;/h3&gt;
&lt;h4&gt;Scan the disks&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@Backup ~]# lsblk
NAME               MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sda                  8:0    0  7.5G  0 disk
├─sda1               8:1    0  600M  0 part /boot/efi
├─sda2               8:2    0    1G  0 part /boot
└─sda3               8:3    0  5.9G  0 part
  ├─almalinux-root 253:0    0  5.1G  0 lvm  /
  └─almalinux-swap 253:1    0  764M  0 lvm  [SWAP]
sdb                  8:16   0 10.9T  0 disk
sdc                  8:32   0 10.9T  0 disk
sdd                  8:48   0 10.9T  0 disk
sde                  8:64   0 10.9T  0 disk
[root@Backup ~]# ddrescue -n -f /dev/sdb /dev/null rescueb.log
GNU ddrescue 1.28
Press Ctrl-C to interrupt
Initial status (read from mapfile)
rescued: 133194 MB, tried: 0 B, bad-sector: 0 B, bad areas: 0

Current status
     ipos:  137872 MB, non-trimmed:        0 B,  current rate:    250 MB/s
     opos:  137872 MB, non-scraped:        0 B,  average rate:    311 MB/s
non-tried:   11862 GB,  bad-sector:        0 B,    error rate:       0 B/s
  rescued:  137872 MB,   bad areas:        0,        run time:         15s
pct rescued:    1.14%, read errors:        0,  remaining time:     10h 33m
                              time since last successful read:          0s
Copying non-tried blocks... Pass 1 (forwards)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上两条命令分别为列出硬盘和扫描硬盘，同时扫描多个硬盘，可以新建多个终端，重复使用ddrescue命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ddrescue -n -f /dev/sdc /dev/null rescuec.log
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ddrescue -n -f /dev/sdd /dev/null rescued.log
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ddrescue -n -f /dev/sde /dev/null rescuee.log
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h3&gt;阵列卡配置&lt;/h3&gt;
&lt;p&gt;我的阵列卡是&lt;code&gt;9260-8i&lt;/code&gt;，管理工具下载地址如下：
My raid card is &lt;code&gt;9260-8i&lt;/code&gt;. The download address of the management tool is:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;ftp://tsupport:tsupport@ftp0.broadcom.com/private/MegaRAID/downloads/8.00-05_Linux_MSM.zip&quot;&gt;&lt;s&gt;ftp://tsupport:tsupport@ftp0.broadcom.com/private/MegaRAID/downloads/8.00-05_Linux_MSM.zip&lt;/s&gt;&lt;/a&gt;
&lt;a href=&quot;ftp://tsupport:tsupport@ftp0.broadcom.com/private/MegaRAID/downloads/8.00-05_Windows_MSM.zip&quot;&gt;ftp://tsupport:tsupport@ftp0.broadcom.com/private/MegaRAID/downloads/8.00-05_Windows_MSM.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Linux版&lt;strong&gt;除了红帽和Debian&lt;/strong&gt;系的太&lt;strong&gt;难用了，新手建议使用WinToGo装Windows版
For newcomers, it is recommended to use the Windows version installed with WinToGo, as the Linux version, as well as the &lt;strong&gt;Red Hat or Debian&lt;/strong&gt; systems, may be F&lt;/strong&gt;king difficult to use.&lt;/p&gt;
&lt;p&gt;下载网页是：
Here&apos;s the website of the download page:
&lt;a href=&quot;https://www.broadcom.com/support/knowledgebase/1211161491782/megaraid-sas-9260-4i---9260-8i---9260de-8i---9261-8i-downloads&quot;&gt;https://www.broadcom.com/support/knowledgebase/1211161491782/megaraid-sas-9260-4i---9260-8i---9260de-8i---9261-8i-downloads&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;具体配置请自行搜索，也可以无脑点下一步
Please search for specific configurations or follow the next step in the software.&lt;/p&gt;
&lt;p&gt;Last updated on Mar. 6th, 2024
SunnyPai&lt;/p&gt;
</content:encoded></item><item><title>从风暴看圈子</title><link>https://fuwari.vercel.app/posts/%E4%BB%8E%E9%A3%8E%E6%9A%B4%E7%9C%8B%E5%9C%88%E5%AD%90/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E4%BB%8E%E9%A3%8E%E6%9A%B4%E7%9C%8B%E5%9C%88%E5%AD%90/</guid><pubDate>Mon, 26 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在温带的一片森林中，冷暖锋相对峙着。一只路过的小蝴蝶扇了扇翅膀，冷锋和暖锋开始向彼此延伸、交融、碰撞，慢慢的，便形成了气旋。气旋越转越快、越来越多的气流加入，一场暴风雨逐渐酝酿。待狂风暴雨后、雨过天晴，只剩一片冷清和一地鸡毛。&lt;/p&gt;
&lt;p&gt;社会中的一个个小群体、小圈子和这个过程也无比类似：一群兴趣相投的人聚集在一起做喜欢的事，于是一个小圈子诞生了、并进入初生期；随着圈子不断发展，他们产生的信息吸引了更多的人，并为了更快捷地交流信息而制定了一系列规则；当圈子内部的规则逐渐成体系、很多老人甚至创始人被排挤出去，同时名声在外、真正爱好于此的人却很难参与其中时，圈子便进入了锢囚期；随着本不是这个爱好的圈外人前来蹭热度，名声败坏，导致爱好并愿意进圈的人越来越少，圈子就逐渐消亡在历史长河。&lt;/p&gt;
&lt;p&gt;然而，并非所有的圈子都会经历以上所有的阶段。很多小圈子，比如业余无线电、家庭服务器，它没有足够多的爱好者，于是不会形成过于复杂的规则、始终保持着开放、单纯的样子，坚守爱好交流的初心。直到未来的某一天，喜好的人越来越少，在大家的视线中绝迹。&lt;/p&gt;
&lt;p&gt;我们可以发现，能够走完以上四个阶段的圈子具有一些共同特点：热爱或潜在的爱好者人数众多、圈子的门槛极低。例如二次元、LGBT，外部的圈子几乎没有门槛，同时在多年发展后已经在某些国家和地区成为一种「现象级」，于是有很多本不爱好于此的人为了寻找畸形的认同感和自我价值，进入这些圈子，最终将圈子变成外人避而不及的乌烟瘴气的样子。&lt;/p&gt;
&lt;p&gt;而在市场经济下的社会，我们始终面临着一个逃不掉的话题——资本。它是社群生命周期的加速器：一方面，资本可以帮助一个小圈子快速发展为大社群；另一方面，当社群足够成熟后，资本的镰刀就会以一种「认同感的攀比」开始收割爱好者们的钱包。这让本无法被量化的归属感和认同感被赋予到现实的物品上，也变相降低了进入圈子的成本。例如二次元圈子的手办、LGBT圈子的徽标周边。资本开始收割也就标志着一个圈子踏入了锢囚期，随后几年内就会消亡。&lt;/p&gt;
&lt;p&gt;又如网络文学，它一开始应该是一群不愿意出版还想让自己的作品被别人看到的人组成的圈子。那时作者也是旧的读者，读者也是未来的作者。&lt;/p&gt;
&lt;p&gt;后来，随着喜欢的人越来越多，资本像闻到血腥味的鲨鱼一样，建起了一个个付费小说站。随着一次次“征文大赛”，少数人获得了上万甚至更多的收益，越来越多的作者开始选择付费平台出版。&lt;/p&gt;
&lt;p&gt;再后来，盗版小说、免费小说站层出不穷，越来越多喜欢白嫖、想消磨时间的人涌入免费小说平台，付费平台的市场占有率越来越低。而作者为了更高的产量而获得更多的收益，网络小说不再是一种文学，而是一种快餐化、标准化的娱乐模式。读者对作者进行谩骂、各分区之间的读者间口诛笔伐。&lt;/p&gt;
&lt;p&gt;它确实被大多数人接受了，不过资本也让它做了一个「接受或灭亡」的选择题。付费站让更多的作者选择资本，而带广告的免费站又让资本两头剥削作者和读者。&lt;/p&gt;
&lt;p&gt;当然，也有些圈子会一天兴起、一夜消亡：比如几年前一天内兴起的显卡挖矿因为一纸禁令短时间内销声匿迹，又如由于政策变更而做不下去的LT（高频量化交易）私募基金。&lt;/p&gt;
&lt;p&gt;那么，我们应该停下来，仔细思考一下：我们应该如何参与到一个社群中？&lt;/p&gt;
&lt;p&gt;有一句话说的很好：月薪一千万和月薪一千块的人，他们的一天都只有24小时。那是什么导致他们的收入天差地别呢？是认知、是眼界，也是掌握的信息。月薪千万的老板，他们会用钱换时间，将一些工作外包给其他人，而月薪几千的人只会思考柴米油盐、思考如何用时间省钱。&lt;/p&gt;
&lt;p&gt;而社群，则可以为我们提供高效、便捷的信息交换渠道，不断地依靠着见到形形色色的人而提升眼界。但我们参与的社群是越多越好吗？&lt;/p&gt;
&lt;p&gt;答案自然是否定的。这里我要借鉴一本名为《变成萝莉不想被发现只好当刺客了》的小说（下称《萝莉刺客》）内的一个概念：&lt;/p&gt;
&lt;p&gt;每个人都有一定的灯火，而信息有直接有效、间接有效、直接无效、间接无效四种，所消耗的「灯火」逐渐递减，但绝对不是等于零。直接有效是两个人面对面地交流，间接有效是阅读书籍、聆听音乐，直接无效是和别人吵架或者说着你听不懂的语言，间接无效则是一团看不懂、不明觉厉的乱码。&lt;/p&gt;
&lt;p&gt;《萝莉刺客》内的设定是：每个人传递信息都需要消耗「灯火」，当「灯火」耗尽，就会陷入永恒的休眠。类比现实，我认为「灯火」和人的精神能量很相似。每个人在接收或表述过多的信息后都会感到身心俱疲，长期处于身心俱疲的状态就会放弃思考，如同行尸走肉一样麻木的活着。&lt;/p&gt;
&lt;p&gt;我相信每个人都不想变成这个样子。短视频、贴吧中都是一些间接有效的信息，你不直接参与其中，但接收着他们的理念、仿佛感同身受但实则半懂不懂，却又发表着自己的「见解」、和别人争吵。量变引发质变，过多浅尝辄止的参与各式各样的圈子会损害一个人的认知。&lt;/p&gt;
&lt;p&gt;我们的确应该对每一种态度兼容并蓄，但这并不意味着每个圈子都应当见识一下。我们应该减少接收的信息总量。这不意味着信息的闭塞，而是在提升每次交流的信息质量，在某个圈子里沉思。沉思会给大家带来积淀，这是可以享用一生的财富。&lt;/p&gt;
&lt;p&gt;沉思是深入参与某个圈子后的必然产物，是学习和感悟的过程，但绝不意味着我们要尽己所能维护圈子的纯洁、让它生存下去。每个圈子或长或短，百年内必将消亡，而像一位为了维持一个她建立起的圈子的纯洁和新人的体验而选择以死明志、从高楼纵身一跃的故人，我们只会为此惋惜，但这并不能改变任何现实。圈子还会以它原本的样子继续发展下去，而她，并不是我们的英雄，只会留下一句「不值得」、「可惜了」的评价。&lt;/p&gt;
&lt;p&gt;社群是交流的地方、是学习的地方，借用刘慈欣的《三体》中的一句话：给岁月以文明，而非给文明以岁月。我们不必追求圈子的万古长存，而是在存在的时间内积淀自己、让它成为历史长河中绚烂的烟火。人生苦短，乘兴而去，待到某日，兴尽而返。&lt;/p&gt;
&lt;p&gt;当然我们很难评价一个行为、一次事件的对与错，就像资本参与进我们参与的圈子一样，它可能使得原本有几十年生命的圈子在几年内被大家弃如敝履，但也在几年内让我们体验到了原本不一定会有的繁盛一时。圈子是人的圈子、社会是人的社会。人不会和圈子绑定在一起，但圈子因为有了人，才被赋予了意义。我们很难评价深度参与一个圈子到底是能获得极大的收益，还是花费时间却收益寥寥。但，趁年轻，勇敢做！人生的起点和终点都是确定的，在其间的每一场经历，都是独属于自己的、最宝贵的财富。&lt;/p&gt;
&lt;p&gt;最近我对存在主义十分感兴趣。德国哲学家马丁·海德格尔对「此在的存在」有如下观点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;人之为存在，不是说机械地对外界环境作出反应，人首先在「行动」中，在其中他领会着存在。&lt;/li&gt;
&lt;li&gt;「此在」意味着「我的存在」，因此具有「我属」特征，但「我」不是孤立的主体，「在世界之中」是此在生存的先天法理。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;人的存在不仅仅是作为一个物理实体存在，而是在与世界的互动中存在。这让我想起了「人的三次死亡」这一观点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一次死亡：当一个人的心跳停止，呼吸消逝，他在生物学上被宣告死亡。&lt;/li&gt;
&lt;li&gt;第二次死亡：当一个人下葬，人们穿着黑衣出席他的葬礼，他们宣告，他在这个社会上不复存在。&lt;/li&gt;
&lt;li&gt;第三次死亡：当这个世界上最后一个记得他的人把他忘记，那时候他才真正地死去。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;很多人都在物理死亡（即物理实体存在的消逝）后的短短几年被忘记，迎来第三次死亡；但也有的人在千百年后依旧被人们铭记、经久不衰。这是因为他们做了深刻的事情，或留下了深刻的思考。&lt;/p&gt;
&lt;p&gt;就像人生，如一场风暴，汲以水分、还以甘霖。但留给世界的是雨露滋润、一道彩虹，还是满目疮痍、一地鸡毛——一切皆未定，你我皆黑马。&lt;/p&gt;
</content:encoded></item><item><title>低成本，懒生活</title><link>https://fuwari.vercel.app/posts/%E4%BD%8E%E6%88%90%E6%9C%AC%E6%87%92%E7%94%9F%E6%B4%BB/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E4%BD%8E%E6%88%90%E6%9C%AC%E6%87%92%E7%94%9F%E6%B4%BB/</guid><pubDate>Sun, 25 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;序言&lt;/h2&gt;
&lt;p&gt;随着改革开放红利日渐消退、经济发展逐渐减缓，人们的消费欲望不断下降；三年疫情让很多人本不富裕的生活雪上加霜。共克时艰后，消费主义和享乐主义被泼了一盆冷水，人们存钱的欲望日趋增长。&lt;/p&gt;
&lt;p&gt;但是，一波又一波的裁员潮下，各行各业工资也在不断缩水。那么，在「开源」日趋艰难的行业内卷现状下，也只剩下「节流」一条路可选。这也是我写下这篇文章的原因。&lt;/p&gt;
&lt;h2&gt;1. 什么是“懒生活”？&lt;/h2&gt;
&lt;p&gt;「懒生活」，从字面看起来是「慵懒的生活」，实际上我更愿将它看作一种&lt;strong&gt;小资的恬静、忙里偷闲的惬意&lt;/strong&gt;。可以在早起上班的路上听上一首歌、看一篇深度长文；也可以在周末享受「太阳晒屁股」的懒觉。它可以理解为低成本下的懒生活，也可以理解为低成本但是懒生活。同时，它并不意味着牺牲物质生活的当下享受，也不意味着生活质量的大幅降低。以下我会从大数据、消费者行为、供应链、经济循环的方面对「低成本懒生活」做出详细的分析和介绍。&lt;/p&gt;
&lt;h2&gt;2. 不要将理解委托他人&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;互联网时代，流量为王。&lt;/strong&gt; 这是因为当下的很多人都放弃了独立思考，而将思考和理解的权利委托于他人。而此时，多如牛毛的自媒体、铺天盖地的广告，就会扰乱人的认知，最终一步步把思考和理解的权利交给他人、看更多的「娱乐至死」的短视频，这样的即时满足会让人逐渐沉溺其中，而其中夹杂的观念、软硬广告，就成了媒体变现的渠道。同时，跟随链接购买到的商品，价格必定不是最优惠的。&lt;/p&gt;
&lt;p&gt;用通俗的话来讲，短视频、小游戏的满足感是高频率、少量的多巴胺（一种导致人快乐的激素）的分泌，同时会快速地触发人大脑的奖励机制。但长此以往会导致人们习惯并沉溺于这种高频率满足，不愿走出舒适圈。另一方面，完成一项任务、进行一次旅行，这是很复杂的一些任务，在完成任务的过程中，我们需要将复杂的任务分解为多个简单的任务，每花上几十分钟、几小时乃至几天完成一项小任务的时候，我们都会收获一次满足感；完成整个任务、达成目标时，会收获大量的满足感。同时，完成任务的步骤也成为了我们宝贵经验的一部分。而经验，就是对世界的理解。&lt;/p&gt;
&lt;p&gt;看到这里，相信很多习惯于「即时满足」的、对抗与自己不同观点的人已经关掉了页面。那接下来我们讲述一下「大数据」在我们看不到的地方如何控制着人们的认知。&lt;/p&gt;
&lt;p&gt;现如今的大数据，都结合着一个「用户行为模型」。我们不需要理解该模型的运作方式，这种类型的科普文章和视频在互联网上数不胜数，只是看你愿不愿意去搜索去阅读。这里只在浅层描述一下：&lt;/p&gt;
&lt;p&gt;当你打开一个页面、甚至用某些触屏键盘软件输入一些内容，你的这一次访问就会被记录。一方面为了「优化你的体验」，而另一方面则是为了大数据分析。他们会将你的访问带着手机的IMEI（一种唯一标识码）电脑的MAC（物理地址，唯一标识）递交到广告API，而你即将打开的小说、短视频、购物软件，则会向API服务商购买这类API服务，并识别你的唯一标识符进行定向推送。而你多次访问的、停留时间长的页面，则会被记录到用户行为模型，方便各厂商的下一次定向推送。这也是为什么在BiliBili评论区甚至本地备忘录发表“我好喜欢小猫”，下一刻打开淘宝则会发现推送了一部分“宠物猫”相关商品的原因。&lt;/p&gt;
&lt;h2&gt;3. 为什么卖家价格总有更低的？&lt;/h2&gt;
&lt;p&gt;相信大家都有这个经历：打开某个购物软件（例如拼多多）并搜索某个条目，刷的商品越多，则会看到价格越低的商品夹杂在其中；而也有许许多多「挂羊头卖狗肉」的商品条目。而买到手则会发现，一开始刷到的高价商品和后来的低价商品甚至连厂家都一模一样，质量上更是几乎没有区别。那么，为什么商家能以如此低的价格拿到货呢？&lt;/p&gt;
&lt;p&gt;你可能会回答：因为他们是从工厂进货。答案确实没错，但要实现「低成本」的生活，了解该现象存在的原因也很重要。&lt;/p&gt;
&lt;p&gt;一个商品的价格和它的价值是截然不同的两个定义。价值包含原材料的成本、生产它的每一环的人力成本、加工设备的成本、运输的成本、店面仓库租金等，这些共同构成了它的价值。而价格则还需要加入金融资产这一考量。比如铁矿炼钢的成本，远低于购买钢材的价格，这是因为金融市场的操作；再比如买一个房子或车子，你获得的是房屋的居住权和产权证明，你并不真正拥有它的一砖一瓦，但与此同时购买房子的资金又会重新流入市场，其中自然包括金融市场。这也是大家熟知的杠杆。当生产商品的每一个环节都被加入了杠杆，那商品的价格自然会基于价值水涨船高。&lt;/p&gt;
&lt;p&gt;另外值得一提的是：商品的品牌价值也包含在价值当中，但不包含在成本中。品牌反映了消费者的信任，也是过往商品的质量证明。这也是大牌商品昂贵的原因。&lt;/p&gt;
&lt;p&gt;卖家价格更低的另一个原因则是，他们大批量地购入商品，帮助工厂和分销商节约了宣传和广告成本（参考上文提到的广告API），因此工厂和分销商也愿意给他们较低的价格。而在二手市场中情况就有所不同了：其中最大的成本是运输和仓储，商品本身是很多企业和个人用完淘汰的，价值并不高。而大批量购入则帮助他们节约了运输和仓储的成本，也降低了一对一客服的精力。这也是大批量购入价格可以压到很低的原因。&lt;/p&gt;
&lt;h2&gt;4. 个人如何实现低成本？&lt;/h2&gt;
&lt;p&gt;这里要提出一个观点：羊毛出在羊身上、&lt;strong&gt;帮卖家省钱也是帮自己省钱&lt;/strong&gt;。上文讲述的成本，其中品牌价值可以压缩、快消品可以通过大批量购入压缩运输成本和宣发客服成本、减少加工环节可以减少人工和金融杠杆在其中的参与。接下来让我们叙述一下具体方式：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;品牌价值的压缩&lt;/strong&gt;，相信大家一定见过工厂直营这类词语吧。但这种「直营」的真实性不但有待商榷，质量也是参差不齐。毕竟苹果代工厂是工厂，华强北代工厂同样也是工厂。那么，如何挑选出质量有保障的低成本商品呢？&lt;/p&gt;
&lt;p&gt;有一种商家，他们不注重宣传、不贴牌，但他们有自己的HomeLab实验室帮助卖家测量产品的各项性能，同时在一些小圈子里进行小规模零成本（忽略时间成本）的宣传，在这里称之为「个人卖家」。这和下文将要提到的「拼车车主」十分类似。&lt;/p&gt;
&lt;p&gt;个人卖家首先会从各大工厂和经销商里挑选低价的货源并购买样品；随后使用专业仪器测量具体的技术参数，例如充电头的电压、协议、纹波，日用品的某些有害化学组分，电子设备的拆解分析和软件测评，食品的试吃和检验…… 他们的确会加收一部分价格，但并不高昂，且帮助我们节约了选购时的时间精力，同时也规避了质量问题导致的可能风险。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;大批量购入的压价&lt;/strong&gt; 是人尽皆知的方案了。但除快消品以外，个人由于「用不完」而无法实现这种行为。因此某些时候会产生「拼车」这一自发性的行为，即有较大需求的「拼车车主」在小圈子里找寻有相同需求的人、统计人数、组建群聊约定「发车」期限、并同时与供应商谈价格。在发车期限抵近时，当需求数量高于供应商批发数量，「拼车车主」会从供应商手中以较低的价格拿到货，并重新包装、在「发车」后通过快递寄出。此时价格同比商家进价的增长幅度是多出来的一次快递费，对于二手商品，由于批量购入替卖家节约了仓储和客服成本，则可以做到压价更低。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;减少加工环节&lt;/strong&gt; 也是一种方案。但始终铭记两点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;我们的目标不是为了折腾而折腾，而是为了以更低的成本实现目标而折腾。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;非个人爱好或职业发展方向，多余的技能很可能一生都用不上。因此自己的学习成本和工时成本也要计算。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;明确这两点后，实现减少加工环节的方式则显得很明确：DIY。&lt;/p&gt;
&lt;p&gt;比如你需要添置一台计算机，找热爱DIY的玩家推荐一份配置单会比线下电脑城的配置单性价比高得多，且还会贴心地推荐低价货源、避坑点，而这一切都是免费的！&lt;/p&gt;
&lt;p&gt;再进一步，如果你精通个人DIY，则会了解到「企业级电子垃圾」比「消费级电子产品」量大管饱 这一特点。因此「上车」（即上文提到的参与拼车）购买二手企业级硬件会实惠很多。&lt;/p&gt;
&lt;p&gt;而假如你是一名电子工程师，你会了解到很多故障配件是因为一些不起眼的电容电阻烧毁导致的，维修起来成本极低，甚至对于一些个人需求还可以自行定制电路板实现，这比现有企业级方案价格低廉得多。&lt;/p&gt;
&lt;p&gt;但想象这样一种情况：你不是电子工程师、也不是资深DIY爱好者、甚至对计算机硬件一窍不通，那么从头学习复杂的知识的时间成本则可能长达数月甚至一年。而在这么久的时间内，你能创造的财富和积累的经验，也变相的拓展了未来在某一领域的可能性及期望收益。当然也可以使用极端的比较：目前最高配置的个人计算机价格绝对不超过20,000元人民币（不计算光效和品牌徽标）。而学习DIY需要花费数月的时间、最终节省1,000元都算很多了。而按照最低工资计算，20时薪、每天2小时，25天就能赚到1,000元，算上休息日正好是一个月。因此，为了节省时间而付出金钱，我认为是一件很值得的事情。&lt;/p&gt;
&lt;p&gt;同样的，「懒生活」这个概念也正是代表着“花钱买时间、用买到的时间享受生活“。&lt;/p&gt;
&lt;h2&gt;5. 低成本懒生活的构想&lt;/h2&gt;
&lt;p&gt;人的需求无非衣食住行、吃喝玩乐。我对「低成本懒生活」中的基本要求为：衣着保暖得体、饮食健康美味、住所温馨自由、出行随心快捷、吃喝洒脱自在、玩乐尽兴而归。&lt;/p&gt;
&lt;p&gt;在此要求上，我将「需求」分为以下几类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;一次需求：指一生只有几次的需求，例如房子、车子的购置&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;低频需求：指可重复使用的物品的不定期更换，例如电脑、手机、家具的维修更换&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;高频需求：指一次性用品的需求，例如食品、药品、日用品&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在此基础上，分别对这几种需求进行描述：&lt;/p&gt;
&lt;p&gt;衣着其中部分属于低频需求、部分属于高频需求。外套这种低频需求，我们可以选择网购、二手平台等方式，二手衣物经过洗涤后并不会对健康造成危害。如果实在有心理压力，一些网购店铺也比线下门店便宜至少50%。而内衣裤这种高频需求则并不适合购买二手，因此可以选择去「1688」这一平台进行批发，并定期更换。此时应当注意选择织物本身的颜色（例如棉布的白色），以防劣质产品掉色，影响健康。&lt;/p&gt;
&lt;p&gt;饮食这一高频需求、甚至可以说是日常需求，这里特指在家吃饭。很多当代年轻人的厨艺其实并不好，因此选择点外卖来填饱肚子。但很现实的一件事情是：很多外卖都应用了预制菜（又名料理包）。除了某些热爱烹饪、对食品有较高要求的人以外，我们可以选择自行购置料理包。订购方式首次可以选择在电商平台，后期向工厂直接订购更划算。此处应当注意，优先选择冷链运输的冷冻料理包，这类产品中不会添加大量的防腐剂影响口感，更不会产生过量的亚硝酸盐危害健康。&lt;/p&gt;
&lt;p&gt;住所，即住房，要仔细思考自己是否真的有需求必须购置。多年来的大基建让城市公共服务变得十分成熟，租房也成为了不错的选择。而房地产市场供大于求，未来价格必然会持续下降。习近平主席曾说：“坚持房子是用来住的，不是用来炒的定位。”因此购买房产也不具备金融层面的意义。所以，在购置前仔细思考自己是否是为了「充门面」、「脸上有光」这一目的购置。同样我个人不提倡也不反对购置婚房，因为它意味着稳定的个人空间的获得，但绝不是婚姻的必需品和附属物。&lt;/p&gt;
&lt;p&gt;出行，我愿将其分为近程、中程、远程三种类型。近程对我来说指3km以内，这段路程可以选择步行，有益健康；中程对我来说是3-10km，这段路程选择公交更廉价方便，同时如果时间紧急也可选择出租车网约车一类；远程对我来说则是10-100km，这段路程乘坐公交会浪费大量时间，因此建议选择地铁（此处指城市轨道交通）、市郊铁路（仅在超大型都市和卫星城间拥有）、城铁（即城际铁路），方案据路线而定，除珠三角城市群外，成本上地铁&amp;gt;市郊铁路&amp;gt;城铁。&lt;/p&gt;
&lt;p&gt;吃喝，这里特指出门外餐，选择则更偏向个人喜好。此时不应过度考量价格，因为它的性价比无论如何也比不上在家吃饭。我们出门吃饭更应当享受它的氛围感和体验感，此时应当综合考量餐品质量和店面装潢。同时，由于低价餐厅的饮品和甜品质量一言难尽，建议路上预定饮品、餐前外带到餐厅、餐后去甜品店外带/堂食（可选）。此时大数据的点评软件和攻略软件给优先推送的餐厅普遍不会太差。如果因为经济条件限制，可以选择降低频次而不是降低价格牺牲单次消费体验。&lt;/p&gt;
&lt;p&gt;玩乐，这里分为两种：城市内游玩及长途旅行。&lt;/p&gt;
&lt;p&gt;城市内游玩的选择通常为电影院、游戏厅、公园等，考量交通成本和时间成本，建议选择就近的场所，但同时如果有外餐需求，由于大型商场的地缘优势会将诸多餐饮店集中在周围，因此可以结合商场位置考量。&lt;/p&gt;
&lt;p&gt;而省际的长途旅行，交通工具则成了必不可少的一环。假如喜欢沿途风景，则选择购置车辆自驾游更适合；而如果喜欢体验某个地区的风土人情，则可以在个人网上交际圈内联系当地人，并和其中交往较深的朋友协商是否可以「蹭住」。同时和其他朋友联系外出游玩，走进当地人的生活。这里我十分不建议去各个网红景点打卡的「行军式旅行」，它除了一堆照片以外什么也带不给你。&lt;/p&gt;
&lt;p&gt;最后再讲一些批发和二手市场交易要注意的点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;优先上网自己搜索该型号的文档，不要一个劲问卖家——卖家的耐心比你想的要差很多：你是小批量，他们大批量的单子比回复你赚的更多，同时有合同也有保障。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;询问要围绕实际价格和产品与描述的一致性，这被称为「小刀」。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一直询问“弱智问题”或者大幅砍价只会导致卖家拉黑你或者坐地起价。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;作为一名旅行者、电子爱好者，我对「低成本，懒生活」的核心思想的理解是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;没有需求不要创造需求，我们不是为了折腾而折腾&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;时间可以换来金钱，但金钱不能买来时间&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;「开源节流」只是暂时的艰难，我们要向前看，为严冬后的春天而准备萌发、生长。&lt;/p&gt;
</content:encoded></item><item><title>初来乍到，请多关照</title><link>https://fuwari.vercel.app/posts/%E5%88%9D%E6%9D%A5%E4%B9%8D%E5%88%B0%E8%AF%B7%E5%A4%9A%E5%85%B3%E7%85%A7/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E5%88%9D%E6%9D%A5%E4%B9%8D%E5%88%B0%E8%AF%B7%E5%A4%9A%E5%85%B3%E7%85%A7/</guid><pubDate>Fri, 23 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;时隔大半年&lt;s&gt;的摆烂&lt;/s&gt;后，向阳哌小站终于在2024/02/23午夜零点重新上线了！
After more than half a year of &lt;s&gt;lying flat&lt;/s&gt;, SunnyPai site is back online again at midnight on 2024/02/23 0:00 (GMT+8:00)!&lt;/p&gt;
&lt;p&gt;先在开门大吉时夸下海口：&lt;strong&gt;坚持做原创内容，拒绝搬运“不可重复性”内容，保护作者著作权！&lt;/strong&gt;
During the time of the creation of the site, I make make a commitment: &lt;strong&gt;insist on making original content, refuse to carry &quot;non-repeatable&quot; content, and protect the author&apos;s copyright!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;本站主要内容关于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;计算机服务器与网络&lt;/li&gt;
&lt;li&gt;旅行与生活&lt;/li&gt;
&lt;li&gt;垂直领域深度思考&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My site is mainly about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Servers and Networks&lt;/li&gt;
&lt;li&gt;Travelling and Life&lt;/li&gt;
&lt;li&gt;Vertical Depth Thinking&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;站点依旧在不断完善，新内容敬请期待！初来乍到，请多包涵！
The site is still under construction, new content will be added soon! Please forgive my scribbling.&lt;/p&gt;
&lt;p&gt;SunnyPai,
Feb. 23, 2024&lt;/p&gt;
</content:encoded></item></channel></rss>