MoreRSS

site iconGamea | 飘逝的风修改

游戏后台开发十多年, 目前就职于Tencent。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

Gamea | 飘逝的风的 RSS 预览

雨路

2025-01-31 08:00:00

Featured image of post 雨路

有点小雨,撑着伞走在去祭拜观星伯伯路上,眼眶有些湿润。这一条路走了多年多次,仿佛看见自己往前走的身影,或推开虚掩的门,或在门口就撞见伯伯。他多半会带着惊讶的说:“咦,你今天来玩嚯啊(我们这方言语气)”,然后马上呼唤“桂花,江崽过来了”。

若是遇上壮年时的他,可能正在做着他的专业工作竹篾匠。儿时的我似乎只惊叹于他的手巧而忘记观察那一件件工艺品是怎么被制作出来的,竹篮、竹椅、竹簸箕,还有体形巨大的一些我甚至说不出名字。也有时没有遇上人,听闻是去哪家干活了。可能有更多我不知名的作品在一件件被纯手工慢慢制出。这是他这辈子养家糊口的工作,一做就是几十年,似乎还记得告诉我十几岁开始学徒,又仿佛在六十多岁仍旧还在做着。即便孩子已经长大成家,亦不曾落下。

若是遇上中年的他,呼唤我一起去干点劳活。我的农村记忆的大多数,关于如何插秧、如何和田、如何收割水稻,又如何推动独轮车将一袋袋的稻子运回家;关于如何种红署土豆,如何分剪重栽;在沙地里种萝卜花生,还有采摘棉花等等,更有在离家极远外的田地里,烈日下劳作到正午,伯母从家里带来热饭,我们吃完休息会儿然后继续投入农作的画面。幼时的我喜欢一起做点事情,他们也视我如儿子般教导。伯母更是对其他人介绍我为“老儿”(是否意为老来得子未可知)。在炎炎的夏日,外面知了不停嚎叫,偶尔有远处自行车铃声响起,大抵是卖绿豆棒冰的商人。我躺在伯伯家的竹床上,手持一把扇子,缓缓入睡。

若是遇上老年的他,手持着一根长长的竹制烟筒,抓一小撮黄烟塞到旱烟洞中,满满的吸一口烟,再缓缓地吐出来,看着烟雾腾起旋转又消散,然后轻轻敲掉烟草残渣,又往复循环。他曾兴奋的告诉我,他女儿给他买了一根很好很漂亮的烟筒,拿出来如获至宝般介绍,我看到了他眼里的亮光。我又想起,很多次看到他在太阳底下晒他的黄烟,像一块块的小豆腐,棕黄色,时光穿梭中从旧房子的窗台晒到新房子的窗台。

工作以后,长期在外,回老家次数甚少,更不像读书每逢寒暑假我都会在伯伯家长住一段时光,我们的见面次数更少了,但是他并没有降低一丝对待我的热情。

大概每年都会问一次你厂里有多少人,我说有几万,他不禁感叹,“那是一个大厂”啊。 然后聊到后面,会说“你是做技术的,坐办公室的,厉害!”在说厉害的同时都会翘起大拇指。年复一年都会重复的问,我只以为是人上了年纪健忘了,那时我并不知道它是阿尔兹海默的前期。

大概每年也会谈起有没有聊得来的姑娘。接着会给我分析一下哪种姑娘适合,还会谈到我的性格和脾气。也有些年会给我介绍他的亲戚家的某个女孩,也会告诫我某个女孩太过精明我会驾驭不住。我无从得知是否最终潜移默化受他影响,最后确实幸运寻找到一个不错的媳妇,可能冥冥中有他助力吧。甚至有时我觉得,一个朴素的农民,他身上的善良和谦逊,也会染于我身、存乎我心吧。

后来的几年,从带着媳妇去看他时,那时他只记得老婆和孩子,孙子们已经成为陌生人,自然也叫不出我的名字了。之后我有了小孩,带着小朋友再去看他,听说病加剧了,已经不认识自己的儿女,幸有伯母成为唯一“亲人”。但这也不妨碍他热情的招待我们,他说看着人就亲,是一家人云云。他继续抽着他的旱烟,熟练的手势,吐出一圈圈烟雾,让我娃看,同时点燃手中的打火机,像大人给小孩子变魔术似的,忽闪忽现,然后自己也像一个小孩一样,笑容满面。我看着他,看着娃,好像某种东西在传承。

我又想起最后一次和大脑清醒的他交谈约莫在三四年前,那时正是正月,心痛不舒服卧床中,他颇为犟不肯去医院医治。他说已经七十多了活够了,很坦然面对死亡,但我估计是不想给子女包袱罢。所幸后来还是听说去做了检查植入了心脏支架,人恢复得很快,我以为便没什么事了:毕竟他一直健朗,这辈子没听说生过啥大点的病。像我常年在外,特期盼亲人们老得慢一点,有时会担心少看了一眼,我很害怕是最后一面。

无从得知是否在近80高龄下麻醉手术加速了他的阿尔兹海默,结果是更加健忘,刚问过话又忘记,刚递过烟给我几分钟后又来。最近几年看望时,除了头脑外其它都没有任何问题,人也是精神的,看着无忧远虑的他,犹如一个孩童,我想这也或许也挺好?我头脑中浮现《困在时间里的人》,一个老父亲在这种病中,面对每天身边“陌生”的脸孔,是否也会恐惧?那些不快乐或痛苦的记忆是否会在大脑中闪回,来回折磨着他呢?

三个月前,听说摔了,治好后又胃出血,人虚弱着躺床上。我在春节回家后去看望了一次,听闻卧床后自己也爬起来过一两次,但之后便没起来。以米汤稀饭为食,有时能吃一碗。胃已经养好些不再便血了,听起来似乎可以静养等待康复。年二十九,正是今年除夕日,早八点多,哥打来电话我没有接到,看到后心里隐有预感,但总期待仅仅是找我约饭,急切地拨通电话,哥说人上午走了,我的耳鸣又猛的加剧,嗡嗡不绝。

不知觉已经到了伯伯家门口,伯母在屋内仍有哭腔,我进房间看着笔直躺在床上身上盖着白布、头上蒙着脸巾。她说你再也没有伯伯了,她告诉他“老儿”来看他了。前几天看望时在床上自言自语的瞬间又在头脑中亮起,他还睁开眼睛似乎看了我一下,没料想几天间就阴阳两隔。点香祭拜,鞠躬、鞠躬、鞠躬、鞠躬、鞠躬、鞠躬、鞠躬,我鼻子一酸眼镜又模糊了。

在回去的路上,雨依旧在下。记忆的碎片一个个袭来:冬天烤火的火盘,总是划好后,让我一起熏手;每个假期到了他家就拉我去理发;他学自行车失败的画面乃至到哪里都是双腿走过去,我也和他一起走路去过陈村;他窝在柴房烧火煮菜迎接我们等等,混乱又真实,仿若昨日,又似在遥远的天际。我真害怕忘记,那么多瞬间,有他也有我。可是一想起我再也无法见到他了,仍旧像断了线的风筝,像心底被掏空了一块。甚至想起未来回老家看望亲人时,我会沮丧,会无所适从,会茫然若失。

我感到一股冰凉扑上脸颊,深吸一口气,扶正了雨伞继续前行。人终有离别之日!我想起这世间的温暖,想起《寻梦环游记》中提到的,或许我们只要记得他能时常想起他,他便不会孤单。安息吧,伯伯,我会记得,你也不曾忘记过我。

 写于2025年正月初三,请水仪式完。

AI编程之Cursor使用技巧及一些思考

2025-01-26 08:00:00

Featured image of post AI编程之Cursor使用技巧及一些思考

很多人说2025年是智能体元年,而在2024年,很多追求高效的程序员已经使用上了Cursor/Windsurf,它似乎让人从几年前的GitHub Copilot又更进一步,我也时常思考未来编程会变成什么样,Cursor以及LLM等对于整个开发流程又会有怎样的影响呢?

前言

本篇文章来源于2024年底在组内的一次技术分享,主题是《Programming with Cursor》。当时以演示为主,由浅入深和大家一起体验了Cursor的强大之处,也分享了一些使用技巧。在整理为博文时,发现其实不少操作视频更有利于理解,所以本文不求文字重现过程,而从另一个角度,谈谈Cursor协作编程的一点思考。

我会简单聊聊它的一些基本操作与设置,但显然手把手教学并不适合于此;然后是一些进阶的玩法,以及如何借助于它重构我们日常的开发流程;最后也扩展聊一点其它AI Code Editor的玩法,以及它们与Cursor的对比。我希望你在阅读本文前最好接触使用过Cursor,或者有其它一些AI辅助代码生成的经验,这会更加有助于理解我说什么。

