2026 年计划清单
活着 练背 练肩 练腿 多搞点钱 搞辆車 jū 瘦到 130 拍婚纱买五金
2025 年计划清单
活着 挣钱 减肥 冲俩软考高级证 这一年. 现代诗人 南瓜. 活得还好, 钱没挣着.体重没掉, 肥肉渐少.软考没过, 再接再厉.
飞牛 NAS + Tailscale 组网踩坑实录
废废的话多多的说家里有台用了很多年的笔记本, 型号是联想小新 700, i7 的 CPU, 8G 内存, 硬盘是买来时我自己换的一块固态 256. 这台笔记本购于 17 年 10 月, 陪我度过了刚毕业时的懵懂, 也陪大美丽度过了研究僧苦修的日常. 进可敲代码, 退可搞学术, 进过水, 也换过屏, 可以说是功高劳苦, 遍体鳞伤. 不忍心让它就这么丢在家里吃灰, 前段时间我一个没忍住, 买了一块 2T 的机械, 一块 1T 的固态, 还有一根 16G 的内存条. 换上以后, 大黑满血复活. 当时有个老登整天找我念叨要组装小主机, 搞 NAS, 我被折磨久了, 心里也有火苗在跳. 心动完我先整理了一下需求, 然后丢给 AI 帮我整理方案: 我有一台闲置的联想小新700电竞版笔记本,i7的cpu,16+8g内存,GTX905m显卡,1t固态硬盘,2t机械硬盘,想安装飞牛OS作为影音nas,win10用来打steam游戏,linux和macOS用来写代码开发php/java/qt/swift,现在了解到可以通过hyper-v, vm等虚拟机,也可以通过pve,ESXi等虚拟化平台满足我的需求,我对开发和游戏可能有一定的性能要求,帮我分析下用哪种方案最优 AI 说我这个需求 PVE 是首选. 那还说啥, 搞呗. 趁着周末, 我一口气折腾到半夜, 然后发现 GG 了. 大黑不支持一个什么 Bios 直通, 给 Bios 升完级依然找不到对应选项. 我特么心里哇凉啊, 头发咔咔掉一地. 裤子都脱了就给我看这个? 第二天一早我还是老老实实地装了 Windows, 然后又通过 Hyper-V 装了飞牛 NAS. 我给飞牛绑了局域网内的固定 IP, 然后把 2T 的机械盘从 windows 禁用掉, 专门给飞牛做存储, 最后又通过 SMB 把硬盘挂载回了大黑, 方便我在不开浏览器的时候也能随时查看飞牛里的文件. 说实话, 用着是真的爽啊, 自带的远程连接虽然只有 2M 带宽, 但是也足够我在公司上传下载文件用, 比之前玩黑群晖的体验强到没话说! 玩了几天以后, 我又喊上老登一块儿联机我的世界, 当时龙猫的启动器正在小范围试用联机功能, 老登刚好就有, 分享完我们畅玩了一天. 结果第二天就看到龙猫发了篇声明, 联机功能没了, 组网的需求嗷一下就上来了. 鉴于龙猫用的 EasyTier, 我也先尝试了一下, 发现功能确实好用, 但碍于我不喜欢他们那套 UI, 我又放弃了. 没错, 颜控就是这么离谱. 挑来选去, 最后还是选了 Tailscale. 踩坑过程虽然 Tailscale 下载安装后登录下账号就能用, 但是最开始我没搞明白, 也不知道它其实需要客户端和命令行结合使用. 我只发现两台设备都安装登录后, 互相访问似乎是没什么反应. 拉上老登又陪我折腾一圈, 发现登录完设备之间确实是通了, 我当时不通是因为访问了飞牛的内网 IP, 而我, 跟本就没给它配置子网路由. 😭 首先, Windows 安装后, 可以直接在命令行使用 tailscale 的各项命令, Mac 安装后, 需要手动添加一个环境变量: 1export PATH="$PATH:/Applications/Tailscale.app/Contents/MacOS" 然后才能在命令行愉快地玩耍, 比如通过 tailscale status 查看各台设备的连接状态, 再或者通过 tailscale ping ip 来查看当前设备到对应设备的连通状态. 也就是这个时候, 我和老登都发现设备之间虽然通了, 但是延迟有点高. AI 说, 应该是没能打洞成功, 再一看 status 的结果, 果然都是中转. 它让我先把 41641 端口在防火墙放开, 但是我没开防火墙, emmm🤔… 那问题就只剩一个, 网络层给我拦了! 登上光猫后台, 没找到什么 UPnP, 但是有个端口映射, 我给配了一下, 再运行 tailscale status, 连接状态果然变成了直连, 快多了. 当天晚上又拉老登联机了一个游戏, 结果游戏内时不时弹起的网络延迟过高让我有点蛋疼. 打开测速网一跑: 73 Mbs, 我千兆的光纤 FTTR, 可以说是拉了一裤兜. 把 Tailscale 关了, 再跑能到 230, 大黑的无线网卡是 400 多, 也算能说得过去. 初步怀疑运营商对大端口的 UDP 做了主动丢包, 尝试查找怎么给 Tailscale 配个端口, 强制所有流量去走 443, 安装目录添加配置C:\ProgramData\Tailscale\config.json: 12345{ "ForceTCP": true, "Socks5Server": "localhost:443", "TunMode": "userspace"} 配置后重启,似乎没啥作用. 微软服务内添加 --port=443 后重启, 依然没啥作用. 正跟 AI 较劲到底该怎么配的时候, 我突然看到之前配置子网路由时的命令, 似乎带了一句 --accept-routes, 去掉以后再测速, 又回到 200+. 总结, 不知道是哪个傻逼在博客里提了一嘴改 443, 被 AI 抓取到以为 Tailscale 是可以配端口的, 特么误我啊! 已知问题如果是 Mac 且开了代理, 打开文件管理有很大概率一直转圈, 似乎是因为 Safari 在代理模式有概率连不上 Socket. 解决方法未知, 暂时只能换浏览器或者关代理.
Mac 菜单栏多合一工具 FancyTool 更新啦!
本次更新聚焦「轻量体验」深度优化:不仅重构了 CPU 占用逻辑与系统唤醒机制,让后台运行更高效;更让动画交互全程保持丝滑流畅,资源消耗却低到近乎无感 —— 哪怕它常驻菜单栏,你也几乎察觉不到它的存在,既不拖慢系统,又能随时响应需求~ 下载地址: [ github ] [ gitee ] 目前软件主要包含以下功能: 🚀 智能CPU动态图标 让性能可视化 将任何GIF图片设置为你的菜单栏图标,它的播放速度会实时响应你的CPU使用率 空闲时悠然自得,高负荷时急速狂飙,用最酷的方式监控系统状态 支持完全自定义上传,打造你的专属动画 🌈 渐变彩色心情签名 用美丽的渐变色彩表达每日心情状态 完全可自定义的颜色和文字,展现独特个性 为您的菜单栏增添一抹艺术气息 📋 高效剪切板管理 记录多次复制历史,随时找回需要的内容 智能分类整理,快速定位所需片段 支持文本、图片等多种格式,提高工作效率 🖥️ 屏幕圆角美化 为Mac屏幕添加优雅圆角,提升视觉美感 智能适配多显示器设置,每块屏幕完美呈现 无性能影响的背景运行,细腻改善视觉体验 📎 菜单栏折叠工具 自动整理拥挤的菜单栏图标,保持界面整洁 一键展开/折叠,平衡简洁与便捷 自定义排序和分组,完全按您的方式组织 技术特点 原生 Swift 开发,完美兼容最新系统 轻量级设计,资源占用极低 直观易用的界面,无需学习成本 定期更新,持续改进功能和体验 如果有好的建议或者使用时遇到任何问题欢迎随时反馈👏
Mac 菜单栏多合一工具自荐:FancyTool
鉴于本人特别喜欢花里花哨的菜单栏,但又不想开机自启太多软件,所以自己开发了一个新的、轻量的,有点花里胡哨但又有些实用功能的多合一工具:[ FancyTool ], 感兴趣的朋友可以点击链接下载使用。 我承认,这里的介绍是有点啰嗦😊 目前软件主要包含以下功能: 🚀 智能CPU动态图标 让性能可视化! 将任何GIF图片设置为你的菜单栏图标,它的播放速度会实时响应你的CPU使用率。 空闲时悠然自得,高负荷时急速狂飙,用最酷的方式监控系统状态。 支持完全自定义上传,打造你的专属动画! 🌈 渐变彩色心情签名 用美丽的渐变色彩表达每日心情状态 完全可自定义的颜色和文字,展现独特个性 为您的菜单栏增添一抹艺术气息 📋 高效剪切板管理 记录多次复制历史,随时找回需要的内容 智能分类整理,快速定位所需片段 支持文本、图片等多种格式,提高工作效率 🖥️ 屏幕圆角美化 为Mac屏幕添加优雅圆角,提升视觉美感 智能适配多显示器设置,每块屏幕完美呈现 无性能影响的背景运行,细腻改善视觉体验 📎 菜单栏折叠工具 自动整理拥挤的菜单栏图标,保持界面整洁 一键展开/折叠,平衡简洁与便捷 自定义排序和分组,完全按您的方式组织 技术特点 原生 Swift 开发,完美兼容最新系统 轻量级设计,资源占用极低 直观易用的界面,无需学习成本 定期更新,持续改进功能和体验 使用方法 赞赏如果觉得有用,可以请我喝杯咖啡☕️ 感谢以下老板投喂,🫰❤️ 姓名 金额 时间 留言 *龙 ¥ 10.00 2025-08-27 15:00:00 ☕️
php、java 和我
前几天 java 30 了,今天看到 php 也 30 了。 我就不一样了,我 30 多了。
echarts 原生分组实现
最近想实现下边这样一个效果,折腾半天后总算搞定了,记录一下. 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151<!DOCTYPE html><html><head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>echarts</title> <style> #echarts { width: 100%; height: 400px; } </style></head><body><div id="echarts"></div><script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.6.0/echarts.min.js"></script><script> let option = { title: { text: 'Stacked Line' }, tooltip: { trigger: 'axis', // 限制tooltip在图表范围内展示 confine: true }, legend: [ { data: ['测试门店', '测试门店2'], top: 0, icon: 'rect' }, { show: false, data: ['测试门店-团单', '测试门店-美团', '测试门店2-团单', '测试门店2-美团'], }, { top: 30, data: ['团单', '美团'], }, ], grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true }, xAxis: { type: 'category', boundaryGap: false, data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, yAxis: { type: 'value' }, series: [ { name: '测试门店', type: 'line', data: [] }, { name: '测试门店2', type: 'line', data: [] }, { name: '团单', type: 'line', data: [] }, { name: '美团', type: 'line', data: [] }, { name: '测试门店-团单', type: 'line', label: { show: true, position: 'top' }, data: [0, 32, 15, 25, 20, 30, 11] }, { name: '测试门店2-团单', type: 'line', label: { show: true, position: 'top' }, data: [120, 132, 101, 134, 90, 230, 210] }, { name: '测试门店-美团', type: 'line', label: { show: true, position: 'top' }, data: [20, 2, 35, 45, 50, 70, 21] }, { name: '测试门店2-美团', type: 'line', label: { show: true, position: 'top' }, data: [10, 12, 11, 14, 50, 20, 10] }, ] }; let myChart = echarts.init(document.getElementById('echarts')); myChart.setOption(option); /** * 切换事件 */ myChart.on('legendselectchanged', function (params) { let selected = params.selected; let names = []; if (selected[params.name] === false) { names = Object.keys(params.selected).filter(i => i.includes(params.name)) }else{ names = Object.keys(params.selected).filter(i => { let arr = i.split('-'); return i.includes(params.name) && params.selected[arr[0]] === true && params.selected[arr[1]] === true }) } names.map(i => { if (selected[params.name] === false) { myChart.dispatchAction({ type: 'legendUnSelect', name: i }); } else { myChart.dispatchAction({ type: 'legendSelect', name: i }); } }) });</script></body></html>
闲来有感
刚才整理邮箱时突然看到一封 24 年由一个外国友人发来的推广,当时可能大概瞄了一眼。 然后就把它忘在了脑后。 外国友人说看到我在博客里推荐的图片转 ico 工具很好用,但是有一些限制,他有一个更好用的工具,并希望我能放进该博文进行展示。 刚才试用完准备去贴链接的时候,看到了一个很久没去访问的博客:litten 域名已经挂了,再看看大佬 github 的推送记录,似乎也停在了 17 年。 8年了。 那一瞬间的鼻头一酸似乎有点过于矫情,但还是忍不住想要感慨一句:时间过得可真特喵的快啊。
follow 认证
This message is used to verify that this feed (feedId:104434909303929856) belongs to me (userId:68900854292651008). Join me in enjoying the next generation information browser https://follow.is. ps. 需要邀请码的可以联系.
系统异常崩溃实录
前言众所周不知,我在 24 年底入职了某连锁品牌的美甲公司,负责相关小程序和后台的开发与维护。 入职前了解到该项目最初由外包团队开发,并使用外包三件套:宝塔、TP、Mysql 进行部署和搭建,当时我心里就对它有了一个大概的印象,但是等我真正接手这个项目时,还是忍不住地两眼一黑,心头有一万头草泥马奔腾而过。 项目结构之混乱,方法定义之奇葩,没有一项不在挑战我认知的下限,我只能说,用屎山来形容这套代码都是在夸它,项目能平稳运行简直就是个奇迹。 哦,也不能算奇迹,因为这勾八玩意儿就没有一天是平稳的。 在告别了手动替换服务器代码并用 git 管理之后,我又先后经历了 CDN 欠费,小程序图片无法正常显示;SSL 证书过期,所有服务全部宕机;以及子项目域名过期却拿不到平台账号,最后只能换绑域名这样的种种混乱…… 在此之后,系统总算平稳运行了几天。 屎山的崩塌正当我撸起袖子,准备奋力重构这坨屎山时,年底到了,我又迎来了新一波的挑战。 1 月 16 号早上 10 点,我把手里刚开发完的小程序推送到正式版,之所以选在这个时间更新,是因为有些门店会营业到凌晨5点,10 前的使用量相对还少一些。 本来只是一个简单的更新操作,但是让我没想到的是,刚发版没一会儿,运营就突然在群里反馈说小程序卡,很卡,非常卡。 我被这消息搞得一头雾水,貌似刚才也没写 bug 吧? 掏出手机操作一下,发现确实不能正常使用,阿西吧,赶紧联系同事撤回了版本。 这回总好了吧?掏出手机一看,还是不正常,群里也还在不停反馈依然无法登录等各种问题,傻眼的我更傻眼了。 打开服务器上的宝塔面板,两眼又是一黑,负载已经飙到了 100%,cpu 也到干了 94.5%。 wtf?这可是三台配置都不算低的服务器,按照上家公司的业务量,这个配置估计只需要一台就足够了。 我赶紧打开 nginx 的 access 日志,结果发现啥也没有,因为配置文件里压根儿就没有记录日志的代码。 再一问同事,之前服务器硬盘被日志塞爆过,没人清理,后来索性就都关了。 我无语凝噎。只能硬着头皮继续分析,发现负载和 cpu 飙升的原因是有几个 php-fpm 进程占用特别高。 它们在干啥?为什么会飙这么高? 正当我们抓耳挠腮,掉了无数头发时,又在云服务器后台发现前一天 0 点也有同样的情况。 再往前一翻,清一色的 0 点和 10 点各项指标飞速飙升,0 点的飙升像座小山,10 点的飙升像座大山。 wō ní mǎ。 开始抓虫我慌了,开始怀疑起这个项目有异常的定时任务。 我的怀疑是有根据的,因为前一波开发的大聪明在调接口时,借助框架的事件驱动模块,用嵌套了两层的 http 接口调用一个所谓的 Task 接口,然后触发了 1000 多个 event…… 为什么要套两层接口,我不知道,为什么要这样写,我也不知道。 我只知道本地的接口被这玩意儿拖到了 6 秒一个请求,开发需求时我都是直接把这行代码注释的。 事情到了这个节骨眼上,我只能硬着头皮研究了一下这块代码,然后清除了里边 90% 左右的无用事件,然后又仔细检查了服务器的 crontab,emmm,就没有在 0 点和 10 点运行的任务。 查到这里事情还是没有大的进展,我的心态已经开始波动了,这屌系统崩就崩吧,这屌工作要不就干到今天算了吧?要不等过了年,我再出去找找其他工作? 正当我想要打开 boss 直骗,给自己发昏的大脑来上一套强制冷却时,系统又诡异地恢复了平静。 我挠着头,一边感叹自己对这个屌系统的认知还是太过于浅薄,一边思考为什么会出现这样的局面,这里边还有没有什么其他值得怀疑的对象。 这时候,运营又在群里反馈了其他问题,我看这一波飙升已经过去,下一波也还很遥远,也就先放下了这件事,先去处理群里的其他问题。 时间一晃到了下午,闲下来的我和同事又发现数据库有很多慢 sql,其中一个最夸张的甚至运行了 126 秒。 是它吧?一定是,要不然还能是谁呢? 我和同事马上开工,把系统里的慢 sql 都给优化了一遍,然后又给服务器装了 Atop 做监控,信心满满地等着 0 点时验证一波。 时间再次来到 0 点,服务器准时出现波动,但是只有 10 秒。 我先打开慢 sql 日志,完美,没有慢sql。再一看 Atop,10 分钟一次的记录完美避开的案发现场。 这样下去明天 10 点铁定得崩,那咋办?还有台闲置的服务器,加上去吧,看看后台,还有门店在使用系统,那只能等明天早上再加。 跟同事约好第二天早上 5 点半起来操作,我估摸这要不把 access 日志打开,看看涌进来的请求是不是都正常,因为这个时候已经开始怀疑是不是被人攻击了。 第二天一早,我们爬起来先把昨天推送失败的小程序再次更新,验证完之后又把新服务器加进了负载,忙完以后定了个 9 点多的闹铃,然后赶紧躺下又眯了一会儿。 不到 10 点,又被群里的消息吵醒,看完发现是前一天优化的 一条 sql 有问题,没有正常生成数据,快 10 点了,我们把问题先丢在一边,先盯着监控看服务器状态。 结果很快再次打脸,新增的服务器虽然也扛住了很多并发,但系统还是崩了,大量用户无法排队,大量门店也无法叫号,这次挣扎再次以失败告终。 我把 access 日志拉了出来,逐行分析了上千行日志,发现事情并没有那么简单,这些请求似乎都很正常,难道攻击我们的还是个高手,伪装成了正常用户? 我统计了每个接口的访问数量,又统计了每个 token 访问的接口数量,还解析了几个用户的 token。但是,这些东西还是没有任何帮助,我没有找到任何被攻击的证据。 事情再一次陷入僵局。 令人无语的真相时间再次来到 0 点,我们提前停下了所有定时任务,系统不出所料,还是全线飘红,不过我们好在知道了问题的根源是在数据库。 但是为什么会在 0 点和 10 点这两个时间涌入大量的请求,我们还是怀疑是不是有人在攻击我们,苦于没有证据,只能继续分析日志。 我们发现在 0 点的一瞬间,系统涌入大量的排队操作,其他调查均无成效的情况下,我们只能统计了 0 点后每家门店的排队情况,打算第二天联系门店核实一下这些排队是否真实,同事也把我们统计的表格发给了老板。 每个人的心头都像压了一座大山,怎么办,再不搞定这个年还能过好吗? 第二天浑浑噩噩地爬起床,灌下一杯超浓咖啡,我带着深深的忧虑再次上班。 路上,同事发来一张聊天截图,老板说,这些是正常的,很多门店就是 0 点开始放号,因为每个门店的排号是有限的,顾客只能在放号的一瞬间去抢,包括十点也是一样的情况。 我觉得天塌了,忍不住骂一声他喵的,合着我们起早贪黑辛苦调查,最后调查了个寂寞,系统宕机纯粹就是因为瞬时并发太大??? wtf!这个世界是真的魔幻啊,做个美甲还要 0 点起来抢号? 波折的解决之路时间一晃又到 0 点,我们白天把排队叫号相关的接口逐个优化,该加缓存的也都加上了缓存,同事也研究起数据库的从库和代理,等着 0 点验证一下能否扛住压力。 然后,我们卡在了第一步,读库连不上去,服务器方面,靠着手动切换负载,硬是扛住了这一波。 再一看日志,排号接口平均在 20 毫秒,叫号接口平均在 250 毫秒,但是读库的内存才使用了 17%,像极了你那个出工不出力天天在摸鱼的老油条同事。 阿西吧,这可不行。 读库可是按小时收费的,扛过了零点高峰,我们马上下了,准备第二天早上继续研究。 第二天一早又把读库配好,也让运营通知了门店错峰放号,我紧盯着监控,准备随时切换负载分配,同事那边也在联系服务器客服,让他们远程协助,解决读库不发力的问题。 但是很遗憾,10 点前读库的问题还是没能解决,服务器小崩了一下。 时间已经到了周日,距离放假还有一周,距离第一次触发这种情况已经过去一周还要多,再不解决,真就过不好这个年了呗。 虽然这是个从系统诞生就已经存在的问题,但在业务高峰期频繁触发实在打脸,老板拉我们开了个会,说以前的人是把服务器的流量降下来,听得我们目瞪狗呆,这是什么傻逼骚操作?降流量,咋不把服务关了呢。 一番拉扯后,我们决定给接口限流,10-10:30 期间,每分钟放出 100 个排号,超出就等下一波。 方法测完上线后,我们终于迎来了第一个好消息,读库能连上了。 当即选了一台服务器切了过去,然后进行了一波测试,发现读库还是有点慢,有点鸡肋。 同事再次提了工单,在对方的大力协助下,我们升级了读库和代理的配置,几乎是在一瞬间,主库的 cpu 睡着了。 0 点后,qps 一路狂飙到了 18000/s,服务器的负载虽然又到了 100%,但是 cpu 一直维持在 80% 左右,这件事总算成了。 我特么能睡个好觉了……