好的,让我们开始吧。

Cursor的来由

要简单介绍它还不容易,如果你了解传统的Copilot,那么Cursor相比有更强的AI能力,以及更易用的交互。它的理念之一是:

“基于你的光标位置,思考你想做什么?”

我来回翻了下Cursor的BLOG,可以见到他们一直在提升它的上下文感知能力,以及多行、跨文件代码变更等。 在比较后面的版本(0.43+)又提升了Agent等能力,进一步提升了AI自动化水平。而Cursor的一个标签挺有意思: Tab, Tab, Tab,这或许意味着它很懂你,你要的只是Tab确认一下,同时它支持多处修改,不断跳转。

Cursor基础交互

之所以能流行,我觉得Cursor把交互做得相当简洁了,主要就四个操作(以MacOS快捷键为例,其它平台自查):

  • Tab:确认某一些代码变更或补全。
  • Cmd+K:在编辑器中对某一段代码进行对话或重写。
  • Cmd+L:唤出Chat窗口,与Cursor对话。
  • Cmd+I:唤出Composer,进行更复杂的如从0构建项目,或多文件修改对话。

不知道为啥,我个人觉得在编码中Cmd+K并不是太好用,它直接对代码进行改写,我更喜欢能看对前后Diff对比再采纳。所以个人最常用的可能是Cmd+LCmd+I。当然Cmd+K在命令行下挺好用,不必切换到聊天,直接生成命令执行,我印象中早些年有个编辑器叫Wrap,它出师未捷而中道崩殂了吧:)

Cursor更厉害的是它的引用能力。只要以@开头,可以引用不少内容,常见的如文件、目录、代码片段,以及更强大的web页面、外部文档,还有Git仓库中的提交等以及整个代码仓库code base等。这里可以简单聊几个小技巧:

  1. 有时候你和它聊一个东西,它显得张冠李戴了,大概率是上下文不够,你可以尝试@引用一些文件,或者对应的结构及函数。会发现它生成的可能更符合你心意了。
  2. 基于可以引用Git,它了解你的仓库情况,所以让它生成一些Commit Message也是不错的选择。格式规范,描述清晰,甚至我感觉它比我自己写得还好。
  3. 有些外部较新的文档,模型大概是没有学会的,这时@web或一个链接给它就很有帮助了。相信它读文档比你快还准确,唉,一边开心一边忧伤吧。
  4. 因为Cursor背后是大模型支撑,所以其上下文有所限制,有时太长你会发现它好像忘记之前的一些内容了,建议适时Cmd+N起一个新的聊天窗口。

Cursor进阶玩法

老实说第一次开启了Agent后的试用,有一些行为让人惊喜连连。这一节我们聊几个进阶玩法, 主要涉及agent模式/yolo模式以及定制化.cursorrules文件,背后的工作原理似乎也是显而易见的,但是却有大用处。

Agent模式

Agent模式需要你的版本在0.43+,有些同学说它的Cursor怎么找不到,我这也不是特供版呀:D 你只是没更新而已(不过更新后也有同学反馈之前通过不断Delete Account来获得反复体验权的被拦截了,原因未知)。对于这种迭代更新较快的软件,及时更新能获得更强大的功能。初步的Agent已经能够做一些我们琐碎的事情了,从自动编写代码,到自动修复一些lint错误,以及自动生成单元测试用例和自动生成提交。

惊艳到我的是,我让其重构一段代码,它同时尝试修复相关lint,发现protobuf的proto有修改,自动去编译proto,它先尝试命令make proto,发现报错了。 接着分析我的Makefile,察觉到是基于Earthly来构建的,并且发现了make code命令可以生成相关协议,接着自动执行编译与修复工作。一切就绪后,给我生成了一个不错的Commit Message,并自动提交了。这期间我就是看它表演,时而让我确认一下要执行的命令,我面带微笑点确定,又一次有点忧伤。

YOLO模式

在使用Agent模式时,当遇到需要在计算机上执行一些命令时,有时会询问于你,要使用者主动点确定,主要是隐私等考虑。但有时我们想更快捷认为可以授权它去做点事,这便是Yolo功能的出现背景,要使用此功能则需要0.44+的版本。相对开启Agent,Yolo这个相当于一个配置,说是一种模式略显牵强。当前默认是不开启Yolo的,显式的为了安全起见,我们还是可以配置允许它自动执行哪些命令,白名单或黑名单都支持。

在启用YOLO后,Agent模式下工作会更加自动化,多数时候已经可以“围观”机器工作了。这个模式我使用的经验倒不是特别多,有时候似乎有些低效的循环,但未来价值可期。

定制化.cursorrules

写文章时再查了一下,前几天更新的0.45版本又一次提升了.cursorrules文件的定制能力,它支持了多仓库级的rules配置,未来研究一下实际效果。我们先说两种使用方式:

  1. 全局的Rules For AI。在Cursor的设置中可直接输入,可以配置一些全局规则,比如我就让它回复使用中文,但是代码注释使用英文,效果很明显。
  2. 在根目录定义.cursorrules文件,在它上面写上你想告诉Cursor的一些提示词。

网上也能找到一些不错的提示词总结,比如awesome-cursorrules。我试着将仓库特定的规则告诉它,比如代码风格,比如一些工具或编译等,这都有助于我们未来更好的与AI沟通。

这个过程中,其实我们还可以偷懒,甚至.cursorrules也是由AI来写的,它基于README或code base,可以帮我们完成一个初稿,我们自己再补充完善一些,未来这就是喂给AI的一部分提示词了。我在想,若是能够不断编辑完善rules,比如如何写一个测试用例,如何写注释,如何写一个模块,那么真的很可能取得不错效果,这一块我应该未来还会持续有更多实践,特别是工作中会经常和某几个仓库打交道,必然有些成熟的惯例是AI能轻松学去的吧:) Cursor Rules

Cursor的其它实践

单元测试

有一些工作是我们平常自己厌烦的,但是咱们的AI助手可是任劳任怨,比如写更多单测。我们自己写平常会有两大问题,用例想不完全以及偷懒覆盖不足。这种目标性比较确定的事情,在Cursor中是比较容易完成的,当然前提是你的代码比较规范,也有一些可参考的示例。

也有些场景生成的代码不太符合预期,那么如何写出AI友好的用例/代码呢?我看Behavior Driven Development (BDD)挺不错,它强调行为,而不是实现,所以可以更聚焦于功能,而不是实现细节。有这种代码框架后,细节刚好AI可以补全,而咱们只需要关注于功能(即用例)。在Go语言中,可以借助于Ginkgo(https://onsi.github.io/ginkgo/),它支持BDD框架。你看着感受一下会不会AI友好些:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var _ = Describe("Books", func() {
 var foxInSocks, lesMis *books.Book

 BeforeEach(func() {
 lesMis = &books.Book{
 Title: "Les Miserables",
 Author: "Victor Hugo",
 Pages: 2783,
 }

 foxInSocks = &books.Book{
 Title: "Fox In Socks",
 Author: "Dr. Seuss",
 Pages: 24,
 }
 })

 Describe("Categorizing books", func() {
 Context("with more than 300 pages", func() {
 It("should be a novel", func() {
 Expect(lesMis.Category()).To(Equal(books.CategoryNovel))
 })
 })

 Context("with fewer than 300 pages", func() {
 It("should be a short story", func() {
 Expect(foxInSocks.Category()).To(Equal(books.CategoryShortStory))
 })
 })
 })
})

未来如何在更多场景中使用AI来帮助完善单测是值得探讨的事情,希望有更多实践后能和大家分享更多心得体会。

Code Review

没想到吧,AI除了帮你写代码,当然也能帮你评审代码。随着不停的听着各种AI刷爆排行榜,那么我也期待它们能帮我把控更多的风险。我尝试将工作中的一些比较隐蔽的BUG,通过Cursor来评审,发现它确实能发现一些问题,甚至一些我们组内多人评审都漏掉的问题。我不由得想,如果大家提交代码前,都有一个这么强力的助手帮你先看看本次改动,提供一些参考建议,那么提交的代码质量会更高,也更有信心。

任劳任怨的AI,它不会因为一次修改几百处而眼花缭乱,它只会默默的遵从你的指定帮你检查。所以给CR的提示词也比较关键,这里我们可以看一下网上的一些总结ai prompts for code reviews。不过我感觉不同团队或项目最好有自己定制的CR规则,比如就写在.cursorrules文件中,这样更有针对性。

这里有点小技巧,我们在Cursor中提交代码前,可以@git选择PR (Diff with Main Branch) ,这样Cursor会基于当前的diff来评审,而不是基于整个仓库。模型上我建议你选择更强的模型,比如claude-3.5-sonnet或者o1-mini等。

我最近拿了一个较复杂的提交来让AI进行Code Review,使用claude-3.5-sonnet模型以及4o都没有发现问题,但我切换到o1-mini,它能够发现。我又试了一下国产最近大火的DeekSeek V3,也能够发现问题。给国产模型点个赞!所以作为CR使用,面对复杂的场景我们就别节约这点消耗啦:)

其它AI Code Editor

除了收费的Cursor/Windsurf等,我们还可以有免费的vscode + cline插件来实现比较好的AI辅助编程体验。当然现阶段我推荐你使用Roo Cline插件(好像又改名叫Roo Code了,这是要摆脱Cline身影啦),它在消耗token上更友好,还有更多功能待你发现。结合上面提到咱使用国产的DeeSeek V3,甚至换上又火爆全球的DeepSeek-R1系列模型,价格便宜,性能强大,应该也是不错的。有点遗憾的是这些插件可能因为只是“插件”,各种体验我感觉还是略逊一筹。

另外,发现Cline有个比较有意思的扩展:MCP Servers。基于MCP(model-context-protocol)协议,定义了模型和工具互相交互的一种范式。当前已经有不少支持它的server了,比如和Git/Sqlite等交互,甚至Cloudflare有:

Cloudflare - Deploy, configure & interrogate your resources on the Cloudflare developer platform (e.g. Workers/KV/R2/D1)

还有不少第三方的MCP server,不确定未来是不是能够此标准一统天下,但它是一个不错的思路,也具备一定的想象空间。

后记

因为时间有限,对于Cursor的体验也说不上深入,但似乎能够看到它带来的工作效率的提升。我们常听说,未来淘汰我们的不是AI,而是不会使用AI的一批人,我不确定是不是自媒体卖课时的危言耸听,但也值得提醒我们,如何不那么轻易被替代。做不了10x程序员,咱有机会2x, 3x吗:)

短期内来说,怎么将这种能力融入到日常开发流程中,并且获得货真价实的质量与效率提升,才是更有意义的事情。 欢迎大家一起交流探讨一下你们是如何使用的呢?也欢迎指正文章中的错漏之处,共同学习,共同进步。

我是个爱折腾技术的工程师,也乐于分享。欢迎点赞、关注、分享,更欢迎一起探讨技术问题,共同学习,共同进步。为了获得更及时的文章推送,欢迎关注我的公众号:

扫码关注公众号

Macbook原生跑Linux体验

2025-01-25 08:00:00

Featured image of post Macbook原生跑Linux体验

作为一个后台开发,对于Linux有天然的亲切感。在之前Mac Mini折腾记中提到过未来想尝试让Macbook也跑一下Linux,于是抽空折腾了一翻。我不确定Linus自己的macbook是否会只安装一个Linux发行版本而弃用MacOS,体验完,我劝你先别着急,且听我道来。

背景

在年前购置了一台新版Mac Mini后,相对而言手上这台Macbook Air便不是唯一能提供生产力的工具了。何况那边内存也有所提升以及量大管饱的存储,更适合重度一些的使用。于是我总算可以安心清理掉一些软件,着手体验一下号称跑原生Linux的Asahi Linux系统了。

我个人从大学在使用Linux桌面,换过N个版本,那时是折腾的欢乐:)但工作后自从误入MacOS阵营,倒是很少接触使用Linux桌面版本了,更多的是作为一个服务器而非桌面使用体验,这也是一次机会让我感受一二。

在Macbook机器上安装Linux

首先你要确保手上是Apple Silicon芯片,可以在Asahilinux的官网找到其支持的设备,除了Air,Pro及Mac Mini、Mac Studio、iMac等也均有支持的设备,还在陆续增加中。当然,很古早的Intel芯片的Macbook有其它安装方式,这里不做讨论。

Asahi Linux aims to bring you a polished Linux® experience on Apple Silicon Macs.

安装命令很简单,在终端执行:

1
curl https://alx.sh | sh

可是我很不幸运,遇到了几个问题,这里记录一下,供大家参考。

空间清理 & 修复

在开始安装Asahi Linux前,它至少要求At least 53GB of free disk space (Desktop install),所以需要清理掉一些空间。这里我移除了一些软件,清理了docker镜像以及ollama模型等,腾出了不少空间。但是在安装时,遇到了个报错:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
We're going to resize this partition:
 APFS [Macintosh HD] (245.11 GB, 6 volumes)
 Total size: 245.11 GB
 Free space: 73.13 GB
 Available space: 0 B
 Overhead: 35.13 GB
 Minimum new size: 245.11 GB (100.00%)

 Warning: The selected partition has a large amount of overhead space.
 This prevents you from resizing the partition to a smaller size, even
 though macOS reports that space as free.

 This is usually caused by APFS snapshots used by Time Machine, which
 use up free disk space and block resizing the partition to a smaller
 size. It can also be caused by having a pending macOS upgrade.

 If you want to resize your partition to a smaller size, please complete
 any pending macOS upgrades and visit this link to learn how to manually
 delete Time Machine snapshots:

 https://alx.sh/tmcleanup

 Not enough available space to resize. Please follow the instructions
 above to continue.

这里提示我需要清理掉Time Machine的快照,于是我打开终端,执行了

1
tmutil listlocalsnapshots /

发现有大量的快照,特别是删除软件后,可能过程中都有快照,空间想要真正腾出来,必须将这些快照删除。

1
tmutil deletelocalsnapshots /

这样,关于磁盘空间的问题就解决了。

磁盘问题 & 修复

不幸运的是,安装过程中还有一个奇怪的磁盘报错:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Checking the object map
Checking the snapshot metadata tree
Checking the snapshot metadata
Checking the document ID tree
Checking the fsroot tree
warning: inode (id 27124912): dir-stats key xf does not exist, despite internal_flags (0x8412)
error: inode with file-id 162290089 has doc-id 26529 but doc-id tree record has file-id 162398146
error: inode with file-id 162398146 has doc-id 26529 but doc-id is already in use
error: inode (id 162398146): xf 1/3: INO_EXT_TYPE_DOCUMENT_ID: invalid doc_id index
error: inode (id 162398146): invalid xfields
fsroot tree is invalid
The volume /dev/rdisk3s5 with UUID 6200BE0F-C0A8-42E2-8E77-F3711AC85C32 was found to be corrupt and needs to be repaired
Checking volume /dev/rdisk3s6
Checking the APFS volume superblock
The volume VM was formatted by apfs_boot_util (1677.50.1) and last modified by apfs_kext (2236.101.1)
Checking the object map
Checking the snapshot metadata tree
Checking the snapshot metadata
Checking the fsroot tree
Checking the extent ref tree
Verifying volume object map space
The volume /dev/rdisk3s6 with UUID EE207A3D-D241-4058-A1BE-B2E2FDAD5434 appears to be OK
Verifying allocated space
Performing deferred repairs
error: Unable to perform deferred repairs without full space verification
The container /dev/disk0s2 could not be verified completely
Storage system check exit code is 8
Error: -69716: Storage system verify or repair failed

Resize failed. This is usually caused by pre-existing APFS filesystem corruption.
Carefully read the diskutil logs above for more information about the cause.
This can usually be solved by doing a First Aid repair from Disk Utility in Recovery Mode.

重启切换到恢复模式,打开磁盘工具,选择急救,再修复,等待完成。期间还报修复失败过,也panic过一次,正当快要放弃时,它有奇迹式的修复成功了,原因未明。若你也有类似问题,可以多试几次,苦笑:(

安装过程

安装完成

按要求重启后,长按电源键,直到出现启动顺序相关提示,松开后选择Fedora,就可以看到不一样的天空了。老实说第一次看到Linux桌面在Macbook上跑起来,还是有点小兴奋的。 启动过程登录过程 那么实际使用起来怎么样呢?

使用体验

在上面安装过程中,可以有选择安装OS的选项,默认是安装Fedora,也可以选择安装Ubuntu等,这里我选择的是Fedora,当年第一款桌面除了红帽就是Fedora,既然是怀旧嘛,那就它了。何况它似乎是推荐的发行版本,希望各方面支持会更好些。

进入系统后蓝牙,无线等一切正常。各种UI操作响应飞快,特别是切换桌面等时,感受真爽。我打开监视器看了下,开了浏览器和一些终端,CPU使用率在4%左右。打开自带的firefox浏览器,访问B站等视频网站,播放流畅,4K及音频播放都很正常,看起来驱动情况完成得相当不错。这系统响应之快,都让我抖了个激灵,这还是我印象中的Linux吗?

系统信息

看似不错,那能否作为我日常开发使用呢?于是乎打算部署一下之前通过Nix管理的开发环境,遗憾失败了。但是VScode的ARM版本支持不错,下载后正常使用,我还安装了最近挺火的Cline插件,毫无问题,要开发似乎是可以的呢?

VScode 虽然Cline+Deepseek v3挺多人推荐,可惜我目前更喜欢使用Cursor开发,交互体验更好,遗憾的是它目前还不支持Linux。还有终端,默认的Konsole,基础能力具全,初步使用还不错。特别是好奇它这个颜色是怎么出来的,我咋黑白电视看多了像看到彩电的惊喜呢?

Kconsole

安装了docker等,也都能正常运行,我略有好奇的是,在ARM架构上,docker容器的可选择性是否相对受限了?这块并没有深度体验,有经验的朋友欢迎告诉我。

可是再进一步体验,我发现了一些问题。首先是输入法,我是个拼音困难用户,日常多使用五笔输入,尝试过fcitx5,ibus,虽然能用,都多少有些不舒畅,包括切换,包括选词等。特别是在某些地方输入法无效,像在系统菜单,死活调不出输入法,只能使用英文咯,这让人颇为恼火。

其次是我习惯使用Chrome来浏览网页,可是它目前还不支持ARM架构;我习惯使用Obsidian来写笔记,虽然它有ARM版本,但是安装后执行报错;我习惯于使用双屏显示器,可是它目前无法通过外接Type-C显示。这些让我的开心程度锐减,似乎拿它作为主力开发系统时机还未成熟。

我像原来MacOS系统一样,合屏放置1-2天后,再次打开电量告急,这让我略为惊讶,可能是系统在节能上还有些问题?我的设置是这样的,懂行的朋友可以指导一下。

电源管理 然后有时通过菜单关机失败,使用命令shutdown倒是可以,略为神奇。

还有一点不得不提,咱们的快捷键也和以往有了相当大的不同,需要一段时间习惯,我已经分不清是Cmd和Ctrl了,晕了。

后记

到这里,简单总结一下:Asahi Linux在Macbook上跑起来,体验还是不错的,但是要作为主力开发系统,似乎还存在一些问题,特别是输入法,以及一些软件的兼容性,还有电源管理等,只能期待后续的更新看能否解决这些问题了,我也会保持关注。

我不确定切换为其它发行版本如Ubuntu后这些问题表现如何,如果你也在试用它,欢迎留言评论分享你的感受。目前我给的建议是玩一玩的话,强烈建议保留原MacOS系统,先体验看是否足够顺畅、好用、如你所愿。

虽略有遗憾,但祝使用愉快,尝鲜并且保持期待,这,或许就是全部意义!

本篇文章内容早2个月已经就绪,但最近工作较忙,延迟到春节假期才整理出来,感谢阅读。不知道这期间系统及周边有多少变化,过程稍有曲折和仅为一家之言,本认为分享价值不大,有读者朋友留言询问,便分享出来,若对你任何方面有一丝帮助,那真是我莫大的荣幸。

我是个爱折腾技术的工程师,也乐于分享。欢迎点赞、关注、分享,更欢迎一起探讨技术问题,共同学习,共同进步。为了获得更及时的文章推送,欢迎关注我的公众号:

扫码关注公众号

Mac mini M4 游戏体验报告

2024-11-25 08:00:00

Featured image of post Mac mini M4 游戏体验报告

大家的 Mac mini M4 入手了吗?每年都有不少朋友会尝试到底 Mac 能不能玩游戏。今年性能又听说强这么多,那不得试试?

我们的好奇心

我入手的是最低配的 16+256G 版本,运气不错,赶上了国补,花费 3500+。它的搭配以及使用感受在上一篇Mac mini M4 折腾记中已经聊过了,感兴趣的可以往前翻一翻。作为一个游戏玩家,虽然没指望长期用它打游戏,但是,咱可以不玩,不能没有这能力是吧?

对于 M4 芯片的 Mac mini,我们可能有几个疑问:

  • 它能玩3A大作吗?玩游戏体验怎么样?
  • 如果我想玩,需要怎么折腾?

带着这些好奇心,我花了一些时间趟趟坑,这篇文章聊聊我的体验,希望对你有所帮助。因为对一些软件接触较短,理解不深,若有错误,欢迎交流。

几种玩游戏的方式探索

MacOS原生玩游戏?

我上一篇文章试过一次,在玩 Inside 时,贴图花了。 对于这种难度不高的游戏,似乎也没有保障。所以如果你直接 MacOS 下玩Steam 的游戏,可能会遇上类似的不开心事情。当然,这个问题我劝你不要怪苹果,可能开发商锅大一点。 有一些游戏它本身在 Mac 下适配不错,也能拥有不错的体验,比如《文明 6》、《古墓丽影》系列、《博德之门3》等,有网友实际玩过还不错,帧率在 1080P 下流畅运行,2K也勉强能跑的地步。

CrossOver 玩游戏

跨平台运行 Windows 软件,或许你听过大名鼎鼎的 Wine,而CrossOver 则是基于它的一个可能更易用的商业化版本,我们就用它来玩玩游戏吧(我折腾过一下免费开源的Whisky,对一些游戏的兼容性差一些)。 关于 CrossOver的一句话介绍:

CrossOver 是一款系统兼容软件,它让您可以在 Mac 和 Linux 系统上运行 Windows 应用/游戏,不必购买 Windows 授权,不必重启,不用虚拟机。通过 CrossOver, 从 dock 直接启动 Windows 应用/游戏,与您的 Mac 和 Linux 系统无缝集成。

刚好上面的 Inside 游戏没有跑得很顺畅,那么给 CrossOver 次能力证明的机会。 看起来贴图没问题了,细心的你或许发现,帧数有下降?别担心实际它跑起来是基本稳定 60 帧,而在截图时游戏自动降频了。 然后接上手柄也试了一下,一切正常能控制。 开胃菜过后,咱来点硬菜。我的Steam库上正好有个《哈迪斯》,它有 Mac 版本,那就两种模式PK一下吧? 就体验来说,MacOS和CrossOver跑的感受差不多,很流量,画面也没打折扣,以下是一小段录屏 :
但是当我想玩一下《生化危机 4 重制》时,报错了:

这个问题,我们需要升级 CrossOver 的默认 game porting toolkit(GPTK)到 2.0 版本。很简单,安装完 Crossover 后,到苹果GPTK官网下载最新版本 GPTK。
阅读一下Read Me.rtf就可以了,我们是用的 CrossOver,就看这几行:

1
2
3
4
CrossOver: replace CrossOver’s copies of the D3DMetal.framework and libd3dshared.dylib found at /Applications/CrossOver.app/Contents/SharedSupport/CrossOver/lib64/apple_gptk/external with the libraries from this distribution:
cd /Applications/CrossOver.app/Contents/SharedSupport/CrossOver/lib64/apple_gptk/external
mv D3DMetal.framework D3DMetal.framework-old; mv libd3dshared.dylib libd3dshared.dylib-old
ditto /Volumes/Evaluation\ environment\ for\ Windows\ games\ 2.0/redist/lib/external/ .

简单说就是备份两个文件夹再覆盖过去就可以了。再次打开软件,正常进入《生化危机 4》。 游玩一切正常,可能识别到机器性能,画质不太高,不过还算流畅,我一小心通过了刚开始的丧尸围剿,哈哈。可惜退出游戏时会报崩溃要强行结束,美中不足呐!

有网友isaced评论:

最近在 Mac Mini M2 Pro + CrossOver 24.04 (GPTK) 尝试了《永劫无间》,除了机身发烫比较厉害,基本可以完美游玩。

2024 年激励无数国内游戏玩家的黑神话自然也是可以畅玩的,看到有网友展示,并且这个兼容性官方网站可查: 可惜我本人购买的是 PS版本,故未亲自验证哈。(顺便说一下,如果你想了解如何在 SteamDeck 上玩 PS 上的游戏,可以见我之前SteamDeck在手,国庆远程游玩PS5指南一文,公众号历史中也可以查看到。)

但是,也别太高兴,CrossOver 并不是万能的,有一些游戏也不兼容,比如想玩一下撸啊撸(英雄联盟)的话,你可能被SayNo,不支持的原因有多种,比如游戏厂商反作弊系统限制。我们可以在这里看到兼容的游戏列表。提前查看可节省掉不少瞎折腾时间:)

PS:前文说过 CrossOver 也不止for 游戏,Windows 的软件等也可以跑,如果你购买了,别浪费,不妨试一下。我居然用它安装了十几年前的金山打字通,运行在 XP 上:)这个软件有 15天免费,国内价格倒也不贵,我购买了 2024版本。但我推荐你不着急购买,是否能解决你的实际问题,并且用几天一切稳定再说呢~

虚拟机玩游戏

前面虽然用 CrossOver 解了一下玩 3A游戏的馋,但大众游戏 LOL居然不行。或许用原生OS 确实不行,你肯定会想那我上虚拟机得行不?正好这次购买 Mac mini 时,同时赠送了一个 PD 的两年授权,那就试一下 PD 虚拟机吧?说做就做,安装上 WeGame,又下载了25G+的游戏,运行看看: 无论怎么尝试依旧不行,这个LOL客户端可太有历史了,估计屎山深筑吧:)有哪位小哥可以跑的话,请不吝赐教,感谢!话说PD也并非没有作用,像 WeGame 在 CrossOver 不行,我们在 PD 里玩有些游戏是没问题的。我打开了一些小游戏,重温了一下《去月球》,只记得那旋律,剧情快忘记了,当年泪目的游戏呢~~~ 看到网上也有朋友试过 VMware 虚拟机,那个兼容性似乎更差一些,这次我没有尝试。其它比如 Mac 下的 UTM 等虚拟化方案,相信不太能超过 PD 便也没有再试。

一些实践Tips

开启Metal HUD

有两种方法:

  1. 在程序启动时添加环境变量:MTL_HUD_ENABLED=1。比如在 CrossOver 中,运行游戏时添加相关参数然后打开游戏即可。如果给Steam添加相关选项后,它启动的游戏也自动会开开HUD。
  2. 直接在终端执行/bin/launchctl setenv MTL_HUD_ENABLED 1然后再启动相关程序,要关闭把 1 改为 0 再执行。这种方式,官方提示CrossOver要先关闭再操作后重新打开。

CrossOver中的选项

你可能会发现CrossOver有一系列的高级设置,默认啥也没开,到底要开哪一个好呢?我们简要介绍一下

设置 功能描述 适用场景 建议
D3DMetal 将 Direct3D 调用转换为 Metal 调用,优化 macOS 上的图形性能。 在 M 系列芯片的 Mac 上运行需要 Direct3D 的游戏。 如果支持,建议开启。
DXVK 将 Direct3D 10 和 11 调用转换为 Vulkan 调用,提升性能和兼容性。 在 Linux 或其他支持 Vulkan 的系统上运行游戏。 在 macOS 上通常无需开启。
ESync 通过减少系统调用优化多线程应用程序性能,特别是在处理同步对象时。 多线程游戏,特别是对同步敏感的应用。 建议开启以提升性能,若有问题可尝试关闭或切换至 MSync。。
MSync 对 ESync 的改进,旨在更好地处理多线程同步,减少性能开销。 高度多线程的应用程序。 可作为 ESync 的替代选项,需根据具体游戏表现进行测试。
高分辨率模式 启用后以高分辨率报告给应用程序,提升视觉效果。 支持高分辨率显示的应用程序。 对于配置较低的设备(如 M4 mini),建议关闭以确保性能稳定。

我们是 Mac,苹果出的 GPTK 正是优化Metal 调用等,故D3DMetal推荐开启。其它建议开启ESync,而高分辨率模式我们这“羸弱“的 M4 mini 就先不开了吧?

个人感受

如果你懂一些技术,看到命令行不会犯怵,可以通过GPTK iwiki 看到如何完全手动安装 Steam、战网等,这样结合 Wine可以完全免费搭建起基本的 Windows游玩平台。如果希望更简单易上手,也可以直接安装 CrossOver,然后像文中提到去升级一下 GPTK2.0 以提供更好的兼容性。

总的来说,想要在 Mac 下愉快玩游戏,其实也挺折腾的,如果手上没有更适合的设备,或者有一定的移动需求而你的设备是 PC 等,这小小的 Mac Mini 倒提供了较好的移动性。不然我觉得你就别浪费时间了,相信上面我遇到的现象也是你随时可能碰到的。但你说它不能玩吧,它还行呢,3A 大作也陆续有不少可以流畅游玩。配置高一些的 Pro 或 Max 甚至在一些游戏上百帧也不是问题。但你说它坑吧,玩个 LOL 都有点困难,特别是国服。

于我而言,过年背回老家接个显示器/键盘/鼠标玩一下或许可考虑,平常嘛,我大概是不太会在这上面玩的啦~白买了我的 CrossOver,也算是给各位探探路啦。

本篇文章就写到这里,感谢阅读。如果期待看到更多玩法,欢迎点赞鼓励,您的支持是我写作的动力!

我是个爱折腾技术的工程师,也乐于分享。欢迎点赞、关注、分享,更欢迎一起探讨技术问题,共同学习,共同进步。为了获得更及时的文章推送,欢迎关注我的公众号:

扫码关注公众号

Mac mini M4 折腾记

2024-11-16 08:00:00

Featured image of post Mac mini M4 折腾记

最近MacMini可是太火了,拿到手一周多,折腾了一些玩意,闲言碎语随手记录一下。我们聊聊配套的硬件选择,聊聊如何更好的利用它,聊聊它的AI能力,聊聊游戏和一些工具。或许有些许参考价值,或许仅是自娱自乐,欢迎交流。

为什么购买

作为十几年的Macbook用户,我绝大多数的工作、学习都是基于Apple的Mac平台,而Windows平台仅用于偶尔游戏娱乐了。若不是要玩某些游戏,我大抵是不会启动Windows机器的。想到这里,顺便盘点一下我使用过的Macbook。

  • 似乎在2013年入的Macbook Air 13寸,它真的超轻,第一次接触它,打开电源后“duang”的一声激起的兴奋似乎还能回味。
  • 可惜当年它还不是视网膜屏的,后面15年换15寸Macbook Pro高配版后,又眼前似乎变清晰了。我用它多年,直到19年左右把它给爱回收了,居然还挺保值,这远超我的预期。
  • 然后公司19年配的带Touchbar那款,这玩意虽然用了三年,但是没太好的印象,感觉Touchbar的体验并不好,特别是对程序员,我的那个快捷键呢? 可是在它快退休的时候,苹果有个键盘召回更换活动,拿到天才吧居然免费把键盘和电源一并免费换了。这让我在转手出去时,居然以一种全新状态(除了屏幕)卖出了不错的价格。真得夸夸苹果的售后服务。
  • 接着遇到全新ARM架构的M1芯片,那个续航真是超级心动。于是借着生日礼物的由头,让媳妇送了一台Macbook Air给我。为了节省点预算,选了丐版的8G内存。老实说后面挺后悔,因为这金贵的内存。最开始8G内存好好的,但随着有舆论说它狂用SSD磁盘,后面开始就卡了。时不时提示内存不足,这严重影响了我的使用体验。一度让我养成了浏览器只打开几个标签页的“好习惯”。但它的轻薄、续航、颜值特别棒,是我家里写代码和码字的主力,和跟随我出没在书房、客厅、卧室的各个角落。这就是所谓爱不释手吧。
  • 22年公司给换了MacBook Pro 15寸,32G+1T的M1 Pro机型,在工作中使用至今。对它还挺满意,就是重了点。让我自己买一台在家用的话,我肯定不会选它。要怪就怪Air系列把我养得娇气了哈~

可是,我却从来没有用过Mac Mini。以前的感受是,就这一台小主机,要价还不便宜?干嘛不多花点钱买台带屏幕、键盘、触控板的MacBook呢,就丐版的Macbook Air也是超香啊?人在权衡这些时,看起来是评论它的定位,而一旦Mini最新版本降到只要3500元,信念它居然就有了回旋的余地,哈哈。原来并不是信念,而是钱在作怪。

当然还是要怪Air时不时提醒我内存不足,又恰逢最新M4芯片的Mac Mini在内存上加量不加价,于是就它了。 当然还是要怪Asahi Linux居然让M1芯片上也可以跑Linux了,好想去折腾一下,有就有了更多理由了。

还有呢,国补优惠这么高,不得支持一下这经济复兴政策嘛。

硬件搭配

最有性价比的当然是最丐版的16G + 256G存储的版本,恰逢国补,我在京东3581元拿下。这台小主机有10核心CPU,其中4个性能核心,6个能效核心,GPU是10核心,NPU是16核心。光有它可玩不转,我们还得搭配很多东西。对我来说,第一个有必要的就是硬盘,毕竟256G的存储空间,装个系统和一些软件就占掉一大半,想试着跑个模型啥的,别说GPU它不行,你硬盘可能先炸为敬了。

虽然我是11月8号拿到的机器,但是在3号预定时,就谋划着硬盘扩充方案了。我们知道网上已经有直接替换内置硬盘的方案了。不过我手头本来就有闲置的前两年支持国货买(囤)的2T的致态TiPlus7100,是时候到它表示真正技术的时候了。咱这个硬盘速度好歹也是PCIE4.0的,不上个雷电4就暴殄天物了。于是左右看各种评测,结合我未来可能长期开机作服务器的用法,还是买个散热好点的带风扇的硬盘盒。最后选择了这个,性价比较高: 机器到手后实测了一下,硬盘盒的读写速度如下:(前者为外接的雷电4硬盘盒,后者为机器内置的M.2硬盘)

然后是键盘,考虑到有时还会有Windows需求,主力是MacOS,所以选择了一款对MacOS友好的键盘。并且想要切换方便,需要三模的(有线/蓝牙/2.4G),于是选择了这款: 到手后它的小巧和颜值还是很喜欢的,敲击手感也不错。之前没有用过矮轴,这次体验下来,感觉还不错,打字不用太辛苦,红轴也不吵。 期间也考虑过不少人推荐的罗技mx keys,似乎很匹配MacOS,不过按键布局上,我更喜欢Nuphy的紧凑。

接着是鼠标,我原本就有几个罗技的鼠标,仅用于打游戏,它只支持2.4G,一般是用于Windows上延迟比蓝牙低一些。然后继续看了一下它们家的Master3S等,这个似乎大手才比较好,小手另有其它如anywhere系列。考虑了一下,我或许还是更适合多年习惯的妙控板,于是放弃购买鼠标了,不买立省100%是不是,把常年放在公司很少使用的触控板带回家了。

显示器的话,家里一直是Redmi 4K的那块畅销屏,用着也不错,就不必升级了。不过原来使用笔记本再外加一块扩展屏,习惯了多屏工作的人,只有一个屏幕都不会写代码了:) 所幸还有经常吃灰的iPad以及一块玩主机的便携屏(1080P),它们都能很方便的加入到生产中,凑合着用吧。

至于音箱,都说Mac Mini只能听个响,作为Apple生态的Apple AirPods耳机咱也是换过几代了,手上自然也是有的,这笔费用支出也免了。

最后,扩展坞什么的,我虽然有,也不需要,也不想用(第一次进系统确实需要,后面就再也没用过了)。天知道插满一堆设备一堆线的Mac Mini,乔帮主知道会不会从坟墓里跳出来,哈哈。

LLM跑一下

百闻不如一测,大家说M4芯片有多厉害,我到手第一天就迫不及待的跑了一下LLM。我用的是LM Studio,跑了下4bit量化的Qwen2-7B模型:

输出速度是22token/s,几次差不多都比较稳定的这个成绩。这个模型是MLX优化过专门for Apple Silicon的,所以速度上比原生版本快了一些。但这个速度嘛,其实我并不惊喜。顺便用Ollama跑一下(我现在硬盘大了,下载这种小模型可不用皱眉啦~),速度也差不多。现在各种闭源模型那输出都飞快,这测试的速度就有点考验耐心啦。当然,这个的速度主要得看GPU,而咱们最丐版的也就只有10核心,或许也就这样了。

那么它和我手上M1 Pro芯片比怎么样呢?同样在LM Studio中同样的模型同样的问题,它的输出有33.84token/s,比M4 Mini快了1.5倍。大概是因为M1 Pro有16核心GPU,而M4 Mini只有10核心GPU。看来GPU的提升对LLM的输出速度还是有比较大的影响。未来真正跑大模型得上Max或者Ultra芯片吧?

玩下游戏

既然跑模型不太行,咱能不能更好的玩Windows游戏呢?当然可以,需要一点折腾时间。我说的肯定不是安装虚拟机玩,那个游戏体验不可能好咯。Steam有MacOS的版本,我先跑了一下它,能运行的游戏不多。跑了一下Inside,这个性能要求不高,帧数比较稳定,但是画面贴图似乎有些问题。

如果我们想玩原生的Windows游戏,最近几年苹果似乎也更关注这一块了。原来推出的game porting toolkit,现在也更新到2.0了。

  • 支持更多的游戏技术。
  • 改进的图形和计算兼容性。
  • 光线追踪。
  • AVX2指令集。
  • 性能提升。

还有开源的Whisky以及更可靠稳定支持更多游戏的商业化软件crossover。之前掉到Whisky里没折腾好,后面有空换crossover试试。从国外老哥的测试体验来看,效果还不错的。要是有M4Pro,打一下低画质的黑悟空问题不大。什么?你想要超高画质吗,那得加钱。可能加钱也解决不了,我也蹲一个他人的测评。

功耗

都说M4芯片的Mac Mini功耗低,性能不俗。我实测休眠时功耗在3W左右(外接了一个雷电4),一般性工作时,功耗在15W左右(接两个显示器),拔掉外置的显示器,功耗在10W左右。 而在LM Studio中跑模型时,GPU用满,功耗能到40W-50W左右,性能释放上还是不错的。

基于这么点功耗,日常使用上应该也不需要关机了。但是或许是这款机器太小了,日常使用上,它还是有一点温度的,温温的,不至于烫手。冬天可作暖手宝了:) 而雷电4的硬盘盒,那玩意还是有一点烫的,我不乐意摸它。

软件推荐

作为一个老MacOS用户,要说有什么推荐的软件,那可太多了。这里就随便介绍几个。

我以前介绍过Mac的神器Alfred,这次再推荐一个Raycast,它和Alfred一样,都是快速启动工具,但是Raycast的UI更简洁,启动更快,功能更强大。然而我还是老Alfred用户,因为我付费终生会员啦~进一步使用参考以前的文章MacOS神器之Alfred workflow概览

苹果的硬盘空间卖这么贵,一个好用的磁盘清理软件还得常备。我我主要用免费好用的Tencent Lemon,它清理的比较干净,自定义选项多,而且有苹果官方的认证。

因为这次在JD购买Mac Mini,顺便被赠送了一个Parallels Desktop的两年激活码。久闻大名,但不想用盗版,既然你给我也笑纳了。它支持Windows、Linux、MacOS跨平台运行,安装Windows后,体验和Windows原生安装没啥区别,启动速度也挺快。当然,毕竟是虚拟机,性能上相比原生还是差一些。对于偶尔要开个Windows使用下专属软件的,这个还是挺方便的。

输入法上,我个人因为习惯使用五笔输入,使用的是清歌输入法(https://qingg.im/)。绿色无广告,因为我太讨厌在输入法中看到广告了。

作为一个开发者,我日常还会使用iTerm2, VScode, Neovim, Cursor,docker等工具,可能你并不需求这些。 最近看评测发现一个不错的监控软件,比原生的活动监视器更好一些。本来最开始的是asitop,但是它对最新的芯片支持不好,又有了一个更好的选择macpm。你只需要:

1
pipx install macpm

然后就可以使用macpm命令查看Mac的性能了。在终端下还挺好看: 一边开着LM Studio跑模型,一边开着macpm监控着机器的性能,感觉还不错。

总结

虽然很多文章力推新版的M4 Mac Mini,但是我还是要看个人使用场景。以下是我认为要慎重的几点:

  • 它只是个主机,你需要再额外配备不少东西,如果你不啥都凑和着用,整体上成本也不会太低。
  • 性能上日常使用不错,但想玩大模型,还是得上Max或者Ultra芯片。
  • 想用它玩游戏,花这个价钱,我推荐你出门找主机PS5什么的2000+更香,或者Windows才是你的归宿。
  • 如果你有Macbook Pro,其实可以不用考虑它。

但是,如果你喜欢折腾又爱玩,那么还是不错的选择:

  • 当个小主机?我相信它的出现,让国内各种小主机厂商都要哀伤了。
  • 当个软路由?长期稳定跑,功耗又低,也很香。
  • 组个NAS?这么多雷电口,芯片又强,至少文件服务能力杠杠的。

或者就用用它的内容缓存能力,让你家各种Apple设备看iCloud照片、视频更流畅,下载安装各更新快捷,也能收获良好的情绪价值。

BTW:怎么感觉下一代的Macbook Air还是会让我心动啊!我的病并没有被Mac Mini治好。

附一张全家福,后面这台主机估计会进入机柜。

本篇文章就写到这里,感谢阅读。如果期待看到更多玩法,欢迎点赞鼓励,您的支持是我写作的动力!

我是个爱折腾技术的工程师,也乐于分享。欢迎点赞、关注、分享,更欢迎一起探讨技术问题,共同学习,共同进步。为了获得更及时的文章推送,欢迎关注我的公众号:

扫码关注公众号

云上云下,资源自由:混合 Kubernetes 集群搭建指南

2024-10-16 08:00:00

Featured image of post 云上云下,资源自由:混合 Kubernetes 集群搭建指南

云厂商的CVM好贵啊!除了丐版引流招新人入坑,其它稍高点的配置那价格就像在考验智商。作为小小个人如果想搭建一套比较完善的kubernetes集群的话,那资源就捉襟见肘了。如何更经济实惠的应对资源不够这个问题,本文给一点新思路。

基本原理

我曾经基于云上一些CVM搭建了一套k8s集群,简单玩玩尚可。但是如果想搞点花样,比如想加点监控或分析,Prometheus一上,内存就咔咔告警;日志采集分析一下?ES或loki等一上,存储也就喵喵在叫。这阻碍我们学习知识了呢?这不能忍。

看过我之前文章的朋友可能知道,我家里有不少小型计算单元与存储,NUC等小主机几台、NAS几台。这有算力、内存、存储都充足。那么,咱可以优势互补,搭建一个云上云下混合的k8s集群吗?当然可以。

本文将借助tailscale及其相关工具(有比较详细的全套使用指南)构建一个云与家庭一体的混合集群,并且在之上我们使用更轻量的k3s发行版搭建一个k8s集群。这样,我们就可借用云上主机,获得如公网IP,备案等必要的便利,同时需要计算资源时又依托于自己家庭内的低成本CPU内存及存储等,真正物尽其用。接下来和我一起来操作并且验证一下我们的想法吧!

构建网络

不知道你听过WireGuard没有,我在之前一篇文章有过介绍。作为已经被Linux内核集成的一个VPN,它使用上还稍有不便。但我们借助于一款名叫tailscale的软件可快速构建安全可靠的虚拟局域网(VPN)。以下是GPT提供的介绍:

Tailscale是一款基于WireGuard协议开发的虚拟专用网络(VPN)工具,它允许用户将能够访问外网的设备聚合成一个虚拟的局域网,实现设备之间的安全通信。以下是关于Tailscale的详细介绍: 内网穿透:Tailscale可以将不同地点的设备连接起来,实现内网穿透,使得用户可以像在同一个局域网内一样访问这些设备。 设备连接:支持Windows、macOS、Linux、iOS和Android等多个平台,使得不同平台的设备可以轻松连接。 安全性:使用加密协议保护通信内容,确保数据的安全性。

它有强大的自动内网穿透能力,并且即使不能直连也会自动使用中继。据我观察,经常是使用几次中继收发消息后,自动打洞成功走上直连。你要说这么强大的软件,它有什么缺点不?那当然有:

  1. tailscale不是免费的,免费有接入节点限制,还有些高级功能有限。
  2. 中继都在国外,若需要经过它转发性能会有影响。

但是,别慌,这都能很好的解决。有个开源的控制面headscale,我们可以自建它解决官方各种限制。我们还可以自建中继服务DEPER。下面会一一道来,不过为了保证数据安全,首先我们得准备一个SSL证书。

使用ACME.sh自动申请证书

这里假定你已经有一个自己的域名了,我们可以借助于开源的acme.sh快速帮我们申请一个时长3个月的SSL证书,并且可以配置自动续期。这个证书是为了后面headscale服务安全性而用的,它也内置了自动申请证书功能,但目前(2024-10)只支持HTTP认证,这对国内域名不友好。我发现我在腾讯云上使用时不成功,可能是备案相关要求导致。所以下面我们就自己手动通过DNS认证来申请吧。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 安装acme.sh
curl https://get.acme.sh | sh -s email=[email protected]

# 方案一:http验证:以standalone模式获取证书(如果网站未备案,在国内机器上操作可能报错,国外机器这里或能成功)
acme.sh --issue --standalone -d example-domain.com

# 方案二:以DNS验证。 我域名托管在cloudflare中,那么就需要设置环境变量。
export CF_Token="你在cloudflare的API token"
export CF_Email="你域名的Email"

acme.sh --issue --dns dns_cf -d example-domain.com

如果你想要调试一下,可以先使用测试域名,避免因为一些报错被平台限制申请。这相关信息查看这里。 申请成功后,你将会获得证书相关的文件,把它拷贝出来放到了/home/ubuntu/example-domain.com备用。

搭建tailscale的控制面headscale

安装配置headscale

An open source, self-hosted implementation of the Tailscale control server. 多亏了开源的方案headscale,我们可以免费使用tailscale。查看这里的指引可轻松搭建。上面有容器方案使用起来简单,比如我们基于docker-compose来部署:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
version: "3.7"

services:
 headscale:
 image: headscale/headscale:v0.23
 restart: unless-stopped
 container_name: headscale
 network_mode: host
 volumes:
 - /home/ubuntu/headscale/config:/etc/headscale
 - /home/ubuntu/example-domain.com:/certs/
 command: serve

上面为了简化网络,使用了host模式。重点是这里面的config配置怎么搞?你可以参考官方仓库中的示例稍作修改,主要是一些地址端口等小小变化,限于文章篇幅,以下仅diff出我的修改与原版差异:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
ubuntu@mercedes:~/headscale/config$ diff config.yaml config.yaml.ori
13,14c13
< #server_url: http://127.0.0.1:8080
< server_url: "https://example-domain.com:8812"
---
> server_url: http://127.0.0.1:8080
19,20c18,19
< listen_addr: 0.0.0.0:8812
< #listen_addr: 127.0.0.1:8080
---
> # listen_addr: 0.0.0.0:8080
> listen_addr: 127.0.0.1:8080
80c79
< enabled: true
---
> enabled: false
221,222c220,221
< tls_cert_path: "/certs/example-domain.com.crt"
< tls_key_path: "/certs/example-domain.com.key"
---
> tls_cert_path: ""
> tls_key_path: ""

这样我们将配置及前面的SSL证书挂载到容器内供headscale使用。之后docker-compose up -d即可启动,注意检查一下启动日志是否一切正常。

在节点安装tailscale并注册

以我使用的Ubuntu系统,我们可以通过apt安装,其它系统官方也有很详细的安装指南。

1
2
3
4
5
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list

sudo apt-get update
sudo apt-get install tailscale

安装完毕后可以输入tailscale version查看一下版本。注意如果太老旧的版本和上面的headscale可能不太兼容哦,用当前最新一般没啥问题。

然后我们将node注册到headscale中:

1
sudo tailscale up --login-server=https://example-domain.com:8812 --accept-routes=true --accept-dns=false

正常会收到一个链接。

1
2
3
To authenticate, visit:

 https://example-domain.com:8812/register/mkey:316fabaca478e6d35190bb8e331004b33c0f8c52c98f202105af41465014a269

打开页面,根据指示在headscale中注册,在注册前,我们可能要先创建一个namespace(新版本叫user)了。

1
2
3
4
5
# 创建一个namespace(user),名叫union。别以为我写错了headscale,前一个是容器名,后一个是命令名
docker exec -it headscale headscale users create union

# 注册
headscale nodes register --user union --key mkey:316fabaca478e6d35190bb8e331004b33c0f8c52c98f202105af41465014a269

然后查看有如下结果:

1
2
# 查看节点列表
docker exec -it headscale headscale nodes list

可能会输出类似的信息,能看到自己对应主机online了就注册成功了。

开启或搭建中继服务DERP

这一步可选,因为tailscale在全球提供了不少节点。但可惜没有大陆内的,延迟可能会有一定影响。如果你希望更快,我这里给一个我的搭建命令,一行docker命令即可(注意它也同样使用了上面申请的SSL证书)。

1
2
3
4
5
6
7
8
9
docker run --restart always \
--name derper-with-verify-2024-10-15 \
--network host \
-v /home/ubuntu/example-domain.com/:/app/certs \
-v /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock \
-e DERP_CERT_MODE=manual \
-e DERP_ADDR=:12345 \
-e DERP_DOMAIN=example-domain.com \
fredliang/derper:latest

这个搭建好后,如果想让headscale使用我们自己搭建的DERP服务,则需要修改一下config。在DERP服务那一块:

1
2
paths:
 - /etc/headscale/derp.yaml

同时把这个文件挂载到容器内。这个文件的示例官方仓库也有,我的是这样的:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# /etc/headscale/derp.yaml
regions:
 900:
 regionid: 900
 regioncode: gz-mercedes
 regionname: Tencent Guangzhou
 nodes:
 - name: 900a
 regionid: 900
 hostname: example-domain.com
 stunport: 3478
 stunonly: false
 derpport: 12345

修改完上面headscale相关配置并重启后,我们可以在节点上执行tailscale netcheck看到定义的中继服务器信息。

加入其它节点并验证网络

除了云上我们购买的节点外,现在我们加入自己家里的一些虚拟机进来,让它未来成为混合集群的一部分。比如我想把家里一台Ubuntu24.04TLS作为节点一部分。这块操作和前面完全一致,先安装tailscale再注册到headscale,然后我们使用node list查看:

1
2
3
4
ubuntu@mercedes:~/headscale$ docker exec -it headscale headscale nodes list
ID | Hostname | Name | MachineKey | NodeKey | User | IP addresses | Ephemeral | Last seen | Expiration | Connected | Expired
1 | union-test | union-test | [j1D6O] | [aDlUn] | union | 100.64.0.3, fd7a:115c:a1e0::3 | false | 2024-10-22 06:46:41 | 0001-01-01 00:00:00 | online | no
2 | outside | outside | [TWC9a] | [MVLAj] | union | 100.64.0.4, fd7a:115c:a1e0::4 | false | 2024-10-22 06:46:40 | 0001-01-01 00:00:00 | online | no

如果你按上面部署了自己的DERP,相信速度会快一些。

1
2
3
4
5
6
$ tailscale ping 100.64.0.3
pong from union-test (100.64.0.3) via DERP(gz-mercedes) in 18ms
pong from union-test (100.64.0.3) via DERP(gz-mercedes) in 19ms
pong from union-test (100.64.0.3) via DERP(gz-mercedes) in 19ms
pong from union-test (100.64.0.3) via DERP(gz-mercedes) in 18ms
pong from union-test (100.64.0.3) via DERP(gz-mercedes) in 19ms

也可以使用tailscale status等检查网络状态。

到这里,我们的混合集群的网络部分已经Ready了,现在你可以看到这两台原本互不相干的机器,它们成为了一个局域网,并且是有着当前最安全的加密通信支撑的安全网络。接下来我们继续完成我们的集群部署以及功能验证。

补充题外话:tailscale好处不止于此,作为VPN,借助于它的Router能力,可以让你很方便的从外界安全的访问整个家庭网络,打通一切网络隔阂。鉴于此事于主题无关,就不在此多言啦。

部署集群

经过前文折腾,网络已经就绪。我已经迫不及待想上个集群了,虽然我曾经尝试过部署一个原生的kubernetes集群,但对于咱们小型集群,使用原生的Kubernetes占用资源还是太多了,我更推荐的还是k3s发行版。 我之前文章也提到过如何创建一个k3s集群。下面简单说明一下过程,并且增补一些实用技巧。

master节点

考虑到集群的稳定性,家里或许没有云上持续可靠,所以master节点可以考虑放在云上。但如果这个集群打算跑很久,云上VM你可能不续费的话,那么以家中节点为master也是可行的,要注意备份集群控制面数据即可。

1
2
3
4
5
6
7
8
9
export INSTALL_K3S_CHANNEL=v1.26
export K3S_TOKEN=union-k3s-on-2024-10-23

curl -sfL https://get.k3s.io | sh -s - server \
--disable=traefik \
--node-ip=100.64.0.4 \
--node-external-ip=<机器外网IP> \
--flannel-iface=tailscale0 \
--tls-san=<机器外网 >

我们在上面的outside(香港)机器上执行如上命令,即可部署一个k8s 1.26版本。对几个参数作个解释:

  • 关闭了默认的traefik。这是我的使用经验,因为未来我们使用它还需要再定义一些参数等(如自动申请证书啥的),故自行管理和部署更好。
  • 节点IP使用的是我们tailscale分配的局域网地址。这样集群内部通信才能走咱们上面的混合网络。
  • node-external-ip指定外网IP,用于LB等暴露时绑定的IP。
  • flannel-iface确保每个节点都使用其 Tailscale接口,不然底层flannel网络不知道应该基于这个设备转发。
  • tls-san需要指定机器的外网IP。为了你的k3s集群api未来可以从外部访问(kubeconfig)。

如果你安装时遇到网络问题进展缓慢,那么可以看下面node的部署,选择国内加速的镜像脚本即可。

你说都2024年10月了,还在用1.26版本?虽然我也尝试了较新的1.30版本,遇到了比较神奇的连接kubernetes api失败的报错,coredns一直起不来。

[INFO] plugin/ready: Still waiting on: “kubernetes”
[INFO] plugin/ready: Still waiting on: “kubernetes”
[INFO] plugin/ready: Still waiting on: “kubernetes”

有issue提可能和内核约莫有些关联,但是咱用的是Ubuntu24.04了,内核不应该低呀。也有issue提到tls-san添加上kubernetes svc ip,尝试均无效。想着换个版本呗?回退到1.26这个我常年用的老版本后,一切正常。此事颇为蹊跷,待我搞完这篇文章再来诊断诊断,在此记下来避免你也同样遇到。

node节点

我把master选择了云上机器,那么node我就选择加入自己家内部的虚拟机啦。我们部署一个node节点,在这里有意切换到一个国内安装脚本。

1
2
3
4
5
6
export INSTALL_K3S_CHANNEL=v1.26
export K3S_TOKEN=union-k3s-on-2024-10-23

curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -s - agent --server https://100.64.0.4:6443 \
--flannel-iface=tailscale0 \
--node-ip=100.64.0.3

启动成功后,我们就有了一个可以小小集群了。查看一下:

1
2
3
4
$ sudo k3s kubectl get nodes
NAME STATUS ROLES AGE VERSION
union-test Ready <none> 73s v1.30.5+k3s1
outside Ready control-plane,master 12h v1.30.5+k3s1

实用技巧

如果你遇到过镜像拉取很慢或者就完全拉不下来,可以为k3s server或agent配置一下代理,根据是master还是node情况来修改/etc/systemd/system/k3s.service.env/etc/systemd/system/k3s-agent.service.env文件,在末尾添加上https代理即可。比如

1
2
K3S_TOKEN='union-k3s-on-2024-10-23'
HTTPS_PROXY=http://<ip>:<port>

然后重启k3s/k3s-agent服务即可。

成果验收

如果上面都操作OK了,集群也调试就绪了。这么辛苦折腾一番,那么是时候收点好处了。我们搞个简单的,部署一个网站,网站实际托管在家里VM上,但是流量入口自云主机。你要问为什么这么搞?那是因为家宽都不让开放80/443端口呀,你得有云上主机才可以。

我们直接部署个nginx来演示,注意这里主动把它调度到家庭VM上(union-test节点)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-deployment
spec:
 replicas: 1
 selector:
 matchLabels:
 app: nginx
 template:
 metadata:
 labels:
 app: nginx
 spec:
 nodeName: union-test # 这里为了测试故意将它调度到家庭内部设备上
 containers:
 - name: nginx
 image: nginx:latest
 ports:
 - containerPort: 80

# k3s默认的servicelb提供了基于VM的LB能力,免费!
apiVersion: v1
kind: Service
metadata:
 name: nginx-service
spec:
 type: LoadBalancer
 selector:
 app: nginx
 ports:
 - protocol: TCP
 port: 80
 targetPort: 80

我们借助k3s中内置了servicelb,它通过iptables一系列规则,帮助你在无需使用云厂商的LB而达到对外暴露服务的目的。然后我们即可以直接访问云上主机的IP地址和端口即可实际访问到家里的计算资源。 跨主机访问Nginx

有这个基础,未来可想象的空间就比较大啦。例如将数据库部署在家庭 NAS 上,将机器学习模型训练任务放到家庭闲置 GPU 上等。咱家里大House不一定非得装小姐姐,也可以放点有用的数据嘛:)

后记

其实k3s的较新版本也直接支持集成tailscale了,并且也支持我们自己部署的headscale作为控制面,详情查看上面链接。不过我们一步步设置过来,对全过程更清晰明白啦!

如此折腾之后,便可充分的利用自建资源,再也不担心搞点研究碰上资源不够的窘境了。未来或许你只需要在云上留下一台最普通的机器即可,连啥负载都可以不放,想想可不要太香,哗哗的省钱。

本篇文章就写到这里,感谢阅读。如果期待看到更多玩法,欢迎点赞鼓励,您的支持是我写作的动力!

我是个爱折腾技术的工程师,也乐于分享。欢迎点赞、关注、分享,更欢迎一起探讨技术问题,共同学习,共同进步。为了获得更及时的文章推送,欢迎关注我的公众号:

扫码关注公众号