Zhiqiang's backyard https://strrl.dev/ Zhiqiang's backyard Hugo en Tue, 17 Mar 2026 23:26:11 -0700 我对 Spec Driven Development 的看法 https://strrl.dev/post/2026/my-thought-about-spec/ Tue, 17 Mar 2026 23:26:11 -0700 https://strrl.dev/post/2026/my-thought-about-spec/ <p>TLDR; 我觉得 Spec Driven Development 没有解决什么问题, 这套范式和方向是错误的. 银弹尚未出现, 软件工程的效率仍旧被限制. 即使 AGI 出现, 能够出现类人的智能表现, 这个困境短期内也无法解决.</p> <p>怎么解决? 我不知道. 没有圣杯, 没有银弹, 小团队快速迭代可以缓解这个问题, 这已经是目前的最优解了. Coding Agent 可以大幅优化这个最优解, 依旧是放大器那个领域, 放大了本来强的地方. 但是没有办法弥补这个缺陷, 解决这个目前.</p> <p>软件工程仍旧是从经验中学到的一些教训, 没有时间的沉淀是无法被验证有效的. 所幸好消息是, 现在 Coding Agent 的出现能让一切加速. 好的经验教训一般都比较容易接受, 然后作为工程师我们也能受益.</p> <p>一项好的设计或者经验, 可能会被独立的多次发现, 只要有一个发现者愿意分享出来而不是私藏, 整个业界就都能受益. 目前工程界和学术界的氛围还是比较开放的, 在这种氛围下, 我对我暂时不会被拉下这件事情还是挺乐观的.</p> <p>OK 回到 Spec Drive Development 这个话题.</p> <p>Spec Driven Development 已经出现有一段时间了. SpecKit 也差不多有半年了. SpecKit 的作者在微软里貌似也因为这个事情得到了晋升. Spec 这个概念在开发者和非开发者里也非常火.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2026/my-thought-about-spec/2026-03-17-23-28-49.png' alt="SpecKit GitHub Star History" /> </p> </p> <p>我在 SpecKit 刚出现的时候就开始用, 一开始感觉还不错, 比我从 0 开始迷茫 prompt 稳妥多了. 然而继续使用后发现, 我的时间陷入到了一轮又一轮提早设计, 脑内逻辑推演里. 最终生成的 Spec, Plan, Task, 只要覆盖到的地方, 执行的还不错, 但是一旦没有覆盖到就是一坨大便.</p> <p>所以我的开发过程变成了:</p> <ul> <li>本质上是瀑布流的项目拆解, 与 AI 对话, YY 出一堆似乎会发生的情况</li> <li>然后发现生成的代码在细节上有非常多的小问题, 而质量又很差, 我非常不想改</li> <li>一个巨大的 PR 就搁置在那里</li> </ul> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2026/my-thought-about-spec/2026-03-17-23-38-54.png' alt="" /> </p> </p> <p>后来 Claude Code Plan Mode 出现了, 我就再没用过 SpecKit. 当然, 那个 “只要覆盖不到的地方就是一坨大便” 的问题一直没有得到解决. 但至少我不需要提前脱离框架想那么多事情了.</p> <p>在很早之前, 我一直就是那个不怎么写文档, 而是坚信“好的代码是自解释”的这个流派的. 同时我期望中的的好代码需要拥有合理的假设, 尽量小的思维负担, 以及足够符合直觉的用法. 一个好的抽象应该是, “我的这个东西啊, 你只要这么这么用, 你就能保证能获得那样那样的效果, 你感兴趣的话可以来看看内部实现, 但是你不不想看, 也没关系, 照常用”.</p> <p>而 Spec Driven Development 就是像极了, 我有一份自然语言描述, 产品文档/PRD/Spec/随便你怎么叫, 然后我有某种机制去把代码对其到这个描述上. 之前这个机制是程序员, 现在这个机制是 Agent.</p> <p>作为程序员, 我们知道:</p> <ol> <li>文档和代码的表达能力之间, 有巨大的 gap, 我们无法在一个经过简化后的载体(spec)上表达完整的信息(product).</li> <li>需求会一直变, 代码一直变, 而文档往往跟不上. 一般来说最早的设计往往偏离真实情况非常远, 所有的软件都是一点一点变得复杂而且坚挺的. 而文档的更新是快速迭代中最弱的环节.</li> <li>代码中包含大量反直觉的的隐含知识和经验, 例如为什么软件的维护成本远高于开发成本, 为什么软件总是无法 bug free, 为什么需要可维护性特别重要. 这些都是工程师在软件工程领域从实践中得到的真实教训. 产品人, 营销人一直不关注这一点, 而 Coding Agent 把这一点百倍放大了.</li> </ol> <blockquote> <p>另外插一句对于用容忍 Vibe Coding 些烂代码的现象, 我觉得不能放任的一个原因是, 假设 Coding Agent 真的像我们一样思考, 那把 API 设计的简单易懂些, 同样也能减少 token 消耗, 减少犯错呀.</p></blockquote> <p>代码就是逻辑, 逻辑一定程度上也算数学吧, 数学很诚实, 不理解就是不理解, 学不会就是学不会. 现在有一个神奇海螺, 摇一摇就能吐出看上去还不错的东西, 感觉打磨打磨就可以赚钱了. 很多人在这个诱惑前丧失了理智, 丧失了思考的能力, 在一个自己不理解, 成功率不确定, 而且未经过时间认证的魔法盒子上装扮成一个小丑, 疯狂地表达自我.</p> <p>之前只是产品人, 营销人. 但是最近越来越多的工程师也开始妥协, 在巨大的诱惑前放弃自己的判断力. 甚至开始诱惑他人, 甚至在这条路上做产品, 让我很难受.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2026/my-thought-about-spec/2026-03-18-00-02-00.png' alt="" /> </p> </p> <p>春江水暖鸭先知, 我相信当奇点到来时, 一线工程师是最先知道的一批人.</p> <p>如果这一天到来, 我也会诚实地接受. 这件事情早晚会发生, 而且无论我做什么事情, 也无法加速或者减缓它的发生.</p> <p>最后, 我曾经问过朋友一个问题:</p> <ul> <li>“什么时候 Coding Agent 能一把过, 直接生成优雅到我能直接 approve 的代码?”</li> <li>“肯定在你失去工作之后.”</li> </ul> <p>我相信未来有一天 AI 一定能到达某种智能程度, 其表现之一是写出非常好的代码, 如果能够到达这个地步, 这就不是简单的我要不要丢工作的问题了, 而是整个社会, 整个人类群体的存在主义危机.</p> 20206 Week 03, 忙 https://strrl.dev/post/weekly-recap/2026/03-%E5%91%A8%E8%AE%B0-%E5%BF%99/ Sun, 18 Jan 2026 12:05:46 -0800 https://strrl.dev/post/weekly-recap/2026/03-%E5%91%A8%E8%AE%B0-%E5%BF%99/ <ul> <li>Anyway 这个周记我还是使用手敲输入; 尽管最近 typeless 好像挺火的, 但是感觉我的表达能力已经非常的支离破碎了. 多写点字, 让自己重新捡一捡结构表达的技巧.</li> <li>最近开始尝试 Claude Code + 各种 MCP / Plugin, 目前我能用上的只有 Linear 和 Notion, 而且还不是编程方面, 只是做自动化方面.</li> <li>把 Linear 接进来以后, 让 Claude Code 当我的 PM. 然后我发现了一件非常震惊的事情, 我现在同时在进行的 side project 有八个. 🤡 感觉自己很傻逼, 又陷入了之前那种忙不赢的状态了. 大概盘点一下手上在做的和想做的活: <ul> <li>Haye AI: 持续迭代, 正在做 Agent Mode 支持其他模型, 还有 <code>@</code> command 和 <code>/</code> command, 写了很多 native 集成, 但是还没做完, 抱歉大家久等了.</li> <li>s3 studio, 用 opendal wasm 做的通用 s3 file explorer: <a href="https://s3-studio.pages.dev">https://s3-studio.pages.dev</a></li> <li>wonder mesh net, 和之前的朋友一起做的, 希望把 self hosted 算力和已有的部署服务集成起来: <a href="https://github.com/STRRL/wonder-mesh-net">https://github.com/STRRL/wonder-mesh-net</a> . 尽量尽早上 Zeabur.</li> <li>Chaos Mesh, 最近持续修复小 bug, DNSChaos 的组件让 AI 重写了一份, 还没来得及 review..</li> <li>cloudflare tunnel ingress controller, 算是老项目了, 最近想捡起来把集成 Gateway API 加进去, 集成 scarf 看看用量.</li> <li>supabase operator, 是一个很有意思的项目, 想打平 self hosted supabase 和 supabase cloud 的 gap</li> <li>info cortex, 最早起源于 AI 推特总结, 现在想集成更多数据源 Gmail, Linear, GitHub 啥的, 然后变成一个类似于 ChatGPT Pulse 的东西.</li> <li>auto flavor, 从和 claude code 里的聊天记录找出我是如何表达不满的, 然后重新整理到 CLAUDE.md 里, 比如说“不要用 npm 用 pnpm”, “不要用行尾注释”.</li> </ul> </li> <li>还有一些其他的想法, 还没开始 <ul> <li>用 LLM 自动分析日志, 过滤噪音, 按照 pattern 分割事件流找 trend, outliers 找 insight.</li> <li>GTD Buddy, 这个蓄谋已久, 非常严格地帮我执行 GTD 五步实践</li> <li>napi.go / pbffi / pbipc, 希望有一个 schema first 的 ffi / ipc 框架, 解决写一个 native 实现(比如说 swift 里的 IOKit), 然后给 JS(electron), Go(wails) 来用</li> <li>duckdb 的 extension, 把 duckdb 作为查询前端, 接入其他的数据, 参考 supabase 的 foreign data 和 <a href="https://github.com/c4pt0r/agfs">https://github.com/c4pt0r/agfs</a></li> <li>想做 ipvs, iptables, nftables 还有流量的可视化 🤡·</li> </ul> </li> <li>最近又看到了一些浪漫主义鸡汤文, 典型代表 Dan Koe 的如何在一天内修好你的生活, 甚至还有一个更进一步的, 如何在一小时内修好你的生活. 吐了, 在粑粑里找点好吃的真难. 😇</li> <li>之前回归线下办公的时候, 预料到了每天通勤的 2 小时如果不能充分利用起来的话, 就会是极大的浪费. 当时 YY 了很多预案, 现在来看的话 <ul> <li>听点播客, 这个还行, 追了很多 商业就是这样 和 科技早知道 的内容, 杀了很多时间</li> <li>和 ChatGPT 讨论思路, 这个行不通, ChatGPT 的 Live Mode 没有思考, 只有一个简单的 WebSearch, 一旦有些深度的研究问题就歇逼了; 关于这点, 其实我有一个想法, 或许可以用 Happy Engineer 的思路, 用一个 Live Mode 的语音模型 + 一堆 Claude Code 真正做事, 可能不错. 但是我不想再加第九个项目了.</li> <li>使用 Happy Engineer 写代码. 完全不行, 在车上没有办法验收, Happy Engineer 也不稳定, 也没有办法边开车边思考正经的程序问题.</li> </ul> </li> </ul> Cloudflare Tunnel Ingress Controller https://strrl.dev/cloudflare-tunnel-ingress-controller/ Wed, 05 Nov 2025 00:00:00 +0800 https://strrl.dev/cloudflare-tunnel-ingress-controller/ <p>A Kubernetes Ingress Controller implementation using Cloudflare Tunnel for secure and easy exposure of services.</p> <p>Visit the project at: <a href="https://tunnel.strrl.dev">tunnel.strrl.dev</a></p> Week 45: 突然更新 https://strrl.dev/post/weekly-recap/2025/45-sudden-updates/ Mon, 03 Nov 2025 09:13:35 -0800 https://strrl.dev/post/weekly-recap/2025/45-sudden-updates/ <p>距离上一次更新又过去了 <code>45 - 27 = 18</code> 周, 四个半月; 说长不长, 说短不短, 足够发生很多事情;</p> <p>之前不知道犯了什么病了, 老是想用英语来写博客. 可能确实内心里还是有些 &ldquo;冲国人不能纯玩&rdquo; 的想法, 写点小东西都要考虑收获点什么.</p> <p>带来的后果就是基本启动不起来, 中文都不想写, 就更别提英文了. 既要又要还要的最终结果就是, 努力了几次以后, 最后还是归零.</p> <blockquote> <p>我看了下从 23 年第 8 周开始犯病写英文周报, 23 年 9 篇, 24 年 9 篇, 25 年 2 篇, 然后断更. 也不能说努力了几次吧, 这个事情阻力足够大, 系统搭出来以后也是脆弱的.</p></blockquote> <p>快速过下最近的状态吧;</p> <h2 id="工作">工作</h2> <h3 id="准备换新坑了">准备换新坑了</h3> <p>最近无论是主职还是 side project, 都在了解很多新玩意. 不是技术上的, 而是组织上的. 我个人来说, 经历大概是:</p> <ul> <li>看到了各种各样各个环节里各种会出错的事情了, 然后有点看开了. 对于如何做成一件事, 已经不去追求那个完美计划了. 笑死, 终于听劝了.</li> <li>太久 remote 工作导致和人交流少, 沟通技能还是显著下滑.</li> <li>现在的工作有点强度不够, 做的事情有意思程度不如 side project. 工作时间提不起劲, 总想着我还有更有意思/有意义的事情要做.</li> <li>然后和 chatgpt 聊了以后, 它管我这叫 &ldquo;结构性自由焦虑&rdquo;, 个体面对过多的自由和选择时产生的焦虑感. (在做 A 和做 B 之间选择了刷推.)</li> </ul> <p>于是准备换个环境试试了; 找到了一个</p> <ul> <li>HQ 在温哥华的, 有趣的 tech startup 公司, SRE 岗;</li> <li>默认 5 天 RTO 工作, 但是我看到有人也远程工作, 应该也可以申请.</li> <li>线下队友有白人, 有亚裔; 远程有欧洲人同事, 文化交流拉满, 很刺激.</li> <li>做的事情应该很有趣(反正面试的时候 VP of Engineering 给我画好饼了)</li> <li>团队氛围可能还有些 push, 评价网站上说这家公司, toxic culture, 加班重(我很好奇北美这边所谓加班重能到啥程度); 但是 VP 说他们想把公司做成工程师会觉得开心的地方, 我自己去线下面试的时候也是能感觉到还不错的.</li> </ul> <p>总体来说给我的感觉像极了 19 年去面试微店的那个感觉.</p> <p>之前我应该也提高过好几次, 在微店的那段时间是我成长最快的经历, 所以我也很是期待接下来的发展了.</p> <p>我不是那种能够悠闲地消磨时间的那种人, 我一直想面对挑战. (贱不贱呐)</p> <p>这又是一个尝试, 我觉得我又在尝试把自己的弦上紧, 然后在规律中重新找回节奏.</p> <p>祝愿我能够安全上车, 善待自己, 有点产出.</p> <p>在 GitRoll 的日子里还是非常快乐的, 有充分的自由度去做 AI 相关的应用. 也和团队进行了很多次不同领域的尝试, 最近大家应该是也要找到新的方向了. 我离开前也内推了一位我的朋友来 GitRoll, 不算是接班, 只是有这么个机会, 如果能合作的话对双方都好. GitRoll 的 founder 们也是目前我见过不吹不装, 很能踏实落地的一波人了. 希望 GitRoll 在未来能够发展得越来越好!</p> <h3 id="ai-coding-agent-或者我们就说-vibe-coding">AI Coding Agent, 或者我们就说 vibe coding</h3> <p>说起来惭愧, 高强度使用 vibe coding 这段时间, 我正好博客断更了.</p> <p>我一直惊叹于人的适应力从我觉得 AI Coding Agent is a thing, 也就还不到半年. 软件行业在依旧浅薄的同时, 更加野蛮生长.</p> <p>我认真对待 AI Coding Agent, 开始尝试写大规模项目的时候, 是从 Claude 4 系列发布后开始尝试的. 大约是 2025 年 5 月 or 6 月, 我还在用 Cursor. Cursor 的 Composer Mode 后来变成 Agent Mode, 差不多经历了 代码片段 -&gt; 单文件 -&gt; 多文件 -&gt; 渐进交互式结对编程.</p> <p>我开始高强度尝试, 这是 5 6 7 月 Cursor 的账单:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2025/45-sudden-updates/2025-11-05-09-04-45.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2025/45-sudden-updates/2025-11-05-09-05-00.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2025/45-sudden-updates/2025-11-05-09-05-10.png' alt="" /> </p> </p> <blockquote> <p>这也是整个行业对 LLM 使用的渐进, 从单次生成, 到 langchain / dify / n8n 为代表的工作流, 再到 Agent 模式(Coding Agent 明显是跑出来了, 电话客服 Agent 之前我看 demo 觉得效果我已经满意了, 我觉得也很快了), 也就这几个月. 夸张点, 真有种 AI 圈里一天, 外面世界一年的感觉了.</p></blockquote> <blockquote> <p>哦, 中间也不乏 Cluely, Poke 这种 pet.com 时刻.</p></blockquote> <h2 id="生活">生活</h2> <h3 id="adhd">ADHD</h3> <p>最近吃了 Vyvanse 以后, 整个人其实状态不像之前. 我不能说跟之前不一样就不好, 但是确实有好的有不好的.</p> <p>好的地方:</p> <ul> <li>做事情明显更专注了</li> <li>作息开始阳间起来</li> <li>之前不想做的事情, 现在明显没有那么厌恶了</li> <li>不再 panic, 我已经很久没有 &ldquo;吃饭的时候想到还未完成的工作, 手就开始发抖&rdquo; 这种体验了</li> <li>游戏操作变好了, 英雄联盟之前很多理论上会的连招, 在激烈打团的时候, 可以很平静地操作出来</li> </ul> <p>不好的地方:</p> <ul> <li>欲望低下, 没有之前那么快乐; 做饭吃饭都没那么快乐了.</li> <li>ADHD &ldquo;接话茬&rdquo; 这个技能明显被压制. 在药效生效期间, 我不再有欲望接别人的话. 无论是老婆的还是朋友的. 之前有可能聊天的时候我能接不停, 现在我可能只能做到保持礼貌的微笑.</li> <li>无法午睡, 喝咖啡和喝茶有可能会更加上头.</li> </ul> <p>整体人变得 平静 和 无趣.</p> <h2 id="线下面基-youtuber-偶像们">线下面基 youtuber 偶像们</h2> <p>这段时间有幸和两位 youtuber 见了面, 一位是一口新饭的 Ray, 一位是 Trucker Gang.</p> <p>有才华有积淀的人还是很多, 每个人也很不一样. 还是要努力好好活着.</p> ADHD Treatment https://strrl.dev/post/2025/adhd-treatment/ Sun, 28 Sep 2025 11:08:41 -0700 https://strrl.dev/post/2025/adhd-treatment/ <h2 id="tldr">TLDR;</h2> <p>I get diagnosed as ADHD, and get some drugs (Vyvanse). It works pretty well, and changed my life a lot.</p> <p>I conducted a personal case study this weekend: I didn&rsquo;t take my Vyvanse for two days, and the results were a noticeable increase in pacing around, getting easily distracted, and feeling irritable towards my family.</p> <p>For friends who suspect they might have ADHD, and feel it has already affected life, study, work, and relationship, I highly recommend using self-assessment scales for self-testing:</p> <p><a href="https://qingshanasd.cn/quotients/adhd/">ADHD SELF-REPORT SCALE / ASRS</a></p> <p>Understand yourself, and take action. It will save your life.</p> <h2 id="my-story">My Story</h2> <blockquote> <p>I originally wrote a lot of content here, but I realized I hadn&rsquo;t organized it well. So I deleted it.</p> <p>Overall, I&rsquo;m still exploring the topic of focus and productivity and don&rsquo;t yet have any best practices worth sharing.</p> <p>The changes brought about by medication are very noticeable, both the <strong>benefits</strong> and the <strong>side effects</strong>.</p></blockquote> <blockquote> <p>Oh, by the way, there isn&rsquo;t one single certain technology or technique that can perfectly solve the problem of high productivity, nor there is certain one that can perfectly solve the problem of how to live a happy life.</p> <p>&ldquo;You do action A and you get result B&rdquo;. Does it sound familiar? Does it sound simple? I call it &ldquo;ROMANTIC narrative&rdquo;, which is heavily used by content creators, marketing people and sales people.</p> <p>And what&rsquo;s moore, simple != easy</p> <p>Placing all hope on a specific medication, a specific app, a specific behavior pattern, or a specific thinking paradigm is <strong>NOT</strong> RELIABLE. Any one of these, take a try, might show short-term effects and make you feel better.</p> <p>That&rsquo;s just &ldquo;feel better&rdquo;, and &ldquo;feel better&rdquo; is fine during exploring new stuff. But in the long run, it&rsquo;s merely a brief period of trial and error. Once the external environment changes or new insights emerge internally, it might no longer be suitable for you. If you don&rsquo;t continually reflect and update it, that technique will become obsolete.</p> <blockquote> <p>Just like my weekly recap, haha.</p></blockquote> <p>What we need to seek is a system, and this system can only be gradually acquired through continuous self-exploration, making mistakes, failing, and summarizing.</p> <p>Make a plan, try them all.</p></blockquote> <blockquote> <p>OK that&rsquo;s enough, these words make me feel I am like a old people who always intent to teach somebody else, just like a 老登.</p></blockquote> <h2 id="qa-more-things-i-want-to-share">Q&amp;A, More Things I Want to Share</h2> <p>If you have other questions, just feel free to ask me, leaving a comment or DM me.</p> <p>You could find me at <a href="https://bento.me/zhiqiang">https://bento.me/zhiqiang</a></p> <h3 id="is-adhd-a-buzz-word-on-social-media-and-new-business-trap-like-sugar-and-insulin">is ADHD a buzz word on social media and new business trap? like Sugar and Insulin</h3> <p>I am not sure. It might be, but it&rsquo;s not important.</p> <h3 id="could-behavior-therapy-work">could &ldquo;Behavior Therapy&rdquo; work?</h3> <p>Yes, it works. But it could NOT work as well as drugs.</p> <p>If the effect of medication is 95 points, the effect of Behavior Therapy might be 20-30 points.</p> <h2 id="useful-resources">Useful Resources</h2> <ul> <li><a href="https://borretti.me/article/notes-on-managing-adhd">Notes on Managing ADHD</a></li> </ul> Panorama Support https://strrl.dev/post/2025/panorama/ Sun, 31 Aug 2025 20:54:37 -0700 https://strrl.dev/post/2025/panorama/ <h2 id="beautiful-panoramic-views">Beautiful Panoramic Views</h2> <p>Check out these amazing 360° panoramic views! You can click and drag to look around, nya~ (。◕‿◕。)</p> <h3 id="burnaby-mountain-park">Burnaby Mountain Park</h3> <script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script><div class="panorama-container" id="container-panorama-0" style="width: 100%; height: 500px; position: relative;"> <div class="panorama-title">Burnaby Mountain Park - Stunning Mountain Vista</div> <div id="viewer-panorama-0" style="width: 100%; height: 100%;" data-panorama-url="https://strrl.dev/post/2025/panorama/Bunarby%20Mountain%20Park.jpg" data-rotation="0 0 0"></div> </div> <script> (function() { console.log('Panorama script starting for panorama-0'); var checkAFrame = function() { console.log('checkAFrame called for panorama-0, AFRAME:', typeof AFRAME); if (typeof AFRAME === 'undefined') { console.log('AFRAME not ready, waiting for panorama-0...'); setTimeout(checkAFrame, 100); return; } console.log('AFRAME is ready for panorama-0!'); var container = document.getElementById('viewer-panorama-0'); if (!container) { console.error('Container not found for viewer-panorama-0'); return; } var panoramaUrl = container.getAttribute('data-panorama-url'); var rotation = container.getAttribute('data-rotation'); console.log('Loading panorama panorama-0 from:', panoramaUrl); console.log('Full URL will be:', window.location.origin + panoramaUrl); if (!panoramaUrl.startsWith('http://') && !panoramaUrl.startsWith('https://')) { panoramaUrl = window.location.origin + panoramaUrl; } console.log('Final panorama URL:', panoramaUrl); var scene = document.createElement('a-scene'); scene.setAttribute('embedded', ''); scene.setAttribute('loading-screen', 'enabled: false'); scene.setAttribute('vr-mode-ui', 'enabled: false'); scene.setAttribute('device-orientation-permission-ui', 'enabled: false'); scene.style.width = '100%'; scene.style.height = '100%'; var assets = document.createElement('a-assets'); var img = document.createElement('img'); img.id = 'panorama-panorama-0'; img.src = panoramaUrl; img.setAttribute('crossorigin', 'anonymous'); assets.appendChild(img); var sky = document.createElement('a-sky'); sky.setAttribute('src', '#panorama-panorama-0'); sky.setAttribute('rotation', rotation); sky.setAttribute('radius', '10'); var camera = document.createElement('a-camera'); camera.setAttribute('look-controls', 'reverseMouseDrag: true'); camera.setAttribute('wasd-controls', 'enabled: false'); camera.setAttribute('position', '0 0 0'); camera.setAttribute('fov', '75'); scene.appendChild(assets); scene.appendChild(sky); scene.appendChild(camera); container.innerHTML = ''; container.appendChild(scene); scene.addEventListener('loaded', function() { console.log('A-Frame panorama panorama-0 loaded'); }); }; console.log('Document ready state for panorama-0:', document.readyState); if (document.readyState === 'loading') { console.log('Adding DOMContentLoaded listener for panorama-0'); document.addEventListener('DOMContentLoaded', checkAFrame); } else { console.log('Calling checkAFrame immediately for panorama-0'); checkAFrame(); } console.log('Script setup complete for panorama-0'); })(); </script> <style> .panorama-container { margin: 1em 0; border-radius: 4px; overflow: hidden; background: #000; position: relative; } .panorama-title { position: absolute; bottom: 10px; left: 10px; color: white; background: rgba(0, 0, 0, 0.7); padding: 5px 10px; border-radius: 3px; font-size: 14px; z-index: 10; pointer-events: none; } .a-enter-vr { display: none !important; } .a-orientation-modal { display: none !important; } .a-loader-title { display: none !important; } </style> <h3 id="little-waterfall">Little Waterfall</h3> <div class="panorama-container" id="container-panorama-1" style="width: 100%; height: 500px; position: relative;"> <div class="panorama-title">Little Waterfall - Peaceful Nature Scene</div> <div id="viewer-panorama-1" style="width: 100%; height: 100%;" data-panorama-url="https://strrl.dev/post/2025/panorama/Little%20Waterfall.jpg" data-rotation="0 0 0"></div> </div> <script> (function() { console.log('Panorama script starting for panorama-1'); var checkAFrame = function() { console.log('checkAFrame called for panorama-1, AFRAME:', typeof AFRAME); if (typeof AFRAME === 'undefined') { console.log('AFRAME not ready, waiting for panorama-1...'); setTimeout(checkAFrame, 100); return; } console.log('AFRAME is ready for panorama-1!'); var container = document.getElementById('viewer-panorama-1'); if (!container) { console.error('Container not found for viewer-panorama-1'); return; } var panoramaUrl = container.getAttribute('data-panorama-url'); var rotation = container.getAttribute('data-rotation'); console.log('Loading panorama panorama-1 from:', panoramaUrl); console.log('Full URL will be:', window.location.origin + panoramaUrl); if (!panoramaUrl.startsWith('http://') && !panoramaUrl.startsWith('https://')) { panoramaUrl = window.location.origin + panoramaUrl; } console.log('Final panorama URL:', panoramaUrl); var scene = document.createElement('a-scene'); scene.setAttribute('embedded', ''); scene.setAttribute('loading-screen', 'enabled: false'); scene.setAttribute('vr-mode-ui', 'enabled: false'); scene.setAttribute('device-orientation-permission-ui', 'enabled: false'); scene.style.width = '100%'; scene.style.height = '100%'; var assets = document.createElement('a-assets'); var img = document.createElement('img'); img.id = 'panorama-panorama-1'; img.src = panoramaUrl; img.setAttribute('crossorigin', 'anonymous'); assets.appendChild(img); var sky = document.createElement('a-sky'); sky.setAttribute('src', '#panorama-panorama-1'); sky.setAttribute('rotation', rotation); sky.setAttribute('radius', '10'); var camera = document.createElement('a-camera'); camera.setAttribute('look-controls', 'reverseMouseDrag: true'); camera.setAttribute('wasd-controls', 'enabled: false'); camera.setAttribute('position', '0 0 0'); camera.setAttribute('fov', '75'); scene.appendChild(assets); scene.appendChild(sky); scene.appendChild(camera); container.innerHTML = ''; container.appendChild(scene); scene.addEventListener('loaded', function() { console.log('A-Frame panorama panorama-1 loaded'); }); }; console.log('Document ready state for panorama-1:', document.readyState); if (document.readyState === 'loading') { console.log('Adding DOMContentLoaded listener for panorama-1'); document.addEventListener('DOMContentLoaded', checkAFrame); } else { console.log('Calling checkAFrame immediately for panorama-1'); checkAFrame(); } console.log('Script setup complete for panorama-1'); })(); </script> <style> .panorama-container { margin: 1em 0; border-radius: 4px; overflow: hidden; background: #000; position: relative; } .panorama-title { position: absolute; bottom: 10px; left: 10px; color: white; background: rgba(0, 0, 0, 0.7); padding: 5px 10px; border-radius: 3px; font-size: 14px; z-index: 10; pointer-events: none; } .a-enter-vr { display: none !important; } .a-orientation-modal { display: none !important; } .a-loader-title { display: none !important; } </style> <h3 id="simon-fraser-university">Simon Fraser University</h3> <div class="panorama-container" id="container-panorama-2" style="width: 100%; height: 500px; position: relative;"> <div class="panorama-title">SFU Campus - Academic Excellence</div> <div id="viewer-panorama-2" style="width: 100%; height: 100%;" data-panorama-url="https://strrl.dev/post/2025/panorama/SFU.jpg" data-rotation="0 0 0"></div> </div> <script> (function() { console.log('Panorama script starting for panorama-2'); var checkAFrame = function() { console.log('checkAFrame called for panorama-2, AFRAME:', typeof AFRAME); if (typeof AFRAME === 'undefined') { console.log('AFRAME not ready, waiting for panorama-2...'); setTimeout(checkAFrame, 100); return; } console.log('AFRAME is ready for panorama-2!'); var container = document.getElementById('viewer-panorama-2'); if (!container) { console.error('Container not found for viewer-panorama-2'); return; } var panoramaUrl = container.getAttribute('data-panorama-url'); var rotation = container.getAttribute('data-rotation'); console.log('Loading panorama panorama-2 from:', panoramaUrl); console.log('Full URL will be:', window.location.origin + panoramaUrl); if (!panoramaUrl.startsWith('http://') && !panoramaUrl.startsWith('https://')) { panoramaUrl = window.location.origin + panoramaUrl; } console.log('Final panorama URL:', panoramaUrl); var scene = document.createElement('a-scene'); scene.setAttribute('embedded', ''); scene.setAttribute('loading-screen', 'enabled: false'); scene.setAttribute('vr-mode-ui', 'enabled: false'); scene.setAttribute('device-orientation-permission-ui', 'enabled: false'); scene.style.width = '100%'; scene.style.height = '100%'; var assets = document.createElement('a-assets'); var img = document.createElement('img'); img.id = 'panorama-panorama-2'; img.src = panoramaUrl; img.setAttribute('crossorigin', 'anonymous'); assets.appendChild(img); var sky = document.createElement('a-sky'); sky.setAttribute('src', '#panorama-panorama-2'); sky.setAttribute('rotation', rotation); sky.setAttribute('radius', '10'); var camera = document.createElement('a-camera'); camera.setAttribute('look-controls', 'reverseMouseDrag: true'); camera.setAttribute('wasd-controls', 'enabled: false'); camera.setAttribute('position', '0 0 0'); camera.setAttribute('fov', '75'); scene.appendChild(assets); scene.appendChild(sky); scene.appendChild(camera); container.innerHTML = ''; container.appendChild(scene); scene.addEventListener('loaded', function() { console.log('A-Frame panorama panorama-2 loaded'); }); }; console.log('Document ready state for panorama-2:', document.readyState); if (document.readyState === 'loading') { console.log('Adding DOMContentLoaded listener for panorama-2'); document.addEventListener('DOMContentLoaded', checkAFrame); } else { console.log('Calling checkAFrame immediately for panorama-2'); checkAFrame(); } console.log('Script setup complete for panorama-2'); })(); </script> <style> .panorama-container { margin: 1em 0; border-radius: 4px; overflow: hidden; background: #000; position: relative; } .panorama-title { position: absolute; bottom: 10px; left: 10px; color: white; background: rgba(0, 0, 0, 0.7); padding: 5px 10px; border-radius: 3px; font-size: 14px; z-index: 10; pointer-events: none; } .a-enter-vr { display: none !important; } .a-orientation-modal { display: none !important; } .a-loader-title { display: none !important; } </style> Beast Mode for Claude Code(and other Code Agents) https://strrl.dev/post/2025/beast-mode-for-claude-code/ Thu, 24 Jul 2025 16:07:33 -0700 https://strrl.dev/post/2025/beast-mode-for-claude-code/ <h2 id="important-updates">Important Updates</h2> <ul> <li>Update at March 1, 2026. The &ldquo;Beast Mode&rdquo; is totally outdated. Current SOTA model(opus 4.5, opus 4.6, sonnet 4.6) could do much better out-of-the-box.</li> <li>Update at Oct 11, 2025. With Claude Sonnet 4.5 and gpt-5-codex, I think I do not need beast mode anymore. Just give a hint, read doc from &ldquo;https://<doc-site>&rdquo; and follow the instruction, AI Coding Agent will handle the rest.</li> </ul> <h2 id="so-what-is-beast-mode">So what is Beast Mode?</h2> <p>It&rsquo;s a typical prompt engineering / context engineering trick that allows you to get the most out of Claude Code or other code agents.</p> <p>Reference:</p> <ul> <li><a href="https://gist.github.com/burkeholland/88af0249c4b6aff3820bf37898c8bacf">https://gist.github.com/burkeholland/88af0249c4b6aff3820bf37898c8bacf</a></li> <li><a href="https://burkeholland.github.io/posts/beast-mode-3-1/">https://burkeholland.github.io/posts/beast-mode-3-1/</a></li> </ul> <h2 id="how-to-enable-beast-mode">How to enable Beast Mode?</h2> <p>for <code>claude</code>, <code>gemini</code> or <code>qwen</code> just copy, paste and run the following instruction in your claude code session:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Please list all files under https://gist.github.com/burkeholland/88af0249c4b6aff3820bf37898c8bacf by api.github.com, pick the latest beast mode version, and replace the toolcalls with your own tool calls. </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Then write the updated version into CLAUDE.md file, always follow the instructions/pattern. </span></span></code></pre></td></tr></table> </div> </div> 2025 Week 27: Quick Update https://strrl.dev/post/weekly-recap/2025/27-quick-updates/ Sat, 05 Jul 2025 14:49:59 -0700 https://strrl.dev/post/weekly-recap/2025/27-quick-updates/ <p>Long time no see!</p> <p>It has been a while since last time I wrote something.</p> <p>I did have some expressions to share. I logged them into my Notion, and the next time I review them days later, I think, fine, that thing is not that important, I can just let it go.</p> <h2 id="professional-stuff">Professional Stuff</h2> <h3 id="ai-coding-assistant">AI Coding Assistant</h3> <p>The last time I talk about AI coding assistant was in <a href="https://strrl.dev/post/weekly-recap/2024/46-quick-updates/">2024 Week 46 Weekly Recap</a>.</p> <p>Half years later, the coding assistant is getting better and better. It could help me</p> <ul> <li>understand a specific design / how it works in a large codebase</li> <li>build a mid-level solution <strong>fully automatic</strong></li> </ul> <p>Some cases like:</p> <ul> <li>understanding how cherry-studio, lobechat, chatbox build their tests with react testing library</li> <li>understanding what&rsquo;re the differences between how RAG solutions actually build</li> <li>build some native modules for <a href="https://haye.ai">Haye</a> app, integrating with macOS API</li> <li>help me write some ansible playbook based on the existing playbooks as reference</li> </ul> <p>Currently, my first choice is <a href="https://docs.anthropic.com/en/docs/claude-code/overview">Claude Code</a>, the most important reason is that it has a very comprehensive &ldquo;plan mode&rdquo;,(use <code>shift</code> + <code>tab</code> to switch modes, until it shows &ldquo;plan mode on&rdquo;)</p> <p> <p class="md__image"> <img src='./plan-mode.png' alt="Claude Code Plan Mode" /> </p> </p> <p>Just like describing the plan in the issue before opening a PR, it gives me a chance to tuning the plan and make it more and more accurate and tasteful.</p> <p>I do not like <a href="https://cursor.com/">Cursor</a> anymore, not about the pricing, but about the performance.</p> <p>I do not care that I would pay more money for a better product, but I can not stand the product is not working well, and its behavior just keeps changing without any explanation.</p> <p> <p class="md__image"> <img src='./cursor-usage.png' alt="My Cursor Usage" /> </p> </p> <p>I have no idea what really happened. Anyway, I will keep trying different products, and use the best one.</p> <p>And there is another huge issues when I using AI coding assistant, that is, What should I do when the AI is responding?</p> <p>I have no idea, I cannot switch to another window because it will break the my thinking flow, and it will cost more time to switch back and forth.</p> <p>I just stay here and wait, thinking what it might going wrong, and the tactic to solve the problem, that makes me feel like I am a dumb.</p> <h2 id="personal-stuff">Personal Stuff</h2> <h3 id="go-get-a-ps5-pro-console">Go get a PS5 Pro console</h3> <p>Recently I found that I played too much League of Legends, and I need to find a way to get rid of it.</p> <p>Playing video games and watching anime are two major pleasures for me, but playing PvP games is not a good way to enjoy&hellip;</p> <p>So as the title says, I am going to get a PS5 Pro console. &lt;3</p> Saturday https://strrl.dev/post/2025/a-saturday/ Sat, 31 May 2025 14:50:57 -0700 https://strrl.dev/post/2025/a-saturday/ <p>Saturday, the weather is nice.</p> <p>I originally wanted to just bring a book to the library and read for the afternoon.</p> <p>But I remembered that I haven&rsquo;t finished things before the deadline (DDL), so I had to bring my computer as well.</p> 2024 Review: 40 questions to ask yourself every year https://strrl.dev/post/2025/40-questions/ Mon, 10 Feb 2025 08:17:09 -0800 https://strrl.dev/post/2025/40-questions/ <p>Several days ago, I read <a href="https://xuanwo.io/2025/01-2024-review/">Xuanwo&rsquo;s 2024 Review - 40 questions to myself</a>, I think I should also make one, to make my life look like it is not that boring.</p> <h2 id="1what-did-you-do-this-year-that-youd-never-done-before">1.What did you do this year that you’d never done before?</h2> <ul> <li>We had a wedding.</li> <li>I started a new career as indie developer, bootstrapped <a href="https://boringboring.design/">Boring Design</a></li> <li>I moved from Hangzhou to Vancouver.</li> <li>I started to learn web 3 systematically.</li> </ul> <h2 id="2-did-you-keep-your-new-years-resolutions">2. Did you keep your new year’s resolutions?</h2> <p>No. I do not think I have new year&rsquo;s resolution. Should I make one?</p> <h2 id="3-did-anyone-close-to-you-give-birth">3. Did anyone close to you give birth?</h2> <p>No, or I did not remember.</p> <h2 id="4-did-anyone-close-to-you-die">4. Did anyone close to you die?</h2> <p>My grandma is gone.</p> <h2 id="5-what-citiesstatescountries-did-you-visit">5. What cities/states/countries did you visit?</h2> <p>Because of the wedding, we drove across Zhejiang, Shandong, Hunan, as a triangle.</p> <p>Otherwise, Chiang Mai, Vancouver.</p> <h2 id="6-what-would-you-like-to-have-next-year-that-you-lacked-this-year">6. What would you like to have next year that you lacked this year?</h2> <p>A health and happiness routine.</p> <h2 id="7-what-dates-from-this-year-will-remain-etched-upon-your-memory-and-why">7. What date(s) from this year will remain etched upon your memory, and why?</h2> <p>The day we arrived at Vancouver, it started my new adventure, let me face to the new challenges.</p> <h2 id="8-what-was-your-biggest-achievement-of-the-year">8. What was your biggest achievement of the year?</h2> <p>Bootstrap <a href="https://boringboring.design/">Boring Design</a>.</p> <h2 id="9-what-was-your-biggest-failure">9. What was your biggest failure?</h2> <p>I lost lots of my productivity in the final months of 2024. Until now I did not find them back.</p> <h2 id="10-what-other-hardships-did-you-face">10. What other hardships did you face?</h2> <p>I need to build connections with local communities.</p> <h2 id="11-did-you-suffer-illness-or-injury">11. Did you suffer illness or injury?</h2> <p>I suffered from middle ear issue, several times.</p> <h2 id="12-what-was-the-best-thing-you-bought">12. What was the best thing you bought?</h2> <p>IKEA ergonomic chair: &ldquo;STYRSPEL&rdquo;.</p> <h2 id="13-whose-behavior-merited-celebration">13. Whose behavior merited celebration?</h2> <p>No idea.</p> <h2 id="14-whose-behavior-made-you-appalled">14. Whose behavior made you appalled?</h2> <p>A series of behaviors from Donald Trump, including launching memecoins, tariffs policy with Canada and Mexico, DOGE;</p> <p>I did not care about politics in 2016, but I do now. He is not a normal politician, I still have no idea what he will bring in the next 4 years.</p> <h2 id="15-where-did-most-of-your-money-go">15. Where did most of your money go?</h2> <p>Living cost.</p> <p>After moving to Vancouver, it will cost me about 3000 CAD just for renting. Food prices are 2x-5x compared to China.</p> <h2 id="16-what-did-you-get-really-really-really-excited-about">16. What did you get really, really, really excited about?</h2> <p>I do not know. That&rsquo;s a big problem.</p> <h2 id="17-what-song-will-always-remind-you-of-this-year">17. What song will always remind you of this year?</h2> <p>星に駆られて, the main theme song of Monster Hunter World.</p> <h2 id="18-compared-to-this-time-last-year-are-you-happier-or-sadder-thinner-or-fatter-richer-or-poorer">18. Compared to this time last year, are you: happier or sadder? Thinner or fatter? Richer or poorer?</h2> <p>sadder, thinner, relatively poorer</p> <h2 id="19-what-do-you-wish-youd-done-more-of">19. What do you wish you’d done more of?</h2> <p>Ship more products, including marketing.</p> <h2 id="20-what-do-you-wish-youd-done-less-of">20. What do you wish you’d done less of?</h2> <p>Spend less time on social media and youtube.</p> <h2 id="21how-are-you-spending-the-holidays">21.How are you spending the holidays?</h2> <p>Keep working.</p> <h2 id="22-did-you-fall-in-love-this-year">22. Did you fall in love this year?</h2> <p>Always with my wife.</p> <h2 id="23-do-you-hate-anyone-now-that-you-didnt-hate-this-time-last-year">23. Do you hate anyone now that you didn’t hate this time last year?</h2> <p>I did not hate somebody in recent years.</p> <h2 id="24-what-was-your-favorite-show">24. What was your favorite show?</h2> <p>拉面赤猫 / ラーメン赤猫 / Red Cat Ramen will be my favorite for this year.</p> <h2 id="25-what-was-the-best-book-you-read">25. What was the best book you read?</h2> <p>小岛经济学 / How An Economy Grows And Why It Crashes</p> <h2 id="26-what-was-your-greatest-musical-discovery-of-the-year">26. What was your greatest musical discovery of the year?</h2> <p>Sadly, no.</p> <h2 id="27-what-was-your-favorite-film">27. What was your favorite film?</h2> <p>It seems I did not watch a full movie this year.</p> <h2 id="28-what-was-your-favorite-meal">28. What was your favorite meal?</h2> <p>妞妞家烧烤</p> <p>It&rsquo;s a BBQ restaurant that companion with us in Hangzhou, from 2019 until we left Hangzhou.</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">问了下良渚村里附近的 妞妞家烧烤 也是他们家的!<br><br>老板今天在那边<br><br>天呐太有缘分了 🥰🥰🥰 <a href="https://t.co/YomIO7X4mg">https://t.co/YomIO7X4mg</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1705906466832695509?ref_src=twsrc%5Etfw">September 24, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <h2 id="29-what-did-you-want-and-get">29. What did you want and get?</h2> <p>The chance that I could do both of daytime and nighttime job.</p> <h2 id="30-what-did-you-want-and-not-get">30. What did you want and not get?</h2> <p>Abilities about marketing, sales and presentation.</p> <p>Tesla Model Y.</p> <h2 id="31-what-did-you-do-on-your-birthday">31. What did you do on your birthday?</h2> <p>I did not remember.</p> <p>Working?</p> <h2 id="32-what-one-thing-would-have-made-your-year-immeasurably-more-satisfying">32. What one thing would have made your year immeasurably more satisfying?</h2> <p>Keeping delivery products.</p> <h2 id="33-how-would-you-describe-your-personal-fashion-this-year">33. How would you describe your personal fashion this year?</h2> <p>simple dumb</p> <h2 id="34-what-kept-you-sane">34. What kept you sane?</h2> <p>Sleep.</p> <h2 id="35-which-celebritypublic-figure-did-you-admire-the-most">35. Which celebrity/public figure did you admire the most?</h2> <p>I am not sure.</p> <h2 id="36-what-political-issue-stirred-you-the-most">36. What political issue stirred you the most?</h2> <p>I lives in Canada now, so I am worry about the policy and relation ship between US and Canada.</p> <h2 id="37-who-did-you-miss">37. Who did you miss?</h2> <p>Teammates in Chaos Mesh team, friends in Liangzhu.</p> <h2 id="38-who-was-the-best-new-person-you-met">38. Who was the best new person you met?</h2> <p>Nestor Balce, he is the co-founder of Vancouver Linux User Group.</p> <h2 id="39-what-valuable-life-lesson-did-you-learn-this-year">39. What valuable life lesson did you learn this year?</h2> <p>Business is more about sales.</p> <h2 id="40-what-is-a-quote-that-sums-up-your-year">40. What is a quote that sums up your year?</h2> <p>I do not know.</p> 2025 Week 05: Quick Updates https://strrl.dev/post/weekly-recap/2025/05-quick-updates/ Sat, 01 Feb 2025 15:16:45 -0800 https://strrl.dev/post/weekly-recap/2025/05-quick-updates/ <p>This is the first weekly recap in 2025.</p> <p>I can not control myself from making new year resolutions, but I know that&rsquo;s meaningless.</p> <p>Recently I can not wake up on time, I am not sure whether it&rsquo;s because of the lack of sleep or the lack of motivation. 😮‍💨</p> <p>I read xuanwo&rsquo;s blog <a href="https://xuanwo.io/2025/01-2024-review/">2024 Review - 40 questions to myself</a>, I think I will also do a review of 2024 in the week.</p> Developer Experience Matters https://strrl.dev/post/2024/dx-matters/ Sat, 11 Jan 2025 16:10:04 -0800 https://strrl.dev/post/2024/dx-matters/ <p>Developer Experience (DX) Matters, especially for side projects, non-profitable open-source projects, and early staged bootstrapped business.</p> <h2 id="i-can-not-stop-working-on-day-job">I Can NOT Stop Working on Day Job</h2> <p>Recently, when I have extra energy after day job, I noticed that I prefer to spend time on my day job project, then the open source project, and finally the side project. But hold on, I have already completed the planned work for the day job project, and based on the importance, I should spend time on the side project first, then the open source project, and finally maybe some leisure time.</p> <p>What&rsquo;s wrong with me?</p> <p>Finally, I noticed that the day job project is soo attractive to me, over others.</p> <h2 id="my-story">My Story</h2> <p>I am a typical passionate guided developer and I love to build things. I have a full-time job, at the same time, I run a few side projects.</p> <p>A designer and me run a app development studio called <a href="https://boringboring.design/">Boring Design</a>, we have made several macOS App products, like <a href="https://haye.ai/">Haye AI</a>, a in-context AI assistant; <a href="https://boringboring.design/products/bridge">Bridge</a>, the human-centric timezone tools; <a href="https://boringboring.design/products/aeir">Aeir</a>, a Youtube Music Player that would not distract you.</p> <p>I am also one of the maintainer of <a href="https://chaos-mesh.org/">Chaos Mesh</a>. Although the maintainer team is not bring lots of feature into it, we&rsquo;re still working on PR reviewing, make we&rsquo;re not left behind the industry. I never stop thinking about what Chaos Mesh could be, with the background as more and more AI coding adopted in more and more companies.</p> <p>When building with Haye AI, at the first months, one of my friends suggested me that do not use storybook for quick iteration. I did listen to him, and it did work well in the first several months. But after that, more and more features added, also more projects started, context switching between projects and features, I found that I spend more and more time on reproduce the environment, and the iteration speed is getting slower and slower.</p> <p>Also, the most important, my passion and energy on the project is getting lower and lower.</p> <p>I need something better to make me deliver more features, also make me enjoy the process.</p> <h2 id="systems-are-better-than-goals">Systems are Better than Goals</h2> <p>The best definition of &ldquo;Developer Experience(DX / DevEx)&rdquo; relates to following factors:</p> <ul> <li>Productivity: how quickly or simply a change can be made to a codebase</li> <li>Impact: how frictionless it is to move from idea to production</li> <li>Satisfaction: how the environment, workflows, and tools affect developer happiness</li> </ul> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2024/dx-matters/2025-01-11-16-56-12.png' alt="DevEx" /> </p> </p> <p>A project with Google DX would be like a perfect system to push the product forward, keep delivering new features and avoid burnout.</p> <p>It&rsquo;s not only about the coding, but also with the final products and user feedbacks that inspire builders to keep building. But in this post, I will focus on the coding part.</p> <h2 id="a-little-trick-on-projects">A Little Trick on Projects</h2> <p>So, what should I do now?</p> <p>Without specific tech words, I need something that could help me profile the correct place to make changes, also let me see the results of changes quickly.</p> <p>As we did use Storybook, but it&rsquo;s not easy to use, its introduce too many extra and unnecessary concepts into my job.</p> <p>After working on SwiftUI projects and drawing inspiration from SwiftUI Preview, I realized that rendering a basic preview without controls or additional complexity is precisely what I needed.</p> <p>I tried with <a href="https://github.com/umijs/dumi">Dumi</a> and <a href="https://github.com/react-cosmos/react-cosmos">React Cosmos</a>, and finally I found that React Cosmos is the best fit for me.</p> <h2 id="at-the-end">At the End</h2> <p>Now I still split the UI part into 3 parts, one is something like <code>&lt;Component&gt;UIView</code> the pure UI code, and <code>&lt;Component&gt;Preview</code> with React Cosmos for quick developing, and final <code>&lt;Component&gt;</code> with view model and business logic.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2024/dx-matters/2025-01-23-16-47-02.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2024/dx-matters/2025-01-23-16-47-20.png' alt="" /> </p> </p> <p>BTW, I find that</p> <ul> <li>Much of JavaScript developers seem dedicated to delivering low-quality code, showing little concern for best practices and caring about nothing, which is reflected in the overall JavaScript ecosystem.</li> <li>I enjoy the Apple SwiftUI/AppKit/Cocoa ecosystem, more and more; Just like Java, it&rsquo;s not the fanciest, but it is stable and reliable, lots of SOPs and best practices. With some patient and humble, I could build a great product with it, also enjoy the process.</li> </ul> <h2 id="references">References</h2> <ul> <li><a href="https://github.blog/enterprise-software/collaboration/developer-experience-what-is-it-and-why-should-you-care/">https://github.blog/enterprise-software/collaboration/developer-experience-what-is-it-and-why-should-you-care/</a></li> <li><a href="https://reactcosmos.org/">https://reactcosmos.org/</a></li> </ul> I do NOT like message recall/replacement https://strrl.dev/post/2024/i-do-not-like-message-recall-or-replace/ Fri, 10 Jan 2025 13:49:36 -0800 https://strrl.dev/post/2024/i-do-not-like-message-recall-or-replace/ <p>I do NOT like message recall/replacement. I prefer to NOT use it during online conversations, for both personal and work-related sessions.</p> <p>Recall or replacement messages encourage people to avoid taking responsibility for their words. It&rsquo;s like saying, &ldquo;I can say whatever I want, and if I regret it, I can just take it back.&rdquo; It&rsquo;s a way to avoid the consequences of our actions.</p> <p>Also at the professional level, it&rsquo;s a way to avoid accountability. If I have sent a message to a client or a colleague, I want to be responsible for what I said, which means, if I made a mistake, I will have to apologize and correct it. I don&rsquo;t want to be able to take it back, and pretend it never happened.</p> <p>We all &ldquo;pretend&rdquo; to be professional and perfect, but it will cost too much to be perfect. As a contrast, I prefer to be honest and transparent. If my colleagues or clients do not accept my apologies, I deserve it.</p> <p>Anyway, it would only happen if I could take the responsibility for my words. Sometimes I work for company and the style of company require us to use message recall/replacement. In that case, I will use it anyway, but I will not like it.</p> <p>No one will ever be perfect, and we all make mistakes. But it&rsquo;s important to learn from them, and not just erase them. It&rsquo;s important to be able to say, &ldquo;I&rsquo;m sorry, I made a mistake,&rdquo; and move on.</p> 2024 Week 51: Quick Updates https://strrl.dev/post/weekly-recap/2024/51-quick-updates/ Sun, 22 Dec 2024 14:20:01 -0800 https://strrl.dev/post/weekly-recap/2024/51-quick-updates/ <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl"> ¯\_(ツ)_/¯. </span></span></code></pre></td></tr></table> </div> </div><h2 id="professional-stuff">Professional Stuff</h2> <p>I take a review about products built by Boring Design:</p> <ul> <li>EasyDevo, Free, <a href="https://easydevo.boringboring.design/">https://easydevo.boringboring.design/</a>, clean my mac but for developers, majorly focus on cleaning javascript node_modules, rust targets, golang build cache, and xcode build cache.</li> <li>Haye, Paid with subscription, <a href="https://haye.ai/">https://haye.ai/</a>, an in-context AI assistant for MacOS. It could be triggered by selection then press the hotkey, then chat with context.</li> <li>Bridge, onetime payment, <a href="https://boringboring.design/products/bridge">https://boringboring.design/products/bridge</a>, a human-centric timezone tool. It could help remote teams to find other&rsquo;s timezone.</li> </ul> <p>We started our first commit at Sep 19, 2023, it has been 15 months. We did make some money, barely to cover the cost of server, services for the products. We need to put more effort into marketing, sales.</p> <h2 id="personal-stuff">Personal Stuff</h2> <p>Recently I feel tired, on both daytime job and side projects. I am trying to back into the energetic state and stay focused on the work.</p> 2024 Week 46: Quick Updates https://strrl.dev/post/weekly-recap/2024/46-quick-updates/ Mon, 18 Nov 2024 20:13:46 -0800 https://strrl.dev/post/weekly-recap/2024/46-quick-updates/ <h2 id="professional-stuff">Professional Stuff</h2> <h3 id="introduced-curosr-to-my-wife">Introduced Curosr to My Wife</h3> <p>Cursor is an AI powered IDE, based on VSCode. The major difference is that it can provide more tight integration with the codebase, like asking questions with <code>@codebase</code>, also it has a &ldquo;composer mode&rdquo; which could help modify files in a more structured way with the diff view. It extremely likes a pair programming colleague, but I am always the &ldquo;navigator&rdquo;. I have used it for a while, and I think it&rsquo;s a good tool for me.</p> <blockquote> <p>What does the &ldquo;navigator&rdquo; mean? Take a look at this article: <a href="https://medium.com/@maaretp/the-driver-navigator-in-strong-style-pairing-2df0ecb4f657">The Driver-Navigator in Strong-Style Pairing</a></p></blockquote> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2024/46-quick-updates/2024-11-18-20-40-45.png' alt="" /> </p> </p> <p>My wife is also an software engineer, and she is working on a new area recently. So I introduced Cursor to her, and she used Cursor for resolving some jobs. She likes it, and I think it&rsquo;s great!</p> <p>But also she share her thoughts about Cursor, because of the Cursor, developer could always be in the &ldquo;navigator&rdquo; role, the overall productivity is higher than the single developer, (and yes, especially in small tasks I think). But the problem is it makes the developer always in the intense status, and she feels more tired than before.</p> <p>When we switching from architecture design to coding/implementation, we change the thinking mode, and that&rsquo;s a good way to relax, have fun, enjoy the coding, and feel like accomplishing something. But Cursor takes over major coding job, so we&rsquo;re tired to always stick in one mode.</p> <p>BTW, sometime Cursor is not even a good &ldquo;driver&rdquo;, it makes mess and we need to clean up. Sometimes I think, I should have made it by myself. 😂</p> <p>Another post about similar point is <a href="https://www.piglei.com/articles/chatgpt-and-how-we-programming/">ChatGPT 正在杀死编程里的乐趣</a>;</p> <h3 id="adopting-scarfsh-on-chaos-mesh">Adopting scarf.sh on Chaos Mesh</h3> <p>I have created ticket on CNCF service desk, asking support for setting up with scarf.sh.</p> <p>But it seems every one is enjoying the KubeCon 🤣</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2024/46-quick-updates/2024-11-18-20-57-03.png' alt="" /> </p> </p> <h3 id="notion-site-is-not-optimized-for-printing-and-reading-mode">Notion Site is not optimized for printing and reading mode</h3> <p>I like reading posts/articles in Reading Mode, sometimes save the post as PDF, send it to my iPad for reading.</p> <blockquote> <p>I always print with the reading mode, it could make the content more tidy. BTW, macOS could also using &ldquo;Apple Intelligence&rdquo; to summarize the article in the Reading Mode! There is the summary of my last post, <a href="https://strrl.dev/post/weekly-recap/2024/45-quick-updates/">2024 Week 45: Quick Updates</a>.</p></blockquote> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2024/46-quick-updates/2024-11-18-21-11-09.png' alt="" /> </p> </p> <p>But recently I noticed some site built with Notion, there is not a good experience for printing and reading mode.</p> <p>Both Reading Mode and Printing is BROKEN on Notion site. I have to duplicate the post into my own workspace, and export it into PDF in the notion app. 🤨</p> <p>For bloggers who are using / consider to using Notion site, and future bloggers, please consider this point.</p> <h2 id="personal-stuff">Personal Stuff</h2> <p>My thoughts about the personal stuff are not organized yet so I will just write them down.</p> <p>It seems after I backed to writing, the journal was also back to normal. It feels really good!</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2024/46-quick-updates/2024-11-18-20-23-03.png' alt="" /> </p> </p> <p>I joined the VanLUG event again, and get to know some new friends. After the purchasing $20 for the membership, I became one of the board members. (BTW at the last board meeting, we have voted to cancel the membership fee for the next year. 🤣) Anyway, compare to contributing by money(not much), contributing effort is more meaningful.</p> <p>There are tons of things to do, but last weekend, my focus was somehow attracted by meme coins. 🤡 That&rsquo;s not good, I need to back.</p> KubeCon NA 2024, my most anticipated topics https://strrl.dev/post/2024/kubecon-na-2024-topics/ Tue, 12 Nov 2024 10:48:27 -0800 https://strrl.dev/post/2024/kubecon-na-2024-topics/ <p>I always make a list about the topics I am most interested in during KubeCon. Here is my list for KubeCon NA 2024. Parts of them already have slides, we could watch them before the conference.</p> <p>And later I will update my comments/reviews on each topic.</p> <h2 id="talks">Talks</h2> <ul> <li><a href="https://kccncna2024.sched.com/event/1i7kV/all-your-routes-are-ready-more-or-less-dave-protasowski?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">All Your Routes Are Ready, More or Less - Dave Protasowski</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7kn/when-life-gives-you-containers-make-an-open-source-rds-a-kubernetes-love-story-sergey-pronin-percona?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">When Life Gives You Containers, Make an Open Source RDS: A Kubernetes Love Story - Sergey Pronin, Percona</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7ng/how-to-move-from-ingress-to-gateway-api-with-minimal-hassle-keith-mattix-microsoft?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">How to Move from Ingress to Gateway API with Minimal Hassle - Keith Mattix, Microsoft</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7nn/running-quantum-safe-applications-on-kubernetes-paul-schweigert-michael-maximilien-ibm-quantum?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Running Quantum-Safe Applications on Kubernetes - Paul Schweigert &amp; Michael Maximilien, IBM Quantum</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7rE/what-agent-to-trust-with-your-k8s-falco-tetragon-or-kubearmor-henrik-rexed-dynatrace?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">What Agent to Trust with Your K8s: Falco, Tetragon or KubeArmor? - Henrik Rexed, Dynatrace</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7nP/what-istio-got-wrong-learnings-from-the-last-seven-years-of-service-mesh-christian-posta-louis-ryan-soloio?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">What Istio Got Wrong: Learnings from the Last Seven Years of Service Mesh - Christian Posta &amp; Louis Ryan, Solo.io</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7p6/the-maintainer-monologues-sarah-christoff-defense-unicorns-jason-hall-chainguard-scott-rigby-karen-chu-independent-ryan-nowak-microsoft?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">The Maintainer Monologues - Sarah Christoff, Defense Unicorns; Jason Hall, Chainguard; Scott Rigby &amp; Karen Chu, Independent; Ryan Nowak, Microsoft</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7ox/per-node-api-server-proxy-expand-the-clusters-scale-and-stability-weizhou-lan-iceber-gu-daocloud?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Per-Node Api-Server Proxy: Expand the Cluster&rsquo;s Scale and Stability - Weizhou Lan &amp; Iceber Gu, DaoCloud</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7pZ/pick-my-project-lessons-learned-from-interviewing-20-end-users-for-cloud-native-case-studies-shedrack-akintayo-bill-mulligan-isovalent-at-cisco?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Pick My Project! Lessons Learned from Interviewing 20+ End Users for Cloud Native Case Studies - Shedrack Akintayo &amp; Bill Mulligan, Isovalent at Cisco</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7pE/how-google-built-a-new-cloud-on-top-of-kubernetes-jie-yu-prashanth-venugopal-google?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">How Google Built a New Cloud on Top of Kubernetes - Jie Yu &amp; Prashanth Venugopal, Google</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7pv/better-together-gpu-tpu-and-nic-topological-alignment-with-dra-john-belamaric-google-patrick-ohly-intel?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Better Together! GPU, TPU and NIC Topological Alignment with DRA - John Belamaric, Google &amp; Patrick Ohly, Intel</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7qY/can-you-put-a-price-tag-on-open-source-mario-fahlandt-kubermatic-bob-killen-cncf?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Can You Put a Price Tag on Open Source? - Mario Fahlandt, Kubermatic &amp; Bob Killen, CNCF</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7q3/open-source-20-the-maintainers-perspective-william-morgan-buoyant-ashley-davis-venafi-deepthi-sigireddi-planetscale-emily-omier-emily-omier-consulting-matt-bates-cofide?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Open Source 2.0: The Maintainers&rsquo; Perspective - William Morgan, Buoyant; Ashley Davis, Venafi; Deepthi Sigireddi, PlanetScale; Emily Omier, Emily Omier Consulting; Matt Bates, Cofide</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7q1/upgrade-safely-avoid-the-pitfalls-of-kubernetes-versioning-rob-scott-google?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Upgrade Safely: Avoid the Pitfalls of Kubernetes Versioning - Rob Scott, Google</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7q7/kubernetes-on-multisites-a-story-about-stateful-app-hybrid-clouds-and-high-availability-florian-coulombel-dell-technologies-jan-safranek-red-hat?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Kubernetes on Multisites – A Story About Stateful App, Hybrid Clouds, and High Availability - Florian Coulombel, Dell Technologies &amp; Jan Šafránek, Red Hat</a></li> <li><a href="https://kccncna2024.sched.com/event/1hoxy/whats-new-in-operator-framework-bryce-palmer-rashmi-gottipati-lalatendu-mohanty-red-hat-attila-meszaros-apple?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">What&rsquo;s New in Operator Framework?! - Bryce Palmer, Rashmi Gottipati &amp; Lalatendu Mohanty, Red Hat; Attila Meszaros, Apple</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7py/still-dont-do-what-charlie-dont-does-making-crd-changes-safer-nick-young-isovalent?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Still Don&rsquo;t Do What Charlie Don&rsquo;t Does - Making CRD Changes Safer - Nick Young, Isovalent</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7rT/gamifying-cloud-native-how-to-design-and-build-an-educational-game-for-your-project-calum-murray-university-of-toronto-faculty-of-applied-science-and-engineering-zainab-husain-ocad-university?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Gamifying Cloud Native: How to Design and Build an Educational Game for Your Project - Calum Murray, University of Toronto, Faculty of Applied Science and Engineering &amp; Zainab Husain, OCAD University</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7qV/object-storage-is-all-you-need-justin-cormack-docker?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Object Storage Is All You Need - Justin Cormack, Docker</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7qn/the-missing-talk-about-api-versioning-evolution-in-your-developer-platform-stefan-schimanski-upbound-sergiusz-urbaniak-independent?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">The Missing Talk About API Versioning &amp; Evolution in Your Developer Platform - Stefan Schimanski, Upbound &amp; Sergiusz Urbaniak, Independent</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7rA/thousands-of-gamers-one-kubernetes-network-surya-seetharaman-red-hat-girish-moodalbail-nvidia-inc?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Thousands of Gamers, One Kubernetes Network - Surya Seetharaman, Red Hat &amp; Girish Moodalbail, NVIDIA Inc</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7rt/goodbye-etcd-running-kubernetes-on-distributed-postgresql-denis-magda-yugabyte?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Goodbye etcd! Running Kubernetes on Distributed PostgreSQL - Denis Magda, Yugabyte</a></li> </ul> <h2 id="lighting-talks">Lighting Talks</h2> <ul> <li><a href="https://kccncna2024.sched.com/event/1iW8z/grpc-the-grpc-standard-library-project-lightning-talk?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">gRPC: The gRPC &ldquo;Standard Library&rdquo; | Project Lightning Talk</a></li> <li><a href="https://kccncna2024.sched.com/event/1i7jv/cl-lightning-talk-kubectl-debug-lacks-an-ide-option-lets-fix-that-mario-loriedo-red-hat?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">⚡ Lightning Talk: <code>Kubectl Debug</code> Lacks an <code>IDE</code> Option. Let’s Fix That! - Mario Loriedo, Red Hat</a></li> <li><a href="https://kccncna2024.sched.com/event/1iW9r/slimtoolkit-improving-dx-with-containers-making-it-easy-to-understand-optimize-and-debug-your-containers-project-lightning-talk?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">SlimToolkit: Improving DX with Containers - Making it Easy to Understand, Optimize, and Debug Your Containers | Project Lightning Talk</a></li> <li><a href="https://kccncna2024.sched.com/event/1iW9Z/project-overview-a-hitchhikers-guide-to-the-cncf-landscape-katherine-druckman-and-lori-lorusso-cncf-ambassador?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Project Overview: A Hitchhiker&rsquo;s Guide to the CNCF Landscape - Katherine Druckman and Lori Lorusso, CNCF Ambassador</a></li> <li><a href="https://kccncna2024.sched.com/event/1iWA9/meshery-visualizing-kubernetes-resource-relationships-with-meshery-project-lightning-talk?iframe=no&amp;w=100%25&amp;sidebar=yes&amp;bg=no">Meshery: Visualizing Kubernetes Resource Relationships with Meshery | Project Lightning Talk</a></li> </ul> 2024 Week 45: Quick Updates https://strrl.dev/post/weekly-recap/2024/45-quick-updates/ Mon, 11 Nov 2024 21:42:15 -0800 https://strrl.dev/post/weekly-recap/2024/45-quick-updates/ <p>I did not feel something special in this week, so just some quick reviews and updates.</p> <h2 id="professional-stuff">Professional Stuff</h2> <h3 id="bring-macos-native-module-to-electron-with-napi-rs-and-swift-bridge">Bring macOS native module to electron with NAPI-RS and swift-bridge</h3> <p>TLDR; Build browser webpage, or build native app. Electron/Tauri/Wails is not the best choice for desktop app, unless</p> <ul> <li>cross-platform is a must</li> <li>also the app do not ask for tightly system integration</li> <li>and you do not care about the look and feel of the app</li> </ul> <p>We developed a in-context AI assistant tool called Haye, <a href="https://haye.ai">https://haye.ai</a>. And we used to decided to use electron as the framework to build it, and now it looks like electron already become the burden of the project. We want to build the native-like experience on macOS, and we always use the webview to imitate the native. And our app want to integrate with the system, like hotkey, notification, Notes, or Shortcuts. None of them can be easily done with only javascript. And there is not so good ecosystem for electron to do this.</p> <p>In the last week to bring more seamless text selection experience, I discovered the native API about accessibility and NSEvent, I found that it is soo easy to do this in native app. Building a native module now become a must-have for us. Luckily, I found two interesting projects, <a href="https://napi.rs/">NAPI-RS</a> and <a href="https://github.com/chinedufn/swift-bridge">swift-bridge</a>. The first project could bring rust to nodejs, and the second project could bring swift to rust.</p> <p>I made a poc last week and it works. So I just take a record here.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2024/45-quick-updates/2024-11-11-22-10-46.png' alt="" /> </p> </p> <p>We use rust as bridge, with swift-bridge and napi.rs, we could get:</p> <ul> <li>bring seamless native API integration to nodejs</li> <li>type-safe and polyfill; Swift -&gt; Rust -&gt; TypeScript, no more <code>any</code>, no more <code>UnsafeMutablePointer</code>;</li> <li>standard publish ci bring by napi.rs.</li> </ul> <p>So using these two projects, I have a way to build and publish node native module with swift and macos native API, somehow it is a good news.</p> <p>I am still exploring the more direct way / best practice to use NAPI and Swift. I will keep updating the progress.</p> <p>But there is one more thing I still need to figure out, some of rpc framework like GRPC, already have the unified DSL to define the service and message, and it supports multiple languages. I am thinking about if I could use the same DSL to define the native API, and just use it as ffi. I will also keep exploring this.</p> <p>If you have any idea or experience about this, please let me know.</p> <h3 id="haye-new-version-released">Haye new version released</h3> <p>We release a new version of Haye. It brings the dedicated window for view chat history and start new chatting.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2024/45-quick-updates/2024-11-11-22-23-57.png' alt="" /> </p> </p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">早上好 / 中午好 / 晚上好 !!<br><br>Haye AI 更新啦! 现在除了划词唤起外, 还支持了直接对话模式. 现在已经是我主力的 AI 对话软件了!<br><br>想拥有方便美观 AI 聊天软件朋友们, 请立刻用起来! 🥰<a href="https://t.co/QGR1TdIV7r">https://t.co/QGR1TdIV7r</a> <a href="https://t.co/CJbr1HfJFt">pic.twitter.com/CJbr1HfJFt</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1855097909244838036?ref_src=twsrc%5Etfw">November 9, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>And we offer a discount, the pricing is 50% off, from $9.99 to $4.99. If you are interested in it, please check it out <a href="https://haye.ai/">here</a>;</p> <blockquote> <p>I also bump the minor version of the app, from 0.1.x to 0.2.x;</p></blockquote> <h3 id="scarfsh">scarf.sh</h3> <p>Several weeks ago, I read the linkerd&rsquo;s story, <a href="https://linkerd.io/2024/10/23/making-linkerd-sustainable/">Towards a Sustainable Service Mesh</a>. In a short word, linkerd would not provide stable release for free, only with the buoyant enterprise subscription.</p> <p>And days later, I found the linkerd&rsquo;s show case with <a href="https://scarf.sh/">scarf.sh</a>, <a href="https://about.scarf.sh/post/how-buoyant-drives-open-source-led-growth-with-linkerd">How Buoyant Drives Open-Source-Led Growth with Linkerd</a>. Scarf.sh is a tool to help open-source project to track the usage of the project, and also help the project to monetize the usage.</p> <p>I take a try with my personal project, <a href="https://github.com/STRRL/cloudflare-tunnel-ingress-controller">STRRL/cloudflare-tunnel-ingress-controller</a>, and it is very easy to setup. I will keep tracking the usage of my project with scarf.sh.</p> <blockquote> <p>BTW if you do not know cloudflare-tunnel-ingress-controller, check it here: <a href="https://strrl.dev/post/2023/unlocking-the-power-of-cloudflare-tunnel-secure-scalable-and-simple-kubernetes-ingress-controller-implementation-for-your-applications">Unlocking the Power of Cloudflare Tunnel: Secure, Scalable, and Simple Kubernetes Ingress Controller Implementation for Your Applications</a>.</p></blockquote> <p>It looks great so far, and I will share it on the Chaos Mesh development meeting, and consider to use it in the project.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2024/45-quick-updates/2024-11-11-22-32-04.png' alt="" /> </p> </p> <h2 id="personal-stuff">Personal Stuff</h2> <h3 id="vanlug-meet-hank-and-sustainable-community">VanLUG, meet Hank, and sustainable community</h3> <p>I joined the Vancouver Linux User Group Meeting last week, that&rsquo;s Annual General Meeting, the boards of VanLUG share the wrap-up of the last year.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2024/45-quick-updates/2024-11-11-22-36-31.png' alt="" /> </p> </p> <p>Nester is impressive, he shared the updates and the future plan of VanLUG. The community did become more active and more awesome in 2024, but it still facing problem on making value and sustainability.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2024/45-quick-updates/2024-11-11-22-46-52.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2024/45-quick-updates/2024-11-11-22-45-56.png' alt="" /> </p> </p> <p><a href="https://vanlug.ca/wp-content/uploads/2024/11/2024-vanlug-year-end-report.pdf">2024 Year End Report from Nestor</a></p> <blockquote> <p><del>The link of presentation on VanLUG is not correct, I would send email to them for asking the correct link. Once I get it, I will update it here.</del> Updated!</p></blockquote> <p>I joined as the paid member, get my vote-card.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2024/45-quick-updates/2024-11-11-22-39-14.png' alt="" /> </p> </p> <blockquote> <p>BTW, I forgot to take cash, so I borrow $20 from Alex. Then I return it to him with e-transfer. People here are so nice, when I ask for help, they propose to lend me the money. I am so grateful for that.</p></blockquote> <p>I also meet with Hank! Handsome big brother! 🔥</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">🔥🔥🔥 今天在 Vancouver Linux User Group 上面基了 <a href="https://twitter.com/hankbao?ref_src=twsrc%5Etfw">@hankbao</a> <a href="https://t.co/0VTOGzentd">pic.twitter.com/0VTOGzentd</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1855434551067308046?ref_src=twsrc%5Etfw">November 10, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <h3 id="crypto">Crypto</h3> <p>After big election completed, the crypto market is getting fire again. Bitcoin is hitting $90k.</p> <p>I still not get the point of the crypto currency, I use to chase &ldquo;value&rdquo; in the market. So I dig into the projects, finding out what them really make.</p> <p>But there are not so many projects really make sense. I am still looking for the project that could bring the &ldquo;real value&rdquo; to the world.</p> <p>Maybe the currency itself is the value, and that&rsquo;s why even memocoin could go high. But I still not get it.</p> 2024 Week 44: Passion or Profession https://strrl.dev/post/weekly-recap/2024/44-passion-or-profession/ Sun, 03 Nov 2024 18:42:15 -0800 https://strrl.dev/post/weekly-recap/2024/44-passion-or-profession/ <h2 id="passion-or-profession">Passion or Profession</h2> <p>Last week I completed <a href="https://m.douban.com/book/subject/26898387/">虚伪的真心话</a> (<a href="https://book.douban.com/subject/26581091/">超思考</a>)by 北野武(<a href="https://wikipedia.org/wiki/Takeshi_Kitano">Takeshi Kitano</a>). Takeshi Kitano is a famous Japanese comedian, actor, and film director, and he is of the same age as people from my grandparents generation.</p> <p>I am an east-asian, and I think China, Japan, and Korea are the three countries that have much similarity in their culture and history. So recently days I have been reading several books of Japanese / Korean authors, and I think that&rsquo;s a really good way to learn and think.</p> <p>There&rsquo;re several different thoughts in this book, like &ldquo;fast-food entertainment&rdquo;, &ldquo;useless politics&rdquo;, &ldquo;chasing dreams, selling dreams&rdquo;, and &ldquo;not earning too much money&rdquo;.</p> <p>The one most impressive to me is about &ldquo;chasing dreams and selling dreams&rdquo;. For me, in the past years of my life, I have always wanted to do something that I am passionate about. But in recent years, I have found that it is not always good and risk-free to only do what I am passionate about. I think it is very important to make an effort on other things that I have no interest in, and that&rsquo;s something I have lacked in the past years.</p> <p>Another aspect of this idea is bring the &ldquo;good feeling&rdquo; when user using the product. People may not really want to &ldquo;be successful&rdquo; or &ldquo;be rich&rdquo;, they do like the feeling of &ldquo;being successful&rdquo; or &ldquo;being rich&rdquo;. So making products / selling resources to people &ldquo;want to become a engineer&rdquo;, &ldquo;want to become a designer&rdquo;, &ldquo;want to become an individual developer&rdquo; would be a good way to make money.</p> <p>But would a product so like that make <strong>value</strong>? I think it is a good question for me to think about. 😳</p> <h2 id="professional-stuff">Professional Stuff</h2> <h3 id="setup-ci-with-self-hosted-macos-runner">Setup CI with self-hosted macOS runner</h3> <p>We used to use <a href="https://flyci.net">FlyCI</a> instead of using GitHub provisioned runners, because the former one is cheaper. But FlyCI announced that they get pivoted to AI CI/CD troubleshooting and the runner hosting service would be stopped(<a href="https://flyci.net/blog/flyci-discontinue-macos-runners">FlyCI: Discontinuing FlyCI macOS Runners - A New Chapter for FlyCI Wingman</a>).</p> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/i284V-JTdQw?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="Introducing FlyCI Wingman: Automatically Fix Your Failing CI Builds"></iframe> </div> <blockquote> <p>I agree that providing computing resources as github action runner is not a good business model. But AI CI/CD troubleshooting is an another trap. It&rsquo;s way far from enough context from only the code base and CI/CD logs for now. But if it could be done one day, I would be very happy to see that!</p></blockquote> <p>So I have to setup a self-hosted macOS runner to pack my apps. Thanks to <a href="https://tart.run">tart</a> and <a href="https://github.com/shapehq/tartelet">tartlet</a>, it is very easy to setup a self-hosted runner.</p> <h3 id="eat-own-dog-food-on-haye">Eat own dog food on Haye</h3> <p>Last week I got my OpenAI account banned with no idea. I lost using chatGPT app and also the API key.</p> <p>As a replacement, I use the new feature of <a href="https://haye.ai">Haye</a> to continue the daily usage of chatGPT.</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">或许是天意, 倒逼我自己吃自己的狗粮 <a href="https://t.co/lzgBTRkqwZ">https://t.co/lzgBTRkqwZ</a> <a href="https://t.co/BAglXjxpAO">pic.twitter.com/BAglXjxpAO</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1849203201947451480?ref_src=twsrc%5Etfw">October 23, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <h3 id="we-turned-our-apple-developer-account-to-a-organization-account">We turned our Apple Developer account to a organization account</h3> <p>After a 3 months of inactivity, we finally have new progress on our products. We&rsquo;re going to release one new version of our product and also start 2 new products on testflight.</p> <h2 id="personal-stuff">Personal Stuff</h2> <h3 id="new-games">New Games</h3> <p><strong>Monster Hunter Wild</strong> starts its public beta test on 2024.10.30 - 2024.11.04, it is a pretty great game.</p> <p>I have played about 16+ hrs in the past 3 days, and I am still not tired of it.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2024/44-passion-or-profession/mhw.jpeg' alt="MHW" /> </p> </p> <p>The new generation of Monster Hunter brings lots of new actions and mechanics, and it is becoming more and more easy to get into. Players would have more fun in the game, and pro players would have more possibility to hit the ceiling.</p> <p>I record some of my gameplay and would like to share to you:</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">试着用 steam deck 玩了下怪猎荒野<br><br>一帧不卡 两帧流畅 我这十五帧要起飞了 🤡<br><br>就是 bug 还是不少,视频尾最后居上了但是卡死了 <a href="https://t.co/L7NPEo6dFG">pic.twitter.com/L7NPEo6dFG</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1852807401688494355?ref_src=twsrc%5Etfw">November 2, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/zTscJN6E7Mc?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="怪物猎人荒野: 初见缠蛙"></iframe> </div> <p><strong>Factorio Space Age</strong> is the new DLC for Factorio, it brings lots of new stuff into the game, but I still not start to play it.</p> <p>BTW, the factorio team also has a great blog called FFF(Factorio Friday Facts), share stories about engineering and gaming design, I love to read it!</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2024/44-passion-or-profession/2024-11-03-20-13-33.png' alt="" /> </p> </p> <p>Link: <a href="https://www.factorio.com/blog/">https://www.factorio.com/blog/</a></p> <p>You could also subscribe it on Follow: <a href="https://app.follow.is/share/feeds/67225064797585424">link</a></p> <p>2025 would be a great year of games, with MHW, GTA6 and others.</p> <h3 id="new-life-in-vancouver">New life in Vancouver</h3> <p>I have been in Vancouver for about 3 months(which also means my temporary driver license is going to expire, damn), I found that I have lost the first passion of exploring the city. Instead, I back to the busy ordinary life, without new exploring and communicate with new people. That&rsquo;s not good.</p> <p>The one big reason I want to move to another place is to get new experiences and information, also to meet new people. But now I am working at home, not working with a local team, and I have no friends in Vancouver. That&rsquo;s not good.</p> <p>I should make a plan to change it. Maybe any suggestions?</p> <p>At last, it takes me about 90 mins to complete this blog, hope you enjoy it!</p> Cheat Sheet for macOS App Signing and Notarizing https://strrl.dev/post/2024/cheatsheet-for-macos-app-signing-and-notatizing/ Thu, 31 Oct 2024 21:46:20 -0700 https://strrl.dev/post/2024/cheatsheet-for-macos-app-signing-and-notatizing/ <h2 id="background">Background</h2> <p>In the last 3 weeks, we just turned the personal Apple Developer membership into a organization membership, also changed the name as &ldquo;Boring Design LLC&rdquo;. I am working on replace old certificates and with new ones.</p> <p>I just realized that I nearly forgot how to get the new certificates for electron app signing, so here is a cheat sheet for that, maybe it will help me again in the future.</p> <h2 id="before-start">Before Start</h2> <p>If a application is not signed, macOS will show a warning dialog when the app is opened, and the user needs to right-click the app and select &ldquo;Open&rdquo; to open the app. If the app is signed with a Apple Developer certificate, the app could be opened by double-clicking.</p> <p>There is an app called <a href="https://mothersruin.com/software/Apparency/get.html">Apprancy</a>, to check the signing status (and more) of an app, like this:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2024/cheatsheet-for-macos-app-signing-and-notatizing/2024-10-31-14-29-33.png' alt="" /> </p> </p> <h2 id="get-the-certificates">Get the Certificates</h2> <p>We are going to use &ldquo;electron/osx-sign&rdquo; to sign the app, it will look up the correct certificate from keychain, so what we need to do is to get prepared with the certificates, download them from Apple Developer website, and install them into the keychain.</p> <ol> <li>Prepare a Certificate Signing Request(CSR) Apple requires a CSR to generate certificates, we could generate it from Keychain Access,:</li> </ol> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2024/cheatsheet-for-macos-app-signing-and-notatizing/2024-10-31-14-04-06.png' alt="" /> </p> </p> <p>No need to tune the settings, and remember to check the &ldquo;Save to disk&rdquo; option.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2024/cheatsheet-for-macos-app-signing-and-notatizing/2024-10-31-14-18-51.png' alt="" /> </p> </p> <ol start="2"> <li>Generate and Download Certificate from Apple Developer</li> </ol> <p>Login into <a href="https://developer.apple.com/account">Apple Developer -&gt; Account</a>, then jump to <a href="https://developer.apple.com/account/resources/certificates/list">Certificates</a></p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2024/cheatsheet-for-macos-app-signing-and-notatizing/2024-10-31-14-21-22.png' alt="" /> </p> </p> <p>Click the &ldquo;+&rdquo; button to create a new certificate, and notice that we should create 2 certificates, one for &ldquo;Developer ID Application&rdquo; and another for &ldquo;Apple Distribution&rdquo;.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2024/cheatsheet-for-macos-app-signing-and-notatizing/2024-10-31-14-22-41.png' alt="" /> </p> </p> <blockquote> <p>&ldquo;Developer ID Application&rdquo; is used for distributing the app outside of Mac App Store, and &ldquo;Apple Distribution&rdquo; is used for distributing the app in Mac App Store.</p></blockquote> <p>Download the certificates and install them into the keychain.</p> <h2 id="setup-signing">Setup Signing</h2> <p>By default, &ldquo;electron/osx-sign&rdquo; will look up the correct certificate from keychain, so we don&rsquo;t need to specify the certificate explicitly. But we could specify the certificate explicitly by setting the <code>identity</code> option in the <code>osxSign</code> option if we have multiple certificates in the keychain.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;osxSign&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;identity&#34;</span><span class="p">:</span> <span class="s2">&#34;Developer ID Application: Boring Design LLC (XXXXXXXXXX)&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>Option reference: <a href="https://github.com/electron/osx-sign/blob/main/src/types.ts">https://github.com/electron/osx-sign/blob/main/src/types.ts</a></p> <h2 id="setup-notarize">Setup Notarize</h2> <p>Notarization is a process to submit the app to Apple for scanning, and Apple will return a ticket if the app is notarized successfully. We could use &ldquo;electron/notarize&rdquo; to notarize the app.</p> <p>I use the following options:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">osxNotarize</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">tool</span><span class="o">:</span> <span class="s1">&#39;notarytool&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">appleId</span><span class="o">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">APPLE_ID</span> <span class="o">||</span> <span class="s2">&#34;&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">appleIdPassword</span><span class="o">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">APPLE_PASSWORD</span> <span class="o">||</span> <span class="s2">&#34;&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">teamId</span><span class="o">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">APPLE_TEAM_ID</span> <span class="o">||</span> <span class="s2">&#34;&#34;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>and it requires:</p> <ul> <li>Apple ID: your apple developer account email</li> <li>Apple Password: the app-specific password, generate it by following the <a href="https://support.apple.com/en-us/102654">guide</a></li> <li>Apple Team ID: the team id, could be found in <a href="https://developer.apple.com/account/#/membership">Apple Developer -&gt; Membership</a></li> </ul> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2024/cheatsheet-for-macos-app-signing-and-notatizing/2024-10-31-14-34-47.png' alt="" /> </p> </p> <p>It could also be used inside the CI environment, like GitHub Actions, by setting the environment variables.</p> <h2 id="pack-it">Pack it</h2> <p>After setting up the signing and notarization, we could finally get a signed and notarized app:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2024/cheatsheet-for-macos-app-signing-and-notatizing/2024-10-31-14-40-48.png' alt="" /> </p> </p> <p>That&rsquo;s perfect, let&rsquo;s ship it!</p> 2024 Week 43: Personal Updates https://strrl.dev/post/weekly-recap/2024/43-personal-updates/ Sat, 26 Oct 2024 16:33:28 -0700 https://strrl.dev/post/weekly-recap/2024/43-personal-updates/ <p>Long time no see! Half years passed since my last weekly recap.</p> <p>Lots of things happened in the last 7 months, and I think it&rsquo;s time to get a quick update on my life.</p> <h2 id="professional-stuff">Professional Stuff</h2> <p>I changed my job 2 times, from <a href="https://limit.dev/">Limit Labs</a> to <a href="https://rss3.io/">RSS3</a>, and now, <a href="https://gitroll.io/">GitRoll</a>. I would not like to the comparison between these companies, but the one same thing I could feel is business is hard, and its really hard to complete the 0-1 process of making profit.</p> <h3 id="boring-design">Boring Design</h3> <p>At <a href="https://boringboring.design/">Boring Design</a>, we are still working on the <a href="https://haye.ai/">Haye</a>. And what a coincidence, when I working on the main chatting view of Haye, my ChatGPT account got banned by OpenAI. 😅</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">或许是天意, 倒逼我自己吃自己的狗粮 <a href="https://t.co/lzgBTRkqwZ">https://t.co/lzgBTRkqwZ</a> <a href="https://t.co/BAglXjxpAO">pic.twitter.com/BAglXjxpAO</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1849203201947451480?ref_src=twsrc%5Etfw">October 23, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>We&rsquo;re also working on exploring the native integration with macOS, using Electron has some limitations, and we want to provide not only beautiful UI, but also more powerful integration with macOS system.</p> <h3 id="cloudflare-tunnel-ingress-controller">Cloudflare Tunnel Ingress Controller</h3> <p><a href="https://github.com/STRRL/cloudflare-tunnel-ingress-controller">Cloudflare Tunnel Ingress Controller</a> is side project I am working on, it&rsquo;s effortless way to using native Ingress to expose services in Kubernetes cluster to the internet.</p> <p>I noticed there&rsquo;re more adoption and contributors to this project, and more options and production level features are built by the community. Maybe I should spend more time on this project.</p> <h2 id="personal-stuff">Personal Stuff</h2> <p>I moved from Hangzhou to Vancouver. Welcome to huddle me if you are in Vancouver!</p> <p>I realized that my english is not good enough to communicate with people in English, so I need to make a new plan to improve my English, as daily practice, writing, and reading.</p> <p>Lots of good routines are broken, like daily exercise, good sleep schedule and weekly recap. I need time to rebuild these routines.</p> <h2 id="others">Others</h2> <p>There&rsquo;re still lots of things I want to share, like lots of new tech, new idea, new products, but I already spent 1 hours on update the blog, update hugo and them, and write this post. I need to back to work now.</p> Haye AI, Llama3 and Tool Call https://strrl.dev/post/2024/haye-llama3-and-tool-call/ Mon, 22 Apr 2024 23:01:17 +0800 https://strrl.dev/post/2024/haye-llama3-and-tool-call/ <h2 id="the-background">The Background</h2> <p>In the last few weeks, Caicai and me are working on the product, <a href="https://haye.ai/">Haye AI</a>, which is an in-context AI assistant.</p> <p>We dedicated our part time to this product, and we are following the fancy ideas and state-of-the-art technologies to make it better.</p> <p>And days ago, Meta released llama 3, which really changed something.</p> <h2 id="the-new-open-source-model-llama-3">The New Open Source Model: LLaMA 3</h2> <p>LLaMA 3 is really impressive in various of aspects:</p> <ul> <li>it supports responding in multiple languages, like Chinese. (But sometime it would respond in Pinyin, and some single words are still left in English.)</li> <li>the overall performance is much better than LLaMA 2, closing to GPT 4</li> <li>some online API provider provides llama 3 in extremely low cost, and fast response speed, which makes llama 3 become the most cost-effective AI model right now.</li> </ul> <p>We used to use gpt-3.5-turbo as the major model for most of the tasks, with some predefined presets. I spend hours and hours to modify the prompts in the playground, and the results are not always good. Once I changed the model to gpt-4, the results are much better, but we can&rsquo;t, because the cost is too high(about 10x - 15x of gpt-3.5-turbo).</p> <p>So we are really happy to see llama 3, and we are trying to integrate it into our product.</p> <h2 id="problems">Problems</h2> <p>There are several problems we are facing:</p> <ul> <li>llama 3 is not natively support function calling, which is a key feature in some tasks</li> <li>still not have reliable LLM Providers to provide llama 3 API</li> <li>even different LLM Providers have different API, event most of them are announced as &ldquo;Open AI Compatible&rdquo;, but they are compatible in different ways <ul> <li>groq does not support function calling with Streaming API, which means I must manually split the tasks based on it requires function calling or not</li> <li>deepinfra, fireworks, together just ignore the function calling in the request</li> <li>openrouter could support function calling with stream, but it respond tool call in the content, not it the expected <code>tool_call</code> field, which is not following the Open AI API standard</li> </ul> </li> </ul> <p>We&rsquo;re still waiting for that there would be available resources on Azure, or other big cloud provider which could let me rust the reliability. At the same time, I would like to work on the function calling feature, possibly I would build a simple layer as an LLM-Agnosticism &ldquo;function calling&rdquo; adapter based on &ldquo;Reason - Act&rdquo; prompting.</p> Haye AI, Llama3 和 Tool Call [CN] https://strrl.dev/post/2024/haye-llama3-and-tool-call-cn/ Mon, 22 Apr 2024 23:01:17 +0800 https://strrl.dev/post/2024/haye-llama3-and-tool-call-cn/ <blockquote> <p>BTW: 这是使用 Haye AI 的翻译功能翻译的.</p></blockquote> <h2 id="背景">背景</h2> <p>在过去的几周里,我和 Caicai 一起致力于开发产品 <a href="https://haye.ai/">Haye AI</a>,这是一个上下文感知的人工智能助手。</p> <p>我们抽出业余时间来开发这个产品,并且我们一直追随着时髦的想法和最先进的技术,以使其变得更好。</p> <p>几天前,Meta 发布了 llama 3,这真的改变了一些东西。</p> <h2 id="新的开源模型llama-3">新的开源模型:LLaMA 3</h2> <p>LLaMA 3在各个方面都非常令人印象深刻:</p> <ul> <li>它支持多种语言的回复,比如中文。(但有时它会用拼音回复,而且有些单词仍然是英文。)</li> <li>总体表现比 LLaMA 2 要好得多,接近GPT 4</li> <li>一些在线 API 提供商以极低的成本和快速的响应速度提供 llama 3,使其成为目前最具性价比的 AI 模型。</li> </ul> <p>我们过去通常使用 gpt-3.5-turbo 作为大多数任务的主要模型,配合一些预定义的预设。我花了很多时间修改 playground 中的提示,但结果并不总是好的。一旦我将模型改为 gpt-4,结果就好得多,但我们不能这样做,因为成本太高(大约是 gpt-3.5-turbo 的 10 倍 - 15 倍)。</p> <p>因此,我们非常高兴看到 llama 3,并且正在尝试将其集成到我们的产品中。</p> <h2 id="遇到的问题">遇到的问题</h2> <p>我们面临着几个问题:</p> <ul> <li>llama 3不支持原生的函数调用,这是一些任务中的关键功能</li> <li>仍然没有可靠的 LLM 提供商提供 llama 3 的API</li> <li>即使不同的 LLM 提供商都宣称与 &ldquo;Open AI&rdquo; 兼容,但它们兼容 Open AI API 的方式也不尽相同 <ul> <li>groq 不支持使用 Streaming API 进行 tool call,这意味着我必须根据是否需要 tool call 手动拆分任务。</li> <li>deepinfra、fireworks 和 together 直接忽略请求中的 tool call。</li> <li>openrouter 可以支持使用 stream 进行 tool call,但它直接在<code>content</code>中回应了工具调用,而不是预期的<code>tool_call</code>字段,这不符合 Open AI API 的标准。</li> </ul> </li> </ul> <p>我们仍在等待 Azure 或其他大型云服务提供商提供可靠的资源,以便我能够信任其可靠性。同时,我也希望能够开发函数调用功能,可能会基于 &ldquo;Reason - Act&rdquo; 提示构建一个简单的层作为 LLM 不可知的&quot;函数调用&quot;适配器。</p> 2024 Week 15: Rushing Code Rushing Life https://strrl.dev/post/weekly-recap/2024/15-rushing-code-rusing-life/ Wed, 10 Apr 2024 15:40:54 +0800 https://strrl.dev/post/weekly-recap/2024/15-rushing-code-rusing-life/ <p>Long time no see. I was too busy to write the weekly recap in the last 4 weeks. I was too busy to do anything else. 😅</p> <p>I just accumulated enough energy and wills to write this post, even it&rsquo;s already 1 am.</p> <p>Our family would face lots of changes in 2024, so I think it worth to record the current status of my life.</p> <p>Maybe 6 months later, I would read this post and think &ldquo;Oh, that was really a interesting time.&rdquo; 🤣</p> <h2 id="progress-and-outcome">Progress and Outcome</h2> <p>In the last weeks, I was making an very intensive work life NOT balance life: I worked with a full-time position, and at the same time, I was working on my product, <a href="https://haye.ai">Haye AI</a>.</p> <p> <p class="md__image"> <img src='./Haye%20AI%20First%20Commit.png' alt="Haye AI First Commit" /> </p> </p> <p>On the side of my full-time job, the team was asked for completing lots of features in the limited time. In the past 3 weeks we completed:</p> <ul> <li>running javascript code as FAAS, integrated with the AI workflow</li> <li>a chatbot platform for LLM agent</li> <li>ComfyUI on cloud gpu</li> </ul> <p>and we are prepared to take more challenges tasks in the next weeks. 🥵</p> <p>On the part-time Haye AI side, we spent about 2 months to build the first public test version of the product. We are going to release the first beta version in the next week. I am very excited about it. In the last 2 months, we spent about 3 - 4 hrs per day to work on it, in other words, we just used 1 month as a full-time job to build it. And we think as we become more proficient, our efficiency will be higher. 🚀</p> <h2 id="lifestyle">Lifestyle</h2> <p>Again, that was totally NOT the WLB lifestyle. 🙅‍♂️ I run as a 9-12-7 working style.</p> <p>But I am not forced to do so, I just want to do so. I feel that I have a goal to achieve, and I have a plan to make it. There is no reason but to put my best effort into it.</p> <p>I was made some notes / warning like &ldquo;do not coding after 10 pm&rdquo;, but it was NOT followed at all. 🤪</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">昨天晚上又肝到一点半, 还没怎么出活<br><br>以后得给自己搞个提醒, 十点以后绝对不能写代码<br><br>写不出来, 白费几个小时<br>写出来了, 第二天再看跟坨💩一样</p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1729655863806165190?ref_src=twsrc%5Etfw">November 29, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>I dedicated on producing new things, which is great. But I did not learn enough new things, which is not good. In the last year, I realized that I need more knowledge in various domain, like business, design, economics, history, etc. I have a long list of books to read, but I did not read them. 😰</p> <p>And I definitely need to take care of myself. I noticed that my health was not as good as before, on both physical and mental. My weight was increased, and I felt tired easily.️ I tried to do some exercise, but I faced the same problem: I did not have enough time. 😮‍💨</p> <p>As a summary, keeping high-intensity output may have risks.</p> <h2 id="rest--entertainment">Rest / Entertainment?</h2> <p>I think I was mentioned that I got lost interest(aka. 电子阳痿) in video games. I discussed with my wife, and I think I found the reason: the rewards from playing game is not as high as building products. Video game was the single way that consumed my leisure time, but now I just spent it on working, with no complaint. ❤️‍🔥</p> <p>That&rsquo;s really weird, but that&rsquo;s the truth.</p> <p>I used to take the social activities as a way to relax, like &ldquo;Liangzhu Crazy Thursday&rdquo;. But now I feel that it is a little bit kind of time wasting. Now I only take the the afternoon part of the event, and I feel that it is enough.</p> <p>Sometimes I need to drive to buy some food materials, eat at restaurants, or engage in activities, and the driving time is a great opportunity to relax. I really enjoy the time when I am driving, whether it&rsquo;s listening to music or a podcast, or simply chatting with my wife. 🥰</p> <p>Should I take more rest? I think I should. But how? I think I need a plan.</p> <h2 id="the-plan">The Plan</h2> <p>I thought &ldquo;I have not enough time&rdquo;, but it might not be true. I think I need to make a plan to make my life more efficient.</p> <p>Discipline brings freedom, but disciplines requires energy. So the basic ideas are changing the environment, building new habits to reduce the requirement of energy. Also take more training to increase the energy level.</p> <ul> <li>Work: During the work time, I still was distracted by many things. I think I could be more focused on my work.</li> <li>Rest: I need to make efforts on sleep regularity. And more kinds of rest.</li> <li>Exercise, Learning, Reading: With stable daytime schedule, I should spent some morning time on these things, instead of doing them at night.</li> <li>Entertainment: video game? I am not sure. Maybe take some time on Diablo 4.</li> </ul> <p>That&rsquo;s all.</p> 2024 Week 11: Personal Updates https://strrl.dev/post/weekly-recap/2024/11-personal-updates/ Wed, 13 Mar 2024 00:09:44 +0800 https://strrl.dev/post/weekly-recap/2024/11-personal-updates/ <p>Okay, that started. Okay. This is the second time that I am trying to use voice recording with speech to text, technology to writing my blog. And if you found something, something is weird because, you know, this is speech to text. So there is not 100% accuracy.</p> <p>I have thought about my life, my career, my income and my future plan. I still have no clear things to chase, or I did not get a really understanding about myself.</p> <p>I do not know what is really I want to get, so every step in my plan or is it plan does not, maybe. Maybe, well, that&rsquo;s not a aligned. That does not align with my future. So, wow. I think I should reduce all of the things, and ask myself what is really I want. What is really things that I want to taste.</p> <p>I thought I have found the idea which is making new things, making products, but it&rsquo;s not really&hellip; it&rsquo;s not really&hellip; the answer.</p> <p>I&rsquo;m just confused. I was taught by traditional Chinese opinions and I just get awakened from lots of information and knowledge for the enlightenment.</p> <p>I did not get ready to think about that and make a clear plan. Even I did not convince with myself to do what I am doing. I just jump into the things that I am engineering so I love building things. I just jump into it and forgot all of the other annoying stuffs. I think I should not escape anymore. I have to think about that.</p> <p>And another thing about it is I do not have enough knowledge to think about the life, think about the future. So I should, I will video put more time on the input and reduce the time on the output. You know, input means reading books, read articles, thinking about the lives. And the output means working, build products.</p> <p>so that&rsquo;s all I think maybe after one month or two months after I will share my new opinion about my life. Yeah, that&rsquo;s all.</p> 2024 Week 5: Personal Updates https://strrl.dev/post/weekly-recap/2024/05-personal-updates/ Sun, 04 Feb 2024 14:00:18 +0800 https://strrl.dev/post/weekly-recap/2024/05-personal-updates/ <p>So, I haven&rsquo;t updated my post for about three or four months. One reason is that I&rsquo;ve discovered once I have an opportunity to focus on something, it&rsquo;s really challenging to find enough time to write it down. I&rsquo;ve realized that it&rsquo;s very difficult to consistently maintain high energy levels. Moreover, it&rsquo;s really tough to complete building products in a short span of time.</p> <p>In the past three months, I&rsquo;ve made progress in several areas. One of these is I got a relatively stable job position, then I launched my indie hacker career. Additionally, I&rsquo;ve been applying to North American universities for a master&rsquo;s degree. These tasks have been substantial enough to consume all my energy, leaving me no time to maintain routine activities like writing weekly recaps or handling accounting tasks. I feel quite regretful about this.</p> <p>In the last several weeks, I&rsquo;ve been working around 70 hours a week just to finish tasks, and yet there are still a lot of things to do and many new things I need to learn. It&rsquo;s really tough.</p> <p>So, there&rsquo;s a plan. I need to have a precise and reasonable understanding of my energy levels and I should allocate this energy into different tasks. I have always put forth my &ldquo;best effort&rdquo; for a long time, but things just got out of under-control. I suppose it&rsquo;s NOT the way it should be.</p> <p>I believe I must clarify what I want to achieve. I need to determine how much time I will spend playing video games, how much time I will dedicate to building things, how much time I will allocate for learning new things, and how much time I will set aside for exercising. I think it&rsquo;s essential to plan these clearly. I must always be disciplined and abide by these rules.</p> <p>I have to be honest with myself - I need some time to rest, or in other words, play video games to keep me happy. Therefore, I must allocate enough time for this. If I don&rsquo;t, I won&rsquo;t be happy and won&rsquo;t be able to maintain focus on other tasks.</p> <p>Recently, I watched a documentary called Stutz, and a very interesting point from it is that all people, regardless of whether they are rich or poor, old or young, always need to face three things. The first is pain, the second is uncertainty, and the third is constant work. We can&rsquo;t escape these aspects of life. However, despite this, life is beautiful and can bring happiness, even amidst pain, uncertainty, and constant work. I totally agree with this.</p> <p>I remember a time when I was playing a game called Blade and Soul during my bachelor&rsquo;s. After I built the final weapons in the game, I lost all motivation to continue playing it.</p> <p>Many people believe that having enough money will rid them of these three things (pain, uncertainty, and constant work). However, after they attain wealth, they find that these problems do not disappear. Some may think that accumulating even more wealth will solve these issues, but that&rsquo;s not the truth. Regardless of wealth, people cannot completely evade pain, uncertainty, and the need for constant work.</p> <p>That&rsquo;s the life, life is a journey that we should enjoy, even with the presence of pain, uncertainty, and constant work. It&rsquo;s crucial to find the right methods to effectively manage these aspects of our lives.</p> <p>So, I believe that in the coming days, I need to be honest with myself and acknowledge that <strong>I can&rsquo;t always be a productive machine</strong>. There are many things in life that I deserve to enjoy.</p> 2023 Week 40: Overwhelming then Keep Focus https://strrl.dev/post/weekly-recap/2023/40-overwhelming-then-stay-focus/ Mon, 02 Oct 2023 09:54:08 +0800 https://strrl.dev/post/weekly-recap/2023/40-overwhelming-then-stay-focus/ <h2 id="overview">Overview</h2> <p>This blog records the time span from 2023-09-18 to 2023-10-01.</p> <h3 id="professional-stuff">Professional Stuff</h3> <h4 id="rebuild-my-linkedin-profile">Rebuild My LinkedIn Profile</h4> <p>Several month ago, I tried to migrate my LinkedIn Profile from China to US, but I account got banned after merge these two accounts.</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">哦豁.... <a href="https://t.co/3xdWzv0e9V">https://t.co/3xdWzv0e9V</a> <a href="https://t.co/xRdvjIM9KX">pic.twitter.com/xRdvjIM9KX</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1648900650510749696?ref_src=twsrc%5Etfw">April 20, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>I lost about all the 300 connections, also connections with certifications and badges.</p> <p>🤦‍♂️ That&rsquo;s so bad.</p> <p>Then later, LinkedIn announced that they quit China market, and I think I could setup a new account.</p> <p>So here is my new LinkedIn account:</p> <p><a href="https://www.linkedin.com/in/zhiqiang-zhou-9964a028b/">https://www.linkedin.com/in/zhiqiang-zhou-9964a028b/</a></p> <p>Welcome to connect with me. ❤️‍🔥</p> <h4 id="chaos-mesh--kubecon-china-2023">Chaos Mesh @ KubeCon China 2023</h4> <p>KubeCon China 2023 was hosted at Shanghai during Sept 26-29. We (Cwen, Xianglin and I) hosted the part-time booth and a Maintainer Track talk about Chaos Mesh.</p> <p>I am so happy that we got lots of attention from the community, there are still several people know us and use Chaos Mesh. We share the same booth with Cilium, so I also met <a href="https://twitter.com/breakawaybilly">Bill Mulligan, the Developer Advocate @ Isovalent</a>. We talked about the open source community and I learned some tricks about keeping the community active.</p> <h4 id="overwhelming-stuffs-keep-focus-on-one-major-thing">Overwhelming Stuffs, Keep Focus on One Major Thing</h4> <p>I used Getting Things Done to organize my project and personal tasks, it used to be efficient before I quit my job.</p> <p>With many stuffs which are not attractive, and some other stuff are very attractive, I could allocate time on them properly.</p> <p>But now, I have too many stuffs and <strong>ALL OF THEM ARE ATTRACTIVE</strong>, I am so confused about which one should I focus on. 😢</p> <p>After talk with <a href="https://twitter.com/Ehco1996/">Ehco1996</a> several weeks ago, I had picked up the one major things I should focus on, and it works well so far.</p> <p>My most valuable resources are my time and my energy. I could not separate them on trivial stuffs. And I realize the charming of &ldquo;focusing on one thing&rdquo; now.</p> <h3 id="personal-stuff">Personal Stuff</h3> <h4 id="try-novas-mt-car">Try Nova&rsquo;s MT Car</h4> <p>One day night at Shanghai, I meet <a href="https://twitter.com/n0vad3v">Nova</a> and try his MT car.</p> <p>IT IS SO COOL!</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/40-overwhelming-then-stay-focus/2023-10-02-11-00-22.png' alt="" /> </p> </p> <p>The engine sound is completely different from my car, and because of the MT, I could definitely control the power of the car. It&rsquo;s AMAZING!</p> <p>I drove the AT car for 1 year. I always use gas pedal to control the speed. When I want to make a overtake, I need to step the gas pedal heavy and quick to hint the AT gearbox downshift. But the MT car is different, just change a lower gear manually, and the car will speed up very quickly, with the beautiful engine sound, and with no lag. 😍</p> <p>The only one thing that I still trying to adapt is &ldquo;matching the engine speed with the gearbox speed&rdquo;, it&rsquo;s also the word &ldquo;降挡补油&rdquo;, It would reduce the jerking when I change the gear.</p> <h4 id="learn-photography">Learn Photography</h4> <p>After I brought the iPhone 13 Mini, I noticed that I took more and more photos. I would like to record daily life with photos, and I would like to take some beautiful photos.</p> <p>Then I ready the book <em>The School of Photography</em>, and I learned some basic knowledge about photography.</p> <p>And I was choosing devices decently. I also borrowed cameras from my friends and try them, thanks them all. 🥰</p> <h4 id="keep-reading-and-find-useful-methodology">Keep Reading and Find Useful Methodology</h4> <p>As I just mentioned, GTD does not works well for me now, because it lacks of how to measure how I feeling about the tasks.</p> <p>I am trying to find new way to keep myself happy, at the same time, keep myself productive.</p> 2023 Week 38: Process or Product https://strrl.dev/post/weekly-recap/2023/38-process-or-product/ Sun, 17 Sep 2023 08:44:54 +0800 https://strrl.dev/post/weekly-recap/2023/38-process-or-product/ <h2 id="overview">Overview</h2> <p>It takes me too long time to write blogs, so I decided to use another way to write posts.</p> <p>I would allocate 30 minutes to write a post, and I would not care about the quality of the post, just write it down.</p> <p>If I found that the quality is not good enough, or there are no more time to express thoughts, I would use other tricks to make it better <strong>in next time</strong>.</p> <h2 id="professional-stuff">Professional Stuff</h2> <h3 id="build-a-desktop-application-electron-or-native">Build a Desktop Application: Electron or Native</h3> <p>Recently I am preparing to build a desktop application as a developer tool. I can not make decision on which technology stack should I use.</p> <ul> <li>My target user are developers on macOS, I have no plan to support Windows or Linux in the first stage.</li> <li>I do not familiar with the native macOS development, but I am familiar with the web.</li> </ul> <p>I asked @Tualatrix about why he keeps building native application for macOS, he said that the native application is more efficient than electron base app, and also it&rsquo;s kind of belief of Apple.</p> <p>I asked my self:</p> <ul> <li>Do you think the performance of the application is important for your product?</li> <li>Do you have faith with Apple?</li> </ul> <p>For me, both answers are no.</p> <p>I think web technology is enough for my product, and I do want to bring my product to all of the developers.</p> <p>So I choose Electron.</p> <blockquote> <p>Also I asked an experienced Product Manager, about this question, and he said, just use the technology you are familiar with, and change to native when you have to.</p></blockquote> <h3 id="in-progress-from-hugo-to-astro">In Progress: From Hugo to Astro</h3> <p>I am stuck with the new theming.</p> <p>I do not have good design sense for a new theme.</p> <p>I should find a good spec or copy from other&rsquo;s theme.</p> <h3 id="aigc-for-music">AIGC for Music</h3> <p>There are soo many AI products about LLM and Image Generation, but AI Product for music does not soo hot in the market.</p> <p>So I take a look about the music generation tools/platforms, and I found that there are already some great products:</p> <ul> <li>AIVA</li> <li>Loudly</li> <li>Soundraw</li> <li>BandLab SongStarter</li> </ul> <p>That&rsquo;s the platform which I think I would use it in the future. All of the build high quality and royalty-free music.</p> <h3 id="social-media-dame">Social Media Dame</h3> <p>I build a chrome extension called &ldquo;Dame&rdquo;, it would block the twitter and youtube.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/38-process-or-product/2023-09-17-09-22-54.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/38-process-or-product/2023-09-17-09-23-32.png' alt="" /> </p> </p> <p>It works well. But I am not going to use it anymore.</p> <p>I found I got really panic, it seems it pouch my heart, I feel shame and guilty, and it&rsquo;s really not good for my mental health.</p> <p>I took an inspection with the Mental Health Section of The First Affiliated Hospital of Zhejiang University School of Medicine, the result told me I have a little bit of anxiety and mania, but not too serious. No need to take medicine, just need to do some aerobic workout and relax.</p> <p>Then I decided to disable the extension.</p> <h2 id="personal-stuff">Personal Stuff</h2> <h3 id="process-or-product">Process or Product</h3> <p>That&rsquo;s the major topic I want to talk about.</p> <p>When I tried to use GTD system and learn about the productivity and project management, I find it led me to make the &ldquo;expected outcome&rdquo; at the beginning of the project.</p> <p>I think it is a good way to focus, but it&rsquo;s not good for me now.</p> <p>It makes me scared, especially when I am not familiar with the project or the domain knowledge.</p> <p>I am soo FOMO when I learning and doing something new.</p> <p>So I decided to only &ldquo;make the expected outcome&rdquo; in my professional area.</p> <p>When learning and trying new things, I just put my time and energy on it, and do not care about the outcome.</p> <p>Hope it would make me feel better.</p> <h3 id="meet-ehco1996">Meet ehco1996</h3> <p>I meet @ehco1996 in Hangzhou.</p> <p>He decided to retire when he is 28.</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">刚和老板说我准备提桶跑路了<br><br>没想到吧,我 28 不到就退休了😗 <a href="https://t.co/BE8IQiyCcg">https://t.co/BE8IQiyCcg</a></p>&mdash; Ehco (@Ehco1996) <a href="https://twitter.com/Ehco1996/status/1701066139043058010?ref_src=twsrc%5Etfw">September 11, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>I think the most important things I learned from the conversation is, I need to keep focus.</p> <p>In the last gap experience, there are soo many things take my attention, and I nearly made nothing completed.</p> <p>Only one things could be done in the same time.</p> <h3 id="liangzhu-culture-village-and-apple-events">Liangzhu Culture Village and Apple Events</h3> <p>In the last several weeks, we went to Liangzhu Culture Village every Thursday.</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">今天疯狂星期四…不是,村民聚众写代码,正式开始。 <a href="https://t.co/O53uCvXH8o">pic.twitter.com/O53uCvXH8o</a></p>&mdash; 图拉鼎 (@tualatrix) <a href="https://twitter.com/tualatrix/status/1694580649896861888?ref_src=twsrc%5Etfw">August 24, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">很开心认识了 Yuhang!我们的玉鸟集「数字游民/远程工作/自由职业」基地又多了一个小伙伴。 <a href="https://t.co/kJv3VWzAn0">https://t.co/kJv3VWzAn0</a></p>&mdash; 图拉鼎 (@tualatrix) <a href="https://twitter.com/tualatrix/status/1694693510312755596?ref_src=twsrc%5Etfw">August 24, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">又到了我们线下聚众写代码之「疯狂代码日」了。<br><br>在这里和大家分享一个好消息,我们和玉鸟集的「杭一末」联合发起了一个面向数字游民的「 我们一起办公吧」活动,目前的福利是满五单送一杯。经常去办公的同学记得下单时出示本海报集单。<br><br>PS:海报里的五位同学由我们本色出演,猜猜我是哪个。 <a href="https://t.co/iQpGdeyK5z">pic.twitter.com/iQpGdeyK5z</a></p>&mdash; 图拉鼎 (@tualatrix) <a href="https://twitter.com/tualatrix/status/1697066220665885046?ref_src=twsrc%5Etfw">August 31, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">今天有点严肃,感觉大家在用代码谈判。 <a href="https://t.co/ZfSKadO5Xf">pic.twitter.com/ZfSKadO5Xf</a></p>&mdash; 图拉鼎 (@tualatrix) <a href="https://twitter.com/tualatrix/status/1697096957779640652?ref_src=twsrc%5Etfw">August 31, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">今天和两个播客节目的几个朋友都见面畅聊了。<br><br>分别是:枫言枫语的 <a href="https://twitter.com/MapleShadow?ref_src=twsrc%5Etfw">@MapleShadow</a> 和 <a href="https://twitter.com/hzlzh?ref_src=twsrc%5Etfw">@hzlzh</a>,硬地骇客的 <a href="https://twitter.com/skoowfancy?ref_src=twsrc%5Etfw">@skoowfancy</a> 和 <a href="https://twitter.com/anson0370?ref_src=twsrc%5Etfw">@anson0370</a> 。<br><br>还有其他新朋友。地点在我们的玉鸟集根据地。真是开心的一天! <a href="https://t.co/irRx7B6iqW">pic.twitter.com/irRx7B6iqW</a></p>&mdash; 图拉鼎 (@tualatrix) <a href="https://twitter.com/tualatrix/status/1698665255881392594?ref_src=twsrc%5Etfw">September 4, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>And we also attend the Apple Event Watch Party in Yuniaoji! There are lots of good memories.</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">开心,和六十多个新老朋友顺利看完了 2023 Apple 秋季发布会🥰也为下次我自己搞产品发布积累了经验。大家下回见! <a href="https://t.co/j3jEZKsTAn">pic.twitter.com/j3jEZKsTAn</a></p>&mdash; 图拉鼎 (@tualatrix) <a href="https://twitter.com/tualatrix/status/1701673207621902837?ref_src=twsrc%5Etfw">September 12, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <h3 id="steam-deck">Steam Deck</h3> <p>I borrowed a Steam Deck from pseudo_yu, it&rsquo;s really a great product!</p> <p>I would not consider to buy the windows gamepad after I tried the SteamOS.</p> <p>Plaid Speed!</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">之前没注意,现在发现无人深空的脉冲引擎特效就是 Plaid Speed<br><br>(Tesla S Plaid 的那个 Plaid <a href="https://t.co/6aTwfEnBMp">pic.twitter.com/6aTwfEnBMp</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1702925918313091288?ref_src=twsrc%5Etfw">September 16, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <h3 id="get-a-hair-cut">Get a Hair Cut</h3> <p>I got a hair cut for the marriage certificate photo.</p> <p>Also pseudo_yu and Hwang got a hair cut too.</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">新文章:「周报 #46 - 告别长发、周报初心与合约开发」<br><br>暂剪去了长&amp;蓝发,也算是近期最大的变化了;写了一篇自己很喜欢的关于知识系统搭建的文章;重新思考了自己写周报的初心;可能有机会写一本技术书籍,期待却也忐忑;还有很多有意思的事。<a href="https://t.co/4c4iDGE6s5">https://t.co/4c4iDGE6s5</a></p>&mdash; pseudoyu (@pseudo_yu) <a href="https://twitter.com/pseudo_yu/status/1701971967191007336?ref_src=twsrc%5Etfw">September 13, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">长头发嘎了,需要换头像吗🙃</p>&mdash; Hwang (@hwwaanng) <a href="https://twitter.com/hwwaanng/status/1702953551734140959?ref_src=twsrc%5Etfw">September 16, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>I would bring it back in the next 2 years!</p> <h2 id="at-the-end">At the end</h2> <p>It still took me about more than 1 hr to completed this post.</p> <p>I think I need to practice more.</p> <p>Oh, about the &ldquo;gap year wrapped&rdquo; series, I would update the new post in the next week. 😋</p> Gap Year Wrapped - Timeline (Second Half) https://strrl.dev/post/2023/gap-year-wrapped---timeline-x2/ Sat, 09 Sep 2023 12:01:24 +0800 https://strrl.dev/post/2023/gap-year-wrapped---timeline-x2/ <p>Last Post: <a href="https://strrl.dev/post/2023/gap-year-wrapped-timeline/">Gap Year Wrapped - Timeline</a></p> <h2 id="timeline">Timeline</h2> <p>I&rsquo;m so excited to continue recording my gap year life the second part. Let&rsquo;s start it.</p> <h3 id="february-2023">February 2023</h3> <p>My major in the university is Digital Media TechKnowledge, so a lot of my university classmates works in Gaming Area like NetEase, Tencent, BiliBili and miHoYo. And actually I am also a hard-core gamer for most kind of games and I still have a dream to build my own game.</p> <p>And finally, I have a chance to build a game, which is a VR game during the Global Game Jam (GGJ). It&rsquo;s a global activity that calls for lots of game designer, developers to join the activity in person or online. In two days, 48 hours, to create an amazing game and at last we would show games to the partners.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-09-24.png' alt="Me, trying the VR Game" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-12-52.png' alt="" /> </p> </p> <p>Video:</p> <p><a href="https://www.bilibili.com/video/BV1gx4y1777b"> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-10-59.png' alt="" /> </p> </a></p> <p>I also we also have a trip in Beijing, actually I have oNOgood experiment experience in Beijing. I prefer to Tianjin, it&rsquo;s more than a modern city then Beijing.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-19-15.png' alt="Take a rest in Tianjin Street Cafe" /> </p> </p> <p>BTW, I also met 象牙山刘能 in Beijing, and that&rsquo;s the most exciting thing in Beijing.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-16-49.png' alt="" /> </p> </p> <p>We went the Universal Beijing Resort, expect for street pop-up event and float parade, the rest are all duplicated roller coasters.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-24-28.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-23-33.png' alt="" /> </p> </p> <p>In one work, not good as the Disneyland in Shanghai.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-18-12.png' alt="" /> </p> </p> <p>And I&rsquo;m starting to prepare for the master degree and we find an advisory services for some references to pick school, and the paperwork.</p> <p>At the last, we traveled to Qiandaohu, and it is very great trip.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-20-16.png' alt="Beautiful Qiandao Lake" /> </p> </p> <h3 id="march-2023">March 2023</h3> <p>After I buy the Volkswagen car, I have a dream which is making an Itasa Car, which means I will paint some anime characters on the surface of the car.</p> <p>I picked Hatsune Miku and which is virtual idol for 16 years. We started to design the itasa car with a designer in this month.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-27-24.png' alt="Design Work" /> </p> </p> <p>I started to do something new, like streaming on YouTube and learning some principle of the design from Google UX and online courses from Facebook design. I also started to have a learning about English the TOEFL exam recently.</p> <p>It&rsquo;s also a great time enjoying Sakura flower. 🌸 I am very luck because there are several Sakura trees in my community.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-30-38.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-30-41.png' alt="" /> </p> </p> <h3 id="april-2023">April 2023</h3> <p>And then this month I took the first TOEFL exams and I got 89 which is not very good but it&rsquo;s kind of enough for some normal school. I still need need to make more effort to get a higher score about 95 or a 100 but yeah it&rsquo;s basic score for some applications.</p> <p>We also travel to Yueyang again, took some beautiful memories.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-49-03.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-49-19.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-49-45.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-50-35.png' alt="" /> </p> </p> <p>We also attended the the Itasa Car Exhibition at ChangSha, 痛一会@长沙. Meet many nice and awesome guys, who love ACG deeply, and keep sharing the happiness to others.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-55-37.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-56-24.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-56-31.png' alt="" /> </p> </p> <p>After we back to Hangzhou, there was also a great news: BIRLAND(玉鸟集) started trail opening! In the next several months, we will have a great time in BIRLAND, meet many new friends and old friends. 🥰</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-11-58-36.png' alt="" /> </p> </p> <h3 id="may-2023">May 2023</h3> <p>After travel to Yueyang, I also travel to Shandon, my hometown.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-15-23-02.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-15-23-34.png' alt="" /> </p> </p> <p>And in this month I also made new friends like daddy like 面包, 智子, LAKR, 炸鸡, Houge.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-14-36-12.png' alt="" /> </p> </p> <h3 id="june-2023">June 2023</h3> <p>We drove to Nanjing for 鸭血粉丝汤. Nanjing is the last city we traveled before the Covid 19 pandemic. Nanjing really impressive me with its delicious food 鸭血粉丝汤.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-14-38-02.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-14-39-53.png' alt="" /> </p> </p> <p>During this month, Apple announced the new device: Vision Pro. I think it worse me spending money to buy it.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-14-41-18.png' alt="" /> </p> </p> <p>This DIABLO IV was released. We spent a lot of time on it.</p> <p>I also spent lots of time on making new friends and keeping connections with old friends. I met 图拉鼎 in this month, met the OriginCode from HZLUG, and I also met friend 深海带鱼, and we have a great time in the piano room.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-14-44-04.png' alt="" /> </p> </p> <h3 id="july-2023">July 2023</h3> <p>I registered as a Apple developer. Why I choose Apple Developer, well, you know, as an engineer, is not the final step to making living hood to making project or product, is selling your product to the end users. I think App Store is one of the best way for developers to sell their product.</p> <p>I ams also a big fans of Apple product, I believe it will give me more chances.</p> <p>Also away meet new friends like Xiaowen and Xinyi. Both of them are very professional in their domain area, and both of them have their different opinion to the differences things, that&rsquo;s really impressive me.</p> <p>And my left foot got really injured, (it does still not recover until I write this article). 😰</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-14-51-14.png' alt="" /> </p> </p> <h3 id="august-2023">August 2023</h3> <p>I have a chance to travel to Shenzhen and Hong Kong.I travel to Hong Kong because I want to apply my credit card and banking account from the overseer oversee bank, and Hong Kong is one of the best choice. We applied for HSBC bank and ZA bank.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-14-56-33.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-14-57-02.png' alt="" /> </p> </p> <p>We also went for a special restaurant is called a magpie, the restaurant owned by one of my favorite Youtuber Cadence Gao.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-14-57-35.png' alt="" /> </p> </p> <p>We also travel to Longyou to met one of my friends who is also my ex-colleague. Longyou is a beautiful city which also have great food and awesome rally racing track.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-15-02-11.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline-x2/2023-10-10-15-01-56.png' alt="" /> </p> </p> <h2 id="comparison-with-the-career-working-in-company">Comparison with the Career working in Company</h2> <p>I will try to make a comparison Career in company and gap year life.</p> <p>For the conclusion of career in company, I think the keyword is <strong>SIMPLE</strong>.</p> <p>While I was working in company, we have clear goals(or maybe not so clear), we always have a direction in the professional domain. It might be making money or build projects or products and it&rsquo;s very simple and intuitive.</p> <p>For the conclusion of gap year life, I think the keyword is <strong>UNLIMITED</strong>.</p> <p>I start to consider making my value in some form like building products, trying to make some investments, and making myself and my family happy. I started to think it, but I still have no clear answer to these questions. But at least, I started to think about it, rather than spend all my time on working.</p> <p>I am very very thanks for all of the friends, who helps me to making living hood during the gap year. I really really appreciate it. Thank you very much. 🥰</p> <h3 id="pros-for-the-gap-experience">Pros for The Gap Experience</h3> <p>I have more free time and then I have more free thoughts, and I start to explore the <strong>possibility</strong> of our life.</p> <h3 id="cons-for-the-gap-experience">Cons for The Gap Experience</h3> <p>Cons are also obvious, I used to be an employee of a company, so my mindset was very simple as an engineer. So in the short term, I could not make a good living hood as before. Without the stable income, the mental pressure is very high.</p> <h2 id="takeaway">Takeaway</h2> <p>That&rsquo;s the last 6 months for the gap year. I tried to use Siri Dictation to speed up the post writing, and it&rsquo;s really helpful.</p> <p>Gap experience is really a great experience. But it makes me not submerge in the endless career life and company work, and it give me a really great chance to think about the life and the future.</p> <p>At last, I would reference a tweet from 花果山大圣, which introduces his opinion about the hard-working and the gap experience:</p> <blockquote> <p>It&rsquo;s a long tweet thread, this is only the opening one</p></blockquote> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">开个thread记录一下,为什么我以前如此坚决的反对996(不惜离职来对抗),以及这两年不上班后,我认为gap year是必要的 (哪怕俩月呢)</p>&mdash; 花果山大圣 (@shengxj1) <a href="https://twitter.com/shengxj1/status/1678730362472763393?ref_src=twsrc%5Etfw">July 11, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>Thanks for reading this non-structured post, I hope you enjoy it.</p> Gap Year Wrapped - Timeline https://strrl.dev/post/2023/gap-year-wrapped---timeline/ Sat, 02 Sep 2023 12:01:24 +0800 https://strrl.dev/post/2023/gap-year-wrapped---timeline/ <h2 id="about-me">About Me</h2> <p>Hi! I am Zhiqiang. I am a full-stack software engineer majoring in cloud computing area. I am the maintainer of <a href="https://github.com/chaos-mesh/chaos-mesh">Chaos Mesh</a>, also I am enthusiastic in any kind of open source software.</p> <p>On August 31th 2022, I left my job at <a href="https://pingcap.com">PingCAP</a> and started my gap year.</p> <p>I will write a series of posts to review my gap year.</p> <p>Fortunately, I have <a href="https://strrl.dev/categories/%E5%91%A8%E6%8A%A5/">history weekly-recap posts</a>, although it definitely less frequently than weekly, it&rsquo;s still very helpful to review my gap year.</p> <p>This is the first one, I am going to review my gap year in a timeline, and record some important moments.</p> <p>And I would write another 2 (or 3) posts, to review my gap year in different aspects.</p> <blockquote> <p>There would NO any suggestion and advice purposes from this post, only my personal life. I would share my thoughts in later post.</p></blockquote> <h2 id="timeline">Timeline</h2> <p>TL;DR, the timeline content might a little boring and flat, the main contents are photos with simple introductions.</p> <p>I am going to reproduce the journey of my gap year in a timeline.</p> <p>If you don&rsquo;t want to read the whole post, you can just jump to the <a href="#summary">Summary</a> section.</p> <h3 id="august-2022">August 2022</h3> <p>My last day in PingCAP is August 31th 2022, which is also the birthday of Hatsune Miku.</p> <p>Several interviews were in progress, majoring in SRE / DevOps, and cloud infra development.</p> <p>Travel to Kunming, Yunnan.</p> <p>The Wujiaying Subway Station, one of my most familiar station during the college life.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/image.png' alt="Subway Wujiaying Station" /> </p> </p> <p>Flied a drone around Yunnan University.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-03-17-26-02.png' alt="Yunnan University" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-03-17-23-37.png' alt="Yunnan University" /> </p> </p> <p>Fei Yang TEPANTAKI, the last meal with my university roommates.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-03-17-25-10.png' alt="Fun &amp; Young TEPANTAKI" /> </p> </p> <p>Fried Potato, the my favorite snacks in Kunming.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-03-17-28-31.png' alt="Fried Potato" /> </p> </p> <h3 id="september-2022">September 2022</h3> <p>Started the idea for a new start-up based on Chaos Mesh, but still kept interviewing. The new company&rsquo;s logo inspired from &ldquo;Faerie Dragon&rdquo;, a naughty creature live in your infrastructure, break something but finally fix it.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-03-17-35-08.png' alt="Logo Inspiration" /> </p> </p> <p>Back to the normal social activities, organized several Hangzhou Linux User Group Hacking Saturdays events:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/20220904_141120.jpg' alt="HZLUG" /> </p> </p> <p>Got a surprised moon cake present from Agora:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/20220905_153029.jpg' alt="Agora Present" /> </p> </p> <p>Travel to my hometown, Dezhou, Shandong.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-03-17-39-28.png' alt="Hui Meng Gong Yuan" /> </p> </p> <p>One of my favorite home-made dishes by my mom:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-03-17-40-27.png' alt="Traditional Dishes made by my mom" /> </p> </p> <p>Also here is a night-view panorama photo of my hometown:</p> <p><a href="https://photos.app.goo.gl/op9nJUHz3HrZaDXy8">https://photos.app.goo.gl/op9nJUHz3HrZaDXy8</a></p> <p>And I bought my new iPhone Mini, I love this device soo much! 🤩</p> <p>I think buying a new iPhone start inspire me to think more on &ldquo;making good products&rdquo;.</p> <h3 id="october-2022">October 2022</h3> <p>I traveled to Yueyang this month.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-09-57-12.png' alt="I love Yueyang" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-01-13.png' alt="Yueyanglou" /> </p> </p> <p>I bought the Windows Dev Kit 2023, I thought it would the best ARM computing device, but I am wrong.</p> <p>Both WSL and Hyper-V could NOT work well on this device. And there is no graphic acceleration API available on video codec, so I have no more usage on it.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-03-53.png' alt="" /> </p> </p> <p>I found that as me get fitter, I love climbing mountains more and more. I realized that working out is a very important part of my life.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-07-08.png' alt="" /> </p> </p> <h3 id="november-2022">November 2022</h3> <p>This month I complete the 4-rounds technical interview with Binance, but I got the message that they would not hire employees from China Mainland anymore. 🥲</p> <p>Also we were going to stop the start-up idea, because we found that it&rsquo;s hard to raise enough money at that time. So we just paused that idea.</p> <p>I started to play Ingress again, and this one I joined some in-person activities, meet some new friends.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-18-52.png' alt="" /> </p> </p> <p>And I attended the DevJoy in Shanghai WeWork, lots of funny booth there.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-20-12.png' alt="" /> </p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-20-30.png' alt="" /> </p> </p> <p>Get lots of stickers. 🤣🤣</p> <h3 id="december-2022">December 2022</h3> <ul> <li>Buy new Car</li> <li>Affected by Covid-19</li> </ul> <p>We bought a new car. Liangzhu Culture Village locates in rural area of Hangzhou, it&rsquo;s a very beautiful place, but it&rsquo;s hard to get out of here without a car. And the winter is soo cold, I think using e-bike is not a good idea anymore.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-21-17.png' alt="" /> </p> </p> <p>I think we got affected by Covid-19 when we are registering the car, we get in touch with soo many people these day. My girlfriend got fever first, then me 3 days after.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-04-20-20-13.png' alt="" /> </p> </p> <p>It&rsquo;s really hard to buy medicines and covid tests these days. But very thanks to my friends, they gave me some Ibuprofen suspensions, it really helped us a lot.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-28-51.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-30-08.png' alt="" /> </p> </p> <p>We were luck we were the first batch of people who got infected, we were also the first batch of people who got recovered. After we recovered, we have a car to travel around Hangzhou. That&rsquo;s kind of a little scared, there was NOT ANY PEOPLE on the street, and NO ONE in the shopping mall.</p> <p>People horded foods, drinks, snacks for the next several days, lots of goods are out of stock.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-30-10.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-32-41.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-33-04.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-33-11.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-33-35.png' alt="" /> </p> </p> <h3 id="january-2023">January 2023</h3> <ul> <li>Spring Festival at HangZhou</li> <li>new toy: Insta 360</li> </ul> <p>We decided to stay at Hangzhou for the Spring Festival, because of the Covid-19. But we still had a great time.</p> <p>I am going to share some photos and videos here, I think it&rsquo;s better than words.</p> <p>Please start watching at 2:10.</p> <p><a href="https://photos.app.goo.gl/cQy6FUpQTYnzFRUf7">https://photos.app.goo.gl/cQy6FUpQTYnzFRUf7</a></p> <p><a href="https://photos.app.goo.gl/Q6U1B47bhw3wcsEy7">https://photos.app.goo.gl/Q6U1B47bhw3wcsEy7</a></p> <p><a href="https://photos.app.goo.gl/F97iDVPWjFLSPQmt6">https://photos.app.goo.gl/F97iDVPWjFLSPQmt6</a></p> <p><a href="https://photos.app.goo.gl/x5JHDdRfUDQ5jurn6">https://photos.app.goo.gl/x5JHDdRfUDQ5jurn6</a></p> <p>People were getting better from Covid-19, and the city was getting back to normal.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-40-58.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/2023/gap-year-wrapped---timeline/2023-09-10-10-41-14.png' alt="" /> </p> </p> <h2 id="summary">Summary</h2> <p>That&rsquo;s the first 6 months for the gap year. Overall, I have more activities and trips than before. And I recorded more moments, let met find that there are many different ways to enjoy life.</p> <p>I do not have soo many continuous writing time, so I just post the first 6 months in this post. I would update the rest half year and other topic in the next post, about:</p> <ul> <li>my personal finance during the gap</li> <li>what I got and what I lost comparing to the previous life</li> <li>products, engineering, skills</li> <li>the plan about the future</li> </ul> <p>Thanks for reading the non structured post, I hope you enjoy it.</p> <p>Next Post: <a href="https://strrl.dev/post/2023/gap-year-wrapped-timeline-x2/">Gap Year Wrapped - Timeline (Second Half)</a></p> What I am Chasing https://strrl.dev/post/2023/what-i-am-chasing/ Sat, 19 Aug 2023 13:02:15 +0800 https://strrl.dev/post/2023/what-i-am-chasing/ <h2 id="honestly-i-do-not-know">Honestly, I do not know</h2> <p>I have to grant that the gap-year would really consume the ambitions. On the days I just left the PingCAP, I sent lots of resumes to companies to get a job, even I have some unrealistic dreams that I (we) build a new start-up based on Chaos Mesh. But now, what I want is only having a good sleep everyday, then enjoying everything that I do.</p> <p>Rather than call it ambition-consuming, it&rsquo;s better that I finally realize that there are lots of tiny happiness could be found in daily life. When I cooking, I enjoy the hot oil splash on my arm, it&rsquo;s heart but it&rsquo;s new experience. When I eating, I feel each fiber inside of the vegetables cracked by my teeth. When I resting, I feel the breeze flow under my hand, and the warm sunlight spread on my body.</p> <h2 id="what-i-chased-before">What I chased before</h2> <p>I failed to figure out what I chased before.</p> <p>I did not work for lots of money, and I do not clear about what could I do in the next several years. What I did was just follow &ldquo;what I could do&rdquo; or &ldquo;it seems interesting&rdquo;.</p> <ul> <li>Java CRUD at Bangsun Tech, I could do that.</li> <li>SRE at WeiDian, I could do that.</li> <li>Build Chaos Mesh at PingCAP, I could do that, and it seems interesting.</li> </ul> <h2 id="future-plans">Future Plans</h2> <p>Well, I think lacking of long-term plan is not a big deal. And I have some interest on the following things:</p> <ul> <li>Personal Finance</li> <li>Build and Design Product</li> </ul> <p>That&rsquo;s all, I think.</p> 2023 Week 32: Ordinary Days x 3 https://strrl.dev/post/weekly-recap/2023/32-ordinary-days/ Sat, 12 Aug 2023 16:11:48 +0800 https://strrl.dev/post/weekly-recap/2023/32-ordinary-days/ <h2 id="overview">Overview</h2> <p>It&rsquo;s so awkward that I still no back to the regular weekly recap. 😅</p> <p>And there are still no many things recorded in Journal since last weekly recap written.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/32-ordinary-days/2023-08-12-16-14-05.png' alt="" /> </p> </p> <h2 id="professional-stuff">Professional Stuff</h2> <h3 id="new-way-to-build-user-interface-chat-bot">New way to build User Interface: Chat Bot</h3> <p>I always stuck with drawing UI.</p> <p>I have made some bad UI design like these:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/32-ordinary-days/2023-08-12-16-48-09.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/32-ordinary-days/2023-08-12-16-49-39.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/32-ordinary-days/2023-08-12-16-53-11.png' alt="" /> </p> </p> <p>I was struggling with the UI design, the layout, typography, color, animation, etc.</p> <p>Until recent days ago, when I was using the Telegram &ldquo;Saved Message&rdquo;, I just realized that the chat bot is another good way to build the User Interface.</p> <p>I think I would revive the &ldquo;GTD Buddy&rdquo; project and build it as a chat bot, that&rsquo;s a dedicated, fully guided, and interactive GTD assistant.</p> <h3 id="in-progress-from-hugo-to-astro">In Progress: From Hugo to Astro</h3> <p>I found that the new static site generator, Astro, is very powerful and flexible, I think it would be a good replacement for Hugo, and I rather became locked-in with the new Astro framework.</p> <p>For me, the content is the most important thing in blog, but the appearance is also a big influence for my writing experiences.</p> <p>There are lots of blogs which have different styles but all of them are beautiful:</p> <ul> <li><a href="https://innei.in/">https://innei.in/</a></li> <li><a href="https://cali.so">https://cali.so</a></li> <li><a href="https://xuanwo.io">https://xuanwo.io</a></li> <li><a href="https://www.pseudoyu.com/">https://www.pseudoyu.com/</a></li> </ul> <p>I have no idea on making a beautiful blog, also no idea on graphic designs.</p> <p>I just have some preferred features before, like:</p> <ul> <li>embed twitter / youtube / link as a card</li> <li>og protocol supports</li> <li>better code block</li> <li>better image preview</li> <li>&hellip;</li> </ul> <p>The initial reason I want to switch to Astro is that I found that Astro could build integration with lots of different frontend frameworks, like React, Vue, Svelte, etc.</p> <p>And the building system is also flexible and pluggable, I have resolved the issue of &ldquo;Image Relative Path in Markdowns&rdquo; by making a custom plugin.</p> <p>Although Astro is a framework, not a library, I have seen that its power. I think I could accept that trap myself into its ecosystem.</p> <h2 id="personal-stuff">Personal Stuff</h2> <h3 id="discord-is-not-good-as-a-saved-message">Discord is not good as a &ldquo;Saved Message&rdquo;</h3> <p>Discord is a Electron App, it&rsquo;s <strong>slow</strong> to open, and sometime it automatically install updates. It really takes more time than open telegram and paste the link to the &ldquo;Saved Message&rdquo;.</p> <p>Telegram always be native apps for different platform, it&rsquo;s very very fast to open.</p> <blockquote> <p>The same thing also happens on Notion, that&rsquo;s another reason I found that I have came to rely on the &ldquo;Saved Message&rdquo; in telegram but not &ldquo;GTD / Capture&rdquo; in Notion.</p></blockquote> <p>Discord has a limitation on upload file size, free user could only upload file with size up to 20MiB, and with Nitro, it would be (Some number in MiB, I forgot). For my use case, a PDF doc might be up to several dozens of MiB, and video would be hundreds of MiB. It&rsquo;s so limited.</p> <p>IIRC, free user in Telegram could upload up to 2 GiB file, and with Telegram Premium, it would be 4 GiB. That&rsquo;s enough for my personal usage.</p> <p>So I am going to move my &ldquo;Saved Message&rdquo; from Discord back to Telegram.</p> <p>The only one thing that Telegram does not do it well is &ldquo;full text searching in Chinese&rdquo;, and it has been a long time since the telegram community report it. ☹️</p> <p>For me, I think here is another solution for that, it relates to the above topic, &ldquo;GTD Buddy&rdquo;, I would integrate the chat bot and Notion Storage, using the searching capability of Noiton.</p> <h3 id="i-broken-my-left-ankle">I broken my left ankle</h3> <p>Yeah.. That&rsquo;s really hurt. 🥹</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">给大家看看崴到的角,很神奇,疼的地方不紫,紫的地方不疼 <a href="https://t.co/cWxeDwIdKB">https://t.co/cWxeDwIdKB</a> <a href="https://t.co/8U8Pmvh5Bh">pic.twitter.com/8U8Pmvh5Bh</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1681661283479830530?ref_src=twsrc%5Etfw">July 19, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>It was 3-4 weeks ago, it does become better, but I still not fully recovered from that damage.</p> <p>And I walked soo much in the past 2 weeks, for looking around new office with Kevin, and touring west lake and markets with my mom.</p> <h3 id="travel-to-shenzhen-and-hong-kong">Travel to Shenzhen and Hong Kong</h3> <p>I traveled to Shenzhen to meet one of my university classmate. She worked as an audio engineer in Tencent, Timi Studio, but she got the message that she would be &ldquo;graduated&rdquo; from the company. Then we cancelled the plan to tour around the Hong Kong, we just stayed in Shenzhen for 2 days, and I came back to Hangzhou earlier than planned.</p> <p>The one main purpose to go to Hong kong is open an account from any Hong Kong bank. I applied for ZA Bank, Ant Bank and HSBC One. The process is kind of smoothly, I does not get rejected, but I am still waiting fot the physical card to be delivered to Hangzhou.</p> <p>I also meet Jie and Innei in Hong Kong, we ate McDonald&rsquo;s and talked a lot. 🥰🥰</p> Properly Positive Feedback and Comfort Zone https://strrl.dev/post/properly-positive-feedback-and-comfort-zone/ Mon, 17 Jul 2023 17:11:08 +0800 https://strrl.dev/post/properly-positive-feedback-and-comfort-zone/ <p>In last few weeks since I completed the TOEFL test, I do not learn English anymore. And I also break the plan in gym with the coach.</p> <p>I am avoiding the potential things that makes me unhappy, but it is the thing makes me unhappy in the long term.</p> <p>Anxious people live in the future, regretful people live in the past. I DO live in present, I fell happy, but I am fear about the future.</p> <p>Recently I only do the thing that makes me happy in the short term, like playing games, and building some side-projects, like Cloudflare Tunnel Ingress Controller and Dejavu. It makes stay at the Comfort Zone, and I just lost the passion to spend time on learning new things, like finance, economics, English, and body building.</p> <p>It&rsquo;s time for me to find the way to spoof the brain, and make me some good habits.</p> <p>I need find some goog positive feedback / reward as the short term motivation.</p> 2023 Week 28: Ordinary Days x 2 https://strrl.dev/post/weekly-recap/2023/28-ordinary-days/ Sun, 09 Jul 2023 10:39:55 +0800 https://strrl.dev/post/weekly-recap/2023/28-ordinary-days/ <h2 id="overview">Overview</h2> <p>I want to back to write the weekly recap regularly.</p> <p>No need content-rich post, just record what happened.</p> <h2 id="professional-stuff">Professional Stuff</h2> <h3 id="project-benefit-on-kubecon-maintainer-track-and-kiosk">Project Benefit on KubeCon: Maintainer Track and Kiosk</h3> <p>We (Chaos Mesh Maintainers) have submitted the application form for Maintainer Track and Offline Booth(Kiosk) on KubeCon China 2023 in Shanghai. If everything goes well, we would have a presentation and a part-time booth here.</p> <p>We are also planning the Maintainer Track part for KubeCon NA 2023. We asked Saiyam to participate in, and he agreed. He also suggested us make a micro-survey to collect some voice from community.</p> <p>All in all, see you in Shanghai!</p> <h3 id="idea-spirit-toad">Idea: Spirit Toad</h3> <p>As you might already know, I am considering walking into the Apple Developer Ecosystem. Following &ldquo;learning-by-doing&rdquo; principle, I would make one or several simple apps to get familiar with the ideation, design, development, and release process.</p> <p>So that is my simple idea that could become my first app: Spirit Toad.</p> <blockquote> <p>中文名: 十全灵蛤蟆</p></blockquote> <p>The idea is came from a TV series called &ldquo;少年大欽差&rdquo;, here is the cut.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/28-ordinary-days/spirit-toad.jpg' alt="Spirit Toad" /> </p> </p> <blockquote> <p>Here, that&rsquo;s a Spirit Toad. There is another male one in my bag. After I find the boy, I would squeeze the male one, and this female one would also make a sound.</p></blockquote> <p>The business of the app is quite simple: the application would always used in pair, hit the button on one device, and the other device would make a sound / receive a notification.</p> <p>I would start at making an iOS app, then move forward to other platforms.</p> <p>Also I think I would publish it on App Store, walk through the whole process.</p> <h3 id="idea-deja-vu-an-open-source-alternative-to-rewindai">Idea: Deja-Vu, an Open Source Alternative to Rewind.ai</h3> <p>Several days ago, I tried to start using Rewind.ai as the powerful tool to record my dataflow on personal computer.</p> <p>But Rewind.ai has some limitations:</p> <ul> <li>Limited &ldquo;Rewind&rdquo;(Search data from recording) Usage. <ul> <li>50 rewind for free plan,</li> <li>10 rewind per month for basic plan,</li> <li>and unlimited rewind for pro plan.</li> <li>ref: <a href="https://www.rewind.ai/pricing">https://www.rewind.ai/pricing</a>.</li> </ul> </li> <li>NOT available on other platform. <ul> <li>I am a linux user and all my major process happens on linux!</li> <li>and I do not want to use mac as the primary device.</li> </ul> </li> </ul> <p>The maker of Rewind.ai said that the power of Apple Silicon could make the recording and OCR process much efficient. But I think it is possible to make a similar tool on a more general computer, without certain devices like Apple Silicon or Nvidia GPU.</p> <p>So I created an Open Source project called <a href="https://github.com/STRRL/dejavu">Dejavu</a>. Want to do it with existed open source tools.</p> <p>I am still working in proof-of-concept stage, and it works well for now! It&rsquo;s quite simple for now:</p> <ul> <li>Capture screenshot every 2 seconds.</li> <li>OCR the screenshot and save the text.</li> <li>use sqlite with Full-Text-Search extension to store and index the text.</li> <li>Query API for the text.</li> </ul> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/28-ordinary-days/rewind-vs-dejavu.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/28-ordinary-days/2023-07-09-12-05-06.png' alt="" /> </p> </p> <h2 id="personal-stuff">Personal Stuff</h2> <h3 id="i-bought-an-apple-watch">I bought an Apple Watch</h3> <p>As just what I said in the last post, I would finally and fully fall into the Apple Ecosystem.</p> <p>I stopped using my Samsung Watch 4, and bought an Apple Watch S8.</p> <p>Also I started to subscribe the Apple Fitness+. Even Samsung have all the competitive alternative solution, and event some of them is free, I even would not to try it.</p> <p>Because the Z flip 4, the cell phone I used, is not good as I expected. I would never buy a Samsung phone again.</p> <p>For people who want to buy a foldable phone, my suggestion is: Don&rsquo;t buy, and wait for the Apple product.</p> <h3 id="diablo-iv-classes">Diablo IV Classes</h3> <p>I have tried all the classes expect Barbarian in Diablo IV, and I finally I still like the rogue most.</p> <p>The first Season of Diablo IV is coming at June 21, and I think I would choose the Rogue as my first class for progression, and maybe try Barbarian later.</p> <p>And, Necromancer is the most powerful class now, that&rsquo;s totally out of our expectation at the start of the game.</p> <h2 id="summary">Summary</h2> <p>So that&rsquo;s the sudden end, just tell some stories, no more stress to make it content-rich and good looking.</p> 2023 Week 24/27: Long Live With Apple https://strrl.dev/post/weekly-recap/2023/24-longlivewithapple/ Tue, 04 Jul 2023 10:53:23 +0800 https://strrl.dev/post/weekly-recap/2023/24-longlivewithapple/ <h2 id="overview">Overview</h2> <p>This is the weekly recap post spans from May 21 to June 16, 2023.</p> <p>This post might be longer than usual, because I do <strong>NOT</strong> spend much time on preparing language tests. 🤡 Instead, I spent lots of time on social activities and playing video games. 😅</p> <p>So there are lots of things to write down.</p> <blockquote> <p>Actually, I&rsquo;m almost exhausted just listing these things on titles. 😵</p></blockquote> <p>Here we go.</p> <h2 id="professional-stuff">Professional Stuff</h2> <h3 id="new-idea-cloudflare-tunnel-ingress-controller">New Idea: Cloudflare Tunnel Ingress Controller</h3> <p>TLDR; I build a Kubernetes Ingress Controller which could expose the Kubernetes Ingress to the Internet,</p> <ul> <li>easily, quickly, and securely</li> <li>without requiring a public IP address</li> <li>without maintaining any Tunnel / Jump Server (like frpc, zerotier, tailscale)</li> </ul> <p>I have a homelab, which contains 4 x86/arm computing devices and 1 storage device. And I use Kubernetes for manage and orchestrate workloads.</p> <p>The networking model in Kubernetes is complex, there are several different kind of networks:</p> <ul> <li>Host Networking, the real network for the Control Plane host or Worker host</li> <li>Pod Networking, the virtual/real network for Pods, usually a virtual overlay networking, which only accessible on Layer 3 (IP Layer)</li> <li>Service Networking, the virtual network for Services, usually virtual IP addresses, and bunch of iptables / ipvs rules.</li> </ul> <p>For exposing a workload running in Kubernetes to the Internet, a system administrator need to understand all these networking, and all of them must be configured correctly.</p> <p>I used to use:</p> <ul> <li>Cilium CNI as Pod Networking</li> <li>MetalLB as Service LoadBalancer</li> <li>Nginx Ingress / Traefik Ingress as Ingress Controller</li> </ul> <p>Then I have DNS records like:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">$ dig nodes.worker.kiu.strrl.cloud </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">;</span> &lt;&lt;&gt;&gt; DiG 9.18.15 &lt;&lt;&gt;&gt; nodes.worker.kiu.strrl.cloud </span></span><span class="line"><span class="cl"><span class="p">;;</span> global options: +cmd </span></span><span class="line"><span class="cl"><span class="p">;;</span> Got answer: </span></span><span class="line"><span class="cl"><span class="p">;;</span> -&gt;&gt;HEADER<span class="s">&lt;&lt;- opco</span>de: QUERY, status: NOERROR, id: <span class="m">2408</span> </span></span><span class="line"><span class="cl"><span class="p">;;</span> flags: qr aa rd ra<span class="p">;</span> QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: <span class="m">1</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">;;</span> OPT PSEUDOSECTION: </span></span><span class="line"><span class="cl"><span class="p">;</span> EDNS: version: 0, flags:<span class="p">;</span> udp: <span class="m">1232</span> </span></span><span class="line"><span class="cl"><span class="p">;;</span> QUESTION SECTION: </span></span><span class="line"><span class="cl"><span class="p">;</span>nodes.worker.kiu.strrl.cloud. IN A </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">;;</span> ANSWER SECTION: </span></span><span class="line"><span class="cl">nodes.worker.kiu.strrl.cloud. <span class="m">30</span> IN A 192.168.1.207 </span></span><span class="line"><span class="cl">nodes.worker.kiu.strrl.cloud. <span class="m">30</span> IN A 192.168.1.203 </span></span><span class="line"><span class="cl">nodes.worker.kiu.strrl.cloud. <span class="m">30</span> IN A 192.168.1.154 </span></span><span class="line"><span class="cl">nodes.worker.kiu.strrl.cloud. <span class="m">30</span> IN A 192.168.1.184 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">;;</span> Query time: <span class="m">163</span> msec </span></span><span class="line"><span class="cl"><span class="p">;;</span> SERVER: 192.168.1.1#53<span class="o">(</span>192.168.1.1<span class="o">)</span> <span class="o">(</span>UDP<span class="o">)</span> </span></span><span class="line"><span class="cl"><span class="p">;;</span> WHEN: Tue Jun <span class="m">20</span> 09:36:20 CST <span class="m">2023</span> </span></span><span class="line"><span class="cl"><span class="p">;;</span> MSG SIZE rcvd: <span class="m">121</span> </span></span></code></pre></td></tr></table> </div> </div><p>So I could use any of these IP addresses to expose a HTTP service locally, like this:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">curl --insecure -v -H Host:jellyfin.strrl.cloud https://nodes.worker.kiu.strrl.cloud </span></span></code></pre></td></tr></table> </div> </div><p>And I use Cloudflare Tunnel to expose these service to the Internet.</p> <p>With this solution, I need to manually configure the Cloudflare Tunnel for each domain, and the ingress layer (traefik ingress) is actually not needed.</p> <p>I imagine that maybe I could use cloudflared as a Ingress Controller directly, and I found that:</p> <p><a href="https://github.com/cloudflare/cloudflare-ingress-controller">cloudflare/cloudflare-ingress-controller</a></p> <p>It&rsquo;s the official Cloudflare Ingress Controller, but it is not maintained for a long time, and it&rsquo;s not working with the latest version of Kubernetes.</p> <p>So I built the successor of it:</p> <p><a href="https://github.com/STRRL/cloudflare-tunnel-ingress-controller">STRRL/cloudflare-tunnel-ingress-controller</a></p> <p>I have used it to expose my several services to the Internet, and it works well for a while. Great!</p> <h3 id="package-on-aur-larksuite-bin">Package on AUR: larksuite-bin</h3> <p>For some reason, I need to use Lark Suite, which is a International version of Feishu. I installed the latest <code>feishu-bin</code> from AUR, but Feishu noticed me that I can NOT use Feishu as Lark. Then I noticed the <code>larksuite-bin</code> on AUR has been marked as outdated.</p> <p>Fortunately, I did explore the <code>feishu-bin</code> package before, I think I could package a new version for <code>larksuite-bin</code>.</p> <blockquote> <p>Actually, the maintainer of <code>feishu-bin</code> on AUR is an ex-colleague of mine, also an old friend from Hangzhou Linux User Group. 😄</p></blockquote> <p>Then I sent a email to the current maintainer of <code>larksuite-bin</code> on AUR, for asking me as the co-maintainer:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/24-longlivewithapple/2023-06-20-09-51-43.png' alt="Email" /> </p> </p> <p>So the final result is I became the maintainer of <code>larksuite-bin</code> on AUR now, and I upgraded the package to the latest version.</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">年轻人的第一次更新 AUR ( <a href="https://t.co/hZJZiYRRHt">pic.twitter.com/hZJZiYRRHt</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1669262247674388481?ref_src=twsrc%5Etfw">June 15, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>Great!</p> <h3 id="summer-ospp-hangzhou">Summer OSPP Hangzhou</h3> <p>I attended the Summer OSPP Hangzhou, and giving a lighting speech:</p> <p> <p class="md__image"> <img src='./DoikJz2i.jpg' alt="" /> </p> </p> <p> <p class="md__image"> <img src='./qDClwlWO.jpg' alt="" /> </p> </p> <p>Slides: <a href="https://docs.google.com/presentation/d/1PUwXGVGcI6Ibk_FcFBqwFYnMfcAxNYX3QT_IyxsGtFQ/edit?usp=sharing">https://docs.google.com/presentation/d/1PUwXGVGcI6Ibk_FcFBqwFYnMfcAxNYX3QT_IyxsGtFQ/edit?usp=sharing</a></p> <h3 id="chaos-mesh-on-kubecon-china-2023">Chaos Mesh on KubeCon China 2023</h3> <p>KubeCon finally come back to China, the previous one was still held before the COVID-19 pandemic.</p> <p>I have applied for a offline booth for Chaos Mesh, as the benefit of being a CNCF Incubating project.</p> <p>So, I will be there, welcome to visit our booth, and talk with us!</p> <h3 id="onboarding-webp-cloud-service">Onboarding WebP Cloud Service</h3> <p><a href="https://nova.moe/">Nova</a> asked me to try his new service, which is a WebP Cloud Service.</p> <p>This site has been configured with that service, and it really reduces the size of images, and speeds up the loading.</p> <p>I have posted another article about this service, take a look if you are interested:</p> <p><a href="http://strrl.dev/post/2023/speed-up-image-loading-with-webp.se/">http://strrl.dev/post/2023/speed-up-image-loading-with-webp.se/</a></p> <h2 id="personal-stuff">Personal Stuff</h2> <h3 id="apple-wwdc">Apple WWDC</h3> <p>There are soo many new software features announced on WWDC, and I am so excited about them:</p> <ul> <li>NameDrop, it&rsquo;s so cool to exchange the contact, but it&rsquo;s not available in current beta version.</li> <li>Offline Map, it&rsquo;s useful, but it&rsquo;s not available in China.</li> <li>CheckIn in Message app, it&rsquo;s also an amazing feature, I always share my location and direction to my girlfriend, and check-in would enhance it. But it&rsquo;s also not available in China now.</li> <li>Mental Health! I have used it for several days, as the objective reflection of my mood.</li> <li>Journal! I want the Journal App so much! The AI generated daily summary is so cool! It would be reflection and summary for my life!</li> </ul> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/24-longlivewithapple/2023-06-20-10-15-21.png' alt="" /> </p> </p> <p>I am thinking about buying iWatch instead of my current Samsung Watch, and fully use the Apple Ecosystem.</p> <p>I researched / explored lots of solutions and methodologies to make me happy and improve the productivity, and I think Apple Ecosystem would help me to achieve them.</p> <h3 id="meet-with-friends">Meet with Friends</h3> <h4 id="heading">🍞</h4> <p>🍞 is a young but professional front-end developer. We have 3 meals together, and talked a lot about the engineering, technology, and life.</p> <p>I am so impressive about his passion about the engineering, I have saw the bright future of him.</p> <h4 id="teacher-">Teacher 🐟</h4> <p>We came to a Piano Cafe one day afternoon, and played a KAWAI Grand Piano. (Or Steinway? I did not remember.)</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">🍖<br>🔥<br><br>梅开二度 <a href="https://t.co/Kiut08542x">https://t.co/Kiut08542x</a> <a href="https://t.co/9JRaxJeT2o">pic.twitter.com/9JRaxJeT2o</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1668896052420939776?ref_src=twsrc%5Etfw">June 14, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>The key of Grand Piano is even much lighter than my digital piano, YAMAHA P115.</p> <p>I took some sheet books for some Game Original Soundtrack, like NieR and Monster Hunter. Teacher 🐟 played them as sight-reading, that&rsquo;s so impressive!</p> <h4 id="tualatrix">TualatriX</h4> <p>TualatriX is a professional iOS developer and also a freelancer, we are both villagers in Liangzhu Culture Village.</p> <p>The first time we meet each other was introduced by Lakr. We have a lunch together, and we talked and coded at the Starbucks for a whole afternoon.</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">今天认识了几个新朋友,大家一起占领了村里的星巴克的大桌,边晒太阳、边聊天、边写代码,很开心。<br><br>傍晚时天空也非常美。 <a href="https://t.co/Ge2yyx1aEt">pic.twitter.com/Ge2yyx1aEt</a></p>&mdash; 图拉鼎 (@tualatrix) <a href="https://twitter.com/tualatrix/status/1660974714595192834?ref_src=twsrc%5Etfw">May 23, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>He also taught me some SwiftUI stuff, and I am so impressive about that, the declarative way to build the UI!</p> <h4 id="pseudoyu">pseudoyu</h4> <p>We came to the Rokid company&rsquo;s activity, which is watching WWDC 2023 together. We tried the unreleased AR devices, it&rsquo;s not kind of great experience, but it&rsquo;s still cool.</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">久违的收到神秘蛋糕的生日仪式感;和 <a href="https://twitter.com/strrlthedev?ref_src=twsrc%5Etfw">@strrlthedev</a> 哥哥参加线下活动、尝鲜 AR 眼镜和闲聊一晚,还被他超帅的初音痛车送回家(四舍五入生日第一秒是初音陪我过的);终于见到了偶像开发者 <a href="https://twitter.com/tualatrix?ref_src=twsrc%5Etfw">@tualatrix</a>;以及即将开始的 WWDC23。<br><br>不错的开端,新的一年大概会是个好年吧。 <a href="https://t.co/fQsrbsQLlD">pic.twitter.com/fQsrbsQLlD</a></p>&mdash; pseudoyu (@pseudo_yu) <a href="https://twitter.com/pseudo_yu/status/1665764414199398402?ref_src=twsrc%5Etfw">June 5, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <h4 id="xiaowen">Xiaowen</h4> <p>Xiaowen and I meet also at the Liangzhu Culture Village, we have a dinner in the &ldquo;甘其食 Baobao 小酒馆&rdquo;.</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">感慨一下年轻真好🫠 <a href="https://t.co/xBbv89JACe">https://t.co/xBbv89JACe</a></p>&mdash; Xiaowen (@ixiaowenz) <a href="https://twitter.com/ixiaowenz/status/1671859005319434241?ref_src=twsrc%5Etfw">June 22, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>I learned something about recording personal cash flow and budget management, he also mentioned a good application called &ldquo;you need a budget&rdquo;. And he also suggested me to get some knowledge about the CFA I certification, it would cover the basic economics and finance knowledge as a bachelor degree.</p> <h3 id="game-the-legend-of-zelda-tears-of-the-kingdom">Game: The Legend of Zelda: Tears of the Kingdom</h3> <p>Great Game! I have cleared the main story when I wrote this post.</p> <p>And there are still lots of funny content like these:</p> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/UkDcydKBb2k?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="Top 200 Best Builds &amp; Moments In Zelda TotK"></iframe> </div> <h3 id="game-diablo-iv">Game: Diablo IV</h3> <p>Another Great Game! I have played 4 different classes, and it consumed me most of the gaming time in the past several weeks.</p> <p>I also extended my friend list on battlenet, it&rsquo;s great to see lots of friends playing this game at the same time.</p> <p>I also streaming my game play on youtube, and here is the recording:</p> <p><a href="https://www.youtube.com/playlist?list=PL2CnjpVBS-U9sBtUAut_d1g0xj6jw9wcQ">https://www.youtube.com/playlist?list=PL2CnjpVBS-U9sBtUAut_d1g0xj6jw9wcQ</a></p> <h2 id="at-last">At last</h2> <p>It have been too long from last updates, I need to find a new way to build the weekly recap, or it consumed too much time to write it.</p> Unlocking the Power of Cloudflare Tunnel: Secure, Scalable, and Simple Kubernetes Ingress Controller Implementation for Your Applications https://strrl.dev/post/2023/unlocking-the-power-of-cloudflare-tunnel-secure-scalable-and-simple-kubernetes-ingress-controller-implementation-for-your-applications/ Fri, 30 Jun 2023 14:51:40 +0800 https://strrl.dev/post/2023/unlocking-the-power-of-cloudflare-tunnel-secure-scalable-and-simple-kubernetes-ingress-controller-implementation-for-your-applications/ <blockquote> <p>This post was assisted by ChatGPT and Grammarly.</p></blockquote> <h2 id="introduction">Introduction</h2> <p>Today, more and more teams are adopting cloud computing and cloud native technologies. However, exposing applications to the Internet is still a challenge. We should always consider the security, scalability, also performance of the solution. And the complexity from different cloud providers makes it even harder, tons of products and services are available, it&rsquo;s going to be a nightmare to choose the right one.</p> <p>Cloudflare Tunnel give users a secure way to expose applications to the Internet with the minimal attack surface. It&rsquo;s also easy to use, and it offers free plan to individuals.</p> <p>Kubernetes is the most popular container orchestration system, it&rsquo;s also the de facto standard for cloud native applications. Kubernetes has a built-in Ingress Resources for exposing applications to the Internet, but it&rsquo;s not enough. We need an Ingress Controller to implement the exposing logic. There are many Ingress Controllers available, which also increase the complexity of the solution.</p> <p>In this post, I will introduce a project, <a href="https://github.com/STRRL/cloudflare-tunnel-ingress-controller">Cloudflare Tunnel Ingress Controller</a>, that combines Cloudflare Tunnel and Kubernetes Ingress Controller to provide a secure, scalable, and simple solution for exposing applications to the Internet. Even though it&rsquo;s still in the very early stage, it&rsquo;s still usable and I&rsquo;m using it in my homelab.</p> <h2>GitHub - STRRL/cloudflare-tunnel-ingress-controller: 🚀 Expose the website directly into the internet! The Kuberntes Ingress Controller based on Cloudflare Tunnel.</h2> <p>🚀 Expose the website directly into the internet! The Kuberntes Ingress Controller based on Cloudflare Tunnel. - STRRL/cloudflare-tunnel-ingress-controller</p> <p><a href="https://github.com/STRRL/cloudflare-tunnel-ingress-controller">Continue reading...</a></p> <img src="https://opengraph.githubassets.com/009e25b03684355a8cce9f70adb258fd945e90d1afeab238015d28ee1fa3c8a2/STRRL/cloudflare-tunnel-ingress-controller" alt=""> <blockquote> <p>It&rsquo;s not an official project from Cloudflare. And there did exist an official project from Cloudflare, <a href="https://github.com/cloudflare/cloudflare-ingress-controller">Cloudflare Ingress Controller</a>, but it does not works and the community is not active anymore.</p></blockquote> <h2 id="use-cases-and-examples">Use Cases and Examples</h2> <p>Imagine that you are working with Kubernetes, and</p> <ul> <li>you are working on a project, and you want to share it to your colleagues for collaborating, like profiling or debugging;</li> <li>or you just finished a proof of concept, and you want to show it to others quickly;</li> <li>or you have some self-hosted services, and you want to expose it to the Internet.</li> </ul> <p>Using Cloudflare Tunnel Ingress Controller, you could expose your applications to the Internet very easily, and it&rsquo;s secure, scalable, and simple. Only create a Kubernetes Ingress Resource, and the Ingress Controller will do the rest.</p> <p>You could follow the <a href="https://github.com/STRRL/cloudflare-tunnel-ingress-controller#get-started">Get Started</a> section to try it out, bootstrap a local minikube Kubernetes Cluster, then expose the Kubernetes Dashboard to the Internet.</p> <p>Also you could take a look on this video to see how smoothly and easily it works:</p> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/e-ARlEnS4zQ?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="Bootstrap Kubernetes and Expose Kubernetes Dashboard in less than 5 mins"></iframe> </div> <h2 id="benefits">Benefits</h2> <p>Easy-to-use; Only create a Kubernetes Ingress Resources, and the Ingress Controller will do the rest. No more complex service and products from different cloud providers.</p> <p>Cloud-agnostic; It works with any Kubernetes Cluster, no matter it&rsquo;s on-premises or in the cloud, no matter it&rsquo;s managed or self-hosted.</p> <p>Other benefits from Cloudflare Tunnel; You could leverage the experience by Cloudflare, like Full TLS encryption on Internet, also no need to manage certificates, no need to have a public IP, no need to expose ports, no need to manage firewall rules, no need to manage DNS records, etc.</p> <h2 id="conclusion">Conclusion</h2> <p>For individual developers, homelab fans and small teams, Cloudflare Tunnel Ingress Controller is a great solution for exposing applications to the Internet. Just give it a try! And it&rsquo;s also a Open Source project, contribution is always welcome!</p> 使用 WebP Cloud Services 加速图片加载 https://strrl.dev/post/2023/%E4%BD%BF%E7%94%A8-webp.se-%E5%8A%A0%E9%80%9F%E5%9B%BE%E7%89%87%E5%8A%A0%E8%BD%BD/ Fri, 16 Jun 2023 09:52:29 +0800 https://strrl.dev/post/2023/%E4%BD%BF%E7%94%A8-webp.se-%E5%8A%A0%E9%80%9F%E5%9B%BE%E7%89%87%E5%8A%A0%E8%BD%BD/ <p>这篇文章是由Notion AI协助完成的.</p> <p>你可能已经注意到了, 我博客上的所有图片都是从<code>webp.strrl.dev</code>加载的.那么, 它到底是什么呢?</p> <h2 id="我的故事">我的故事</h2> <p>我在<code>strrl.dev</code>上写作和发布文章.为了使故事更加生动有趣, 我经常包含图片、画布或贴纸.</p> <p>然而, 我的手机上的原始图片可能有几兆字节大小.此外, 我有时会录制GIF来介绍交互, 这也可能导致文件大小过大的问题.</p> <p>Nova告诉我他们提供的一项服务可以作为中间层来缩小图像大小.</p> <h2 id="什么是-webp-cloud-services">什么是 WebP Cloud Services?</h2> <p>这是一项云服务, 可以通过提供现代图像格式的图片来加速网站的加载时间.</p> <h2 id="webp-cloud-services-可以在哪些地方使用">WebP Cloud Services 可以在哪些地方使用?</h2> <p>这项服务可以用于任何关心以下问题的网站:</p> <ul> <li>加载速度, 和/或</li> <li>减少网络数据流量使用.</li> </ul> <h2 id="为什么使用-webp-cloud-services">为什么使用 WebP Cloud Services?</h2> <p>因为它可以真正减少图片的大小和加载时间.</p> <p>对比</p> <p>之前:</p> <p> <p class="md__image"> <img src='./webp.se-before.png' alt="Untitled" /> </p> </p> <p>之后:</p> <p> <p class="md__image"> <img src='./webp.se-after.png' alt="Untitled" /> </p> </p> <p>完整报告:</p> <ul> <li><a href="https://pagespeed.web.dev/analysis/https-strrl-dev-post-weekly-recap-2023-21-selfdrivinglongtrip/i4gxdepubp?form_factor=mobile">https://pagespeed.web.dev/analysis/https-strrl-dev-post-weekly-recap-2023-21-selfdrivinglongtrip/i4gxdepubp</a></li> <li><a href="https://pagespeed.web.dev/analysis/https-strrl-dev-post-weekly-recap-2023-21-selfdrivinglongtrip/z04jigvyme?form_factor=desktop">https://pagespeed.web.dev/analysis/https-strrl-dev-post-weekly-recap-2023-21-selfdrivinglongtrip/z04jigvyme</a></li> </ul> <h2 id="如何使用-webp-cloud-services">如何使用 WebP Cloud Services?</h2> <p>我使用hugo生成我的博客, 通过Hugo“Markdown Render Hooks”, 我可以自定义渲染图像的方式.所以我只需替换图像的URL.</p> <p>请按照 <a href="https://docs.webp.se/webp-cloud/access/">https://docs.webp.se/webp-cloud/access/</a> 上的文档, 以各种方式将其与您的网站集成.</p> Speed Up Image Loading With WebP Cloud Services https://strrl.dev/post/2023/speed-up-image-loading-with-webp.se/ Fri, 16 Jun 2023 09:52:07 +0800 https://strrl.dev/post/2023/speed-up-image-loading-with-webp.se/ <p>This post was assisted by Notion AI.</p> <p>You may have noticed that all images on my blog load from webp.strrl.dev. So, what exactly is that?</p> <h2 id="my-story">My Story</h2> <p>I write and publish posts on <code>strrl.dev</code>. To make the stories more vivid and interesting, I always include images, canvases, or stickers.</p> <p>However, the original images from my phone can be several megabytes in size. Additionally, I sometimes record GIFs to introduce interactions, which can also cause issues with large file sizes.</p> <p>Nova has informed me of a service they offer that can act as a middle layer to shrink the image size.</p> <h2 id="what-is-webp-cloud-services">What is WebP Cloud Services?</h2> <p>This is a cloud service that could speed up the load time of your website by delivering images in modern image formats.</p> <h2 id="where-can-webp-cloud-services-be-used">Where can WebP Cloud Services be used?</h2> <p>This service can be used on any website that cares about:</p> <ul> <li>loading speed, and/or</li> <li>reducing network data traffic usage.</li> </ul> <h2 id="why-use-webp-cloud-services">Why use WebP Cloud Services?</h2> <p>Because it could really reduce the size of the image, and the loading time.</p> <p>Comparison</p> <p>Before:</p> <p> <p class="md__image"> <img src='./webp.se-before.png' alt="Untitled" /> </p> </p> <p>After:</p> <p> <p class="md__image"> <img src='./webp.se-after.png' alt="Untitled" /> </p> </p> <p>Full reports:</p> <ul> <li><a href="https://pagespeed.web.dev/analysis/https-strrl-dev-post-weekly-recap-2023-21-selfdrivinglongtrip/i4gxdepubp?form_factor=mobile">https://pagespeed.web.dev/analysis/https-strrl-dev-post-weekly-recap-2023-21-selfdrivinglongtrip/i4gxdepubp</a></li> <li><a href="https://pagespeed.web.dev/analysis/https-strrl-dev-post-weekly-recap-2023-21-selfdrivinglongtrip/z04jigvyme?form_factor=desktop">https://pagespeed.web.dev/analysis/https-strrl-dev-post-weekly-recap-2023-21-selfdrivinglongtrip/z04jigvyme</a></li> </ul> <h2 id="how-to-use-webp-cloud-services">How to use WebP Cloud Services?</h2> <p>I use hugo to generate my blog, with Hugo &ldquo;Markdown Render Hooks&rdquo;, I could customize the way to render images. So I could just replace the URL of the image.</p> <p>Follow the documentation at <a href="https://docs.webp.se/webp-cloud/access/">https://docs.webp.se/webp-cloud/access/</a> for various ways to integrate it with your site.</p> 2023 Week 21: Self-driving Long Trip https://strrl.dev/post/weekly-recap/2023/21-selfdrivinglongtrip/ Mon, 22 May 2023 11:43:07 +0800 https://strrl.dev/post/weekly-recap/2023/21-selfdrivinglongtrip/ <h2 id="overview">Overview</h2> <p>This is another so-called weekly recap but is actually updated monthly. 😅</p> <p>Things were coming continuously and never stopped in the last few days, and there are not so much dedicated time for coding and building stuff. That&rsquo;s seriously bad.</p> <p>I would try to back to the work-life pattern before the Labor Day Holidays, and try to make plans and trace them.</p> <p>The lifestyle &ldquo;just following my heart&rdquo; brought me lots of pleasure and happiness, but it does not make me feel good when I look back. And I did not make any &ldquo;value&rdquo; in the last few weeks.</p> <p>I need to push myself a little harder.</p> <h2 id="professional-stuff">Professional Stuff</h2> <h3 id="hugo-theme-doge">Hugo Theme Doge</h3> <p>I still keep discovering the solution of bring some dynamic content into hugo theme.</p> <p><a href="https://twitter.com/thecalicastle">Cali</a> built a beautiful and full-featured personal site:</p> <p><a href="https://cali.so">https://cali.so</a></p> <p>There are several amazing features I also want to bring them into my site:</p> <ul> <li>The cover image of the post</li> <li>Open Graph Card</li> <li>Link Preview Card</li> <li>Light/Dark Theme Switch</li> <li>Reactions, like giscus reactions based on GitHub Issue/Discussion, but it&rsquo;s more beautiful with motion animations</li> <li>Personal Activity, show the application I am using on the website</li> <li>also, lots of motion animations!</li> </ul> <p>Activity, Cover Image, Reactions</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/21-selfdrivinglongtrip/2023-05-22-15-46-02.png' alt="Activity, Cover Image, Reactions" /> </p> </p> <p>Open Graph Card (on Twitter, as Twitter Card)</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">昨天写了挺久,也是我第一次写博客,致敬一下陈皓(左耳朵耗子)<br>他或许离开了这个世界,但他没有离开我们<br>您是我的榜样<a href="https://t.co/3yt8PsDBYu">https://t.co/3yt8PsDBYu</a></p>&mdash; Cali Castle (@calicastle) <a href="https://twitter.com/calicastle/status/1658620846737375233?ref_src=twsrc%5Etfw">May 16, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>Link Preview</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">话说 @thecalicastle dalao, 鼠标悬浮在链接上就可以预览页面内容的这个 feature 叫什么呀? <br><br>(好炫酷! 想给自己的也整上 <a href="https://t.co/pv6A0SzIzK">pic.twitter.com/pv6A0SzIzK</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1660543519365398528?ref_src=twsrc%5Etfw">May 22, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>Light/Dark Theme Switch</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/21-selfdrivinglongtrip/Peek2023-05-2215-49.gif' alt="Light/Dark Theme Switch" /> </p> </p> <p>Animations:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/21-selfdrivinglongtrip/Peek2023-05-2215-53.gif' alt="Animations" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/21-selfdrivinglongtrip/Peek2023-05-2215-54.gif' alt="Animations" /> </p> </p> <p>I also noticed a library could be used to decorate site with animations:</p> <p><a href="https://github.com/framer/motion">https://github.com/framer/motion</a></p> <p>This library is designed for React, but hugo is a static site generator. So I need to compound React with Hugo.</p> <p>Better animation is one of the reason that I decide to compound React with Hugo, another reason is the discussion system.</p> <p>I am considering keep using GitHub Discussion as the backend of the discussion system, just like Giscus, maybe also keep compatibility with Giscus. But the view is displayed like &ldquo;Twitter Style&rdquo;: comments and reactions are displayed like on Twitter. I think maybe I could use React to write the view much easier, and manually bind it to the DOM. I also find that Giscus is also built with React, and it works in the same way.</p> <h2 id="personal-stuff">Personal Stuff</h2> <h3 id="self-driving-long-trip-4000-km-in-last-4-weeks">Self-driving Long Trip, 4000 km in last 4 weeks</h3> <p>In the last several weeks, I drove my car for about 4000 km, acrossing Zhejiang, Jiangsu, Anhui, Hubei, Hunan, Shandong provinces.</p> <p>Before the trip, I had just completed the first maintenance of my car (as 5000 km driving for the first car maintenance), and I have to make the second maintenance soon as 10k km.</p> <p>Long distance driving is definitely energy consuming, it would take me about 10 hours to drive about 800 km. And I do not want to take long distance driving in the recent future.</p> <p>I noticed that one high-speed expressway might be splited into different parts, and different expressways might also use same fragment of the road, as 共线段. As differnet expressways are built by local province goverments, there are differnet styles of the road in the different parts of the road. That&rsquo;s kind of very interesting! I would introduce the different styles of different provinces&rsquo; expressways.</p> <p>In Zhejiang Province, esperially Hangzhou, the most obvious characteristic is &ldquo;扫码事故救援&rdquo;, which means you could use your phone to scan the QR code on the top of the safe barrier stub when you face the car accident. I think each QR code might have more accurated location infomation, it&rsquo;s very useful for the emergency rescue.</p> <p>In Anhui Province, one of the thing I noticed is the huge economic gap between different districts. For example, the expressway nearby Huangshan(黄山) is 8-ways expressway, but after driving out of Huangshan district, it would be 4-ways expressway. Another thing is ther are more speed bump on the expressway, and there are lots of tunnnels which has 80 km/h speed limit. That&rsquo;s not good, because the speed limit for ground road is 120 km/h, it&rsquo;s dangerous to change the speed frequently.</p> <p>In Hunan Province, the thing is the huge emergency refuge area.</p> <p>In Hubei Province, the safe barrier is painted as blue. And the speed limits in Hubei Province are weird: 90 km/h and 110 km/h.</p> <h3 id="game-the-legend-of-zelda-tears-of-the-kingdom">Game: The Legend of Zelda: Tears of the Kingdom</h3> <p>That&rsquo;s a amazing game and I played it every day since it was released.</p> <p>And I do not want to make much comments on it, after I finish it, I would write a dedicated post for it, maybe.</p> 2023 Week 17: Ordinary Days https://strrl.dev/post/weekly-recap/2023/17-ordinarydays/ Tue, 25 Apr 2023 13:47:47 +0800 https://strrl.dev/post/weekly-recap/2023/17-ordinarydays/ <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/17-ordinarydays/2023-04-25-13-48-50.png' alt="Koujirou Sasahara" /> </p> </p> <p>The ordinary days that we live in may, in fact, be a series of miracles.</p> <p>The reason why I make such an exclamation is that in the past several weeks, my mood really turned a lot, from depressed to relaxed, from anxiety to calm down. We(my girlfriend and I) also completed tons of things on our plan, and these things were completed in a tight schedule.</p> <p>It seems all the things were followed one by one, and we resolved each of them without breaks. And finally, we made it very well. Happy Ending(, temporarily).</p> <h2 id="overview">Overview</h2> <p>It has been a long time since I wrote the last &ldquo;weekly recap&rdquo;. It&rsquo;s about 4 weeks.</p> <p>I took the TOEFL exam in mid-April, and it consumed lots of my mental energy, so I just did not record the journal during these days.</p> <p>But as you know, I did not get a good enough score, so I have to prepare it again. Wish I would get a better score next time.</p> <p>Although I have a few journal as the materials for this weekly recap, but I really really tweeted a lot. I will collect the funny stuff from my history tweets, and express some of my thoughts.</p> <p>So basically, this weekly recap is kind of monthly recap for my April.</p> <p>And this is the query I used to collect these tweets:</p> <p><a href="https://twitter.com/search?q=(from%3Astrrlthedev)%20until%3A2023-05-01%20since%3A2023-04-01&amp;src=typed_query">https://twitter.com/search?q=(from%3Astrrlthedev)%20until%3A2023-05-01%20since%3A2023-04-01&amp;src=typed_query</a></p> <h2 id="professional-stuff">Professional Stuff</h2> <h3 id="toefl-exam">TOEFL Exam</h3> <p>I want to share the differences between how I prepare the exam as a student and how I do it after I graduated.</p> <p>When I was in high school, there was only one mid-term exam and only one final-term exam each semester, and there is no chance to re-take the exam. I had no other way but only prepared for exams as hard as I can, without any measure or standard to evaluate the preparation. The most extreme case is the &ldquo;Gao Kao&rdquo;(高考), the college entrance exam, one for all as a single exam.</p> <p>After I took into the university, things got a little change: the final score would consider the ordinary class performance, the mid exam and the final exam, but the final exam still tool 70% weight.</p> <p>After I graduated from the university and got the first job, I found that the project and engineering runs in a different way:</p> <ul> <li>project managers and engineers make a research on possible potential ways</li> <li>then we figure out the tradeoff between different ways</li> <li>then we choose the best / most efficient way</li> <li>if it does NOT work, we would repeat the process, re-evaluate the tradeoff and choose another way</li> </ul> <p>I decided to use the engineering way to prepare this exam: first, take general preparation for a exam, evaluate the situation, then make the rest decisions.</p> <p>I use a word book and some online courses for preparing the exam, and actually, I did not complete all of them before the exam. 🤣 I took the exam, got a intermediate score, also got confidence and experience.</p> <p>For <strong>reading and listening</strong>, there are still lots of words and phrases that I can not understand. The target is <strong>understanding all the sentences</strong> of the mock testing material. I should memorize more words, and keep reading and listening more materials, like <em>WSJ Journal</em>, <em>TED/TEDx</em>, <em>stuff you should know</em>, etc. Maybe practice some <strong>dictation</strong> in the future.</p> <p>For <strong>speaking</strong>, put more attention on the pronunciation of the words and the intonation of the sentences. The target is <strong>expressing the thoughts(with notes) clearly without hesitation and repetition</strong> and <strong>always thinking in English</strong>. Just keep practicing with friends in the weekly English Club. Maybe practice some &ldquo;following up&rdquo; with the podcast and videos.</p> <p>For <strong>writing</strong>, I just have no other ideas about that. Maybe just keep the habit of writing the weekly recap and the daily journal. But they did not help a lot, because the TOEFL does not test the storying skill, but the ability to write a formal essay.</p> <blockquote> <p>Another funny story is that I just learned some tricks and writing templates from my girlfriend as &ldquo;TOEFL Writing Crash Course&rdquo;, and it worked perfectly, I got 21 in the writing section.</p></blockquote> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">🤡 女朋友带我十分钟速成托福综合写作</p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1647932575607058434?ref_src=twsrc%5Etfw">April 17, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>Take it easy! Good luck to us! 🎉</p> <h3 id="ssd-broken">SSD Broken</h3> <p>Just the day before the TOEFL exam day, my primary dev machine SSD got broken.</p> <p>I noticed some phenomenon that might caused by the SSD, but I did not take it seriously.</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">🌿锁了个屏,拿手机发了个推,然后发现<br><br>我 盘 没 了 <a href="https://t.co/QlJQOnf5M3">pic.twitter.com/QlJQOnf5M3</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1634041195952472064?ref_src=twsrc%5Etfw">March 10, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>And one day, things got worse, the whole system became unavailable, any commands would report &ldquo;IO Error&rdquo;, and Kernel Message shows that the nvme controller is down.</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">奇怪,下一步该怎么 profile 呢?<br><br>ssd 的问题? 电源的问题?kernel 的问题? <a href="https://t.co/5uEJareY12">https://t.co/5uEJareY12</a> <a href="https://t.co/2fVCeBfPyK">pic.twitter.com/2fVCeBfPyK</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1647835081300664320?ref_src=twsrc%5Etfw">April 17, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>So I think there must be something broken in hardware level, maybe just incompatibility, or maybe dated / aging firmware / hardware. At that time, I did not have much mental energy to find the root cause, I just want to fix it ASAP.</p> <p>I bought a new SSD(with the same capacity and sector size, for exactly <code>dd</code> command to copy the data), and just replaced the old one, but used another nvme slot on the mother board.</p> <p>Finally, the primary dev machine was back to work, with better IO performance from the next generation of the same series SSD.</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">莽完了! 复活啦!<br><br>因为两块 SSD fdisk 看 bytes 和 sector 数量都一样的, 所以直接 dd 盘了.<br><br>然后接回去, 重启! 进系统啦! <a href="https://t.co/8iByY2ESCn">https://t.co/8iByY2ESCn</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1648652041684938752?ref_src=twsrc%5Etfw">April 19, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>But I also noticed that the &ldquo;broken&rdquo; (suspiciously) SSD just works well on my Desktop during the <code>dd</code> process, and I use the an external PCIE-NVME card to connect the SSD to the Desktop. So I guess the problem might be the compatibility between the SSD and the motherboard, or some power management issues.</p> <p>Maybe I could use the old one as another storage for games! Yeah! 1 TiB more Storage!</p> <h3 id="kubecon-eu-2023">KubeCon EU 2023</h3> <p>I do not even registered the online KubeCon EU 2023 virtual. I have bad experiences with past online confluences, there are lots of interesting presentations happened at the same time, and I finally need to watch the recording after the streaming.</p> <p>I decide just watch the recording, no online streaming anymore. Another relaxing way to enjoy the summit.</p> <p>The recording videos are still not available on youtube yet, after they are uploaded to youtube, I will make a wishlist of topics, and take some notes / reviews. I would also collect / tidy my wishlists and reviews for past KubeCons into my knowledge base site. I would publish them at the same time.</p> <p><strong>Again, special thanks to Saiyam</strong>. He brought the talk for Chaos Mesh, and tell us the in-person presentation worked very well: lots of listeners, and some feedbacks from users.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/17-ordinarydays/2023-05-01-23-18-45.png' alt="" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/17-ordinarydays/2023-05-01-23-19-05.png' alt="" /> </p> </p> <h3 id="new-idea-kubernetes-auditing-dashboard">New idea: Kubernetes Auditing Dashboard</h3> <p>It seems there is NO such project that works as a dedicated Kubernetes Auditing System, even as the most simple one.</p> <p>Some cloud service suggest their integration with Kubernetes auditing, some blogs post the ELK integration with auditing log, and KubeSphere also provide an log based integration.</p> <p>And it seems there is NO open source project exists in this area.</p> <p>So I just created a new project: <a href="https://github.com/STRRL/kubernetes-auditing-dashboard">Kubernetes Auditing Dashboard</a></p> <blockquote> <p>The last time I have similar idea, new project on new area which have no predecessors, is the <a href="https://github.com/STRRL/kubectl-image">kubectl-image</a>. The vision of the project is providing user-friendly interface to interact with images on each kubernetes node, like warming up and garbage collection, even like repository-less container images distribution. But as you can see, this project is still working-in-progress for unlimited time. 🤣</p></blockquote> <h3 id="new-idea-hugo-theme-doge">New idea: Hugo Theme Doge</h3> <p>My primary domain is Backend developing and infrastructure, also some practice as System Admin. I have only a few skill in Frontend developing and UX Design.</p> <p>I tried the online course like Google UX, but I do not finish it yet. (Shame, I know. I definitely should find some time and finish it in the future.) And I also like &ldquo;learning-by-doing&rdquo;.</p> <p>A designer friends told me that one of the important thing of design is the layout of the each component, and he suggested me imitating some sites by yourself, and I would find the &ldquo;feeling&rdquo; about the design. He also suggested me this site: <a href="https://dribbble.com/">https://dribbble.com/</a>. Many designers &ldquo;showoff&rdquo; their portfolios on this site.</p> <p>I just have a demand of new hugo theme: <a href="https://strrl.dev/post/weekly-recap/2023/13-normalweeklyrecap-s/#refine-the-blog-theme">2023 Week 13 / Refine the Blog Theme</a>. Why not create a new theme by myself, also imitating some sites?</p> <p>That&rsquo;s the work:</p> <ul> <li><a href="https://github.com/STRRL/hugo-theme-doge">hugo-theme-doge</a></li> <li>also I would publish my blog in the theme: <a href="https://doge.strrl.dev/">https://doge.strrl.dev/</a></li> </ul> <p>Preview:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/17-ordinarydays/2023-05-01-23-41-57.png' alt="" /> </p> </p> <p>But as you know, a static personal blog site based on Hugo could not act exactly the same as the social media platform. I have made some bypass solutions with discussion plugin integration for reaching similar functions.</p> <p>I would keep constructing this theme in the next weeks, and it will replace with hugo-theme-even as the primary theme of my site. 🤩</p> <h2 id="personal-stuff">Personal Stuff</h2> <h3 id="itasha-car">ITASHA CAR</h3> <p>My Itasha Car completed, and I really love it.</p> <p>No more words to say, just follow this twitter thread:</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">在 Miku 生日这天, 俺的 Miku 痛车开始施工了! <a href="https://t.co/S584nhBrjB">pic.twitter.com/S584nhBrjB</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1633836036395782161?ref_src=twsrc%5Etfw">March 9, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <h3 id="trip-at-labor-day-holiday">Trip at Labor Day Holiday</h3> <p>We take a trip during Labor Day Holiday, and we get fully relaxed.</p> <p>We attended the Itasha Car Party in ChangSha, also went to the comic exhibition nearby.</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">痛一会 in 长沙 <a href="https://t.co/Le9zlGdipc">pic.twitter.com/Le9zlGdipc</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1652864080762540032?ref_src=twsrc%5Etfw">May 1, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">感受一下群友的变态 <a href="https://t.co/BP97J3oHCX">pic.twitter.com/BP97J3oHCX</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1652653916759408642?ref_src=twsrc%5Etfw">April 30, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>The only one thing I want to say is: there are too many Genshin Impact stuffs here, and Hatsune Miku becomes dated star. I am hardly to find some peripheral products of Miku, but tons of them for Genshin. 😢😢</p> <p>When I writing this post, it is still during the holiday. So I would not write too much about the trip, just tell you we have definitely great time. 😜</p> <p>Maybe I would write something about the trip in the next weekly recap.</p> <h3 id="new-twitter-account-maybe">New Twitter Account Maybe</h3> <p>I am considering about create a new Twitter account, only for technical stuffs in English. The current twitter account have to many daily life content, and I think it&rsquo;s not good for my professional branding(if I have it. 🤣)</p> <p>And I also consider that maybe I should lock my current twitter account, and only accept the followers I know in person. I am not sure about this for now. I want to share the happiness from my daily life, but a locked account is not good for this.</p> <h3 id="funny-stuff">Funny Stuff</h3> <p>Fel Walnut</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">邪能核桃 <a href="https://t.co/kFJhqTAkmk">pic.twitter.com/kFJhqTAkmk</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1644622748290023425?ref_src=twsrc%5Etfw">April 8, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>You Looking &ldquo;Perfect&rdquo; Today</p> <blockquote class="twitter-tweet"><p lang="zh" dir="ltr">上次我还坐了这个 <a href="https://t.co/vIFItiHbvC">pic.twitter.com/vIFItiHbvC</a></p>&mdash; STRRL.gpt (@strrlthedev) <a href="https://twitter.com/strrlthedev/status/1652243179482259456?ref_src=twsrc%5Etfw">April 29, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 2023 Week 13: Normal Weekly Recap(s) https://strrl.dev/post/weekly-recap/2023/13-normalweeklyrecap-s/ Sun, 05 Mar 2023 10:46:15 +0800 https://strrl.dev/post/weekly-recap/2023/13-normalweeklyrecap-s/ <h2 id="overview">Overview</h2> <h2 id="professional-stuff">Professional Stuff</h2> <h3 id="chaos-mesh-presentation-on-kubecon-2023-eu">Chaos Mesh presentation on KubeCon 2023 EU</h3> <p>Due to diverted personal priorities, we were not able to prepare the Maintainer track in time for Kubecon EU.</p> <p>Several weeks a go, Saiyam noticed that and he wanted to schedule a presentation for Chaos Mesh, and it was already pass the deadline of CFP.</p> <p>Saiyam encouraged us sending the email to the &ldquo;CNCF Events&rdquo; and &ldquo;CNCF Speakers&rdquo;, to ask if there is a chance to let him present about Chaos Mesh on the KubeCon 2023 EU.</p> <p>And we did, luckily, we got the response which CNCF would make an exception for us, and there was a available slot for the presentation coincidentally, so there it is:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/13-normalweeklyrecap-s/2023-03-30-08-43-34.png' alt="" /> </p> </p> <p><a href="https://kccnceu2023.sched.com/event/1K6Ai">https://kccnceu2023.sched.com/event/1K6Ai</a></p> <h3 id="itasha-car-and-overcommunicate">Itasha Car and Overcommunicate</h3> <p>TLDR; If you want to decorate your car as itasha car, do NOT find a personal designer.</p> <p>Here is a concept called &ldquo;Overcommunicate&rdquo; in open source community. It means that the information carried in your message should be as much as possible, and the receiver could understand the basic idea of the message without asking more questions. I think that&rsquo;s a good practice for the async communication.</p> <p>Once I got out of the engineering community, I suffered a totally different communication style in contrast.</p> <p>In the past few weeks, I spent lots of time on the itasha car. I experienced a terrible time on the communication both in the QQ group and with the designer.</p> <p>I found and joined the QQ group called &ldquo;浙痛组&rdquo;, and as same as other ACG group, this group fully occupied with the low-energy content, memos, repeated messages, and tons of stickers. I tried to ask some question about the precess of the itasha car, only get few responds, and most of them are just &ldquo;only answer the very next step, and show off that I know how to do it&rdquo;. There is not kind of a friendly community.</p> <p>During the communication with the designer, I realized that I made a bad decision in that I over-trust the business ability of the so-called &ldquo;designer.&rdquo; He started the design without the accurate size data of the car, just building a mask based on an internet image of the car. He just made up the final design with a simple combination of original stuff, with no way to re-draw or paint based on the original art. He refused to accept my suggestion and refused to explain why, with simply saying &ldquo;it just can not do it.&rdquo; I was a student of Digital Media major, something I think it&rsquo;s possible and even easy to change, but he just refused to accept it. Later, both of us got frustrated, and we just finished the work with no more fundamental changes to the final design.</p> <p>By now, everything goes well. I would wait another 7 - 10 days for an appointment with the printing guy. And I hope I could finish the itasha cat in the next 2 or 3 weeks.</p> <p>At last, a quick peek of the final design:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/13-normalweeklyrecap-s/2023-03-30-09-37-34.png' alt="" /> </p> </p> <h3 id="refine-the-blog-theme">Refine the Blog Theme</h3> <p>I still miss my first theme used in this blog, it&rsquo;s a Material Style theme for hexo, simple and clean.</p> <p>I started to think maybe I should build my own theme, with some features I want, like the preview of panorama images and embedded cards for links (like twitter and youtube).</p> <p>Several days ago, I noticed that Material 3 / Material You finally get out, and replace the Material 2, became the default page of material.io. But there are not many available components in web, so maybe later, I could build a Material 3 theme for hugo.</p> <h2 id="personal-stuff">Personal Stuff</h2> <h3 id="self-driving-tour-at-qiandao-lake">Self-Driving Tour at Qiandao Lake</h3> <p>Too far to remember, but still a good trip.</p> <p> <p class="md__image"> <img src='./DJI_0003.JPG' alt="" /> </p> </p> <h3 id="hidden-drawer">Hidden Drawer</h3> <p>I brought a hidden drawer, for store the phones.</p> <p>The Phone it self is a huge trigger to disrupt my focus, so I decided to put it in somewhere I could not see it.</p> <p>It works well.</p> <h3 id="fix-the-printer">Fix the printer</h3> <p>My printer broken mightily caused by the long-term unuse and lack of maintenance.</p> <p>I clean the &ldquo;Imaging Drum&rdquo; with alcohol, and it works much better now, except there is an area in the left side of the paper, which is not printed.</p> <p>Before:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/13-normalweeklyrecap-s/2023-03-30-10-03-06.png' alt="" /> </p> </p> <p>After:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/13-normalweeklyrecap-s/2023-03-30-10-03-14.png' alt="" /> </p> </p> <h3 id="diablo-iv-public-beta">Diablo IV Public Beta</h3> <p>Diablo IV started its public beta in the last 2 weeks, and I played it.</p> <p>It&rsquo;s a great game, more better than Diablo 3. It is definitely optimized with game controller, and I think I would not use the keyboard and mouse in the future gameplay.</p> <p>I record the gameplay with OBS and youtube, maybe I would review them before the release day of the Diablo IV.</p> <p><a href="https://www.youtube.com/playlist?list=PL2CnjpVBS-U8GwOPNMiXP1hz9s2F8Stgl">https://www.youtube.com/playlist?list=PL2CnjpVBS-U8GwOPNMiXP1hz9s2F8Stgl</a></p> 2023 Week 9: Beijing Sucks 🤷‍♂️ https://strrl.dev/post/weekly-recap/2023/09-beijingsucks/ Mon, 27 Feb 2023 13:25:16 +0800 https://strrl.dev/post/weekly-recap/2023/09-beijingsucks/ <h2 id="overview">Overview</h2> <p>This weekly recap spans from February 22nd to February 26th, 2023.</p> <p>You might notice that I changed the name of this series from &ldquo;Weekly Report&rdquo; to &ldquo;Weekly Recap.&rdquo; I was inspired by <a href="https://yuchanns.xyz/notes/weekly-recap/2023-02-27">yuchanns&rsquo;s weekly recap</a>. &ldquo;Weekly Report&rdquo; would make me feel stressed because I used to have to write a weekly report for my previous jobs. &ldquo;Weekly Recap&rdquo; is more relaxed as an informal summary of my week.</p> <h2 id="professional-stuff">Professional Stuff</h2> <h3 id="new-idea-using-chatgptgpt-3-davinci-to-build-a-grammar-explainer">New Idea: Using ChatGPT/GPT-3 Davinci to build a Grammar Explainer</h3> <p>ref: <a href="https://twitter.com/strrlthedev/status/1628950852185788416">https://twitter.com/strrlthedev/status/1628950852185788416</a></p> <blockquote> <p>AI is a popular topic in social media, especially chatGPT. There was a traffic spike on this twitter from the data of twitter analytics, even though it&rsquo;s only an <strong>IDEA</strong>, not a product or PoC Demo. 🤪</p></blockquote> <p>The background is I am learning English and preparing for the language exams. The long sentences in the reading part still took effort to comprehend. Maybe AI could help me understand it, I searched on the internet, and there were only a few products as grammar explainers. Still, products like Grammarly as a grammar checker differ from what I want.</p> <p>Occasionally, I tried to ask the ChatGPT with my question, and it works pretty well:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/09-beijingsucks/2023-02-27-18-54-27.png' alt="" /> </p> </p> <p>Then I found another kind of usage of chatGPT: processing the unstructured text into structured information:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/09-beijingsucks/2023-02-27-18-56-44.png' alt="" /> </p> </p> <p>ref: <a href="https://twitter.com/shing19_eth/status/1627258771071463424">https://twitter.com/shing19_eth/status/1627258771071463424</a></p> <p>One more thing, I heard that ChatGPT could guide the developer in writing codes. I think it would also work for me.</p> <p>Until now, the whole process settled in my mind:</p> <ul> <li>And ask ChatGPT to guide me in writing this application</li> <li>.. to use ChatGPT to explain the grammar of the sentence</li> <li>.. as the structured format, like JSON</li> <li>.. also append the translation of the sentences</li> <li>Streaming as Live Coding</li> <li>&hellip; and youtube would also record the streaming automatically</li> </ul> <p>Kind of a funny idea, but it&rsquo;s definitely worth trying. 🤪</p> <h3 id="mirroring-ipad-or-iphone-on-linux">Mirroring iPad or iPhone on Linux</h3> <p>I demanded to mirror my iPad to my screen because sometimes I would draft my idea on the iPad, and I would like to share it with others during the meeting. I used to join the meeting with the Zoom app on my iPad. Still, it&rsquo;s weird because of duplicated personal identities appear on the zoom participants.</p> <p>I wonder if there is a way to mirror the iPad screen to my desktop, and I also heard that there is a hacked version of the AirPlay server on Raspberry Pi.</p> <p>At last, I found that open-source software: <a href="https://github.com/antimof/UxPlay">UxPlay</a>, and luckily, someone has packed it on AUR.</p> <p>The experience of UxPlay is pretty good, the sound and the video are both fluent, and the latency is hard to notice:</p> <p> <p class="md__image"> <img src='./Peek%202023-02-27%2019-13.gif' alt="" /> </p> </p> <blockquote> <p>That&rsquo;s also good news for my girlfriend. She always likes to watch some videos on her iPad, complaining that the screen is not big enough.</p></blockquote> <h3 id="ossrh-outage">OSSRH Outage</h3> <p>OSSRH is one of the upstreams of Maven Central, hosting lots of open-source project artifacts. It&rsquo;s one of the most critical infrastructures for the open-source java ecosystem.</p> <p>But such an important infrastructure is not stable (like enterprise service). It&rsquo;s been down for nearly 2 days:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/09-beijingsucks/2023-02-27-19-20-43.png' alt="" /> </p> </p> <p>Ref:</p> <ul> <li><a href="https://status.maven.org/incidents/1wlz7yhdm0wp">https://status.maven.org/incidents/1wlz7yhdm0wp</a></li> <li><a href="https://twitter.com/strrlthedev/status/1628199303457169408">https://twitter.com/strrlthedev/status/1628199303457169408</a></li> </ul> <p>The outage is caused by abuse by publishing too many artifacts, intentionally or unintentionally. And the OSSRH team could only recover from it by manually deleting them:</p> <ul> <li><a href="https://issues.sonatype.org/projects/OSSRH/issues/OSSRH-89036?filter=allopenissues">https://issues.sonatype.org/projects/OSSRH/issues/OSSRH-89036?filter=allopenissues</a></li> </ul> <p>Finally, the issue was resolved. Maybe the publisher realized the misuse of OSSRH, or the OSSRH team banned the publisher&rsquo;s account.</p> <h2 id="personal-stuff">Personal Stuff</h2> <h3 id="beijing-sucks">Beijing Sucks</h3> <p>I traveled to Beijing and Tianjin last week, and I was so disappointed about Beijing.</p> <p>I lived in a hotel near the Tiantan(天坛), and there are lots of hutongs around it. I walked across them and found that they would not be worse anymore: even though the hutongs were narrow, there was lots of debris on each side of the hutong. And there are lots of cars parked on the side of the hutong, it seems these cars are not unused, but I have no idea how to park the car into the hutong and drive out of there.</p> <p>I walk further to the Soshow Mall, and the entire 6 floor is full of ACG derivatives. Both my girlfriend and I were obsessed with a statue of Devil Hunter Valla:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/09-beijingsucks/2023-02-27-19-55-17.png' alt="" /> </p> </p> <p>I asked the store owner for the price, and he told us it cost about 2800 CNY, and the statue was the handcrafted limited edition, was the 34th of 128 items.</p> <p>We did not buy it but would eventually buy it in the future.</p> <p>Another day, I went to Wangfujing Street and got shocked after I walked out of the subway station: lots of ravens flew on my head and quacked loudly:</p> <p>ref: <a href="https://twitter.com/strrlthedev/status/1626061065787441152">https://twitter.com/strrlthedev/status/1626061065787441152</a></p> <p>And Wangfujing Street is not prosperity as I expected, there are not soo many people and shops, and one of the shops has even got closed since the pandemic. A foreign book store intrigued me, and there are lots of comic posts and game posts for sale, and other technical books in several languages:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/09-beijingsucks/2023-02-27-19-49-02.png' alt="" /> </p> </p> <p>Then I went to the Forbidden City, as a kind of boring tourism, because I do not get any interest in the historical sites.</p> <p>On the last day, I went to Universal Studios Beijing. In summary: it is not as good as Shanghai Disneyland.</p> <p>But the butter beer (no alcohol edition) is delicious, and we bought a cup for another 30 CNY as a souvenir:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-recap/2023/09-beijingsucks/2023-02-27-20-00-37.png' alt="" /> </p> </p> <blockquote> <p>After we backed to Hangzhou, we found we could buy butter beer with alcohol in the supermarket, so we drank a taste of it again. 😜</p></blockquote> <p>Most of the activities in Universal Studios Beijing only have the funny on the form. Still, there are no good stories behind them.</p> <p>And most of the forms are roller coasters, roller coasters, roller coasters&hellip; (same as the most popular activity in the Harry Potter section as the roller coasters, we nearly took about 90 mins to queue it 🥲) It&rsquo;s too bad for older people like my girlfriend and me.</p> <p>But there are still a few good activities:</p> <ul> <li>One activity in Minions Section, but I forgot the name, though it is a kind of in-room roller coaster, I feel much safer. 😇</li> <li>A flash mod in the square near the entrance. I still have no idea about the activity name, but I will upload a video to Youtube later.</li> <li>The parade. But it lacks the Happy Potter theme. 🤷‍♂️</li> </ul> <h3 id="healthier-breakfast-and-sleep-habits">Healthier Breakfast and Sleep Habits</h3> <p>I tried to build healthier breakfast and sleep habits, like:</p> <ul> <li>sleep at 22:30 pm and wake up at 6:30 am</li> <li>less sugar and starch in the breakfast</li> </ul> <p>I found that I had too much sleep, which would cause listlessness in the daytime. Also, eating carbohydrates as primary food would make me feel very tired in the 30 - 60 mins after breakfast.</p> <p>To make me feel more energetic, I must take care of the above habits. Also the exercise, I would go back to the gym and resume the training this week.</p> <h3 id="sponge-airpods-earbuds-replacement">Sponge AirPods Earbuds Replacement</h3> <p>Several days ago, some friends told me that the AirPods Pro earbuds would trigger ear infection/inflammation, and they did: <a href="https://twitter.com/strrlthedev/status/1626024009572958208">https://twitter.com/strrlthedev/status/1626024009572958208</a></p> <p>I brought another sponge replacement, which is much better than the original one, and the inflammation did not worsen recently.</p> <h3 id="star-guardian-vlogs-from-lol-official-youtube-channel">Star Guardian Vlogs from LOL Official Youtube Channel</h3> <p>I am a big fan of the Star Guardian series and am excited about the new heroes that will be released, including the Star Guardian series.</p> <p>I found the official League of Legends Youtube channel released 3 short videos about the Star Guardian series: <a href="https://www.youtube.com/watch?v=5rAeyo3K36g">https://www.youtube.com/watch?v=5rAeyo3K36g</a></p> <p>So I am sure there are several new heroes: Seraphine, Orianna, and Senna.</p> 2023-08: Global Game Jam https://strrl.dev/post/weekly-report/2023/08-globalgamejam/ Mon, 06 Feb 2023 21:05:29 +0800 https://strrl.dev/post/weekly-report/2023/08-globalgamejam/ <h2 id="overview">Overview</h2> <p>The weekly report is from January 31st to February 21th, 2023.</p> <p>I decided to write the weekly report series in English because I want to improve my English skill. Not just for writing but primarily for getting familiar with English words and phrases.</p> <p>That&rsquo;s also why I delayed this blog for a few weeks. I was using Grammarly when I wrote the blog, and spent too much time embellishing it. At last, I gave up writing the blog in the Grammarly editor and only used it to check the content after I completed the writing.</p> <p>I participated in the English Club several times in the last three weeks. My English corpus is too small to respond to others&rsquo; questions: I have to construct in my brain for a while, search vocabulary for what I want to express, then I can finally speak it out if I still do not forget what the opinion I origin wish to say.</p> <h2 id="professional-stuff">Professional Stuff</h2> <h3 id="standard-bug-set">Standard Bug Set</h3> <p>I found an exciting code repo on GitHub: <a href="https://github.com/jkoppel/QuixBugs">jkoppel/QuixBugs</a>. It introduces some common one-line bugs for some classic algorithms in both java and python. Compared to asking the interviewee to write algorithm codes from scratch, it might be a better way to inspect the professional skills and experiences.</p> <p>I noticed this repo by some news about ChatGPT which said that ChatGPT could resolve many cases in the given repo.</p> <p>Also, a tweeter has tried to interview ChatGPT for a junior developer job: <a href="https://twitter.com/zanmato1984/status/1623638722167336960">https://twitter.com/zanmato1984/status/1623638722167336960</a>. In conclusion, ChatGPT would not get hired, but it knows a lot about computer architecture and the operating system.</p> <h3 id="trivial-issues-after-exchanging-harddisk-between-pcs">Trivial Issues after Exchanging Harddisk between PCs</h3> <p>As the highly anticipated new game (Hogwarts Legacy) was released, my girlfriend asked me to exchange the graphic cards for a smoother game experience. Her gaming PC set was i5-9600F with RTX 2070, and mine was i7-11700 with RTX 3080.</p> <p>I once supposed it was just a straightforward case about exchanging graphic cards, but I was totally wrong. 😅</p> <p>After exchanging graphic cards, her computer failed to run any game, including the Hogwarts Legacy and the Monster Hunter Rise. The computer just got powered off and then restarted. We thought that it might be caused by the graphic driver. So we updated the nvidia driver to the latest version, but it did not work. I opened the windows event viewer and found that there was no critical software log at all. Then I realized that it might be the power issue: RTX3080 requires more power than RTX2070. In common sense, the 80 series always requires more power than the 70 series. I opened the performance overlay to monitor the power consumption. I noticed during the loading scene and shader compiling phase the power of graphic cards did not exceed over 80 watts, which means the graphic card did not engage. Once it was about to enter the main scene, the PC got powered off. I also tried that with the non-game software 3DMarks, and it could be reproduced easily.</p> <p>I inspected our PCs&rsquo; power supplies: hers got 550w, and mine got 850w, and both were modular. So I started to exchange power supplies between PCs. Changing the power supply is not as easy as changing the graphic card: I need to open another side of the back panel, unscrew about 4 screws, poll all the clamped cables out from the plug, and finally reconnect them with the new one. I exchanged them and then packed the PC case confidentially without giving it a test. I connected the power cable and opened the switch, but the computer did not boot. I tried on another PC, and both of them did not work. Even the lights on the motherboard were not on.</p> <p>I had no idea about this circumstance, and I asked friends. They told me that different models of modular power supplies have different cable sequences, so the cable might not be adaptable.</p> <p>I recognized I needed to use the power supply and cable in pairs. But dismounting the power cable from the case would be complicated because I had to unravel all cables bound on the backside and tidy and tie them again in the new place.</p> <p>Finally, I decided to change nothing but only harddisks between PCs. My computer got 3 SSDs, one of which was mounted on a PCIE extension card; hers had 2 SSDs plus one SATA HDD. It&rsquo;s still a complicated thing to be done.</p> <p>Anyway, exchanging harddisks resolved the original demand: my girlfriend got a better game experience on Hogwarts Legacy, except for one thing: her Windows lost the activation after changing the hardware, and I forgot the production keys. 🥲</p> <p>I will NOT DIY a new gaming PC again in the future. Upgrading and trivial adaptation issues would make me crazy.</p> <h2 id="personal-stuff">Personal Stuff</h2> <h3 id="global-game-jam">Global Game Jam</h3> <p>The Global Game Jam 2023 is held from February 3rd to February 5th, and the theme of this GGJ is &ldquo;Roots.&rdquo;</p> <p>It was my first time participating in the GGJ, and I asked some college friends to play together.</p> <p>One week ago, I proposed an idea about Tower Defence Game but played with VR. We brainstormed about the expected products and found that making it on a 2-days jam was viable.</p> <p>The origin design of the game contains 2 major gameplays:</p> <ul> <li>TPS on position fixed tower</li> <li>Tower Defence with a 45-degree top view</li> </ul> <p>We finished the gameplay design before the theme was released, so we have also prepared to only modify the art style to accustom the theme.</p> <p>We uploaded a video about the gameplay demonstration: <a href="https://www.bilibili.com/video/BV1gx4y1777b">bilibili</a>.</p> <h3 id="diablo-3-season-28-ptr">Diablo 3 Season 28 PTR</h3> <p>Diablo 3 Season 28 will be open the following Friday, February 24th. I played in the PTR server to early access the new changes, the new season theme of Season 28.</p> <p>There was a severe bug in the PTR for the Demon Hunter: the set &ldquo;Natalya&rsquo;s Vengeance&rdquo; had an unexpected interaction with the set &ldquo;Shadow&rsquo;s Mantle,&rdquo; and the damage would be increased by 6000% with a melee weapon. So everyone could rush the Great Rift 150 with a melee weapon and the 5+2 build mentioned above.</p> <p>And there is an overpowered buff that could be abused by any class. When the player uses a potion, gain a random shrine or the Dimensional Power pylon effect. If we are lucky enough, we could get the power of Conduit/Lighting continuously and rush the Great Rift 150 in about 3 minutes.</p> <p>And one skill of Necromancer could reduce the cooldown of the potion, which means we could use the potion more frequently.</p> <p>But in the official updates of Season 28 later, the player could no longer gain the Conduit pylon by the potion. Only random shrines and &ldquo;Power&rdquo; with a duration of 16 seconds would be available.</p> <h3 id="start-using-shared-library-in-apple-photos">Start using Shared Library in Apple Photos</h3> <p>My girlfriend and I have established the apple family sharing for a long time, but we forgot to set up the &ldquo;Shared Library.&rdquo; Several weeks ago, we found that we have many photos of each other but do not have them ourselves. So we take a long time to manually share the pictures by Airdrop and share albums.</p> <p>Soon, we found that photos could be shared <strong>automatically</strong> by &ldquo;Shared Library&rdquo;: when we activate the &ldquo;share&rdquo; as taking the picture, it appears in both of our Photo applications. That&rsquo;s really convenient!</p> <h3 id="panoramic-camera-insta-360-x3">Panoramic Camera: Insta 360 X3</h3> <p>I brought a panoramic camera Insta 360 X3, on the day near the new year. I am so excited about it. It could take 360-degree videos and photos without nearly any post-processing. I could look around <strong>after</strong> I took the picture.</p> <p>I took panoramic videos of our house, tourism, and hiking with my girlfriend. We can always find funny stuff when we review the videos.</p> <p>But the quality of the video is not good enough, even though it is already recorded in 5.7K or 8K. The viewpoint is blurred when I look around. It looks like a 360p video.</p> <p>The video file size is so huge: I could only take about 9 hours of video with a 512GB SD card. It takes about two times the video content duration to export the video from insta private format to MP4, and it takes another 2 times to upload the video to youtube.</p> <h2 id="other">Other</h2> <p>I was still working on preparing for the language test. My original plan is to memorize vocabulary first, after completing half of the word lists, then take the simulation test. I am not sure I should take a course for the TOEFL test.</p> <p>I have been eager(also anxious) for the next phase because I did not take the simulation test before and have no idea what the exam could be. I have completed about 1600 to 4300 words now, about 38%. It still requires one more week to move into the next phase.</p> <p>Many other things are worth recording, but I would not postpone this blog anymore. New content about &ldquo;Healthier breakfast and sleep habits,&rdquo; &ldquo;Itasha Car,&rdquo; &ldquo;Tourism in Beijing and Tianjin,&rdquo; and &ldquo;Panoramic Times-clasp Videos&rdquo; will come up in the next blog.</p> 2023-04: 过年附近 https://strrl.dev/post/weekly-report/2023/04-%E8%BF%87%E5%B9%B4%E9%99%84%E8%BF%91/ Mon, 30 Jan 2023 19:58:56 +0800 https://strrl.dev/post/weekly-report/2023/04-%E8%BF%87%E5%B9%B4%E9%99%84%E8%BF%91/ <p>这里又是一份周报, 时间范围是<code>2023-01-16</code>到<code>2023-01-30</code>, 会记录一些工作及生活上有意思的事情.</p> <p>上周因为过年太过于舒服所以鸽了.</p> <h2 id="代码计算机相关">代码/计算机相关</h2> <h3 id="绝妙的主意-编程--游戏成就">绝妙的主意: 编程 + 游戏成就</h3> <p>ref: <a href="https://twitter.com/strrlthedev/status/1614859527421308928">https://twitter.com/strrlthedev/status/1614859527421308928</a></p> <p>算是一个交叉应用?</p> <p>但是我之前木有接触过太多 IDE 插件的制作, 不知道有什么 HOOK 可以放进去. 也没太想好玩家的数据放到哪里, 公开还是私有, 如何反作弊 / 公平性.</p> <p>趣味性, 功能性挺好的, 只是细节上还是有蛮多要考虑的.</p> <h2 id="生活相关">生活相关</h2> <h3 id="和-pseudoyu-面基">和 pseudoyu 面基</h3> <p>年关里和 pseudoyu 面基了. 哥哥是个文雅的帅哥, 我像个巨魔. 😅</p> <p>聊了一些关于 web 3, 云, 以及 web 3 的事情, 果然不一样的人经历有不一样的精彩!</p> <p>而后 pseudoyu 推荐了一些杭州可以逛的自然景点, 等天气暖和一点了就去玩.</p> <h3 id="换了宜家的人体工学椅">换了宜家的人体工学椅</h3> <p>前段时间一直吵着腰痛, 腿痛, 膝盖痛, 感觉是坐姿的问题, 换了椅子全好了!</p> <p>之前是一个傲风电竞椅, 买了两年多了, 没错我就是冤大头. 非常地不舒服, 也就是能转能躺能跑了.</p> <p>后来想着, 买椅子一定要去试用下. 找朋友试了两三个工学椅, 给我的感受就是, 即使拉到最高, 也还是很矮.</p> <p>一次偶然的机会, 在逛宜家的时候试了试他们的椅子, 发现宜家椅子的最低, 差不多是之前那个傲风椅子的最高. 感觉非常的合适, 而后又去对比了下网易严选的椅子, 还是不如宜家的舒服.</p> <p>所以最后去店里直接买下来了!</p> <h3 id="全景照片--全景视频拍摄与播放">全景照片 / 全景视频拍摄与播放</h3> <p>偶然的机会得到了一个 instant 360 全景摄像机, 可以拍摄出一些有趣的照片和视频来.</p> <p>之前我对于全景照片的认识, 只是手机相机的&quot;超广角&quot;, 还有 DJI 的球型照片. 这都是使用多张照片然后拼合, 得到结果的.</p> <p>俺受赏这台全景摄像机, 也是拼合, 但是会更有趣些, 它只有前后两个摄像头, 但是每个摄像头的角度是 210 度, 每个角度都有足够的 overlap, 这样就可以较为轻松地合成 360 图片.</p> <blockquote> <p>这就是鱼眼摄像头嘛, 后来查了查才知道, 许多眼睛长在两边的生物(比如说兔子), 都是可以有很广的视角的, 很有意思. 但是也有缺点, 没办法分辨距离.</p></blockquote> <p>拍摄视频是 5.7k 的分辨率, 但是拍出来的视频是私有的格式, 需要再到 PC 上去转 + 封装, 才可以用播放器打开, 或者上传到 youtube. 视频的体积也很大, 差不多 128 GiB 的 SD 卡, 可以录制 2.5 小时的视频.</p> <p>现在我还没有上传任何全景视频上去, 主要就是因为转码和上传的时间太长了.</p> <p>不过在博客里嵌入一些全景图貌似是可以的, 需要研究一下现在使用的图片预览插件, 增加全景图的支持就好了.</p> <h3 id="暴雪国服难民">暴雪国服难民</h3> <p>大年初三暴雪关服. 然后最近女票一直在亚服玩, 在风暴英雄里能够看到很多国服难民. 特征比较明显: 等级都是个位数, 骑着赠送的坐骑, 时不时掉线.</p> <p>太惨了太惨了.</p> <p>当然也有些好消息, 可以配制英文语言包了. 而且星际暗黑中的很多阉割内容也能看到了.</p> <p>顺便一提, 暗黑 3 28 赛季 PTR 在 2 月 1 日开启, 这个赛季看上去蛮好玩的, 准备去尝试一下.</p> <h3 id="再呻吟一下">再呻吟一下</h3> <p>想到了 20 年年关在家里啃 Kubernetes In Action, 一心想从 Java CRUD 跳出来.</p> <p>23 年年关在啃英语, 希望这次也能和那次一样顺利. 🥰</p> 2023-02: 快过年了 https://strrl.dev/post/weekly-report/2023/02-%E5%BF%AB%E8%BF%87%E5%B9%B4%E4%BA%86/ Sun, 15 Jan 2023 18:04:18 +0800 https://strrl.dev/post/weekly-report/2023/02-%E5%BF%AB%E8%BF%87%E5%B9%B4%E4%BA%86/ <p>这里又是一份周报, 时间范围是<code>2023-01-09</code>到<code>2023-01-15</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="代码计算机相关">代码/计算机相关</h2> <h3 id="有趣的工具-lnav">有趣的工具: lnav</h3> <p>从推友那里得知了一个有趣的工具: <a href="https://github.com/tstack/lnav">lnav</a>.</p> <p>ref: <a href="https://twitter.com/AFutureD/status/1612297761357189121">https://twitter.com/AFutureD/status/1612297761357189121</a></p> <p>这是一个强大的命令行工具, 主要是用来花式查看/统计/分析日志的. 有了它, 你可以做到:</p> <ul> <li>同时在一个视图/多个视图中查看多个日志文件/日志流</li> <li>高亮日志中的 JSON / XML 内容</li> <li>统计日志的频率, error, warning, info 等级别的频率</li> <li>将日志作为数据源, 使用 sql 语句进行查询/统计/分析</li> </ul> <p>而且最近就直接用上了: chaos mesh 的 <code>make</code> 命令性能比较差, 想 profile 一下到底是哪里慢了.</p> <p>但是 make 不像 service 那样方便和 tracing 系统集成, 它又不是一个 CPU 密集型应用, 所以我的一个歪门邪道的想法是: 用 <code>strace</code> + <code>lnav</code> 来分析是哪里慢了.</p> <p>执行命令 <code>trace make help 2&gt;&amp;1 | lnav -t</code>, 然后按 <code>i</code> 进入 histogram 视图, 使用 <code>z</code>/<code>shift+z</code> 缩放到合理的比例尺后可以看到, 有某个时间窗口内的日志特别少, 一定程度上说明这个时间窗口内, 等待的时间比较长.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-report/2023/02-%E5%BF%AB%E8%BF%87%E5%B9%B4%E4%BA%86/2023-01-15-18-18-31.png' alt="lnav histogram / timeline view" /> </p> </p> <p>然后再根据这个时间戳看原来的日志, 发现慢的原因是执行了若干个脚本, 然后赋值给变量.</p> <blockquote> <p>问题定位了. 改进在路上了.</p></blockquote> <h3 id="准备参加-game-jam">准备参加 Game Jam</h3> <p>第一次了解到 Game Jam, 是在 BK 的纪录片里: <a href="https://www.youtube.com/watch?v=ygWbvkzqTKU">Game Jam 2022 在上海 独立游戏 纪录片 | 钱从哪来 S01 Documentary</a>.</p> <p>因为我本科是数字媒体技术专业的嘛, 大学里学了不少游戏相关的课程, 虽然工作后没有在游戏领域折腾, 但是对于制作一款游戏还是依旧感兴趣的.</p> <p>这次的 Game Jam 联系了大学的同学, 在这周六下午喝了杯咖啡, 简单沟通了一下想法, 基本上达成一致(准备偷跑)了.</p> <p>实际上, 树莓专业的同学, 在毕业后保持初心在多媒体相关行业的真不算多, 10% - 20% 还在, 其余的(比如说我)都去其他方向了.</p> <p>这次 Game Jam 的时间是 2023/2/5 - 2023/2/7, 线上线下均可参加, 线下地点有北京, 广州, 重庆, 武汉, 杭州, 深圳, 上海, 济南多个站点.</p> <p>总是还是蛮兴奋的.</p> <h3 id="最近的-coding-状态">最近的 coding 状态</h3> <p>最近回归了猛草 JVM 语言的时代, Kotlin 出活真的不要太爽.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-report/2023/02-%E5%BF%AB%E8%BF%87%E5%B9%B4%E4%BA%86/2023-01-15-18-28-04.png' alt="Wakatime" /> </p> </p> <h2 id="生活相关">生活相关</h2> <h3 id="准备英语考试">准备英语考试</h3> <p>最近开始开始逐渐在英语上投入精力了, 自己的基础还是非常弱, 许多单词和语法都不怎么会.</p> <p>参加了一次线下的英语角, 感觉能听懂个三四成. 说的话我倒是没有心理压力(脸比较大), 但是语言磕磕巴巴, 比较困难.</p> <p>短期内的计划是:</p> <ul> <li>背单词</li> <li>学语法</li> <li>跟着 Official Guide to the TOEFL iBT Test 学</li> <li>参加英语角</li> </ul> <h3 id="快过年了">快过年了</h3> <p>这周周末应该是最后一个工作日的周末了, 大家都在商场里备年货, 非常的热闹, 也非常的拥挤.</p> <p>本来也想去商场屯一点东西, 结果停车半小时都没有找到车位, 放弃了, 工作日再过来.</p> <p>节日对于我来说其实也没有太多什么不一样, 从<em>枫言枫语</em>的 Justin 提出过的一个观点: <strong>这个世界是连续的, 节日只是人为规定的, 事情并不会在某个具体的时间点后突然变好, 或者突然变差.</strong></p> <p>因此我也没有给过年做特别的安排, 照常过就可以了, 朝着自己的目标努力.</p> 2023-01: 新冠初愈 https://strrl.dev/post/weekly-report/2023/01-%E6%96%B0%E5%86%A0%E5%88%9D%E6%84%88/ Sun, 08 Jan 2023 09:25:07 +0800 https://strrl.dev/post/weekly-report/2023/01-%E6%96%B0%E5%86%A0%E5%88%9D%E6%84%88/ <p>这里又是一份周报, 时间范围是<code>2023-01-02</code>到<code>2023-01-08</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="代码计算机相关">代码/计算机相关</h2> <h3 id="尝试了区块链上自动交易做套利">尝试了区块链上自动交易做套利</h3> <p>上段时间不知道为什么魔怔了, 开始想通过自动交易赚钱. 于是就开始了这个尝试.</p> <p>结果是没啥完成啥利润, 然后成本付出了大约 $60 的样子.</p> <blockquote> <p>想要盈利不仅需要分析和 coding, 还得需要一些领域内的经验</p></blockquote> <p>不过在纯工程上来说, 研究套利还是蛮有意思的:</p> <ul> <li>从假设到实现, 从参考其他的人的行为, 加上文档和参考, 写出自己的实现</li> <li>通过理论, 代码逻辑和统计, 推算利润区间</li> <li>一点点优化合约代码, 减少 gas fee</li> <li>使用 pprof 与 opentelemery 做 profiling, 优化性能</li> </ul> <p>正在写一篇相关的文章准备详细介绍做了啥事, 过一段时间能够写完吧.</p> <h2 id="生活相关">生活相关</h2> <h3 id="新冠恢复期">新冠恢复期</h3> <p>上周是在新冠恢复后的第二周, 总体的精神和身体状况都不好.</p> <p>有一份质量不错的材料, 病友们可以参考一下: <a href="https://apps.who.int/iris/bitstream/handle/10665/349695/WHO-EURO-2021-855-40590-62244-chi.pdf?sequence=1&amp;isAllowed=y">康复指导手册: COVID-19 相关疾病的自我管理 第二版</a></p> <h3 id="准备再上个学">准备再上个学</h3> <p>准备再去北美读个硕士. 上上周约了 cxs 的 30 min 时间, 打听了下近况, 以及当地的氛围. 上周也分别和自己的两个大学好友, 一位是 PhD 在读, 一位是 FANG 大厂员工聊了聊生活状况.</p> <p>上周也大略捋了下时间线和需要的准备工作, 也花了一段时间把期望的学校看了一下, 收集了一点资料.</p> <p>看上去今年时间比较宽裕, 准备好好搞一搞英语.</p> <p>祝我好运.</p> 2022-52: 2022 总结 https://strrl.dev/post/weekly-report/2022/52-2022%E6%80%BB%E7%BB%93/ Sat, 31 Dec 2022 11:41:54 +0800 https://strrl.dev/post/weekly-report/2022/52-2022%E6%80%BB%E7%BB%93/ <p>这里是鸽了将近 2 个月周报, 顺便是年终总结.</p> <h2 id="2022-年">2022 年</h2> <h3 id="周报">周报</h3> <p>从 2022 年的 1 月 29 日起开始写第一篇周报, 到现在断断续续写了 42 篇周报.</p> <p>其实当时写周报的时候就已经预感到了会有这一天到来, 读着自己之前写的周报, 再回想一下当时的心境, 是一种什么样的体验.</p> <h3 id="变无业">变无业</h3> <p>我于 2022 年 8 月 31 日从 PingCAP 离职了, 离职的原因嘛, 也在 <a href="https://strrl.dev/post/weekly-report/2022/27-%E6%89%BE%E6%96%B0%E5%9D%91/">2022-27: 找新坑</a> 这篇文章里提及了.</p> <p>后来面了若干家公司, 也拿到了一些 Offer, 甚至工资算下来能够有 30% - 50% 的涨幅, 但是最终还是选择没有接下任何一家公司的 Offer, 而是期望在一个看上去更&quot;不错&quot;的方向里.</p> <blockquote> <p>感谢帮助我内推的朋友们, 也非常感谢猎头 Danny 给我介绍了很多好机会.</p></blockquote> <p>用 Chaos Mesh 这个产品去创业.</p> <p>当然后来发展逐渐变得差了起来, 今年的投资圈非常的冷, 尽管有建信金科, Adobe, Databricks 的用户们愿意为我们站台, 接受 VC 们的询问, 但是还是没有能够拿到乐观的数字. 这个事情算是告一段落了.</p> <p>后续又有一次甚至能够直接有望润出去的工作机会, 无奈最后技术面结束后, 被 HR 告知后续不计划再在大陆招同学了, 也是比较可惜.</p> <blockquote> <p>也是因为我还没有优秀到能让对方公司帮我润出去吧.</p></blockquote> <p>在这段时间里, 以兼职的形式帮助前老板强哥做一些事情, 补贴家用, 非常感谢强哥.</p> <p>于是乎我目前的状态就是一个在杭州的灵活就业人员, 但是上两天买退烧药的时候发现自己的医保没有续上, 不能用了, 烦心事还是有一些的.</p> <h3 id="买车车">买车车</h3> <p>不知道为什么今年的冬天格外的冷, 雪好像已经下了好几场了, 迫于现在住的比较偏远, 出行太不方便了, 于是买了一辆车.</p> <p>人生中第一次买车, 也是第一次拥有车, 还是蛮激动的, 毕竟拿了驾照三年了没开过车, 有了车以后开了个爽.</p> <p>不过我应该是当时在买车附近的时候感染的新冠, 那天女朋友就嗓子不舒服, 喝了很多水, 我开车也是眼睛不太舒服.</p> <h3 id="得新冠">得新冠</h3> <p>自己觉得新冠还是比感冒要凶很多的, 我自己的话是烧了两天, 晚上睡觉十分煎熬, 差不多 1 小时到 2 小时就要醒一次, 上厕所并再次补充很多水分.</p> <p>谢谢住在附近的朋友们, 在俺们发烧的时候借给了俺们布洛芬, 在发烧的时候没有过于难受. 今天是第 8 天了, 还是比较容易感觉累, 身体 + 精神. 开车的时候能明显感觉注意力比较难集中, 有时候意识会突然掉几个 ticks 的感觉.</p> <p>另外身体在病的时候, 情绪也很容易感觉到 emo. 比如说最近一段时间就特别害怕变成肺炎重症, 然后因为没有医保没有办好, 没有办法治病就死掉了 / 或者是自己花光了钱也没有治好死掉了 / 或者是治好了没有钱吃饭饿死了. 🥲</p> <p>特别感谢女朋友在这段时间的陪伴和开导, 家人的支持能给我很多温暖和动力.</p> <h3 id="整了一堆没搞好的个人修养--方法论">整了一堆没搞好的个人修养 / 方法论</h3> <h4 id="gtd">GTD</h4> <p>GTD 的效果是明显的, 但是由于个人的懒惰没有坚持下来, 总想着这会&quot;沉迷在 XX 事情中&quot;, 过一会再去 trigger GTD 吧, 久而久之很容易忘记 GTD 这个工具.</p> <p>而且目前为止也依旧没有非常好用的工具来实践它, 目前我的方案是使用 Notion 里自建的 database 来存储我的这些事情, 然后建了一些不同的 view 来查看不同的 stuff. 有时会参考 facilethings 里的文章来作为流程指导.</p> <p>我预感到接下来如果无论是工作还是生活, 使用 GTD 来驱动各种事情的推进是<strong>非常有必要的</strong>. 不要让自己的那些小的地方偷懒, 这不想去做那不想去做, 慢慢地积攒到自己崩溃.</p> <h4 id="健身">健身</h4> <p>最近天气变冷后, 就再也没有去参加有氧和力量训练了.</p> <p>体力和精神状态有明显地下滑.</p> <p>我觉得需要 2 周后, 新冠恢复地差不多了, 立刻恢复训练.</p> <h4 id="冥想">冥想</h4> <p>冥想有助于让我不瞎想, 控制自己的思绪. 很惭愧只看了书籍 &lt;十分钟冥想&gt; 的第一章, 尝试着用了它的方法, 用了以后确实会有点所谓 &ldquo;六根清净&rdquo; 的感觉.</p> <p>很遗憾, 每天都 coding 到十一点才睡觉, 没腾出时间来看书和冥想.</p> <h3 id="整了一堆烂尾的项目">整了一堆烂尾的项目</h3> <h4 id="growth-ofcodes">growth-of.codes</h4> <p>揭示项目复杂度随时间增加的项目, 类似于 <a href="https://star-history.com">https://star-history.com</a>, 但是纵轴是代码复杂度.</p> <p>ref: <a href="https://strrl.dev/post/weekly-report/2022/09-%E6%87%88%E6%80%A0%E7%9A%84%E4%B8%80%E5%91%A8/#growth-ofcodes">https://strrl.dev/post/weekly-report/2022/09-%E6%87%88%E6%80%A0%E7%9A%84%E4%B8%80%E5%91%A8/#growth-ofcodes</a></p> <p>没有继续迭代下去的原因是发现自己并不熟悉其他的项目, 而且代码复杂度其实是&quot;虚高&quot;的, 参考意义不大.</p> <h4 id="dodo-rooster">dodo rooster</h4> <p>这个项目是想通过密码学 + 可信计算的方式来实现一个可审计地真匿名论坛, 大家使用自己的密钥来发言, 通过投票来禁言或者&quot;开盒&quot;大家认为需要被开盒的匿名身份.</p> <p>没有继续迭代下去的原因是一方面我不再需要这个项目了, 另外一方面是因为大家对于言论和身份的敏感也没有到这种地步. (是没需求了.)</p> <h4 id="kaniuse">kaniuse</h4> <p>完成度还算不错的作品?</p> <p><a href="https://kaniuse.vercel.app/">https://kaniuse.vercel.app/</a></p> <p>能够展示 CRD API 版本随着 kubernetes 版本变化, 展示可用情况的图表. 拿最常说的 Ingress 为例:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-report/2022/52-2022%E6%80%BB%E7%BB%93/2022-12-31-22-40-29.png' alt="" /> </p> </p> <p>下一步向做的是能够自动生成 Kubernetes Upgrade / Migration Guide. 比如说选定某个升级路径(比如 Kubernetes 1.19 -&gt; 1.25)后, 会提示哪些 API 版本将要 deprecated 了, 哪些 API 要被删除了, 要做哪些 migration 工作.</p> <p>没有再继续迭代下去的原因是因为精神状态不好, 去瞎想别的东西去了.</p> <p>这个应该还会继续做下去. ( GTD 捡起来以后. )</p> <h4 id="gha-ci-grid">GHA CI Grid</h4> <p>完成度比较低但是&quot;能用&quot;.</p> <p><a href="https://gha-ci-grid.vercel.app/">https://gha-ci-grid.vercel.app/</a></p> <p>借鉴了 prow bot 和 testgrid, 展示 GitHub Action 历史执行历史的网页.</p> <p>没有再继续迭代下去的原因, 是因为当前这个程度已经能够量化的分析出 Chaos Mesh 的 E2E 测试的稳定性了, (flake rate 56% 左右 🥲), 没需求了.</p> <h4 id="学-nand2tetris">学 Nand2Tetris</h4> <p>这个作业写到了 Assembler, 后来失去了 cue, 就没有再捡起来.</p> <h4 id="学-google-ux">学 Google UX</h4> <p>这个倒在了后来想整理到 dendron 去, 遗失了进度, 后来失去了 cue, 就没有再捡起来.</p> <blockquote> <p>其实 GTD 在很多时候都是充当了一个 cue 的作用.</p></blockquote> <h4 id="看-kubecon-宣讲">看 KubeCon 宣讲</h4> <p>两次都列了想看的 Talk 列表, 在最开始几天还是一天能看三四个的. 后来也是因为去忙别的/玩别的去了, 遗失了 cue, 再没有捡起来.</p> <h3 id="买了一些电子设备">买了一些电子设备</h3> <ul> <li>Samsung Galaxy Z Fold 4; 不推荐, 别买.</li> <li>iPhone 13 mini; 好东西, 果子家的东西真的是精品.</li> <li>Microsoft dev kit 2023; 不推荐, 别买.</li> <li>HP Color Laser 150nw 打印机; 有打印机确实方便, 但是用处不多.</li> <li>DJI Mini 2; 大号玩具, 挺好玩的.</li> <li>Macbook Air 2020; 好东西, 强力的生产力工具, 果子精品.</li> </ul> <h2 id="未来-the-right-or-the-easy">未来, the Right or the Easy</h2> <p>先列几个需要做的事情吧:</p> <ul> <li>依旧需要 discipline 来鞭策自己的行为, 自己实在是太懒散了.</li> <li>做安排和计划, 比如说看书的计划, 练琴的计划等等, 而不是每天吃完饭就做到电脑前开始敲不知道哪来的代码, 一敲敲到晚上十一点.</li> <li>恢复健身, 保持身体健康和心情愉悦.</li> </ul> <p>再就是一个方向的问题, 我未来的事业要何去何从.</p> <p>还记得 2020 年 5 月份, 我从第一家公司跳到第二家公司, 身份从 Java CRUD Boy 变成了 Senior DevOps Engineer, 从此我就开始了我和 Kubernetes 的孽缘.</p> <p>刚开始新工作还是很开心的, 但是后来被自己的组长建议每个季度都要花 3 - 4 周的时间整理述职和新 OKR 的时候我显然绷不住了. 而且我在 SRE 小组也需要轮流 oncall 以及处理和其他组的对接杂务, 真正能安静下心 coding 的时间不多.</p> <blockquote> <p>陷入了自我怀疑. 我发现我这个人就老喜欢自我怀疑, 担心自己哪天就被淘汰了.</p></blockquote> <p>在那时我开始好好想未来的规划, 刚好 PingCAP 在招 Chaos Mesh 相关的岗位, 要求熟悉 Linux 和 Kubernetes, 而且我挺早前就听说 PingCAP 这家公司名声不错, 氛围好. 于是在尝试下, 我加入了 PingCAP.</p> <p>其实当时我已经比较怀疑国内的工程氛围已经比较毒了, 但是我还是抱着试一试的心态去了 PingCAP. 如果 PingCAP 还是不行, 那我也就只能考虑国外的 IT 氛围了.</p> <p>一开始 PingCAP 氛围确实不错, 但是后来不行了. 这也是我离职的原因之一.</p> <p>于是乎我已经有了前车之鉴, 国内氛围就是这样的毒, 其他的公司我现在看上去虽然现在还好, 但是未来也不一定会继续保持得多好. 我应该怎么办呢?</p> <p>正确的路应该是时候考虑北美了, 这可能是正确的事情. 但是我现在处于 gap 的状态, 虽然经济上应该能够维持到去北美上个学再去找个工作, 但是心理上的负担非常大. 🥲</p> <p>或者说还是找个国内的公司继续假装无事发生? (直到下一次自己再崩溃?)</p> <p>我的内心里其实是有答案了, 但是我依旧缺少信心和决心.</p> <p>无论如何, 现在先开始学英语吧, 无论是不是出去, 都不亏.</p> <p>然后在新的一年里, 把自己的状态调整好, 在年初的 1 - 2 个月内, 把选择做出来, 把选择坚定地做下来.</p> 2022-45: DevJoy https://strrl.dev/post/weekly-report/2022/45-devjoy/ Tue, 08 Nov 2022 10:25:15 +0800 https://strrl.dev/post/weekly-report/2022/45-devjoy/ <p>这里又是一份周报, 时间范围是 <code>2022-11-02</code> 开始 到<code>2022-11-08</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="chaos-mesh-arm-物理机喜提升杯">Chaos Mesh ARM 物理机喜提升杯</h3> <p>最近收到一封邮件, 说是 Equinix Metal 的机房设备升级, 之前 Chaos Mesh 用的 <code>c2.large.arm</code> 实例需要被铲, 询问了下, 可以直接升级到 <code>c3.large.arm64</code>.</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-report/2022/45-devjoy/2022-11-08-10-41-57.png' alt="equinix metal" /> </p> </p> <p>机器的配置有了整体的提升:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-report/2022/45-devjoy/2022-11-08-10-43-34.png' alt="c2.large.arm" /> </p> </p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-report/2022/45-devjoy/2022-11-08-10-43-54.png' alt="c3.large.arm64" /> </p> </p> <blockquote> <p>另外我也估算了下目前手上的存储资源, 全部大约有 1.4 TiB 可用, 平均分布 3 副本也有 480 GiB 可用, 对于跑 Prow bot 看上去相当够了.</p></blockquote> <h3 id="github-api-graphql-vs-rest">GitHub API GraphQL vs REST</h3> <p>之前写了个统计 GitHub Action 失败率的小应用嘛: <a href="https://github.com/STRRL/gha-ci-grid">https://github.com/STRRL/gha-ci-grid</a>, 图开发方便, 使用的 Octokit 的 REST Client 实现的逻辑, 后来发现统计 Job 成功率的时候就特别麻烦, 需要 repo -&gt; workflow -&gt; workflow run -&gt; job run 查四层. 看了下 GraqhQL 貌似可以写一个 query 直接拿到所有的信息, 感觉非常香, 准备后面更新一下.</p> <h3 id="准备再去考点证">准备再去考点证</h3> <p>自从上次考了 CKA 以后就没在关注其他的认证了, 后续我的安排应该也不会很紧, 还是需要拿一些新的认证.</p> <p>方向大约是 LF 和 AWS 的一些认证吧.</p> <p>另外学习 AWS Cloud Practitioner Essentials 的时候确实了解到好多新知识.</p> <h2 id="生活相关">生活相关</h2> <h3 id="参加了-devjoy">参加了 DevJoy</h3> <p>关于 DevJoy 是什么可以看这里: <a href="https://www.devjoy.org/">https://www.devjoy.org/</a>.</p> <p>对俺来说是大型网友见面会, 见到了 Mila, 彦青姐, 高策哥哥, 天翼哥哥, 高松哥哥.</p> <p>展会上也有一些好玩的东西, 比如说:</p> <ul> <li>高策哥哥铺子上搭建了一个 stable diffusion 的环境, 我起手一个 <code>bishojo</code> 开始进行召唤</li> <li>Microsoft Reactor 的铺子上带来了 Hololens 2, 可惜工作人员不让顾客玩, 只能看投屏, 而且价格感人, $3500</li> <li>哔哩哔哩铺子上进行 AI Solo 赛, 打赢了 AI 就送赫斯缇亚(线上球)手办.</li> </ul> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-report/2022/45-devjoy/stable-diffusion-bishojo.jpeg' alt="召唤美少女" /> </p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-report/2022/45-devjoy/2022-11-08-10-37-59.png' alt="程序员安慰剂" /> </p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-report/2022/45-devjoy/2022-11-08-10-38-16.png' alt="Hololens" /> </p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-report/2022/45-devjoy/2022-11-08-10-38-25.png' alt="DOTA 2 AI 对战" /> </p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-report/2022/45-devjoy/2022-11-08-10-38-39.png' alt="上海蓝 Po 真的多" /> </p> </p> <h3 id="天气转凉-感冒了">天气转凉, 感冒了</h3> <p>上周天气转凉了, 我头铁得, 又穿着速干 T 恤爬山了, 结果被冻麻了.</p> <p>这两天身体不太舒服, 鼻塞流鼻涕喉咙痛.</p> <p>虽然自己核酸一直都是阴性, 但是不敢在外面咳嗽, 擤鼻涕. 😇</p> 2022-44: 鸽与停滞的 GTD https://strrl.dev/post/weekly-report/2022/44-%E9%B8%BD%E4%B8%8E%E5%81%9C%E6%BB%9E%E7%9A%84gtd/ Tue, 01 Nov 2022 23:05:16 +0800 https://strrl.dev/post/weekly-report/2022/44-%E9%B8%BD%E4%B8%8E%E5%81%9C%E6%BB%9E%E7%9A%84gtd/ <p>这里又是一份周报, 时间范围是 不知道什么时候开始 到<code>2022-11-01</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="看-kubecon-na-2022">看 KUBECON NA 2022</h3> <p>这次的 KUBECON 又有好多内容感兴趣, 关于我的观后感, 记录在这里了:</p> <p><a href="https://www.notion.so/strrl/KUBECON-22-NA-c39e92e4277d4aa2b4d1cf45077a86a6">https://www.notion.so/strrl/KUBECON-22-NA-c39e92e4277d4aa2b4d1cf45077a86a6</a></p> <h3 id="买了些新设备">买了些新设备</h3> <p>AirPods Pro 2, 很不幸, AirPods Pro 泡洗衣机了洗了, 它没有撑过来, 被迫买了新款. 好心疼.</p> <p>Windows Dev Kit 2023, 微软新出的开发者主机, 高通骁龙的计算平台, 4 大核 4 小核, 32G 内存, ¥4488, 比 mac mini 实惠. 但是目前还没法装 Linux. 有潜力成为最好的 arm64 linux 开发机.</p> <h2 id="生活相关">生活相关</h2> <h3 id="停滞的-gtd">停滞的 GTD</h3> <p>TLDR; 这周需要把停滞的 GTD 重新捡回来. 目标: 每天爬山之前过一遍 Daily Review.</p> <p>在今年年初的一段时间里, 我开始学习 GTD 这种管理要做什么事情的方法, 不得不说有一定的作用.</p> <p>只是在最近的实践中变得越来越变形, 然后时间停滞在 2022 年 10 月 3 日, 我不再更新我的 GTD, 也不再去做 daily routine:</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-report/2022/44-%E9%B8%BD%E4%B8%8E%E5%81%9C%E6%BB%9E%E7%9A%84gtd/2022-11-01-23-09-27.png' alt="" /> </p> </p> <p>然后在接下来的一段时间里, 个人状态有明显的下滑, 事情不再能完成, 计划被打乱, 一切回归不可控但又似乎没啥问题的虚无状态中.</p> <p>即使到现在我还没有感觉到有啥不适, 毕竟每天都没有什么要做的事, 打打混, 写点开心的代码很不错.</p> <p>为了以防未来将会到来的焦虑和后悔, 决定把 GTD 需要捡回来.</p> <h3 id="好像不晕车了">好像不晕车了</h3> <p>大约从九月下旬开始早睡觉, 大约十月中旬发现, 我好似又不晕车了, 在的士上玩手机也不会头晕了, 开心!</p> <h3 id="聊天邀约">聊天邀约</h3> <p>跟风, 在 cal.com 上创建了一个用来约时间聊天的日历, 有兴趣找俺聊天的同学可以随意定时间, 或者再协调:</p> <p><a href="https://cal.com/strrl/30min">https://cal.com/strrl/30min</a></p> <p>目前和 1 位网友聊过了, 我话太多了, 输出了很多但是听的太少了. 😰</p> 2022-41: 爬山上瘾 https://strrl.dev/post/weekly-report/2022/41-%E7%88%AC%E5%B1%B1%E4%B8%8A%E7%98%BE/ Tue, 18 Oct 2022 15:34:21 +0800 https://strrl.dev/post/weekly-report/2022/41-%E7%88%AC%E5%B1%B1%E4%B8%8A%E7%98%BE/ <p>这里又是一份周报, 时间范围是<code>2022-10-13</code>到<code>2022-10-19</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">Nand2Tetris</h3> <p>没做. <code>¯\_(ツ)_/¯</code></p> <blockquote> <p>几次想尝试开始但是都去做别的玩具了.</p></blockquote> <h3 id="google-ux">Google UX</h3> <p>没看. <code>¯\_(ツ)_/¯</code></p> <h3 id="最近-rust-上手了">最近 rust 上手了</h3> <p>好!</p> <p> <p class="md__image"> <img src='https://webp.strrl.dev/post/weekly-report/2022/41-%E7%88%AC%E5%B1%B1%E4%B8%8A%E7%98%BE/2022-10-19-20-23-55.png' alt="" /> </p> </p> <h2 id="生活相关">生活相关</h2> <h3 id="爬山上瘾">爬山上瘾</h3> <p>发现身体状态的提升会上瘾的, 现在在附近的地方爬山, 来回都从山里走, 总爬升差不多 400m, 非常舒服!</p> <h3 id="玩了一把泄漏的-novelai">玩了一把泄漏的 NovelAI</h3> <p>网上找了个懒人整合包, 跑起来以后发现自己脑子里根本没有啥关键词. 也没画出啥可爱的东西.</p> <blockquote> <p>不够涩!</p></blockquote> 2022-40: 去岳阳玩 https://strrl.dev/post/weekly-report/2022/40-%E5%8E%BB%E5%B2%B3%E9%98%B3%E7%8E%A9/ Wed, 12 Oct 2022 19:31:46 +0800 https://strrl.dev/post/weekly-report/2022/40-%E5%8E%BB%E5%B2%B3%E9%98%B3%E7%8E%A9/ <p>这里又是一份周报, 时间范围是<code>2022-10-05</code>到<code>2022-10-12</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">Nand2Tetris</h3> <p>没做. <code>¯\_(ツ)_/¯</code></p> <h3 id="google-ux">Google UX</h3> <p>没看. <code>¯\_(ツ)_/¯</code></p> <h3 id="refactoring-ui">Refactoring UI</h3> <p>这是一个挺出名的书籍吧, 从 zlibrary 上找到某个版本大致看了下.</p> <p>大致的内容是对于设计 UI 一些常见的 Pattern, 包括布局, 颜色, 图标等等.</p> <p>给我留下几个较深印象的是:</p> <ul> <li>先设计 feature, 而不是 layout</li> <li>使用 HSL 颜色模型来进行颜色的设计</li> <li>背景与主体需要有足够的对比度(<a href="https://contrast-ratio.com/">contrast ratio</a>), 大于 4.5:1 才好.</li> </ul> <h3 id="家里的跳板又寄了">家里的跳板又寄了</h3> <p>目前俺还是主要使用 zerotier 作为回家的方案, 但是很不巧的是, 家里只有一台 zerotier 的节点.</p> <p>而且很不巧的是, 在我出家门的第二天, 这台机器所在的物理机整个都挂掉了.</p> <p><a href="https://twitter.com/strrlthedev/status/1578350876241973248">https://twitter.com/strrlthedev/status/1578350876241973248</a></p> <p>回家以后发现机器灯还亮着, 于是强制重启以后看了下机器 kernel 日志:</p> <p> <p class="md__image"> <img src='./assets/2022-10-12-19-56-29.png' alt="kernel message" /> </p> </p> <p>发现还是之前网卡的那个问题.</p> <p>根据 PVE 帖子上的方法, 把 TCP checksum offloading 关了就可以了.</p> <blockquote> <p>上次出问题的时候也是这个预兆, 然后后来发现是内存问题. 这次希望内存不要再出问题了, 毕竟一条 32 GiB 的内存要小一千快钱呢.</p></blockquote> <p>经过这次后, 引发了写一个 zerotier operator 的想法:</p> <ul> <li>使用 CRD 加入 Network, 配置 forwarding</li> <li>多节点加入 Network</li> <li>主备的方式进行高可用</li> <li>自动 routing 和 iptables forwarding</li> </ul> <p>先挖个坑! 以后再填!</p> <h2 id="生活相关">生活相关</h2> <h3 id="黄码转绿码">黄码转绿码</h3> <p>2022.10.11, 买了到杭州西站的高铁票. 到站后我变成了黄码, 然后同行的女朋友依旧是绿码.</p> <p>再进行了单管核酸后, 把我安置在了一个名为 &ldquo;黄码转码区&rdquo;, 让我在支付宝健康码里进行申诉, 等待变成绿码后才能离开.</p> <p>我人傻了. 又不让走, 也不让隔离, 就让这提交申请以后等着. 我问这个区域里其他的人, 被告知出去的时间从 30 min - 6 hr 不等.</p> <p>填完了申诉, 等了半小时后, 我尝试着向良渚社区这边打了个电话. 说明了我的情况后, 被告知我有一个电话号码 156xxxx6711, 经过了中风险区, 所以给了黄码.</p> <p>其实这个号码 2 - 3 年前就没有在用了, 但是刚来杭州的时候还是用这个登记了.</p> <p>说明这个号码我没有再使用的情况后, 社区工作人员说会给我安排一个三天三检的套餐, 并修改我的状态为绿码.</p> <p>几分钟后, 我的健康码变成了绿码, 于是我准备离开了. 这时其他人都围过来问我是怎么弄的, 我说找对应社区打电话咨询情况, 并且我也建议他们不要干等, 也打电话问一下.</p> <p>转码区后, 再次排队更新自己的报备情况, 又作了一个混检, 终于顺利出站了.</p> <p>整个过程经历一个半小时左右.</p> <blockquote> <p>另外有一个细节, 杭州西站 P2 停车场貌似不好上运溪高架, 而 P4 比较方便上运溪高架. 以后打车要去 P4.</p></blockquote> <h3 id="身份证续期">身份证续期</h3> <p>我想大家应该都是在高考之前办的身份证吧, 而且第一个身份证的有效期是 10 年的.</p> <p>我的身份证在 11 月中旬过期, 所以最近我去附近有户籍科的公安局尝试办新的身份证.</p> <p>一开始我在电话上问了, 说可以外省是可以异地办理的.</p> <p>然后我到了现场, 照片也拍了(丑的一批), 录入的时候发现, 我的户口所在地, 老家的派出所名字改了:</p> <ul> <li>之前是 &ldquo;AA县BB街道CC派出所&rdquo;</li> <li>现在是 &ldquo;CC派出所&rdquo;</li> </ul> <p>这个派出所的注册编号也变了, 然后被告知要回老家办理. :(</p> <p>心情复杂.</p> <p>最近又要回山东了:(</p> <h3 id="去岳阳玩">去岳阳玩</h3> <p>又去岳阳玩了, 各处缺水, 洞庭湖也是, 水位非常低.</p> <p>在洞庭湖附近飞了飞机, 风真的大, 飞机耗电很严重, 抖得也很厉害, 而且总是提醒风大危险.</p> <p>最后, 分享些自己拍的照片吧!</p> <p> <p class="md__image"> <img src='./assets/2022-10-12-20-21-19.png' alt="" /> </p> <p class="md__image"> <img src='./assets/2022-10-12-20-21-26.png' alt="" /> </p> <p class="md__image"> <img src='./assets/2022-10-12-20-21-31.png' alt="" /> </p> <p class="md__image"> <img src='./assets/2022-10-12-20-21-40.png' alt="" /> </p> <p class="md__image"> <img src='./assets/2022-10-12-20-21-43.png' alt="" /> </p> </p> 2022-39: 普通的周报-之三 https://strrl.dev/post/weekly-report/2022/39-%E6%99%AE%E9%80%9A%E7%9A%84%E5%91%A8%E6%8A%A5-%E4%B9%8B%E4%B8%89/ Wed, 05 Oct 2022 19:52:59 +0800 https://strrl.dev/post/weekly-report/2022/39-%E6%99%AE%E9%80%9A%E7%9A%84%E5%91%A8%E6%8A%A5-%E4%B9%8B%E4%B8%89/ <p>这里又是一份周报, 时间范围是<code>2022-09-26</code>到<code>2022-10-04</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">Nand2Tetris</h3> <p>这周写了 VM Translator Part 1: <a href="https://github.com/STRRL/nand2tetris-projects/tree/master/07/vm-translator">https://github.com/STRRL/nand2tetris-projects/tree/master/07/vm-translator</a>.</p> <p>用 rust 梭的, 到目前为止感觉都还不错, 目前的体验是:</p> <ul> <li>创建同时包含字面 string 和需要 render 的 string 的数组时, 不是很好用, 都得转 <code>&amp;str</code>/<code>String</code>, 然后再用 iterator map 成需要的类型;</li> <li>应 <code>clone</code> 尽 <code>clone</code>;</li> <li>enum 真好用;</li> </ul> <h3 id="google-ux">Google UX</h3> <p>没看. <code>¯\_(ツ)_/¯</code></p> <h3 id="翻译了一些文章">翻译了一些文章</h3> <p>翻译了 <a href="https://whatiknown.strrl.dev/notes/g2xw1fmq6l7g1yvxjwof41k/">Documentation System</a>, 这个系列的文章.</p> <p>这几篇文章的实用性很强, 如果对于如何构建一个好的文档心里没谱的话, 可以尝试参考着来.</p> <h3 id="kaniuse-后续">kaniuse 后续</h3> <p>目前已经糊了一个非常简单的放在这里了: <a href="https://kaniuse.vercel.app/">https://kaniuse.vercel.app/</a></p> <p>功能的话可谓是相当简陋, 就是抄了一小部分的 <a href="https://github.com/stackrox/k8s-i-use">https://github.com/stackrox/k8s-i-use</a>.</p> <p>这次尝试不用 UI 库, 而是用 CSS 框架来画 UI, 有点难. 还在摸索.</p> <blockquote> <p>配置 nuxt 的过程中还遇到了一些 ts 类型体操相关的问题, 被朋友推荐看一遍 ts 的 Release Notes. 🤣🤣🤣</p></blockquote> <h3 id="新坑-gha-ci-grid">新坑: GHA CI Grid</h3> <p>重所周知, CI 是会失败的. 但是如果 CI 中执行的是 flaky test, 也会给开发者带来不好的体验.</p> <p>Chaos Mesh 正在受这种情况折磨, 而且挺久了, 但是一直没有具体/量化地去分析下现状. Chaos Mesh 使用 CNCF 的 GiHub Enterprise 套餐, 有无上限的 GitHub Action 资源, 所以 Chaos Mesh 大部分的 CI 都是在 GitHub Action 上进行的.</p> <blockquote> <p>感谢 CNCF. OwO</p></blockquote> <p>但是 GitHub Action 与一些 self hosted CI (比如说 Drone, Jenkins), 或者一些 CI 服务(Circle CI, Travis CI)相比, 在执行历史的统计, 还有 testcase report/junit report 的支持上做的不好.</p> <blockquote> <p>话说最近无意间发现 Spring 的 CI 好漂亮啊: <a href="https://ci.spring.io/">https://ci.spring.io/</a>. 是这个工具: <a href="https://concourse-ci.org/">https://concourse-ci.org/</a></p></blockquote> <p>一个例子: 我想知道哪些 testcase 是 flaky 的, flake rate 是多少. 目前 GitHub Action 没有直接一个 Dashboard 可以看, 需要自己调 API 去算一算.</p> <p>于是想要类似于 <a href="https://testgrid.k8s.io">https://testgrid.k8s.io</a> 那样的东西, 于是俺就又梭了一个: <a href="https://gha-ci-grid.strrl.dev/">https://gha-ci-grid.strrl.dev/</a>.</p> <p>比如要看 Chaos Mesh 的 CI 统计, 就访问 <a href="https://gha-ci-grid.strrl.dev/gha/chaos-mesh/chaos-mesh">https://gha-ci-grid.strrl.dev/gha/chaos-mesh/chaos-mesh</a>.</p> <blockquote> <p>如果发现请求失败, 出现限流或者 <code>HTTP 403</code> 了, 记得点 &ldquo;Connect with GitHub&rdquo;, 拿一个 Token, 避免限流.</p></blockquote> <p>顺便也体验到了有钱公司 Vercel 的开发者的响应速度:</p> <p><a href="https://twitter.com/strrlthedev/status/1575772493641457666">https://twitter.com/strrlthedev/status/1575772493641457666</a></p> <p>结果比较惨:</p> <p> <p class="md__image"> <img src='./assets/2022-10-05-20-34-50.png' alt="GHA CI Grid" /> </p> </p> <blockquote> <p>人的这个脑子啊, 对抽象感觉真是不敏感. 每个 PR 都要 rerun 几次 test 好像也没啥, 统计出数字, 50% 的 flake rate 来能立刻感觉出不一样了.</p></blockquote> <p>当然, 昨天晚上 Chaos Mesh 双周会上也提到这个事情了, 大家准备下阶段把 testcases 搞一搞, 让开发者们开心.</p> <h2 id="生活">生活</h2> <h3 id="守望-2-开服了">守望 2 开服了</h3> <p>约着之前的朋友打了几把, 又回到了紧张刺激的游戏体验中. 但是我觉得我太老了, 注意力和反应速度都不行了, 只能玩玩不需要瞄准的莫姨划划水这样.</p> <h3 id="到秋天了">到秋天了</h3> <p>这两天气温抖得很厉害, 经历了一个昨天 36 度今天 17 度体验, 出门人就给冷麻了.</p> <h3 id="刷到了死侍新电影的预告">刷到了死侍新电影的预告</h3> <p>看上去要和狼叔一起整活了! 开心!</p> <p> <p class="md__image"> <img src='./assets/2022-10-05-20-47-31.png' alt="DP" /> </p> </p> <p> <p class="md__image"> <img src='./assets/2022-10-05-20-47-45.png' alt="DP" /> </p> </p> <p><a href="https://twitter.com/RealHughJackman/status/1574866641623588876?s=20&amp;t=yMRpEX0s0uDAfzrIgFibHg">https://twitter.com/RealHughJackman/status/1574866641623588876?s=20&amp;t=yMRpEX0s0uDAfzrIgFibHg</a></p> <p><a href="https://twitter.com/RealHughJackman/status/1575102901919576065?s=20&amp;t=yMRpEX0s0uDAfzrIgFibHg">https://twitter.com/RealHughJackman/status/1575102901919576065?s=20&amp;t=yMRpEX0s0uDAfzrIgFibHg</a></p> 2022-38: 事情是难的 https://strrl.dev/post/weekly-report/2022/38-%E4%BA%8B%E6%83%85%E6%98%AF%E9%9A%BE%E7%9A%84/ Tue, 27 Sep 2022 12:30:10 +0800 https://strrl.dev/post/weekly-report/2022/38-%E4%BA%8B%E6%83%85%E6%98%AF%E9%9A%BE%E7%9A%84/ <p>这里又是一份周报, 时间范围是<code>2022-09-19</code>到<code>2022-09-26</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">Nand2Tetris</h3> <p>开始填坑了, 这周写了 hack assembler: <a href="https://github.com/STRRL/nand2tetris-projects/tree/master/06/hack-assembler">https://github.com/STRRL/nand2tetris-projects/tree/master/06/hack-assembler</a>.</p> <h3 id="google-ux">Google UX</h3> <p>课程转旁听了, 不继续交钱了. 断断续续重新看了一些东西.</p> <p>主要意识到的东西是, 产品是给用户用的, 而不是工程师和设计师意淫出来的, 永远都要去追用户的需求, 而不是只考虑自己的想法. 在迭代的各个阶段都要时刻记住以用户的需求为导向, 而且通过产出原型 -&gt; 测试 -&gt; 改进的方式, 不断地去验证自己的想法是否符合用户的需求.</p> <blockquote> <p>那我是领域专家, 用户是领域小白怎么办? 不知道, 还没找到答案.</p></blockquote> <p>那谁是用户呢?</p> <p>2C 产品意味着任何人都有可能是你的用户, 但是 2B 产品就不一定了, 我不知道如何确定用户是谁.</p> <blockquote> <p>比如说 TiDB 和 Chaos Mesh 的用户显然应该多少都和计算机沾点边的.</p></blockquote> <h3 id="试着做-rustlings">试着做 rustlings</h3> <p>找了个下午 + 晚上肝完了 rustlings, 感觉对 Rust 并没有更多新的认识, 但是增长了些信心.</p> <p>还是得找个合适的项目练练手.</p> <h3 id="想优化一下博客的样式和内容">想优化一下博客的样式和内容</h3> <p>我的赛博花园好丑啊!</p> <p>打开了之前的一篇文章, 密密麻麻的全是字, 完全不想看.</p> <p>一方面样式使得字太密集了, 另一方面确实文字描述太多.</p> <blockquote> <p>两手都要抓! 两手都要硬!</p></blockquote> <p>所以自己胡乱改了下样式, 主要是增大了字体和行间距.</p> <blockquote> <p>并不是各位的设备缩放变了.</p></blockquote> <p>下一步想做的事: 卡片式的连接貌似非常不错, 可以试着整整!</p> <h3 id="绝妙的点子-kaniusecom">绝妙的点子: kaniuse.com</h3> <p>前端的朋友应该都熟悉 caniuse.com, 大家可以在这里找到某个特性在不同浏览器的不同版本的支持情况.</p> <p> <p class="md__image"> <img src='./assets/caniuse.png' alt="" /> </p> </p> <p>最近在 Kubernetes 的使用过程中, 我遇到了类似的问题: 我想知道某个不同特性在不同版本的 Kubernetes 中的支持情况.</p> <p>比如说 Ingress 这个 API, 有三个不同的 GroupVersion:</p> <ul> <li><code>extensions/v1beta1</code>, 于 <code>1.14</code> 被标记为废弃, 与 <code>1.22</code> 移除</li> <li><code>networking.k8s.io/v1beta1</code>, 于 <code>1.14</code> 引入, 于 <code>1.22</code> 移除</li> <li><code>networking.k8s.io/v1</code>, 于 <code>1.19</code> 引入, 目前(<code>1.25</code>)正在使用</li> </ul> <p>要搜集这些信息, 目前只能靠手动的人力搜索, 还没有一个工具在索引这些信息.</p> <p>如果能有一个工具, 以这种形式展示, 那我就非常开心了:</p> <p> <p class="md__image"> <img src='./assets/kaniuse.jpg' alt="" /> </p> </p> <p>如果能再多告诉我一点信息, 比如, 我提供我当前用的 API 版本是 <code>X</code>, Kubernetes 版本是 <code>Y</code>, 这个工具推荐我在哪个日期前应该做哪些 migration 工作.</p> <p>这只是 Kubernetes API 相关的, 如果也能自动化有办收集一些 API 无关的 feature lifecycle, 也在这里展示, 那就更好了.</p> <h2 id="生活相关">生活相关</h2> <h3 id="事情是难的">事情是难的</h3> <p>最近因为事情比较杂, 胡思乱想的时间也多了起来. 上段时间其实精神状态都不是很好, 没有固定的工作内容后, 感觉坐在电脑前也失去了像以前那样敲代码的动力.</p> <p>于是乎给自己定了一些每日目标完成:</p> <ul> <li>上一节 MOOC</li> <li>读任意一本书的一个章节</li> <li>翻译一篇英文文章</li> <li>完成 LeetCode 上的一道题</li> </ul> <p>而后发现这些目标过于琐碎, 而且做了以后也没有什么正反馈, 于是最近几天又改了: 每天 4 选 2 完成即可.</p> <p>离开学校以后, 自学的特点就是有大量碎片化的知识和概念, 而大量摄入这些所谓碎片化的&quot;干货&quot;以后, 对学习的认知都发生了一定的改变: 预期投入太低, 预期收获太高.</p> <p>需要投入大片连续的时间来去集中制作或学习某事, 而不是碎片化的时间, 琐碎的输入/输出.</p> <p>假期难得, 不要把自己绷太紧了.</p> <p>另外还了解到的一个观点是, 在工程做疲倦了以后, 休息的方式是专心的做一些艺术性的事情, 比如音乐, 画画&hellip; 准备后续试一下.</p> <blockquote> <p>这就是传说中的, 做完数学做英语, 做完英语做物理, 做完物理做语文&hellip;</p></blockquote> <h3 id="买了-iphone-13-mini">买了 iPhone 13 mini</h3> <p>和女朋友在逛商场的时候, 她去把玩了 iPhone 14 Pro, 我顺手把玩了旁边的 iPhone 13 mini, 突然感到一阵震惊, 这个太舒服了.</p> <p>我对 iPhone 5 那个模具一直很喜欢, 小巧, 有棱有角.</p> <p>经过反复思考, 女朋友的劝说, 还有推友的劝说后, 这台很多方面都很舒服, 只有刘海 + 没高刷这两个缺点的手机, 还是买下来了.</p> <blockquote> <p>女朋友原话: 自从 Note 9 换了以后, 就几乎没见过你中意别的手机. 只有俩缺点的手机很难得的, 现在错过了后面更难有了, 买了得了.</p></blockquote> <p>贴一张合照:</p> <p> <p class="md__image"> <img src='./assets/phones.jpg' alt="phones" /> </p> </p> <h3 id="跑步机---爬山">跑步机 -&gt; 爬山</h3> <p>最近天气凉快了, 在教练的建议下早上可以去爬山, 而不是跑步机.</p> <p>跑步机上也太无聊了, 哪怕有点东西看和听, 固定的景色总会让我走神, 而且走神也没有很开心. 不如爬山一路看风景.</p> <p> <p class="md__image"> <img src='./assets/hiking.png' alt="hiking" /> </p> </p> <p>不过教练也提醒了, 爬山不像跑步机那样可以定时定量, 要多靠自己注意.</p> <p>比如说最近这几次, 其实心率都不够快, 要 140 - 150 效果才好.</p> <blockquote> <p>不过教练说中午就别去了, 天气暖了以后, 会有蛇出没. 😐</p></blockquote> <h3 id="分享一些好玩的娱乐内容">分享一些好玩的娱乐内容</h3> <p>最近保持心情愉悦听和看的一些内容:</p> <ul> <li><a href="https://open.spotify.com/show/4bW9I6PXtNz7485FiVnsft">凑近点看</a>, 群口相声</li> <li><a href="https://open.spotify.com/show/4KspyMLIvHhrLzyQBvagW9">世界莫名其妙物语</a>, 群口相声</li> </ul> 2022-37: 灵活就业进行中 https://strrl.dev/post/weekly-report/2022/37-%E7%81%B5%E6%B4%BB%E5%B0%B1%E4%B8%9A%E8%BF%9B%E8%A1%8C%E4%B8%AD/ Mon, 19 Sep 2022 19:23:28 +0800 https://strrl.dev/post/weekly-report/2022/37-%E7%81%B5%E6%B4%BB%E5%B0%B1%E4%B8%9A%E8%BF%9B%E8%A1%8C%E4%B8%AD/ <p>这里又是一份周报, 时间范围是<code>2022-09-12</code>到<code>2022-09-19</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">Nand2Tetris</h3> <p>本周没有进行 Nand2Tetris 的学习.</p> <h3 id="google-ux">Google UX</h3> <p>迫于之前学过的都忘记了. 所以这次学的时候顺便开始做&quot;笔记&quot;: <a href="https://whatiknown.strrl.dev/notes/bl9wq6sc32ufvri0ukuyqkh/">https://whatiknown.strrl.dev/notes/bl9wq6sc32ufvri0ukuyqkh/</a></p> <h3 id="一丢丢关于程序的瞎想">一丢丢关于程序的瞎想</h3> <p>&ldquo;可复现性&rdquo; 是软件行业能够快速稳定发展的重要的基础.</p> <blockquote> <p>但是出处我找不到了&hellip;</p></blockquote> <p>&ldquo;可复现性&quot;意味着, 只要一个人有生产资料(代码, 电脑), 他就能够使用这些生产资料做出一样的东西来. 相比于建筑行业, 哪怕拥有了足够的钢筋水泥, 也几乎不可能在<strong>极短的时间内</strong>构建出<strong>一模一样</strong>的建筑来.</p> <p>这个特点使得计算机的工件/产物能够广泛的传播和使用, 分布式的合作能够以空前的规模进行, 行业内问题的解决效率也非常非的高.</p> <p>目前在投身开源项目的构建时, 俺自己认为维护&quot;可复现性&quot;有很重要的几点:</p> <ul> <li>有一份好的 Contributing guidelines, 尤其是在工程角度.</li> <li>任何代码都能够在开发者本地环境上构建和运行, 包括所有的测试.</li> </ul> <p>在今后的工程作业中, 俺会多注意这两点.</p> <h3 id="准备使用-zfs-替换-btrfs-作为开发机的文件系统">准备使用 zfs 替换 btrfs 作为开发机的文件系统</h3> <p>上次杭州 LUG 的分享会上, 有一位同学分享了 zfs 相关的内容. 鉴于我一直以使用 btrfs 作为开发机的文件系统而且也正在顺利使用着 snapshot 功能做备份.</p> <p>因为群晖上其实也是使用 btrfs 的嘛, 于是想尝试一下使用 btrfs send 和 btrfs receive 来做一次异地备份. 结果就是体验非常不好:</p> <ul> <li>速度很慢, 很久一段时间只有 60KiB/s 的速度, 峰值也只有 60MiB/s.</li> <li>没有办法断点续传. 一旦中断, 就必须重新开始.</li> </ul> <p>于是在上周的 hzlug 我又问了下那位同学, 回复说 zfs 是可以断点续传的.</p> <p>正好 NAS 换下来了 4 块 2TiB 的盘, 可以收个蜗牛星际组 zfs 再试试!</p> <h2 id="生活相关">生活相关</h2> <p>最近 journal 其实记录的并不多, 发现生活上也没啥可聊的. 先不写了吧.</p> 2022-36: 喜迎中秋节 https://strrl.dev/post/weekly-report/2022/36-%E5%96%9C%E8%BF%8E%E4%B8%AD%E7%A7%8B%E8%8A%82/ Mon, 12 Sep 2022 16:48:53 +0800 https://strrl.dev/post/weekly-report/2022/36-%E5%96%9C%E8%BF%8E%E4%B8%AD%E7%A7%8B%E8%8A%82/ <p>这里又是一份周报, 时间范围是<code>2022-09-05</code>到<code>2022-09-11</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">Nand2Tetris</h3> <p>本周没有进行 Nand2Tetris 的学习.</p> <h3 id="google-ux">Google UX</h3> <p>本周没有进行 Google UX 的学习.</p> <blockquote> <p>啥也没学, 我是废物.</p></blockquote> <h3 id="给-nas-扩容">给 NAS 扩容</h3> <p>最开始搭建 NAS 的时候, 因为过于弱小买了 4 块 WD 的 SMR 2T 盘, 可以说是冤大头大队长了. 最近迫于用量要过 2 / 3 了, 开始考虑扩容的事情.</p> <p>朋友给推荐了 WD HC550 16T 企业盘, 虽说是矿盘但是企业盘有 5 年质保也不错.</p> <p>闲鱼上询问了几家低价的却都在成都, 发不出货来. 于是 fallback 到江浙沪地区, 买了四块 HC520 12T 的盘.</p> <p>然后就开始了紧张刺激的扩容之旅.</p> <p>之前建存储池的时候, 使用了群晖的 SHR(Synology Hybrid RAID), SHR 是软件 RAID5 + BTRFS. 而且 SHR 也没办法换成其他的 RAID 方式了.</p> <p>而且俺的整个 NAS 只有一个存储池, 还吃掉了所有的 4 个盘位. 所以扩容的过程其实一块块地换盘, 然后 SHR / RAID5 修复重建的过程.</p> <blockquote> <p>大家不要学我.</p></blockquote> <p>大约经历了 3 天左右, 存储它自己迁移好了.</p> <p>稍微看了下 SHR 的做法:</p> <ul> <li>之前 2T 的盘, 每个盘上都有 4 个分区, 然后各个分区分别用 mdadm 做了软 RAID <ul> <li>sda1, sdb1, sdc1, sdd1 是 <code>mdadm</code> 做了 <code>RAID1</code> 的 <code>/dev/md0</code>, 格式化成 <code>ext4</code>, 挂在了根上</li> <li>sda2, sdb2, sdc2, sdc2 做了 <code>RAID1</code>, 是 <code>/dev/md1</code>, 是 swap(的一部分, 还有一部分是 zram; 分层 swap, 好.)</li> <li>sda3, sdb3, sdc3, sdd3 是 <code>/dev/md2</code>, 做了 <code>RAID5</code>, 这才是 SHR 的数据</li> </ul> </li> <li>然后使用了 LVM, 将 <code>/dev/md2</code> 作为一个 PV, 加到 VG 里, 最后划了一个 LV, 格式化成 btrfs 挂上来.</li> <li>换了 12T 的盘进行扩容, 迁移的方式是先建立一个之前一样的分区表, 按顺序恢复 <code>/dev/md0</code>, <code>/dev/md1</code>, <code>/dev/md2</code>.</li> <li>然后将剩余空间建立了新分区, 并且创立了新的软 <code>RAID5</code> 设备 <code>/dev/md3</code>.</li> <li>最后是将 <code>/dev/md3</code> 也作为 PV 加到 VG 里, 调整 LV 的大小, 调整 btrfs 的大小, 扩容完成.</li> </ul> <p>不得不说还是非常妙的, 一开始我还以为是直接使用 btrfs 接了裸盘, 没想到是一层 md array, 再加一层 LVM.</p> <p>设计真的很不错, 而且反正家用机, 性能要求不怎么样, 还算可以啦.</p> <h3 id="做个游戏玩玩">做个游戏玩玩</h3> <p>最近的 Survival / Survivor 游戏系列比较火:</p> <ul> <li>Vampire Survivors</li> <li>Nomad Survival</li> <li>SoulStone Survivors</li> <li>还有一个手游 Survivor.io (换皮 Vampire Survivors)</li> </ul> <p>手痒想自己也做一个类似的.</p> <p>作为一个年老而且躁动的玩家, 只是遵循游戏制作者意图 / 设计进行游戏, 已经不能满足我的需求了. 有时候自己能够一些比较有趣的游戏机制, 然后就仅限于自己的脑海里了.</p> <p>俺想做一个定制度高的游戏, 它既可以使玩家, 也可以使开发者对它进行较大的更改, 加入自己想要的角色, 技能, 机制, 特效以及地图.</p> <blockquote> <p>把 Steam 创意工坊好好用起来.</p></blockquote> <p>总之整个东西还在慢慢地梭中, 不知道什么时候能有一个雏形出现.</p> <h3 id="what-nobody-tells-you-about-documentation">&ldquo;What nobody tells you about documentation&rdquo;</h3> <p>Ref:</p> <ul> <li><a href="https://www.youtube.com/watch?v=t4vKPhjcMZg">https://www.youtube.com/watch?v=t4vKPhjcMZg</a></li> <li><a href="https://documentation.divio.com/introduction/">https://documentation.divio.com/introduction/</a></li> </ul> <p>这是一篇将如何构建文档的 Talk. 提到我们应该构建 4 份内容, 而不是一个文档. 四个内容分别是:</p> <ul> <li>Tutorials</li> <li>How-to guides</li> <li>Discussion / Explanation</li> <li>Reference</li> </ul> <p> <p class="md__image"> <img src='https://documentation.divio.com/_images/overview.png' alt="4 quadrants" /> </p> </p> <p>每份内容都有自己的特点, 适合的读者, 以及适合的场景.</p> <p>俺后面也会尝试跟随这个思路去更新文档.</p> <h2 id="生活相关">生活相关</h2> <h3 id="回老家过中秋">回老家过中秋</h3> <p>今年中秋回了躺山东家里, 然后今年中秋和教师节重合了嘛, 也给妈妈顺便庆祝了教师节.</p> <p>把无人机也带回家给爸妈玩了, 爸妈表示好玩!</p> <p>晚上出去散步, 县城里的环境还是不错的, 公园挺多, 活动中心小情侣也不少hhhhh.</p> <h3 id="又胖了">又胖了</h3> <p>回到杭州上秤 175 斤了, 回家三天涨了 5 斤. 北方的食物是真的碳水多啊! 黄桥烧饼, 鸡蛋火烧, 煎饼果子, 菜卷子, 手擀面. 吃了个爽!!!</p> <blockquote> <p>放假三天就胖了, 我是废物.</p></blockquote> <h3 id="尝试把-daily-notes-从-notion-移动到-dendron-然后又移回来了">尝试把 Daily Notes 从 Notion 移动到 Dendron (然后又移回来了)</h3> <p>Dendron 是一个俺比较喜欢的 Knowledge Base 工具, 然后它的 Schema 和 Template 功能挺强大的, 像日记这种有规则而且需要管理的东西, 比较适合用 Dendron.</p> <p>于是俺配置好了 Daily Notes 的 Schema 和 Template, 试着用了两天, 结果发现了大问题:</p> <p>木有移动端! 木有办法在生活中记录随笔!</p> <p>于是又回到了 Notion.</p> <p>但是也是有好处的, 将 5MJ(5 Minutes Journal) 的模板迁移到了 Notion, 然后就可以在手机上记录了!</p> 2022-35: 休息休息修整修整 https://strrl.dev/post/weekly-report/2022/35-%E4%BC%91%E6%81%AF%E4%BC%91%E6%81%AF%E4%BF%AE%E6%95%B4%E4%BF%AE%E6%95%B4/ Sun, 04 Sep 2022 13:36:56 +0800 https://strrl.dev/post/weekly-report/2022/35-%E4%BC%91%E6%81%AF%E4%BC%91%E6%81%AF%E4%BF%AE%E6%95%B4%E4%BF%AE%E6%95%B4/ <p>这里又是一份周报, 时间范围是<code>2022-08-29</code>到<code>2022-09-04</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">Nand2Tetris</h3> <p>本周没有进行 Nand2Tetris 的学习.</p> <h3 id="google-ux">Google UX</h3> <p>本周没有进行 Google UX 的学习.</p> <h3 id="离职啦">离职啦</h3> <p>俺这周三从 PingCAP 离职啦.</p> <p>会先休息一段时间 :) 这段时间内的主要精力会写一些让自己开心而且 peace 的东西玩~</p> <h2 id="生活相关">生活相关</h2> <h3 id="hzlug-h6-线下活动">HZLUG H6 线下活动</h3> <p>再次和大家在线下聊天了, 这次人数达到了一个峰值: 来了 9 个人!</p> <p>有两个分享:</p> <ul> <li>在 ZFS 上使用 bedrock linux / 通过 ipxe 启动 bedrock with zfs</li> <li>Proof assistant, formal verification and dependent type</li> </ul> <p>鸽鱼带来了一个有趣的设备: 充电头 + 充电宝 + USB 扩展坞 + 移动 SSD 硬盘 这么一个缝合怪, 挺有意思的, 等他的评测文章.</p> <p>另外到场的一位同学也现场安装了 Asahi Linux, 体验还不错, 但是也还是达不到生产工具的水平.</p> <p>ref: <a href="https://hzlug.org/09-03-h6-photo/">https://hzlug.org/09-03-h6-photo/</a></p> <h3 id="健身暂停两后后的复健">健身暂停两后后的复健</h3> <p>上上周去了云南旅游, 上周在家里摆了一周, 连续两周都没有去健身房, 自己的体质下降许多.</p> <p>周一中午练心肺, 菜成了一个弱鸡, 一会就头晕 + 喘不过气来了.</p> <p>还是得持续得坚持行为习惯, 而不是说设置一个目标.</p> <h3 id="暗黑-3-新赛季的流行-builds">暗黑 3 新赛季的流行 Builds</h3> <p>开服之前: 死灵法师好强, 好好玩! 🤩</p> <p>开服之后: 好像别的职业更好玩. 🤔</p> <p>圣教军加上这个赛季特有的&quot;天使坩埚&quot;效果, 天拳跑马到达了一个全新的台阶, 全自动清图打怪, 全程操作只需要一个按键, 抠脚专用. 悬赏/小米指定速刷职业.</p> <blockquote> <p>骑马法师</p></blockquote> <p>武僧这个赛季再次完美了, PTR 中出现的所有 bug, 有减益的全修了, 有增益的全部变成 feature 保留了. 散件敲钟变成了能同时享有元素戒两种元素加成的 BD.</p> <blockquote> <p>完美法师 / 敲钟法师</p></blockquote> <p>野蛮人也有一条非常炫酷的&quot;天使坩埚&quot;效果: 25 码的敌人会被旋风斩持续的吸引. 而且这个控制不受怪物的控制递减机制, 而就是说能够无限聚怪 + 控制, 辅助蛮成为了这个赛季的 T0 辅助.</p> 2022-34: 喜迎暗黑 3 第 27 赛季 https://strrl.dev/post/weekly-report/2022/34-%E5%96%9C%E8%BF%8E%E6%9A%97%E9%BB%91-3-%E7%AC%AC-27-%E8%B5%9B%E5%AD%A3/ Sun, 28 Aug 2022 17:55:46 +0800 https://strrl.dev/post/weekly-report/2022/34-%E5%96%9C%E8%BF%8E%E6%9A%97%E9%BB%91-3-%E7%AC%AC-27-%E8%B5%9B%E5%AD%A3/ <p>这里又是一份周报, 时间范围是<code>2022-08-22</code>到<code>2022-08-28</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <blockquote> <p>这周整周都在请假(继续摆), 所以计算机相关的比较少. 有些有趣的点子俺还在整理, 估计下 2 - 3 周, 想得差不多了再和大家分享.</p></blockquote> <h3 id="nand2tetris">Nand2Tetris</h3> <p>本周没有进行 Nand2Tetris 的学习.</p> <h3 id="google-ux">Google UX</h3> <p>本周没有进行 Google UX 的学习.</p> <h3 id="试用-grafana-operator">试用 Grafana Operator</h3> <p>在用了 Home Assistant 以后, 想做的 Grafana Dashboard 逐渐变得多了起来. 在经历过若干次没有持久化到 ConfigMap, 结果 Grafana Pod 重建以后, 梭到一半 Dashboard 丢失的事情后, 俺开始寻找方便的方法去管理 Grafana Dashboard.</p> <blockquote> <p>为啥俺不直接用 ConfigMap + JSON, 因为俺是有一些 Dashboard 是从线上下载下来的. 这涉及到一个 Grafana 的<a href="https://github.com/grafana/grafana/issues/10786">陈年老 issue</a>, 导致很多导入的 JSON 都需要 <a href="https://github.com/grafana/grafana/issues/10786#issuecomment-568788499">patch 一下</a>才能流畅使用 provisioning, 每次手工 patch 太累了.</p></blockquote> <p>Grafana Operator 支持做这件事情, 效果类似于<a href="https://github.com/grafana-operator/grafana-operator/blob/master/deploy/examples/dashboards/DashboardFromGrafana.yaml">这个 example</a>.</p> <p>也支持已经画好的 Dashboard 通过 ConfigMap 方式导入, <a href="https://github.com/grafana-operator/grafana-operator/blob/master/deploy/examples/dashboards/DashboardFromConfigMap.yaml">example</a>.</p> <p>现在我可以比较愉快的同时使用线上导入的 Dashboard 和我自己编辑的 Dashboard 了!</p> <p>如果大家有什么办法管理 Grafana Dashboard, 也请告诉俺! 提前感谢.</p> <blockquote> <p>实在不行再挂 PV.</p></blockquote> <h2 id="生活相关">生活相关</h2> <h3 id="肝暗黑-3-第-27-赛季">肝暗黑 3 第 27 赛季</h3> <p>上一次 26 赛季还是在<a href="https://strrl.dev/post/weekly-report/2022/15-%E5%96%9C%E8%BF%8E%E6%9A%97%E9%BB%91-3-%E7%AC%AC-26-%E8%B5%9B%E5%AD%A3/">上一次</a>.</p> <p>这次 PTR 我也<a href="https://strrl.dev/post/weekly-report/2022/28-%E7%83%AD%E4%B9%8E%E7%9A%84%E6%9A%97%E9%BB%913ptr/">兴致勃勃得参加了</a>, 而且试过了/爽到了<a href="https://www.youtube.com/watch?t=312&amp;v=L8HoiwKVvlQ&amp;feature=youtu.be">新鲜的 BUG</a>, 然后这个 bug 在第二天就被热修复了.</p> <p>这次俺也和女朋友一起开荒, 并在赛季第二天晚上打过了 120 层! 开心!.</p> <p>这次也是用的拉斯玛套打亡灵大军, 断手操作. 这才是 ARPG!</p> <blockquote> <p>拉斯玛就是暗黑 4 CG 里, 复活莉莉丝的那个人. ref: <a href="https://youtu.be/0SSYzl9fXOQ?t=518">https://youtu.be/0SSYzl9fXOQ?t=518</a></p></blockquote> <blockquote> <p>纪念视频占位符</p></blockquote> <p>由于这几天玩得太肝了, 洗澡的时候发现掉了不少头发.</p> <p> <p class="md__image"> <img src='./assets/hair.jpg' alt="hair" /> </p> </p> <h3 id="买了新手机-z-flip-4">买了新手机 Z Flip 4</h3> <p>因为 Z Flip 4 太可爱了所以买了.</p> <p> <p class="md__image"> <img src='./assets/z-flip-4.jpg' alt="z flip 4" /> </p> </p> <p>到手之后发现并没有想象中的那么小巧, 还是挺重的. 并且这一代铰链很重, 我一个手打不开. (算是个好事, 不要老解锁玩手机.)</p> <p>只能放一张 SIM 卡, 而且国行还不支持 eSIM.</p> <blockquote> <p>我就是冤大头.</p></blockquote> <p>今天出去吃饭带了两个手机, 发现续航和 S20 也差不多.</p> <p>总之除了好看之外, 好像确实没别的太大优势了.</p> <p>另外 cover screen 可以启动任意 APP, 比如说&hellip;</p> <p>我可以在这里看健康码:</p> <p> <p class="md__image"> <img src='./assets/cover-screen-health-code.jpg' alt="Health Code" /> </p> </p> <p>我可以在这里看 youtube:</p> <p> <p class="md__image"> <img src='./assets/cover-screen-youtube.jpg' alt="Youtube" /> </p> </p> <p>我可以在这里刷 twitter:</p> <p> <p class="md__image"> <img src='./assets/cover-screen-twitter.jpg' alt="Twitter" /> </p> </p> <p>我可以在这里打音游:</p> <p> <p class="md__image"> <img src='./assets/cytus.jpg' alt="Cytus" /> </p> </p> <blockquote> <p>还有视频版本的: <a href="https://mobile.twitter.com/strrlthedev/status/1563880450204266496">https://mobile.twitter.com/strrlthedev/status/1563880450204266496</a></p></blockquote> <p>Cytus 2 (还有 Steam Link, PS Remote Play)竟然还在 GoodLocks 这个应用的 Cover Screen Suggested Application 里.. 开发团队你认真的吗.</p> <p> <p class="md__image"> <img src='./assets/cover-screen-suggested-apps.jpg' alt="suggested applications" /> </p> </p> <p>这一小块屏幕, 拿来养宠物非常合适. API 是开放的, 简单搜了下貌似有人已经在 cover screen 上做其他事情了, 感觉可以玩玩! <a href="https://github.com/CarudiBu/SubUI-browser/">https://github.com/CarudiBu/SubUI-browser/</a></p> <h3 id="发现自己日记里的记录完全想不起来了">发现自己日记里的记录完全想不起来了</h3> <p>发现记录事情的时候, 还是得记录得详细一些. 比如说这一条, 我就完全不记得自己要做什么了.</p> <p> <p class="md__image"> <img src='./assets/what.png' alt="what" /> </p> </p> <h3 id="lycoris-recoil-是真的好看">Lycoris Recoil 是真的好看</h3> <p> <p class="md__image"> <img src='./assets/the-future.jpeg' alt="THE FUTURE" /> </p> </p> <blockquote> <p>图源: <a href="https://mobile.twitter.com/sticnarf/status/1551606274529574913/photo/1">https://mobile.twitter.com/sticnarf/status/1551606274529574913/photo/1</a></p></blockquote> <p>啊,我好了, 好得不能再好了. 贴贴突突太强了.</p> <p>meme: <a href="https://twitter.com/ArmandoValores/status/1560852344304173057">https://twitter.com/ArmandoValores/status/1560852344304173057</a></p> 2022-33: 去云南旅游 https://strrl.dev/post/weekly-report/2022/33-%E5%8E%BB%E4%BA%91%E5%8D%97%E6%97%85%E6%B8%B8/ Sun, 21 Aug 2022 14:20:02 +0800 https://strrl.dev/post/weekly-report/2022/33-%E5%8E%BB%E4%BA%91%E5%8D%97%E6%97%85%E6%B8%B8/ <p>这里又是一份周报, 时间范围是<code>2022-08-16</code>到<code>2022-08-21</code>, 会记录一些工作及生活上有意思的事情.</p> <p>此时我正在回杭州的高铁上写这篇周报.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">Nand2Tetris</h3> <p>本周没有进行 Nand2Tetris 的学习.</p> <h3 id="google-ux">Google UX</h3> <p>本周没有进行 Google UX 的学习.</p> <blockquote> <p>但是 Coursera 已经在扣第二个月的钱了.</p></blockquote> <h3 id="数组旋转">数组旋转</h3> <p>最近在 LeetCode 上刷到了这个题: <a href="https://leetcode.com/problems/rotate-image/">48. Rotate Image</a></p> <p>当时我立刻反应起来了, 这个我会, 在计算机图形学里学过, 拿个矩阵算子算一下就行了. 三维的坐标系都能算, 二维的肯定能搞定.</p> <p>然后怎么都想不起来那个算子怎么写了. ¯_(ツ)_/¯</p> <p>靠着直觉想起来是先斜对角线做翻转, 然后再上下翻转. 画了画好像确实是对的, 然后稀里糊涂写了代码糊上去了.</p> <p>我以为毕业以后不去做游戏相关的工作, 计算机图形学的知识就不会再用上了hhhhh.</p> <blockquote> <p>挖个坑, 后面补充个文章, 把正确的矩阵算子怎么推出来的补上.</p></blockquote> <h3 id="成为了-chaos-mesh-maintainer">成为了 Chaos Mesh Maintainer</h3> <p>Ref: <a href="https://github.com/chaos-mesh/chaos-mesh/pull/3512">https://github.com/chaos-mesh/chaos-mesh/pull/3512</a></p> <p>总之感谢大家额支持和认可吧, Chaos Mesh 潜力很大, 期望能够为未来云服务的稳定性带来更大的贡献.</p> <h3 id="关于打洞回家的网络优化">关于打洞回家的网络优化</h3> <p>之前一直用 zerotier 和 tailscale 打洞, 而且我的活动一般都在省内, 所以一般直连效果会比较好.</p> <p>这次到了云南, 发现跨省之间的直连质量太差了, 延迟在 350 ms 左右, 但是从阿里云的 VPS 走中转就能到 60 ms.</p> <p>但是俺不知道怎么让它(zerotier/tailscale)优先走中转, 所以很是难过.</p> <p>如果谁知道请告诉我.</p> <p>因为延迟太高了, 所以之前搭的 Wake on LAN, 还有 Nvidia Shield + Moonlight 也没用上. 没有成功地远程打游戏.</p> <p>在旅馆的时间都在写玩具和刷推了.</p> <h2 id="生活相关">生活相关</h2> <h3 id="去云南昆明玩">去云南昆明玩</h3> <p>这次去昆明玩特意没有坐飞机, 而是做高铁, 因为高铁上可以看风景和吃泡面!</p> <p>也是俺第一次吃自热米饭, 买了两种, 一种是有加热包的, 另一种是需要拿沸水泡的(并不是自热). 感觉非常神奇, 干巴米泡/煮一会就变软了, 配上自带的调料包还是非常好吃的.</p> <p>这次去昆明主要是避暑 + 回忆吧, 俺大学在昆明读的, 认识了很好的朋友, 还有位很好的老师. 这位老师在 2016 年的时候带俺们基于 docker 搭建了云南大学镜像站(虽然现在还是用 tunasync 了)和其他校内的基础设施, 也使俺最早接触到容器技术, 对俺后面的职业生涯也有很大的影响.</p> <blockquote> <p>最近了解到老师和本科同学们正在基于 Kubernetes 搭建 Self-Hosted GitPods 和 Gitlab 配合做授课实验环境. 俺也很乐意帮忙. 然后遇到的第一个问题就是选择 Offline Installation 还是配置好全局代理. 🤣 GFW 害人不浅.</p></blockquote> <p>这次去昆明之一的主要目的也是约这位老师吃饭, 同时也在线下和云南 Linux 用户组的 <a href="https://twitter.com/Houge_Langley">Houge</a> 面基了!</p> <p>Ref: <a href="https://twitter.com/Houge_Langley/status/1560258889081241602">https://twitter.com/Houge_Langley/status/1560258889081241602</a></p> <p>另外也探望了下云大, 学校依旧在严格的疫情管控中, 俺也没办法进去, 只能飞无人机进去偷拍几张照片:</p> <p><a href="https://twitter.com/strrlthedev/status/1560474377807728641">https://twitter.com/strrlthedev/status/1560474377807728641</a></p> <p><a href="https://twitter.com/strrlthedev/status/1560473324286709760">https://twitter.com/strrlthedev/status/1560473324286709760</a></p> <p>昆明处于云贵高原, 最大的特点就是显得云很低, 对于云彩的分层非常明显, 这种感觉在别处还是很少感觉得到的.</p> <p>另外再一个体验就是之前上学时候经常去的地方都木有了, 之前云南南门的南都(违章建筑)小吃街被拆了, 变回了大棚, 西门也是.</p> <p>七彩云南第壹城经常和老师一起去的那家巴西自助烤肉变成了海鲜自助, 和女朋友之前在百盛附近经常吃的大骨头小火锅也木有了.</p> <p>给朋友们买了(俺觉得是云南特产的)鲜花饼, 有空送给大家.</p> 2022-32: 摸了 https://strrl.dev/post/weekly-report/2022/32-%E6%91%B8%E4%BA%86/ Mon, 15 Aug 2022 20:26:04 +0800 https://strrl.dev/post/weekly-report/2022/32-%E6%91%B8%E4%BA%86/ <p>这里又是一份周报, 时间范围是<code>2022-08-08</code>到<code>2022-08-15</code>, 会记录一些工作及生活上有意思和没那么有意思的事情.</p> <p>这周周报很敷衍.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">Nand2Tetris</h3> <p>本周没有进行 Nand2Tetris 的学习.</p> <h3 id="google-ux">Google UX</h3> <p>本周没有进行 Google UX 的学习.</p> <h3 id="清灰">清灰</h3> <p>上次把机柜里声音最大的那台机器(索泰 zbox)暂时下掉了, 于是 NUC 就成为了声音最大的那台机器.</p> <p>进行了灰的清:</p> <p> <p class="md__image"> <img src='./assets/clean-the-nuc.jpeg' alt="Clean the NUC" /> </p> </p> <p>效果显著! 现在机柜里几乎听不见什么风扇声音了.</p> <h2 id="生活相关">生活相关</h2> <h3 id="摸了">摸了</h3> <p>上周的话, 各家聊得都到谈 offer 了. 总之是在各种纠结吧, 心情也不是很好, 也没记录啥.</p> <p> <p class="md__image"> <img src='./assets/only-one-journal.png' alt="Only One Journal" /> </p> </p> <p>然后这里面唯一的正文是:</p> <p> <p class="md__image"> <img src='./assets/in-todoist.png' alt="In todoist" /> </p> </p> <p>反正现在是想不起来了. 🤣</p> <h3 id="出去玩">出去玩</h3> <p>从明天开始就开始请年假了. 准备出去旅游. 从疫情以后, 还没出去旅游过. 很是期待.</p> 2022-31: 是七夕喔 https://strrl.dev/post/weekly-report/2022/31-%E6%98%AF%E4%B8%83%E5%A4%95%E5%96%94/ Sun, 07 Aug 2022 16:10:48 +0800 https://strrl.dev/post/weekly-report/2022/31-%E6%98%AF%E4%B8%83%E5%A4%95%E5%96%94/ <p>这里又是一份周报, 时间范围是<code>2022-08-02</code>到<code>2022-08-07</code>, 会记录一些工作及生活上有意思和没那么有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">Nand2Tetris</h3> <p>本周没有进行 Nand2Tetris 的学习.</p> <h3 id="google-ux">Google UX</h3> <p>本周没有进行 Google UX 的学习.</p> <h3 id="whatiknownstrrldev-从-logseq-迁移到-dendron">whatiknown.strrl.dev 从 logseq 迁移到 dendron</h3> <p>前文:</p> <ul> <li><a href="https://strrl.dev/post/weekly-report/2022/28-%E7%83%AD%E4%B9%8E%E7%9A%84%E6%9A%97%E9%BB%913ptr/#%E6%9C%89%E8%B6%A3%E7%9A%84%E7%AC%94%E8%AE%B0%E8%BD%AF%E4%BB%B6-dendron">https://strrl.dev/post/weekly-report/2022/28-热乎的暗黑3ptr/#有趣的笔记软件-dendron</a></li> <li><a href="https://strrl.dev/post/weekly-report/2022/29-%E5%9B%B0%E5%9B%B0%E5%9B%B0/#%E5%8D%9A%E5%AE%A2%E4%BB%8E-gtihub-pages--cloudflare-proxy-%E8%BF%81%E7%A7%BB%E5%88%B0-cloudflare-pages">https://strrl.dev/post/weekly-report/2022/29-困困困/#博客从-gtihub-pages--cloudflare-proxy-迁移到-cloudflare-pages</a></li> </ul> <p>相对于 dendron, typora 这种所见即所得的 Markdown 编辑器, 我更喜欢编辑 &ldquo;Raw Markdown&rdquo; + 预览的方式进行记录.</p> <blockquote> <p>但是折腾的时候也注意到了, dendron 真的还在比较早期. 生成的 static 站优化也不是很好, lighthouse performance 分数比较低. 而且文档说得其实也云里雾里的.</p></blockquote> <p>Cloudflare Pages 自带 CI/CD, 只需要配置下:</p> <ul> <li>命令 <code>npm install @dendronhq/dendron-cli@latest &amp;&amp; npx dendron publish export</code></li> <li>输出目录 <code>.next/out</code></li> </ul> <p>就配置好了!</p> <blockquote> <p>不需要写 GitHub Action Workflow YAML, 好耶!</p></blockquote> <p>目前这个站 <a href="https://whatiknown.strrl.dev">https://whatiknown.strrl.dev</a> 也还在迁移中, 后续内容会再慢慢搬运(并重新排版)上去的.</p> <h3 id="叠-巨大喷流-单线多拨叠上行">叠! 巨大喷流! 单线多拨叠上行</h3> <p>之前和同事传大文件, 再次被家里的 30Mbps 上传恶心到了.</p> <p>上网搜了下, 貌似电信曾经有一个 50 元每月的上行提速包可以提到 200Mbps, 但是现在也办理不了了.</p> <p>而且电话咨询了 10000, 目前也没有其他方式可以提高上行.</p> <p>那就只能试着单线多拨了.</p> <p>单线多拨的原理比较简单:</p> <ul> <li>光猫改桥接</li> <li>路由器使用 macvlan 将一个 wan 虚拟成多个 wan</li> <li>使用 mwan3 做 load balancing</li> </ul> <blockquote> <p>学好计网是真的有用啊, 在此之前 macvlan 只在学校机房(做虚拟机)和上家公司 IDC 机房(docker network)里见过.</p></blockquote> <p>简单介绍下 mwan3, 其实就是一堆 iptables mangle 表的规则 + ip routing table policy + 多张路由表:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Chain mwan3_policy_load_balance (1 references) </span></span><span class="line"><span class="cl">target prot opt source destination </span></span><span class="line"><span class="cl">MARK all -- 0.0.0.0/0 0.0.0.0/0 mark match 0x0/0x3f00 statistic mode random probability 0.25000000000 /* pppoe4 1 4 */ MARK xset 0x400/0x3f00 </span></span><span class="line"><span class="cl">MARK all -- 0.0.0.0/0 0.0.0.0/0 mark match 0x0/0x3f00 statistic mode random probability 0.33300000010 /* pppoe3 1 3 */ MARK xset 0x300/0x3f00 </span></span><span class="line"><span class="cl">MARK all -- 0.0.0.0/0 0.0.0.0/0 mark match 0x0/0x3f00 statistic mode random probability 0.50000000000 /* pppoe2 1 2 */ MARK xset 0x200/0x3f00 </span></span><span class="line"><span class="cl">MARK all -- 0.0.0.0/0 0.0.0.0/0 mark match 0x0/0x3f00 /* pppoe1 1 1 */ MARK xset 0x100/0x3f00 </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">root@OpenWrt:~# ip rule list </span></span><span class="line"><span class="cl">0: from all lookup local </span></span><span class="line"><span class="cl">1001: from all iif pppoe-pppoe1 lookup 1 </span></span><span class="line"><span class="cl">1002: from all iif pppoe-pppoe2 lookup 2 </span></span><span class="line"><span class="cl">1003: from all iif pppoe-pppoe3 lookup 3 </span></span><span class="line"><span class="cl">1004: from all iif pppoe-pppoe4 lookup 4 </span></span><span class="line"><span class="cl">2001: from all fwmark 0x100/0x3f00 lookup 1 </span></span><span class="line"><span class="cl">2002: from all fwmark 0x200/0x3f00 lookup 2 </span></span><span class="line"><span class="cl">2003: from all fwmark 0x300/0x3f00 lookup 3 </span></span><span class="line"><span class="cl">2004: from all fwmark 0x400/0x3f00 lookup 4 </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">root@OpenWrt:~# ip route list table 1 </span></span><span class="line"><span class="cl">default via x.x.x.x dev pppoe-pppoe1 proto static metric 10 </span></span><span class="line"><span class="cl">10.80.0.0/12 via 192.168.1.203 dev br-lan proto static </span></span><span class="line"><span class="cl">x.x.x.x dev pppoe-pppoe1 proto kernel scope link src x.x.x.x </span></span><span class="line"><span class="cl">192.168.1.0/24 dev br-lan proto kernel scope link src 192.168.1.1 </span></span><span class="line"><span class="cl">root@OpenWrt:~# ip route list table 2 </span></span><span class="line"><span class="cl">default via x.x.x.x dev pppoe-pppoe2 proto static metric 20 </span></span><span class="line"><span class="cl">10.80.0.0/12 via 192.168.1.203 dev br-lan proto static </span></span><span class="line"><span class="cl">x.x.x.x dev pppoe-pppoe2 proto kernel scope link src x.x.x.x </span></span><span class="line"><span class="cl">192.168.1.0/24 dev br-lan proto kernel scope link src 192.168.1.1 </span></span></code></pre></td></tr></table> </div> </div><p>四拨以后将上行差不多叠到了 100Mbps, 先这么用吧.</p> <p> <p class="md__image"> <img src='./assets/upload.png' alt="Upload" /> </p> </p> <h3 id="绝妙的主意-ourcloud">绝妙的主意: OurCloud</h3> <p>上下文:</p> <ul> <li><a href="https://twitter.com/strrlthedev/status/1555495072103206912">https://twitter.com/strrlthedev/status/1555495072103206912</a></li> <li><a href="https://twitter.com/strrlthedev/status/1555480588026388480">https://twitter.com/strrlthedev/status/1555480588026388480</a></li> </ul> <p>期望是能够将自己的设备贡献出来, 让大家使用, 类似于 P2P 的精神. 和 BONIC Network 的区别是, 任何人都可以将自己想执行的 workload 跑在这个池子里.</p> <p>参考 BT/PT 的设计, 现在目前想到的问题是:</p> <ul> <li>如何度量 CPU 时间</li> <li>如何防止作弊</li> </ul> <p>相信第一个问题已经有成熟的方案了, 比如说 AWS 的按量付费.</p> <p>但是第二个问题比较难顶, 暂时还没有什么高效的思路.</p> <h3 id="双显示器调教">双显示器调教</h3> <p>俺现在是两台显示器上下配置:</p> <ul> <li>DELL U2718 HDMI 在上面</li> <li>DELL U2720 DP 在下面</li> </ul> <p> <p class="md__image"> <img src='./assets/displays.png' alt="displays" /> </p> </p> <p>有好久时间了, 感觉两块屏幕的颜色也差太多了. 而且上面那块屏幕明显太亮了, 饱和度堪忧:</p> <p> <p class="md__image"> <img src='./assets/before.jpg' alt="before" /> </p> </p> <p>仔细 profile 下, 发现 HDMI 走的是 YPbPr, 这显然不太对劲. 搜索了下, 这好似是 amdgpu 驱动的问题:</p> <ul> <li>使用 HDMI 连接显示器, 当 amdgpu 驱动识别到显示器支持 YPbPr 时, 优先使用 YPbPr 而不是 RGB.</li> </ul> <p>Windows 下的 amdgpu 驱动有 UI 可以进行配置, 但是 linux 下就没有这么好用的东西了.</p> <p>采取的解决方案是参考<a href="https://gist.github.com/RLovelett/171c374be1ad4f14eb22fe4e271b7eeb">这个 gist</a>, patch 了 edid 来骗过 amdgpu 驱动, 说&quot;咱不支持 YPbPr&quot;.</p> <p>在调整(并开启 Smart HDR)后, 显示明显变柔和了, 但是颜色依旧统一:</p> <p> <p class="md__image"> <img src='./assets/after.jpg' alt="after" /> </p> </p> <h3 id="使用-cloudflare-暴露一些服务并配置">使用 Cloudflare 暴露一些服务并配置</h3> <blockquote> <p>起因是看到了这么一个推, 推荐了一个视频, 非常有意思: <a href="https://twitter.com/yurusan_p/status/1555232890023182338">https://twitter.com/yurusan_p/status/1555232890023182338</a>.</p></blockquote> <p>YouTube 接着推荐了一个这场大会的另外一个视频, 也非常有意思: <a href="https://www.youtube.com/watch?v=hMtu7vV_HmY">https://www.youtube.com/watch?v=hMtu7vV_HmY</a>.</p> <p>讲的是一些暴露在公网的, 没有认证/加密的 VNC / RDP 服务里到底暴露了什么, 挖掘的成果十分有趣:</p> <ul> <li>炼钢的系统</li> <li>太阳能系统</li> <li>自来水供水系统</li> <li>空调系统</li> <li>煤矿系统</li> <li>&hellip;</li> </ul> <p>&ldquo;What could possibly go wrong!&rdquo;</p> <p> <p class="md__image"> <img src='./assets/liquid-steel.png' alt="What could possibly go wrong!" /> </p> </p> <p>总之, 抱着&quot;我反正没有将这个 IP / 域名告诉过其他人, 没有人会发现的, 能出啥问题&quot;这种思路是非常危险的.</p> <p>所以我将我上两天暴露的 <a href="https://prow.strrl.cloud">https://prow.strrl.cloud</a> 使用 Cloudflare Zero Trust 配置了下, 需要 Auth 才能访问.</p> <p>我使用 GitHub 作为 &ldquo;Identity Provider&rdquo;(借用一下这个概念), 并且用 GitHub Organization + Teams 实现了类似 RBAC 的效果:</p> <ul> <li>GitHub Account 是 User</li> <li>Teams 是 Role</li> <li>使用加入了特定 Teams 的 GitHub Account 登陆后才能访问这个服务</li> </ul> <p>体验非常好, 只是 GitHub OAuth2 App 的 ICON 还没有画, 后面再改吧.</p> <p>还有一个插曲, 期间 Cloudflare 提示来自 bot 的流量增加了 60%, 并推荐我把 &ldquo;Bot Fight Mode&rdquo; 打开.</p> <p>我尝试打开了, 结果我自己上不去了:</p> <p> <p class="md__image"> <img src='./assets/blog-403.png' alt="blog 403" /> </p> </p> <p>然后又弱弱的给他关了. 🤣</p> <h2 id="生活相关">生活相关</h2> <h3 id="跑步机上看视频">跑步机上看视频</h3> <p>最近发现在跑步机上学东西效果还是差劲了点, 很多时候想记录东西都没有办法记下来.</p> <p>所以现在 fallback 到了另一个方案: 看各种大会视频的录播. 比如说最近在看 KUBECON EU 2022!</p> <p>而且一般一个 talk 的时间在 40 - 50 分钟左右, 1.5 倍速的话, 半小时有氧可以看 1 个, 一个小时有氧可以看 2 个. 非常舒服了!</p> <p>而且一般来说能听得懂的 talk 中遇到有趣的点子, 不会过于离开自己的知识范围, 用手机迅速的记录下来, 也还行.</p> <h3 id="饵丝-吃过都说好">饵丝: 吃过都说好</h3> <p>最近在两个地方都很巧地听到/聊到了饵丝:</p> <ul> <li>Podcast 世界莫名其妙物语, EP96 莫名其妙酒店大赏, 在 25:40 左右, 见师提到了饵丝口感十分滴好, 浇头也很丰富, 给出了极高的评价!</li> <li>HZLUG, 大家在讨论旅游和昆明的时候, 一位朋友提到了饵丝的肉臊子非常的好吃!</li> </ul> <blockquote> <p>《世界莫名其妙物语》终于上 Spotify 了! 小宇宙再见了您嘞!</p></blockquote> <p>之前在云南大学上学的时候也经常和女朋友一起吃 2.2 一碗的饵丝做早饭, 好吃的一批.</p> <p>上段时间, 女朋友也在网上买了一些饵丝自己煮着吃, 味道虽说比较还原, 但是臊子还是没啥料.</p> <blockquote> <p>应该过不了多久, 俺们就会有机会去昆明玩耍了, 到时候去吃饵丝和米线! 希望疫情不要再变严重.</p></blockquote> <h3 id="推荐几款类似的-好玩的-route-lite-游戏">推荐几款类似的, 好玩的 Route Lite 游戏</h3> <p>在挺久之前, 俺就推荐了 &ldquo;Vampire Survivors&rdquo; 这款游戏, 后来还有一款较为类似的游戏: &ldquo;黎明前 20 分钟&rdquo;</p> <ul> <li><a href="https://strrl.dev/post/weekly-report/2022/08-%E5%8F%AA%E6%98%AF%E5%BF%99%E7%A2%8C%E7%9A%84%E4%B8%80%E5%91%A8/#%E6%B8%B8%E6%88%8F-vampire-survivors">https://strrl.dev/post/weekly-report/2022/08-只是忙碌的一周/#游戏-vampire-survivors</a></li> <li><a href="https://strrl.dev/post/weekly-report/2022/23-%E4%B8%8D%E8%A7%A3%E5%BF%99%E7%A2%8C%E5%8F%8D%E6%80%9D/#%E6%8E%A8%E8%8D%90%E6%B8%B8%E6%88%8F-%E9%BB%8E%E6%98%8E%E5%89%8D-20-%E5%88%86%E9%92%9F">https://strrl.dev/post/weekly-report/2022/23-不解忙碌反思/#推荐游戏-黎明前-20-分钟</a></li> </ul> <p>他们的主要特征是, 不需要太多操作进行攻击, 或者几乎不需要操作, 技能/攻击自动释放, 玩家更多关注的是走位和朝向.</p> <p>而这周打开 Steam 推荐队列, 感觉一下子出现了好多类似的游戏:</p> <ul> <li><a href="https://store.steampowered.com/app/2066020/Soulstone_Survivors/">SoulStone Survivors</a></li> <li><a href="https://store.steampowered.com/app/1059980/Just_King/">Just King</a></li> <li><a href="https://store.steampowered.com/app/1929870/Nomad_Survival/">Nomad Survival</a></li> </ul> <p>都比较有趣!!!</p> <p>周六晚上玩了挺长一段时间 SoulStone Survivors, 在好玩的同时, 给我的感觉在就是: 我们也能做, 跟女朋友大学毕设水平差不多, 我上我也行!</p> <blockquote> <p>啊! 好想做游戏啊啊啊!</p></blockquote> <h3 id="七夕喔">七夕喔</h3> <p>在七夕, 我们作为老夫老妻在中午自己烤了披萨庆祝, 互相送了礼物. 🥰</p> <p>新晋算力:</p> <p> <p class="md__image"> <img src='./assets/present-1.jpg' alt="Present 1" /> </p> </p> <p>烧:</p> <p> <p class="md__image"> <img src='./assets/present-2.jpg' alt="Present 2" /> </p> </p> 2022-30: 普通的周报 之二 https://strrl.dev/post/weekly-report/2022/30-%E6%99%AE%E9%80%9A%E7%9A%84%E5%91%A8%E6%8A%A5-%E4%B9%8B%E4%BA%8C/ Mon, 01 Aug 2022 21:00:05 +0800 https://strrl.dev/post/weekly-report/2022/30-%E6%99%AE%E9%80%9A%E7%9A%84%E5%91%A8%E6%8A%A5-%E4%B9%8B%E4%BA%8C/ <p>这里又是一份周报, 时间范围是<code>2022-07-25</code>到<code>2022-08-01</code>, 会记录一些工作及生活上有意思和没那么有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">Nand2Tetris</h3> <p>本周又没有进行 Nand2Tetris 的学习.</p> <h3 id="google-ux">Google UX</h3> <p>最近依旧是着重学习方法论相关的东西.</p> <p>看了太多资料和视频发现记不太住, 需要用的时候还是需要再回顾一下. 需要好好的理一下笔记了.</p> <h3 id="有趣的项目-kubebrain">有趣的项目: Kubebrain</h3> <p>Kubernetes 堪称是云时代的 OS 了, 众多的应用运行在 Kubernetes 上, 大家即使不是运维相关领域的同学, 也大概听过这个项目的大名.</p> <p>然而这个项目有一个比较重的问题, 它目前强依赖了 <a href="https://github.com/etcd-io/etcd">etcd</a>. 而 etcd 的维护状态也<a href="https://groups.google.com/a/kubernetes.io/g/steering/c/e-O-tVSCJOk">不是很乐观</a>.</p> <p>社区中有项目做出过尝试, 比如说:</p> <ul> <li>Consul 的方案: <a href="https://github.com/kubernetes/kubernetes/pull/31622">https://github.com/kubernetes/kubernetes/pull/31622</a></li> <li>DynamoDB 的方案: <a href="https://github.com/kubernetes/kubernetes/issues/53162">https://github.com/kubernetes/kubernetes/issues/53162</a></li> <li>CRDB 的方案: <a href="https://docs.google.com/document/d/1ziZ7Tye7xYeZ1v7_RH181vmA5EWaAOZtK7shtpQCER4/edit#heading=h.gf21pnrv3do1">https://docs.google.com/document/d/1ziZ7Tye7xYeZ1v7_RH181vmA5EWaAOZtK7shtpQCER4/edit#heading=h.gf21pnrv3do1</a></li> <li>一些其他相关的讨论: <a href="https://groups.google.com/g/kubernetes-sig-api-machinery/c/-FhpiVTX7YE/m/FhjwUeaXFQAJ">https://groups.google.com/g/kubernetes-sig-api-machinery/c/-FhpiVTX7YE/m/FhjwUeaXFQAJ</a></li> </ul> <p>总之目前的状态是, kubernetes 还无法原生使用除 etcd 之外的组件管理状态.</p> <blockquote> <p>TiKV 作为 CNCF 毕业级别项目, 如果能作为 etcd alternative 支持 Kubernetes, 听上去&quot;名正言顺&quot;.</p></blockquote> <p>不过看上去数据库的开发者和 Kubernetes 的开发者明显不是同一波人, 这个事情始终没有没有人来正儿八经做.</p> <p>直到 <a href="https://github.com/kubewharf/kubebrain">kubewharf/kubebrain</a> 的出现!</p> <blockquote> <p>其实去年在杭州某场线下的分享里, 字节的同学已经提及过 <a href="https://github.com/kubewharf/kubegateway">kubewharf/kubegateway</a> 还有其他相关的项目了.</p></blockquote> <p>Kubebrain 目前支持将 TiKV 作为存储后端, 并且在没有调优的情况下, 吞吐量能够达到 etcd 的 2 - 2.5 倍. 可喜可贺!</p> <blockquote> <p>Reference: <a href="https://github.com/kubewharf/kubebrain/blob/main/docs/benchmark.md">https://github.com/kubewharf/kubebrain/blob/main/docs/benchmark.md</a></p></blockquote> <p>目前俺对这个项目兴趣挺大的, 在 issue 中提了些问题, 也顺便蹭了两个 PR:</p> <blockquote> <p>毕竟上次 Hackathon 想做没做出来&hellip;</p></blockquote> <ul> <li><a href="https://github.com/kubewharf/kubebrain/pull/5">chore: remove the dependency with k8s.io/kubernetes</a></li> <li><a href="https://github.com/kubewharf/kubebrain/pull/7">fix: the link for performance result screenshots</a></li> <li><a href="https://github.com/kubewharf/kubebrain/issues/8">Question: A little confusion about the stateless, availability and scalability.</a></li> <li><a href="https://github.com/kubewharf/kubebrain/issues/11">Question: more other backends support, and native watch support</a></li> </ul> <h3 id="chaos-mesh-发布了-230">Chaos Mesh 发布了 2.3.0</h3> <p>总之是发布了!</p> <p><a href="https://github.com/chaos-mesh/chaos-mesh/releases/tag/v2.3.0">https://github.com/chaos-mesh/chaos-mesh/releases/tag/v2.3.0</a></p> <p>自 Release Cycle 定下以来第一次还算是按时的发布.</p> <p>期待 2 个月后的 2.4.0!</p> <h3 id="云时代的开发者效率服务">云时代的开发者效率服务</h3> <p>最近有越来越多的人知道俺在看机会了, 也有越来越多的人咨询我对 &ldquo;XXXX&rdquo; 是否感兴趣.</p> <p>还真别说, 我还真发现了一个挺有意思的领域: 云时代的开发者效率服务.</p> <p>联系俺的是一位字节跳动的大佬, 向俺解释了他们目前阶段做的事情和未来要做的事情:</p> <ul> <li>目前做的是 Cloud IDE 相关的事, 效果比较不错;</li> <li>未来会考虑在云的架构下, 作为公司雇员, 如何最大化开发的效率. 做的方便包括但不限于: 开发工具, CI/CD 服务, 服务架构设计, 业务/服务框架, 语言等</li> </ul> <p>提到了一些类似的服务/工具:</p> <ul> <li><a href="https://tilt.dev/">https://tilt.dev/</a></li> <li><a href="https://nocalhost.dev/">https://nocalhost.dev/</a></li> <li><a href="https://heighliner.dev/">https://heighliner.dev/</a></li> <li><a href="https://www.pulumi.com/product/">https://www.pulumi.com/product/</a></li> </ul> <p>最后想了想还是婉拒了. 虽然字节很大, 如果能做出好的工具而且能够在公司内推行, 效率的提升一定是显著的. 但是我还是不喜欢将自己做的事情和一个公司紧紧绑在一起, 我一旦离开这家公司, 那我做的事情就也跟着无了.</p> <h2 id="生活相关">生活相关</h2> <h3 id="和-xuanwo-哥哥还有推友们线上聊天">和 Xuanwo 哥哥还有推友们线上聊天</h3> <p>前文: <a href="https://strrl.dev/post/weekly-report/2022/28-%E7%83%AD%E4%B9%8E%E7%9A%84%E6%9A%97%E9%BB%913ptr/#%E4%B8%8E-xuanwo-%E5%93%A5%E5%93%A5%E5%B0%9D%E8%AF%95%E5%9C%A8-gathertown-%E4%B8%8A%E8%BF%9B%E8%A1%8C%E5%85%83%E5%AE%87%E5%AE%99-social">https://strrl.dev/post/weekly-report/2022/28-%E7%83%AD%E4%B9%8E%E7%9A%84%E6%9A%97%E9%BB%913ptr/#%E4%B8%8E-xuanwo-%E5%93%A5%E5%93%A5%E5%B0%9D%E8%AF%95%E5%9C%A8-gathertown-%E4%B8%8A%E8%BF%9B%E8%A1%8C%E5%85%83%E5%AE%87%E5%AE%99-social</a></p> <p>Ref: <a href="https://twitter.com/strrlthedev/status/1553657804329607169">https://twitter.com/strrlthedev/status/1553657804329607169</a></p> <p>成功地在 gather.town 上进行了一波元宇宙 social! 不过免费版确实在串流的音质和时延上做的不太好, 中间大家发现了延迟高, 容易掉线等情况.</p> <p>聊了一些商业公司中的开源项目, 个人职业发展相关的一些话题!</p> <p>我对 &ldquo;不要把个人的人生目标和商业公司绑定&quot;这个事情有了更深一步的认识. 作为打工人, 工作中尽职尽责, 公司与个人各取所需, 向着自己的理想努力迈进才是正确的方向.</p> <p>这次活动人数最多时有同时 12 人在线, 抓拍了一张照片:</p> <p> <p class="md__image"> <img src='./assets/gather.jpeg' alt="gather photo" /> </p> </p> <h3 id="散步路上-看到了一些儿童用袋子捉知了-san-掉没了">散步路上, 看到了一些儿童用袋子捉知了, san 掉没了</h3> <p>周六本来开开心心去西溪那边散步, 然后遇到了让我 san 值清零的事情:</p> <p>有一些孩子们用网袋抓了好多知了, 知了还在袋子里叫得非常大声..</p> <p>差不多是这个效果:</p> <p> <p class="md__image"> <img src='./assets/zhiliao.jpg' alt="知了" /> </p> </p> <p>SAN 瞬间清零了. 😇</p> <h3 id="航拍-炸机及维修置换">航拍, 炸机及维修置换</h3> <p>周五想着去公司的机会应该不会太多了, 想着去飞飞无人机, 拍一拍附近的写字楼和风景.</p> <p>当然也确实拍了一些写字楼和黄龙体育场的照片:</p> <p> <p class="md__image"> <img src='./assets/photo_2022-08-01_22-52-15.jpg' alt="黄龙体育馆" /> </p> </p> <p> <p class="md__image"> <img src='./assets/photo_2022-08-01_22-52-20.jpg' alt="黄龙万科" /> </p> </p> <p>但是在回家下降过程中炸机了.</p> <blockquote> <p>终于迎来了首炸.</p></blockquote> <p>撞上了 G 幢的写字楼然一直贴墙滑/摔了下来. 差不多是这个样子:</p> <p> <p class="md__image"> <img src='./assets/drone-crash.jpg' alt="crash" /> </p> </p> <blockquote> <p>好像是支付宝的办公区, 不知道有没有人受到惊吓.</p></blockquote> <p>然后就坏了!</p> <p> <p class="md__image"> <img src='./assets/broken-drone.jpg' alt="战损" /> </p> </p> <blockquote> <p>分享了这件事情以后, 也有盆友门分享了他们的炸机照, 有晚上炸鸡的, 还有掉水里的&hellip;</p></blockquote> <p>因为买了 DJI Care, 所以维修/置换还是挺方便的, 周五预约了周日来取件, 取件的同时也发出了新件. 周一就收到了新机器! 好耶!</p> <p>Ref: <a href="https://twitter.com/strrlthedev/status/1553911614952181762?s=20&amp;t=qlVLvSoReshDripzFOQlcA">https://twitter.com/strrlthedev/status/1553911614952181762?s=20&amp;t=qlVLvSoReshDripzFOQlcA</a></p> <h3 id="健身--减肥一个月左右的效果">健身 / 减肥一个月左右的效果</h3> <p>效果还是比较明显的! :)</p> <p> <p class="md__image"> <img src='./assets/lose-weight.jpg' alt="lose weight" /> </p> </p> <h3 id="我想玩打拳僧哇哇哇">我想玩打拳僧哇哇哇</h3> <p>现在的时间是 22:30, 估计今天又是没有时间玩暗黑三测试服了.</p> <p>武僧在这个赛季有一项有趣的天使坩埚特效: 百烈拳只会触发第二段. 而这正是一段攻击频率特别高的特效.</p> <p>在翔龙的 100% 额外攻速的加持下, 理论上能够到很高的攻速.</p> <blockquote> <p>暗黑 3 攻速还要算档位, 目前还没算过. 总之就是很快.</p></blockquote> <blockquote> <p>疾风骤雨!!!</p></blockquote> <p>另外高攻速就有可能能带重击宝石(银河织星者之泪)来冲层!</p> <blockquote> <p>怀念圣套死灵逛街流了.</p></blockquote> <p>这周四 PTR 就要关服了, 一定得抽时间去试一试!</p> 2022-29: 困困困 https://strrl.dev/post/weekly-report/2022/29-%E5%9B%B0%E5%9B%B0%E5%9B%B0/ Sun, 24 Jul 2022 15:37:22 +0800 https://strrl.dev/post/weekly-report/2022/29-%E5%9B%B0%E5%9B%B0%E5%9B%B0/ <p>这里又是一份周报, 时间范围是<code>2022-07-18</code>到<code>2022-07-24</code>, 会记录一些工作及生活上有意思和没那么有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">Nand2Tetris</h3> <p>本周没有进行 Nand2Tetris 的学习. 🤣</p> <blockquote> <p>这周跑步的时候把上段时间积攒的没听的播客听了一遍~</p></blockquote> <h3 id="google-ux">Google UX</h3> <p>之前一段时间提到过, Google UX 课程中的很多方法论是可以应用到别的领域的.</p> <p>最近一段时间正在准备进行一些客户访谈, 了解下社区用户对 Chaos Mesh 的使用现状以及预期.</p> <h3 id="好玩的点子-github-profile-badges">好玩的点子: GitHub Profile Badges</h3> <p>之前俺在自己的 <a href="https://github.com/STRRL">GitHub Profile Page</a> 里一直使用 <a href="https://github.com/puf17640/git-badges">puf17640/git-badges</a> 这个项目中的 Visits Count Badges 这个功能.</p> <p>而大约在几周前, 这个服务后面的托管服务器出现了问题, 导致这个 badges 不可用了.</p> <p>而正好我最近对 Serverless 很感兴趣, 就尝试着使用 Cloudflare Workers + Cloudflare Workers KV 做了一个<a href="https://github.com/STRRL/serverless-github-badges">类似的实现</a>.</p> <blockquote> <p>因为是 Serverless, 所以不需要运维! 也不怎么需要担心它出故障下线! 太爽了!</p></blockquote> <p>目前已经写<del>抄</del>完前者的功能了.</p> <p>另外俺有个朋友也在做类似的事情: 把一些自己的状态, 同步展示到一个地方, 比如说: Steam 正在玩什么游戏, Spotify 正在听什么歌.</p> <p>俺也有类似的想法, 想把自己的健康数据也同步上去: 昨天睡了多少觉, 过去若干小时心跳区间是多少, 走了多少步等等.</p> <blockquote> <p>不知道有木有机会揉成一个东西.</p></blockquote> <h3 id="博客从-gtihub-pages--cloudflare-proxy-迁移到-cloudflare-pages">博客从 GtiHub Pages + Cloudflare Proxy 迁移到 Cloudflare Pages</h3> <p>俺的博客域名是 <a href="https://strrl.dev">strrl.dev</a> 嘛, 它其实是个 hugo 项目, 然后用了 GitHub Pages + Custom domain.</p> <p>后来(忘记出于什么原因)为这个域名配置了 Cloudflare 的 Proxy.</p> <p>最近遇到的问题是, strrl.dev 的解析就不再是 GitHub Pages 的 IP, 而是 Cloudflare 的 IP. 因此 GitHub Pages 的证书签不下来了.</p> <p>之前的解决方式是, 先把 Cloudflare 的 Proxy 关掉, 等 Github Pages 证书更新以后, 再打开.</p> <p>但是太折腾了, 每 3 个月就来这么一次也顶不住嘛.</p> <blockquote> <p>而且这次在操作过程中, 明显影响到了使用体验. 有几个小伙伴私信俺说博客挂了.</p></blockquote> <p>于是俺干脆直接迁到 Cloudflare Pages 上了.</p> <p>迁移过程非常顺滑, 在 Cloudflare Pages 上点击 Connect GitHub, 安装一个 GitHub App, 选择框架, 俺这里是 Hugo, 然后就完事了.</p> <p>以后不用在来手动改解析惹! 开心!</p> <h3 id="尝试使用-chrome-os-flex">尝试使用 Chrome OS Flex</h3> <p>偶然间看到了&quot;可以使老设备重新焕发生机的 Chrome OS Flex&quot; 发布了正式版!</p> <p>对于我来说, Chrome OS Flex 最大的特点在于, 它可以真正的使用 Linux 和 创建 VM. 香香!</p> <blockquote> <p>参考 <a href="https://support.google.com/chromeosflex/answer/11542901">Differences between Chrome OS Flex and Chrome OS</a></p></blockquote> <p>我把我的闲置 mbp 2018 拿出来准备试一试, 看看到底能不能&quot;重新焕发生机&quot;.</p> <blockquote> <p>有朋友要问了, 你的 mbp 不是拿去置换了嘛? 很惭愧&hellip; 没有, 本来是选了置换的. 结果下单后发现键盘布局选错了, 又重新下了一单, 第二单忘记选置换了. 结果就吃灰了.</p></blockquote> <p>跟着 <a href="https://support.google.com/chromeosflex/answer/11552529">Chrome OS Flex installation guide</a> 走便可以安装 Chrome OS Flex 了.</p> <p>引导以后, 发现 mbp 自带的触摸板和键盘木有反应, 于是拿 Hub 来接上了 USB 键鼠.</p> <p>选择试用 Chrome OS Flex 后, 进行了一系列的正常的配置, 时区啊, 语言啊什么的. 然后到了配置 Google Assistant, 让我说 &ldquo;OK, Google&rdquo;, 说了好几次都没有反应, 意识到麦克风应该没有适配. 于是选择了跳过.</p> <p>然后配置网络, wifi 是用不了的.. 我接了根网线到 Hub 上, 继续配置.</p> <p>配置好 Google 帐号后, 进入了桌面环境.</p> <p>然后不知道从哪里把我的 Chrome Tab 同步过来了, 打开了一堆网页. 其中有一个是 Youtube 视频, 播放时倒是不卡, 但是木有声音. 🥲</p> <p>最后想尝试一下 Linux development environment, 结果告诉俺需要 3GB 以上空间才能安装, Live USB 模式下装不上.</p> <p>好, 那我装!</p> <p>重启电脑这次不选择试用而是直接点了安装, 结果告诉我安装失败.</p> <p>(而且错误日志是 js&hellip; 我看不懂了..)</p> <p>于是乎果断放弃, 选择再等等.</p> <blockquote> <p>咱也看不懂 Apple 产品的型号, 应该确实没有在 Chrome OS Flex <a href="https://support.google.com/chromeosflex/answer/11513094">Certified models list</a> 里. 再等等吧.</p></blockquote> <h2 id="生活相关">生活相关</h2> <h3 id="和朋友们烤肉">和朋友们烤肉!</h3> <p>和朋友们住的挺近的, 于是乎我们进行了一次聚众烤肉!</p> <p>从六点多烤到九点, 而且中途还在下了几阵子雨, 我们打着伞烤. 🤣</p> <p>可以说是非常的开心了!</p> <p>挑一张<del>拍太糊</del>不会暴露隐私的图片放上来:</p> <p> <p class="md__image"> <img src='./assets/bbq.jpg' alt="BBQ" /> </p> </p> <h3 id="好玩的游戏-nova-drift">好玩的游戏: Nova Drift</h3> <p>这是一款 rogue-lite 的飞行射击游戏!</p> <h3 id="最近精神状态不是很好">最近精神状态不是很好</h3> <p>最近在尝试 23:00 - 7:00 的睡觉时间, 但是总是变成 23:00 躺到床上, 然后入睡还要一段时间.</p> <p>所以精神状态不太好, 到下午就哈欠连天, 女朋友也反映我下午晚上最常说的话就是 &ldquo;困死了困死了, 不行了不行了&rdquo;.</p> <p>甚至有一次去做力量训练, 中途被教练叫停了, 说看我面色不好, 算了让我回去休息, 而且叮嘱我如果前一天没睡好就不要来做力量训练了.</p> <p>后面睡觉还是要再早点上床躺着, 才能把睡眠时间拉够一些.</p> <h3 id="俺的博客上线了友链">俺的博客上线了友链</h3> <p>诶嘿! 俺终于把<a href="https://strrl.dev/links/">友链</a>加上了!</p> <p>想加友链直接评论, 或者在其他任意渠道私信俺都可以~</p> <p>只不过现在样式有些土, 大家如果有什么花里胡哨的样式可以尽情推荐给俺!</p> Links https://strrl.dev/links/ Mon, 18 Jul 2022 22:40:11 +0800 https://strrl.dev/links/ <h2 id="strrl-的朋友们">STRRL 的朋友们!</h2> <blockquote> <p>如果有盆友觉得俺括号里加的内容不合适, 可以联系俺改掉或者删掉. 🙈</p></blockquote> <ul> <li><a href="https://blog.thgirls.yt/">Tokyo Hacker Girls, Asahi Lina and <del>Asahi</del> Cyan Nyan</a></li> <li><a href="https://homura.live/">Homura(永远17岁的男孩子!)</a></li> <li><a href="https://a-wing.top/">新一(可爱! 有趣!)</a></li> <li><a href="https://www.manjusaka.blog/">Manjusaka(Saka 哥哥!)</a></li> <li><a href="https://xuanwo.io/">Xuanwo(Xuanwo 哥哥!)</a></li> <li><a href="https://blog.mwish.me/">mwish(是个猛男!)</a></li> <li><a href="https://www.pseudoyu.com">Pseudoyu(推友; 思想深度比俺深多了! 学习学习!)</a></li> <li><a href="https://fika.ink/">Fika&rsquo;s Blog - Light up the dream.</a></li> </ul> <p> <p class="md__image"> <img src='dancing-banana.webp' alt="Dancing Banana" /> </p> </p> 2022-28: 热乎的暗黑 3 PTR https://strrl.dev/post/weekly-report/2022/28-%E7%83%AD%E4%B9%8E%E7%9A%84%E6%9A%97%E9%BB%913ptr/ Sun, 17 Jul 2022 16:02:14 +0800 https://strrl.dev/post/weekly-report/2022/28-%E7%83%AD%E4%B9%8E%E7%9A%84%E6%9A%97%E9%BB%913ptr/ <p>这里又是一份周报, 时间范围是<code>2022-07-12</code>到<code>2022-07-17</code>, 会记录一些工作及生活上有意思和没那么有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">Nand2Tetris</h3> <p>看完了 Compiler 部分的课程, 实验还没有开始做.</p> <blockquote> <p>已经,积攒了两个 unit 的实验了喂! 得做实验啊!</p></blockquote> <h3 id="有趣的笔记软件-dendron">有趣的笔记软件: dendron</h3> <p>Dendron: <a href="https://www.dendron.so/">https://www.dendron.so/</a></p> <p>我将使用 dendron 来替代 logseq 来构建我的 knowledge base.</p> <p>早在前段时间, 由于 logseq 的官方 sync 迟迟不肯出来, <a href="https://strrl.dev/post/weekly-report/2022/10-%E6%98%A5%E5%A4%A9%E6%9D%A5%E4%BA%86/#%E6%8A%98%E8%85%BE-logseq-%E5%90%8C%E6%AD%A5">我准备使用 obsidian 来代替 logseq</a>. 而在使用 Notion 记录 Journal 后, 发现体验非常的好! 于是我也没有入 obsidian.</p> <p>其实 logseq 的发布也是比较一言难尽, 它会将所有的资源打包成一个硕大的 json, 然后这一坨需要加载进去以后, 你的正文才会显示出来.</p> <p>体验不好.</p> <p>我在 happy xiao 的播客: <a href="https://happyxiao.com/happy30pod-074/">快乐三十分 074 为什么要学编程</a> 这一期中得知了 Dendron 这个工具.</p> <p>Dendron 是一个 VSCode 的插件, 同样拥有双向链接与 graph view (但是 publish 时没有 graph view)的功能. 而且它的目录结构以 <code>layer-1.layer-2.layer-3</code>这种形式来决定. 也就是说, 文件名中以 dot 的分割的不同部分就是目录结构.</p> <p>另外 dendron-cli 中的 publish 命令, 可以将你的知识后花园非常方便的发布为一个基于 Next.js 的静态站点, 自带目录结构与搜索功能. 比如 <a href="https://wiki.dendron.so/">Dendron 的 Wiki</a> 就是用 dendron 自己发布的.</p> <blockquote> <p>不过这个工具处于早期嘛, 有 bug 是难免的事情. 比如说 <a href="https://blog.dendron.so/">Dendron 的 Blog</a> 因为 Next.js 的某些问题(不知道是缺陷还是始终姿势不正确), 在浏览器中不能正常显示.</p></blockquote> <p>其实我本身比较喜欢 VSCode 编辑 RAW Markdown + 右侧 Preview 的形式来写东西, 不太喜欢 Notion/logseq 这种立即式的编辑方式. 认识 Dendron 以后, 觉得深陷其中无法自拔. 🤩</p> <p>我决定在接下来的 2 - 3 周内慢慢将我的 kb 从 logseq 迁移到 dendron, 发布, 然后替换 <a href="https://whatiknown.strrl.dev">https://whatiknown.strrl.dev</a>.</p> <h3 id="更新-homelab-硬件">更新 Homelab 硬件</h3> <p>最近杭州迎来了连续几天 40+ 摄氏度的炎热天气, 我的 homelab 散热自然开始慢慢顶不住了, 噪音开始从间歇性聒噪变为了持续性聒噪.</p> <p>终于我在这周下架了一台主要的噪音源: 运行 Jellyfin 的索泰 zbox. 下架以后, 立刻清净了许多.</p> <p>这个设备是我在咸鱼上 1500 淘的准系统, 把我大三时的主力笔记本的值钱元件都迁了上去:</p> <ul> <li>i7-7700K</li> <li>MXM 接口的 GTX 1070</li> <li>2 x 16G 内存</li> <li>若干 SSD 与 HDD</li> </ul> <p>当时它的<a href="https://twitter.com/strrlthedev/status/1449825559471480836">散热模块就是被我爆改了</a>, 当时就感觉心虚的一批, 果然到了夏天开始, 散热出现了大问题.</p> <p>这也是我 Homelab 中 唯一有独显, 方便做显卡直通的机器. 因此它的主要负载之一是作为 Jellyfin 的机器, 看流媒体时进行硬件解码.</p> <p>另外它也是我的 homelab 中 Kubernetes Cluster 的 Control Plane 的节点之一, 所以下架以后我的 Kubernetes Cluster 一直是 2 master 节点跑着, 目前也没啥问题! 👍</p> <p> <p class="md__image"> <img src='./assets/degraded-kubernetes-control-plane.png' alt="Degraded Kubernetes Control Plane" /> </p> </p> <p>后续我准备为 Homelab 新增两台机器,</p> <ul> <li>一台 ATX 塔式的静音机箱, 弄点噪音小一些的水冷.</li> <li>一台/若干 ARM 设备, 被动散热.</li> </ul> <blockquote> <p>看了下 Turing Pi, 咸鱼上有卖, 价格 1400 左右. 但是 Pi Computing Module 是真的贵啊, 一块要 1000 左右.</p></blockquote> <h3 id="controller-runtime-的-pr-终于有人看了">Controller Runtime 的 PR 终于有人看了</h3> <p>在较早之前, 为 Controller Runtime 提了一个修复 <code>logr.Logger.WithValue()</code> 方法时, 不能正确将 Kubernetes <code>runtime.Object</code> 使用 <code>kubeAwareEncoder</code> 进行解码的 PR:</p> <ul> <li>Issue: <a href="https://github.com/kubernetes-sigs/controller-runtime/issues/1290">https://github.com/kubernetes-sigs/controller-runtime/issues/1290</a></li> <li>PR: <a href="https://github.com/kubernetes-sigs/controller-runtime/pull/1883">https://github.com/kubernetes-sigs/controller-runtime/pull/1883</a></li> </ul> <p>在两个月后终于有人 Review 了! (狗头)</p> <p>希望它能顺利合进去.</p> <h3 id="寻找新的机会">寻找新的机会</h3> <p>正如大家所知的, 最近的就业形式不是很好. 但我也在尽自己的努力, 希望找到自己感兴趣和值得付出方向, 以及聊得来/合作愉快的新合作伙伴. 🥰</p> <h2 id="生活相关">生活相关</h2> <h3 id="暗黑-3-274-ptr-开服啦">暗黑 3 2.7.4 PTR 开服啦</h3> <blockquote> <p>太开心了! 这次终于吃上了热乎的 BUG!</p></blockquote> <p>暗黑 3 2.7.4 PTR 在这周四开服了! 这是暴雪被微软收购以后, 迎来的第一个赛季! 改动可谓是诚意满满!</p> <p>关于更新的具体细节内容俺这里就不提了, 大家可以去哔哩哔哩搜索 &ldquo;秋仲琉璃子不语&rdquo; 这位 up, 或者通过官方帖子和凯恩之角的帖子来了解好玩的细节.</p> <p>为什么要玩 PTR 呢?</p> <p>首先, PTR 的游戏模式中有一个特殊的商人, 可以特殊商人处使用 50 血岩直接购买:</p> <ul> <li>职业套装物品</li> <li>传奇宝石</li> <li>其他散件传奇物品: 主副手武器, 防具等</li> <li>随从装备</li> <li>大量五章材料, 黄蓝白材料, 硫磺</li> <li>皇家宝石, 打孔器等等</li> </ul> <p>也就是说, 一旦在 PTR 中开荒到了 70, 你将会立刻毕业. 而且转型的难度非常低.</p> <blockquote> <p>对于我们(我和我女朋友)来说, 0 - 70 开荒反而是 D3 现在最有意思的环节, 是我们每个赛季必定参与的保留节目! 🤩</p></blockquote> <p>而且众所周知, 设计师会在每个赛季开始时, 设计许多有趣的新机制, 以及对旧的装备带来词缀的更新.</p> <p>所以难免就会发生 OverPower 的情况出现:</p> <ul> <li>增伤系数文字描述是加法, 代码实现是乘法(出现过 N 次了), 强度太高</li> <li>被玩家开发出了出格的 Build, 强度太高</li> <li>装备之间的联动出现预期外的情况, 强度太高</li> </ul> <p>这次死灵法师就出现了第 3 种情况的 &ldquo;BUG&rdquo;, 50 码内的敌人会不停地受到&quot;亡者大军 - 异界大军&quot;的效果, 而且配合某件装备(大军头)后, 伤害会发生质的变化!</p> <blockquote> <p>这才叫真正的亡者大军嘛! 逛街躺过 150 大秘境.</p></blockquote> <p>俺终于有幸蹭上热乎的了! <a href="https://youtu.be/L8HoiwKVvlQ?t=312">录了视频进行留念!</a></p> <p> <p class="md__image"> <img src='./assets/real-army-of-died.png' alt="Real Army of Died" /> </p> </p> <p>不过这个 BUG 在第 2 天就被<a href="https://us.forums.blizzard.com/en/d3/t/diablo-iii-ptr-274-714-hotfix-update/52951">热修复</a>了. 😭</p> <blockquote> <p>活出 PTR. ❌<br> 活了 1 天. ✔️</p></blockquote> <p>当然这个赛季除了死灵法师之外, 其他的职业也都有不同程度的加强/整活:</p> <ul> <li>猎魔人的集束箭变为激光!</li> <li>猎魔人扫射时自动释放能量消耗技!(玩过风暴英雄的同学脑补维拉的 R1 会自动释放 W, 玩过英雄联盟的同学脑补萨米拉 R 自动释放寒冰 W.)</li> <li>武僧的七相拳留下一个灵体持续释放七相拳!(这是替身攻击!)</li> <li>法师的奥术飞弹将释放 20 个飞弹, 并自带自瞄符文!(真正的火多重!)</li> <li>&hellip;</li> </ul> <p>非常期待这一次的 PTR 了!</p> <p>不过这次的赛季改动也让我十分的担心, 因为它和星际争霸 2 最后出现的合作模式威望系统太像了:</p> <ul> <li>每个指挥官/职业都有 3 种不同的变体</li> <li>不同的变体将会较大得改变打法</li> <li>想要完全体验所有的变体, 需要特别耗肝</li> </ul> <p>上次威望系统更新以后不久, 星际争霸 2 就宣布不会有新内容更新了, 只是平衡性调整. 估计暗黑 3 后面也是类似的: 有爱的游戏设计师/工程师, 在游戏生命周期的最后, 把自己的所有对这个游戏的想法与爱, 灌注到这个游戏中.</p> <blockquote> <p>JOJO, 这是我最后的波纹了, 收下吧!</p></blockquote> <blockquote> <p>唉, 别又玩死一个游戏. 😭</p></blockquote> <h3 id="与-xuanwo-哥哥尝试在-gathertown-上进行元宇宙-social">与 Xuanwo 哥哥尝试在 Gather.town 上进行元宇宙 social</h3> <p>上次在<a href="https://twitter.com/strrlthedev/status/1546689590899093504">这个推文</a>中, 英俊潇洒才华横溢的 <a href="https://twitter.com/OnlyXuanwo">Xuanwo</a> 哥哥愿意分享一下他作为开源项目团队中 &ldquo;工具人&rdquo; 的角色, 进行上传下达(向上管理之类的?)的经历. 同时也有许多推友表示, 自己也比较感兴趣.</p> <p>因此俺试着想了个办法, 在 gather.town 这个线上元宇宙 Workspace 中找了一个合适的场景, 来作为下次分享时的&quot;场地&quot;.</p> <p> <p class="md__image"> <img src='./assets/gather-online-cafe.png' alt="Gather Online Cafe" /> </p> </p> <blockquote> <p>俺和 Xuanwo gege 试着用了这个场景闲聊了一会, 感觉体验还不错!</p></blockquote> <p>估计到时候我们就在这个线上咖啡馆见面吧!</p> <p>细节会在后续一段时间内告诉大家的, 请保持期待! 🥰</p> <h3 id="健身与做饭">健身与做饭</h3> <p>参与健身后, 健身教练要求/建议自己做饭吃. 有一个明显的变化是, 记账变轻松了: 之前是每天若干顿外卖, 现在是一次超市购物, 能吃好几天. 而且现在我也很喜欢周末和女朋友一起去附近的商场, 先下馆子改善下伙食, 然后买一堆食物为接下来的几天作储备.</p> <p>我们(主要是俺女朋友)也做了很多好吃的菜:</p> <ul> <li>红烧排骨</li> <li>香菜牛肉</li> <li>酸辣土豆丝/白菜/豆芽</li> <li>虾仁滑蛋</li> <li>辣炒鸡胸肉</li> <li>&hellip;</li> </ul> <p>第一次感觉到生活可以这样美好!</p> <blockquote> <p>补充一张照片</p></blockquote> <p> <p class="md__image"> <img src='./assets/daily-food.jpg' alt="Daily Food" /> </p> </p> <blockquote> <p>女朋友实在是太强了! 俺何德何能&hellip;</p></blockquote> 2022-27: 找新坑 https://strrl.dev/post/weekly-report/2022/27-%E6%89%BE%E6%96%B0%E5%9D%91/ Mon, 11 Jul 2022 22:21:46 +0800 https://strrl.dev/post/weekly-report/2022/27-%E6%89%BE%E6%96%B0%E5%9D%91/ <p>这里又是一份周报, 时间范围是<code>2022-07-04</code>到<code>2022-07-11</code>, 会记录一些工作及生活上有意思和没那么有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>这周没有看多少 NAND2Tetris 的课程, 看完了 Jack Language Spec 的那部分, 还没有做实验.</p> <h3 id="google-ux">Google UX</h3> <p>开的新坑, 在 Coursera 以上 $39 每月的订阅价格, 开始学习 Google UX.</p> <p>上两天在 twitter 上也谈论了一些关于 UX 的话题, 比较有趣, 这里也搬运, 也顺便一下吧:</p> <p>Reference: <a href="https://twitter.com/strrlthedev/status/1545917312699510784">https://twitter.com/strrlthedev/status/1545917312699510784</a></p> <p>Google 内部将近有一个 4000 人的团队, 为各个产品设计 UX, 包括但不限于: Google Map, Google Assistants, Google Search. 同时分工也十分细致, 从 research 到 design 再到 dev.</p> <p>让我感到十分震撼的同时, 我也做出了一个判断: 如果我作为开发者, 万一和 Google 这种体量的公司在领域内有竞争, 在交互方面我是几乎赢不了的, 只能尝试在艺术和创作方面上&quot;剑走偏锋&quot;.</p> <p>同时我也没有在 Google 内发现过于&quot;惊艳&quot;的产品交互.</p> <blockquote> <p>至于&quot;惊艳&quot;, 我觉得想 baba is you 这种形式算是非常惊艳了.</p></blockquote> <p>与此同时, Google UX 这门课也向我阐述了一种观点: &ldquo;好的 UX 是自然的, 而坏的 UX 是明显的.&rdquo;</p> <blockquote> <p>插话, 就像空气一样. 空气在且良好的时候, 你感受不到它. 当它坏了, 甚至消失了, 你才觉得这很重要. 类似的比喻也出现在某个 go scheduler 的分享中.</p></blockquote> <p>Google UX 的课程比较有意思, 和所谓的&quot;干货&quot;不同, 它先描述 UX 行业内可能的职业生涯模式, 然后介绍了学习路径, 另外再描述了一个产品的设计迭代流程. 整个 week 1-4 的内容就过去了, 实际领域细节相关的从下个部分开始.</p> <blockquote> <p>许多做事的方法不仅仅是适用于做 UX 的, 也适用于工程以及产品的迭代.</p></blockquote> <h3 id="关于自由开发者">关于自由开发者</h3> <p>我自己是一个崇尚自由的人, 打工是不可能打一辈子的, 从很早以前就憧憬着自由开发者这个工作: 用自己的喜欢的工具, 做自己喜欢的事情, 能够养活自己.</p> <p>上次参与了声网的 <a href="https://www.nglab.io/incubator">独立开发者孵化器</a> 活动后, 我发现所谓&quot;独立开发者&quot;的难度可能并不亚于创业. 另外我在经济, 商业和运营等方面的知识过于缺乏.</p> <p>还好时间还不晚, 我想从现在开始, 去了解一些之前不了解的知识.</p> <blockquote> <p>忘记在谁的博客里看到过的, 光是&quot;维持现状&quot;, 就已经很辛苦, 被迫去了解新的知识了. 但是我的想法更乐观一些, 其实我做的这些事情并不是 &ldquo;维持现状&rdquo;, 而是真真切切地提升自己, 只是偶然自己的提升和环境的败落对冲掉了. 当时机合适时, 二者还是可以组合出一个更好的未来的.</p></blockquote> <h3 id="通过-cloudflare-暴露内网服务">通过 Cloudflare 暴露内网服务</h3> <p>经过和 <a href="https://twitter.com/n0vad3v">Nova Kwok</a> 的激情讨论后, 我大概弄明白了使用 Cloudflare Argo Tunnel 的正确姿势:</p> <ul> <li>挑个好 IP</li> <li>走代理</li> </ul> <p>在进行合适的配置以后, 我成功地将内网的影音服务流畅得播放出来, 而且能够吃满我家的 30M 上行带宽.</p> <blockquote> <p>1000M 下行, 30M 上行, 真有你的电信.</p></blockquote> <p>估计以后我有什么好玩的, 在内部部署的服务, 会以<code>&lt;some-service&gt;.strrl.cloud</code>的形式暴露出来. 请大家期待吧!</p> <h3 id="找新坑">找新坑</h3> <p>算是一个正式的宣布吧, I am available for hire.</p> <p>由于工作内容调整的原因, 我估计会在下一个季度中, 缩减项目本身迭代以及社区的人力投入.</p> <p>下个季度我的工作内容发生了变化, 少有项目本身迭代和社区相关的. 换句话说, 我估计得要去做一些所谓&quot;为稳定性做出贡献&quot;的事情. 这些在我眼里看来, 是不尊重工程, 也没有明确计划的杂活. 全职写开源的好日子结束了. 我工作不开心了.</p> <p>这个从 CNCF 沙箱项目到成长到孵化项目, 到现在 AWS FIS 和 Azure Chaos Studio 都可以与它集成. 社区也是同类开源项目中最为活跃的.</p> <blockquote> <p>无论换坑还是不换坑, 目前的几个活跃的开发者, 短期内可能都不会再像以前那样活跃了.<br> 其中一位活跃开发者阐述了在 <a href="https://gist.github.com/richhickey/1563cddea1002958f96e7ba9519972d9">Open Source is Not about U</a> 中的一些观点, 让我还有一些希望: 开源项目的主导者从来都不是某家公司或某个机构, 而是这些活跃的开发者们. 我也希望在未来能够以更纯粹地方式参与到这个项目里吧.</p></blockquote> <p>目前我在尝试公司内部申请了其他部门的转岗申请, 目前聊的还算开心.</p> <p>也试着投了一些其他公司的相关和不相关的岗位, 目前已经有几家在面试流程中了, 期望一切顺利. :)</p> <blockquote> <p>我的最好期望是, 在一家尊重工程与工程师的公司里, 继续做些有趣且有挑战性的事情. 然后用我的爱和热情来继续维护这个项目, 直到消耗殆尽.<br> 啊哈, 光是&quot;维持现状&quot;已经是一件非常难的事情了.</p></blockquote> <h2 id="生活相关">生活相关</h2> <h3 id="健身有了一点效果">健身有了一点效果</h3> <p>具体表现在:</p> <ul> <li>体能有明显的上升, 有氧运动, 坡度 17 速度 4 走 45 min 从最开始的非常累, 到现在的没有很累了;</li> <li>体重减了 7 斤. 不过教练说这绝大多数是水.</li> <li>对身体上的不舒服的容忍度高了. 比如说我之前散步一小会不舒服, 就要闹着回家, 但是现在知道, 这点难受远远到不了危险的程度, 可以继续忍受.</li> </ul> <p>明天教练说早上的有氧改爬山了, 说带我去见是一个新路径, 很开心.</p> <blockquote> <p>啊, 如果能回到高中的那个体能和精神就好了.</p></blockquote> <h3 id="休假">休假</h3> <p>这周 3 4 5 我请了三天年假, 休息.</p> <h3 id="推荐游戏-十三机兵防卫圏">推荐游戏: 十三机兵防卫圏</h3> <p>在多个(不同圈子的)好友的推荐下, 我在这周末两天肝完了这个游戏.</p> <p>剧情确实天马行空, 男女主角们都非常的可爱! 13 个人物, 每个人物都非常得生动与丰满.</p> <p>对我来说战斗部分是一个减分项, 不让我好好看剧情. :(</p> <p>最后, 结局是一个皆大欢喜 happy ending, 没有人受伤的世界达成了!</p> <blockquote> <p>不够涩.</p></blockquote> 2022-26: 生活的掌控感 https://strrl.dev/post/weekly-report/2022/26-%E7%94%9F%E6%B4%BB%E7%9A%84%E6%8E%8C%E6%8E%A7%E6%84%9F/ Sun, 03 Jul 2022 18:44:58 +0800 https://strrl.dev/post/weekly-report/2022/26-%E7%94%9F%E6%B4%BB%E7%9A%84%E6%8E%8C%E6%8E%A7%E6%84%9F/ <p>这里又是一份周报, 时间范围是<code>2022-06-27</code>到<code>2022-07-03</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>目前已经看了 Compiler 一部分的课程, 实验还没有做.</p> <blockquote> <p>同样也是在有氧的时候看的.</p></blockquote> <h3 id="故障演练">故障演练</h3> <p>现在的时间是周日的下午 18:50, 说实话我现在已经从故障演练的紧绷神经中缓过来了.</p> <p>总体来说这次演练的成果相当不错, 发现了很多产品的问题. 能够发现问题就是好事, 如果不事先内部发现, 那到时候就是线上用户去&quot;发现&quot;了.</p> <p><strong>但是</strong>我作为参与其中的工程师来说, 体验比较差. 并且从其他一同参与进这次活动的工程师的反馈和客观表现来看, 这种活动对于人精力的消磨是十分大的, 进展到后面, 大家都出现过不同情况的&quot;低级错误&quot;, 比如识别错当前正在执行的场景, 修改文档时误操作等.</p> <p>另外整个工程之间中充斥着两个字: 散装. 负责指挥的人几乎不怎么管细节, 也没有指派一个人来管细节, 事情能办成真的基本上全靠靠谱工程师的专业精神. 准备以及执行过程中多次要求&quot;加戏&quot;, 一再质疑工程师拟定方案进度太慢.</p> <p>希望这种事情不要有下次.</p> <blockquote> <p>我感觉甚至留下了轻微的后遗症, 会偶尔&quot;幻听&quot;到飞书的消息通知声. 在写这篇日志的时候就发生了一次, 然后发现我的系统音量是静音的. 唉, 😭.</p></blockquote> <h3 id="绝妙的主意-github-profile-身体状态徽章">绝妙的主意: GitHub Profile 身体状态徽章</h3> <p>起源: <a href="https://twitter.com/strrlthedev/status/1542100414413172737">https://twitter.com/strrlthedev/status/1542100414413172737</a></p> <p>我想做成一个 badge 放到 GitHub Profile 上, 类似达到的效果比如: 一个 badge 表示 zhiqiang 过去 1 小时的心率是在 55 - 70, zhiqiang 过去今天活动了 50 分钟.</p> <p>再比如说, 这样:</p> <p> <p class="md__image"> <img src='./assets/badge.svg' alt="Heart Rate Badge" /> </p> </p> <blockquote> <p>显然心率 233 这人怕是要出事了</p></blockquote> <p>但是我也遇到了一个比较棘手的问题, Google Fitness 的 API 其实更新的比较慢, 数据上传上去以后, 仍旧需要一段时间(指 2 ~ 5 小时)才能够查询到. 其实这样的话心率展示就效果不太好了.</p> <p>如果有办法能把延迟做到半小时左右, 那就绝妙了.</p> <h2 id="生活相关">生活相关</h2> <h3 id="小缇娜的奇幻之地-欢乐但是-bug-超多">小缇娜的奇幻之地: 欢乐但是 bug 超多</h3> <p>上上周买了这个游戏, 因为它相当于是无主之地 3 的番外嘛. 剧情非常的棒, 在桌游的背景上, 讲述了各种鬼怪的有趣故事.</p> <p>可爱的反派, 可爱的主角团, 可爱的 NPC. 还有诚意一万分的本地化配音与文案. 我作为剧情党极为享受.</p> <p>唯一的缺点就是 bug 太多了, 比如说:</p> <ul> <li>局域网联机没法用;</li> <li>宠物血条显示一直是空的;</li> <li>背包页面装备贴图加载不出来;</li> <li>闪退;</li> </ul> <blockquote> <p>再就是人老了, 玩一会游戏就累. 两周过去了才刚出闪蹄城.</p></blockquote> <h3 id="准备使用-todoist-替代-facile-things">准备使用 todoist 替代 facile things</h3> <p>最开始接触 GTD 的时候, 我在 Notion 里用 Database 糊了一个任务管理. 受限于当时的一些易用性和性能问题吧, 用得不是很舒服.</p> <p>后来使用 <a href="https://strrl.dev/post/weekly-report/2022/16-%E5%B0%8F%E5%8C%BA%E9%9D%99%E6%80%81%E7%AE%A1%E7%90%86/#%E6%9C%89%E8%B6%A3%E7%9A%84-gtd-%E5%B7%A5%E5%85%B7-facilethings">Facile Things 作为了我的 GTD 工具</a>, 它的特点也十分明显: 它转为 GTD 设计, 使用过程中处处都是提示我如何正确使用这些 Task. 比如它</p> <ul> <li>提供了完整的公开文档和 blog, 细致地说明了使用 FacileThings 如何应用 GTD.</li> <li>操作页面中处处都有 GTD 相关的提示, 并 GTD 有些 perspective 的方式也有展现. 比如, 人生目标, 五年目标, Area, 近期行为能否能对应上去等等.</li> </ul> <p>其实大家可能也发现了, 这些都是&quot;软&quot;的实力, 我可能熟悉了 GTD, 或者我使用打印机把这些提示打印出来也能起到类似或者折扣的效果.</p> <p>这正是我准备做的事情.</p> <p>FacileThings 的问题有:</p> <ul> <li>WebUI 和安卓 App 交互都不好, 卡顿, 甚至 WebUI 的导航栏会有 bug, 让我点击事件没啥反应, 只能去输入 URL(幸好我背过了)</li> <li>与 Google Calendar 的 routine 交互有大问题, 重复的事件拒绝后不会自动删除, 导致我有很多拒绝的事件被添加了</li> <li>扩展少; 例如我想使用 toggle track 记录时间, todoist 可以做到, 而现在我只能手动记录</li> </ul> <p>综上, 我准备转移阵地到 todoist 了. 在熟悉了 GTD 后, 我依然会将 facilethings 的 blog 存档作为我的指导, 但是使用 todoist 作为更好的工具.</p> <blockquote> <p>FacileThings 的年度订阅续费也停了, 准备计划的 facilethings-cli 也准备鸽了, 而且 todoist 已经有现成的 cli 了.</p></blockquote> <h3 id="对生活的掌控感">对生活的掌控感</h3> <p>啊哈, 在<a href="https://strrl.dev/post/weekly-report/2022/23-%E4%B8%8D%E8%A7%A3%E5%BF%99%E7%A2%8C%E5%8F%8D%E6%80%9D/#%E5%85%B6%E4%BB%96">前文</a>中提到过一些最近工作生活心态的调整. 这里可能再罗嗦一点吧.</p> <p>我发现我在难过, 焦虑的时候, 是现实生活与自己期望中生活的反差, 而自己目前又太弱小做不到改变所导致的. 在认识到自己的弱小以后, 我需要以更加朴素, 更加低水平且更加客观的方式对自己的生活进行控制. 主要的行为方法是, 认识到我的脑子的限制, 使用笨拙且可靠的方式达成目标, 并且需要客观地记录自己的行文和变化.</p> <p>一方面, 我需要去行动, 另一方面, 我需要去记录. 凡事预则立, 不预则废. 过往的记录是制定未来计划的最好参考. 如果没有客观的记录, 那我的未来计划也会像上文的&quot;故障演练&quot;一样散装.</p> <p>我自己是一个非常不自律, 也没啥主动性的人, 我需要一个极强的兴趣点, 或者是有人 push 我才能完成好某件事. 当然也可以自己 push 自己, 只要找到好工具 or 方法论, 比如说 GTD 就可以系统性地自我 push 了.</p> 2022-25: 好忙 https://strrl.dev/post/weekly-report/2022/25-%E5%A5%BD%E5%BF%99/ Sun, 26 Jun 2022 10:57:17 +0800 https://strrl.dev/post/weekly-report/2022/25-%E5%A5%BD%E5%BF%99/ <p>这里又是一份周报, 时间范围是<code>2022-06-20</code>到<code>2022-06-26</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>这周听完了 Nand2Tetris Part 1 的最后一周的课, 课程内容是写一个 assembler. 实验还没有开始做, 准备拿 go 去梭一把.</p> <blockquote> <p>有趣的是视频课程是在跑步机上做有氧运动的时候看完的. 😜</p></blockquote> <h3 id="忙故障演练">忙故障演练</h3> <p>从上周周三开始, 公司内准备在 RDG 团队范围内进行实战演练. 而且这么大规模的故障演练只给了一周半的时间来准备, 实在是太急了.</p> <p>Chaos Mesh 小组自然就作为提供故障注入的小组参与进来了.</p> <p>我的角色不仅是 Chaos Mesh 的用户, 而且还要作为接口人, 整理所有的故障场景. 这使得我加入贵司以来再次回忆到当年作为 SRE 的恐惧. 漫天的会, 不停地找各种人, 不停地扯皮. 非常忙, 体验非常不好.</p> <p>过去的 8 个工作日里, 开了 18 个会. 其中 4 个是周期性会议, 2 个是部门分享, 其余都是沟通, 沟通, 沟通. 体会到了上面给压力, 下面也给压力, 手上也没有什么权利, 作为一个接口人夹在中间无依无靠还要硬着肉皮搬砖的感受.</p> <p>经过这次的经历, 意识到了目前内一些能力与角色的缺失, 而且这个问题短时间内恐怕无法改变. 另外整个团队这么多人, 也没有调一个 PM 来主导这件事, 整个事情的组织实在是差劲.</p> <p>希望未来故障演练由我们团队来主导, 而不是由其他团队来主导.</p> <p>准备演练以后请几天假报复性休息一下.</p> <h2 id="生活相关">生活相关</h2> <h3 id="notion-日记频率开始逐渐恢复">Notion 日记频率开始逐渐恢复</h3> <p>大家可能已经发现了, 自从第 19 周的周报开始一直到现在为止, 内容一直比较水.</p> <p>其实是我一直用作为生活记录的 Notion Journal 的更新频率出现了问题:</p> <p> <p class="md__image"> <img src='./assets/notion-journal.png' alt="Notion Journal" /> </p> </p> <p>可以看到过去有段时间, Notion Journal 的更新频率是每周只有 2 - 3 次. 有很多有意思的想法都遗失了.</p> <p>最近一周算是恢复了, 庆祝庆祝. 🎉</p> <h3 id="开始去健身房健身了">开始去健身房健身了</h3> <p>经过缜密的思考后, 我去小区附近的健身房里办了季卡和私教, 准备开始健身和减肥了.</p> <p>健身的目的很简单, 期望自己能在白天能够有足够的精力工作, 晚上有好的睡眠质量.</p> <p>从周三当天晚上开始的, 每周 1234 锻炼, 567 休息.</p> <p>我倒不期望有什么非常快速的转变, 期望一个季度后, 能够晚上有 2 小时的深度睡眠, 然后白天不需要咖啡就可以精神充沛就可以了. :D</p> <h3 id="细粒度地规划时间">细粒度地规划时间</h3> <p>最近在做规划时, 发现自己在安排行程时, 已经开始不由自觉的用 半个小时 作为最小粒度了.</p> <p>这非常不好!</p> <p>我期望自己对时间的安排在下一步至少做到 15 min 级别的粒度, 这样可以安排得更紧凑一些.</p> 2022-24: 主力设备换新 https://strrl.dev/post/weekly-report/2022/24-%E4%B8%BB%E5%8A%9B%E8%AE%BE%E5%A4%87%E6%8D%A2%E6%96%B0/ Sat, 18 Jun 2022 13:45:25 +0800 https://strrl.dev/post/weekly-report/2022/24-%E4%B8%BB%E5%8A%9B%E8%AE%BE%E5%A4%87%E6%8D%A2%E6%96%B0/ <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>本周没有进行 NAND2Tetris 的学习;</p> <h3 id="macbook-pro-2018---macbook-air-2020">Macbook Pro 2018 -&gt; Macbook Air 2020</h3> <p>mba 到手了. 因为从 intel 机器通过迁移助手初始化的新机器, 所以花了点时间清理 intel 架构的 binary 和 app.</p> <p>整体来说, 体验还是不错的. 俺终于有了一个安静, 流畅, 清凉, 便携, 长续航的终端设备.</p> <p>非要说有什么缺点的话:</p> <ul> <li>屏幕变小了, 还不太适应;</li> <li>音响真的垃圾;</li> <li>右侧没有 IO 口, 也不太适应;</li> </ul> <p>试用了一下 Asahi Linux, 整体体验还是比较不错的. 我需要用到的大部分的编程工具链都可以直接试用.</p> <p>目前遇到一些问题:</p> <ul> <li>telegram 和 chromium 由于分发时 jemalloc 还没有支持 16K Page Size 的原因不能用. (这也意味着 Electron App 也不能用)</li> <li>AUR 上 feishu-bin 没有打 arm64 的包</li> </ul> <p>还不能成为主力的办公环境. 如果有 arm 的开发需求还是可以切过来用的.</p> <blockquote> <p>附上个关于类似问题的链接: <a href="https://github.com/AsahiLinux/docs/wiki/Broken-Software">https://github.com/AsahiLinux/docs/wiki/Broken-Software</a></p></blockquote> <h3 id="尝试重写-kubernetes-ipset-部分代码">尝试重写 Kubernetes ipset 部分代码</h3> <p>issue: <a href="https://github.com/kubernetes/kubernetes/issues/109034">https://github.com/kubernetes/kubernetes/issues/109034</a></p> <p>原因是 ipset 相关 API 里暴露了太多细节, 导致使用的时候, 需要额外再去了解更多 ipset 相关的知识才能正确地使用 API, 不太不方便.</p> <p>因为使用到这部分功能的代码并不多(貌似只有 kube-proxy), 所以前人提了这个 issue, 对相关代码进行重写.</p> <p>俺倾向对不同类型 ipset 相关的 API 最起码做到 schema 上的严格, 但是由于 go 语言的一些限制, 最后的 API 可能还是比较丑.(但是使用上更安全, 理解压力也会变小.)</p> <p>其实 Chaos Mesh 也有对 ipset 操作的需求, 如果能和进去, Chaos Mesh 也能复用这部分代码.</p> <blockquote> <p>但是社区同学貌似并不关心这个问题, 也不回复俺. (可能是没有 at 正确的人?</p></blockquote> <h2 id="生活相关">生活相关</h2> <h3 id="被团建摧残了">被团建摧残了</h3> <p>昨天公司团建, 斗胆报名了 ATV 越野车的项目.</p> <p>体验十分糟糕.</p> <p>刹车油门都在右手上, 龙头的方向操控也非常不灵敏; 开了一会我就决定放弃了.</p> <p>在教练的指引下, 搭乘可靠伙伴 tmgg 的车继续了我剩下的的旅程.</p> <p>但是接下来的路程里也比较艰难, 路上全部都是故意挖的坑, 还有故意放的水. 然后由于我本身比较重, 感觉 tmgg 操作的也比较吃力. 🙈</p> <p>总之下次我不会再去报名这个项目了.</p> <p>团建因为在一个山里, 各个项目之间的距离也很远, 由于我缺乏运动过于弱小, 第二天肩膀, 大腿, 屁股都比较痛.</p> <blockquote> <p>需要锻炼身体!</p></blockquote> 2022-23: 不解, 忙碌, 反思 https://strrl.dev/post/weekly-report/2022/23-%E4%B8%8D%E8%A7%A3%E5%BF%99%E7%A2%8C%E5%8F%8D%E6%80%9D/ Sun, 12 Jun 2022 22:54:00 +0800 https://strrl.dev/post/weekly-report/2022/23-%E4%B8%8D%E8%A7%A3%E5%BF%99%E7%A2%8C%E5%8F%8D%E6%80%9D/ <p>这里又是一份周报, 时间范围是<code>2022-06-06</code>到<code>2022-06-12</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>本周没有进行 NAND2Tetris 的学习;</p> <blockquote> <p>继续狂鸽</p></blockquote> <h3 id="在-m2-发布后买了-m1-macbook-air">在 M2 发布后买了 M1 MacBook Air</h3> <p>2022 年 6 月 7 日, 苹果在 WWDC 2022 上发布了搭载 M2 芯片的新设备. 最开始我对新一代 MacBook Air 的期待是&quot;粉色 + 32G 内存&quot;. 结果大失所望, 都没有.</p> <p>迫于手上的 18 年 mbp 急需更换, 我选择购买了 2020 年的 M1 MacBook Air.</p> <p>预计下下周到手. :)</p> <blockquote> <p>当年 2w5 买的 mbp, 现在折价只能折 5000 不到. 用了差不多四年, 平均每天 18 块.</p></blockquote> <h3 id="脆弱的开源社区">脆弱的开源社区</h3> <p>起源于这篇 twitter: <a href="https://twitter.com/strrlthedev/status/1534824698365612033">https://twitter.com/strrlthedev/status/1534824698365612033</a></p> <p>后来联系到了一位 dalao, 聊了聊 Chaos Mesh 社区的问题.</p> <p>目前 Chaos Mesh 实质上仍是 PingCAP 主导的项目, 项目的绝大部分活跃开发者都是 PingCAP 的雇员.</p> <p>目标, 决策, 参与都不透明. 社区贡献很难参与, 只能做一些简单的事情.</p> <p>一旦活跃成员不再活跃, 这个项目也就凉了.</p> <h2 id="生活相关">生活相关</h2> <h3 id="推荐游戏-无人深空-vr-模式">推荐游戏: 无人深空 VR 模式</h3> <p>很早之前就注意了无人深空是有 VR 模式的, 直到最近才去尝试.</p> <p>坐在椅子上使用原地模式游玩还是非常有趣的, 手动驾驶飞船和机架的感觉非常棒.</p> <p>满足了小时候的梦想.</p> <p>refer: <a href="https://twitter.com/strrlthedev/status/1534930351214063616">https://twitter.com/strrlthedev/status/1534930351214063616</a></p> <h3 id="推荐游戏-黎明前-20-分钟">推荐游戏: 黎明前 20 分钟</h3> <p>逛 Steam 队列时发现了这款游戏, 因为只需要 18 港币, 所以干脆直接买了下来.</p> <p> <p class="md__image"> <img src='./assets/20-min.jpeg' alt="20 min till dawn on Steam" /> </p> </p> <p>这款游戏和 vampire survivor 非常类似, 不知道谁借鉴了谁.</p> <p>今天一天玩了 8 个小时.</p> <blockquote> <p>喷子配闪电太猛了.</p></blockquote> <h3 id="比较有意思的游戏-shotgun-king-the-final-checkmate">比较有意思的游戏: Shotgun King: The Final Checkmate</h3> <p>这是个佷搞的游戏, 讲的是黑棋国王昏庸残暴, 导致所有的其他臣民都去了白棋那里.</p> <p>黑棋国王只剩下了一把王室霰弹枪, 然后向白棋发起了战争.</p> <p>总体来说就是玩家扮演黑棋国王, 拥有一把(射程 5, 威力 3, 弹药 6 的)霰弹枪. 每个回合内可以移动一次并开枪一次. 白方就是正常的棋子, 会用正常的国际象棋规则进行移动和吃子.</p> <p>把对方的王干碎游戏就胜利了.</p> <p> <p class="md__image"> <img src='./assets/shotgun-king.png' alt="shotgun king" /> </p> </p> <blockquote> <p>我太菜了, demo 版第一关都打不过去, 所以没有买.</p></blockquote> <h2 id="其他">其他</h2> <p>最近发生了一些事情, 工作上没有以前那么快乐了.</p> <p>为公司打工, 做了再多成果, 项目效果再出众, 绩效再好也是别人赋予的价值.</p> <p>多投资自己吧, 希望自己能认可自己.</p> 2022-22: 端午假期 https://strrl.dev/post/weekly-report/2022/22-%E7%AB%AF%E5%8D%88%E5%81%87%E6%9C%9F/ Sun, 05 Jun 2022 11:05:20 +0800 https://strrl.dev/post/weekly-report/2022/22-%E7%AB%AF%E5%8D%88%E5%81%87%E6%9C%9F/ <p>这里又是一份周报, 时间范围是<code>2022-05-31</code>到<code>2022-06-05</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>本周没有进行 NAND2Tetris 的学习;</p> <blockquote> <p>继续狂鸽</p></blockquote> <h3 id="投稿-kubecon-na">投稿 KUBECON NA</h3> <p>接<a href="https://strrl.dev/post/weekly-report/2022/20-%E5%96%9C%E8%BF%8Ekubecon/#%E4%BD%BF%E7%94%A8%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE%E7%BB%84%E5%90%88%E4%B8%80%E4%B8%AA-chap-alternative">上文</a>, 俺试着投了一篇!</p> <p> <p class="md__image"> <img src='./assets/kubecon-na-cfp.png' alt="KUBECON NA CFP" /> </p> </p> <h3 id="chaos-engineering-collection-on-ossinsightio">Chaos Engineering Collection on ossinsight.io</h3> <p>这周四和贵司社区的同学们分享了 Chaos Mesh 项目的现状, 社区的老师们立刻提议在 OSSInsight 中加入 Chaos Engineering 这个集合. 两天后就加上了:</p> <p><a href="https://ossinsight.io/collections/chaos-engineering">Chaos Engineering - Monthly Ranking</a></p> <p> <p class="md__image"> <img src='./assets/ossinsight-monthly-rank.png' alt="Monthly Rank" /> </p> </p> <blockquote> <p>Litmus Chaos 在最近一段时间进行了较强力度的宣发, 增长势头很快! ❤️</p></blockquote> <h2 id="生活相关">生活相关</h2> <h3 id="初步接入智能家居">初步接入智能家居</h3> <p>之前一直想监控家里的用电情况, 后来发现小米的智能插座就可以简单的做到这一点.</p> <p>于是购入了小米智能插座 x 5 和温湿度计 x 5.</p> <p>使用以后还是发现了一些了不得的事情:</p> <ul> <li>机柜的整体功耗保持在 180W 左右;</li> <li>我的工作台功耗保持在 60W 左右;</li> <li>下雨时室外湿度约在 96% - 98%, 室内在 80%-90%, 考虑买抽湿机了;</li> </ul> <p>俺也跟风使用 Home Assistent 做了和 HomeKit 的关联, 能够用 Siri 做一些简单的事情了.</p> <p>此外 Home Assistent 有 prometheus 的集成, 可以和俺现有的 Prometheus Stack 集成. 不过 Grafana Dashboards 里貌似没有对应 prometheus 的数据源, 需要自己撸一个.</p> <h3 id="逛宜家">逛宜家</h3> <p> <p class="md__image"> <img src='./assets/ikea-panorama.jpg' alt="Ikea Panorama" /> </p> </p> <blockquote> <p>貌似俺还不知道有什么工具可以方便的分享全景图.</p></blockquote> <h2 id="其它">其它</h2> <p>端午快乐! 儿童节快乐!</p> 2022-21: 受苦修复 Kubernetes 集群 https://strrl.dev/post/weekly-report/2022/21-%E5%8F%97%E8%8B%A6%E4%BF%AE%E5%A4%8Dkubernetes%E9%9B%86%E7%BE%A4/ Tue, 31 May 2022 21:55:42 +0800 https://strrl.dev/post/weekly-report/2022/21-%E5%8F%97%E8%8B%A6%E4%BF%AE%E5%A4%8Dkubernetes%E9%9B%86%E7%BE%A4/ <p>这里又是一份周报, 时间范围是<code>2022-05-23</code>到<code>2022-05-30</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>本周没有进行 NAND2Tetris 的学习;</p> <blockquote> <p>狂鸽</p></blockquote> <h3 id="修复-homelab-kubernetes-集群">修复 Homelab Kubernetes 集群</h3> <p>这是这期周报鸽久的主要原因吧, homelab 的计算设备&quot;上架&quot;后, kubernetes 集群并没有恢复之前的工作.</p> <p>在终于修复了问题并恢复了正常服务后, 俺开始整理这期的周报.</p> <h4 id="硬件损坏-内存条坏了一个">硬件损坏: 内存条坏了一个</h4> <p>这是俺第一次遇到这种灵车硬件问题.</p> <p>这个其实是很多问题的根本原因, 往上可以追溯到:</p> <ul> <li><a href="https://twitter.com/strrlthedev/status/1454491934110613512">https://twitter.com/strrlthedev/status/1454491934110613512</a></li> <li><a href="https://twitter.com/strrlthedev/status/1468114058356281346">https://twitter.com/strrlthedev/status/1468114058356281346</a></li> <li><a href="https://twitter.com/strrlthedev/status/1531110913754812417">https://twitter.com/strrlthedev/status/1531110913754812417</a></li> </ul> <p>具体表现的话, 看这个图应该有一些 sense 了:</p> <p> <p class="md__image"> <img src='./assets/mem.jpeg' alt="Mem" /> </p> </p> <p>读写不一致, 某一个 bit 变了.</p> <p>因为内存有问题&hellip; 所以所有的一切诡异现象都得到了合理地解释:</p> <ul> <li>Kernel Panic</li> <li>segfault/sgv</li> <li>etcd checksum mismatch</li> <li>ceph checksum mismatch</li> <li>etc.</li> </ul> <p>目前的手段是把有问题的那条内存拆下来了, 并且缩了上面机器的内存配给, 目前运行平稳.</p> <blockquote> <p>并且问了笔记本维修厮能修吗.</p></blockquote> <h4 id="与-etcd-cri-和-ceph-搏斗">与 etcd, CRI 和 Ceph 搏斗</h4> <p>之前内存的问题自然会带来很多烂摊子, 包括但不限于:</p> <ul> <li>etcd 启动不起来, 因为 etcd checksum mismatch</li> <li>ceph monitor (mon) 和 metadata server(mds) 启动不起来, 因为 .db 文件 rocksdb checksum mismatch</li> <li>ceph osd 启动不起来, 因为 sst rocksdb checksum mismatch</li> <li>/var/lib/kubelet/pods 下一堆 kubelet 删不掉, root 用户 <code>rm -rf</code> 也删不掉, 提示 <code>Resource Busy</code> 的资源. (感觉和挂载的卷有关)</li> </ul> <p>俺依次简单提几嘴怎么修:</p> <p>etcd 启动不起来, etcd checksum mismatch. 俺目前是 3 节点集群, 所以把有问题的那个节点的 members 文件夹直接删掉重启, 就可以解决了. etcd 会自动从别的节点那里把数据同步回来.</p> <blockquote> <p>如果是单节点的话, 俺之前的做法是把有问题的文件删掉, 然后通过 etcdutl 和 etcdctl 重新走一遍备份恢复的流程解决</p></blockquote> <p>ceph monitor (mon) 和 metadata server(mds) 启动不起来, 因为 .db 文件 rocksdb checksum mismatch. 俺用的 rook-ceph, 找到 /var/lib/rook 下对应的文件删之即可.</p> <p>ceph osd 启动不起来, 因为 sst rocksdb checksum mismatch. 这个看上去比较棘手, 因为 osd 是直接用了一个 device mapper 的设备, 没有文件系统. 因为俺的数据都做了 3 副本, 所以铲掉两个 OSD 完全没啥问题. 我就重建了. 重建过程可以参考俺的 <a href="https://whatiknown.strrl.dev/#/page/rook%20ceph%20cheatsheet">rook ceph cheatsheet</a>.</p> <p>/var/lib/kubelet/pods 下一堆 kubelet 删不掉. disable 掉 kubelet, 重启 node, 然后删掉. 🙈 我太坏了.</p> <p>最后再次感谢一下 3 副本的 cephfs 给我的数据带来保障. ❤️</p> <p> <p class="md__image"> <img src='./assets/ceph-replicas.png' alt="cephfs" /> </p> </p> <h3 id="跨平台的-rss-阅读器-fluent-reader">跨平台的 RSS 阅读器: Fluent Reader</h3> <p>之前在 MacOS 平台上一直使用 Reeder 作为 RSS 阅读器, 更换到 Linux 平台后使用 Feedly. 但是 Feedly 的免费账户有限制:</p> <ul> <li>最多 500 个源(俺达不到)</li> <li>最多 3 个分类(俺达到了!)</li> </ul> <p>因此我也在慢慢地注意合适的替代品, 最终在 thunderbird 和 Fluent Reader 中选择了后者.</p> <p>Fluent Reader 是使用 flutter 编写的开源跨平台 RSS 阅读器, 仓库在: <a href="https://github.com/yang991178/fluent-reader">https://github.com/yang991178/fluent-reader</a></p> <p>目前使用体验十分舒畅!</p> <h3 id="交换机改散热大失败">交换机改散热大失败</h3> <p>接<a href="https://strrl.dev/post/weekly-report/2022/20-%E5%96%9C%E8%BF%8Ekubecon/#project-shoe-rack-v2">上文</a>, 我从咸鱼买了一个二手 H3C 24 口 POE 交换机.</p> <p>到手后发现其自带了 3 个 8000 转的风扇, 噪音太大, 想接猫扇进行缓解.</p> <p>于是乎京东下单三个猫扇, 改装时发现主板上是 3pin 接口, 又尝试接线.</p> <p>结果线接好后, PoE 模组依旧提示散热风扇状态是 Fault, PoE 不供电.</p> <p>refer: <a href="https://twitter.com/strrlthedev/status/1529831160691318785">https://twitter.com/strrlthedev/status/1529831160691318785</a></p> <p>随后去淘宝下单散热风扇的兄弟低速静音款(6000 转), 效果也不好, 依旧很大.</p> <p>现在的方向是主动在供电线上串一个电阻(做一条减速线), 进行二次的减速. 过两周再试试吧. 实在不行只能再出手了.</p> <h3 id="微软发布-project-volterra">微软发布 Project Volterra</h3> <p>伴随着<a href="https://www.youtube.com/watch?v=yICVNta8jMU">炫酷地发布视频</a>, 微软发布了 Project Volterra.</p> <p>这是一款面向开发者的 ARM 终端设备, 将使用高通的 SoC 作为处理器. 它的亮点是 &ldquo;stackable&rdquo;, 我强烈怀疑能够通过某种虚拟机/超融合技术将多台设备的资源共享, 性能横向扩展.</p> <p>但是按照微软的惯例, 新设备出现之前至少还得等个一年以上的时间. 所以目前性能最强的 ARM 计算设备依旧是 Apple M1 系列.</p> <p>期望即将到来的 WWDC 能够发布一些新硬件吧, 俺也是时候买一波新 Mac 了.</p> <h3 id="hzlug-h6-线下聚会">HZLUG H6 线下聚会</h3> <p>杭州疫情情况趋向于稳定, 于是在 2022-05-28 举行了一次线下聚会.</p> <p>闲聊了三个小时~</p> <p>refer: <a href="https://hzlug.org/0528-h6-photo/">https://hzlug.org/0528-h6-photo/</a></p> <h2 id="生活相关">生活相关</h2> <p>没有特别记录好玩的事情, 转几条推特吧:</p> <ul> <li>野生大型纸箱: <a href="https://twitter.com/strrlthedev/status/1529399466431684611">https://twitter.com/strrlthedev/status/1529399466431684611</a></li> <li>女朋友的 iPhone 物理连点外挂: <a href="https://twitter.com/strrlthedev/status/1530528590617620484">https://twitter.com/strrlthedev/status/1530528590617620484</a></li> <li>商场里的暴利共享街机: <a href="https://twitter.com/strrlthedev/status/1530504582828552192">https://twitter.com/strrlthedev/status/1530504582828552192</a></li> </ul> <h2 id="总结">总结</h2> <p>这周疲于折腾, 没有记录更多好玩的事情. 惭愧.</p> <p>最后祝大家儿童节快乐. 上海解封快乐.</p> 2022-20: 喜迎 KUBECON https://strrl.dev/post/weekly-report/2022/20-%E5%96%9C%E8%BF%8Ekubecon/ Sun, 22 May 2022 17:30:38 +0800 https://strrl.dev/post/weekly-report/2022/20-%E5%96%9C%E8%BF%8Ekubecon/ <p>这里又是一份周报, 时间范围是<code>2022-05-18</code>到<code>2022-05-22</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>本周没有进行 NAND2Tetris 的学习;</p> <h3 id="facilethings-cli-后续">FacileThings CLI 后续</h3> <p>亲爱的 FacileThings CEO 给俺提供了 API 接口, 估计下周可以动工了!</p> <h3 id="使用开源项目组合一个-chap-alternative">使用开源项目组合一个 ChAP Alternative</h3> <p>混沌工程里的老大哥 Netflix 内部有一个项目叫做 ChAP(Chaos Automation Platform), 它可以自动地进行混沌实验, 合理地控制使范围, 自动稳态分析, 最后通知相关人员试验结果.</p> <p>它是一个庞大的系统, 对于某个企业或者某个组织的服务来说, ChAP 至少能够和 CD , API Gateway/Service Mesh, Observability, ChatOps 组件进行集成, 才能够打到这样的效果.</p> <p>我们之前也在想, 有没有可能能够使用现有的主流开源组件, 组合一个 ChAP 出来呢? 值得一试!</p> <blockquote> <p>如果 PoC 成功, 这可能是我们组 KUBECON NA 2022 的演讲~</p></blockquote> <blockquote> <p>另外 KUBECON NA 2022 CFP 截止日期延期到下下周一了~ 好耶! refer: <a href="https://twitter.com/lizrice/status/1528310359391608834">https://twitter.com/lizrice/status/1528310359391608834</a></p></blockquote> <h3 id="线上参与-kubecon-eu-2022">线上参与 KUBECON EU 2022</h3> <p>🎉 这周 KUBECON EU 2022 召开了!</p> <p>这次 Chaos Mesh Office Hour 人气没有上次高了, 峰值约有 30 人. 果然线上还是不如线下有激情呀.</p> <p>这次的 talk 俺感兴趣的也非常多, 俺在开始前做好了记录, 有些时间太晚的或者冲突的就没看直播, 后面再开始慢慢看这些俺感兴趣的 talk;</p> <p>目前俺感兴趣的演讲中, 已经看了的有:</p> <ul> <li>Lightning Talk: Locating and Debugging Failures with Linkerd and Telepresence - Alejandro Pedraza, Buoyant &amp; Edidiong Asikpo, Ambassador Labs</li> <li>Lightning Talk: Beginner to Maintainer Journey of a Student - Debabrata Panigrahi, National Institute of Technology Rourkela</li> <li>Kubernetes is Your Platform: Design Patterns For Extensible Controllers - Rafael Fernández López, SUSE &amp; Fabrizio Pandini, VMware</li> <li>The Risks of Single Maintainer Dependencies - John McBride, VMware</li> <li>Prow! Leveraging Developer-Centric CI for Your OSS Project! - Nabarun Pal, VMware &amp; Arsh Sharma, Okteto</li> <li>OSS Docs and How to Scale Them: Common Themes From the CNCF Ecosystem - Celeste Horgan, CNCF</li> <li>Unraveling the Magic Behind Buildpacks - Sambhav Kothari, Bloomberg &amp; Natalie Arellano, VMware</li> <li>Cloud Native Chaos Engineering with LitmusChaos - Karthik S, Umasankar Mukkara &amp; Udit Gaurav, ChaosNative; Saiyam Pathak, Civo</li> <li>Full Mesh Encryption in Kubernetes with WireGuard and Calico - Peter Kelly, Tigera</li> <li>Make Cloud Native Chaos Engineering Easier - Deep Dive into Chaos Mesh - Cwen Yin, PingCAP</li> </ul> <p>还未看的有:</p> <ul> <li>Effective Disaster Recovery: The Day We Deleted Production - Rick Spencer &amp; Wojciech Kocjan, InfluxData</li> <li>Been There, Done That: Tales of Burnout from the Open Source World - Savitha Raghunathan, RedHat &amp; Divya Mohan, SUSE</li> <li>Good Governance Practices for CNCF Projects - Dawn Foster, VMware</li> <li>Open Policy Agent (OPA) Intro &amp; Deep Dive - Anders Eknert, Styra &amp; Will Beason, Google</li> <li>Case Study: Bringing Chaos Engineering to the Cloud Native Developers - Uma Mukkara, ChaosNative &amp; Ramiro Berrelleza, Okteto</li> <li>CNCF 101 - Kristi Tan, The Linux Foundation &amp; Charley Mann, Cloud Native Computing Foundation</li> <li>Operating Prometheus in a Serverless World - Colin Douch, Cloudflare</li> <li>Sharing Knowledge: Writing Good Docs for Quick Approval - Jared Bhatti, Waymo</li> <li>What If&hellip; Kube-Apiserver Could be Extended Via WebAssembly? - Flavio Castelli, SUSE</li> <li>Better Reliability Through Observability and Experimentation - Julie Gunderson, Gremlin &amp; Kerim Satirli, HashiCorp</li> <li>Kubernetes Persistent Data Challenges – AZ, Region and Multi-Cloud Patterns - Chris Milsted, Ondat &amp; Patrick McFadin, DataStax</li> <li>You&rsquo;re a Community Manager? But What Do You REALLY Do?! - Nanci Lancaster, VMware &amp; Karen Chu, Microsoft</li> <li>Cloud Native Mentorship: Tips for Being a Great Mentor to CNCF Students - Lucas Servén Marín, Private</li> <li>Implementing Anti-patterns: Kubernetes Cross-namespace Resource Ownership - Tom Coufal, Red Hat</li> <li>&ldquo;My CNI Plugin Did… What?!&rdquo;: Debugging CNI with Style and Aplomb - Douglas Smith &amp; Daniel Mellado Area, Red Hat</li> <li>From Monitoring to Observability: Left Shift your SLOs with Chaos - Michael Friedrich, GitLab</li> <li>Making Sense of Chaos: Implementing Chaos Engineering in a Fintech Company - Iqbal Farabi &amp; Giovanni Sakti, GoTo Financial</li> <li>Metrics as a First-Class Citizen in the E2E Testing Landscape - Matej Gera &amp; Jéssica Lins, Red Hat</li> </ul> <p>作为一个朴素的开发者/软件工程师, 可以在开源社区建设以及文档建设的演讲中获取非常多的经验和知识. 俺希望能够把这些东西良好地运用起来~</p> <p>如果下周个人时间较为充裕的话, 俺会为它们写观后感! 🤩🤩🤩</p> <h2 id="生活相关">生活相关</h2> <h3 id="食物商品的-bliss-point">食物商品的 bliss point</h3> <p>最近若干次看到了 Bliss point 这个概念, <a href="https://en.wikipedia.org/wiki/Bliss_point_(food)">Wiki</a>.</p> <p>俺自己的理解, Bliss point 大概指一种配方, 使人对某种味道能够产生&quot;恰到好处&quot;的满足, 最大程度地激起人的正反馈.</p> <p>对于食品商业公司来说, 找到 Bliss point 是研发新品以及改善现有产品的关键, 它使人产生对产品的好感和依赖.</p> <p>对于消费者来说, 这使得购买产品后的感受更加深刻, 并且使人对产品的满意度更加明显.</p> <p>但是对于肥胖的人(比如说我)来说, 这是一个致命的诱惑. 因为 Bliss point 被专业的人员刻意制造出来, 直接打到了人类生理上的敏感点上, 是我摄入更多本不应该摄入的营养.</p> <p>俺在了解了这一点后, 对于食品的看法更加明确:</p> <ul> <li>我喜欢吃某些食物(比如说零食), 是因为它们确实非常好吃, 而不是我贪吃; 我不应该因为喜欢吃零食而产生羞愧与罪恶感;</li> <li>零食本身及其具有诱惑, 在充分了解这一点后, 拒绝不必要的零食将会更加理智和容易;</li> </ul> <h3 id="无人机有一个电机阻力稍大">无人机有一个电机阻力稍大</h3> <p>周六飞无人机的时候, 明显听到噪音略大, 在 100m 的高度飞行时就能听到很明显的声音, 这在之前是没有的;</p> <p>降落以后用手摆弄, 发现 3 号电机的阻力明显较大; 但是电机停机时桨叶停止的时间, 没有肉眼能区别的不同;</p> <p>先这样飞吧, 出了问题再说;</p> <h3 id="project-shoe-rack-v2">Project Shoe Rack v2</h3> <p>在大约两年前的上一次换租时, 俺仔细关注了新房子弱电的位置, 各个房间网线面板的分布以及网线的布局, 做了最初版的家庭 AC+AP 以及有线网络的架设;</p> <p>在当时俺称它为 Project Shoe Rack:</p> <p> <p class="md__image"> <img src='./assets/project-shoe-rack.png' alt="Project Shoe Rack" /> </p> </p> <p>它是 homelab 的基础; 再在后来添置了几台计算设备后, 成了我现在 homelab 的雏形.</p> <p>上周换房后, 弱电在一个不会打扰人的位置, 而且附近的空间可以放得下一个 140cm, 26U 的机柜, 新空间大约乘 3. 因此我的 homelab 得以升级.</p> <p>最近仍在添置设备中, 最近入手的设备有:</p> <ul> <li>26U 机柜</li> <li>10 分位 PDU</li> <li>交换机 x2 (一台咸鱼 H3C PoE 交换机, 一台 TP-Link 家用交换机)</li> <li>配线架 x2, 理线架 x2</li> <li>UPS (两年后终于把坑填上了)</li> </ul> <p>中间有意思的插曲是 H3C 的交换机内的固件是坏的, 又重新刷了新固件才工作; 而且风扇也太吵了, 买了三个猫扇(还在路上).</p> <p>等到新设备到了后, 可以开始着手玩玩网络摄像头和家庭监控了~ 激动得搓手手</p> <h3 id="一楼蚊虫好多">一楼蚊虫好多</h3> <p>说点不开心的, 我们从 11 楼搬到了 1 楼, 蚊虫明显多了;</p> <p>而且新房子是推窗而且没有纱窗, 这就比较痛苦了. 虽说睡觉时可以使用电蚊香驱蚊, 不会因为蚊子叫影响睡眠, 但是白天依旧会被叮. 尤其是叮到手指上, 又痛又痒.</p> <p>下周的一个重要的事情就是把纱窗搞好. 🤪</p> 2022-19: 乔迁 https://strrl.dev/post/weekly-report/2022/19-%E4%B9%94%E8%BF%81/ Tue, 17 May 2022 23:12:13 +0800 https://strrl.dev/post/weekly-report/2022/19-%E4%B9%94%E8%BF%81/ <p>这里又是一份周报, 时间范围是<code>2022-05-08</code>到<code>2022-05-17</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>这周我自己没有新的进度.</p> <p>但是成功拉了女朋友一起入坑, 正在做 Project 1. 🌚</p> <h3 id="vtb-出道">VTB 出道</h3> <p>使用 m1 mbp 而又急迫需要 linux 环境的同学一定听说过 Asahi Linux 这个发型版. 它自称 “A vanilla Arch Linux ARM environment”, m1 的性能续航再来跑 linux, 真的是香爆了.</p> <p>然后重点来了, Asahi Linux 有一个开发者 vtuber 出道了! 朝日リナ: <a href="https://www.youtube.com/c/AsahiLina">https://www.youtube.com/c/AsahiLina</a></p> <p>感觉挺有意思的;</p> <p>是时候在 Chaos Mesh 里推进一波了!</p> <p>稍微搜了下, 美少女皮淘宝上几百块就能买得到定制的, 等这个 Q 忙完了交差, 然后整个美少女皮来活跃社区气氛!</p> <blockquote> <p>尝试让这个项目保持有趣! (但是在奇怪的方向上)</p></blockquote> <h3 id="bugbash-活动">bugbash 活动</h3> <p>这次 bugbash 活动又开始了, 在这次, 有些问题终于积累得过久, 显现出来了:</p> <ul> <li>没有 assign 机制, 多个 contributor 同时修一个 bug</li> <li>PR 没 Issue; 很难意识到这个 PR 做了什么事情, liftbot 的扫描结果和 GitHub 依旧有些脱节; 或者, PR 里有一个指向问题的 URL 也好呀.</li> </ul> <blockquote> <p>有空去 bugbash slack channel 反映一下~</p></blockquote> <h3 id="绝妙的点子-使用-vercel-做类似于-uptime-robot-的事情">绝妙的点子: 使用 Vercel 做类似于 Uptime Robot 的事情</h3> <p>基本思路:</p> <ul> <li>serverless 不会死, 服务器“可能”遍布世界各地</li> <li>datadog 免费 tier 就有够用的 API 来写入时序数据以及进行查询</li> </ul> <p>但是遭到了朋友的“反击”:</p> <p> <p class="md__image"> <img src='./assets/no-serverless-uptime-robot.png' alt="No Serverless Uptime Robot" /> </p> </p> <h3 id="rust-the-book-竟然还能卖钱">rust the book 竟然还能卖钱</h3> <p>发现了这么一个好玩的玩意: <a href="https://item.jd.com/12878638.html">https://item.jd.com/12878638.html</a></p> <p>它就是 the book 的翻译版本, 竟然还能卖 CNY 140. 唏嘘.</p> <p>社区翻译<a href="https://github.com/rust-lang-cn/book-cn">就在这</a>, 而且还在活跃地更新. 这就是卖的信息差吗?</p> <h3 id="kubeadm-join-control-plane-使用第一个-etcd-的-member-进行健康检查">kubeadm join &ndash;control-plane 使用第一个 etcd 的 member 进行健康检查</h3> <p>refer: <a href="https://twitter.com/strrlthedev/status/1524789602967379968">https://twitter.com/strrlthedev/status/1524789602967379968</a></p> <blockquote> <p>有空去提个 issue.</p></blockquote> <h3 id="kubecon-来啦">kubecon 来啦</h3> <p>KUBECON EU 终于来了!</p> <p>俺这次有非常非常多想听的 talk, 主要集中在:</p> <ul> <li>可观测性</li> <li>混沌工程</li> <li>社区建设</li> </ul> <p>估计下周能就能看到俺对这次 KUBECON 的碎碎念了</p> <h2 id="生活相关">生活相关</h2> <h3 id="搬家">搬家</h3> <p>这是这周周报拖更的原因.</p> <p>换了一个更加舒服的房子, +1 室, 游戏室和书房分开了. 周末忙着搬家收拾东西所以没时间写了~</p> <p>新的地方有山有水有鸟有树, 散步不愁, 风景不愁. 太太太舒服了.</p> <p>而且住在一楼, 能不出家门飞无人机, 也能种种花草.</p> <p>之前无论和朋友, 还是和女朋友都聊到, 我好想有一个院子, 院子里有一个带大伞的桌子, 伞下的桌子有电有网. 大雨的时候, 我就在伞下办公! 绝了! 现在又近了一步哈哈哈.</p> <p>示意图:</p> <p> <p class="md__image"> <img src='./assets/my-dream.png' alt="My Dream" /> </p> </p> <h3 id="下班路上的趣事">下班路上的趣事</h3> <p>有一次齐电驴下班路上, 看到前面一个小男孩开开心心地骑着自行车在前面.</p> <p>然后他口袋里掉出来一个亮闪闪的卡片, 像我小时候收集的那种游戏王卡片类似, 但是大一圈.</p> <p>亮闪闪的卡片飞舞在空中, 提醒了我它估计是某个稀有级别的卡片.</p> <p>但是俺没有去帮他捡起来.🥲 他也没有意识到自己的宝贝掉了.</p> <p>回到家一定会哭很久吧.</p> 2022-18: 普通的周报 https://strrl.dev/post/weekly-report/2022/18-%E6%99%AE%E9%80%9A%E7%9A%84%E5%91%A8%E6%8A%A5/ Sun, 08 May 2022 13:21:02 +0800 https://strrl.dev/post/weekly-report/2022/18-%E6%99%AE%E9%80%9A%E7%9A%84%E5%91%A8%E6%8A%A5/ <p>这里又是一份周报, 时间范围是<code>2022-05-02</code>到<code>2022-05-07</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>本周没有进行 NAND2Tetris 的学习;</p> <h3 id="绝妙的点子from-推友-justforlxz-github-action-as-kubernetes-worker-node">绝妙的点子(From 推友 @justforlxz): GitHub Action as Kubernetes Worker Node</h3> <p>refer: <a href="https://twitter.com/justforlxz/status/1522949621982834689">https://twitter.com/justforlxz/status/1522949621982834689</a></p> <p>将 Abuse 进行到底!</p> <p>之前有一个项目叫 ORAS (OCI Registry As Storage), 可以将 github package 作为免费的存储.</p> <p>现在又有同学提出了使用 GitHub Action 蹭免费算力的好方向. 其实对于这种不稳定的计算资源, 只要搞好调度, 就可以拿来用了, 而 Kubernetes 可能非常适合做这件事!</p> <p>我准备后面也去试试, 或许能够嫖到其他免费 CI 的资源.</p> <blockquote> <p>当然计算资源有了以后, 剩下的问题是存储怎么办, 这个暂时还没有思路.</p></blockquote> <h3 id="kubecon-eu-online-折扣券">Kubecon EU Online 折扣券</h3> <p>refer: <a href="https://twitter.com/PingCAP/status/1521275594121617411">https://twitter.com/PingCAP/status/1521275594121617411</a></p> <p>KUBECON EU 马上就要开始了, 之前在 LFX Mentorship 认识的一位印度 Mentee 已经飞到西班牙线下参加了, 太羡慕了!</p> <p>无法出去的我只能线上参与, 为了省下 $75 的报名费, 有非常多的组织和社区开展了类似的活动, 一般只要大家转发并且叭叭两句就可以获取(直接打到免费的)折扣券了.</p> <h3 id="taichi-community-voxel-challenge">Taichi Community Voxel Challenge</h3> <p>refer: <a href="https://twitter.com/strrlthedev/status/1522583389462831105">https://twitter.com/strrlthedev/status/1522583389462831105</a></p> <p>Taichi 社区开展了一个非常有趣而且精彩的活动, 果然和艺术结合起来, 给人带来的快乐更大呀.</p> <p>大家的投稿在这边, 都非常的精彩: <a href="https://github.com/taichi-dev/voxel-challenge/issues/11">https://github.com/taichi-dev/voxel-challenge/issues/11</a></p> <h3 id="upstream-first">Upstream First</h3> <p>在整理 Chaos Mesh Release Cycle 时, 也想了想, 自己只在 Chaos Mesh 里自嗨是不行的. 还是要去多去活跃的社区里混.</p> <p>最近开始关注 Kubernetes 以及相关生态项目的 issue, 找一点力所能及的活干.</p> <p>报名了 Kubernetes Release Shadow Program.</p> <p>期望在接下来的的一年里能够成为某个 SIG 里活跃的一员吧.</p> <blockquote> <p>off-topic: 最近也参与了 <a href="https://www.nglab.io/incubator">NGLAB 孵化器</a> 这个项目, 希望学到一些在工程外的知识.</p></blockquote> <h3 id="开始了解项目管理">开始了解项目管理</h3> <p>作为工程师, 这个东西是避不开的. 虽然我并不想成为项目经理, 但是了解下如何管理项目总是需要的. 同时避免被不合格的项目经理带歪.</p> <p>开始看 Head First PMP. 希望在未来能够对自己的玩具项目也有一些规划, 如果能够把经验也应用到工作中那是更好的.</p> <h2 id="生活相关">生活相关</h2> <h3 id="杭州亚运会延期">杭州亚运会延期</h3> <p>因为疫情延期了, 具体日期未知.</p> <p>也希望能够减少下杭州基建的压力.</p> <h3 id="好玩的游戏-nintendo-sport">好玩的游戏 Nintendo Sport</h3> <p>在尘封许久的 NS 上买了这款游戏, 当晚劳累过度, 胳膊疼了好几天.</p> <p>电脑真的非常强, 网球项目里, &ldquo;非常强&quot;的电脑发的球根本接不住.</p> <p>只能我和女朋友在羽毛球里菜鸡互啄.</p> <h3 id="买了一个上头的-apple-pencil">买了一个上头的 Apple Pencil</h3> <p>并怎么不纯正的嘉心糖整了个活</p> <p>refer: <a href="https://twitter.com/strrlthedev/status/1522789483170582535">https://twitter.com/strrlthedev/status/1522789483170582535</a></p> <h2 id="其他">其他</h2> <p>最近调休, 心情不美丽, 没有太多脑洞, 周报有些应付.</p> 2022-17: 喜迎劳动节 https://strrl.dev/post/weekly-report/2022/17-%E5%96%9C%E8%BF%8E%E5%8A%B3%E5%8A%A8%E8%8A%82/ Mon, 02 May 2022 10:18:54 +0800 https://strrl.dev/post/weekly-report/2022/17-%E5%96%9C%E8%BF%8E%E5%8A%B3%E5%8A%A8%E8%8A%82/ <p>这里又是一份周报, 时间范围是<code>2022-04-24</code>到<code>2022-05-01</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>本周没有进行 NAND2Tetris 的学习;</p> <h3 id="给学校的镜像站扩容">给学校的镜像站扩容</h3> <p>大约一段时间之前(一个月前), mirrorz 的红人同学提醒 YNU MIRROR 已经停止更新了; 而直到上周我才去看;</p> <p>发现是分的 15T 空间已经不够用了:</p> <p> <p class="md__image"> <img src='./assets/mirror.png' alt="mirror" /> </p> </p> <p>然后顺手将它扩到了 25 TiB, 不得不说, ext4 的 online-resize 还是挺快的, 大约不到半小时就完成了 resize, 现在在正常工作了;</p> <p>但是追上游的更新还是要更久的时间 =.=</p> <h3 id="chaos-mesh-v220-released">Chaos Mesh v2.2.0 Released</h3> <p>Chaos Mesh v2.2.0 总算憋出来了, 憋了五个月, 笑死: <a href="https://github.com/chaos-mesh/chaos-mesh/releases/tag/v2.2.0">https://github.com/chaos-mesh/chaos-mesh/releases/tag/v2.2.0</a></p> <p>关于这种及其痛苦的发版模式, 亟待改善, 需要一个健康而且无压力的发版流程: <a href="https://github.com/chaos-mesh/chaos-mesh/issues/3172">https://github.com/chaos-mesh/chaos-mesh/issues/3172</a></p> <p>应该最近 1 - 2 内就会完成 draft proposal, 并在下一个 minor version 中得到初次的实践;</p> <h3 id="绝妙的点子from-keao-理论-sla-计算器">绝妙的点子(From Keao): 理论 SLA 计算器</h3> <p>最近在 Chaos Mesh 的头脑风暴中, keao 同学提出了一个非常 amazing 的点子: 理论 SLA 计算器.</p> <p>(在我的理解中,) SLA 计算器想做的事情是, 假设程序自身没有会导致可用性下降的前提下, 告诉 SLA 计算器该应用所依赖的各个服务(其他应用, 云服务, 基础设施, 中间件等), 以及依赖关系(强依赖? 带降级的弱依赖? 重试?), SLA 计算器能够得出当前的设计能达到的最大理论 SLA;</p> <p>例如, 我写了一个简单的 Web 程序, 它只有一个 <code>/ping</code> 接口, response body 固定为 <code>pong</code>. 然后我将它部署到单个 AWS EC2 上, 假设任何的网络都木有问题, 那么我的程序的 SLA 受限于 EC2, 是 <code>99.5%</code>;</p> <p>后面我再优化一下, 我部署 3 个副本到 3 个不同的 EC2 上, 并在前面使用一个 ELB 做负载均衡, 那我的程序的 SLA 应该是 <code>(1 - (1-0.995)^3)*0.9999 = 0.999899875</code>, 大约是 <code>99.9899875%</code> 了, 年度不可用时间大约为 52.6257 min;</p> <blockquote> <p>EC2 的单实例 SLA 不赔钱写的是 <code>99.5%</code>; <a href="https://aws.amazon.com/compute/sla/">https://aws.amazon.com/compute/sla/</a> ELB 的 SLA 不赔钱写的是 <code>99.99%</code>; <a href="https://aws.amazon.com/elasticloadbalancing/sla/">https://aws.amazon.com/elasticloadbalancing/sla/</a></p></blockquote> <p>如果这个时候, 我声明我的 SLA 在 <code>99.9%</code>, 即年度不可用时间为 525.6 min, 留得故障预算好像过于多了;</p> <p>而如果我声明我的 SLA 在 <code>99.99%</code>, 即年度不可用时间为 52.55999999999421 min, 和理论最大 SLA 相差约 4 秒, 看上去也是一个不错的选择; (拿 AWS 赔我的钱再赔给客户, 再倒贴点钱, 我就是赌狗)</p> <p>精彩的还在后面, 有了理论的 SLA 后, Chaos Mesh 能够向不同的组件和依赖注入故障, 来验证声明的依赖关系, 依赖方式等是否真的符合预期;</p> <p>例如刚才的例子上, 我声明了 ELB 会接到 3 个 EC2 上, 但是我实际运维的时候只接了 1 个; 错误注入到那个节点上时, 整个服务就瘫了;</p> <p>这个点子太有意思了, 有意思到甚至不想把它产品的 ROADMAP 里, 而是我们自己维护以及实现, 让它野蛮生长.</p> <h3 id="codeseeio">codesee.io</h3> <p>在公司群的聊天里发现了这么一个较为厉害的工具: <a href="https://app.codesee.io/">codesee.io</a>; 它能够将代码的依赖绘制出图, 甚至 golang 能够做到文件级别的依赖分析, 而不只是包级别哦!</p> <p> <p class="md__image"> <img src='./assets/chaos-mesh-dep-graph-1.png' alt="Chaos Mesh Dependency Graph 1" /> </p> </p> <p>例如从这个图上看, 有两个很显眼的问题:</p> <ul> <li>controllers 包里有东西依赖了 cmd 包</li> <li>pkg 包里有东西依赖了 controllers 包</li> </ul> <p>让我们仔细点开一下:</p> <p> <p class="md__image"> <img src='./assets/chaos-mesh-dep-graph-2.png' alt="Chaos Mesh Dependency Graph 2" /> </p> </p> <p>果然发现 <code>podnetworkchaos</code> 和 <code>util</code> 下面的一部分测试代码引用了 cmd 的内容. (铲掉铲掉!)</p> <p>再看看另外一边:</p> <p> <p class="md__image"> <img src='./assets/chaos-mesh-dep-graph-3.png' alt="Chaos Mesh Dependency Graph 3" /> </p> </p> <p>在 pkg 下, 也有 <code>ctrl</code>, <code>selector</code>, <code>dashboard</code>, <code>status</code>, <code>workflow</code> 中的不同内内容依赖了 <code>controllers</code> 包内的内容. 这也是需要整理的.</p> <blockquote> <p>如果出度入度/依赖被依赖能用不同的颜色表示那就更好了, 有时候箭头找不到啊..</p></blockquote> <p>另外它还有一个 tour 的功能, 看上去可以以动画的方式去过代码, 这对新人/社区贡献者熟悉代码可太有帮助了! 后面去研究一下;</p> <ul> <li>另外的遗憾是语言上还不支持 Kotlin;</li> <li>另外如果也能通过 openapi/graphql/其他 RPC schema 的方式, 把不同语言的依赖通过 openapi 联系在一起, 那也会非常的酷!</li> </ul> <h3 id="american-fuzzy-lop">american fuzzy lop</h3> <p>这周接触了 <a href="https://github.com/google/AFL">AFL</a>, 看上去它可以以一个引导试的方式来进行 fuzz test; 而且也有 golang 上的 port: <a href="https://github.com/dvyukov/go-fuzz;">https://github.com/dvyukov/go-fuzz;</a></p> <p>对 fuzzing 我还不是太熟悉, 等有了一些知识后再来分享下吧~</p> <h2 id="生活相关">生活相关</h2> <h3 id="无人机航拍">无人机航拍</h3> <p>买的 DJI MINI 2 到了! 拍了很多令我舒服的照片!</p> <p> <p class="md__image"> <img src='./assets/photo_2022-05-02_11-34-33.jpg' alt="photo" /> </p> <p class="md__image"> <img src='./assets/photo_2022-05-02_11-34-38.jpg' alt="photo" /> </p> <p class="md__image"> <img src='./assets/photo_2022-05-02_11-34-41.jpg' alt="photo" /> </p> <p class="md__image"> <img src='./assets/photo_2022-05-02_11-34-44.jpg' alt="photo" /> </p> </p> <h3 id="taichi-voxel-challenge">Taichi Voxel Challenge</h3> <p>最近看到了彦青姐的朋友圈, 发现了 taichi 社区的 Voxel Challenge 这么一个活动; 差不多就是用 99 行代码, 去画一写有意思的 3D 像素风作品;</p> <p>目前已经有很多有趣的作品已经提交到<a href="https://github.com/taichi-dev/voxel-challenge/issues/11">这里</a>了, 瞻仰瞻仰;</p> <p>俺自己手撸了一个 nyaacat, 奈何太菜, 撸完就已经将近 300 了, 苦于找办法 compact 中.</p> <p> <p class="md__image"> <img src='./assets/nyaacat-dark.jpg' alt="nyaacat dark" /> </p> </p> <p> <p class="md__image"> <img src='./assets/nyaacat-light.jpg' alt="nyaacat light" /> </p> </p> 2022-16: 小区静态管理 https://strrl.dev/post/weekly-report/2022/16-%E5%B0%8F%E5%8C%BA%E9%9D%99%E6%80%81%E7%AE%A1%E7%90%86/ Sun, 24 Apr 2022 20:13:36 +0800 https://strrl.dev/post/weekly-report/2022/16-%E5%B0%8F%E5%8C%BA%E9%9D%99%E6%80%81%E7%AE%A1%E7%90%86/ <p>这里又是一份周报, 时间范围是<code>2022-04-17</code>到<code>2022-04-23</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>本周没有进行 NAND2Tetris 的学习;</p> <h3 id="将-tidb-cloud-添加到了-free-fordev">将 TiDB Cloud 添加到了 free-for.dev</h3> <p>我之前在做 growth-of.codes, 尝试 serverless 的时候, 状态必须使用一个 SaaS, 调研了一些服务, 包括 Cloudflare KV, MongoDB 的 free-tier, 还有某个 Redis 的 free-tier 等. 但是各家的用量限制, 或者是调用 quota 都不是很高. 最终我选择了 TiDB Cloud, 因为提供了一年的 10 GiB 存储, 和不限量的调用 quota.</p> <p>后来 TiDB Cloud 结束了内部 dog-food 试用, 1-year free dev tier 开始对所有人开放, 这么好的东西肯定要分享出去, 因此我提了个 PR:</p> <p><a href="https://github.com/ripienaar/free-for-dev/pull/2408">Add TiDB Cloud Dev Tier. #2408</a></p> <p>大家可以试试, 和 serverless 真的是绝配了. (疯狂白嫖!)</p> <h2 id="生活相关">生活相关</h2> <h3 id="有趣的-gtd-工具-facilethings">有趣的 GTD 工具 FacileThings</h3> <p>较久之前, 我在看完 GTD 后开始构建自己的外部大脑; 使用的工具是 Notion, 得益于它强大的 database, 和页面内 block, 我构建出了一套灵活的工具流.</p> <p>Notion 工作得很好, 从过年附近到现在, 它已经帮我追踪并管理 406 件&quot;事情&quot;了.</p> <p>但是一件事情的实施并不是有了好用的工具就完事了, 很多时候我依然会忘记去做事情, 然后有时会懈怠, 有时会忘记怎么做; 后来我在 Notion 中建立了一个名为 GTD CheatSheet 的 Page, 手动整理以及记录自己需要做什么.</p> <p>在自己&quot;摸石头过河&quot;的途中我突然发现了这个工具: <a href="https://app.facilethings.com/">FacileThings</a>.</p> <p>对我来说, 它的亮点在于:</p> <ul> <li>丰富的&quot;文档&quot;</li> <li>在应用内时时刻刻提醒你, 你应该怎么做</li> </ul> <p>例如, <a href="https://facilethings.com/learning/en/tutorial/reviewing-your-lists">如何做 Daily Review</a>, <a href="https://facilethings.com/learning/en/tutorial/the-weekly-review">如何做 Weekly Review</a>, <a href="https://facilethings.com/learning/en/tutorial/getting-perspective">Purpose/Vision/Goal 级别的目标应该怎么定</a> 等等;</p> <p>在 UI 交互上, 也时刻提醒我, 你在做 XXX 的时候, 应该注意 XXXX:</p> <p> <p class="md__image"> <img src='./assets/facile-things-capture.png' alt="FacileThings Capture" /> </p> </p> <blockquote> <p>我是永远也不会点掉右上角的 &ldquo;Got it&rdquo; 了, 我就要他一直提醒我. 就像之前和某位产品经理朋友聊天, 他告诉我, 产品经理的作用并不只是规划一个宏伟且可行的蓝图, 而也要时刻提醒你, 你的东西用户用上去烂透了, 防止开发人员沉浸在自己的意淫中.</p></blockquote> <p>它的这些亮点可以完美的覆盖我的 GTD CheatSheet, 所以我挑了一个晚上, 将我的工具流从 Notion 搬到了 FacileThings 上. 整个迁移过程十分流畅且无痛, 体验非常好.</p> <p>再稍微说下缺点, FacileThings 是一款比较古老的应用, 貌似 2010 年就出现了; 因此它的 Web App 和安卓 App 都称不上是&quot;非常好用&quot;, 但是也绝对够用. 但是它只有 Web App 一个接入方式, 也不算太方便.</p> <p>我想在当下, 一个工具如果好用, 是一定要提供 API 的. 但是 FacileThings 没有文档说明他们有暴露 API, 然后尝试工单问了下, 没想到 CEO 亲自回答了:</p> <p> <p class="md__image"> <img src='./assets/facile-things-api.png' alt="Facile Things the ticket about API" /> </p> </p> <p>真好, 非常期待! 而且印象分 ++ ❤️❤️❤️</p> <h3 id="自动化记账">自动化记账</h3> <p>由于下周就要放五一假期了, 所以这周 TMD 要调休.</p> <p>真的很烦调休诶, 你说我本来周末一天 Review 自己, 一天休息多好. 结果周天要上班, 没时间反思自己了. (包括这个周报也是赶出来的)</p> <p>Weekly Review 目前最繁琐的事情就是 beancount 记账这件事, 我没有每天记录的习惯, 但是如果超出一周再去记, 那负反馈就直接打满, 以后就更不想记了.</p> <p>自动化记账的需求迫在眉睫!</p> <blockquote> <p>五一尝试去解决这个问题, 找一些自动化的轮子, 哪怕是 WebUI 用一下也好.</p></blockquote> <h3 id="小区静态管理">小区静态管理</h3> <p>我们小区它自己封了.</p> <p>上段时间据说我们小区某幢出现了病人, 但是无论是从微信杭州发布公众号上, 还是从 TG 的频道上, 都没有看到这个病例, 也没有看到我们这个地区(余杭区)的管控通知. 反倒是拱墅区的病例一直在更新, 也官宣了进行静态管制.</p> <p>我们小区就很迷惑, 有一部分离那幢楼近的人被拉去酒店 14 + 7 了, 其他人员不准出小区, 但是快递和外卖正常工作. (像是街道级别的措施) 🤔🤔🤔</p> <p>为了让大家取外卖和类似于盒马生鲜, 叮咚买菜的包裹, 在西门搭建了类似一个这样的区域:</p> <p> <p class="md__image"> <img src='./assets/package-exchange.jpg' alt="拿外卖" /> </p> </p> <blockquote> <p>因为有喇叭在喊&quot;快拿快取, 请勿逗留, 请勿折回, 请勿拍照&quot;, 我就没拍<del>把照片放出来</del>, 大家自行想象一下.</p></blockquote> <p>让我联想到了肺泡, 氧气(食物)从这个区域里进来, 被红细胞(我)带回家里, 来维持生命.</p> <blockquote> <p>有照片的官方报道: <a href="https://mp.weixin.qq.com/s/kIxVnjRmx-t453REg4wX6w">链接</a></p></blockquote> <h3 id="中耳炎它自己好了">中耳炎它自己好了</h3> <p>我的左耳它自己好了, 也不痛了, 也不痒了, 也不流脓了, 开心!</p> [翻译] 结对编程模板 https://strrl.dev/post/2022/translation/%E7%BB%93%E5%AF%B9%E7%BC%96%E7%A8%8B%E6%A8%A1%E6%9D%BF/ Sun, 17 Apr 2022 22:19:19 +0800 https://strrl.dev/post/2022/translation/%E7%BB%93%E5%AF%B9%E7%BC%96%E7%A8%8B%E6%A8%A1%E6%9D%BF/ <p><a href="https://tuple.app/pair-programming-guide/template">原文链接</a></p> <p><a href="http://strrl.dev/categories/%E7%BB%93%E5%AF%B9%E7%BC%96%E7%A8%8B/">结对编程系列</a></p> <hr/> <p>以下是你的下一次结对编程的模板:</p> <ol> <li><input disabled="" type="checkbox"> 大声地商定高层次的目标.</li> <li><input disabled="" type="checkbox"> 将工作分解成一只手数的过来的任务, 并对其按优先级排序.</li> <li><input disabled="" type="checkbox"> 决定你们的&quot;驾驶员&quot;/&ldquo;导航员&quot;互换策略.</li> <li><input disabled="" type="checkbox"> 配置 git 来分享&quot;信用&rdquo;.</li> <li><input disabled="" type="checkbox"> 消除分心的因素.</li> <li><input disabled="" type="checkbox"> 工作.</li> <li><input disabled="" type="checkbox"> 用一个小型的回顾来分析这次结对</li> </ol> <p>让我们对每个步骤进行详细讨论.</p> <h2 id="1-大声地商定高层次的目标">1. 大声地商定高层次的目标</h2> <p>大声地说出你们在较高层次上希望完成什么.</p> <p>你不会认为两个目标不一致的人开始结对编程是可能的, 但是(定义一致的目标)是出乎意料的简单.</p> <h2 id="2-将工作分解成一只手数的过来的任务-并对其按优先级排序">2. 将工作分解成一只手数的过来的任务, 并对其按优先级排序</h2> <p>将你们的高层次目标分解成少量的小步骤是值得尝试的.</p> <p>这又很多好处:</p> <ul> <li>这使得目标不那么令人生畏.</li> <li>你们更容易发现死胡同和陷阱.</li> <li>你们可以按照优先级对任务清单排序.</li> <li>你们更有可能注意到, 任务 C 比任务 B 更简单, 并适当地重新排序.</li> <li>你们可以根据你们目前的能量水平来决定当前的任务.</li> <li>它可以给你们一个地方来放置工作时想到的新任务.</li> <li><a href="https://www.jamesshore.com/v2/books/aoad1/pair_programming">有些人</a>喜欢将每个任务写到自己的索引卡上. 他们堆叠在&quot;导航员&quot;前. 每个卡片都可以成为记录笔记或者想法的好地方, 以便在中途休息时提炼出来.</li> </ul> <h2 id="3-决定什么时候交换驾驶员导航员">3. 决定什么时候交换&quot;驾驶员&quot;/&ldquo;导航员&rdquo;</h2> <p>Unless you already know what works best for you, I strongly recommend the Pomodoro Technique: 如果你已经知道怎么做对你们来说最有效了, 否则我强烈建议使用&quot;番茄钟&quot;:</p> <ul> <li>编码 25 分钟.</li> <li>休息 5 分钟.</li> <li>交换 &ldquo;驾驶员&rdquo;.</li> </ul> <p>如果你想尝试,还有其他的<a href="https://tuple.app/pair-programming-guide/styles">结对编程方式</a>.</p> <h2 id="4-配置-git-来分享信用">4. 配置 git 来分享&quot;信用&quot;</h2> <p>如果你们两个人在编写同一份代码, 你们两个的名字应该都出现在提交上.</p> <p>这里有一个方便的指南, 可以正确的配置 git.</p> <p>另外: GitHub 能够原生地明白这一点, 并把你们都显示在提交上.</p> <p>有一些工具可以让这件事情更简单:</p> <ul> <li><a href="https://github.com/chrisk/git-pair">git pair</a></li> <li><a href="https://github.com/git-duet/git-duet">git duet</a></li> <li><a href="https://github.com/kejadlen/git-together">git-together</a></li> </ul> <h2 id="5-消除分心的因素">5. 消除分心的因素</h2> <p>对你的搭档和工作表示尊重.</p> <ul> <li>不要带手机, 或者把它静音.</li> <li>禁用你用来结对编程的机器上的通知.</li> <li>关闭电子邮件/Slack/Twitter/IRC. 不要在第二台显示器上保留分散注意力的东西.</li> </ul> <h2 id="6-工作">6. 工作</h2> <p>做工!</p> <p>别忘了:</p> <ul> <li>作为导航员: 提出问题而不是提出需求.</li> <li>作为驾驶员: 说明你在做什么和为什么.</li> <li>尽量避免过度沟通.</li> <li>多中断, 多休息.</li> <li>经常互换角色.</li> <li>做(当下)最容易成功的简单事情.</li> <li>避免这些<a href="https://tuple.app/pair-programming-guide/antipatterns">结对编程反模式</a></li> </ul> <h2 id="7-做一次小型回顾">7. 做一次小型回顾</h2> <p>在结对结束后, 化几分钟反思下这次精力.</p> <p>首先, 讨论哪些做得好.</p> <p>然后, 考虑怎样才能让下一次做得比这次好上个 1%.</p> <p>可能需要改进的地方:</p> <ul> <li><strong>专注</strong>: 是否有分心的情况出现?</li> <li><strong>沟通</strong>: 是否有长时间不说话?</li> <li><strong>节奏</strong>: 配对是不是在任何时间都像在&quot;坐牢&quot;?</li> <li><strong>责任分工</strong>: 你们工作分配得好吗?</li> <li><strong>代码质量</strong>: 你们的最终产品是否高质量?</li> </ul> [翻译] 你的第一次结对 https://strrl.dev/post/2022/translation/%E4%BD%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BB%93%E5%AF%B9/ Sun, 17 Apr 2022 21:47:41 +0800 https://strrl.dev/post/2022/translation/%E4%BD%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BB%93%E5%AF%B9/ <p><a href="https://tuple.app/pair-programming-guide/the-case-for-pair-programming">原文链接</a></p> <p><a href="http://strrl.dev/categories/%E7%BB%93%E5%AF%B9%E7%BC%96%E7%A8%8B/">结对编程系列</a></p> <hr/> <p>首先: 放松. 你能行.</p> <p>结对编程只是两个人在一个任务上互相帮助. 你可能曾经&quot;意外地&quot;在面对棘手的 bug 或者新代码时和同事结对编程过.</p> <p>也就是说, 一开始有点紧张是很常见的. 因此, 第一次结对编程的最大敌人通常是紧张.</p> <p>这里有一些可以保持较低压力的技巧.</p> <h2 id="和一个和善的人进行尝试">和一个和善的人进行尝试</h2> <p>理想情况下, 你的第一次结对编程会和一个经验丰富的结对编程者进行尝试. 但是, 更重要的和善.</p> <p>变得更和善把.</p> <h2 id="在你是清醒的时候去做">在你是清醒的时候去做</h2> <p>争取在早晨的第一个事情时候就去做, 即咖啡因和动力都很高的时候.</p> <p>要特别避免在午饭后, 或这天很晚的时候去做.</p> <h2 id="符合人体工程学">符合人体工程学</h2> <ul> <li>相邻而坐, 让显示器离你们一样远</li> <li>为每个人插一个键盘</li> <li>稍微把字放大一点</li> <li>用一个你们都熟悉的编辑器/IDE</li> </ul> <h2 id="选一个轻松的任务">选一个轻松的任务</h2> <p>在你有了一些结对编程的经验后, 你会发现, 当问题变难时, 结对编程才会真正发会作用.</p> <p>但是在第一次结对编程时, 试着在没那么吓人的问题上进行尝试, 那些你已经知道如何较好完成的事情.</p> <h2 id="或者别叫它结对">或者别叫它&quot;结对&quot;</h2> <p>&ldquo;结对&quot;这个词带着一些包袱.</p> <p>如果这个想法让你的同伴感到害怕, 可以考虑不使用这个词.</p> <p>试着说&quot;我能看一眼吗&rdquo;?</p> <h2 id="试着聚众编程">试着聚众编程</h2> <p>有些朋友们发现聚众编程比两个人结对编程没那么吓人一些.</p> <p>下面是你们要做的:</p> <ul> <li>把三个或者更多的开发人员召集起来.</li> <li>把代码放到电视, 或者大显示器上.</li> <li>一个人&quot;开车&quot;, 其他人&quot;导航&quot;.</li> <li>频繁地换司机, 大约十分钟一次就好.</li> <li>惊叹于你们产生的代码质量, 你们从对方学到了多少东西, 以及这多么有趣.</li> </ul> <h2 id="时间框架">时间框架</h2> <p>从较短的时间开始, 45-60 分钟就差不多可以了.</p> <p>结对编程需要高于平均水平的注意力和沟通, 这可能会让你很快就感到疲惫不堪.</p> <p>随着时间的推移, 你的耐力会越来越强, 但一开始需要保持较短的时间.</p> <h2 id="在得出结论前再等等">在得出结论前再等等</h2> <p>在你的第一次结对编程后, 你可能会对结对编程有些看法.</p> <p>尽量避免这种情况.</p> <p>结对的同伴在质量和兼容性上差别非常大. 在你决定结对编程不适合你之前, 试着和五个不同的人尝试结对.</p> <h2 id="用一个模板">用一个模板</h2> <p>想为你的第一次结对编程得到更多的指导吗?</p> <p>请查看我们的 <a href="https://strrl.dev/post/2022/translation/%E7%BB%93%E5%AF%B9%E7%BC%96%E7%A8%8B%E6%A8%A1%E6%9D%BF/">结对编程模板</a> 获取一些想法.</p> 2022-15: 喜迎暗黑 3 第 26 赛季 https://strrl.dev/post/weekly-report/2022/15-%E5%96%9C%E8%BF%8E%E6%9A%97%E9%BB%91-3-%E7%AC%AC-26-%E8%B5%9B%E5%AD%A3/ Sun, 17 Apr 2022 12:42:46 +0800 https://strrl.dev/post/weekly-report/2022/15-%E5%96%9C%E8%BF%8E%E6%9A%97%E9%BB%91-3-%E7%AC%AC-26-%E8%B5%9B%E5%AD%A3/ <p>这里又是一份周报, 时间范围是<code>2022-04-10</code>到<code>2022-04-16</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="工作代码计算机相关">工作/代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>这周还没有学习 NAND2Tetris 哦;</p> <p>上周把 HACK Computer 做完了, 估计下半段的学习要主要到软件方面了.</p> <h3 id="气隙服务器-devsecops-zarf">气隙服务器 DevSecOps: zarf</h3> <p>在 twitter 无意中刷到了一个很酷的软件: <a href="https://github.com/defenseunicorns/zarf">defenseunicorns/zarf</a>, 它可以在气隙(没有或有限的外部网络连接)服务器中 delivery 镜像之类的.</p> <p>这和俺之前的 kubectl-push 想做的事情有些类似; 在设计时, 我遇到了一个 kubectl-push 如何 self-bootstrap 的问题, zarf 比较好地解决了这个问题, 让我们看看它是怎么做的吧:</p> <p>在 zarf 项目的 README 中的最后一段<a href="https://github.com/defenseunicorns/zarf#zarf-nerd-notes">Zarf Nerd Notes</a>, 简单介绍了 &ldquo;injector system&rdquo;, 描述了 zarf bootstrap 的过程:</p> <ul> <li>把一个 in-memory image registry 的 binary, 名为 <code>zarf-registry</code>, 以 512KiB 为大小切片, 放到 ConfigMap 中</li> <li>把一个 rust 写的拼装程序, 名为 <code>zarf-injector</code> 也放到 ConfigMap 中</li> <li>随便找一个可用的 image, 创建一个 &ldquo;injector&rdquo; Pod, 在 Pod 里挂载上述的 ConfigMap, 启动拼装程序, 让 in-memory image registry 开始 serve. (这个是 short-term 的registry)</li> <li>使用 portforwarding, 将 Zarf Registry 的 image 传上去</li> <li>创建 &ldquo;zarf-docker-registry&rdquo; Pod, 通过这个 in-memory registry 拉刚才的镜像并启动. (这个是 long-term 的 registry)</li> <li>bootstrap 完毕, 清理 ConfigMap 和 Pod</li> </ul> <p>这个思路非常好! 先通过 ConfigMap delivery 一些小东西, 然后再 Delivery 自己真正的东西.</p> <p>截至当前, zarf 中这两个 binary 文件大小如下, 需要使用 29 个 ConfigMap, 不清楚对 apiserver 以及 etcd 的负担有多大.</p> <p> <p class="md__image"> <img src='./assets/zarf.png' alt="zarf" /> </p> </p> <blockquote> <p>想水个改 typo 的 <a href="https://github.com/defenseunicorns/zarf/pull/438">PR</a>, 然后被他们的开发人员在更大的 PR 里给海纳百川了, 没蹭到 contribution.</p></blockquote> <h3 id="pointer-receiver-的误导">pointer receiver 的误导</h3> <p>关联: <a href="https://twitter.com/strrlthedev/status/1514628768492507141">https://twitter.com/strrlthedev/status/1514628768492507141</a></p> <p>最近在 review Chaos Mesh 的时候, 发现有相当一部分的 Constructor 返回的是 struct 而不是 pointer, 然后这个 struct 中用了类似于 <code>sync.Mutex</code> 等不能 copy value 的东西. 然后有些方法用的是 value receiver 而不是 pointer receiver.</p> <p>对于第一个问题其实没啥好说的, 修了就好了;</p> <p>对于第二个问题, 想到了之前和同事发生过的一段对话, &ldquo;如果用 pointer receiver 会使内存分配到堆上, 而 value receiver 会在栈上, 为了性能考虑, 我要用 value receiver&rdquo;.</p> <blockquote> <p>过早优化是万恶之源.</p></blockquote> <p>当然还有一些其他理由, 比如说&quot;默认/推荐用 value receiver&quot; 什么的. 当时我没太在意, 但是我怀疑是不是 go 的官方文档在哪里误导了.</p> <p>查了一下, 果然, 在 A Tour of GO 中有如下描述:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">There are two reasons to use a pointer receiver. </span></span><span class="line"><span class="cl">The first is so that the method can modify the value that its receiver points to. </span></span><span class="line"><span class="cl">The second is to avoid copying the value on each method call. </span></span></code></pre></td></tr></table> </div> </div><p>这种就给人一个&quot;除了这两个情况之外, 请默认使用 value receiver&quot;的意义.</p> <p>其实工程代码还是更像 <a href="https://github.com/golang/go/wiki/CodeReviewComments#receiver-type">Go Code Review Comments</a> 中所说的, 用 pointer receiver 更加普遍.</p> <p>有一个相关的 <a href="https://github.com/golang/go/issues/17524">issue</a> 以及 <a href="https://go-review.googlesource.com/c/tour/+/31728/">CL</a> 提及了这个问题, 但是看来后续没有跟进了.</p> <h2 id="生活相关">生活相关</h2> <h3 id="尝试时间追踪类软件">尝试时间追踪类软件</h3> <p>看到推友在使用 toggl tracking, 我觉得非常的好用, 于是这周尝试了下.</p> <p>比如说这周, 感觉天天都在开会和写材料, 之前是没有什么客观定量分析的, 但是现在就有了:</p> <p> <p class="md__image"> <img src='./assets/toggl-track-report.png' alt="toggl track report" /> </p> </p> <p>使用 Project 的方式对记录的时间简单分了下类, 就有了很直观的感受了.</p> <p>目前使用上来说, 方便是非常方便的, 有 Web 端, 安卓 APP, Linux 和 macOS 也都有 native app.</p> <p>安卓上还有小组件, 放到首屏提醒自己:</p> <p> <p class="md__image"> <img src='./assets/photo_2022-04-17_15-08-09.jpg' alt="toggl android" /> </p> </p> <p>但是个人的记录习惯还没有养成, 需要继续培养~</p> <h3 id="换了个双屏配置">换了个双屏配置</h3> <p>关联: <a href="https://twitter.com/strrlthedev/status/1514227327198466052">https://twitter.com/strrlthedev/status/1514227327198466052</a></p> <p>脖子还在适应中, 感觉副屏使用率比竖屏那种方式高一些.</p> <h3 id="尝试冥想">尝试冥想</h3> <p>最近看了一下关于冥想的书, 对冥想有了一些很粗浅的认识.</p> <p>冥想不是什么都不去想, 因为人的思绪就是会不停的冒出来的. 冥想是在思绪冒出来后, 尽量不让自己的意识被思绪抓走了, 而是 let it go, 或者被抓走后, 意识再回来.</p> <p>一个比较有趣的想象场景或者比喻就是, 你坐在公路旁边, 公路就是你的脑袋, 你的思绪就像一辆辆开过去的车. 好事情的思绪就像好车开过, 你的注意力就可能被好车吸引了. 坏事情的思绪就像破车开过, 你可能就想阻止破车开在你的公路上.</p> <p>冥想做的事情是, 尽量不要管这些车, 就随他去, 无论是好车还是破车, 不去尝试去控制他们.</p> <p>感觉这像一中 meta thinking(Metacognition?), 让自己对自己的想法有一个客观的认识. 有了想法以后, 总是有冲动去行动, 而冥想是尝试在行动前, 有更多的客观认识.</p> <p>自己简单尝试了下, 在早上起床后, 是比较容易进入这种状态的. 而在下午或者晚上, 就会比较难, 脑子的冒出的思绪就经常更加&quot;重要&quot;或&quot;具有吸引力&quot;, 会更加难以&quot;回到公路旁&quot;.</p> <h3 id="暗黑-3-第-26-赛季">暗黑 3 第 26 赛季</h3> <p>这周五新赛季开了! 这次的赛季特点是梦魇回响, 收益是给的经验非常多, 类似于很早前的大米打票评定等级.</p> <p>我和女朋友双双选择了猎魔人开荒, 在大约四个小时候达到了 70 级, 六个小时后做完赛季旅程.</p> <p>第二天上午掠夺者箭塔 BD 就齐了, 下午冰吞转转也齐了.</p> <p>这次开荒无论是运气还是效率来说是最高的一次, 中间木有太多被卡住的时候.</p> <p>不过克己守心对戒好像暗改了, 扫射出的追踪箭不能触发克己的效果了.</p> <p>准备后面去玩一个野蛮人去试试新 BD 雷蔻抛石.</p> <h2 id="其他">其他</h2> <p>这周好像有些敷衍, 不说了, 我要刷暗黑去了.</p> [翻译] 结对编程案例 https://strrl.dev/post/2022/translation/%E7%BB%93%E5%AF%B9%E7%BC%96%E7%A8%8B%E6%A1%88%E4%BE%8B/ Mon, 11 Apr 2022 22:34:47 +0800 https://strrl.dev/post/2022/translation/%E7%BB%93%E5%AF%B9%E7%BC%96%E7%A8%8B%E6%A1%88%E4%BE%8B/ <p><a href="https://tuple.app/pair-programming-guide/the-case-for-pair-programming">原文链接</a></p> <p><a href="http://strrl.dev/categories/%E7%BB%93%E5%AF%B9%E7%BC%96%E7%A8%8B/">结对编程系列</a></p> <hr/> <blockquote> <p>这篇文章主要是基于作者在开发与结对编程方面的丰富经验而提出的论点. 如果你想阅读关于科学研究结对编程的总结, 请查看的我们的这篇<a href="https://tuple.app/pair-programming-guide/scientific-research-into-pair-programming">Scientific Research Into Pairing</a>文章.</p></blockquote> <h2 id="用三句话">用三句话</h2> <p>随着时间的推移, 团队的产出会变慢, 因为他们积累了一些欠佳的代码, 而这阻碍了团队的进度.</p> <p>一对程序员会倾向于写出比独立工作的程序员更好的代码.</p> <p>经常进行结对编程的团队将更长时间地保持快速的产出速度.</p> <h2 id="用三段话">用三段话</h2> <p>一个产出速度慢的团队总是一致产出慢, 因为他们正同一个欠佳的代码(codebase)作斗争. 这将花费非常多的时间来修复 bug 和回退, 然后发现你的代码变更以惊人的方式对整个系统都产生了影响, 需要深入探索才能够作出改变. 你可以写出将这些问题最小化的代码, 只是难度更大.</p> <p>结对编程为这一挑战带来了更多的睿智的火力! 通过两双眼睛, bug 会被更早地被发现. 有了两个脑袋在头脑风暴, 能够找到更多的创造性的解决方案. 一个人在一直观察, 可以少走一些弯路(也可以少分一些心).</p> <p>通过结对编程来投资高质量的代码, 可以带来更好的代码库(codebase), 从而使未来的开发工作能够更快的进行.</p> <h2 id="用三小节">用三小节</h2> <h3 id="到底是什么拖慢了开发速度">到底是什么拖慢了开发速度?</h3> <p>解答这个问题的最好方式, 就是看看产出速度慢的团队花了这么多时间做了什么事:</p> <ul> <li><strong>回退.</strong> 慢的团队经常在无意中破坏了之前正常工作的特性.</li> <li><strong>修复新 bug.</strong> 慢的团队无法覆盖新功能中的所有边界情况, 而是在已经&quot;完成&quot;工作后, 生产环境中才发现它们.</li> <li><strong>对抗坏的架构.</strong> 慢的团队在不稳定的基础上进行构建. 当发现架构不好时, 他们不会咬紧牙关去修复它.</li> <li><strong>重写.</strong> 慢的团队发现他们的项目质量到了一个&quot;理解和改变比扔掉一切重写&quot;的水平.</li> <li><strong>分散注意力.</strong> 慢的团队经常被会议和社交媒体分散注意力.</li> </ul> <h3 id="结对编程如何帮助解决问题">结对编程如何帮助解决问题?</h3> <ul> <li><strong>回退.</strong> 回退是可以通过一个测试套件(test suite)来预防的. 多数人都知道他们应该写测试, 但是他们没有坚持这样做. 在结对编程中, 测试的水平会趋向于两位参与的开发者的最大值.</li> <li><strong>修复新 bug.</strong> Bug 往往隐藏在未被考虑的边界情况中. 在结对编程中, 一位开发者明确地负责思考这些边界情况, 而另一位开发者负责打字, 这增加了边界情况被正确处理的机会.</li> <li><strong>对抗坏的架构.</strong> 当每个架构上的决定都由两个人共同考虑时, 团队倾向于找到优秀的解决方案.</li> <li><strong>重写.</strong> 这仍然有可能会发生, 但如果有了更高的质量, 在必须重写前它能够撑得更久.</li> <li><strong>分散注意力.</strong> 没有什么比一个你桌子旁的人, 更能够改变你刷 Twitter 的习惯了.</li> </ul> <h3 id="咋开始呢">咋开始呢?</h3> <p>查看我们的指导: <a href="https://strrl.dev/post/2022/translation/%E4%BD%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BB%93%E5%AF%B9/">你的第一次结对</a>.</p> 2022-14: 普通的周报 https://strrl.dev/post/weekly-report/2022/14-%E6%99%AE%E9%80%9A%E7%9A%84%E5%91%A8%E6%8A%A5/ Sat, 09 Apr 2022 21:37:19 +0800 https://strrl.dev/post/weekly-report/2022/14-%E6%99%AE%E9%80%9A%E7%9A%84%E5%91%A8%E6%8A%A5/ <p>这里又是一份周报, 时间范围是<code>2022-04-05</code>到<code>2022-04-09</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="代码计算机相关">代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>花了俩小时, 把 week 5 的实验写完啦!</p> <p>很感叹那怕是 HACK 这样看似简单的计算机, 内部的设计已经非常精巧/巧妙了.</p> <p>对于我来说, 我只能处在一个&quot;能看懂&quot;的水平上了, 让我去设计不知道再花多少时间才能学会.</p> <p>对手上的计算设备有了更多的敬畏. 计算机不愧是人类智慧的结晶(之一).</p> <h3 id="dodo-saysdodo-poc-完成">dodo-says/dodo PoC 完成</h3> <p>接<a href="https://strrl.dev/post/weekly-report/2022/13-%E6%B8%85%E6%98%8E%E5%81%87/#%E5%8C%BF%E5%90%8D%E8%AE%BA%E5%9D%9B-what-does-dodo-say">上文</a>, 这个周末完成了最初的 PoC, 实现了最基础的功能:</p> <ul> <li>只有一定数量的委员会成员同意后, 才能解密原文;</li> <li>通过使用其私钥解密某特定内容, 表示委员会成员同意;</li> </ul> <p>稍微记录了一下使用方式, 欢迎来试试 <a href="https://github.com/dodo-says/dodo#basic-usage--demo">dodo</a>!</p> <p>预计后面会写一篇文章以故事的形式来描述 dodo 想要做什么事情.</p> <h3 id="学习些前端知识">学习些前端知识</h3> <p>很惭愧, 自己对前端知识一直&quot;半瓶子不满&quot;, 长期处在一个&quot;能用框架, 不懂原理&quot;的情况上.</p> <p>最近学习了一下 babel, webpack, css 布局, 感觉有了新鲜的认知, 又捅破了一丢丢窗户纸. 😜</p> <p>愈来发现我需要去整体过一下 ES2015 的 spec / reference 了.</p> <blockquote> <p>回想起来, 自己真正看完的第一个系统性的文档是 Spring Boot Reference, 从那以后, 我意识到碎片化的知识的质量不如系统性的知识, 前者一定需要自己整理后才会产生作用.</p></blockquote> <h3 id="好用的工具-health-sync">好用的工具: Health Sync</h3> <p>最近再想, 怎么把自己的健康信息通过 API 拿出来, 做个统计什么的. 由于我目前还是用的三星的一系列设备, 而三星并没有做的像 Apple 的 HealthKit 那样好用的 API; 尝试导出 CSV 然后在导入, 无奈数据量太多又没有 schema, 靠猜意思去解析是行不通的;</p> <p>虽然三星没有 API 但是谷歌有哇, 只要把健康数据同步到 Google Fit 就可以了. 自己建立一个 APP 然后使用 OAuth 就可以调 Google Fit 的 API 拿自己想要的东西了.</p> <p>然后发现了这个工具: <a href="https://play.google.com/store/apps/details?id=nl.appyhapps.healthsync&amp;hl=en&amp;gl=US">Health Sync</a>, 目前我的使用方式是每 15 min 就把三星健康中的数据同步到 Google Fit 中.</p> <blockquote> <p>有了 API 可以做什么呢? 还没想好, 估计是替代我日记中的每日健康统计吧.</p></blockquote> <h3 id="新点子-弹幕玩星际">新点子: 弹幕玩星际</h3> <p>之前在 B 站的时候, 发现了一位有趣的 up 主 <a href="https://space.bilibili.com/34239">_pdz</a>, ta 的直播间一般是常开的, 内容是<a href="https://live.bilibili.com/704155">弹幕玩红警 3</a>. (印象中 ta 把源码放到 GitHub 了, 只是我一时找不到链接了.)</p> <p>作为星际的老粉, 我觉得这个有趣的形式应该也可以用到 SC2 里去. 而且之前曾经有一波 AI 玩 SC2 的风潮, 我觉得 SC2 的 API 应该会更加完备一些.</p> <blockquote> <p>都是 08 年的 dead game, RA3 可以 SC2 也行!</p></blockquote> <p>大略搜了下, 可供参考的内容有:</p> <ul> <li>SC2 API <ul> <li>Offical C++ API: <a href="https://github.com/Blizzard/s2client-api">Blizzard/s2client-api</a></li> <li>Community Python API: <a href="https://github.com/BurnySc2/python-sc2">BurnySc2/python-sc2</a></li> </ul> </li> <li><a href="https://aiarena.net/">SC2 AI Arena</a>, 是 AI 玩星际的排行榜, 大家上传自己的模型, 这个站点不停地举行对战, 进行线上 Streaming, 记录对战记录并更新积分榜. <ul> <li>这个平台有一个功能, 允许任何人贡献自己的机器作为算力作为 worker 跑对战, 只需要启动一个 docker 容器就可了; 我觉得里面可能会有一个 headless 的星际客户端;</li> <li>这个站点有 24/7 的 <a href="https://aiarena.net/stream/">live streaming</a> 功能, 点进去看了看, 镜头切的也比较合理, 也不会长时间盯着一个地方看而变得无聊. (点进去就看到了托马斯溜枪兵(卡射程拉扯消耗, 极限微操)这种有趣的画面)</li> </ul> </li> </ul> <p>放张截图, 这是另一局 ZvZ, 蓝色方直接三矿开到对面然后爆狗推了:</p> <p> <p class="md__image"> <img src='./assets/ai-zvz.png' alt="ZvZ" /> </p> </p> <p>等心情好的时候可以考虑梭一把了!</p> <h3 id="新想法-监控数据的频域分析">新想法: 监控数据的频域分析</h3> <p>起因, 经过:</p> <p> <p class="md__image"> <img src='./assets/metrics-frenquency-domain-analysis.png' alt="metrics frequency domain analysis" /> </p> <p class="md__image"> <img src='./assets/metrics-frenquency-domain-analysis-2.png' alt="metrics frequency domain analysis 2" /> </p> </p> <p>只能说有点好奇吧, 但是相关的事情肯定有人做过了.</p> <blockquote> <p>所谓的大数据不就是拿着我的行为时序数据, 然后对我做预测吗.</p></blockquote> <h2 id="生活相关">生活相关</h2> <h3 id="好喝的柠檬撞奶">好喝的柠檬撞奶</h3> <p>在书亦烧仙草发现了一个好喝的&quot;柠檬撞奶&quot;, 去冰少糖, 有姜和柠檬的味道.(一周内好像喝了三次了, 好喝的.)</p> <p>女朋友试过的另一款饮品叫&quot;橙漫山茶花&quot;, 也非常不错.</p> <p>我发现这两款饮品都有一个共同点, 前期是强烈的味觉刺激, 后期是持久的嗅觉刺激:</p> <ul> <li>柠檬撞奶, 前面是姜和椰奶的味道, 后续是柠檬的清香;</li> <li>橙漫山茶花, 前面是橙子的酸甜, 后续是乌龙茶的清香;</li> </ul> <p>前期刺激猛烈, 后期感觉持久, 二者加在一起, 有点像是&quot;猛烈的刺激持续&quot;很久的感觉;</p> <p> <p class="md__image"> <img src='./assets/drinking.jpg' alt="drinking" /> </p> </p> <p>这种东西太神奇了, 通过欺骗自己的感官, 让自己获得了持久的快乐.</p> <h3 id="京东快递资源紧张">京东快递资源紧张</h3> <p>因为上海疫情的原因, 可能各大家物流公司都去参与统筹了吧. 在京东自营上买的东西, 有一周了还木有发货.</p> <p>不太好.</p> <h3 id="杭州的目前囤菜冲动还比较克制">杭州的目前囤菜冲动还比较克制</h3> <p>近一周去了永辉和盒马, 发现蔬菜水果的库存还是蛮多的, 大家也没有出现很强的囤货冲动.</p> <p>挺好的.</p> <h3 id="瞎想-卡比是怎么飞起来的">瞎想: 卡比是怎么飞起来的</h3> <p>最近新游戏 <em>星之卡比探索发现</em> 上线啦! 虽然俺还没有买和玩, 但是看了一些视频内容. 让我产生了新的瞎想: 卡比是咋飞的?</p> <p>卡比在飞的时候处于这个状态:</p> <p> <p class="md__image"> <img src='./assets/kirby-fly.png' alt="kirby fly" /> </p> </p> <p>像是含了一大口气, 体积变大, 然后飘起来了.</p> <p>这让我们能联想到什么? 对, 就是<strong>潜水艇</strong>.</p> <p>但是如果需要在空气中漂浮/飞行的话, 填充物的密度必须比空气低才行.</p> <p>然后我提出了大胆的猜想:</p> <p><strong>在飞行时, 卡比的内部空间为真空.</strong></p> <p>然后我们再思考, 卡比能够无限制吸入空气, 甚至可以能够作为攻击手段</p> <p> <p class="md__image"> <img src='./assets/kirby-inhale.png' alt="kirby inhale" /> </p> </p> <p>所以我再大胆的猜测:</p> <p><strong>卡比内部有一个可控的隧道, 另一端连接着真空环境.</strong></p> <blockquote> <p>或者再激进点, 卡比里面有个黑洞?</p></blockquote> <p>这样, 为什么卡比能够吸入, 卡比为什么能漂浮, 就都能解释得通了, 感觉非常的合理! 🤩👍</p> <h3 id="国产-wemod-一修大师">国产 WeMod &ldquo;一修大师&rdquo;</h3> <p>最近发现了游侠网发布了一个类似 WeMod 的修改器集合产品 &ldquo;一修大师&rdquo;.</p> <p>除了关闭修改后, 会给你打开浏览器到游侠网官网外, 还没有其他明显流氓行径.</p> <h2 id="其他">其他</h2> <h3 id="开源只是手段-不是目的">开源只是手段, 不是目的</h3> <p>我还没有办法完全理解这句话.</p> <p>我就是个喜欢写代码的人, 能让我开心的写代码我就没有其他的烦恼了. 开源能够使我和世界上其他优秀的工程师共事, 合作, 分享, 这件事情实在是太美妙和激动了.</p> <p>但是最近和 dalao 们的聊天中发现, 在商业公司中写代码, 工程师需要自己去掌握主导权和话语权. 否则就会被其他人抢走主导权. 而这个其他人可能是产品, 可能是商业, 可能是其他任何没有软件工程知识的人(或者组织).</p> <p>所有人的认知都是片面的, 工程师擅长工程, 市场部门擅长商业, (其他部门负责其他), 任何一方获得过多的主导权都可能会导致&quot;大事&quot;(比如说创业成功, 项目获得业界广泛认可并采用等)的方向或者执行出现问题.</p> <p>所以我为了开心写代码, 不得不去考虑更多的问题, 要花时间和其他人探索方向, 做 trade-off.</p> <p><a href="https://warp.dev">warp.dev</a> 是最近的一个热门项目, 虽然它目前还没有开源, 但是它有开源的计划, 而且对于个人用户也是免费的. 他的商业计划在这里<a href="https://github.com/warpdotdev/Warp/discussions/400">Open sourcing Warp and business model</a> (俺自己还没看, 哭哭)</p> <p>据说这是一种被称为 Product-Led Growth 的方式, 类似是以产品为中心的发展策略. 我需要更多的时间来理解它.</p> <p>&ldquo;Chaos Mesh 的目的是什么呢&rdquo; 将会是我未来一段时间要解决的问题.</p> <h3 id="开源项目的代码质量">开源项目的代码质量</h3> <p>开源协作意味着各种经验的人会提交 PR 到仓库, 而合 PR 的&quot;标准&quot;是&quot;只要这个 PR 有积极意义&quot;就会被合并.</p> <p>这就意味着开源项目的 maintainer 需要花费时间去单独在代码质量上作出改进才行.</p> <p>而改进代码质量这个东西是很难去量化的, 因为他不会带来直接的&quot;效益&quot;.</p> <p>代码质量问题就像是空气污染问题, 我知道我需要洁净的空气, 但是我对于空气质量&quot;优&quot;, &ldquo;良&rdquo;, &ldquo;轻度污染&rdquo;, &ldquo;重度污染&quot;缺少直接/线性的认知, 也有相当一部分人群长久生活在&quot;重度污染&quot;中.</p> <p>我的生存本能觉得, 空气质量改进一下是好事, 但是说服不了自己, 因为这件事带来不了什么明显的生活质量改变.</p> <p>我的工程师经验觉得, 代码质量改进一下是好事, 但是说服不了上级, 因为这件事带来不了什么明显的效益.</p> <blockquote> <p>以上均是个人观点, 不代表其他任何组织和自然人的立场;</p></blockquote> 2022-13: 清明假 https://strrl.dev/post/weekly-report/2022/13-%E6%B8%85%E6%98%8E%E5%81%87/ Mon, 04 Apr 2022 17:01:11 +0800 https://strrl.dev/post/weekly-report/2022/13-%E6%B8%85%E6%98%8E%E5%81%87/ <p>这里又是一份周报, 时间范围是<code>2022-03-27</code>到<code>2022-04-04</code>, 会记录一些工作及生活上有意思的事情.</p> <blockquote> <p>这周周六补了一天班, 昨天玩了一天, 周报也顺势顺延啦!</p></blockquote> <h2 id="代码计算机相关">代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>Week 5 视频看完了, 作业还在做.</p> <blockquote> <p>¯\<em>(ツ)</em>/¯</p></blockquote> <h3 id="用上-arch-linux-啦">用上 Arch Linux 啦</h3> <p> <p class="md__image"> <img src='./assets/arch.jpeg' alt="Arch Linux" /> </p> </p> <p>因为之前是使用 btrfs 装的 fedora, 这次只需要新建一个 subvolume 作为根装上 arch, 不需要动 home 就活了.</p> <p>之前的很多东西都还在, 心情比较舒畅.</p> <p>目前还有各种各样的缩放问题没有调整好, 其余暂时没有什么问题.</p> <p>用 <code>yay</code> 装包实在是太方便了.</p> <h3 id="匿名论坛-what-does-dodo-say">匿名论坛 what-does-dodo-say</h3> <p>接<a href="https://strrl.dev/post/weekly-report/2022/12-%E8%B4%A2%E5%B9%B4%E6%9C%AB/#%E5%8C%BF%E5%90%8D%E8%AE%BA%E5%9D%9B%E5%BC%80%E5%B7%A5%E4%BA%86">上文</a>, 开坑了开坑了, 开了两个坑:</p> <ul> <li>主仓在 <a href="https://github.com/dodo-says/what-does-dodo-say">dodo-says/what-does-dodo-say</a></li> <li>PoC 仓在 <a href="https://github.com/dodo-says/dodo">dodo-says/dodo</a></li> </ul> <p>昨天今天已经在在 PoC 仓库里写一些代码了, 希望明天能够写完 committee 相关的行为, 然后把加密引进来.</p> <h3 id="flux-cd-on-homelab">Flux CD on homelab</h3> <p>之前一直直接使用 yaml manifest 作为 homelab kubernetes 集群的描述文件, 但是随着 homelab 中使用 helm 安装的东西越来越多, 只放一个 helm chart <code>values.yaml</code> 逐渐不太变得不太合适了.</p> <p>受 Kubernetes Pattern 的影响, 对 Watch/Reconcile 有一些偏好, 比较喜欢使用 Flux 作为 Homelab 的 CD 工具.</p> <p>不过迁移过程还是有些痛的, 需要把老的 helm release 删掉然后重新使用 Flux CD 装一遍.</p> <p>目前已经完成了 Cilium, Cert Manager 和 traefik 的迁移, 还有剩下一部分令人头疼的部分, 比如说:</p> <ul> <li>Rook Ceph</li> <li>Prometheus Operator</li> </ul> <p>剩下的问题后面再慢慢考虑吧.</p> <h3 id="使用-cloudflare-access-暴露部分服务">使用 Cloudflare Access 暴露部分服务</h3> <p>自己在 homelab 上部署了一些好玩的服务, 比如说 calibre, jellyfin 以及一些搜刮器什么的, 然后在家里的网络里做了域名劫持, 直接指向 kubernetes 的 worker node.</p> <p>在看了 Nova Kwok 的一片博文: <a href="https://nova.moe/accelerate-and-secure-with-cloudflared/">使用 Cloudflare Argo Tunnel(cloudflared) 来加速和保护你的网站</a> 后, 我萌生了将我的服务网暴露到公网的想法.</p> <p>简单试了一下, 效果很差. 链接质量非常差劲, 只能带的动简单的 API 以及文字较多的网页. 像 homer 这种服务也都需要很久才能加载出来.</p> <p>估计后面要去详细了解一下 Cloudflare 的各种机制才能去定向优化了.</p> <blockquote> <p>看到 Cloudflare Zero Trust 的控制面板里非常多的功能, tuna 群里也有同学提到了可以使用 Cloudflare 在网页中进行内网的 SSH 与 VNC, 看上去也是非常的香! 有希望在未来把通过 zerotier 回家这个方案替换掉.</p></blockquote> <h3 id="从-cncf-申请的计算资源拿到了">从 CNCF 申请的计算资源拿到了</h3> <p>大约等了一段时间后, 同组的同学收到了来自 CNCF 的 Equnix Metal 的激活邮件.</p> <blockquote> <p>但是俺还没有收到, 不知道是漏发了还是什么其他的原因. 🥲</p></blockquote> <p>同组的同学立刻开了一台 32C128G 的 ARM 机器出来, 非常的痛快!</p> <h2 id="生活相关">生活相关</h2> <h3 id="星际-2-cg-剪辑">星际 2 CG 剪辑</h3> <p>发现了一个将近一个半小时的星际争霸 2 CG 剪辑, 4K 升采样过的.</p> <p>1.5 倍速过了一遍, 啊好怀念.</p> <p><a href="https://www.youtube.com/watch?v=Bu0B4busV5c">视频地址</a></p> <p>个人依旧觉得最令人舒服的镜头是, 星灵重新夺回自己的母星艾尔后, 一段重新建设的&quot;延迟摄影&quot;(<a href="https://youtu.be/Bu0B4busV5c?t=4215">1:10:15</a> 开始). 配合着大主教旁白 &ldquo;gather the survivors, rebuild our cities&rdquo;, 多少还算是个 happy ending.</p> <p> <p class="md__image"> <img src='./assets/aiur.png' alt="艾尔" /> </p> </p> <blockquote> <p>星际争霸啥时候出电影啊?</p></blockquote> <h3 id="想买-acgmikucom">想买 acgmiku.com</h3> <p>Vocaloid 同好协会/acgmiku.com 是俺在高中以及大学早期长混的一个社区, 俺曾经也是一位论坛管理员; 但是后期由于 V 圈的没落和管理人员内部的分裂, 这个站现在已经被挂了巨量广告然后也无人维护了.</p> <blockquote> <p>甚至联系到早期成员, 都没人知道这个站域名在谁那里, 后面的机器在谁那里.</p></blockquote> <p>在 whois 信息中中到了 networksolutions 的这个信息, 只能挂一个 backorder 去慢慢捞了.</p> <p>如果能捞到, 坐一个静态页放点历史也是蛮有趣的.</p> 2022-12: 财年末 https://strrl.dev/post/weekly-report/2022/12-%E8%B4%A2%E5%B9%B4%E6%9C%AB/ Sun, 27 Mar 2022 11:42:27 +0800 https://strrl.dev/post/weekly-report/2022/12-%E8%B4%A2%E5%B9%B4%E6%9C%AB/ <p>这里又是一份周报, 时间范围是<code>2022-03-20</code>到<code>2022-03-26</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="代码计算机相关">代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>很是丢人, 上上一周的作业现在也还没有完成.</p> <p>希望今天能补上上上一周的进度.</p> <h3 id="最近使用-fedora-遇到的一个问题-准备换发行版了">最近使用 Fedora 遇到的一个问题, 准备换发行版了</h3> <p>这个问题遇到了有几周了, 现象是执行 <code>dnf update</code> 非常的慢, 将近 20 分钟, cli 告诉我它卡在 <code>Verifying</code> 这句话上:</p> <p> <p class="md__image"> <img src='./assets/almost-20min.png' alt="Almost 20 minutes" /> </p> </p> <p> <p class="md__image"> <img src='./assets/hangs-on-verifying.png' alt="Hangs on verifying" /> </p> </p> <p>趁机 profile 一下, 发现 IO 挺活跃的:</p> <p> <p class="md__image"> <img src='./assets/iostat.png' alt="iostat" /> </p> </p> <p>再仔细看一下, 发现是 dnf 在大力读写 <code>history.sqlite</code> 等文件:</p> <p> <p class="md__image"> <img src='./assets/filetop.png' alt="filetop" /> </p> </p> <p>到此 profile 戛然而止, 以 dnf stuck history.sqlite 为关键词没有搜索到看似可行的解决方案.</p> <blockquote> <p>其实上面这段 profile 过程是几周前的; 当时也看到把 history.sqlite 直接删掉是安全的, 我也试着删掉了. 但是效果不理想, 一段时间后再次遇到了 stuck 的问题.</p></blockquote> <p>最终, 我决定换到 Arch Linux 去.</p> <p>估计下周找个时候开工.</p> <h3 id="匿名论坛开工了">匿名论坛开工了</h3> <p>之前提到过一个<a href="https://strrl.dev/post/weekly-report/2022/06-%E5%BC%80%E5%B7%A5%E7%AC%AC%E4%B8%80%E5%91%A8/#%E5%8F%88%E4%B8%80%E4%B8%AA%E7%BB%9D%E5%A6%99%E7%9A%84%E7%82%B9%E5%AD%90---dodo-rooster">绝妙的点子</a>, 是一个关于构建匿名论坛的方式.</p> <p>偶然看到 disksing 也有<a href="https://disksing.com/anonymous-forum/">类似的想法</a>, 俺感到十分的激动!</p> <p>已经牵线搭桥了准备做了, 估计大几个月就可以和大家 PoC 了吧.</p> <h3 id="jetbrains--vs-code-中-kubernetes-插件的动态-schema-支持猜想">JetBrains / VS Code 中 Kubernetes 插件的动态 schema 支持猜想</h3> <p>VS Code 和 JetBrains 中 Kubernetes 都是支持从当前的 kubectx 中去拿 Resource 的 schema 来给予代码提示的:</p> <p> <p class="md__image"> <img src='./assets/vscode-kubernetes.png' alt="VS Code Kubernetes" /> </p> </p> <p>我对它的实现感到好奇.</p> <p>(虽然没看代码,) 直觉告诉我这和 <code>kubectl explain</code> 有关, 结果仔细看了下还真是; 执行 <code>kubectl -v7 explain &lt;resource&gt;</code> 时, 会发现它用了这个 API <code>/openapi/v2</code>.</p> <p>手动访问一下, 就会发现响应中有所有的 Resource 的 Schema, 包括 CRD.</p> <h3 id="记一次尴尬的-profiledebug-经历">记一次尴尬的 profile/debug 经历</h3> <p>这个故事起源于这个 issue: <a href="https://github.com/chaos-mesh/chaos-mesh/issues/2927">chaos-mesh/chaos-mesh#2927</a></p> <p>在 IOChaos 的注入中, 在尝试 mount fuse 到一个挂载点时, 出现了挂载点非空的情况.</p> <p>我一开始的思路是, 我们的 ptrace 漏掉了什么东西, 导致进程可能做了一些文件的操作.</p> <p>然后就开始折腾:</p> <ul> <li>又是 debug, 又是 strace, 又是 bcc opensnoop 的;</li> <li>甚至看了下 zookeeper 的持久化相关代码; 当然, 结论是 zk 根本没做什么文件相关的操作;</li> <li>甚至开始想除了 open 和 mmap 之外还有啥读写文件系统上文件的操作;</li> </ul> <p>结果情况是挂载点本来就不是空的, <code>-o nonempty</code> 是期望中的.</p> <blockquote> <p>image 是 <code>k8s.gcr.io/kubernetes-zookeeper:1.0-3.4.10</code>, 目录是 <code>/var/lib/zookeeper</code>.</p></blockquote> <p> <p class="md__image"> <img src='./assets/mount-move-issue.png' alt="mount-move-issue" /> </p> </p> <blockquote> <p>当然对于&quot;除了 open 和 mmap 之外还有啥读写文件系统上文件的操作&quot;, 大家有啥了解的也可以告诉俺.</p></blockquote> <h3 id="家里再次断电-再次修集群">家里再次断电, 再次修集群</h3> <p>周五上班后, 得知家里再次出现了一次电力问题. 导致 homelab 中一台 master 节点再次挂掉了:</p> <p> <p class="md__image"> <img src='./assets/homelab-down.png' alt="Homelab Down" /> </p> </p> <p>鸽了较久的 UPS 紧迫程度 ++</p> <h3 id="chaos-mesh-在申请-cncf-的计算资源">Chaos Mesh 在申请 CNCF 的计算资源</h3> <p>接<a href="https://strrl.dev/post/weekly-report/2022/09-%E6%87%88%E6%80%A0%E7%9A%84%E4%B8%80%E5%91%A8/#cncf-%E7%9A%84%E8%AE%A1%E7%AE%97%E8%B5%84%E6%BA%90">上文</a>, 不得不说 CNCF 是真的大方, 看上去已经同意了: <a href="https://github.com/cncf/cluster/issues/203">cncf/cluster#203</a>.</p> <blockquote> <p>顺便提到另外一件事, 在社区老师和 CNCF 联系后, GitHub chaos-mesh 组织已经进入了 CNCF Enterprise 套餐, 我们也不会受到 GitHub Action Shared Runner 并行的限制了!</p></blockquote> <p>接下来我们将会拥有充足的计算资源给 CI 使用, 同组的 keao 同学看上去已经开始玩 kubevirt 了, 使用了基于虚拟机化的容器后, 我们将有能力对 kernel 相关的 Chaos 进行更好的测试覆盖.</p> <h2 id="生活相关">生活相关</h2> <h3 id="hzlug-hacking-saturday">HZLUG Hacking Saturday</h3> <p>再一次举办了 HZLUG 的 Hacking Saturday, 活动日志在这: <a href="https://hzlug.org/0326-h6-photo/">2022/03/26 Hacking Saturday Afternoon 活动照片</a>.</p> <p>现场装虚拟机, 玩了 Bedrock Linux; 把 Alpine, Arch, Fedora 装到了一台机器上.</p> <blockquote> <p>就不重复放图了, 截图在活动日志里.</p></blockquote> <p>另外接触了 <code>sudo</code> 的替代品 <code>doas</code>.</p> <p>很感谢 you06, Minung, LiFePO4 参与这次活动!</p> <p>另外有一位参与者带了一款很有意思的设备, 是 <a href="https://www.unihertz.com/products/titan">Unihertz Titan</a>. 是一款三防安卓机, 外形硬朗, 很酷.</p> <p>其他俺感兴趣的是 netboot, ipxe 相关的事情, 可能后续活动中再去细聊吧.</p> <p>另外交流后也是下决定用 Arch Linux 了, 再见 Fedora.</p> <blockquote> <p>tmgg 真捧场! 赞美 tmgg!</p></blockquote> <h3 id="在-pingcap-自己的胆子变大了">在 PingCAP, 自己的胆子变大了</h3> <p>最近发现自己敢在一些场合发表自己的看法了, 例如说公司内, 组内, 等等.</p> <p>在之前的公司内, 氛围都比较压抑, 上级对下级的压力都比较中, 技术上设计上有问题都不太敢&quot;反驳&quot;, 更不要说文化上了.</p> <p>在 PingCAP 后, 我发现自己甚至有表达自己对某些事情的冲动, 我认为这是一种好事, 这和企业内的文化是相关的.</p> <blockquote> <p>想继续维护这种氛围, 也是我想做匿名论坛的原因之一.</p></blockquote> <h3 id="一些职业发展的小烦恼">一些职业发展的小烦恼</h3> <p>目前我做的事情在 <a href="https://github.com/chaos-mesh/chaos-mesh">Chaos Mesh</a> 这个项目上. 它是开源的混沌工程平台, 涉及到 Linux Kernel, 网络, 文件系统, Kubernetes, Kubernetes Operator, 前端等等等.</p> <p>它真的非常酷!</p> <p>目前项目取得了一些小进展吧, 比如说:</p> <ul> <li>进入了 CNCF 孵化器</li> <li>有一些 Adopter, 比如说字节, 网易, 腾讯, 小鹏汽车</li> <li>微软 Azure 的 Azure Chaos Studio 也集成了 Chaos Mesh</li> </ul> <p>但是最近在项目未来的发展上, 有一些迷茫/牵制:</p> <ul> <li>我个人希望依然投入最多的精力在开源项目本身和社区的建设上</li> <li>产研的大目标希望能够在 Cloud 方面有一些落地</li> <li>商业期望在国内拉到更多的 2B 客户</li> <li>小组内暂时还没有明确未来的目标</li> </ul> <p>但是我发现我:</p> <ul> <li>不知道如何构建社区</li> <li>无法量化投入到社区内的成本</li> <li>无法量化社区的价值</li> <li>不知道如何吸引更多的(而不是长久的)贡献</li> <li>不知道如何和其他社区去做合作 (比如说和各种中间件社区合作, 如果能成, 那真的太 OP 了)</li> </ul> <p>我(们)可能会在下一个财年内丢失掉一些话语权, 最坏的打算是工作重心从开源项目/社区转移到内部落地.</p> <blockquote> <p>个人看法, 在 PingCAP 玩落地, 可能真不如去字节里去玩落地.</p></blockquote> <p>我希望获取这方便的帮助, 但是不清楚去找谁. 出身 Apache 社区的老师, 例如 tison 老师, jvzhiyuan 老师可能是合适的请教方向.</p> <p>这个事情需要去做了.</p> <blockquote> <p>组内有太多优秀的同学了, 我很不想把他们的精力浪费到工程中枯燥的部分.</p></blockquote> <h3 id="财年末">财年末</h3> <p>很快三月要结束了, 2022 财年要结束了, 京东, 有赞都裁了很多人, 不知道他们的年终奖怎么办.</p> <p>上午还在干活, 下午就要交接真的很恐怖.</p> <p>我们都是弱势群体, 需要想办法保护好自己.</p> 2022-11: 春天没来 https://strrl.dev/post/weekly-report/2022/11-%E6%98%A5%E5%A4%A9%E6%B2%A1%E6%9D%A5/ Sat, 19 Mar 2022 19:38:05 +0800 https://strrl.dev/post/weekly-report/2022/11-%E6%98%A5%E5%A4%A9%E6%B2%A1%E6%9D%A5/ <p>这里又是一份周报, 时间范围是<code>2022-03-13</code>到<code>2022-03-19</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="代码计算机相关">代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>很是丢人, 上一周的作业现在也还没有完成.</p> <p>希望明天能补上上一周的进度.</p> <h3 id="github-action-junit-test-report">GitHub Action Junit Test Report</h3> <p>最近正在做将 Chaos Mesh e2e 迁移到 GitHub Action 上, 发现了一个问题: 我还没有找到一个好的方法来展示这个测试报告.</p> <p>目前 Chaos Mesh 的 e2e 测试使用 ginkgo 输出 junit-xml 类型的测试报告, 然后喂给 Jenkins, Jenkins 会给一个比较好看的页面出来, 例如:</p> <p> <p class="md__image"> <img src='./assets/jenkins-test-report.png' alt="Jenkins Testing Report" /> </p> </p> <p>我想在 GitHub Action 里也有类似的报告出来, 告诉我哪些 testcase 挂了, 并且把相关的日志展示出来.</p> <blockquote> <p>ginkgo e2e test 的日志实在是有点难找&hellip;.</p></blockquote> <p>目前已经试过的是 <a href="https://github.com/dorny/test-reporter">dorny/test-reporter</a> 这个 Action, 但是它目前有一个比较棘手的 <a href="https://github.com/dorny/test-reporter/issues/67">issue</a>. 简而言之就是它新生成的 Check 没有出现在&quot;正确&quot;的位置. 而且由于 GitHub Checks API 的限制, 无法直接将某个 Check 直接&quot;塞&quot;到特定的 CheckSuite 里.</p> <p>关于这个问题, 可以通过一个 <a href="https://github.community/t/github-actions-status-checks-created-on-incorrect-check-suite-id/16685/8">workaround</a> 实现, 而且俺试着实现了一下, 貌似不是很难. 如果没有其他方法的话, 这个算是一个下策.</p> <p>另外有一个叫做 <a href="https://www.check-run-reporter.com/">Check Run Reporter</a> 的服务看上去也不错, 在未来也是一个备选的方案.</p> <p>大家有什么好方法也希望推荐给俺!</p> <h3 id="grafana-dashboard-for-controller-runtime">Grafana Dashboard for Controller Runtime</h3> <p>最近在梳理 Chaos Mesh 本身的监控项, 发现 controller-runtime 本身有一些有意义的性能相关的监控项, 俺就顺手画了两个 Grafana Dashboard 传上去了.</p> <p>在<a href="https://grafana.com/grafana/dashboards/?search=controller-runtime">这里</a>, 顺便安利一下.</p> <h2 id="生活相关">生活相关</h2> <h3 id="春天它没来">春天它没来</h3> <p>最近气温变化幅度还是挺大的, 最高 30 度, 最低 10 度不到. 上周六还只穿短袖外套, 今天又穿上了长袖锁子甲.</p> <p> <p class="md__image"> <img src='./assets/weather.png' alt="气温" /> </p> </p> <h3 id="长颈鹭">长颈鹭</h3> <p>这周又去散步! 再次看到了长颈鹭, 并幸运地拍下了宝贵的照片.</p> <p> <p class="md__image"> <img src='./assets/photo_2022-03-19_19-49-49.jpg' alt="长颈鹭" /> </p> </p> <h3 id="买了本英文字帖">买了本英文字帖</h3> <p>如题, 买了个衡水体考研英语字帖, 希望自己的手写体写得好看一些.</p> <h3 id="暗黑-3-新赛季-ptr">暗黑 3 新赛季 PTR</h3> <p>惭愧, 其实 PTR 上周就开了. 新赛季目前带来的感兴趣:</p> <ul> <li>职业装备改动只有豆角和蛮子, 但是强度并不乐观;</li> <li>武僧狠狠砍了一刀, 伤害只有上赛季的 20%;</li> <li>豆角的平 A 套还是很带感的!</li> <li>带来了一个新模式, 类似于最初始阶段的大米钥匙, 不停刷怪, 然后死亡或者怪多到一定程度结束, 最终定级, 给予奖励;</li> <li>新模式的特点是海量经验. (PTR 里 70 级以后的第一次新模式刷完(5 mins)直接到 580 巅峰)</li> <li>所以这个赛季的套路是拿巅峰和打卡莽过 150?</li> </ul> <blockquote> <p>拳僧什么时候站起来啊?</p></blockquote> <h3 id="午饭偶遇前前同事">午饭偶遇前前同事</h3> <p>在午饭时突然认出了最开始公司的 PM, 了解到他最近跳到了蚂蚁, 同时也聊到另一位同事(算是我实习时的 mentor)也在同一项目组工作.</p> <blockquote> <p>在那时的工作环境里, 这位 PM 的乐观心态给了俺很多鼓励, 俺也非常敬佩他!</p></blockquote> <p>非常开心, 约了下周一起恰个饭!</p> <h3 id="journal-迁移到了-notion">Journal 迁移到了 Notion</h3> <p>上次评论区里 xuanwogege 稍微提醒一下后, 意识到 Journal 还是放到 Notion 里比较好. 而且 Notion 有模板的功能, 很多起床后的 checklist 也顺便放进去了.</p> <blockquote> <p>但是最近记得比较匮乏, 周报里少有乐子. 还是说其实就是客观上就是没有遇到乐子.</p></blockquote> 2022-10: 春天来了 https://strrl.dev/post/weekly-report/2022/10-%E6%98%A5%E5%A4%A9%E6%9D%A5%E4%BA%86/ Sat, 12 Mar 2022 19:21:41 +0800 https://strrl.dev/post/weekly-report/2022/10-%E6%98%A5%E5%A4%A9%E6%9D%A5%E4%BA%86/ <p>这里又是一份周报, 时间范围是<code>2022-03-06</code>到<code>2022-03-12</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="代码计算机相关">代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>果不其然, 目前为止还是依旧没有完成 NAND2Tetris 的作业.</p> <p>周天再说吧.</p> <h3 id="在-hzlug-上学到了-nix">在 HZLUG 上学到了 Nix</h3> <p>HZLUG Hacking Saturday Afternoon <a href="https://hzlug.org/0312-h6-photo/">再次成功举办了</a>!</p> <p>这次学到了 Nix 的好多概念和使用方法.</p> <p>之前提到过 <a href="https://strrl.dev/post/weekly-report/2022/06-%E5%BC%80%E5%B7%A5%E7%AC%AC%E4%B8%80%E5%91%A8/#nix-%E7%9A%84%E5%B1%88%E8%BE%B1%E8%AF%95%E7%94%A8">试用 Nix 大失败</a> 的故事, 现在回想起来应该是当时的 master 上的安装脚本有问题吧. 这次再安装 multi-user 的时候就一路成功了.</p> <p>Nix 香!</p> <h3 id="chaos-mesh-参与-gsoc-项目">Chaos Mesh 参与 GSoC 项目</h3> <p>GSoC 2022 来了! 这次的 GSoC 将不再只允许学生/毕业生参加, 任何热爱开源的人都可以参与! 这次 Chaos Mesh 有两个非常有意思的 idea:</p> <ul> <li>单个 binary 集成 etcd, kube-apiserver 以及 controller-manager</li> <li>使用 unix socket 代替 RPC over stdio</li> </ul> <p>有兴趣的同学可以申请起来了哦!</p> <p>附: <a href="https://github.com/cncf/mentoring/blob/main/summerofcode/2022.md#chaos-mesh">Chaos Mesh 相关的项目列表</a></p> <h3 id="折腾-logseq-同步">折腾 logseq 同步</h3> <p>tldr; logseq 没那么香了; 没有折腾好, 准备成为 obsidian 付费用户了.</p> <p>我需要在 4 - 5 个设备上进行同步:</p> <ul> <li>安卓手机</li> <li>iPad</li> <li>linux 桌面环境</li> <li>macos 桌面环境</li> <li>windows 桌面环境</li> </ul> <p>Dropbox: linux 客户端需要依赖 libgnome, 我现在用的 KDE, 没敢装.<br> OneDrive: 没官方 linux 客户端.<br> Syncthing: 朋友反映经常出先 conflicts.<br> Git: 移动端难以自动同步;</p> <p>如果有推荐的同步方式请安利给我! &#x2764;&#xfe0f;</p> <h2 id="生活相关">生活相关</h2> <h3 id="春天来了-气温上升">春天来了, 气温上升</h3> <p>最近几天的气温已经冲上了 20 - 25 摄氏度, 已经可以穿短袖了.</p> <p>有太阳可真是好啊!</p> <h3 id="乌鸫筑巢">乌鸫筑巢</h3> <p>最近窗台上出现了黑身黄嘴的鸟儿在建窝, 查了下貌似是乌鸫. 而且也有很多同样在杭州的新闻, 说乌鸫也在自家窗台, 阳台筑巢.</p> <h3 id="长颈鹭">长颈鹭</h3> <p>上周天和女朋友出去徒步, 看到了一只白色的长脖子鸟.</p> <p>我们决定将其命名为长颈鹭.</p> <h3 id="vr-游戏-virtuoso">VR 游戏: Virtuoso</h3> <p>Virtuoso 非常酷, 能够在 VR 中玩 looping.</p> <p>但也由于它的自由度太高, 其实游玩的过程就是编曲的过程, 需要创作的热情. 我没有继续玩很久.</p> <p>如果未来能够加入一些不需要创作元素(不需要动脑子)的音游元素那就更好完了!</p> <p><a href="https://store.steampowered.com/app/1213710/Virtuoso">Virtuoso on Steam</a></p> <h3 id="游戏-绯红结系">游戏: 绯红结系</h3> <p>周六中午打开了游戏机, 玩了一会绯红结系(俺一周目男主线刚刚玩到渡月教那里).</p> <p>鸫和岚好可爱啊!</p> <p> <p class="md__image"> <img src='./assets/Scarlet_Nexus_Tsugumi_Nazar.png' alt="Tsugumi" /> </p> </p> <p> <p class="md__image"> <img src='./assets/Scarlet_Nexus_Arashi_Spring.png' alt="Arasi" /> </p> </p> <h3 id="腰疼">腰疼</h3> <p>最近的脊柱左侧腰窝越来越疼了, 难受.</p> <h3 id="每日-checklist">每日 checklist</h3> <p>在拥有了打印机后, 我打印了一些每日 checklist, 内容大致包括:</p> <ul> <li>昨晚睡眠质量</li> <li>提醒自己洗漱</li> <li>使用工作的第一个小时(两个番茄钟)进行&quot;重要, 不紧急&quot;的个人建设</li> </ul> <p>目前还在试实行中, 蛮有意思的! 起床后就能投身建设中!</p> <p>但是它貌似和在 logseq 中记录日记有些冲突, 之前有些会记录到 logseq 的事情就记录到纸上了.</p> <p>我个人还是期望继续使用 logseq 日记的, 后续需要调整.</p> <h3 id="尝试使用-beancount-记账">尝试使用 beancount 记账</h3> <p>如题, 迈出财务自由第一步! <del>不是</del></p> 2022-09: 懈怠的一周 https://strrl.dev/post/weekly-report/2022/09-%E6%87%88%E6%80%A0%E7%9A%84%E4%B8%80%E5%91%A8/ Sat, 05 Mar 2022 09:15:17 +0800 https://strrl.dev/post/weekly-report/2022/09-%E6%87%88%E6%80%A0%E7%9A%84%E4%B8%80%E5%91%A8/ <p>这里又是一份周报, 时间范围是<code>2022-02-27</code>到<code>2022-03-05</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="代码计算机相关">代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>很惭愧, 到目前为止还没有看完机器语言部分的课程.</p> <blockquote> <p>希望今明两天看完并完成作业吧.</p></blockquote> <blockquote> <p>Zhiqiang 啊 Zhiqiang! 你怎么能如此堕落!</p></blockquote> <blockquote> <p>更新于 2022-03-05 15:29:20, 诶嘿, Week 4 作业做完了.</p></blockquote> <h3 id="growth-ofcodes">growth-of.codes</h3> <p>这周基本上每晚都会写一点这个项目 <a href="https://github.com/strrl/growth-of-codes">growth-of-codes</a>. 最后我选择了部署在 Vercel 上, 数据使用免费的 TiDB Cloud Dev Tier. 地址在 <a href="https://growth-of.codes">growth-of.codes</a></p> <p>目前有了一个简单的页面:</p> <p> <p class="md__image"> <img src='./assets/growth-of-codes.png' alt="growth-of-codes" /> </p> </p> <p>目前是找了一份 (2018) 年的 TOP 100 项目列表, 白嫖了 GitHub Action 的算力分析出来的.</p> <p>下一步的计划是想办法如何能够对任意的 GitHub repo 在&quot;合适&quot;的时间内分析出它的复杂度增长数据.</p> <h3 id="dnf-update-后-goland-出现了一堆莫名其妙的动画效果">dnf update 后, Goland 出现了一堆莫名其妙的动画效果</h3> <p> <p class="md__image"> <img src='./assets/goland-animation.gif' alt="animation" /> </p> </p> <h3 id="chaos-mesh-有-contributor-提出想要实现-chaos-on-windows">Chaos Mesh 有 Contributor 提出想要实现 Chaos on Windows</h3> <p>Chaos Mesh 一直专注在 Linux 容器上, 对于其他操作系统几乎不提供支持.</p> <blockquote> <p>印象中之前俺<a href="https://stackoverflow.com/questions/64652375/chaos-mesh-on-aks">在 stack overflow 回复 Chaos Mesh 不支持 Windows</a> 的回答被无情 -1 了.</p></blockquote> <p>但是这周我们收到了一个振奋人心的 issue:</p> <p>Chaos Mesh support for windows nodepool <a href="https://github.com/chaos-mesh/chaos-mesh/issues/2956">#2956</a></p> <p>有社区同学表达了对 Windows 支持的兴趣! 而且在 Slack 的沟通中得知, 有同属同一团队的两位同学将会着手实现.</p> <p>真的是太棒了啦!</p> <h3 id="cncf-的计算资源">CNCF 的计算资源</h3> <p>在之前的<a href="https://strrl.dev/post/weekly-report/2022/07-%E5%85%B4%E5%A5%8B%E4%B8%8E%E5%BF%99%E7%A2%8C%E7%9A%84%E4%B8%80%E5%91%A8/#chaos-mesh-%E6%88%90%E4%B8%BA%E4%BA%86-cncf-incubating-%E7%BA%A7%E5%88%AB%E9%A1%B9%E7%9B%AE">内容</a>里提到过, CNCF 将会对毕业以及孵化项目提供计算资源.</p> <p>这周发现了 <a href="https://github.com/cncf/cluster">cncf/cluster</a> 这个项目, 发现条件似乎更为宽松. 这几周忙过以后, 可以去尝试一下, 能不能申请一些机器来做 Self Hosted GitHub Action Runner 了.</p> <blockquote> <p>另外社区的同事翁老师也询问了 CNCF, 被回复 <a href="https://strrl.dev/post/weekly-report/2022/08-%E5%8F%AA%E6%98%AF%E5%BF%99%E7%A2%8C%E7%9A%84%E4%B8%80%E5%91%A8/#%E5%85%B6%E4%BB%96">Ihor</a> 同时也负责申请计算资源这件事, 体现出 CNCF 貌似存在较为严重的人员单点问题.</p></blockquote> <h2 id="生活相关">生活相关</h2> <h3 id="忘记在-logseq-里记日记了">忘记在 logseq 里记日记了</h3> <p>之前在 logseq 的 journal 中都会每天多多少少记录一点, 但是这周的周三,周四,周五都没有记录.</p> <p>周三是一早起来就去上班了, 没有打开家里用来工作的电脑.</p> <p>周四往后就是忘记了这个事情.</p> <p>看来在养成习惯之前还是需要有地方提醒自己一下的.</p> <blockquote> <p>另外 logseq 依旧没有推出太好用的多端同步方案, 我正在考虑要不要成为 obsidian 的付费用户.</p></blockquote> <h3 id="准备使用纸质材料记录生活-checklist">准备使用纸质材料记录生活 checklist</h3> <p>上周买了打印机, 其实到目前为止都还没有产生作用.</p> <p>准备今天整理一下, 打印出 checklist/cheat sheet, 例如:</p> <ul> <li>每天早上起来需要做什么</li> <li>周末的 GTD 整理需要做什么</li> <li>&hellip;</li> </ul> <p>以及一些需要&quot;播种&quot;(重要不紧急)的事情, 比如:</p> <ul> <li>想写好看的英文手写体</li> <li>想学双拼</li> <li>想看掉屯的某些书</li> <li>&hellip;</li> </ul> <h3 id="游戏-death-squared">游戏: Death Squared</h3> <p>这周女朋友发现了一个好玩的解密游戏, 叫做 <a href="https://store.steampowered.com/app/471810/Death_Squared/">Death Squared</a>, 目前(截至到 March 8th) Steam 上正在绝赞打折中(90% off).</p> <blockquote> <p>三块五你买不了吃亏, 三块五你买不了上当.</p></blockquote> <p>玩家将操控两个 Square 对象进行解密, 目的是移动方块到目标位置. 但是场景中的很多元素会随着方块的移动来作出反应, 例如:</p> <ul> <li>踩下按钮地上冒出尖刺, 碰到会失败</li> <li>激光会锁定攻击方块, 需要使用地图元素, 或者操纵的另外一个方块挡住</li> <li>可以踩到另外一个玩家的方块上进行叠高高</li> </ul> <p>它的背景也非常有意思, 讲述的是一位&quot;大厂员工&quot;在&quot;监督&quot; AI(也就是玩家) 解密. 同时也有另外一个监督型 AI (NPC, 名叫 IRIS) 来和大厂员工同时监督.</p> <p>配音做得非常好, 女朋友第一次进行游戏时, 只听声音我还以为她在看美剧.</p> <p>总是还是一款不错的游戏!</p> <blockquote> <p>然后发现 Xbox 手柄接收器可以同时连接多个手柄. 好耶!</p></blockquote> <h2 id="总结">总结</h2> <p>怎么许多事情掉了链子呢!? NAND2Tetris 没做完, 日记也没写!</p> <blockquote> <p>周末也有好多事情要做, 晚上 20:00 - 22:00 有一个宣讲, 还需要把 slides 改成中文.</p></blockquote> <p>气愤啊气愤.</p> 2022-08: 只是忙碌的一周 https://strrl.dev/post/weekly-report/2022/08-%E5%8F%AA%E6%98%AF%E5%BF%99%E7%A2%8C%E7%9A%84%E4%B8%80%E5%91%A8/ Sat, 26 Feb 2022 18:52:54 +0800 https://strrl.dev/post/weekly-report/2022/08-%E5%8F%AA%E6%98%AF%E5%BF%99%E7%A2%8C%E7%9A%84%E4%B8%80%E5%91%A8/ <p>这里又是一份周报, 时间范围是<code>2022-02-20</code>到<code>2022-02-26</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="代码计算机相关">代码/计算机相关</h2> <h3 id="nand2tetris">NAND2Tetris</h3> <p>很惭愧, 到目前为止还没有看完时序逻辑电路部分的课程.</p> <blockquote> <p>立个 flag, 明天看完, 把大作业做了.<br> 更新于 2022-02-27 13:50:49, 做完啦, 完成了 Bit, Register, RAM 8 - 16K, PC. 但是在 perspectives 提到的使用两个 NAND 实现 DFF 还是没太明白, 后面再看看.</p></blockquote> <h3 id="lfx-mentorship-候选人决定">LFX Mentorship 候选人决定</h3> <p>LFX Mentorship 候选人最终决定, 选中了 Chengwei Guo 同学!</p> <blockquote> <p>Guo 同学是 CMU 的在读 master. (大佬带带我啊</p></blockquote> <p>顺便聊一下<a href="http://localhost:1313/post/weekly-report/2022/07-%E5%85%B4%E5%A5%8B%E4%B8%8E%E5%BF%99%E7%A2%8C%E7%9A%84%E4%B8%80%E5%91%A8/#%E5%BC%80%E5%A7%8B%E5%A4%84%E7%90%86-lfx-mentorship-mentee-%E7%94%B3%E8%AF%B7">小作业</a>的结果吧. 总共收到了 11 份回复邮件, 其中有 9 份是选择了 quiz 1, 2 份同时完成了 quiz 1 和 quiz 2.</p> <blockquote> <p>有够卷的. 如果有幸再参与下次 Mentorship, 我要明确标明同时完成两份 quiz 会减分. 😡</p></blockquote> <p>对于 quiz 1, 大部分的问题出现在:</p> <ul> <li>使用了 katacoda 默认的 minikube 镜像, 而其中的 minikube 是 1.8.1 版本, 不支持 <code>--nodes</code> 参数. 步骤中使用了 <code>--nodes</code> 参数却没有升级 minikube, 跑不下去了.</li> <li>和上面类似的, helm 使用了 2.x</li> <li>Chaos Mesh 没有卸载干净. 有的同学只删除了 Chaos Mesh 所在的 namespace, 没有清理 cluster-level 的资源. 或者只使用 <code>helm uninstall</code> 删除了 helm release, 没有清理 CRD. 其实俺之前也想到了这个问题, 暗示了安装卸载步骤可以参考文档站. 可能大家还是想当然了, 认为 <code>helm uninstall</code> 会把事情处理好.</li> </ul> <p>对于 quiz 2, 一位同学使用的 kubeclient 去 list pods, 然后将 IP 返回. 这挺好的(朴素的 cloud native 应用), 只是它提供的 manifest 中没有 rbac 的内容, 稍稍减分. 另外一位同学使用了 Headless Service, 然后使用 DNS 解析到 IP, 也挺好的.</p> <p>关于评判标准, 是按照项目的最终完成度来看的: 我将化身一位完全不懂的小白, 根据项目中的指引(quiz 1 就是只按照 katacoda 操作, quiz 2 就是看 README), 尝试走完这个项目. 如果指引信息有问题走不下去了, 俺也就不会继续往下看了. 看最终哪个项目完成的最彻底.</p> <blockquote> <p>所以为了追求 quiz 1 中的 bonus: multi-node minikube, 而忽视了低版本 minikube 并不支持 <code>--nodes</code> 参数, 导致前期启动 minikube 集群失败, 就算是完成度低了.</p></blockquote> <h3 id="事故-homelab-集群中两个-btrfs-卷升天了">事故: homelab 集群中两个 btrfs 卷升天了</h3> <blockquote> <p>要是搁在公司的生产环境, 硬盘分区丢数据的事故不算 P0 也算 P1 了吧.</p></blockquote> <p>目前推测事故根本原因:</p> <ul> <li>homelab 的 PDU 插在了灯光线路上.</li> <li>盲目的 <code>btrfs check --repair</code></li> </ul> <p>事情是这样的:</p> <ul> <li>我需要更换一个日光灯的面板开关</li> <li>我关掉了配电箱的 &ldquo;灯光&rdquo; 开关</li> <li>家里 WiFi 没有了(WiFi 是由 homelab 机柜中的 PoE 交换机供电的)</li> <li>虚拟机启动不起来后没有查询 wiki, 直接 archlinux live iso 启动准备修复.</li> <li>忽视了 <code>btrfs check --repair</code> 的警告选择了强制执行.</li> <li>寄了</li> </ul> <blockquote> <p>另外附上修复 btrfs 的<a href="https://en.opensuse.org/SDB:BTRFS#How_to_repair_a_broken.2Funmountable_btrfs_filesystem">正确做法</a>.</p></blockquote> <p>因此两台虚拟机由于作为 rootfs 的 btrfs 卷被损坏, 导致无法启动. 因此我的 homelab 中 ceph 也有两个 OSD 掉了.</p> <p> <p class="md__image"> <img src='./assets/ceph-osd.png' alt="ceph-osd" /> </p> </p> <blockquote> <p>掉了的是 0,1; OSD 2,3,4 是上段时间换硬盘缩容的时候直接删了老的 OSD 重建的.</p></blockquote> <p>虽然这周已经过了五天了但是依旧不想去修, 就让它 degrade 着吧.</p> <h2 id="生活相关">生活相关</h2> <h3 id="购入了一台打印机">购入了一台打印机</h3> <p>接<a href="https://en.opensuse.org/SDB:BTRFS#How_to_repair_a_broken.2Funmountable_btrfs_filesystem">上文</a>, 于是就买了. 但是目前还没设置好, 有啥用处或者可玩点下周再告诉你们吧~~</p> <h3 id="游戏-vampire-survivors">游戏: Vampire Survivors</h3> <p>与本周五的 Steam 探索队列中发现了这款游戏, 一款另类的像素风地牢游戏.</p> <p>玩家只需要走位, 角色可以自动攻击. 可以同时装备六款武器和六款饰品, 特定的武器与饰品组合可以将满级武器进化为神器.</p> <p> <p class="md__image"> <img src='./assets/v-m.jpg' alt="VampireSurvivors" /> </p> </p> <blockquote> <p>两天玩了 9 小时了.</p></blockquote> <h3 id="游戏-埃尔登法环">游戏: 埃尔登法环</h3> <p>被大树守卫劝退.</p> <p>被归树看门犬劝退.</p> <p>(有没有大佬教教我)</p> <h3 id="周六下午徒步">周六下午徒步</h3> <p>周六和女朋友出去散步, 走到了一个梁山文化的展览馆.</p> <p> <p class="md__image"> <img src='./assets/likui.jpg' alt="likui" /> </p> </p> <p>馆内解释了, 施耐庵在钱塘时创作了<em>水浒传</em>, 而钱塘就是当今西溪. 所以梁山的文化以及地貌其实是参考了西溪.</p> <blockquote> <p>不敢苟同. 看个乐子吧.</p></blockquote> <h2 id="其他">其他</h2> <p>俄罗斯乌克兰开战了. 第一次感受到战争和我们的生活比较近, 在咨询 Mentorship 相关问题的时候, Ihor 告诉我他暂时不太行.</p> <p> <p class="md__image"> <img src='./assets/ihor-with-limited-availability.png' alt="ihor-with-limited-availability" /> </p> </p> <blockquote> <p>Ihor 是 Kubernetes 的 PM, CNCF 的 Developer Advocate.</p></blockquote> <p>希望平民没事.</p> 2022-07: 兴奋与忙碌的一周 https://strrl.dev/post/weekly-report/2022/07-%E5%85%B4%E5%A5%8B%E4%B8%8E%E5%BF%99%E7%A2%8C%E7%9A%84%E4%B8%80%E5%91%A8/ Sat, 19 Feb 2022 12:22:49 +0800 https://strrl.dev/post/weekly-report/2022/07-%E5%85%B4%E5%A5%8B%E4%B8%8E%E5%BF%99%E7%A2%8C%E7%9A%84%E4%B8%80%E5%91%A8/ <p>这里又是一份周报, 时间范围是<code>2022-02-13</code>到<code>2022-02-19</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="撸代码计算机相关">撸代码/计算机相关</h2> <h3 id="nand2tetris-进度">NAND2Tetris 进度</h3> <p>第二周的 NAND2Tetris 的内容不算多, 最后的大作业是完成一个 ALU. 两位老师直接提供了一个非常 fancy 的 HACK ALU 实现, 它确实非常的精炼以及优雅, 但是这也让我感到了一个很大的问题: 如果让我去设计一个 ALU, 我依旧是做不出来的.</p> <p>好吧这可能对于 NAND2Tetris 来说可能是超纲了, 毕竟它的目的是教我了解计算机如何工作, 而不是教我如何优雅设计一个 ALU.</p> <blockquote> <p>不过这周的大作业还没写, 挖个坑, 写完大作业来更新一下, 在把这个坑填上.</p></blockquote> <blockquote> <p>2022-02-19 17:06:09 更新, 做完啦! <a href="https://www.reddit.com/r/NandToTetris/comments/pzlf93/sub_bus_of_an_internal_node_may_not_be_used_any/">踩了一个坑</a>, 新加 CHIP 能解决. 神奇的设定</p></blockquote> <h3 id="growth-ofcodes-进度">growth-of.codes 进度</h3> <p>接<a href="https://strrl.dev/post/weekly-report/2022/06-%E5%BC%80%E5%B7%A5%E7%AC%AC%E4%B8%80%E5%91%A8/#%E7%BB%9D%E5%A6%99%E7%9A%84%E7%82%B9%E5%AD%90---growth-ofcodes">上周的绝妙点子</a>, growth-of.codes 已经开始正式开工了.</p> <p>现在做的事情是:</p> <ul> <li>对于一个 GitHub repo, 根据特定的频率 (daily, weekly, monthly) 筛选出 commit, 以文件为单位, 使用 scc 把复杂度记录下来</li> <li>然后存储到 TiDB Cloud 中</li> </ul> <blockquote> <p>白嫖了 TiDB Cloud Dev Tier, 包括 TiDB x 1, TiKV x 1, TiFlash x 1. 包含 TiKV 和 TiFlash 的容量都是 10 GiB. 目前用量是 TiKV 2.7 GiB, TiFlash 1.1 GiB.</p></blockquote> <p>当前是<a href="https://github.com/STRRL/growth-of-codes/actions/workflows/persisted-directly-with-list.yaml">白嫖了 GitHub Action</a> 作为跑任务的工作负载, 已经了跑了一定量的数据(大约 3700 万行了), 不过也有相当一部分任务没有跑成功.</p> <p>同时数据的规模还是超乎了我的想象:</p> <p> <p class="md__image"> <img src='./assets/growth-of-codes-github-action.png' alt="产物超大" /> </p> </p> <p>下一步的计划分成两个方向:</p> <ul> <li>通过 serverless 实现一个分发分析任务的玩意, 再实现一个执行分析任务的 daemon, 跑到我的 homelab 里.</li> <li>前端展示, 初步想到的两个形式是折线图和色块图(分别类比 star-history 和 codecov 的代表性图表).</li> </ul> <h3 id="尝鲜-serverless">尝鲜 Serverless</h3> <p>在构建 growth-of.codes 时, 因为不想再自己 self-host 任何一个对外服务了(看过俺 twitter 的人应该稍微有些了解, 俺的 homelab 做不了任何 SLA 保证. 哈哈哈哈哈). 同时 Serverless, Faas 等概念在经过一定时间的沉淀后, 我觉得是时候尝试下这种对个人开发者十分友好的交付方式了!</p> <p>目前已经试过的服务有:</p> <ul> <li>AWS Lambda</li> <li>Google Cloud Functions (Delivery by Source Codes)</li> <li>Vercel Serverless Function</li> </ul> <p>还未体验, 在计划中将去体验的有:</p> <ul> <li>Google Cloud Functions (Delivery by Container Image)</li> <li>Cloudflare Workers</li> </ul> <p>AWS 作为老牌的云服务商, AWS Lambda 的表现非常稳定, 通过使用 API Gateway 作为 Trigger, 触发一个 Lambda 函数, 就能让我们的服务跑起来. 我的使用方式是用一个 Container Image 去部署 AWS Lambda, 在部署前它要求我把这个镜像<strong>必须</strong>作为一个私有项目放到 Amazon Elastic Container Registry 上, 稍微有些麻烦. 另外一点是作为 AWS 的初级用户, 各个功能要连起来好复杂, 比如说我找了好久暴露 Lambda 服务的方式, 才发现需要用过 AWS API Gateway 做暴露.</p> <p>GCP Function 的使用方式不能说更加简单. 虽然 Google Functions 也支持从容器镜像里启动 Function, 但这次我换了个套路, 从源码部署. 步骤还比较简单, 把 GitHub Repository mirror 到 Google Cloud Source Repositories 里, 然后直接选择 Functions 所在的文件夹, 就可以部署了. 我选择了 Public 且无需 Auth 的暴露方式, 所以部署完成后会直接给一个 url, 就可以直接调用这个函数了. 总的来说还算好用, 用下来的感受就是部署速度有点慢.</p> <p>最后俺试了 Vercel, 试用之前还发生了<a href="https://twitter.com/strrlthedev/status/1491660110787379201">乌龙</a>, 让我误以为 Vercel Serverless Functions 需要氪金才能使用. 但是后来还是<a href="https://twitter.com/strrlthedev/status/1493941533367992322">真香</a>了, 目前也是用下来体验较好的服务.</p> <p>最终选择使用 Vercel 的原因是, 它有 <code>vercel dev</code>, 我可以通过这个命令在本地启动一个几乎一模一样的服务, 方便我在本地测试和开发(说难听点, 方便糊烂摊子). 而 AWS 和 GCP 都没有做这一件事, 如果我需要在本地测试或者开发, 那么我就需要自己写另外的入口, 虽然并不是做不到的事情, 但是回带来一定的复杂度, 而且维护测试环境与生产环境的统一是一件耗费脑力的事情. AWS 与 GCP 可能更想做企业级用户吧, 不通环境的问题对企业级用户肯定是内部有个轮子来解决啦.</p> <p>Vercel 的 <code>vercel dev</code> 对个人开发者来说真的是一个福音, 在本地糊好, 部署上去就行了. 虽然 <code>vercel dev</code> 有 bug, 比如说配置了 &ldquo;Root Directory&rdquo;, 它的 <code>vercel dev</code> go-bridge 没有传递正常的 modpath, 导致不能用了, 但是还是可以用过一些小 trick (在 sub directory 新建新的 project 专门做 <code>vercel dev</code>)来绕过, 可以说是瑕不掩瑜.</p> <p>Vercel 的体验可以说是非常好, 但是 cloudflare 也提供了一个叫做 <code>miniflare</code> 的本地开发工具, 看上去也很能打, 最后我应该会在这两者中选择一个来使用.</p> <blockquote> <p>如果俺哪里做的不好, 或者漏掉了最佳实践, 欢迎安利给俺!</p></blockquote> <h3 id="golang-中同时享受受苦-gorm-transaction-repository-pattern-的丑陋实现">Golang 中同时享受(受苦) GORM, Transaction, Repository Pattern 的丑陋实现</h3> <p>上上章节提到了需要为 growth-of.codes 写个任务分发系统, 凭着我 CRUD Boy 的经验, 这还不是很好做吗?(笑)</p> <p>但是在真正上手代码的时候, 我发现了一个问题: go 生态中没有像 Spring 里的 <code>TransactionManager</code> 这个东西, 导致我写事务相关的代码时必须和 GORM 绑定起来, 它带来的坏处是: 我没有办法写一个干净的 Repository 接口, 然后为不同的存储后端写不同的实现了.</p> <p>目前也暂时没办法, 就直接和 GORM 糊在一起了, 耦合高的一批.</p> <blockquote> <p>呜呜 Kotlin 我的 Kotlin, 好想用 Kotlin 啊.</p></blockquote> <h3 id="目前手上在忙的-chaos-mesh-feature">目前手上在忙的 Chaos Mesh Feature</h3> <p>从年前&quot;拖&quot;到现在的一个大 Feature 终于有了点眉目, 提交了 <a href="https://github.com/chaos-mesh/rfcs/pull/38">RFC</a>.</p> <p>大体讲的一个事情是, 将某个监控平台的图表引入到 Chaos Mesh 中来&quot;看&quot;, 并且通过展示混沌实验相关数据来&quot;增强&quot;显示.</p> <p>我不确定这一步走的对不对, 它可能是 Chaos Mesh &ldquo;产品化&quot;的第一步, 也有可能是走向所谓&quot;小而美, 生态闭环&quot;深渊的一步.</p> <blockquote> <p>下周再回复 Comments 吧, 周末休息一下玩一玩. :P</p></blockquote> <h3 id="chaos-mesh-成为了-cncf-incubating-级别项目">Chaos Mesh 成为了 CNCF Incubating 级别项目</h3> <p>周四凌晨, <a href="https://www.cncf.io/blog/2022/02/16/chaos-mesh-moves-to-the-cncf-incubator/">CNCF 宣布 Chaos Mesh 成为了 CNCF Incubating 级别项目</a>. &#x1f389;</p> <blockquote> <p>负责社区的老师貌似提到, 虽然热度不酸很大, 但是比 TiKV 毕业热度还要大一些.</p></blockquote> <p>上次在 HZLUG Hacking Saturday 的时候, 和另一位 TiKV Committer 聊到为啥 TiKV 已经是毕业项目了, 但是没有 CNCF 没有赞助 CI 资源. 回答, 现在都是 jenkins, 难迁移到新的平台上去.</p> <p>趁着 Chaos Mesh 目前 CI 还没有太复杂, 后面可以考虑一下嫖 CI 资源了! E2E test 多版本和多 platform 的 matrix 指日可待(?)</p> <h3 id="开始处理-lfx-mentorship-mentee-申请">开始处理 LFX Mentorship Mentee 申请</h3> <p>这次 Chaos Mesh 的项目是在 <a href="https://mentorship.lfx.linuxfoundation.org/project/09847d84-5d14-4c05-8644-57cdde5b6466">katacoda 中创建混沌实验示例</a>. 总共收到 31 份申请, 俺给他们又留了小作业, 题目二选一:</p> <ul> <li>在 katacoda 中创建一个 scenario, 完成 &ldquo;新建 Kubernetes 集群&rdquo;, &ldquo;安装 Chaos Mesh&rdquo;, &ldquo;卸载 Chaos Mesh&rdquo;.</li> <li>编写一个 Cloud Native Web App, 叫做 buddy. 当 buddy 运行在 Kubernetes 内时, 调用 <code>GET /buddy/list</code> 返回所有 <code>buddy</code> 副本的 IP 地址.</li> </ul> <p>小作业是这周六上午(19日, 就在刚刚)通过邮件 bcc 给大家, deadline 是 24 日. 我们将在 25 日决定出最后的 mentee 人选.</p> <blockquote> <p>不知道难度怎么样. 大家有什么想法呢?</p></blockquote> <h3 id="cloud-native-day-tokyo">Cloud Native Day Tokyo</h3> <p>俺在 Cloud Native Day Tokyo/Observability Conference 2022 上<a href="https://event.cloudnativedays.jp/o11y2022/talks/1358">投的一篇 presentation</a> 中了. 需要在 25 日前提交 40 min 的录像.</p> <p>然额我的 slides 还没有做完, 下周的两天甚至三天的时间都要忙这件事了.</p> <h2 id="生活相关">生活相关</h2> <h3 id="好玩不累的-beat-saber">好玩不累的 Beat Saber</h3> <p>某天晚上终于把 Beat Saber 的 Mod 与歌单收拾好了! 下了一堆二次元歌曲! 打起来十分快乐!</p> <blockquote> <p>好多歌曲难度只有 Expert, Expert+, 虽然只能开 No Fail 打个 E 评分, 但可是真的快乐.</p></blockquote> <p>玩 Beat Saber 确实也会消耗很多体力, 出汗量比健身环还要多, 能明显感到汗从背上流到小腿. 但是运动强度显然没有健身环那么强, 心率不会超过 150.</p> <h3 id="睡眠质量有所改善">睡眠质量有所改善</h3> <p>最近定期睡觉前一小时吃一粒腿黑素(计算了一下是 1.6mg), 在用三星表持续追踪自己的睡眠周期和深睡眠时间, 深度睡眠时间在明显地变长: 17 分钟 -&gt; 41 分钟 -&gt; 50 分钟 -&gt; 1 小时 14 分钟. 白天也更有精神了. 配合中午的 coffee nap, 基本上能做到全天不会太久头疼头晕困顿发傻的的这种感觉了. Things under control! 这感觉真好.</p> <p>另外三星健康睡眠有一个蛮有趣的功能, 提供了睡眠模型. 我自己的模型是刺猬:</p> <p> <p class="md__image"> <img src='./assets/samsung-health-sleep-symbol.jpg' alt="刺猬" /> </p> </p> <p>虽然不知道可信度有多高但是这个刺猬好可爱哦!</p> <p>也还有其他可爱的动物:</p> <p> <p class="md__image"> <img src='./assets/all-sleep-symbols.jpg' alt="Others" /> </p> </p> <p>详情页面还会有动物睡眠的动画, 可爱!</p> <blockquote> <p>不会手机录 GIF, 大家脑部一下可爱的动画吧.</p></blockquote> <h3 id="想买一台打印机">想买一台打印机</h3> <p>最近有很多 checklist 需要去做, 比如说早上起来要做什么做什么, 工作到某个时间点要做什么做什么, 每周 Review 要做什么做什么.</p> <p>我突然发现, 在电子设备上做这种事情, 还不如手写然后打勾好用.</p> <blockquote> <p>如果你们有啥推荐的软件也可以推荐给俺.</p></blockquote> <p>但是手写实在是累哦, 想买台打印机, 打印出一些 checklist, 然后到时候自己打勾就好了.</p> <p>另外彩打貌似可以玩纸模, 看别人的分享, 完成度很好的样子.</p> <p>但是由于书房空间不太够了, 还是等女朋友回来后商量一下再说吧. =.=||</p> <h3 id="新发现的-up-主-鞑厨高寒">新发现的 up 主: 鞑厨高寒</h3> <p>最近比较喜欢一位 up 主<a href="https://space.bilibili.com/572164928">鞑厨高寒</a>. 看上去他是东北人, 厨师, 在深圳是多个餐厅的合伙人. 他是一个比较有个性的人, 外表比较粗狂, 说话也比较有能量. 另外他的店名也很有趣, 都是鸟类的名字, 八哥, 喜鹊, 夜莺, 山雀(等等). 作为一系列厨房题材的视频, 作为消遣来看是很开心的.</p> <blockquote> <p>虽然经常彪英文, 以及作出一些很&quot;凶猛&quot;的行为显得有些&quot;装B&rdquo;, 但是人家就是大大方方承认在&quot;装B&quot;, 作为一种风格来说还挺有趣的. 他也经常提到&quot;按我说的做, 不要按我做的做&quot;. 🤣</p></blockquote> <p>视频中也有一些梗了:</p> <ul> <li>给&quot;战友&quot;做工作餐</li> <li>投喂老陈(摄像师)</li> <li>&ldquo;按我说的做, 不要按我做的做&rdquo;</li> <li>&ldquo;掰着胳膊&quot;说定量配方</li> </ul> <p>最喜欢的一期是<a href="https://www.bilibili.com/video/BV1qg411G7Fg">调酒相关的</a>, 高寒和调酒师之间的互动我要笑死了.</p> <p>推荐给大家, 希望他的视频也能为大家带来欢乐!</p> <h3 id="忙碌">忙碌</h3> <p>上周无论是工作时间还是下班后的个人时间都安排得满满当当的, 甚至有了 &ldquo;我想玩风暴英雄, 但是 Beat Saber 看上去更健康一些, 然后晚上还是安排玩 Beat Saber, 但是心里由于没有玩到风暴英雄感到很空虚&rdquo; 的这种感觉.</p> <p>不太清楚到底应该如何取舍(或者统一?), 我该做和我想做.</p> <h2 id="总结">总结</h2> <p>开工第二周, 俺开始作为一个生产力机器, 叮当乱响地跑起来了!</p> 速记: 无题 1 https://strrl.dev/post/shorthand/%E6%97%A0%E9%A2%98-1/ Mon, 14 Feb 2022 14:42:26 +0800 https://strrl.dev/post/shorthand/%E6%97%A0%E9%A2%98-1/ <p>中午在 coffee nap 的时候, 脑子里止不住的瞎想啊, 突然想到了十几年前, 自己练琴的场景.</p> <p>具体也记不得年龄了, 不过肯定是在小学, 小孩子嘛, 被逼着练琴, 也没有被解释原因, 心里肯定是不痛快的.</p> <p>那个回忆是这样的, 已经在吵架了, 我哭, 母亲也哭, 我大声哭闹, 然后质问母亲, &ldquo;为什么你们都不会弹琴, 却要求我会呢?&rdquo;.</p> <p>那时候母亲楞了一段时间, 我甚至当时想着&quot;我的话有效了?&quot;</p> <p>然后过了一会被母亲从两边拧着脸说, &ldquo;正是因为我不会, 才希望你会.&rdquo;</p> <p>这对于当时的我是一个很大的冲击, 因为当时我认为父母就是 the best.</p> <blockquote> <p>后续记不得了. 当然后续对练琴感到兴趣, 是在初中某一个时间点, 突然出现了兴趣. 很奇怪, 我现在只能解释为, 脑子的构造发生了变化, 想通了.</p></blockquote> <p>如果我在未来有了后代, 我不希望自己像自己的母亲那样, 恼羞成怒地说出这样的话. 直接承认, 我不会, 但是我希望你会, 然后阐明一下论据<strong>可能</strong>会更好吧.</p> <blockquote> <p>我的父亲在上段时间也提到过, 小时候爷爷奶奶经常打他, 所以我的父亲决心自己不会这么对孩子. 显然俺爹是没做到的. :P 不过我小时候也确实欠揍.</p></blockquote> <p>上周在某个咖啡馆休息的时候, 我, 咖啡师和一个可爱的小孩子聊天, 他说他的梦想是当赛车手. 那个时候我突然意识到, 想让小孩子明白, &ldquo;实现梦想是需要实践的, 梦想不去做只是瞎想&rdquo; 这个理念即复杂, 又残酷.</p> <p>所以我放弃了, 选择了听孩子天马行空描绘自己的梦想.</p> <p>多大的孩子才能适合接触一些 &ldquo;有梦想需要去做&rdquo; 这种理念呢?</p> <p>我能不能当一个合格的家长? 显然是不行的.</p> 2022-06: 开工第一周 https://strrl.dev/post/weekly-report/2022/06-%E5%BC%80%E5%B7%A5%E7%AC%AC%E4%B8%80%E5%91%A8/ Sat, 12 Feb 2022 13:56:42 +0800 https://strrl.dev/post/weekly-report/2022/06-%E5%BC%80%E5%B7%A5%E7%AC%AC%E4%B8%80%E5%91%A8/ <p>这里又是一份周报, 时间范围是<code>2022-02-05</code>到<code>2022-02-12</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="撸代码计算机相关">撸代码/计算机相关</h2> <h3 id="玩一玩-nand2tetris">玩一玩 NAND2Tetris</h3> <p>俺在本科的专业是数字媒体技术, 和&quot;正统&quot;的计算机科学相比, 缺少了:</p> <ul> <li>数字电路, 模拟电路等( EE 相关的课程)</li> <li>操作系统</li> <li>编译原理</li> </ul> <p>多的是:</p> <ul> <li>计算机图形学</li> <li>多媒体编程</li> <li>多媒体剪辑与后期制作</li> <li>2D / 3D 美术</li> <li>乐理</li> </ul> <p>本科结束后, 我依旧完成不了&quot;给你半导体和导线, 构建出通用计算机&quot;这一目标.</p> <p>偶然间在 twitter 上看到了 &ldquo;Turing Complete&rdquo; 这个游戏, 同时也提到了 NAND2tetris. 算是为了弥补自己的一个遗憾吧, 开始在coursera 上看 NAND2Tetris.</p> <p>刚刚完成了第一周的作业, 理解了从真值表写出布尔表达式, 再到组合成门电路, 原来是这么回事.</p> <h3 id="绝妙的点子---growth-ofcodes">绝妙的点子 - growth-of.codes</h3> <p>对于开源事业来说, 分析开源项目的发展历程, 是比较有趣的. 比如说通过 star-history.com 来看一个 GitHub repo 的 star 数量,一定程度上能够反映它的火热程度.</p> <p> <p class="md__image"> <img src='./assets/star-history-2022212-container-runtime.png' alt="" /> </p> </p> <p>可以粗略的看出 docker 作为工业和个人使用的好工具, 它的热度以及热度增长速度是超过仅作为工业上常用的容器运行时 containerd与 cri-o 的.</p> <p>而后起之秀 podman 在发展速度上显然也没有 docker 那么快.</p> <p>再看一组图:</p> <p> <p class="md__image"> <img src='./assets/star-history-2022212-chaos-engineering.png' alt="" /> </p> </p> <p>chaosblade, chaos-mesh 和 litmus 目前的斜率差不多, 说明目前整个 chaos engineering 生态还是有一定关注度的.</p> <p>另外 chaos-mesh, chaosblade 中都存在较抖的地方, 说明在哪附近应该发了什么 announcement 快速吸引了一批人.</p> <p>其实除了 star 数据之外, 俺自己也比较关心的另外一个数据是代码的量级与复杂度. 举个例子拿当前 chaos-mesh 来说:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span><span class="lnt">33 </span><span class="lnt">34 </span><span class="lnt">35 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ scc . </span></span><span class="line"><span class="cl">─────────────────────────────────────────────────────────────────────────────── </span></span><span class="line"><span class="cl">Language Files Lines Blanks Comments Code Complexity </span></span><span class="line"><span class="cl">─────────────────────────────────────────────────────────────────────────────── </span></span><span class="line"><span class="cl">Go <span class="m">511</span> <span class="m">111849</span> <span class="m">12772</span> <span class="m">11190</span> <span class="m">87887</span> <span class="m">13736</span> </span></span><span class="line"><span class="cl">YAML <span class="m">153</span> <span class="m">178816</span> <span class="m">310</span> <span class="m">1385</span> <span class="m">177121</span> <span class="m">0</span> </span></span><span class="line"><span class="cl">TypeScript <span class="m">128</span> <span class="m">15626</span> <span class="m">1531</span> <span class="m">2180</span> <span class="m">11915</span> <span class="m">1564</span> </span></span><span class="line"><span class="cl">Markdown <span class="m">26</span> <span class="m">1678</span> <span class="m">491</span> <span class="m">0</span> <span class="m">1187</span> <span class="m">0</span> </span></span><span class="line"><span class="cl">Shell <span class="m">25</span> <span class="m">4863</span> <span class="m">418</span> <span class="m">757</span> <span class="m">3688</span> <span class="m">279</span> </span></span><span class="line"><span class="cl">SVG <span class="m">22</span> <span class="m">886</span> <span class="m">0</span> <span class="m">266</span> <span class="m">620</span> <span class="m">0</span> </span></span><span class="line"><span class="cl">Dockerfile <span class="m">10</span> <span class="m">308</span> <span class="m">87</span> <span class="m">9</span> <span class="m">212</span> <span class="m">36</span> </span></span><span class="line"><span class="cl">JSON <span class="m">10</span> <span class="m">5793</span> <span class="m">0</span> <span class="m">0</span> <span class="m">5793</span> <span class="m">0</span> </span></span><span class="line"><span class="cl">C <span class="m">4</span> <span class="m">239</span> <span class="m">32</span> <span class="m">64</span> <span class="m">143</span> <span class="m">9</span> </span></span><span class="line"><span class="cl">Python <span class="m">4</span> <span class="m">376</span> <span class="m">19</span> <span class="m">88</span> <span class="m">269</span> <span class="m">7</span> </span></span><span class="line"><span class="cl">TOML <span class="m">4</span> <span class="m">95</span> <span class="m">9</span> <span class="m">57</span> <span class="m">29</span> <span class="m">0</span> </span></span><span class="line"><span class="cl">TypeScript Typings <span class="m">4</span> <span class="m">77</span> <span class="m">3</span> <span class="m">65</span> <span class="m">9</span> <span class="m">0</span> </span></span><span class="line"><span class="cl">gitignore <span class="m">3</span> <span class="m">78</span> <span class="m">20</span> <span class="m">9</span> <span class="m">49</span> <span class="m">0</span> </span></span><span class="line"><span class="cl">Plain Text <span class="m">2</span> <span class="m">16</span> <span class="m">0</span> <span class="m">0</span> <span class="m">16</span> <span class="m">0</span> </span></span><span class="line"><span class="cl">Protocol Buffers <span class="m">2</span> <span class="m">320</span> <span class="m">53</span> <span class="m">0</span> <span class="m">267</span> <span class="m">0</span> </span></span><span class="line"><span class="cl">Docker ignore <span class="m">1</span> <span class="m">20</span> <span class="m">3</span> <span class="m">0</span> <span class="m">17</span> <span class="m">0</span> </span></span><span class="line"><span class="cl">Groovy <span class="m">1</span> <span class="m">313</span> <span class="m">10</span> <span class="m">88</span> <span class="m">215</span> <span class="m">7</span> </span></span><span class="line"><span class="cl">HTML <span class="m">1</span> <span class="m">52</span> <span class="m">0</span> <span class="m">35</span> <span class="m">17</span> <span class="m">0</span> </span></span><span class="line"><span class="cl">JavaScript <span class="m">1</span> <span class="m">12</span> <span class="m">2</span> <span class="m">0</span> <span class="m">10</span> <span class="m">0</span> </span></span><span class="line"><span class="cl">License <span class="m">1</span> <span class="m">201</span> <span class="m">32</span> <span class="m">0</span> <span class="m">169</span> <span class="m">0</span> </span></span><span class="line"><span class="cl">Makefile <span class="m">1</span> <span class="m">364</span> <span class="m">82</span> <span class="m">13</span> <span class="m">269</span> <span class="m">3</span> </span></span><span class="line"><span class="cl">Smarty Template <span class="m">1</span> <span class="m">139</span> <span class="m">19</span> <span class="m">0</span> <span class="m">120</span> <span class="m">10</span> </span></span><span class="line"><span class="cl">─────────────────────────────────────────────────────────────────────────────── </span></span><span class="line"><span class="cl">Total <span class="m">915</span> <span class="m">322121</span> <span class="m">15893</span> <span class="m">16206</span> <span class="m">290022</span> <span class="m">15651</span> </span></span><span class="line"><span class="cl">─────────────────────────────────────────────────────────────────────────────── </span></span><span class="line"><span class="cl">Estimated Cost to Develop <span class="o">(</span>organic<span class="o">)</span> <span class="nv">$10</span>,402,741 </span></span><span class="line"><span class="cl">Estimated Schedule Effort <span class="o">(</span>organic<span class="o">)</span> 33.491163 months </span></span><span class="line"><span class="cl">Estimated People Required <span class="o">(</span>organic<span class="o">)</span> 27.595197 </span></span><span class="line"><span class="cl">─────────────────────────────────────────────────────────────────────────────── </span></span><span class="line"><span class="cl">Processed <span class="m">14603718</span> bytes, 14.604 megabytes <span class="o">(</span>SI<span class="o">)</span> </span></span><span class="line"><span class="cl">─────────────────────────────────────────────────────────────────────────────── </span></span></code></pre></td></tr></table> </div> </div><p>只看 go 的话, 它目前的复杂度是 <code>13736</code>, 这是个什么概念呢, 可以和其他的项目对比一下:</p> <ul> <li>scc 的复杂度是 <code>1473</code></li> <li>frp 的复杂度是 <code>2636</code></li> <li>clash 的复杂度是 <code>3232</code></li> <li>caddy 的复杂度是 <code>7711</code></li> <li>traefik 的复杂度是 <code>9825</code></li> <li>prometheus 的复杂度是 <code>14799</code></li> <li>hugo 的复杂度是 <code>16973</code></li> <li>etcd 的复杂度是 <code>38566</code></li> <li>influxdb 的复杂度是 <code>60341</code></li> <li>tidb 的复杂度是 <code>100316</code></li> <li>containerd 的复杂度是 <code>125054</code></li> <li>docker 的复杂度是 <code>195758</code></li> <li>kubernetes 的复杂度是 <code>549928</code></li> </ul> <blockquote> <p>参考<a href="https://github.com/boyter/scc#complexity-estimates">scc#complexity-estimates</a>, 同语言之间的相对值比较还是有意义的.</p></blockquote> <p>除了项目之间对比之外, 复杂程度随着时间的变化也是非常有趣的! 而这就是 growth-of.codes 想做的事情: 展示代码的复杂程度随着时间的变化.</p> <p>比如说某一天复杂度突然增加, 可能是加了什么新 feature(或者合了屎); 某一天复杂度突然降低, 可能是进行了重构(或者铲了屎).</p> <p>基本上做得事情就是, 把某个项目的历史 commits 俺天 checkout 出来, 跑一下 scc 然后放到存储里, 后续再展示.</p> <p>俺还是想把它做得 cool 一点, 顺便玩玩 serverless 和云数据库.</p> <h3 id="又一个绝妙的点子---dodo-rooster">又一个绝妙的点子 - dodo rooster</h3> <p>🦤 dodo rooster, 渡渡鸟栖木.</p> <blockquote> <p>借鉴了 war3 中暗夜精灵族建筑, &ldquo;奇美拉栖木&rdquo; (Chimaera Roost) 的名字.</p></blockquote> <p>至于渡渡鸟是什么, 大家可以参考 <a href="https://en.wikipedia.org/wiki/Dodo">Wiki</a> 和 <a href="https://longfangsong.github.io/tipedia/zh/what/%E6%B8%A1%E6%B8%A1%E9%B8%9F.html">这里</a>.</p> <p>dodo rooster 是一个类似于 slido 的匿名论坛. 需要接入外部的 auth 系统, 登录后可以选择匿名昵称. 为了防止过激言论, 可以允许委员会成员&quot;开盒&quot;匿名身份.</p> <p>差不多思路如下:</p> <ol> <li>开启匿名讨论前, 选出 N 个公平公正的委员会成员;</li> <li>委员会成员全员生成一会非对称密钥, 并上传公钥.</li> <li>N 个委员会成员开启一个 Session, 生成一対非对称密钥, 我们分别称之为 A-pub 和 A-priv</li> <li>持久化公钥.</li> <li>随即使用 Shamir&rsquo;s Secret Sharing 配合参数 &ldquo;分成 N 份, 至少 M 份才能还原信息&rdquo; 对 A-priv 进行分发, 使用委员会成员的公钥加密分发后的&quot;碎片&quot;, 持久化加密后的信息.</li> <li>剩余其他 x 个成员加入, 使用 auth 登入, 将 id 与 匿名身份的对应关系使用 A-pub 加密后持久化.</li> <li>使用匿名身份发言</li> <li>尝试&quot;开盒&quot;某个匿名身份, 需要至少 M 个委员会成员的支持, 还原出 A-priv, 解密 id 与 匿名身份的对应关系.</li> </ol> <blockquote> <p>Shamir&rsquo;s Secret Sharing 是一中密码学的算法, 可以理解为&quot;一个消息加密后被分成 a 份, 只有至少凑齐 b 份后才能够解密出来.&quot;</p></blockquote> <p>需要开盒某个匿名身份的话, 一定需要 A-priv, 而完整的 A-priv 有且只有存在于:</p> <ul> <li>步骤 3, 4, 5 内存中</li> <li>步骤 8 的内存中</li> </ul> <p>而且完整的 A-priv 只有在 N 个委员会成员中, 至少有 M 个成员使用私钥解密后, 才会得出. 因此在有了信任的委员会成员后, dodo rooster 可以做到真正的&quot;匿名&quot;, 没有技术手段可以破解.</p> <blockquote> <p>嗯, 对比的就是某系统的前台匿名, 后台实名.</p></blockquote> <p>最后, 因为 A-priv 总归会出现在某台服务器的内存中的, 而 dump 内存再扣密钥我想也并不是什么难事, 所以解决这个问题的最佳方案是:</p> <ul> <li>开源, 代码中没有后门, 偷偷传/存了一份 A-priv</li> <li>serverless, 没有人能够直接控制服务器 or 很难去控制运行时的服务器</li> </ul> <p>其实俺觉得这个适用场景还蛮大的&hellip;.</p> <h3 id="ynuosa-上新机器">YNUOSA 上新机器</h3> <p>感谢慷慨的 TUNA 给我们捐赠了一台 DELL Poweredge R720 机器, 之前它一直在教师办公室吃灰, 最近终于有机会放回机柜了.</p> <p>我一直有一个大胆的想法, 就是在虚拟机层面用上类似于 Kubernetes Pod Networking 的大平层设计. 后来发现 VMWare 支持了这个特性, 叫做 &ldquo;vSphere Distributed Switch&rdquo;, 功能如其名, 跨 host 的网络交换.</p> <p>但是上到机柜里后, 发现了一个较为严重的问题, 两个 esxi host 之间的网不是直通的, 我们只能自己想办法做虚拟机的 overlay network 大平层了.</p> <p>现在使用的方法是, esxi host 中分别起转发机器, 我们称之为 relay-alice 和 relay-bob, relay 之间使用一个都能访问到的&quot;公网&quot; IP 通过 wireguard 做 tunnel, 然后再使用 tinc 借助 tunnel 的 IP 做二层的转发. 现在我们有了一个大平层, 以后 workload VM 之间的互相访问会变得非常直接.</p> <blockquote> <p>感谢<a href="https://atr.me/">星云蘑菇</a>提的建议!</p></blockquote> <p>另外 workload networking 的网关其实就是一台 openwrt, 可以装 openclash, 利好安装 kubernetes.</p> <h3 id="nix-的屈辱试用">nix 的屈辱试用</h3> <p>想赶下风潮用下 nix, 结果被吃了下马威: 官方的文档建议使用 multi-user 的安装方式, 根据步骤一步一步走完后, 出现了先后出现了nix 的 daemon 启动不起来, <code>error: could not set permissions on '/nix/var/nix/profiles/per-user' to 755: Operation not permitted</code>, 和 <code>error: cannot connect to daemon at '/nix/var/nix/daemon-socket/socket': Connection refused</code> 等等问题. 而且使用搜索引擎搜索我的环境(fedora) 加问题描述基本上没有看得对眼的.</p> <p>无奈铲之, 试了一下 single-user, 然后就活了&hellip;活了&hellip;</p> <p>总之体验比较差, 在新的心血来潮之前不准备再摆弄 nix 了.</p> <h2 id="生活相关">生活相关</h2> <h3 id="睡眠质量堪忧">睡眠质量堪忧</h3> <p>某天早上起来昏昏沉沉, 打开三星健康看到昨晚的深度睡眠只有 17min. 最近在看<em>睡眠革命</em>, 里面提到了几个有意思的事情:</p> <ul> <li>少睡了的觉是没有办法补救的</li> <li>长期的睡眠不足会使快速眼动睡眠被加入到前面的睡眠周期中, 导致深度睡眠少</li> <li>预计入睡的 90min 前准备睡觉, 少做剧烈运动, 进入光线偏暗的环境, 少看荧幕. 允许的话洗热水澡或泡(热水)脚.</li> </ul> <p>反省一下自己, 我一只都是对着屏幕一直到睡觉前的 10 - 15 分钟, 然后有需要的话快速冲个澡, 然后躺在床上期望快速睡着.</p> <p>看完了书以后感觉到, 这样能快速睡着真的是见了鬼了哦.</p> <p>也就是说, 如果我准备 00:00 睡觉/睡着的话, 最好是 22:30 就要从电脑前走开了, 准备洗澡, 然后再在<em>某个地方</em>(还没想好在哪, 但是我不喜欢在床上)看会纸质书, 然后到点睡觉. 这和我目前的生活习惯还是差的挺多的, 但是精神状态差实在是太痛苦了, 我认为在看完那本书后, 值得尝试一下.</p> <h3 id="hzlug-hacking-saturday">HZLUG Hacking Saturday</h3> <p>zion 大佬给介绍了一个合适的地方, 是一个共创空间的一楼大厅, 可以用来线下小聚. 我们在 2022-02-12 举办了恢复后了第一次HZLUG Hacking Saturday, 三个爷们就这样聊了一下午:</p> <p><a href="https://hzlug.org/0212-h6-photo/">https://hzlug.org/0212-h6-photo/</a></p> <blockquote> <p>ylgg 真捧场! 赞美 ylgg!</p></blockquote> <h2 id="总结">总结</h2> <p>开工第一周, 效率拉胯, 静想整些没用的.</p> 2022-05: 杭州就地过年实录 https://strrl.dev/post/weekly-report/2022/05-%E6%9D%AD%E5%B7%9E%E5%B0%B1%E5%9C%B0%E8%BF%87%E5%B9%B4%E5%AE%9E%E5%BD%95/ Fri, 04 Feb 2022 13:55:33 +0800 https://strrl.dev/post/weekly-report/2022/05-%E6%9D%AD%E5%B7%9E%E5%B0%B1%E5%9C%B0%E8%BF%87%E5%B9%B4%E5%AE%9E%E5%BD%95/ <p>这里又是一份周报, 时间范围是<code>2022-01-28</code>到<code>2022-02-04</code>, 会记录一些工作及生活上有意思的事情.</p> <h2 id="撸代码相关">撸代码相关</h2> <p>还是先聊聊撸代码相关的事情吧, 毕竟过去一周一直都在休假, 虽然一直没停下 coding 但是也没碰一行工作相关的代码. (doge</p> <h3 id="猫年水的第一个-pr">猫年水的第一个 PR</h3> <p>大年三十那天在整理 homelab 的时候, 发现在<a href="https://twitter.com/strrlthedev/status/1469330815712563202">上次重建了 Kubernetes 集群</a>后, 监控项并没有全部恢复上去. 于是开始重新创建监控项, 顺手<a href="https://github.com/prometheus-operator/prometheus-operator/pull/4541">修复了一个会导致 panic 的 bug</a>.</p> <p>引起 panic 的原因很简单, <code>err error</code> 是一个 interface, 它可能会是一个 <code>nil</code>. 然后 error 的 resolver 也没有判断 err 是否为 nil, 直接调用了 <code>err.Error()</code>.</p> <blockquote> <p>对于代码段的&quot;预期行为&quot;, 还是要写到注释里哇. 如果 error resolver (它这里是 <code>rejectFn()</code>) 的注释里说明, <code>err could not be nil</code>, 也能让调用者注意一下.</p></blockquote> <blockquote> <p>想念 Kotlin, TS, Rust &ldquo;Void safety&rdquo; 的各种好.</p></blockquote> <p>大年三十提的 PR, 大年初一合进去了, 开心哇.</p> <h3 id="给自己上刑-全开-golangci-lint">给自己上刑, 全开 golangci-lint</h3> <p>在俺刚工作写 Java 那会, 因为之前接触工程太少了, 组长看了直摇头, 给俺直接上了刑: SonarQube Quality Gates 直接拉到 A. 它会给你报各种 warning:</p> <ul> <li>没做非空处理</li> <li><code>else-return</code> 是多余的</li> <li>函数过于复杂(complexity 大于十几)</li> <li>函数体太长了(印象是超过 200 行)</li> <li>该加 <code>final</code> 没加 <code>final</code></li> <li>注释中没解释某个参数</li> <li>注释中没解释为什么<code>@Deprecated</code></li> <li>等等&hellip;</li> </ul> <p>虽然每次写完了代码, CI 跑了以后都要改不少, 但是感觉自己变强了!</p> <p>最近的项目里, GitHub 推荐的 Sonatype Lift 不太好用, 一方面是因为比较慢, 另一方面是因为默认情况下不在 CI/GitHub Actions 里跑, 很容易忘记它. 因此俺又拾起了 goalngci-lint, 直接给 <code>kubectl-push</code> 上了邢, 而且除了禁用了弃用以及 issue 中提到行为有冲突的之外, 开启了其他所有的 linter. 一通修改之后, 终于变绿了!</p> <h3 id="lfx-mentorship-q1-2022-上新">LFX Mentorship Q1-2022 上新</h3> <blockquote> <p>关于 LFX Mentorship 的简介可以参考这篇<a href="https://twitter.com/strrlthedev/status/1427527683827593221?s=20&amp;t=BtZWay-ZGZiOBexLVVYnrw">推文</a>.</p></blockquote> <p>又到了 LFX Mentorship 上新的季节了, 这次 Chaos Mesh 又为各位新人们带了一个好玩的新玩意: <a href="https://mentorship.lfx.linuxfoundation.org/project/09847d84-5d14-4c05-8644-57cdde5b6466">CNCF - Chaos Mesh: Interactive Katacoda Playground for Chaos Experiment Examples</a>.</p> <p>这个项目想使用 katacoda playground 把 Chaos Mesh 中的各个 example 作为可交互的例子跑起来, 这样比起冷冰冰的 yaml 文件, 有一个可以操作的环境更为直接! 这个项目不是那么硬核, 而且它的工作和产出不主要在 coding. 所以想体验作为开源软件工程师, 来写文档, 写 demo 的同学可以考虑下报名~</p> <p>这次的 LFX Mentorship 的 timeline 以及可选的项目可以参考<a href="https://github.com/cncf/mentoring/blob/main/lfx-mentorship/2022/01-Spring/README.md">这篇文档</a>. 另外, 每个人只有一次作为 Mentee 的机会, 请慎重选择你的项目.</p> <h3 id="chaos-mesh-incubation">Chaos Mesh Incubation</h3> <p>Chaos Mesh Incubation 投票已经获得了 9 票, 应该是已经达到进阶为孵化器项目的标准了! 非常的开心, 等待一个官宣!</p> <p><a href="https://lists.cncf.io/g/cncf-toc/topic/88571074#6568">Mailing list</a></p> <h3 id="对于备份恢复工具的新想法">对于备份恢复工具的新想法</h3> <p>最近一直在用 btrfs 的 snapshot 做备份和增量备份, 写了脚本来随缘跑跑. 之前的 send 是直接写到另一块 HDD 上去了, 最近想放到 NAS 里. 所以又多填了几步 mount nfs 的过程.</p> <p>俺在想, 有没有那么一个工具, 它可以使用 zfs/btrfs 的 snapshot 机制做备份, 然后后面对接了各种存储, 文件啊, S3 啊, WebDAV 啊什么的. 俺现在也在自己寻找中, 如果有人知道的话请告诉我.</p> <p>如果木有的话俺想自己撸一个. 🤩</p> <h2 id="一个人在杭州就地过年">一个人在杭州就地过年</h2> <p>年前蛮早的时候, 就和父母盘算着, 今年还是不回去了. 一方面因为山东的基层过度执行太严重了, 到地隔离 7 + 7, 没有办法快去快回, 另外一方面也是因为家里养了三条狗子, 我的作息和狗子们不重合, 休息不够实在是难受.</p> <p>另外就在放假的前几天, 杭州也寄了, 貌似从 1.26 出现了病例以后, 每天都有新增. (回不去辽, 回不去辽)</p> <p>但是女朋友顺利回家了, 南方比较人性化, 持核酸阴性结果就可以回家过年了. 上两天还在给我转播剧本杀, 打麻将, 真的是羡慕死了.</p> <h3 id="就地过年的朋友们">就地过年的朋友们</h3> <p>无论是高中同学, 还是大学同学, 都有相当一部分人选择了就地过年.</p> <p> <p class="md__image"> <img src='./assets/photo_2022-02-04_14-27-19.jpg' alt="不回家才他妈快乐" /> </p> </p> <p>忘记什么时候看到了 &ldquo;90 后不再维系亲戚关系&rdquo; 类似的报道了, 对我来说确实是这样的. 在我的印象中, 走亲戚从小就是一份苦差事, 被家里大人拉着坐不知道多久的车, 见到一片不认识的人. 🤪</p> <h3 id="读书-读书-读书">读书 读书 读书</h3> <p>从公司的看书群里里被安利了<a href="https://m.douban.com/book/subject/1013208/"><em>如何阅读一本书</em></a>, 尝试翻看.</p> <p> <p class="md__image"> <img src='./assets/Screenshot_20220204_144007.png' alt="读书群强势安利" /> </p> </p> <p>最近也差不多详略(不太)得当地看完了, 最大的感触是看书不应是一件根据页码顺序读, 而应是要先建索引, 再去填充内容.</p> <p>小时候妈妈也曾经教过我, 看书要先略读, 再细读; 我也能依稀记得,按照这种方式能够理解一本书后的喜悦. 但是这个技能点不知道什么时候被我丢了. 根据页码顺序读也不是不行, 只是书中的内容并不全部都是重要的, 会浪费一部分时间. 大约是一两年前, 我曾经依照顺序阅读的方式看完了 <em>Kubernetes in Action</em>, 因为当时是几乎完全不理解 Kubernetes, 所以把书中的句句都当作重点来看, 现在回想起来, 确实是效率太低了.</p> <p>另外在阅读的时候一定要做好记录, 因此我创建了 <a href="https://whatiknown.strrl.dev/#/page/books">Books</a> 这个 logseq page, 用于记录我在阅读时发现的一些东西.</p> <h3 id="风暴-风暴-风暴">风暴 风暴 风暴</h3> <p>放假在家怎么能不打游戏呢! 年后开始了高强度的风暴英雄, 甚至一度达到了四人车五人车的盛况. 自从微软收购了暴雪以后, 真的是心情舒畅哇. 啊哈哈啊哈哈</p> <p>(如果想一起打游戏可以加俺的好友, <code>锐凌大魔王#5955</code>)</p> <h3 id="烟花爆竹管不住哇">烟花爆竹管不住哇</h3> <p>说起烦恼的事情, 那就不得不提居民附近内放烟花了. 虽然已经下发了通知, 小区公园, 门口的大 LED 屏上也明确标明, 不准燃放烟花爆竹, 但是依旧管不住. 因为我家在 11 楼, 二踢脚飞起来差不多就在 10 - 11 楼的高度, 二踢脚就在你脸上爆炸的感觉还是挺害怕的.</p> <p>所以在某天俺终于鼓起勇气打了 96110 举报了烟花爆竹. 现象是只有三十晚上仍有较多的爆竹, 初一早上木有, 后面也木有了, 就当作是起效果了吧. 不过初六开业估计还是得有人放的.</p> <h2 id="总结">总结</h2> <p>一个人就地过年爽的一批.</p> 抄一抄 Xuanwo 的工作流 & 第一篇周报 https://strrl.dev/post/weekly-report/2022/03-%E6%8A%84%E4%B8%80%E6%8A%84xuanwo%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%B5%81-%E7%AC%AC%E4%B8%80%E7%AF%87%E5%91%A8%E6%8A%A5/ Sat, 29 Jan 2022 13:09:43 +0800 https://strrl.dev/post/weekly-report/2022/03-%E6%8A%84%E4%B8%80%E6%8A%84xuanwo%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%B5%81-%E7%AC%AC%E4%B8%80%E7%AF%87%E5%91%A8%E6%8A%A5/ <h2 id="周报">周报</h2> <p>这是俺的第一篇周报, 时间范围是 <code>2022-01-22</code> 到 <code>2022-01-28</code>. 会记录一些工作以及生活上有意思的东西.</p> <h3 id="chaos-mesh">Chaos Mesh</h3> <h4 id="cncf-incubation">CNCF Incubation</h4> <p>Chaos Mesh 的申 Incubation 已经进入了投票阶段, 这个阶段最多长达 6 个周, 在此期间, CNCF TOC 们会通过<a href="https://lists.cncf.io/g/cncf-toc/topic/vote_chaosmesh_for/88571074">邮件列表</a>的方式来提交投票, 超过 <code>2/3</code> 即可通过; 目前已经有 11 席中已经有 6 票 <code>+1</code>. 满怀期待.</p> <p>成为 Incubation Project 后, Chaos Mesh 将获得更多的帮助, 目前能够想到的是会有更多曝光的机会, 在 KubeCon 有单独的席位, 并且会有 webinar 的活动.</p> <blockquote> <p>另外印象中 Incubating 和 Graduated 项目是有 CI 基础设施的赞助来着, 但是找不到 Reference 了.</p></blockquote> <h4 id="混沌实验的可观测性">混沌实验的可观测性</h4> <p>大白话: 在 Chaos Dashboard 里能够看应用(已经配置好的) Grafana Dashboard.</p> <p>这个 Feature 讨论许久了, 而且在最开始也<a href="https://cloud-native.slack.com/archives/C0193VAV272/p1640013796164600">被用户吐槽过</a>.</p> <p>以后需不需要 Chaos Mesh 采集一些只有它才擅长采集的 Metrics, 比如说:</p> <ul> <li>密度较高的 CPU, Memory, IO 等资源使用</li> <li>被影响 Pod 网络之间延迟, 丢包率等</li> </ul> <p>还不确定要不要做.</p> <h4 id="lfx-mentorship-q1-2022">LFX Mentorship Q1-2022</h4> <p>LFX Mentorship 又来了! 这次俺又想出了一个<a href="https://github.com/cncf/mentoring/blob/main/lfx-mentorship/2022/01-Spring/project_ideas.md#interactive-katacoda-playground-for-chaos-experiment-examples">好玩的点子</a>, 使用 Katacoda 把 Chaos Mesh 目前提供的 examples 变得更加&quot;具象化&quot;. 这次的 Project 应该不需要深奥的 coding, 更多的是做 scenario 的演示. 对于 Mentee 来说, 在 12 周的时间里, 完成一些较为简单的工作<del>摸摸鱼划划水</del>, 能够拿到 $3000 的补贴, 另外你的工作成果也会被放到 chaos-mesh.org 上.</p> <p>LFX Mentorship Q1-2022 将在 2022-02-02 - 2022-02-13 开始开放 Mentee 的申请, 欢迎还在上学的同学参与! 大家可以考虑准备报名了~</p> <p>最后放一个<a href="https://github.com/cncf/mentoring/discussions/445">原文链接</a></p> <h3 id="hangzhou-linux-user-group">Hangzhou Linux User Group</h3> <p>今年年中, zionfuo 由于工作原因去了上海, 于是把 HZLUG &ldquo;托付&quot;给了俺. 但是俺是一个愣头愣脑的工程师, 没有举办过啥活动, 再加上疫情的影响, 至今也没有玩出一个线下的活动. 反观 Shanghai LUG, 依旧每周都玩得很 high, 羡慕死了. 再看看 houge 今年新创办的 Yunnan LUG, 也开始在年关内筹办线下活动了.</p> <p>在上段时间, 联系了公司内的社区运营同学, 她们答应可以把 HangZhou Office 的大会议室借给我们. 但是期望中的效果依旧是有 Hacking Saturday 这种 weekly 的活动, 每周都去占用公司的大会议室还是不太好意思的. 因此我还是想去找一个合适的咖啡馆, 大家可以有个桌子收拾自己的设备, 然后能尽兴地聊一聊. 至于大会议室, 如果未来有 Monthly Meetup, 或者是有同学想做主题分享的话, 再去使用那个场地.</p> <h3 id="生活方面">生活方面</h3> <h4 id="half-life-alyx">Half-Life: Alyx</h4> <p>由于在上届的 TiDB Hackathon 中, <del>很惭愧地</del>拿到了最佳创意奖, 有五千大洋的奖金, 于是买了一台 Oculus Quest 2. 设备其实上周就到了, 但是最近一周开始了重度游玩(迷失在元宇宙里).</p> <p>半衰期: 爱莉克斯是一款饭制的 VR 游戏, 目前在 Steam 平台有售. Oculus Quest 2 在进入开发者模式后, 打开 Air Link 就可以连接到 SteamVR 玩 PCVR 的游戏了.</p> <blockquote> <p>从名字 &ldquo;Air Link&rdquo; 上来看, 不知道与 Apple 有没有什么交易.</p></blockquote> <p>游戏的质量还是比较高的, 甚至某个游戏场景中还有一个<a href="https://twitter.com/strrlthedev/status/1485631347586920450?s=20&amp;t=BoLFzh7A5LeLN6F4hawT7w">可以交互的钢琴</a>.</p> <p>但是就像其他的打僵尸游戏一样, 它依旧算是一款恐怖游戏. 我是非常介意恐怖元素的, 所以我</p> <p> <p class="md__image"> <img src='./assets/half-life-alyx-trainer.png' alt="trainer" /> </p> </p> <blockquote> <p>果然恐惧来源于火力不足.</p></blockquote> <h4 id="其他">其他</h4> <ul> <li>阿里旁边亲橙里的新时期烤肉无了, 变成了一家 KTV. 绕远去另一家吃, 但是感觉味道没有倒闭的那家好. 🥲</li> <li>睡眠质量变差, 入睡时间长, 又需要恰腿黑素了.</li> <li>玩 VR 游戏对脖子负担太重了, 左边脖子痛.</li> <li>三星要发布 S22 了, 但是依旧是异形屏.</li> <li>想恢复运动和锻炼.</li> </ul> <h2 id="关于抄一抄-xuanwo-的工作流">关于抄一抄 Xuanwo 的工作流</h2> <p>Zhiqiang 在尝试找到适合自己的工作/学习方式, 准备试着抄一抄 Xuanwo 哥哥的目前的流程.</p> <h3 id="前情提要">前情提要</h3> <p>自从加入 PingCAP 的 Chaos Mesh 小组后, 由于工作方式不再像是之前需求 -&gt; 评审 -&gt; 开发 -&gt; 交付, 而是变成了以 GitHub 为核心工具的, 更为灵活的工作流. 我的工作效率其实产生了一定的波动.</p> <p>我本身是个懒人, 而且又会出现很多天马行空的想法感觉可以做, 所以最后的结果是鸽了太多太多的东西. Leader 也曾经找过我谈话, 要注重一下想法的落地.</p> <p>今年 10 月份开始, 俺开始读 <em>Getting Things Done</em>, 并开始尝试依照这本书提供的方式来整理自己的任务. (但是目前的效果还不算太好, 因为书至今没读完, GTD 学了个半吊子.)</p> <p>上段时间在乱刷 GitHub 的时候, 发现了 Xuanwo 哥哥的 GitHub Profile 提到了:</p> <blockquote> <p>I think it&rsquo;s a reproducible way for learning, working and thinking. Anyone with a similar background to mine can start learning incrementally with this repo. Also, It will be very interesting to see how this project will develop in the end. Whether the end result is good or bad, I believe it will be an interesting journey.</p></blockquote> <p>那既然有这么强的暗示了, 那我就不客气了, 开抄. <del>(你的东西很不错, 但下一秒就是我的了</del></p> <h3 id="拿过来一把梭">拿过来一把梭</h3> <p>目前看上去, Xuanwo 哥哥的东西主要分为三个部分:</p> <ul> <li>logseq 用于构建知识库: <a href="https://note.xuanwo.io/">Note</a></li> <li>Blog 用于记录和总结, 主要是周报/双周报: <a href="https://xuanwo.io/">Blog</a></li> <li>GitHub Projects 用于管理项目进度: <a href="https://github.com/users/Xuanwo/projects/2">Xuanwo&rsquo;s Work</a></li> </ul> <p>我就直接开抄:</p> <ul> <li>同样使用 logseq 构建知识库: <a href="https://whatiknown.strrl.dev/">whatiknown</a></li> <li>同样使用 Blog 以及周报的形式来记录和总结: <a href="https://strrl.dev/">Blog</a></li> </ul> <p>关于是否使用 GitHub Projects 来管理工作进度, 我仍有顾虑. 目前用 Notion 来管理, 效果还一般, 等待看完:</p> <ul> <li><em>Getting Things Done</em></li> <li><a href="https://docs.github.com/en/issues/organizing-your-work-with-project-boards/managing-project-boards/about-project-boards">GitHub Projects Boards 文档</a></li> </ul> <p>后, 再决定使用哪个吧.</p> <p>同时使用 logseq 的 journal 记录每天发生的事情, 免得双周报的时候没得写.</p> 开源与商业产品冲突吗 https://strrl.dev/post/weekly-report/2022/02-%E5%BC%80%E6%BA%90%E4%B8%8E%E5%95%86%E4%B8%9A%E4%BA%A7%E5%93%81%E5%86%B2%E7%AA%81%E5%90%97/ Fri, 28 Jan 2022 02:34:46 +0800 https://strrl.dev/post/weekly-report/2022/02-%E5%BC%80%E6%BA%90%E4%B8%8E%E5%95%86%E4%B8%9A%E4%BA%A7%E5%93%81%E5%86%B2%E7%AA%81%E5%90%97/ <p>这其实是对于 Chaos Mesh 的一些&quot;抱怨&quot;, 有些问题还不知道如何去解决, 这里是一些完全没有章法的胡思乱想.</p> <h2 id="对比之后不太自信">对比之后不太自信</h2> <p>刚刚看了一个 <a href="https://chaoscarnival.io/">Chaos Carnival 2022</a> 中的一个<a href="https://www.youtube.com/watch?v=JJJF8s9fuGk">演讲</a>, 涉及到了 Chaos Mesh 和 Litmus Chaos 之间的对比. 看完后内心还是有一些波澜. 跑到客厅吃完凉掉了的溜肉段, 想来想去还是需要记一下, 权当&quot;沉淀&quot; 下来.</p> <h2 id="chaos-mesh-是一个好产品吗">Chaos Mesh 是一个好产品吗?</h2> <p>这个问题的答案, 目前肯定是否定的. 因为算上即使我现在的认知, 带着现在的 Chaos Mesh Artifacts, &ldquo;穿越&rdquo; 回两年前做 SRE 的时候, 我也不太会将它用到我们的应用上, 因为 Chaos Mesh 还不够&quot;成熟&quot;. 不够&quot;成熟&quot;仅表示, 有些重要的的特性, 我想到了但是你木有; 所以我不会用.</p> <p>Chaos Mesh 在混沌注入的能力上异常强大, 基本是没有什么其他平台能够在注入的功能上能一战的. 但是在最近的 TiDB Hackathon 上, 有一组同学在使用 Chaos Mesh 的时候明确地指出 &ldquo;太难用了!&rdquo;, &ldquo;我注入了故障进去以后啥都看不到&rdquo;.</p> <p>另外, 如何定义&quot;产品&quot;.</p> <blockquote> <p>此处应该去查阅一些项目管理相关的知识, 先挖个坑. 下面的内容暂时都是我的瞎想, 理解是肯定存在偏见与错误的.</p></blockquote> <p>目前我认为的&quot;产品&quot;, 是指一个能够交付给 &ldquo;End User&rdquo; 的产物. 想 AZure Chaos Studio 这种将 Chaos Mesh 集成进去再提供服务的情况, Chaos Mesh 不算是产品, 它只能算是工具.</p> <p>那么老老实实做一个强大的工具不好吗? 为什么一定要纠结产品呢?</p> <p>因为不做产品就有可能意味着工具也有可能活不下去. 我(们)现在之所以能够靠写 Chaos Mesh 吃饭, 是因为资本认为它未来能够卖钱. 而&quot;未来&quot;是多久, 我并不明确知道, 我目前主观估测是 1 - 2 年. 如果资本放弃了它, 那它作为工具的未来可能会变得更加自由, 但是生长的速度与质量绝对不会比现在好.</p> <blockquote> <p>此处应该去查阅一些开源项目的历史, 他们背后的公司在早期阶段是如何运作的.</p></blockquote> <p>由于 Chaos Mesh 是一个混沌工程平台, 它的特性决定了它几乎不会存在个人用户, 也就是说使用 Chaos Mesh 的绝大多数都是 B 端用户. 我不能确定我们是否还需要对于 B 端用户当作小白来看待, 对概念和交互方式的简化无所不用其极. 老实说, 在使用 <a href="https://www.gremlin.com/">Gremlin</a> 的时候, 我确实能够感受到 Gremlin 在把我当作小白来指引:</p> <ul> <li>不严谨但是亲切的实验类型</li> <li>最后需要收入填写表单来记录试验结果(Pass or Failed)</li> <li>简单但是能用的实验编排</li> </ul> <p>如果我能算得上是一个&quot;专业用户&quot;的话, Gremlin 依旧能够带给我超越 Chaos Mesh 很多的使用体验.(这不废话嘛, 人家做 SaaS 不知道多少年了.)</p> <p>因此, 虽然作为一个开源项目, 把它变得&quot;好用&quot;依旧是比较重要的.</p> <h2 id="人是如何感知到某个东西好用的">人是如何感知到某个东西好用的?</h2> <p>我主观认为的&quot;好用&quot;要符合人的直觉, 而<a href="https://en.wikipedia.org/wiki/Intuition">直觉</a>其实是一种行为模式, 不同的人会因为阅历和经验的不同, 产生不同的行为模式. 这也表明了人在依靠直觉进行动作时, 并没有使用现有的知识进行思考, 并产生新的知识.(懒惰?)</p> <p>所以, 我的思路是, 先选定 Chaos Mesh 的目标用户, 假设他们有某种程度的经验, 再去揣测他们的直觉, 最后再设计出的 Chaos Mesh 交互方式才是好用的.</p> <p>我主观认为的&quot;好用&quot;也要使它&quot;可见&quot;和&quot;可理解&quot;:</p> <ul> <li>&ldquo;可见&rdquo; 指人看到了变化, 通过数据的对比 or 拟物的动画;</li> <li>&ldquo;可理解&quot;指即使某人没有前置知识, 他依旧能产生&quot;我懂了&quot;的感觉; (真玄乎了, 这怎么做到?)</li> <li>&ldquo;可见&quot;和&quot;可理解&quot;同时也要保证正确性, 绝对不能扭曲事实(错误的引用或改变定义), 尽量不隐藏细节;</li> </ul> <p>&ldquo;可见&quot;和我们常说的&quot;可观测性&quot;又不是完全相同的一回事, &ldquo;可见&quot;指用户的双眼看到了 something changed, 这种&quot;可见&quot;需要依靠&quot;可观测性&quot;技术来实现.</p> <blockquote> <p>我在向大家作&quot;可见&quot;相关 feature 介绍的时候, 用的是&quot;混沌实验的可观测性&rdquo;, 引起了我们小组内部也有一部分分歧:</p> <ul> <li>一部分同学(好吧其实只有我)认为, 需要为 Chaos Mesh 所做的行为展示其影响, 需要为所有混沌实验类型提供直接影响到的 metrics 以&quot;自证&quot;混沌实验的效果;</li> <li>另一部分认为&quot;自证&quot;只会存在于刚接触 Chaos Mesh 时的探索阶段, 在上手后, 用户更关注的是应用的 metrics;</li> </ul> <p>虽然实际上这两个事情毫不冲突, 实现起来也是毫不相干的两部分代码, 但在排期时有一个优先级的问题. 目前我们正在做后者, 而前者我并不知道如何再以何种方式引进来了. (这个时候我甚至有点希望自己是一个 contributor, 写些并不在 roadmap 里但是自己感兴趣/认为重要的代码.)</p></blockquote> <p>&ldquo;可理解&quot;看上去是在唬人, 因为我想做一件有些违背&quot;常理&quot;的事情: 对于一个即使没有前置知识的人, 依旧使他 make sense.</p> <blockquote> <p>如何做到? 不知道.</p></blockquote> <h2 id="额外瞎想-chaos-mesh-是一个好的开源项目吗">额外瞎想: Chaos Mesh 是一个好的开源项目吗?</h2> <p>我主观认为 Chaos Mesh 目前算是一个好的开源项目, 因为:</p> <ul> <li>它有硬核的部分</li> <li>它有有趣的部分</li> </ul> <p>但是它仍然有一些没有做好的地方:</p> <ul> <li>受众小, 门槛高</li> <li>决策不够透明</li> </ul> <h2 id="总结">总结</h2> <p>冲突吗? 没有根本利益上的冲突, 但是商业产品要求开源项目&quot;额外&quot;地点一个技能点: 这个项目要卖产品的, 要考虑产品的种种设计, 比如说易用性. 但是这个技能点恐怕不太能吸引到社区 contributor, 因为它看上去不够 cool, 不够 hardcode, 也不够 funny. 当然这个假设是因为我不是研究 UX 的同学, 所以觉得它没啥意思. 🤣</p> <p>话剧话说, 都可以整, 但是需要人来指路. 最后贴个广告, Chaos Mesh 团队正在招 PM, 如果你对它感兴趣, 可以联系俺内推.</p> 2022-01 Resetup Blog https://strrl.dev/post/weekly-report/2022/01-resetup-blog/ Thu, 20 Jan 2022 22:26:05 +0800 https://strrl.dev/post/weekly-report/2022/01-resetup-blog/ <p>又闲得没事把 blog 重新搭建起来了, 希望这次再苟久一点.</p> 试用 tiup 有感 https://strrl.dev/post/before-2022/%E8%AF%95%E7%94%A8tiup%E6%9C%89%E6%84%9F/ Thu, 09 Apr 2020 15:22:49 +0000 https://strrl.dev/post/before-2022/%E8%AF%95%E7%94%A8tiup%E6%9C%89%E6%84%9F/ <p>最近关注 TiDB 生态圈里又出现了一个新成员: tiup.</p> <p>看到这个组件并试用了以后, 顿时老泪纵横: 这就是我当年刚来到邦盛这家公司时, 开发&quot;运维平台&quot;, 想做的事情啊.</p> <p>当时的设想: <p class="md__image"> <img src='https://i.imgur.com/GHBfUxF.png' alt="" /> </p> </p> <p>也是 既可以用来本地开发人员用(tiup playground),也可以线上生产用(tiup cluster).</p> <p>结果被 leader 微笑着说 &ldquo;我们有实施人员, 不需要这个.&rdquo; 拒绝了.</p> <p>结果现在还在人工管理包, 人工控制版本. 演示环境/连调环境都用一个, 做了更改总是会影响到他人.</p> <p>我枯了.</p> <p>看到自己脑中的想法, 被更加专业的人实现了, 心里即开心(自己的想法正确), 又难受(为什么没有人支持我呢).</p> [翻译] Zookeeper Internals https://strrl.dev/post/before-2022/zookeeper-internals/ Tue, 31 Mar 2020 20:22:25 +0000 https://strrl.dev/post/before-2022/zookeeper-internals/ <p>[toc]</p> <blockquote> <p>原文链接: <a href="https://zookeeper.apache.org/doc/r3.2.2/zookeeperInternals.html">https://zookeeper.apache.org/doc/r3.2.2/zookeeperInternals.html</a></p></blockquote> <h2 id="introduction">Introduction</h2> <p>这篇文档包含 Zookeeper 的内部工作机制的相关信息. 目前为止, 讨论了以下几个 topic:</p> <ul> <li><a href="#Atomic-Broadcast">Atomic Broadcast</a></li> <li><a href="#Logging">Logging</a></li> </ul> <h2 id="atomic-broadcast">Atomic Broadcast</h2> <p>Zookeeper 的核心是一个原子消息系统, 它可以使所有的 server 保持同步.</p> <h3 id="guarantees-properties-and-definitions">Guarantees, Properties, and Definitions</h3> <p>Zookeeper 使用的消息系统可以提供如下保证:</p> <p><em>可靠的投递(Reliable delivery)</em>:</p> <p>如果一条消息 m 投递到了某个 server, 它最终会被投递到所有的 server.</p> <p><em>全局有序(Total order)</em>: 如果在一台 server 上消息 a 在是早于 b 投递的, 拿在所有的服务器上 a 都会早于 b 投递. 如果 a 和 b 都是已被投递的 message, 那有可能 a 早于 b 投递也有可能 b 早于 a 投递.</p> <p><em>因果有序(Causal order)</em>: 如果消息 b 的 sender 在收到了 a 之后发送了消息 b, 那么 a 一定早于 b.如果同一个 sender 先发送 b 再发送 c, 那么 c 一定晚于 b.</p> <p>Zookeeper 的消息系统同样需要高效, 可靠, 易于实现和维护. 我们会大量地使用消息, 所以我们需要系统能够处理每秒上千次的请求. 尽管我们需要至少 <code>k+1</code> 个正确的 server 才能发送新消息, 但我们必须能够从失败中恢复, 比如说断电. 当我们在实现系统时, 我们的时间和人力都很少, 所以我们需要一个工程师可以理解并且好实现的协议. 我们最终发现我们的协议满足所有的目标.</p> <p>我们的协议假设我们能在 server 之间构建点对点的 FIFO channel. 尽管类似的服务通常会假设消息传递会丢失或者重新排序, 考虑到我们使用 TCP 进行通信, 我们对于 FIFO channel 的假设还是很实用的. 我们明确依赖了 TCP 的这些特性:</p> <p><em>顺序投递(Ordered delivery)</em>: 数据是和它被发送的一样的顺序被投递的, 消息 m 直到 m 之前的消息都投递成功了 (delivered) 才会发送. (它造成的结果是, 如果消息 m 丢失则 m 后面的消息都会丢失.)</p> <p><em>关闭后不会再有消息(No message after close)</em>: 一旦 FIFO chanel 关闭, 不会再从它这里收到新消息.</p> <p>FLP 证明了如果在一个全异步的分布式系统中发生了故障, 是无法达成共识的. 为了确保再出现故障时我们能够达成共识, 我们会使用超时机制.(译者注: 可以达到部分同步) 然而, 我们依赖时间是为了保持存活(liveness), 而不是正确性(correctness). 所以如果如果超时机制出现了问题(比如说时钟出现了故障), 消息系统可能会挂起(hang), 但是不会违反它的保证.</p> <blockquote> <p>FLP 是一篇论文, 也是准备翻译的, 挺久前挖的坑, 还没填. (我 在 丢 人</p></blockquote> <p>在描述 ZooKeeper 消息传递协议时,我们将讨论数据包(packets), 提案(proposals)和消息(messages):</p> <p><em>数据包(Packet)</em> 是通过 FIFO channel 传递的一段 bytes 序列</p> <p><em>提案(Proposal)</em> 是 agreement 的最小单位. <strong>提案</strong>通过在 Zookeeper server 的一个 Quorum 之间传递<strong>数据包</strong>来达成 agreed 的. 大部分的的提案都会包含一个消息(Message), 但是 NEW_LEADER 提案是一个不含消息(Message)的例子.</p> <p><em>消息(Message)</em> 是一串 bytes, 会被自动地广播到所有的 Zookeeper server.</p> <h3 id="leader-activation">Leader Activation</h3> <h3 id="active-messaging">Active Messaging</h3> <h3 id="summary">Summary</h3> <h3 id="comparisons">Comparisons</h3> <h2 id="quorums">Quorums</h2> <h2 id="logging">Logging</h2> <h3 id="developer-guidelines">Developer Guidelines</h3> Basic Paxos https://strrl.dev/post/before-2022/basic-paxos/ Mon, 30 Mar 2020 21:40:29 +0000 https://strrl.dev/post/before-2022/basic-paxos/ <p>最近可能需要自己实现分布式的系统了, 所以提前预习了下相关知识.</p> <p>参考资料:</p> <ul> <li><a href="https://en.wikipedia.org/wiki/Paxos_(computer_science)#Basic_Paxos">Wikipedia: Paxos#Basic Paxos</a></li> <li><a href="http://pages.cs.wisc.edu/~remzi/Classes/739/Fall2017/paxos.lecture.pdf">Basic Paxos</a></li> <li><a href="https://www.youtube.com/watch?v=JEpsBg0AO6o">Video:Paxos lecture (Raft user study)</a></li> <li><a href="https://karanchahal.github.io/2018/03/08/Basic-Paxos/">Karan&rsquo;s Blog: Basic Paxos</a></li> </ul> <h2 id="basic-paxos-可以解决什么问题">Basic Paxos 可以解决什么问题</h2> <p>假设一个分布式系统里的每个节点都是一个状态机, Basic Paxos 可以保证集群中的过半机器的状态机所在的状态是一样的 (replicated state machine).</p> <blockquote> <p>就很有趣, 它只保证在某个时间点, 有半数以上的机器的状态是相同的, 却不一定是你想要的. (狗头 但是并不能保证状态变化的顺序一样, 那是 Multi Paxos 想做的, 做一个 replicated log.</p></blockquote> <h2 id="怎么解决的">怎么解决的</h2> <p>前提: 消息内容不会被篡改.</p> <p>Paxos 中有三个角色, Proposer, Acceptor 和 Learner. 由于 Learner 的行为是被动学习, 所以我们先不考虑 Learner.</p> <p>再假设一个情况, 每个节点上的程序既是 Proposer 又是 Acceptor.</p> <blockquote> <p>疑问: 什么情况下 <strong>需要</strong> Proposer 和 Acceptor 分开呢?</p></blockquote> <p>逻辑图:</p> <p> <p class="md__image"> <img src='https://i.imgur.com/WaeqbLe.jpg' alt="Basic Paxos" /> </p> </p> <p>像这样的一个协议, 我们可以不从时间点的开始阐述问题, 而是从某个中间时间开始. 然后开始状态只是一个特殊情况处理.</p> <blockquote> <p>不同的实现在细节上确实不一样. 而且 Basic Paxos 并不考虑集群之间是怎么发现的, 这是另外一个问题了. Basic Paxos 的前提是已经知道集群的 Nodes 已经在这里了, 而且 Node 之间&quot;知道&quot;怎么发送消息过去, 只是消息有可能会失败.</p></blockquote> <p>下面描述的过程都有可能在任意时刻有任意数量并发的发生.</p> <p>如果用户想改变集群里的个状态, 需要使用 client 向任意一个 Proposer 发出请求, 想要设置状态为<code>newValue</code>. 然后 Proposer 会开始执行 Basic Paxos 过程.</p> <p>Acceptor 需要维护 3 个状态:</p> <ul> <li>minProposal</li> <li>acceptedProposal</li> <li>acceptedValue</li> </ul> <p>Proposal 需要维护 1 个状态</p> <ul> <li>Proposal number, 用于生成下一个新的 Proposal number</li> </ul> <blockquote> <p>这里会用 Wikipedia 中的几个词: Prepare, Promise, Accept, Accepted 来代指 2 个 Phase 中的 4 次 RPC.</p></blockquote> <h3 id="phase-1-prepare">Phase 1: Prepare</h3> <p>Proposer 选择一个 proposal number <code>n</code>.</p> <blockquote> <ul> <li>每个 Proposal 需要有唯一的 proposal number. 其中一个实现方案是这样: Proposal number 分为两部分, Round ID 和 Server ID. 比如说这是第 3 台 server 发起的第 5 次 proposal, 那这次 proposal number 为 <code>5.3</code>.</li> <li>如果 Proposer 和 Acceptor 一起, 那么 Proposer 就可以从 Acceptor 那里拿到最新的<code>minProposal</code>,然后用<code>minProposal + 1</code>作为新的 Round ID.</li> </ul></blockquote> <p>向所有的 Acceptor 发送请求 <code>Prepare(n)</code>. 等待 Acceptor 的回应.</p> <blockquote> <p>实现细节区别: Wikipedia 上说只向一个 Acceptor 的 <a href="https://en.wikipedia.org/wiki/Paxos_(computer_science)#Quorums">Quorum</a> 发送就可以了. 细节问题, 不同实现不一样.</p></blockquote> <hr> <p>对于某个收到<code>Prepare(n)</code>的 Acceptor:</p> <ul> <li>如果 <code>n &gt; minProposal</code>, 则 <code>minProposal = n</code>.</li> <li>响应<code>Promise(acceptedProposal, acceptedValue)</code></li> </ul> <blockquote> <p>实现细节区别, 三种实现:</p> <ul> <li>若不满足<code>n &gt; minProposal</code>, 不响应.</li> <li>若不满足<code>n &gt; minProposal</code>, 响应 <code>Nack</code>.</li> <li>无论满足不满足, 都响应<code>Promise(acceptedProposal, acceptedValue)</code>. 会在 Accept 阶段替换为最新的值.</li> </ul> <p>第二个实现相较于第一个可以更快速收敛, 让这次的 Basic Paxos 过程直接在 Prepare 阶段结束. 但这样看起来, 第三种实现是最稳妥的: 假设发生了网络故障, 而这个 Proposer 正好可以访问到某些部分网络分区中的 Acceptor, 那也会让他们执行 Accept 阶段. (这个例子也太极限了, 像是在强行解释, 应该还有别的好处.)</p></blockquote> <p>⬆️ 收到<code>Prepare(n)</code>的 Acceptor 都会这么做.、</p> <hr> <p>然后对于刚才的 Proposer:</p> <ul> <li>如果收到了半数以上的<code>Promise</code>, 在所有的 Acceptor 响应的 Promise <code>[Promise(acceptedProposal, acceptedValue), ...]</code>中, 取出 acceptedProposal 最大的 pair. 如果<code>Proposal number &gt; 最大的 acceptedProposal</code>(注意是 <strong>大于</strong> 不是 <strong>大于等于</strong> ), 则使用<code>(proposal number, newValue)</code>, 否则为<code>(proposal number, acceptedValue)</code></li> </ul> <blockquote> <p>实现细节区别: 如果 Acceptor 是第二种实现, 收到了半数以上的<code>Nack</code>, 可以重头再来了. 如果是第一种实现, Acceptor 有可能永远收不到半数以上的 Promise. 整个过程其实客观上来看就停止了. 但是缺少一个显式的声明, 明确的告诉 Proposer 停止. 仍在疑惑, 这种实现下什么时候真正停止而且释放资源.</p></blockquote> <h3 id="phase-2-accept">Phase 2: Accept</h3> <p>Proposer 在 prepare 的最后一个阶段会确定一个 KV pair, Key 为 proposal number, V 为收到的<code>Promise</code>中<code>acceptedProposal</code>最大的值或者是<code>newValue</code>.</p> <blockquote> <p>不记得<code>newValue</code>是啥的小伙伴, 快点<code>CTRL+F</code>在本文里搜一下<code>newValue</code>.</p></blockquote> <p>WIP&hellip;</p> <h2 id="其他细节问题">其他细节问题</h2> <p>Q: 如果连续向 Proposer 发出新的请求, 第二个 Proposal 在第一个 Proposal 的 Prepare 阶段还未完成就发送了, 怎样处理. A:</p> [翻译]深度挖掘 kubernetes: CustomResources 代码生成 https://strrl.dev/post/before-2022/%E6%B7%B1%E5%BA%A6%E6%8C%96%E6%8E%98-kubernetes-customresources-%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90/ Thu, 27 Feb 2020 20:42:17 +0000 https://strrl.dev/post/before-2022/%E6%B7%B1%E5%BA%A6%E6%8C%96%E6%8E%98-kubernetes-customresources-%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90/ <p>最近在看 sample-controller 的时候注意到了其特殊的特性. code generation. 感觉还是蛮重要的, 因此翻译了这个出自于官方的 blog.</p> <blockquote> <p>原文: <a href="https://blog.openshift.com/kubernetes-deep-dive-code-generation-customresources/">https://blog.openshift.com/kubernetes-deep-dive-code-generation-customresources/</a></p></blockquote> <p>随着 kubernetes 越来越多的作为分布式应用的平台, 越来越多的项目将使用扩展点在更高的层级上构建软件. CustomResourceDefinitions(CRD) 在 kubernetes 1.7 中作为 alpha 的特性引入, 随后在 1.8 中升级为 beta. 它是许多用例的中很自然的构建模块, 尤其在实现了某种 controller(有时候成为 operator)的模式中. 此外, CRD 非常容易建立和使用.</p> <p>在 Kubernetes 1.8 中, 在基于 golang 的项目中的使用也变得更加自然: 通过用户提供的 CustomResources,我们可以利用在 Kubernetes 或 OpenShift 中使用的相同代码生成工具. 这篇文章展示了代码生成器是如何工作的, 以及如何用最少的代码行将它们应用到自己的项目中, 为您提供生<code>deepcopy</code>函数, 带有类型的客户端, <code>lister</code> 和 <code>informer</code>, 所有的这些只需要调用一个 shell 脚本和一些代码中的注解. <a href="https://github.com/openshift-evangelists/crd-code-generation">openshift-evangelists/crd-code-generation</a>可以作为完整的蓝图项目.</p> <h2 id="代码生成---为什么">代码生成 - 为什么</h2> <p>那些在 golang 中原生使用 ThirdPartyResources 或 CustomResourceDefinition 的人可能会惊讶于突然在 Kubernetes 1.8 中需要使用 client-go code-generation. 准确的说, client-go 需要 <code>runtime.Object</code>类型(golang 中, CustomResources 必须实现 <code>runtime.Object</code> 接口)必须有 <code>DeepCopy</code>方法. 这里的代码生成通过 deepcopy-gen 生成器起作用, 可以在 k8s.io/code-generator 这个 repo 中找到.</p> <p>此外, 还有一些大多数使用 CustomResources 的用户所希望的 code-generator:</p> <ul> <li>deepcopy-gen, 为所有的类型 T 创建 <code>func (t* T) DeepCopy() *T</code> 方法.</li> <li>client-gen, 为 CustomResources APIGroups 创建带有类型的 <code>clientsets</code>.</li> <li>informer-gen, 为 CustomResources 创建提供基于事件的接口 <code>infomer</code>, 用来对服务器上 CustomResources 的变化作出反应.</li> <li>lister-gen, 为 CustomResources 创建 <code>lister</code>, 为 GET 和 LIST 请求提供一个只读的缓存层.</li> </ul> <p>后两者是构建 controller(有些人称之为 operator)的基础. 在接下来的文章中, 我们将会关注 controller 的细节. 这四个代码生成器为构建功能完备的, 生产级的 controller 提供了强大的基础, 和上游中 kubernetes controllers 使用的都是相同的机制和软件包.</p> <p><code>k8s.io/code-generator</code> 中还有<a href="https://github.com/kubernetes/code-generator/tree/master/cmd">更多的 generator</a>来满足其他的场景, 比如, 如果你需要构建自己的 aggregated API server,除了使用带有版本的类型之外, 你还会用到一些内部的类型. <code>Conversion-gen</code> 会创建<code>conversions</code>函数在内部和外部类型之间做转换. <code>Defaulter-gen</code>将为某些字段赋默认值.</p> <h2 id="在你的项目中调用-code-generators">在你的项目中调用 Code-Generators</h2> <p>Kubernetes 中所有的代码生成器都是在 <a href="https://github.com/kubernetes/gengo">k8s.io/gengo</a> 上实现的. 它们都会使用一些通用的命令行参数. 基本上, 所有的 generator 获取输入的 package(<code>--input-dirs</code>), 逐个类型的操作,并输出生成的代码. 这些被生成的代码:</p> <ul> <li>要么生成到与输入文件所在的一样的目录(使用<code>--output-file-bas &quot;zz_generation.deepcopy&quot;</code>来定义文件名), 为了实现 deepcopy-gen.</li> <li>或者生成到一个或多个输出的包中(使用 <code>--output-package</code>), 像 client-gen,informer-gen 和 lister-gen 做的那样(一般生成到 <code>pkg/client</code>目录).</li> </ul> <p>刚才的描述听上去像是需要长时间的摆弄命令行参数才能开始, 但是所幸这不是真的: <a href="https://github.com/kubernetes/code-generator">k8s.io/code-generator</a>带来了一个 shel 脚本<a href="https://github.com/kubernetes/code-generator/blob/master/generate-groups.sh">generate-groups.sh</a>, 可以执行 CustomResources 的 use-case 所需的繁重的脚本. 你需要做的是就是在你的项目中执行一行命令, 一般在 <code>hack/update-codegen.sh</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ vendor/k8s.io/code-generator/generate-groups.sh all <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span>github.com/openshift-evangelist/crd-code-generation/pkg/client <span class="se">\ </span>github.com/openshift-evangelist/crd-code-generation/pkg/apis <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span>example.com:v1 </span></span></code></pre></td></tr></table> </div> </div><p>它可以在像这样的目录结构下执行: <p class="md__image"> <img src='https://tva1.sinaimg.cn/large/00831rSTly1gcdpdwi1h6j30g40dymxt.jpg' alt="package tree" /> </p> </p> <p>所有的 APIs 在<code>pkg/apis</code>下, clientsets, informers, listers 在<code>pkg/client</code>下被生成. 换句话说, <code>pkg/client</code>是完全生成的. <code>types.go</code>文件旁边的<code>zz_generated.deepcopy.go</code>文件中也包含了我们需要的 CustomResourceDefinition 类型. 两者都不应该手动修改, 而是通过运行以下命令创建:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ hack/update-codegen.sh </span></span></code></pre></td></tr></table> </div> </div><p>通常来说, 这个文件旁边应该也有一个 <code>hack/verify-codegen.sh</code>, 当生成文件没有更新时会以一个非 0 的状态码退出.</p> <p>这对于放入 CI 脚本中非常有帮助: 如果开发人员无意中修改了文件或文件刚刚过时, CI 会注意到并&quot;抱怨&quot;(complain).</p> <h2 id="控制生成的代码---通过-tags">控制生成的代码 - 通过 Tags</h2> <p>正如上面所说的, code-generator 的一些行为是通过命令行参数来控制的(尤其是需要被处理的 package), 更多的属性是通过你 golang 文件中的 tags 来控制的.</p> <p>有两种类型的 tag:</p> <ul> <li>对 <code>package</code> 的 Global tags, 在<code>doc.go</code>中</li> <li>对需要被处理的类型的 Local tags</li> </ul> <p>一般来说 tags 长 <code>// +tag-name</code> 或者 <code>// +tag-name=value</code> 这个样子, 也就是说, 它们会被写到注释中. 由于标签的原因, 注释在文件中的位置可能是非常重要的. 有些 tag 必须直接注释在某些类型(对于 global tag 是 <code>package</code> 那一行)的上面, 有些必须和类型(或者 <code>package</code>那一行)至少用一行空行分开. 我们正在努力使它在 1.9 发布周期中更加一致且不会出错(PR <a href="https://github.com/kubernetes/kubernetes/pull/53579">#53579</a> 和 ISSUE <a href="https://github.com/kubernetes/kubernetes/issues/53893">#53893</a>). 做好一个空行就可能造成问题的准备. 最好是照着 example 做, 并且复制它的基本样子.</p> <h3 id="global-tags">Global Tags</h3> <p>Global tags 写在 package 的<code>doc.go</code>文件中. 一个典型的 <code>pkg/apis/&lt;apigroup&gt;/&lt;version&gt;/doc.go</code> 文件看起来像这样:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// +k8s:deepcopy-gen=package,register</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Package v1 is the v1 version of the API.</span> </span></span><span class="line"><span class="cl"><span class="c1">// +groupName=example.com</span> </span></span><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">v1</span> </span></span></code></pre></td></tr></table> </div> </div><p>他告诉 deepcopy-gen 默认为这个 package 下面的所有类型都创建 deepcopy 方法. 如果你有不需要或者不想要生成 deepcopy 的 type, 你可以对这个 type 使用 local tag <code>// +k8s:deepcopy-gen=false</code> 来选择性的关闭(opt-out). 如果你没有开启 package 级别的 deepcopy, 你必须对每个希望有 deepcopy 使用选择行开启(opt-in), 通过 local tag <code>// +k8s:deepcopy-gen=true</code>.</p> <p>注意: 在上面例子中的 <code>register</code> 关键词会开启将 deepcopy 方法注册到 scheme. 这在 Kubernetes 1.9 中会被完全的去掉, 因为 scheme 不再负责执行 <code>runtime.Object</code>的 deepcopy. 取而代之的是只需要调用<code>yourobject.DeepCopy()</code> 或者 <code>yourobject.DeepCopyObject()</code>. 你现在已经可以, 而且也应该在 1.8 为基础的版本中这么做, 因为这种方式更快, 更不容易出错. 此外你也应该为使用这种模式的 1.9 作准备.</p> <p>最后, <code>// +groupName=example.com</code> 定义了标准 API 组名称(原文: fully qualified API group name). 如果你这里写错了, client-gen 会生成错误的代码. 注意这个 tag 必须写在<code>package</code>的上一行(看 <a href="https://github.com/kubernetes/kubernetes/issues/53893">Issue #53893</a>).</p> <h3 id="local-tags">Local Tags</h3> <p>Local Tags 可以直接写在 API type 的上方, 也可以写在其上方的第二个注释块中. 这有关于 CustomResources 的 <a href="https://blog.openshift.com/kubernetes-deep-dive-api-server-part-3a/">deep dive 系列</a> API server 中可以作为示例的 <a href="https://github.com/openshift-evangelists/crd-code-generation/blob/master/pkg/apis/example.com/v1/types.go">types.go</a>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// +genclient</span> </span></span><span class="line"><span class="cl"><span class="c1">// +genclient:noStatus</span> </span></span><span class="line"><span class="cl"><span class="c1">// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Database describes a database.</span> </span></span><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">Database</span> <span class="kd">struct</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">metav1</span><span class="p">.</span><span class="nx">TypeMeta</span> <span class="s">`json:&#34;,inline&#34;`</span> </span></span><span class="line"><span class="cl"> <span class="nx">metav1</span><span class="p">.</span><span class="nx">ObjectMeta</span> <span class="s">`json:&#34;metadata,omitempty&#34;`</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">Spec</span> <span class="nx">DatabaseSpec</span> <span class="s">`json:&#34;spec&#34;`</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// DatabaseSpec is the spec for a Foo resource</span> </span></span><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">DatabaseSpec</span> <span class="kd">struct</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">User</span> <span class="kt">string</span> <span class="s">`json:&#34;user&#34;`</span> </span></span><span class="line"><span class="cl"> <span class="nx">Password</span> <span class="kt">string</span> <span class="s">`json:&#34;password&#34;`</span> </span></span><span class="line"><span class="cl"> <span class="nx">Encoding</span> <span class="kt">string</span> <span class="s">`json:&#34;encoding,omitempty&#34;`</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// DatabaseList is a list of Database resources</span> </span></span><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">DatabaseList</span> <span class="kd">struct</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">metav1</span><span class="p">.</span><span class="nx">TypeMeta</span> <span class="s">`json:&#34;,inline&#34;`</span> </span></span><span class="line"><span class="cl"> <span class="nx">metav1</span><span class="p">.</span><span class="nx">ListMeta</span> <span class="s">`json:&#34;metadata&#34;`</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">Items</span> <span class="p">[]</span><span class="nx">Database</span> <span class="s">`json:&#34;items&#34;`</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>注意我们已经为所有的类型默认开启了 deepcopy, 所以我们可以使用选择性关闭(opt-out). 但是这些类型, 都是 API 类型, 它们需要 deepcopy. 也就是说, 我们不需要在示例的 <a href="https://github.com/openshift-evangelists/crd-code-generation/blob/master/pkg/apis/example.com/v1/types.go">types.go</a>中开关 deepcopy, 只需要在<a href="https://github.com/openshift-evangelists/crd-code-generation/blob/master/pkg/apis/example.com/v1/doc.go">doc.go</a>中以 package 级别开启.</p> <h3 id="runtimeobject-and-deepcopyobject">RUNTIME.OBJECT AND DEEPCOPYOBJECT</h3> <p>有一个特殊的 deepcopy tag 需要特殊说明:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object</span> </span></span></code></pre></td></tr></table> </div> </div><p>如果你已经尝试 用 Kubernetes 1.8 中的 client-go 使用 CustomResources(有些人可能已经遇到了, 因为它们意外地使用了 master 分支上的 k8s.io/apimachinery), 你会遇到编译错误, CustomResources 的类型没有实现<code>runtimeObject</code>因为<code>DeepCopyObject() runtime.Object</code>没有在你的类型中定义. 原因是由于在 1.8 中, <code>runtime.Object</code>接口<a href="https://github.com/kubernetes/apimachinery/blob/7089aafd1ef57551192f6ec14c5ed1f49494ccd2/pkg/runtime/interfaces.go#L237">用了这个方法签名进行扩展</a>, 因此每个<code>runtime.Object</code>都必须实现<code>DeepCopyObject</code>. 实现<code>DeepCopyObject() runtime.Object</code>比较琐碎:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="nx">in</span> <span class="o">*</span><span class="nx">T</span><span class="p">)</span> <span class="nf">DeepCopyObject</span><span class="p">()</span> <span class="nx">runtime</span><span class="p">.</span><span class="nx">Object</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">c</span> <span class="o">:=</span> <span class="nx">in</span><span class="p">.</span><span class="nf">DeepCopy</span><span class="p">();</span> <span class="nx">c</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">c</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">nil</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>幸运的是, 你不需要为每个类型都实现一遍, 只需要在你的顶级 API 类型上加这个 local tag:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object</span> </span></span></code></pre></td></tr></table> </div> </div><p>在我们的例子中 <code>Database</code>和<code>DatabaseList</code>都是顶级类型,因为它们会作为<code>runtime.Object</code>使用. 根据经验, 那些嵌入了<code>metav1.TypeMeta</code>的是顶级类型. 另外, 这些也是 clients 为了使用 client-gen 创建的类型.</p> <p>注意, <code>// +k8s:deepcopy-gen:interfaces</code>标签可以, 也应该在你的类型中有类型为 interface 的域的时候使用, 例如 <code>field SomeInterface</code>. 这样 <code>// +k8s:deepcopy-gen:interfaces=example.com/pkg/apis/example.SomeInterface</code>会生成一个<code>DeepCopySomeInterface() SomeInterface</code>方法. 这允许它以类型正确的方式对这些字段进行深度复制.</p> <h3 id="client-gen-tags">CLIENT-GEN TAGS</h3> <p>最后, 有一些控制 client-gen 的 tag, 我们的例子中用了两个:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// +genclient</span> </span></span><span class="line"><span class="cl"><span class="c1">// +genclient:noStatus</span> </span></span></code></pre></td></tr></table> </div> </div><p>第一个 tag 告诉 client-gen 为这个类型创建一个 client. 注意你不需要也不能把它放在<code>List</code>类型的上方.</p> <p>第二个 tag 告诉 client-gen 这个类型没有通过<code>/status</code>子资源做 spec-status 的分离. 结果就是你不能在 client 中使用<code>UpdateStatus</code>方法(client-gen 只要在你的 struct 中看到<code>Status</code>, 就会直接生成这个). <code>/status</code> 子资源仅在 1.8 中对于原生(使用 golang)实现的资源才可用. 但是随着<a href="https://github.com/kubernetes/community/pull/913">PR 913</a>中为 CustomResources 讨论子资源, 这种情况可能很快就会改变.</p> <p>对于集群级别的资源, 你需要使用这个 tag:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// +genclient:nonNamespaced</span> </span></span></code></pre></td></tr></table> </div> </div><p>对于某些特殊目的的 client, 你可能还希望详细控制 client 可以使用哪些 HTTP 方法. 这可以用一些 tag 来完成, 比如:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// +genclient:noVerbs</span> </span></span><span class="line"><span class="cl"><span class="c1">// +genclient:onlyVerbs=create,delete</span> </span></span><span class="line"><span class="cl"><span class="c1">// +genclient:skipVerbs=get,list,create,update,patch,delete,deleteCollection,watch</span> </span></span><span class="line"><span class="cl"><span class="c1">// +genclient:method=Create,verb=create,result=k8s.io/apimachinery/pkg/apis/meta/v1.Status</span> </span></span></code></pre></td></tr></table> </div> </div><p>前三个 tag 很明显能看出是什么意思, 但是最后一个需要额外说明下. 使用这个 tag 的类型是 create-only 的, 而且返回的并不是 API type 本身, 而是<code>metav1.Status</code>. 对于 CustomResources 这没有很大的意义, 但是对于用户提供的使用 golang 写的 API server, 这写资源可以存在,而且也这么做了, 例如 OpenShift API.</p> <h2 id="a-main-function-using-the-types-clients">A Main Function Using the Types Clients</h2> <p>在 Kubernetes 1.7 或者更早以前, 大部分的例子都是使用的<a href="https://github.com/kubernetes/client-go/tree/master/dynamic">client-go dynamic client</a>操作 CustomResources. 原生的 Kubernetes API 类型有更方便的 typed client 已经很久了. 这在 1.8 中会改变: 上面提到的 client-gen 可以为你的自定义 type 生成原生的, 功能完整的, 而且易用的 typed client. 事实上, client-gen 不知道他操作的是 CustomResources 还是 kubernetes 原生类型.</p> <p>因此, 使用这种客户端和使用 kubernetes client-go 客户端是完全等价的. 这里有一个非常简单的例子:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span><span class="lnt">33 </span><span class="lnt">34 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="o">...</span> </span></span><span class="line"><span class="cl"> <span class="nx">metav1</span> <span class="s">&#34;k8s.io/apimachinery/pkg/apis/meta/v1&#34;</span> </span></span><span class="line"><span class="cl"> <span class="s">&#34;k8s.io/client-go/tools/clientcmd&#34;</span> </span></span><span class="line"><span class="cl"> <span class="nx">examplecomclientset</span> <span class="s">&#34;github.com/openshift-evangelist/crd-code-generation/pkg/client/clientset/versioned&#34;</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">kuberconfig</span> <span class="p">=</span> <span class="nx">flag</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;kubeconfig&#34;</span><span class="p">,</span> <span class="s">&#34;&#34;</span><span class="p">,</span> <span class="s">&#34;Path to a kubeconfig. Only required if out-of-cluster.&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="nx">master</span> <span class="p">=</span> <span class="nx">flag</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;master&#34;</span><span class="p">,</span> <span class="s">&#34;&#34;</span><span class="p">,</span> <span class="s">&#34;The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">flag</span><span class="p">.</span><span class="nf">Parse</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">cfg</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">clientcmd</span><span class="p">.</span><span class="nf">BuildConfigFromFlags</span><span class="p">(</span><span class="o">*</span><span class="nx">master</span><span class="p">,</span> <span class="o">*</span><span class="nx">kuberconfig</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">glog</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;Error building kubeconfig: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">exampleClient</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">examplecomclientset</span><span class="p">.</span><span class="nf">NewForConfig</span><span class="p">(</span><span class="nx">cfg</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">glog</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;Error building example clientset: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">list</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">exampleClient</span><span class="p">.</span><span class="nf">ExampleV1</span><span class="p">().</span><span class="nf">Databases</span><span class="p">(</span><span class="s">&#34;default&#34;</span><span class="p">).</span><span class="nf">List</span><span class="p">(</span><span class="nx">metav1</span><span class="p">.</span><span class="nx">ListOptions</span><span class="p">{})</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">glog</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;Error listing all databases: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">db</span> <span class="o">:=</span> <span class="k">range</span> <span class="nx">list</span><span class="p">.</span><span class="nx">Items</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;database %s with user %q\n&#34;</span><span class="p">,</span> <span class="nx">db</span><span class="p">.</span><span class="nx">Name</span><span class="p">,</span> <span class="nx">db</span><span class="p">.</span><span class="nx">Spec</span><span class="p">.</span><span class="nx">User</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>它需要一个 kubeconfig 文件才能工作, 事实上这和 kubectl, kuberntes clients 的用法是一样的.</p> <p>与动态客户端使用的旧版 TPR(Third Party Resources) 或者 CustomResources 相比, 你不需要做类型转换. 取而代之的, client 调用看上去就像本地调用一样:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nx">list</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">exampleClient</span><span class="p">.</span><span class="nf">ExampleV1</span><span class="p">().</span><span class="nf">Databases</span><span class="p">(</span><span class="s">&#34;default&#34;</span><span class="p">).</span><span class="nf">List</span><span class="p">(</span><span class="nx">metav1</span><span class="p">.</span><span class="nx">ListOptions</span><span class="p">{})</span> </span></span></code></pre></td></tr></table> </div> </div><p>这个例子中的结果是 <code>DatabaseList</code>类型, 代表你集群里的所有的数据库. 如果你把类型切换到 cluster-wide(没有 namespace; 不要忘记使用<code>// +genclient:nonNamespaced</code>告诉 client-gen), 这个调用会变成:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nx">list</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">exampleClient</span><span class="p">.</span><span class="nf">ExampleV1</span><span class="p">().</span><span class="nf">Databases</span><span class="p">().</span><span class="nf">List</span><span class="p">(</span><span class="nx">metav1</span><span class="p">.</span><span class="nx">ListOptions</span><span class="p">{})</span> </span></span></code></pre></td></tr></table> </div> </div><h2 id="在-golang-中以编程方式创建一个-customresourcedefinition">在 Golang 中以编程方式创建一个 CustomResourceDefinition</h2> <p>这个问题经常出现, 简单说下在 golang 代码中怎么以编程的方式创建一个 CRD.</p> <p>client-gen 总是创建出所谓的 clientsets. Clientsets 将一个或多个 API 组捆绑到一个客户端中. 通常来说, 这些 API group 在一个 repo 里, 而且被放置在一个 package 下. 例如, 这篇文章示例中的<code>pkg/apis</code>, 或者 Kubernetes 中的 k8s.io/api.</p> <p>CustomResourceDefinitions 在这个 repo<a href="https://github.com/kubernetes/apiextensions-apiserver">kubernetes/apiextensions-apiserver repository</a>中提供. 这个 API server(也可以独立启动)是嵌入到 kube-apiserver 的, 所以 CRD 在每个 kubernetes 集群中都是可用的. 但是操作 CRD 的 client 代码被生成到了 apiextensions-apiserver 这个 repo, 当然也需要用到 client-gen. 在读了这篇文章后, 在<a href="https://github.com/kubernetes/apiextensions-apiserver/tree/master/pkg/client">kubernetes/apiextensions-apiserver/tree/master/pkg/client</a>中找到客户端也不应该惊讶, 也不因该觉得为了创建 CRD 而创建一个新的 client 示例是意外的.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span><span class="lnt">8 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="o">...</span> </span></span><span class="line"><span class="cl"> <span class="nx">apiextensionsclientset</span> <span class="err">&#34;</span><span class="nx">k8s</span><span class="p">.</span><span class="nx">io</span><span class="o">/</span><span class="nx">apiextensions</span><span class="o">-</span><span class="nx">apiserver</span><span class="o">/</span><span class="nx">pkg</span><span class="o">/</span><span class="nx">client</span><span class="o">/</span><span class="nx">clientset</span><span class="o">/</span><span class="nx">clientset</span><span class="err">”</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nx">apiextensionsClient</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">apiextensionsclientset</span><span class="p">.</span><span class="nf">NewForConfig</span><span class="p">(</span><span class="nx">cfg</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="o">...</span> </span></span><span class="line"><span class="cl"><span class="nx">createdCRD</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">apiextensionsClient</span><span class="p">.</span><span class="nf">ApiextensionsV1beta1</span><span class="p">().</span><span class="nf">CustomResourceDefinitions</span><span class="p">().</span><span class="nf">Create</span><span class="p">(</span><span class="nx">yourCRD</span><span class="p">)</span> </span></span></code></pre></td></tr></table> </div> </div><p>注意在你建立了新的 CRD 后, 你需要等待<code>Established</code>条件. 只有这样以后, kube-apiserver 才会处理这个资源. 如果你没有等这个条件, 所有的 CustomResources 相关的操作都会返回 404.</p> <h2 id="更多的资料">更多的资料</h2> <p>目前 kubernetes 生成器的文档还有很多改进的空间, 也非常欢迎任何帮助. 它们刚刚从 kubernetes 中把代码抽取到<a href="https://github.com/kubernetes/code-generator">k8s.io/code-generator</a>, 为了让 CustomResources 的用户使用. 他的文档当然会随着时间的推移而不断改进, 并且此博客文章也旨在为此做出贡献. 有关不同生成器的更多信息, 通常最好查看 Kubernetes 本身内的示例(例如,在 <a href="https://github.com/kubernetes/api">k8s.io/api</a> 中), 有许多高级用例的 <a href="https://github.com/openshift/origin">OpenShift</a>, 以及生成器本身:</p> <ul> <li><a href="https://github.com/kubernetes/gengo/tree/master/examples/deepcopy-gen">Deepcopy-gen</a>可以从它的 <a href="https://github.com/kubernetes/gengo/blob/master/examples/deepcopy-gen/main.go#L17">main.go</a>文件中获取一些文档.</li> <li><a href="https://github.com/kubernetes/code-generator/tree/master/cmd/client-gen">Client-gen</a>可以从<a href="https://github.com/kubernetes/community/blob/master/contributors/devel/generating-clientset.md">这里</a>获取一些文档.</li> <li><a href="https://github.com/kubernetes/code-generator/tree/master/cmd/informer-gen">Informer-gen</a>和<a href="https://github.com/kubernetes/code-generator/tree/master/cmd/lister-gen">lister-gen</a>目前没有更多的文档, 但是 <a href="https://github.com/kubernetes/code-generator/blob/master/generate-groups.sh">generate-groups.sh</a>展示了它们是如何被调用的.</li> </ul> <p>文章中的所有例子都是可以被作为功能完整的 repo 获取的, 可以轻松的用作你自己实验的蓝图:</p> <ul> <li><a href="https://github.com/openshift-evangelists/crd-code-generation">https://github.com/openshift-evangelists/crd-code-generation</a>.</li> </ul> 天杀的键盘连击 https://strrl.dev/post/before-2022/%E5%A4%A9%E6%9D%80%E7%9A%84%E9%94%AE%E7%9B%98%E8%BF%9E%E5%87%BB/ Thu, 13 Feb 2020 16:51:49 +0000 https://strrl.dev/post/before-2022/%E5%A4%A9%E6%9D%80%E7%9A%84%E9%94%AE%E7%9B%98%E8%BF%9E%E5%87%BB/ <h2 id="情况">情况</h2> <p>最近在家里大量使用蝶式键盘办公, c i o b tab 均出现了疯狂的连击. 导致:</p> <ul> <li>git commit 疯狂打错</li> <li>docker/kubectl 常用命令打错</li> <li>更加“自动”的自动补全</li> </ul> <p>另外发现编程的时候 o 这个字母好多, java 程序员,很多类名都以 -or 结尾.</p> <h2 id="方案">方案</h2> <p><a href="https://github.com/aahung/Unshaky">https://github.com/aahung/Unshaky</a></p> <h2 id="效果">效果</h2> <p>一个下午: <p class="md__image"> <img src='https://tva1.sinaimg.cn/large/0082zybply1gbv4de8qsij30go0t80up.jpg' alt="连击" /> </p> </p> kubernetes from scratch https://strrl.dev/post/before-2022/kubernetes-from-scratch/ Sun, 02 Feb 2020 15:28:34 +0000 https://strrl.dev/post/before-2022/kubernetes-from-scratch/ <p>从头开始装一个 kubernetes.</p> <p>现在是 2020-02-02 15:29</p> <p>参考资料: <a href="https://github.com/kelseyhightower/kubernetes-the-hard-way">https://github.com/kelseyhightower/kubernetes-the-hard-way</a></p> <h2 id="准备">准备</h2> <p>将在两台虚拟机上安装 kubernetes:<br> kmaster 2C4G ubuntu-18.04 192.168.50.57<br> worker-0 2C4G ubuntu-18.04 192.168.50.195</p> <h2 id="生成证书">生成证书</h2> <p>kubernetes 各个组件之间都是需要经过 HTTPS 双向认证的, 所以至少为每个组件都生成一对公私钥和证书:</p> <p>这里使用 cfssl 这个工具来生成证书, 其实也可以用 openssl 的. (一年前还是用的 openssl</p> <p>关于 cfssl 和 openssl 以后开一个新坑再来研究吧.</p> <p>按照 kubernetes-the-hard-way 中的步骤, 做到 api server 部分时, 需要把 IP/hostname 手动指定一下.</p> <h2 id="master-节点-安装-etcd">master 节点 安装 etcd</h2> <p>这里只用的单节点的 etcd, 需要修改启动参数, 同时 IP 与集群中的机器的地址也需要更改.</p> <h2 id="master-节点-启动-kubernetes-control-plane-相关服务">master 节点 启动 Kubernetes Control Plane 相关服务</h2> <p>完全按照教程来, 只不过更新了包的版本.</p> <p>增加了一个 ClusterRole <code>system:kube-apiserver-to-kubelet</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">rbac.authorization.k8s.io/v1beta1</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">ClusterRole</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">metadata</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">annotations</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">rbac.authorization.kubernetes.io/autoupdate</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;true&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">labels</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">kubernetes.io/bootstrapping</span><span class="p">:</span><span class="w"> </span><span class="l">rbac-defaults</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">system:kube-apiserver-to-kubelet</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">rules</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">apiGroups</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="s1">&#39;&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">resources</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">nodes/proxy</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">nodes/stats</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">nodes/log</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">nodes/spec</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">nodes/metrics</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">verbs</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="s1">&#39;*&#39;</span><span class="w"> </span></span></span></code></pre></td></tr></table> </div> </div><p>以及一个 cluster role binding <code>system:kube-apiserver</code></p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">rbac.authorization.k8s.io/v1beta1</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">ClusterRoleBinding</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">metadata</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">system:kube-apiserver</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">namespace</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">roleRef</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">apiGroup</span><span class="p">:</span><span class="w"> </span><span class="l">rbac.authorization.k8s.io</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">ClusterRole</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">system:kube-apiserver-to-kubelet</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">subjects</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">apiGroup</span><span class="p">:</span><span class="w"> </span><span class="l">rbac.authorization.k8s.io</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">User</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">kubernetes</span><span class="w"> </span></span></span></code></pre></td></tr></table> </div> </div><h2 id="worker-节点">worker 节点</h2> <p>同样完全按照教程来, 只不过更新了包的版本, 跟着修改一些配置文件.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span><span class="lnt">8 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">wget -q --show-progress --https-only --timestamping <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.17.0/crictl-v1.17.0-linux-amd64.tar.gz <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> https://github.com/opencontainers/runc/releases/download/v1.0.0-rc10/runc.amd64 <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> https://github.com/containernetworking/plugins/releases/download/v0.8.5/cni-plugins-linux-amd64-v0.8.5.tgz <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> https://github.com/containerd/containerd/releases/download/v1.3.2/containerd-1.3.2.linux-amd64.tar.gz <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> https://storage.googleapis.com/kubernetes-release/release/v1.17.2/bin/linux/amd64/kubectl <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> https://storage.googleapis.com/kubernetes-release/release/v1.17.2/bin/linux/amd64/kube-proxy <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> https://storage.googleapis.com/kubernetes-release/release/v1.17.2/bin/linux/amd64/kubelet </span></span></code></pre></td></tr></table> </div> </div><p>启动 kubelet 时还出现了一个小插曲: <a href="https://github.com/kubernetes/kubernetes/issues/73189">https://github.com/kubernetes/kubernetes/issues/73189</a></p> <p>插曲二 iptables FORWARD 默认 POLICY 是 DROP</p> <h2 id="安装-flannel">安装 flannel</h2> <p>需要修改两个地方</p> <ol> <li><a href="https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml">https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml</a> 修改这里的 podCidr, 和前面保持一致(10.200.0.0/16)</li> <li><a href="https://github.com/coreos/flannel/blob/master/Documentation/troubleshooting.md#kubernetes-specific">https://github.com/coreos/flannel/blob/master/Documentation/troubleshooting.md#kubernetes-specific</a>, 这里我手动 patch 了.</li> </ol> <h2 id="冒烟测试">冒烟测试</h2> <p>部署了一个 <em>kubernetes in action</em> 的一个例子:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nn">---</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">v1</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">ReplicationController</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">metadata</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">kubia-v1</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">spec</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">replicas</span><span class="p">:</span><span class="w"> </span><span class="m">3</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">template</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">metadata</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">kubia</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">labels</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">app</span><span class="p">:</span><span class="w"> </span><span class="l">kubia</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">spec</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">containers</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">nodejs</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">luksa/kubia:v1</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">ports</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">containerPort</span><span class="p">:</span><span class="w"> </span><span class="m">8080</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">kubia-http</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nn">---</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">v1</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Service</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">metadata</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">kubia</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">spec</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">NodePort</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">selector</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">app</span><span class="p">:</span><span class="w"> </span><span class="l">kubia</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">ports</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">80</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">targetPort</span><span class="p">:</span><span class="w"> </span><span class="m">8080</span><span class="w"> </span></span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># strrl @ worker-0 in ~ [13:08:47]</span> </span></span><span class="line"><span class="cl">$ curl localhost:30545 </span></span><span class="line"><span class="cl">This is v1 running in pod kubia-v1-th9ph </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># strrl @ worker-0 in ~ [13:08:48]</span> </span></span><span class="line"><span class="cl">$ curl localhost:30545 </span></span><span class="line"><span class="cl">This is v1 running in pod kubia-v1-h8z47 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># strrl @ worker-0 in ~ [13:08:49]</span> </span></span><span class="line"><span class="cl">$ curl localhost:30545 </span></span><span class="line"><span class="cl">This is v1 running in pod kubia-v1-685vm </span></span></code></pre></td></tr></table> </div> </div><h2 id="总结">总结</h2> <p>现在时间 2020-02-02 21:09 去掉中间吃饭的一个半小时,总共耗时 4.5 小时.</p> <p>整理感觉下来,kubernetes 的部署除了证书和配置文件有点繁琐之外,其他地方还比较直接, 挺符合直觉的.</p> <p>并不比感觉用 kubeadm 复杂很多.</p> Sarasa Mono T SC 的含义 https://strrl.dev/post/before-2022/sarasa-mono-t-sc-%E7%9A%84%E5%90%AB%E4%B9%89/ Thu, 16 Jan 2020 09:32:50 +0000 https://strrl.dev/post/before-2022/sarasa-mono-t-sc-%E7%9A%84%E5%90%AB%E4%B9%89/ <p>Sarasa Mono T SC 作为现在的主力字体, 每次都忘记这几个是啥意思.</p> <p>sarasa 更纱 Mono 等宽 SC 简体中文.</p> <p>关于 T:</p> <blockquote> <p>Have ligature, Em dashes (——) are full width —— MonoT Have ligature, Em dashes (——) are half width —— Mono No ligature, Em dashes (——) are half width —— Term</p></blockquote> 未来有你成都站 https://strrl.dev/post/before-2022/%E6%9C%AA%E6%9D%A5%E6%9C%89%E4%BD%A0%E6%88%90%E9%83%BD%E7%AB%99/ Mon, 11 Nov 2019 12:04:39 +0000 https://strrl.dev/post/before-2022/%E6%9C%AA%E6%9D%A5%E6%9C%89%E4%BD%A0%E6%88%90%E9%83%BD%E7%AB%99/ <p>我是个葱葱人 hhhhhh.</p> <p>以前由于穷和懒一直没有去过现场, 今年决定去一次. 一开始并不知道今年未来有你有四站(上海成都北京广州), 成都票出来以后就和女票商量买了票, 并且约了在成都的大学同学. (后来才发现上海是最早的, 11.2, 失策, 明年去上海好了)</p> <p>而且周天晚上是 LOL S9 的决赛, FPX 打 G2, 担心周末落地杭州后看不到比赛.</p> <p>周六上午五点半起, 赶六点半的机场大巴. 去程的飞机还航空管制呆了一个多小时, 还好计划中预留了两个小时. 到达成都后稍微休息了一会就直接去会场了.</p> <p>由于太菜没有找到摊子的位置, 也木有买到绿毛玩偶, 直到检票的时候发现摊子在另一侧, 需要绕过去.</p> <p>偷个图, 朋友买的绿毛 <p class="md__image"> <img src='https://i.imgur.com/vb1xod5.jpg' alt="朋友买的绿毛" /> </p> </p> <p>进会场以后感觉和大家格格不入, 周围都是有活力的年轻人, 而自己已经是一个社畜了. 演唱会开始以后大家都站起来疯狂打 call, 而我 emmm 留下了激动的泪水. 麻麻原来现场就是这么刺激的呀.</p> <p> <p class="md__image"> <img src='https://i.imgur.com/M0vlMmn.jpg' alt="频谱" /> </p> </p> <p>结束以后随便拍了一张照片留念一下, 明年还是要继续参加的.</p> <p> <p class="md__image"> <img src='https://i.imgur.com/Pthyddp.jpg' alt="会场门口的葱葱挖掘机" /> </p> </p> <p> <p class="md__image"> <img src='https://i.imgur.com/H81No45.jpg' alt="结束" /> </p> </p> <p>第二天约了大学同学吃了火锅, 选了一个不怎么辣的. 吃完后喝饮料吹逼, 分别前表示欢迎来杭州继续吹逼.</p> <p> <p class="md__image"> <img src='https://i.imgur.com/mm9KtZe.jpg' alt="明哥和老王" /> </p> </p> <p>晚上没有错过太多决赛, 飞机落地后已经 1:0 了, 而且还刷到这么一条表情包:</p> <p> <p class="md__image"> <img src='https://i.imgur.com/B2KollE.jpg' alt="tian 盲僧" /> </p> </p> <p>路上看了第二场, 回到家看了第三场. FPX 一路虐菜拿到冠军.</p> <p>舒服了</p> <p>这次折腾了两天, 不算很累. 时间虽然紧张, 但是没有耗很多体力, 周一还是照常上班.</p> <p>啊美好的周末, 以后可以多出去玩.</p> Brewer’s Conjecture and the Feasibility of Consistent, Available, Partition-Tolerant Web Services https://strrl.dev/post/before-2022/brewers-conjecture-and-the-feasibility-of-consistent-available-partition-tolerant-web-services/ Thu, 31 Oct 2019 14:26:51 +0000 https://strrl.dev/post/before-2022/brewers-conjecture-and-the-feasibility-of-consistent-available-partition-tolerant-web-services/ <p>[toc]</p> <p><a href="https://users.ece.cmu.edu/~adrian/731-sp04/readings/GL-cap.pdf">原文</a></p> <h2 id="摘要">摘要</h2> <p>当设计分布式的 web 服务时, 有三个经常考虑到的属性: 一致性 (consistency), 可用性(availability)和分区容错性(partition tolerance). 三者是不可能同时达到的. 在这个文章里, 我们将会在一个异步网络模型中证明这个猜想, 然后在部分同步模型中讨论解决这个问题的方案.</p> <h2 id="1-introduction">1 Introduction</h2> <p>Brewer 受邀在 PODC 2000 上讲话时发表了一个猜想: 在一个(分布式)的 web 服务中是不可能同时保证以下三点的:</p> <ul> <li>一致性</li> <li>可用性</li> <li>分区容错性</li> </ul> <p>这三点是真实的 web 服务所关注而且所期望的. 在这个文章中, 我们先会讨论 Brewer 在这个猜想中想表达什么; 然后我们会具体化这些概念并证明猜想; 最后我们将描述并尝试正式确定一些针对此实际困难的现实解决方案.</p> <p>当今大多数的 web 服务尝试提供强一致性的数据. 在设计 ACID 数据库这方面已经有足够的研究了, 而且大多数 web 服务的新框架都是依赖与这些数据库的. Web 服务之间的交互都被期望是以一种事务的(transactional)方式进行: 操作在提交时要么全部成功要么全部失败(原子性), 提交过的事务能够被以后所有的事务看到(一致性), 未提交的事务之间是相互隔离的(隔离性), 一旦事务被提交它应该是永久的(持久性). 这显然是很重要的, 例如账单信息和商业交易记录保持强一致性.</p> <p>同样, web 服务也被期望是高可用的. 每个请求都应该会成功而且能够收到一个响应. 当服务 down 掉了, 它会产生一些很明显的现实世界问题: 典型的例子是如果一个网上交易的网站 down 了, 那么它会有一些潜在的法律上困难问题. 如果一个网站在最需要它是却不能访问, 那么这个问题会更加恶化. 当今大多数的 web 服务的目标都是像他们使用的网络那样可靠: 只要任意一个服务是可用的, 那么整个 web 服务就是可访问的.</p> <p>最后, 在一个高度分布式的网络中, 需要提供一定的容错能力. 当一些节点崩溃或者连接失败时, 服务能够照常工作是非常重要的. 能够在网络被分为多个部分时仍然能够 survive, 是理想的容错能力. 在这个文章中不会谈论到 stopping failures, 尽管有些情况下可以把 stopping failures 比做存在于分区自身唯一组件中的节点.</p> <h2 id="2-formal-model">2 Formal Model</h2> <p>在这节中, 我们会正式定义单词<em>一致性</em>, <em>可用性</em>和<em>分区容错性</em>的含义.</p> <h3 id="21-atomic-data-objects">2.1 Atomic Data Objects</h3> <p>具体化一个一致性服务最自然的方式是原子数据对象(atomic data object). 原子性或者线性化、一致性是当今大多数 web 服务所期望的. 为了保证一致性, 对于所有的操作必须有一个全局的顺序, 就像所有的操作看上去在一个实例上完成的. 这等等效于要求分布式的请求分享内存, 像在同一个节点上执行, 每次响应一个操作. 原子读/写共享内存的一个重要属性是, 在写操作完成之后开始的任何读操作都必须返回该值, 或以后写操作的结果.(为什么是还能是 or the result of a later write operation ?) 通常来说, 这是用户最容易理解的, 能提供一致性保证的模型. 对于尝试设计使用分布式服务的客户端应用程序的用户而言, 这是最方便的。</p> <h3 id="22-available-data-objects">2.2 Available Data Objects</h3> <p>为了使一个分布式系统持续式可用, 系统中非故障节点受到的每个请求都必须产生响应. 也就是说, 服务使用的任何额算法都最终都必须中止. 在某些情况下有一种可用性的弱定义: 不对这个算法在中止之前放入运行时之间做限制, 因此允许无限制的计算. 从另一方面来说, 为了满足分区容错, 这可以被看作是可用性的强定义: 即使发生了严重的网络错误, 每个请求都应该获得中止(有响应).</p> <h3 id="23-partition-tolerance">2.3 Partition Tolerance</h3> <p>上面关于可用性和原子性的定义都是为了满足分区容错. 为了建模分区容错, 网络可能会随意丢掉任意数量从一个节点发往另一个节点的消息. 当网络发生了分区, 所有的从某一个分区的某个节点发往另一个分区的某个节点的消息都会丢失. (任意形式的消息丢失都可以建模为, 在消息丢失的瞬间将通信节点分开的临时分区)</p> <p>原子性(2.1)意味着每个响应都必须是原子的, 即使算法中的有些消息不会被传递. 可用性(2.2)意味着所有收到的请求都必须有响应, 即使有些消息可能会丢失. 注意这和一个纯共享内存系统中的的非等待中止(wait-free termination)有点像: 即使网络中的其他节点都失败了(这个节点再在他自己唯一的网络分区里), 也必须产生一个合法的响应. 除了网络完全失败之外, 不允许系统出现不正确的响应.</p> <h2 id="3-asynchronous-networks">3 Asynchronous Networks</h2> <h3 id="31-impossibility-result">3.1 Impossibility Result</h3> <p>为了证明这个猜想, 我们将使用异步网络模型, 如 Lynch 在 [7] 中描述的一般. 在异步网络模型中, 没有时钟, 节点职能通过收到的消息和本地的计算来作出决定.</p> <p><strong>定理 1</strong> 在异步网络模型中, 不可能实现一个读/写的数据对象, 在全部都是对等运算时(包括那些消息可能会丢失的情况), 都满足下面的特性:</p> <ul> <li>可用性 Availability</li> <li>原子一致性 Atomic consistency</li> </ul> <p><em>证明</em>: 我们使用反证法. 假设一个算法 <em>A</em> 存在, 能够满足三个准则: atomicity, availability 和 partition tolerance. 我们将构建一次 <em>A</em> 的执行, 其中存一个返回不一致响应的请求. 证明的方法类似于 Attiya [1] 等人和 Lynch [8] 用过的方法. 假设网络至少由两个节点组成. 因此网络可以被划分成两个不相交的非空集合: ${G_1,G_2}$. 证明这个问题的核心思路是假设在 $G_1$ 和 $G_2$ 之间的消息全部丢失. 然后有一个 $write$ 操作在 $G_1$ 上发生, 然后有一个 $read$ 操作在 $G_2$ 上发生, 然后 $read$ 操作并不能返回稍早前 $write$ 操作的结果.</p> <p>更正式一点, 使某个原子对象(atomic object)的初始值为 $v_0$. 使 $\alpha_1$</p> TCP_NODELAY 是什么 https://strrl.dev/post/before-2022/tcp-nodelay-%E6%98%AF%E4%BB%80%E4%B9%88/ Wed, 02 Oct 2019 10:58:54 +0000 https://strrl.dev/post/before-2022/tcp-nodelay-%E6%98%AF%E4%BB%80%E4%B9%88/ <h2 id="引言">引言</h2> <p>最近在使用 <code>curl</code> 的时候经常注意到:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl"># strrl @ eiu in ~ [11:02:50] </span></span><span class="line"><span class="cl">$ curl -v google.com </span></span><span class="line"><span class="cl">* Rebuilt URL to: google.com/ </span></span><span class="line"><span class="cl">* Trying 127.0.0.1... </span></span><span class="line"><span class="cl">* TCP_NODELAY set </span></span><span class="line"><span class="cl">* Connected to 127.0.0.1 (127.0.0.1) port 6152 (#0) </span></span><span class="line"><span class="cl">&gt; GET http://google.com/ HTTP/1.1 </span></span><span class="line"><span class="cl">&gt; Host: google.com </span></span><span class="line"><span class="cl">&gt; User-Agent: curl/7.54.0 </span></span><span class="line"><span class="cl">&gt; Accept: */* </span></span><span class="line"><span class="cl">&gt; Proxy-Connection: Keep-Alive </span></span><span class="line"><span class="cl">&gt; </span></span><span class="line"><span class="cl">&lt; HTTP/1.1 301 Moved Permanently </span></span><span class="line"><span class="cl">&lt; Location: http://www.google.com/ </span></span><span class="line"><span class="cl">&lt; Content-Type: text/html; charset=UTF-8 </span></span><span class="line"><span class="cl">&lt; Date: Wed, 02 Oct 2019 03:02:53 GMT </span></span><span class="line"><span class="cl">&lt; Expires: Fri, 01 Nov 2019 03:02:53 GMT </span></span><span class="line"><span class="cl">&lt; Cache-Control: public, max-age=2592000 </span></span><span class="line"><span class="cl">&lt; Server: gws </span></span><span class="line"><span class="cl">&lt; Content-Length: 219 </span></span><span class="line"><span class="cl">&lt; X-XSS-Protection: 0 </span></span><span class="line"><span class="cl">&lt; X-Frame-Options: SAMEORIGIN </span></span><span class="line"><span class="cl">&lt; </span></span><span class="line"><span class="cl">&lt;HTML&gt;&lt;HEAD&gt;&lt;meta http-equiv=&#34;content-type&#34; content=&#34;text/html;charset=utf-8&#34;&gt; </span></span><span class="line"><span class="cl">&lt;TITLE&gt;301 Moved&lt;/TITLE&gt;&lt;/HEAD&gt;&lt;BODY&gt; </span></span><span class="line"><span class="cl">&lt;H1&gt;301 Moved&lt;/H1&gt; </span></span><span class="line"><span class="cl">The document has moved </span></span><span class="line"><span class="cl">&lt;A HREF=&#34;http://www.google.com/&#34;&gt;here&lt;/A&gt;. </span></span><span class="line"><span class="cl">&lt;/BODY&gt;&lt;/HTML&gt; </span></span><span class="line"><span class="cl">* Connection #0 to host 127.0.0.1 left intact </span></span></code></pre></td></tr></table> </div> </div><p>会有一个 TCP_NODELAY set 的日志打出来, 然鹅已经不是很记得大学计网里关于这个特性了, 所以自己又翻一番资料去了解这个.</p> <p>这件事涉及到 TCP 的两个机制: 纳格算法(Nagle&rsquo;s algorithm)与延迟确认(Delayed ACK).</p> <h2 id="nagles-algorithm">Nagle&rsquo;s algorithm</h2> <p>有这么一种情况, 在某种场景下, 我会以某种恒定的速度往 TCP 流中塞 1 byte 的数据. 那这种情况下其实会浪费很多资源, 因为一个 TCP packet 中, 光是 header 就在 20-60 byte, payload 才 1 byte. 所以为了减少这种情况,就加入了一个 write buffer.</p> <p>伪代码:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">if there is new data to send then </span></span><span class="line"><span class="cl"> if the window size ≥ MSS and available data is ≥ MSS then </span></span><span class="line"><span class="cl"> send complete MSS segment now </span></span><span class="line"><span class="cl"> else </span></span><span class="line"><span class="cl"> if there is unconfirmed data still in the pipe then </span></span><span class="line"><span class="cl"> enqueue data in the buffer until an acknowledge is received </span></span><span class="line"><span class="cl"> else </span></span><span class="line"><span class="cl"> send data immediately </span></span><span class="line"><span class="cl"> end if </span></span><span class="line"><span class="cl"> end if </span></span><span class="line"><span class="cl">end if </span></span></code></pre></td></tr></table> </div> </div><p>这样通过引入了一个 buffer, 减少了不必要的传输.</p> <h2 id="tcp-delayed-ack">TCP Delayed ACK</h2> <p>Delayed ACK 是为了避免发送只为了 ACK 而发的 packet. 但是也有限制, delay 的长度不能超过 500ms.</p> <h2 id="化学反应">化学反应</h2> <p>由于发送端一直收不到 ACK, 就会一直卡在为代码中的 <code>enqueue data in the buffer until an acknowledge is received</code>处. 可能一直到 500ms 过了, 收到了 ACK 才真正的发送接下来的数据.</p> <p>但是为什么基于 HTTP 的 curl 需要这么一个东西, 还是暂时没有挖清楚, 猜测和 HTTPS 有关.</p> <h2 id="总结">总结</h2> <p>如果自己需要开发一个 rpc 框架, 记得使用 TCP_NODELAY.</p> <p>参考资料:</p> <ol> <li><a href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol">https://en.wikipedia.org/wiki/Transmission_Control_Protocol</a></li> <li><a href="https://en.wikipedia.org/wiki/Nagle%27s_algorithm">https://en.wikipedia.org/wiki/Nagle%27s_algorithm</a></li> <li><a href="https://en.wikipedia.org/wiki/TCP_delayed_acknowledgment">https://en.wikipedia.org/wiki/TCP_delayed_acknowledgment</a></li> <li><a href="https://tools.ietf.org/html/rfc896">https://tools.ietf.org/html/rfc896</a></li> <li><a href="https://tools.ietf.org/html/rfc1122#section-4.2.3.2">https://tools.ietf.org/html/rfc1122#section-4.2.3.2</a></li> </ol> Restful API Mock 工具: JSONPlaceholder https://strrl.dev/post/before-2022/restful-api-mock-%E5%B7%A5%E5%85%B7-jsonplaceholder/ Tue, 09 Jul 2019 13:10:48 +0000 https://strrl.dev/post/before-2022/restful-api-mock-%E5%B7%A5%E5%85%B7-jsonplaceholder/ <p>最近闲逛的时候发现了这个工具, <a href="https://jsonplaceholder.typicode.com">JSONPlaceholder</a>.<br> 它自带了一些数据, 比如说 posts, users 啊.<br> 而且正如它的名字 placeholder, 在开发时一些还没定下的 POST/PUT/DELETE 接口也可以直接发过去.</p> <p>另外还有一个项目<code>My JSON Server</code>, 可以将你的 JSON 数据放到 Github 上的一个仓库里, 然后就可以使用这个功能, 无需自己搭服务器.</p> <p>最后, 这几个功能是由<a href="https://github.com/typicode/json-server">json-server</a>和<a href="https://github.com/typicode/lowdb">LowDB</a>实现的.<br> json-server 也可以在本地使用, 当初搜 mock 工具的时候没找到这个工具, 惭愧惭愧.</p> <blockquote> <p>这几个软件的作者 typicode, GitHub 头像是 FF14 里的仙人掌. hhhhhh</p></blockquote> (翻译)高质量的软件是否值得它所需的成本? https://strrl.dev/post/before-2022/%E9%AB%98%E8%B4%A8%E9%87%8F%E7%9A%84%E8%BD%AF%E4%BB%B6%E6%98%AF%E5%90%A6%E5%80%BC%E5%BE%97%E5%AE%83%E6%89%80%E9%9C%80%E7%9A%84%E6%88%90%E6%9C%AC/ Sat, 29 Jun 2019 21:37:25 +0000 https://strrl.dev/post/before-2022/%E9%AB%98%E8%B4%A8%E9%87%8F%E7%9A%84%E8%BD%AF%E4%BB%B6%E6%98%AF%E5%90%A6%E5%80%BC%E5%BE%97%E5%AE%83%E6%89%80%E9%9C%80%E7%9A%84%E6%88%90%E6%9C%AC/ <blockquote> <p><a href="https://martinfowler.com/articles/is-quality-worth-cost.html">原文地址</a></p></blockquote> <p>在软件开发项目中一个常见的争论, 花时间在提高软件质量, 还是专注于发布更有价值的功能. 通常来说, 提供新功能主导着讨论, 导致很多开发人员抱怨他们没有时间花在架构和代码质量上.</p> <p><a href="https://en.wikipedia.org/wiki/Betteridge%27s_law_of_headlines">Betteridge 的头条新闻定律</a>告诉我们, 任何标题以问号结尾的文章都可以用&quot;不&quot;来概括. 那些熟悉我的人不会怀疑我想违背这个定律. 但是这篇文章走远了 - 它直接颠覆了这个问题. 这个问题假设在质量和成本之间是有取舍的. 但是这个情况并不适用于软件开发: 高质量的软件其实会在开发时消耗更低的成本.</p> <p>虽然我的大部分文章都是针对专业的软件开发人员的, 但是本文不会假设你有任何有关软件开发机制的知识. 我希望这篇文章能够对任何与软件相关工作有关的人都有帮助, 尤其是作为软件开发团队的商业领袖.</p> <h2 id="我们习惯在质量和成本之间做取舍">我们习惯在质量和成本之间做取舍</h2> <p>就像我在开头提到的, 我们习惯在质量和成本之间做取舍. 当我在更换智能手机时, 我可以选择更昂贵的型号,具有更快的处理器,更好的屏幕和更多的内存. 或者我可以放弃其中的一些&quot;质量&quot;来省钱. (Or I can give up some of those qualities to pay less money.) 这其中并没有一个绝对的规则, 有时我们可以用便宜的价格买到质量好的商品. 更多情况下, 我们有不同衡量价值的标准: 有些人其实不会真正意识到这个屏幕比另一个更好. 但是大多数情况下这种假设是正确的: 更好的质量通常会花费更多.</p> <h2 id="软件质量意味着很多事情">软件质量意味着很多事情</h2> <p>在我讨论软件质量之前, 我需要解释一下它是什么. 这里有一个复杂的问题: 很多东西都可以算作软件质量. 我能想到 UI: 他是否能轻松引导我需要做的任务, 并且使我更加高效而且减少挫折? 我能想到可靠性: 它包含可能会造成错误的缺陷吗? 架构是它的另一个方面: 源码是否被分为清晰的模块, 能够使程序员轻易地理解他们这周所要工作的代码.</p> <p>这三个质量的例子并不是一个详细的列表, 但是他们足够表明一个重要的观点. 如果我是软件的客户或用户, 我不会称赞那些我们称之为质量的东西. 用户会判断 UI 是不是好. 高管能判断他的员工是不是更加高效. 用户和客户会注意到缺陷, 特别是在丢失数据和系统不工作时. 但是客户和用户不会感知到软件的架构.</p> <p>因此, 我把软件质量分为外部(UI 和缺陷)和内部(架构). 区别在于用户和客户能够区分出一个软件产品有高的外部质量, 而无法区分出高或者低的内部质量.</p> <h2 id="乍一看-内部质量对用户来说无关紧要">乍一看, 内部质量对用户来说无关紧要</h2> <p>既然内部质量是客户和用户看不见的, 那它重要吗? 让我们想象一下 Rebecca 和我写一个追踪和预测航班延误的应用. 我们的应用都是做了一样的核心功能, 都有优雅的 UI, 也都几乎没有缺陷. 唯一的不同是她的代码是被整洁地整理过的, 而我的是一团糟. 然后这还另外一个不同: 我卖 $6, 她卖 $10.</p> <p>既然客户不会看到源码, 而且源码也不会对应用的运行有影响, 那为什么额有人会为 Rebecca 的软件多付$4 呢? 换句话说, 为更好的内部质量付钱是不值得的.</p> <p>我的另一种表达方式是: 为了外部质量付出是有意义的, 而为内部质量付出是没有意义的. 用户会判断他们是不是会为更好的 UI 花更多的钱,因为他们能够看到 UI 是否是够好以至于能够值那些钱. 但是哟哦那个户看不到软件内部的结构, 更别说判断它是不是更好了. 为什么要为没有效果的东西付出更多?既然如此 - 为什么软件开发人员应该花时间和精力来提高工作的内部质量?</p> <h2 id="内部质量可以更轻松地增强软件">内部质量可以更轻松地增强软件</h2> <p>所以为什么软件开发者还提出内部质量的问题呢? 程序员将最多的时间花在了修改代码上. 甚至在一个新系统中, 几乎所有的编程工作也都是在一个已有代码基础的环境里进行的. 当我想为软件增加新功能时, 我的第一个任务时找出如何将这个新特性整合进当前软件的工作流程中。然后我需要改变这个流程使我的功能整合进去. 我经常使用应用中已经存在的数据, 所以我需要理解这些数据代表着什么, 它和它周围的数据有怎样的关系,为了我的新功能我需要什么数据.</p> <p>所有的这些都和我理解已存在的代码有关. 但是软件经常变得很难理解. 逻辑非常乱, 数据难以理解, 在六个月前某个命名可能对 Tony 有意义, 但是现在对于我来说, 它和 Tony 离职的原因一样神秘. 这些形式都是程序员所指的 <strong>cruft</strong> - 当前代码的样子和它理想中样子的差别.</p> <h2 id="客户只关心新功能快速的上线">客户只关心新功能快速的上线</h2> <p>让我们看一下为什么内部质量对于用户和客户来说是有意义的. 更好的内部质量可以使新特性的增加变得简单, 因此变得更快和更便宜. Rebecca 和我也许现在都有一个一样的应用, 但是在接下来的几个月里, Rebecca 更高的质量可以让她可以每星期更快得增加一些新特性, 而我一值卡在处理一些 cruft, 只为了作出一些很简单的特性. 我无法和 Rebecca 的开发速度做竞争, 很快她的软件比我的更具有特色. 然后我所有的用户卸载了我的应用, 转而用 Rebecca 的, 尽管她又提高了她软件的价格. <p class="md__image"> <img src='https://i.imgur.com/9Ldp2YX.jpg' alt="crufts" /> </p> </p> <blockquote> <p>如果我们将一个有很多 cruft 的系统和另一个等价的,但是没有 cruft 的系统相比. Cruft 意味着新特性会花费更多的时间, 花费多余的时间是 cruft 的代价, 而且每次做新特性时都会有. 没有 cruft, 新特性可以更快地加进去.</p></blockquote> <h2 id="可视化内部质量的影响">可视化内部质量的影响</h2> <p>内部质量的基本作用是降低未来变化的成本. 但是编写好的软件需要额外的努力, 这在短期内会产生一些成本.</p> <p>一种可视化的方法是看我绘制的软件积累功能以及时间(和成本)的假想图. 对于大多数的软件工作, 曲线看起来是这样的.</p> <p> <p class="md__image"> <img src='https://i.imgur.com/Q6iTkH1.jpg' alt="curve with cumulative functionality and time" /> </p> </p> <blockquote> <p>纵轴: 功能累计, 横轴: 时间.<br> 对于大多数的软件系统来说, 随着时间的推移增加新功能变得越来越难. 这意味着需要较长的时间才能够体现出成本的增加.</p></blockquote> <p>这就是内部质量差的情况. 进度在一开始很快, 但是随着时间的推移, 增加新功能变得越来越难. 甚至一个小改动都需要程序员理解大量的代码, 而且是难以理解的代码. 当他们作出改变的时候, 会造成预期外的问题, 使得需要大量时间的来测试和修复问题.</p> <p>注意高的内部质量就是为了减少生产力的下降. 事实上,在有些产品会产生相反的效果,开发人员可以通过利用先前的工作轻松构建新功能. 因为它需要一支技术精湛,训练有素的团队来实现这一目标. 但是我们只有偶尔会见到这样.</p> <p> <p class="md__image"> <img src='https://i.imgur.com/hdju99a.jpg' alt="compare" /> </p> </p> <blockquote> <p>纵轴: 功能累计, 横轴: 时间.<br> 高质量的软件在一开始时, 开发速度明没有那么快. 但是以后会更快, 更便宜. 这个点在几周内就会发生, 而不是几个月.</p></blockquote> <p>这里有一个微妙的地方: 有一段时间里, 低质量是比高质量更具有生产力的. 在这个时间段是可以在质量和成本之间里做一些 trade-off. 当然, 问题在这: 这个时期到底会有多长.</p> <p>这里我们要弄明白为什么这是一个假想图. 我们无法量化软件团队提供的产出。 由于无法量化产出,从而无法量化生产率,因此无法对低内部质量的后果(这也很难量化)提出可靠的数字。 无法量化产出在专业工作中非常普遍 - 我们如何量化律师或医生的生产力?</p> <p>我通过征求我所知道熟练开发人员的意见,来评估交叉点的. 答案让很多人感到惊讶. 开发者发现低质量的代码会在几周内显著得降低他们的生产力. 因此,内部质量和成本之间的权衡取舍并不. 即使小的项目也能从好的软件实践中获益, 这也能从我的经历中证明.</p> <h2 id="即使最棒的团队也会产生-cruft">即使最棒的团队也会产生 cruft</h2> <p>许多非开发人员倾向于认为只有当开发团队粗心大意并且犯错时才会制造 cruft, 但即使是最优秀的团队也会在工作时不可避免地产生一些 cruft.</p> <p>我想用一个当我和我们最好的技术团队领导聊天的故事来说明这一点. 他刚刚完成了一个被广泛认为是非常成功的项目. 无论是在功能, 施工时间和成本方面, 客户都对交付的系统感到满意. 我们的员工对该项目的工作经验持积极态度. 技术领导确实很高兴, 但也承认系统的架构并不好. 我的反应是&quot;怎么可能 - 你是我们最好的架构师之一.&quot; 他的答复是任何一位经验丰富的软件架构师都熟悉的答案:&ldquo;我们做出了很好的决定, 但现在才真正明白我们应该如何构建它&rdquo;.</p> <p>很多人, 包括一些软件行业的一些人, 会把构建软件比作建造大教堂或者摩天大楼 - 毕竟这是我们把高级程序员称作架构师的原因. 但是构建软件需要在一个充满着不确定的未知世界中, 而不是一个物理世界.</p> <h2 id="高质量的软件生产成本更低">高质量的软件生产成本更低</h2> <p>总结一下上面所说的:</p> <ul> <li>忽视内部质量会导致 cruft 的快速堆积</li> <li>cruft 拖慢了 feature 的开发</li> <li>即使是是优秀的团队也会产生 cruft, 但是通过保持高的内部质量, cruft 才能够变得可控</li> <li>高的内部质量使 cruft 保持在最少, 从而允许团队可以用少的人力, 时间和成本来增加新 feature</li> </ul> <p>可悲的是,软件开发人员通常不能很好地解释这种情况. 我和开发团队讨论过很多次, 她们说&quot;他们(管理层)不让我们写高质量的代码, 因为这会耗费太多的时间&quot;. Developers often justify attention to quality by justifying through the need for proper professionalism. (开发者经常用&quot;专业性的体现&quot;来正当化高质量的代码?) 但是这暗示了高质量是有代价的, 这注定了他们的论点. 令人讨厌的是, 由此产生的繁琐代码既使开发人员的生活更艰难, 又使客户付出了很多钱. 在考虑内部质量时, 我强调我们仅应将其视为一种经济论点. 较高的内部质量降低了将来功能的成本, 这意味着花时间编写好的代码实际上降低了成本.</p> <p>这就是为什么问题一开始没有指出重点. 高质量软件带来的&quot;成本&quot;是负的(不会带来成本, 反而会减少成本). 我们习惯于在生活是对大多数质量和成本之间做取舍, 但是这对软件的质量来说是没有意义的. (他对于外部质量是有意义的, 比如说一个精心设计的 UE.) 由于成本和内部质量之间的关系不同寻常而且违反直觉, 因此很难被接受. 但是了解这一点对于最大效率的开发软件至关重要.</p> <p>(完)</p> 红黑树 https://strrl.dev/post/before-2022/%E7%BA%A2%E9%BB%91%E6%A0%91/ Mon, 03 Jun 2019 21:17:32 +0000 https://strrl.dev/post/before-2022/%E7%BA%A2%E9%BB%91%E6%A0%91/ <p>红黑树是一种自平衡二叉查找树, 它的特点是拥有良好的最坏情况的时间复杂度: O(log n). 因此 Java 的 HashMap 使用红黑树可以一定程度上避免 hash 碰撞攻击.</p> <h2 id="二叉树">二叉树</h2> <p>二叉树是每个节点最多只有两个分支的树, 二叉树的分支具有左右次序,不能随意颠倒。</p> <h2 id="二叉查找树">二叉查找树</h2> <ol> <li>左子树上所有结点的值均小于或等于它的根结点的值</li> <li>右子树上所有结点的值均大于或等于它的根结点的值</li> <li>左、右子树也分别为二叉排序树</li> </ol> <p>存在向链表退化的问题.</p> <h2 id="平衡二叉查找树">平衡二叉查找树</h2> <ol> <li>每个节点的左右两子树高度差都不超过 1</li> <li>其每一个子树均为平衡二叉树</li> </ol> <h2 id="avl-树">AVL 树</h2> <p>AVL 树是一种自平衡二叉查找树, 它能够保证增删查的的平均和最坏时间复杂度都是 $O(log\ n)$. 增加或者删除时需要进行一次/多次树旋转以达到重新平衡.</p> <p> <p class="md__image"> <img src='https://tva1.sinaimg.cn/large/0082zybply1gc360m7qucj30m80fq0u6.jpg' alt="AVL树的重新平衡" /> </p> </p> <p>变换只要记住两点即可(When &amp; How):</p> <ol> <li>平衡因子是它的左子树的高度减去它的右子树的高度, 平衡因子为 2/-2 时才会进行旋转.</li> <li>Pivot 会成为新的根节点, 其他的子树根据<strong>值域</strong>重新找坑即可.</li> </ol> <h2 id="红黑树">红黑树</h2> <ol> <li>节点是红色或黑色。</li> <li>根是黑色。</li> <li>所有叶子都是黑色(叶子是 NIL 节点)。</li> <li>每个红色节点必须有两个黑色的子节点。(从每个叶子到根的所有路径上不能有两个连续的红色节点。</li> <li>从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。</li> </ol> <p>红黑树如果把红节点和父节点当成一起的话, 可以看作是 2-3-4 树. 但是红黑树更容易理解, 且自平衡的操作会简单些.</p> <p>红黑树是一种“不严格”的自平衡树, 它的红节点给它带来的便利就是减少了插入和删除时的操作.</p> <blockquote> <p>有人把红节点理解为&quot;缓存&quot;.</p></blockquote> Translate "man iptables" (updating) https://strrl.dev/post/before-2022/iptables/ Mon, 27 May 2019 21:24:35 +0000 https://strrl.dev/post/before-2022/iptables/ <p>[toc]</p> <blockquote> <p>强迫自己看 iptables 的文档. 翻的很烂, 自己明白就行.</p></blockquote> <p> <p class="md__image"> <img src='https://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg' alt="Netfilter-packet-flow" /> </p> </p> <h2 id="name">Name</h2> <p>iptables - administration tool for IPv4 packet filtering and NAT iptables - IPv4 包过滤和 NAT 的管理工具</p> <h2 id="synopsis-简介">Synopsis 简介</h2> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span><span class="lnt">8 </span><span class="lnt">9 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">iptables [-t table] -[AD] chain rule-specification [options] </span></span><span class="line"><span class="cl">iptables [-t table] -I chain [rulenum] rule-specification [options] </span></span><span class="line"><span class="cl">iptables [-t table] -R chain rulenum rule-specification [options] </span></span><span class="line"><span class="cl">iptables [-t table] -D chain rulenum [options] </span></span><span class="line"><span class="cl">iptables [-t table] -[LFZ][chain] [options] </span></span><span class="line"><span class="cl">iptables [-t table] -N chain </span></span><span class="line"><span class="cl">iptables [-t table] -X [chain] </span></span><span class="line"><span class="cl">iptables [-t table] -P chain target [options] </span></span><span class="line"><span class="cl">iptables [-t table] -E old-chain-name new-chain-name </span></span></code></pre></td></tr></table> </div> </div><h2 id="description-描述">Description 描述</h2> <p>Iptables is used to set up, maintain, and inspect the tables of IP packet filter rules in the Linux kernel.<br> 在 linux 内核中 iptable 被用来配置, 维护和检查 IP 包过滤规则表.</p> <p>Several different tables may be defined.<br> 可能会定义多个不同的表.</p> <p>Each table contains a number of built-in chains and may also contain user-defined chains.<br> 每个表都有几个内置的 Chain, 也有一些用户定义的 Chain.</p> <p>Each chain is a list of rules which can match a set of packets.<br> 每个 Chain 都有一组规则用来匹配一组数据包.</p> <p>Each rule specifies what to do with a packet that matches.<br> 每个规则都指明了如何处理被匹配的数据包.</p> <p>This is called a &rsquo;target&rsquo;, which may be a jump to a user-defined chain in the same table. 这被称为 target, 它可能是到同一张表下某个用户定义的 Chain 的跳转.</p> <h2 id="targets">Targets</h2> <p>A firewall rule specifies criteria for a packet, and a target.<br> 一条防火墙规则表明了数据包的规范和它的 target.</p> <p>If the packet does not match, the next rule in the chain is the examined;<br> 如果数据包没有匹配上, 那么这条这个 Chain 内的下一条规则将继续尝试匹配.</p> <p>if it does match, then the next rule is specified by the value of the target, which can be the name of a user-defined chain or one of the special values ACCEPT, DROP, QUEUE, or RETURN. 如果数据包匹配上了, 则下一条规则由 target 的值来指定, 它可能是一个用户定义的 Chain, 或者是下列特殊值之一: ACCEPT, DROP, QUEUE 或者 RETURN.</p> <p>ACCEPT means to let the packet through.<br> ACCEPT 表示允许包通过.</p> <p>DROP means to drop the packet on the floor.<br> DROP 表示将包丢在防火墙外.</p> <p>QUEUE means to pass the packet to userspace.<br> QUEUE 表示将包发往用户空间.</p> <p>(How the packet can be received by a userspace process differs by the particular queue handler.<br> (user space 进程如何收到数据包会因为 queue handler 的不同而不同.</p> <p>2.4.x and 2.6.x kernels up to 2.6.13 include the ip_queue queue handler.<br> 2.4.x 和 2.6.x 直到 2.6.13 的内核会包含一个 ip_queue queue handler.</p> <p>Kernels 2.6.14 and later additionally include the nfnetlink_queue queue handler.<br> 2.6.14 以及更高版本的内核内核额外包含了一个 nfnetlink_queue queue handler.</p> <p>Packets with a target of QUEUE will be sent to queue number &lsquo;0&rsquo; in this case.<br> 在这种情况下, 目标为 QUEUE 的数据包会发往序号为 0 的 queue. (没明白)</p> <p>Please also see the NFQUEUE target as described later in this man page.) 另请参阅本手册页后面所述的 NFQUEUE 目标.)</p> <p>RETURN means stop traversing this chain and resume at the next rule in the previous (calling) chain.<br> RETURN 表示停止遍历这条 chain 并接着从上个(调用) chain 的下一条 rule 开始.</p> <p>If the end of a built-in chain is reached or a rule in a built-in chain with target RETURN is matched, the target specified by the chain policy determines the fate of the packet.<br> 如果到了内置 chain 的末尾或者一条目标为 RETURN 的内置链规则匹配上, 则 target 被这条 chain 的 policy 所决定.</p> <h2 id="tables">Tables</h2> <p>There are currently three independent tables (which tables are present at any time depends on the kernel configuration options and which modules are present).<br> 当前有三张独立的表(当前有哪些表存在取决于当前的 kernel 配置以及有哪些模块启用).</p> <p><code>-t, --table table</code> This option specifies the packet matching table which the command should operate on.<br> 这个选项指定了命令操作的哪张表.</p> <p>If the kernel is configured with automatic module loading, an attempt will be made to load the appropriate module for that table if it is not already there.<br> 如果内核配置了自动模块加载,则会尝试加载该表的相应模块(如果该表尚不存在).</p> <p>The tables are as follows:<br> 有以下表:</p> <p><code>filter</code>: This is the default table (if no -t option is passed).<br> 这是默认的表(如果<code>-t</code>选项没有被指定).</p> <p>It contains the built-in chains <code>INPUT</code> (for packets destined to local sockets), <code>FORWARD</code> (for packets being routed through the box), and <code>OUTPUT</code> (for locally-generated packets).<br> 它包括了内置的链: <code>INPUT</code>(匹配目标是本机 socket 的包), <code>FORWARD</code>(匹配从本机经过的包)和 <code>OUTPUT</code>(匹配从本地生成的包)</p> <p><code>nat</code>: This table is consulted when a packet that creates a new connection is encountered.<br> 遇到创建新连接的数据包时,会查询此表.</p> <p>It consists of three built-ins: <code>PREROUTING</code> (for altering packets as soon as they come in), <code>OUTPUT</code> (for altering locally-generated packets before routing), and <code>POSTROUTING</code> (for altering packets as they are about to go out).<br> 它包括三条内置的链: <code>PREROUTING</code>(在数据包进入时立即更改), <code>OUTPUT</code>(在本地生成的数据包在路由之前进行修改)和 <code>POSTROUTING</code> (用于在数据包即将发送时更改数据包).</p> <p><code>mangle</code>: This table is used for specialized packet alteration.<br> 这个表被用来做特殊包修改.</p> <p>Until kernel 2.4.17 it had two built-in chains: <code>PREROUTING</code> (for altering incoming packets before routing) and <code>OUTPUT</code> (for altering locally-generated packets before routing).<br> 直到内核版本 2.4.17, 它有两个内置 CHAIN: <code>PREROUTING</code>(在包路由之前修改) 和 <code>OUTPUT</code>(在从本地产生的包在路由之前修改).</p> <p>Since kernel 2.4.18, three other built-in chains are also supported: <code>INPUT</code> (for packets coming into the box itself), <code>FORWARD</code> (for altering packets being routed through the box), and <code>POSTROUTING</code> (for altering packets as they are about to go out).<br> 自内核 2.4.18 后, 其他三个内置的 <code>CHAIN</code> 也被支持了: <code>INPUT</code>(进入本机的包), <code>FORWARD</code>(修改通过本机的包) 和 <code>POSTROUTING</code>(在包即将发送时修改).</p> <p><code>raw</code>: This table is used mainly for configuring exemptions from connection tracking in combination with the NOTRACK target.<br> 这个表主要和 NOTRACK 目标一起使用, 用来配置避免 connection tracking.</p> <p>It registers at the netfilter hooks with higher priority and is thus called before ip_conntrack, or any other IP tables.<br> 它在 netfilter hooks 中有更高的优先级, 因此它会在 ip_conntrack 或者任何其他的 IP 表之前被调用.</p> <p>It provides the following built-in chains: <code>PREROUTING</code> (for packets arriving via any network interface) <code>OUTPUT</code> (for packets generated by local processes)<br> 它提供了下列内置的 CHAIN: <code>PREROUTING</code>(修改到达任意网络接口的包), <code>OUTPUT</code>(修改本地生成的包).</p> <h2 id="options">Options</h2> <p>The options that are recognized by iptables can be divided into several different groups.<br> 能被 iptables 识别的选项可被分成几个不同的组.</p> <h3 id="commands">COMMANDS</h3> <p>These options specify the specific action to perform.<br> 这些选项声明了将要执行的特定行为.</p> <p>Only one of them can be specified on the command line unless otherwise specified below.<br> 除非另有说明, 否则只能在一行命令中指定一个命令.</p> <p>For all the long versions of the command and option names, you need to use only enough letters to ensure that iptables can differentiate it from all other options.<br> 对于所有的长的命令, 你可以只用足够的字母, 能够保证 iptables 将它从命令中区分开即可。</p> <p><code>-A, --append chain rule-specification</code><br> Append one or more rules to the end of the selected chain. When the source and/or destination names resolve to more than one address, a rule will be added for each possible address combination.<br> 在选择的 CHAIN 后追加一条或多条规则. 当规则中的 source 和/或 destination 名可以处理多余一个地址时, 每个可行的地址组合都会新增一条规则.</p> <p><code>-D, --delete chain rule-specification</code><br> <code>-D, --delete chain rulenum</code><br> Delete one or more rules from the selected chain. There are two versions of this command: the rule can be specified as a number in the chain (starting at 1 for the first rule) or a rule to match.<br> 从选择的 CHAIN 中删除一条或多条规则. 这条命令有两种使用方式: 使用 CHAIN 中的数字(从第一条规则以数字 1 开始)或者匹配规则.</p> <p><code>-I, --insert chain [rulenum] rule-specification</code><br> Insert one or more rules in the selected chain as the given rule number.<br> 向选择的 CHAIN 中以给定的 number 插入一条或多条规则.</p> <p>So, if the rule number is 1, the rule or rules are inserted at the head of the chain. This is also the default if no rule number is specified.<br> 所以如果 number 为 1, 规则就会被插入到 CHAIN 的头部. 如果没有声明 number, 这也是默认行为.</p> <p><code>-R, --replace chain rulenum rule-specification</code><br> Replace a rule in the selected chain. If the source and/or destination names resolve to multiple addresses, the command will fail. 在选择的 CHAIN 中替换一条规则. 如果规则中的 source 和/或 destination 名匹配了多个地址, 这条命令会失败.</p> <p>Rules are numbered starting at 1.<br> 规则的序号从 1 开始.</p> <p><code>-L, --list [chain]</code><br> List all rules in the selected chain. If no chain is selected, all chains are listed.<br> 列出所选 CHAIN 的所有规则. 如果没有 CHAIN 被选择, 所有的 CHAIN 都会被列出.</p> <p>As every other iptables command, it applies to the specified table (filter is the default), so NAT rules get listed by 就像其他的 iptables 命令一样, 它需要一个指定的表(默认表是 filter), 所以 NAT 规则可以这样被列出:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">iptables -t nat -n -L </span></span></code></pre></td></tr></table> </div> </div><p>Please note that it is often used with the -n option, in order to avoid long reverse DNS lookups.<br> 请注意<code>-n</code>经常被使用, 他表示避免长时间的反向 DNS 查询.</p> <p>It is legal to specify the -Z (zero) option as well, in which case the chain(s) will be atomically listed and zeroed.<br> 也可以使用 <code>-Z</code>(zero)选项, 将把 CHAIN 中的计数器归零.</p> <p>The exact output is affected by the other arguments given.<br> 输出也会收到其他给定参数的影响.</p> <p>The exact rules are suppressed until you use 输出都是被精简过的, 直到你使用</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">iptables -L -v </span></span></code></pre></td></tr></table> </div> </div><p><code>-F, --flush [chain]</code><br> Flush the selected chain (all the chains in the table if none is given).<br> 清空选定的 CHAIN. (如果没有指定, 则是所有的 CHAIN)</p> <p>This is equivalent to deleting all the rules one by one. 这和一条条删除所有的 rules 是等价的.</p> <p><code>-Z, --zero [chain]</code><br> Zero the packet and byte counters in all chains.<br> 将所有 CHAIN 的 packet 和 byte 计数器重置为 0.</p> <p>It is legal to specify the -L, &ndash;list (list) option as well, to see the counters immediately before they are cleared. (See above.)<br> 他可以和<code>-L</code>一起使用, 在重置之前查看计数器的值.</p> <p><code>-N, --new-chain chain</code><br> Create a new user-defined chain by the given name.<br> 使用给定的名字新建一个用户定义的 CHAIN.</p> <p>There must be no target of that name already. 名字不能已经成为 target.</p> <p><code>-X, --delete-chain [chain]</code><br> Delete the optional user-defined chain specified.<br> 删除给定的用户定义的 CHAIN.</p> <p>There must be no references to the chain.<br> 这条 CHAIN 不能被引用.</p> <p>If there are, you must delete or replace the referring rules before the chain can be deleted.<br> 如果 CHAIN 被引用了, 你必须删除或者替换相关的规则, 才能使之能够被删除.</p> <p>The chain must be empty, i.e. not contain any rules.<br> CHAIN 必须是空的, 或者说不能有任何 rules.</p> <p>If no argument is given, it will attempt to delete every non-builtin chain in the table.<br> 如果没有给定参数, 它会尝试删除表中所有非内置的 CHAIN.</p> <p><code>-P, --policy chain target</code><br> Set the policy for the chain to the given target.<br> 设置 CHIAN 的策略为给定的 target.</p> <p>See the section TARGETS for the legal targets.<br> 查看 TARGETS 章节来了解合法的 targets.</p> <p>Only built-in (non-user-defined) chains can have policies, and neither built-in nor user-defined chains can be policy targets.<br> 只有内置的 CHINA 才有 policy, 内置或者用户定的 CHAIN 都不能成为 policy 的 targets.</p> <p><code>-E, --rename-chain old-chain new-chain</code><br> Rename the user specified chain to the user supplied name.<br> 重命名一个用户指定的 CHAIN 为用户给定的名字.</p> <p>This is cosmetic, and has no effect on the structure of the table.<br> 这只是个装饰品, 对表结构没有任何影响.</p> <p><code>-h</code><br> Help. Give a (currently very brief) description of the command syntax. 帮助. 提供一个(目前很简单的)命令语法说明.</p> <h3 id="parameters">PARAMETERS</h3> <p>The following parameters make up a rule specification (as used in the add, delete, insert, replace and append commands).<br> 下面的参数组成了一条 rule specification(可以用在 <code>add</code>, <code>delete</code>, <code>insert</code>, <code>replace</code> 和 <code>append</code>命令里).</p> <p><code>-p, --protocol [!] protocol</code><br> The protocol of the rule or of the packet to check.<br> 规则或者被检查包的协议.</p> <p>The specified protocol can be one of tcp, udp, icmp, or all, or it can be a numeric value, representing one of these protocols or a different one.<br> 规定的协议可以是 <code>tcp</code>, <code>udp</code>, <code>icmp</code>, 或者 <code>all</code> 的其中一个, 或者是一个数字, 代表协议之一或者不同协议.</p> <p>A protocol name from /etc/protocols is also allowed.<br> 在<code>/etc/protocols</code>中的协议名都是允许的.</p> <p>A &ldquo;!&rdquo; argument before the protocol inverts the test.<br> 在协议名前的<code>!</code>会反转测试.</p> <p>The number zero is equivalent to all.<br> 数字 0 等于<code>all</code>.</p> <p>Protocol all will match with all protocols and is taken as default when this option is omitted.<br> <code>all</code>将匹配所有的协议, 这也是该选项被忽略时的默认行为.</p> <p><code>-s, --source [!] address[/mask]</code><br> Source specification.<br> 声明源地址.</p> <p>Address can be either a network name, a hostname (please note that specifying any name to be resolved with a remote query such as DNS is a really bad idea), a network IP address (with /mask), or a plain IP address.<br> 地址可以是一个网络名, 主机名(请注意, 使用 DNS 来解析任何名称都是不好的), IP 地址(带有/掩码), 或者单独一个 IP 地址.</p> <p>The mask can be either a network mask or a plain number, specifying the number of 1&rsquo;s at the left side of the network mask.<br> 掩码的形式可以是一个网络掩码或者是一个数字, 来指定掩码中从左边数, 1 的数量.</p> <p>Thus, a mask of 24 is equivalent to 255.255.255.0.<br> 因此掩码 <code>24</code> 和 <code>255.255.255.0</code> 是等效的.</p> <p>A &ldquo;!&rdquo; argument before the address specification inverts the sense of the address.<br> 在地址前的<code>!</code>参数代表将地址反转.</p> <p>The flag &ndash;src is an alias for this option.<br> 标志<code>--src</code>是该选项的别名.</p> <p><code>-d, --destination [!] address[/mask]</code> Destination specification.<br> 声明目标地址.</p> <p>See the description of the -s (source) flag for a detailed description of the syntax.<br> 查看<code>-s(source)</code>以获取语法的详细描述.</p> <p>The flag &ndash;dst is an alias for this option.<br> 标志<code>--dst</code>是该选项的别名.</p> <p><code>-j, --jump target</code><br> This specifies the target of the rule; i.e., what to do if the packet matches it.<br> 它标识了规则的目标,即规则匹配成功后要做什么.</p> <p>The target can be a user-defined chain (other than the one this rule is in), one of the special builtin targets which decide the fate of the packet immediately, or an extension (see EXTENSIONS below).<br> 目标可以是一个用户定义的 CHAIN(除了这条规则所在的 CHAIN), 内置 targets 之一(将立刻决定包的去向), 或者是一个 extension(查看下面的 EXTENSIONS 章节).</p> <p>If this option is omitted in a rule (and -g is not used), then matching the rule will have no effect on the packet&rsquo;s fate, but the counters on the rule will be incremented.<br> 如果在规则中省略了这个选项(而且没有使用<code>-g</code>), 则这条规则匹配到之后对包的去向没有任何影响, 但是增加这个条规则的计数器.</p> <p><code>-g, --goto chain</code><br> This specifies that the processing should continue in a user specified chain.<br> 它指定流程应该跳转到一个用户定义的 CHAIN 里.</p> <p>Unlike the &ndash;jump option return will not continue processing in this chain but instead in the chain that called us via &ndash;jump. 不像<code>--jump</code>选项, (goto)不会重新回到调用方的 CHAIN 继续处理.</p> <p><code>-i, --in-interface [!] name</code> Name of an interface via which a packet was received (only for packets entering the INPUT, FORWARD and PREROUTING chains).<br> 接收包时所使用的网络接口名(只能在 <code>INPUT</code>, <code>FORWARD</code>和 <code>PREROUTING</code>中使用).</p> <p>When the &ldquo;!&rdquo; argument is used before the interface name, the sense is inverted.<br> 在网络接口名前加入<code>!</code>会反转其含义.</p> <p>If the interface name ends in a &ldquo;+&rdquo;, then any interface which begins with this name will match.<br> 如果网络接口以<code>+</code>结尾, 则任意以这个名字开头的接口都会匹配.</p> <p>If this option is omitted, any interface name will match.<br> 如果这个选择被忽略, 任何接口名都会匹配.</p> <p><code>-o, --out-interface [!] name</code> Name of an interface via which a packet is going to be sent (for packets entering the FORWARD, OUTPUT and POSTROUTING chains).<br> 发送包时所使用的网络接口名(在<code>FORWARD</code>, <code>OUTPUT</code>和<code>POSTROUTING</code>中使用).</p> <p>When the &ldquo;!&rdquo; argument is used before the interface name, the sense is inverted.<br> 在网络接口名前加入<code>!</code>会反转其含义.</p> <p>If the interface name ends in a &ldquo;+&rdquo;, then any interface which begins with this name will match.<br> 如果网络接口以<code>+</code>结尾, 则任意以这个名字开头的接口都会匹配.</p> <p>If this option is omitted, any interface name will match.<br> 如果这个选择被忽略, 任何接口名都会匹配.</p> <p><code>[!] -f, --fragment</code> This means that the rule only refers to second and further fragments of fragmented packets.<br> 这代表这条规则只是为了被分片的包中的第二个以及以后的包.</p> <p>Since there is no way to tell the source or destination ports of such a packet (or ICMP type), such a packet will not match any rules which specify them.<br> 由于这样的包里不含有 source 或 destination 信息(或者 ICMP 类型), 这样的包不会匹配任意条规则.</p> <p>When the &ldquo;!&rdquo; argument precedes the &ldquo;-f&rdquo; flag, the rule will only match head fragments, or unfragmented packets. 当<code>!</code>在<code>-f</code>前时, 规则会只匹配第一个分片, 或未分片的包.</p> <p><code>-c, --set-counters PKTS BYTES</code> This enables the administrator to initialize the packet and byte counters of a rule (during INSERT, APPEND, REPLACE operations). 这可以使管理员重置一条规则的包和字节计数器(在<code>INSERT</code>, <code>APPEND</code>, <code>REPLACE</code>操作时)</p> <h3 id="other-options">OTHER OPTIONS</h3> <p>The following additional options can be specified:<br> 可以指定以下附加选项:</p> <p><code>-v, --verbose</code> Verbose output.<br> 详细输出.</p> <p>This option makes the list command show the interface name, the rule options (if any), and the TOS masks.<br> 这个选项使<code>list</code>命令显示网络接口名, 规则的选项和 TOS mask.</p> <p>The packet and byte counters are also listed, with the suffix &lsquo;K&rsquo;, &lsquo;M&rsquo; or &lsquo;G&rsquo; for 1000, 1,000,000 and 1,000,000,000 multipliers respectively (but see the -x flag to change this). 包和字节计数器也会被列出,带有后缀<code>K</code>, <code>M</code>或者<code>G</code>代表 1000, 1,000,000 和 1,000,000,000 倍数(可以使用<code>-x</code>改变这个行为).</p> <p>For appending, insertion, deletion and replacement, this causes detailed information on the rule or rules to be printed. 在添加, 插入, 删除和替换时, 会打印出规则或规则的详细信息.</p> <p><code>-n, --numeric</code> Numeric output.<br> 数字输出.</p> <p>IP addresses and port numbers will be printed in numeric format.<br> IP 地址和端口号会以数字的形式输出.</p> <p>By default, the program will try to display them as host names, network names, or services (whenever applicable). 默认情况下, 程序会尝试将他们以主机名, 网络名或者服务明(当适用时).</p> <p><code>-x, --exact</code> Expand numbers.<br> 展开数字.</p> <p>Display the exact value of the packet and byte counters, instead of only the rounded number in K&rsquo;s (multiples of 1000) M&rsquo;s (multiples of 1000K) or G&rsquo;s (multiples of 1000M).<br> 显示包和字节计数器的精确值, 来替代使用 K,M 或 G 的大体值.</p> <p>This option is only relevant for the -L command. 这个选项智能和<code>-L</code>命令一起使用.</p> <p><code>--line-numbers</code> When listing rules, add line numbers to the beginning of each rule, corresponding to that rule&rsquo;s position in the chain. 当列出规则时, 为每个规则在开头加一个行号, 对应着规则在 CHAIN 中的位置.</p> <p><code>--modprobe=command</code> When adding or inserting rules into a chain, use command to load any necessary modules (targets, match extensions, etc). 当向 CHAIN 中添加或插入一条规则时, 使用命令来加载任意需要的模块(比如说 targets, 匹配扩展等).</p> <h2 id="match-extensions">Match Extensions</h2> <p>iptables can use extended packet matching modules.<br> iptables 可以使用扩展的包匹配模块.</p> <p>These are loaded in two ways:<br> 有两种方法可以加载它们</p> <p>implicitly, when -p or &ndash;protocol is specified, or with the -m or &ndash;match options, followed by the matching module name; 隐式加载, 当指定了<code>-p</code>/<code>--protocol</code>, 或者带有<code>-m</code>/<code>--match</code>选项, 后面跟匹配模块的名称.</p> <p>after these, various extra command line options become available, depending on the specific module.<br> 除此之外, 根据具体模块, 可以使用各种不同的命令.</p> <p>You can specify multiple extended match modules in one line, and you can use the -h or &ndash;help options after the module has been specified to receive help specific to that module. 你可以在一行中配置多个扩展匹配模块, 你可以在模块后使用 <code>-h</code> 或者 <code>-help</code>选项来获取他们的帮助信息.</p> <p>The following are included in the base package, and most of these can be preceded by a ! to invert the sense of the match. 下面这些选项都内置在基本包中, 他们中大多数都可以使用 <code>!</code>来反转匹配的含义.</p> <h3 id="account">account</h3> <blockquote> <p>没用过 不熟</p></blockquote> <p>Account traffic for all hosts in defined network/netmask. 统计在某个网络/子网中的所有主机.</p> <blockquote> <p>这里的 account 类似与 statistics, 相关信息: Traffic accounting.</p></blockquote> <p>Features: 特性:</p> <ul> <li> <p>long (one counter per protocol TCP/UDP/IMCP/Other) and short statistics 详细(每个协议一个单独的 counter)或精简的统计</p> </li> <li> <p>one iptables rule for all hosts in network/netmask 每个在子网中的所有主机的每条规则</p> </li> <li> <p>loading/saving counters (by reading/writting to procfs entries) 加载/保存 计数器( 通过读/写 /procfs 来统计)</p> </li> </ul> <p><code>--aaddr network/netmask</code> defines network/netmask for which make statistics. 定义需要统计的子网</p> <p><code>--aname name</code> defines name of list where statistics will be kept. If no is specified DEFAULT will be used. 定义统计列表的名字. 如果未设置, 则使用 DEFAULT.</p> <p><code>--ashort</code> table will colect only short statistics (only total counters without splitting it into protocols.) 只会统计简单的信息(只有总数的计数器, 没有细分到每个协议一个计数器).</p> <p>Example usage: 用例:</p> <p>account traffic for/to 192.168.0.0/24 network into table mynetwork: 统计 mynetwork 表中, 从 <code>192.168.0.0/24</code> 的发送/接收的情况</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># iptables -A FORWARD -m account --aname mynetwork --aaddr 192.168.0.0/24</span> </span></span></code></pre></td></tr></table> </div> </div><p>account traffic for/to WWW serwer for 192.168.0.0/24 network into table mywwwserver: 统计 mynetwork 表中, 从 <code>192.168.0.0/24</code> 的发送/接收的情况, 而且是 WWW 服务器的情况</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># iptables -A INPUT -p tcp --dport 80 -m account --aname mywwwserver --aaddr 192.168.0.0/24 --ashort</span> </span></span><span class="line"><span class="cl"><span class="c1"># iptables -A OUTPUT -p tcp --sport 80 -m account --aname mywwwserver --aaddr 192.168.0.0/24 --ashort</span> </span></span></code></pre></td></tr></table> </div> </div><p>read counters: 读取计数器</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># cat /proc/net/ipt_account/mynetwork # cat /proc/net/ipt_account/mywwwserver</span> </span></span></code></pre></td></tr></table> </div> </div><p>set counters: 设置计数器</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># echo &#34;ip = 192.168.0.1 packets_src = 0&#34; &gt; /proc/net/ipt_account/mywwserver</span> </span></span></code></pre></td></tr></table> </div> </div><p>Webpage: <a href="http://www.barbara.eu.org/~quaker/ipt_account/">http://www.barbara.eu.org/~quaker/ipt_account/</a></p> <h3 id="ddrtype">ddrtype</h3> <p>This module matches packets based on their address type. 这个模块通过地址类型来匹配包.</p> <p>Address types are used within the kernel networking stack and categorize addresses into various groups.<br> 地址类型在内核网络栈中使用, 并且被分为不同的组.</p> <p>The exact definition of that group depends on the specific layer three protocol.<br> 组的确切定义依赖于特定的三层协议.</p> <p>The following address types are possible:<br> 下面的地址类型是有可能出现的</p> <p>UNSPEC an unspecified address (i.e. 0.0.0.0)<br> <code>UNSPEC</code> 一个不明确的地址(比如 0.0.0.0)</p> <p>UNICAST an unicast address<br> <code>UNICAST</code> 一个单播地址</p> <p>LOCAL a local address<br> <code>LOCAL</code> 一个本地地址</p> <p>BROADCAST a broadcast address<br> <code>BOARDCAST</code> 一个广播地址</p> <p>ANYCAST an anycast packet<br> <code>ANYCAST</code> 一个任播地址</p> <blockquote> <p><a href="https://en.wikipedia.org/wiki/Anycast">Anycast</a></p></blockquote> <p>MULTICAST a multicast address<br> <code>MULTICAST</code> 一个组播地址</p> <p>BLACKHOLE a blackhole address<br> <code>BLACKHOLE</code> 一个黑洞地址</p> <blockquote> <p><a href="https://en.wikipedia.org/wiki/Black_hole_(networking)">Black hole (networking)</a></p></blockquote> <p>UNREACHABLE an unreachable address<br> <code>UNREACHABLE</code> 一个无法到达的地址</p> <p>PROHIBIT a prohibited address<br> <code>PROHIBIT</code> 一个禁止的地址</p> <p>THROW FIXME <code>THROW</code> 待补充</p> <p>NAT FIXME <code>NAT</code> 待补充</p> <p>XRESOLVE</p> <p><code>--src-type type</code><br> Matches if the source address is of given type<br> 匹配源地址类型</p> <p><code>--dst-type type</code><br> Matches if the destination address is of given type<br> 匹配目标地址类型</p> <h3 id="ah">ah</h3> <p>This module matches the SPIs in Authentication header of IPsec packets. 这个模块会匹配 IPSec 包中认证头的 SPIs.</p> <blockquote> <p>IPsec 不熟悉, 不懂.</p></blockquote> <p><code>--ahspi [!] spi[:spi]</code></p> <blockquote> <p>原文也木有其他解释了. SPI 是个什么东西, 不知道, 挖个坑以后填(咕咕咕).</p></blockquote> <h3 id="childlevel">childlevel</h3> <p>This is an experimental module.<br> 这是一个实验性的模块.</p> <p>It matches on whether the packet is part of a master connection or one of its children (or grandchildren, etc).<br> 它匹配某个包是否是主连接的一部分或者是它的子连接(或者孙子连接, 之类的).</p> <p>For instance, most packets are level 0. FTP data transfer is level 1. 举例, 大多数的包在 level 0. FTP 的 数据传输在 level 1.</p> <blockquote> <p>FTP 的控制流用 20 端口, 数据流在 21 端口. 这里也挖个坑.<br> 类似的 websocket 应该也可以用 childlevel 匹配. 这个选项好像没了? 或者是因为试验性的原因, <a href="http://ipset.netfilter.org/iptables-extensions.man.html">这个文档</a>里没有这个参数.</p></blockquote> <p><code>--childlevel [!] level</code></p> <h3 id="comment">comment</h3> <p>Allows you to add comments (up to 256 characters) to any rule. 为任意一条 rule 增加注释(最多 256 个字符).</p> <p><code>--comment comment</code> Example: iptables -A INPUT -s 192.168.0.0/16 -m comment &ndash;comment &ldquo;A privatized IP block&rdquo;</p> <h3 id="condition">condition</h3> <p>This matches if a specific /proc filename is &lsquo;0&rsquo; or &lsquo;1&rsquo;.<br> 匹配在<code>/proc</code>下的文件是否是 0 或者 1.</p> <p><code>--condition [!] filename</code> Match on boolean value stored in /proc/net/ipt_condition/filename file<br> 匹配储存在<code>/proc/net/ipt_condition/filename</code>的布尔值</p> <h3 id="connbytes">connbytes</h3> <p>Match by how many bytes or packets a connection (or one of the two flows constituting the connection) have tranferred so far, or by average bytes per packet. The counters are 64bit and are thus not expected to overflow ;)</p> <p>The primary use is to detect long-lived downloads and mark them to be scheduled using a lower priority band in traffic control.</p> <p>The transfered bytes per connection can also be viewed through /proc/net/ip_conntrack and accessed via ctnetlink</p> <p>[!] &ndash;connbytes from:[to] match packets from a connection whose packets/bytes/average packet size is more than FROM and less than TO bytes/packets. if TO is omitted only FROM check is done. &ldquo;!&rdquo; is used to match packets not falling in the range. &ndash;connbytes-dir [original|reply|both] which packets to consider &ndash;connbytes-mode [packets|bytes|avgpkt] whether to check the amount of packets, number of bytes transferred or the average size (in bytes) of all packets received so far. Note that when &ldquo;both&rdquo; is used together with &ldquo;avgpkt&rdquo;, and data is going (mainly) only in one direction (for example HTTP), the average packet size will be about half of the actual data packets. Example: iptables .. -m connbytes &ndash;connbytes 10000:100000 &ndash;connbytes-dir both &ndash;connbytes-mode bytes &hellip;</p> <h3 id="connlimit">connlimit</h3> <p>Allows you to restrict the number of parallel TCP connections to a server per client IP address (or address block). [!] &ndash;connlimit-above n match if the number of existing tcp connections is (not) above n &ndash;connlimit-mask bits group hosts using mask Examples:</p> <blockquote> <p>allow 2 telnet connections per client host</p></blockquote> <p>iptables -p tcp &ndash;syn &ndash;dport 23 -m connlimit &ndash;connlimit-above 2 -j REJECT</p> <blockquote> <p>you can also match the other way around:</p></blockquote> <p>iptables -p tcp &ndash;syn &ndash;dport 23 -m connlimit ! &ndash;connlimit-above 2 -j ACCEPT</p> <blockquote> <p>limit the nr of parallel http requests to 16 per class C sized network (24 bit netmask)</p></blockquote> <p>iptables -p tcp &ndash;syn &ndash;dport 80 -m connlimit &ndash;connlimit-above 16 &ndash;connlimit-mask 24 -j REJECT</p> <h3 id="connmark">connmark</h3> <p>This module matches the netfilter mark field associated with a connection (which can be set using the CONNMARK target below). &ndash;mark value[/mask] Matches packets in connections with the given mark value (if a mask is specified, this is logically ANDed with the mark before the comparison). connrate</p> <p>This module matches the current transfer rate in a connection. &ndash;connrate [!][from]:[to] Match against the current connection transfer rate being within &lsquo;from&rsquo; and &rsquo;to&rsquo; bytes per second. When the &ldquo;!&rdquo; argument is used before the range, the sense of the match is inverted.</p> <h3 id="conntrack">conntrack</h3> <p>This module, when combined with connection tracking, allows access to more connection tracking information than the &ldquo;state&rdquo; match. (this module is present only if iptables was compiled under a kernel supporting this feature) &ndash;ctstate state Where state is a comma separated list of the connection states to match. Possible states are INVALID meaning that the packet is associated with no known connection, ESTABLISHED meaning that the packet is associated with a connection which has seen packets in both directions, NEW meaning that the packet has started a new connection, or otherwise associated with a connection which has not seen packets in both directions, and RELATED meaning that the packet is starting a new connection, but is associated with an existing connection, such as an FTP data transfer, or an ICMP error. SNAT A virtual state, matching if the original source address differs from the reply destination. DNAT A virtual state, matching if the original destination differs from the reply source. &ndash;ctproto proto Protocol to match (by number or name) &ndash;ctorigsrc [!] address[/mask] Match against original source address &ndash;ctorigdst [!] address[/mask] Match against original destination address &ndash;ctreplsrc [!] address[/mask] Match against reply source address &ndash;ctrepldst [!] address[/mask] Match against reply destination address &ndash;ctstatus [NONE|EXPECTED|SEEN_REPLY|ASSURED][,&hellip;] Match against internal conntrack states &ndash;ctexpire time[:time] Match remaining lifetime in seconds against given value or range of values (inclusive)</p> <h3 id="dccp">dccp</h3> <p>&ndash;source-port,&ndash;sport [!] port[:port] &ndash;destination-port,&ndash;dport [!] port[:port] &ndash;dccp-types [!] mask Match when the DCCP packet type is one of &lsquo;mask&rsquo;. &lsquo;mask&rsquo; is a comma-separated list of packet types. Packet types are: REQUEST RESPONSE DATA ACK DATAACK CLOSEREQ CLOSE RESET SYNC SYNCACK INVALID. &ndash;dccp-option [!] number Match if DCP option set.</p> <h3 id="dscp">dscp</h3> <p>This module matches the 6 bit DSCP field within the TOS field in the IP header. DSCP has superseded TOS within the IETF. &ndash;dscp value Match against a numeric (decimal or hex) value [0-63]. &ndash;dscp-class DiffServ Class Match the DiffServ class. This value may be any of the BE, EF, AFxx or CSx classes. It will then be converted into it&rsquo;s according numeric value.</p> <h3 id="dstlimit">dstlimit</h3> <p>This module allows you to limit the packet per second (pps) rate on a per destination IP or per destination port base. As opposed to the &rsquo;limit&rsquo; match, every destination ip / destination port has it&rsquo;s own limit. THIS MODULE IS DEPRECATED AND HAS BEEN REPLACED BY &lsquo;&lsquo;hashlimit&rsquo;&rsquo; &ndash;dstlimit avg Maximum average match rate (packets per second unless followed by /sec /minute /hour /day postfixes). &ndash;dstlimit-mode mode The limiting hashmode. Is the specified limit per dstip, dstip-dstport tuple, srcip-dstip tuple, or per srcipdstip-dstport tuple. &ndash;dstlimit-name name Name for /proc/net/ipt_dstlimit/* file entry [&ndash;dstlimit-burst burst] Number of packets to match in a burst. Default: 5 [&ndash;dstlimit-htable-size size] Number of buckets in the hashtable [&ndash;dstlimit-htable-max max] Maximum number of entries in the hashtable [&ndash;dstlimit-htable-gcinterval interval] Interval between garbage collection runs of the hashtable (in miliseconds). Default is 1000 (1 second). [&ndash;dstlimit-htable-expire time After which time are idle entries expired from hashtable (in miliseconds)? Default is 10000 (10 seconds).</p> <h3 id="ecn">ecn</h3> <p>This allows you to match the ECN bits of the IPv4 and TCP header. ECN is the Explicit Congestion Notification mechanism as specified in RFC3168 &ndash;ecn-tcp-cwr This matches if the TCP ECN CWR (Congestion Window Received) bit is set. &ndash;ecn-tcp-ece This matches if the TCP ECN ECE (ECN Echo) bit is set. &ndash;ecn-ip-ect num This matches a particular IPv4 ECT (ECN-Capable Transport). You have to specify a number between &lsquo;0&rsquo; and &lsquo;3&rsquo;.</p> <h3 id="esp">esp</h3> <p>This module matches the SPIs in ESP header of IPsec packets. &ndash;espspi [!] spi[:spi]</p> <h3 id="fuzzy">fuzzy</h3> <p>This module matches a rate limit based on a fuzzy logic controller [FLC] &ndash;lower-limit number Specifies the lower limit (in packets per second). &ndash;upper-limit number Specifies the upper limit (in packets per second).</p> <h3 id="hashlimit">hashlimit</h3> <p>This patch adds a new match called &lsquo;hashlimit&rsquo;. The idea is to have something like &rsquo;limit&rsquo;, but either per destination-ip or per (destip,destport) tuple. It gives you the ability to express</p> <p>&lsquo;1000 packets per second for every host in 192.168.0.0/16&rsquo; &lsquo;100 packets per second for every service of 192.168.1.1&rsquo;</p> <p>with a single iptables rule. &ndash;hashlimit rate A rate just like the limit match &ndash;hashlimit-burst num Burst value, just like limit match &ndash;hashlimit-mode destip | destip-destport Limit per IP or per port &ndash;hashlimit-name foo The name for the /proc/net/ipt_hashlimit/foo entry &ndash;hashlimit-htable-size num The number of buckets of the hash table &ndash;hashlimit-htable-max num Maximum entries in the hash &ndash;hashlimit-htable-expire num After how many miliseconds do hash entries expire &ndash;hashlimit-htable-gcinterval num How many miliseconds between garbage collection intervals</p> <h3 id="helper">helper</h3> <p>This module matches packets related to a specific conntrack-helper. &ndash;helper string Matches packets related to the specified conntrack-helper. string can be &ldquo;ftp&rdquo; for packets related to a ftp-session on default port. For other ports append -portnr to the value, ie. &ldquo;ftp-2121&rdquo;. Same rules apply for other conntrack-helpers.</p> <h3 id="icmp">icmp</h3> <p>This extension is loaded if &lsquo;&ndash;protocol icmp&rsquo; is specified. It provides the following option: &ndash;icmp-type [!] typename This allows specification of the ICMP type, which can be a numeric ICMP type, or one of the ICMP type names shown by the command iptables -p icmp -h</p> <h3 id="iprange">iprange</h3> <p>This matches on a given arbitrary range of IPv4 addresses [!]&ndash;src-range ip-ip Match source IP in the specified range. [!]&ndash;dst-range ip-ip Match destination IP in the specified range.</p> <h3 id="ipv4options">ipv4options</h3> <p>Match on IPv4 header options like source routing, record route, timestamp and router-alert. &ndash;ssrr To match packets with the flag strict source routing.</p> <p>&ndash;lsrr</p> <p>To match packets with the flag loose source routing.</p> <p>&ndash;no-srr To match packets with no flag for source routing. [!] &ndash;rr To match packets with the RR flag. [!] &ndash;ts To match packets with the TS flag. [!] &ndash;ra To match packets with the router-alert option. [!] &ndash;any-opt To match a packet with at least one IP option, or no IP option at all if ! is chosen. Examples: $ iptables -A input -m ipv4options &ndash;rr -j DROP will drop packets with the record-route flag. $ iptables -A input -m ipv4options &ndash;ts -j DROP will drop packets with the timestamp flag.</p> <h3 id="length">length</h3> <p>This module matches the length of a packet against a specific value or range of values. &ndash;length [!] length[:length]</p> <h3 id="limit">limit</h3> <p>This module matches at a limited rate using a token bucket filter. A rule using this extension will match until this limit is reached (unless the &lsquo;!&rsquo; flag is used). It can be used in combination with the LOG target to give limited logging, for example. &ndash;limit rate Maximum average matching rate: specified as a number, with an optional &lsquo;/second&rsquo;, &lsquo;/minute&rsquo;, &lsquo;/hour&rsquo;, or &lsquo;/day&rsquo; suffix; the default is 3/hour. &ndash;limit-burst number Maximum initial number of packets to match: this number gets recharged by one every time the limit specified above is not reached, up to this number; the default is 5.</p> <h3 id="mac">mac</h3> <p>&ndash;mac-source [!] address Match source MAC address. It must be of the form XX:XX:XX:XX:XX:XX. Note that this only makes sense for packets coming from an Ethernet device and entering the PREROUTING, FORWARD or INPUT chains.</p> <h3 id="mark">mark</h3> <p>This module matches the netfilter mark field associated with a packet (which can be set using the MARK target below). &ndash;mark value[/mask] Matches packets with the given unsigned mark value (if a mask is specified, this is logically ANDed with the mask before the comparison).</p> <h3 id="mport">mport</h3> <p>This module matches a set of source or destination ports. Up to 15 ports can be specified. It can only be used in conjunction with -p tcp or -p udp. &ndash;source-ports port[,port[,port&hellip;]] Match if the source port is one of the given ports. The flag &ndash;sports is a convenient alias for this option. &ndash;destination-ports port[,port[,port&hellip;]] Match if the destination port is one of the given ports. The flag &ndash;dports is a convenient alias for this option. &ndash;ports port[,port[,port&hellip;]] Match if the both the source and destination ports are equal to each other and to one of the given ports.</p> <h3 id="multiport">multiport</h3> <p>This module matches a set of source or destination ports. Up to 15 ports can be specified. A port range (port:port) counts as two ports. It can only be used in conjunction with -p tcp or -p udp. &ndash;source-ports [!] port[,port[,port:port&hellip;]] Match if the source port is one of the given ports. The flag &ndash;sports is a convenient alias for this option. &ndash;destination-ports [!] port[,port[,port:port&hellip;]] Match if the destination port is one of the given ports. The flag &ndash;dports is a convenient alias for this option. &ndash;ports [!] port[,port[,port:port&hellip;]] Match if either the source or destination ports are equal to one of the given ports.</p> <h3 id="nth">nth</h3> <p>This module matches every &rsquo;n&rsquo;th packet &ndash;every value Match every &lsquo;value&rsquo; packet [&ndash;counter num] Use internal counter number &rsquo;num&rsquo;. Default is &lsquo;0&rsquo;. [&ndash;start num] Initialize the counter at the number &rsquo;num&rsquo; insetad of &lsquo;0&rsquo;. Most between &lsquo;0&rsquo; and &lsquo;value&rsquo;-1. [&ndash;packet num] Match on &rsquo;num&rsquo; packet. Most be between &lsquo;0&rsquo; and &lsquo;value&rsquo;-1.</p> <h3 id="osf">osf</h3> <p>The idea of passive OS fingerprint matching exists for quite a long time, but was created as extension fo OpenBSD pf only some weeks ago. Original idea was lurked in some OpenBSD mailing list (thanks grange@open&hellip;) and than adopted for Linux netfilter in form of this code. Original fingerprint table was created by Michal Zalewski <a href="mailto:[email protected]">[email protected]</a>.</p> <p>This module compares some data(WS, MSS, options and it&rsquo;s order, ttl, df and others) from first SYN packet (actually from packets with SYN bit set) with dynamically loaded OS fingerprints.</p> <p>&ndash;log 1/0 If present, OSF will log determined genres even if they don&rsquo;t match desired one.</p> <p>0 - log all determined entries, 1 - only first one. In syslog you find something like this: ipt_osf: Windows [2000:SP3:Windows XP Pro SP1, 2000 SP3]: 11.22.33.55:4024 -&gt; 11.22.33.44:139 ipt_osf: Unknown: 16384:106:1:48:020405B401010402 44.33.22.11:1239 -&gt; 11.22.33.44:80</p> <p>&ndash;smart if present, OSF will use some smartness to determine remote OS. OSF will use initial TTL only if source of connection is in our local network. &ndash;netlink If present, OSF will log all events also through netlink NETLINK_NFLOG groupt 1. &ndash;genre [!] string Match a OS genre by passive fingerprinting Example: <code>#iptables -I INPUT -j ACCEPT -p tcp -m osf --genre Linux --log 1 --smart</code></p> <p>NOTE: -p tcp is obviously required as it is a TCP match.</p> <p>Fingerprints can be loaded and read through /proc/sys/net/ipv4/osf file. One can flush all fingerprints with following command:</p> <p>echo -en FLUSH &gt; /proc/sys/net/ipv4/osf Only one fingerprint per open/write/close. Fingerprints can be downloaded from <a href="http://www.openbsd.org/cgi-bin/cvsweb/src/etc/pf.os">http://www.openbsd.org/cgi-bin/cvsweb/src/etc/pf.os</a></p> <h3 id="owner">owner</h3> <p>This module attempts to match various characteristics of the packet creator, for locally-generated packets. It is only valid in the OUTPUT chain, and even this some packets (such as ICMP ping responses) may have no owner, and hence never match. &ndash;uid-owner userid Matches if the packet was created by a process with the given effective user id. &ndash;gid-owner groupid Matches if the packet was created by a process with the given effective group id. &ndash;pid-owner processid Matches if the packet was created by a process with the given process id. &ndash;sid-owner sessionid Matches if the packet was created by a process in the given session group. &ndash;cmd-owner name Matches if the packet was created by a process with the given command name. (this option is present only if iptables was compiled under a kernel supporting this feature) NOTE: pid, sid and command matching are broken on SMP</p> <h3 id="physdev">physdev</h3> <p>This module matches on the bridge port input and output devices enslaved to a bridge device. This module is a part of the infrastructure that enables a transparent bridging IP firewall and is only useful for kernel versions above version 2.5.44. &ndash;physdev-in [!] name Name of a bridge port via which a packet is received (only for packets entering the INPUT, FORWARD and PREROUTING chains). If the interface name ends in a &ldquo;+&rdquo;, then any interface which begins with this name will match. If the packet didn&rsquo;t arrive through a bridge device, this packet won&rsquo;t match this option, unless &lsquo;!&rsquo; is used. &ndash;physdev-out [!] name Name of a bridge port via which a packet is going to be sent (for packets entering the FORWARD, OUTPUT and POSTROUTING chains). If the interface name ends in a &ldquo;+&rdquo;, then any interface which begins with this name will match. Note that in the nat and mangle OUTPUT chains one cannot match on the bridge output port, however one can in the filter OUTPUT chain. If the packet won&rsquo;t leave by a bridge device or it is yet unknown what the output device will be, then the packet won&rsquo;t match this option, unless [!] &ndash;physdev-is-in Matches if the packet has entered through a bridge interface. [!] &ndash;physdev-is-out Matches if the packet will leave through a bridge interface. [!] &ndash;physdev-is-bridged Matches if the packet is being bridged and therefore is not being routed. This is only useful in the FORWARD and POSTROUTING chains.</p> <h3 id="pkttype">pkttype</h3> <p>This module matches the link-layer packet type. &ndash;pkt-type [unicast|broadcast|multicast]</p> <h3 id="policy">policy</h3> <p>This modules matches the policy used by IPsec for handling a packet. &ndash;dir in|out Used to select whether to match the policy used for decapsulation or the policy that will be used for encapsulation. in is valid in the PREROUTING, INPUT and FORWARD chains, out is valid in the POSTROUTING, OUTPUT and FORWARD chains. &ndash;pol none|ipsec Matches if the packet is subject to IPsec processing. &ndash;strict Selects whether to match the exact policy or match if any rule of the policy matches the given policy. &ndash;reqid id Matches the reqid of the policy rule. The reqid can be specified with setkey(8) using unique:id as level. &ndash;spi spi Matches the SPI of the SA. &ndash;proto ah|esp|ipcomp Matches the encapsulation protocol. &ndash;mode tunnel|transport Matches the encapsulation mode. &ndash;tunnel-src addr[/mask] Matches the source end-point address of a tunnel mode SA. Only valid with &ndash;mode tunnel. &ndash;tunnel-dst addr[/mask] Matches the destination end-point address of a tunnel mode SA. Only valid with &ndash;mode tunnel. &ndash;next Start the next element in the policy specification. Can only be used with &ndash;strict</p> <h3 id="psd">psd</h3> <p>Attempt to detect TCP and UDP port scans. This match was derived from Solar Designer&rsquo;s scanlogd. &ndash;psd-weight-threshold threshold Total weight of the latest TCP/UDP packets with different destination ports coming from the same host to be treated as port scan sequence. &ndash;psd-delay-threshold delay Delay (in hundredths of second) for the packets with different destination ports coming from the same host to be treated as possible port scan subsequence. &ndash;psd-lo-ports-weight weight Weight of the packet with privileged (&lt;=1024) destination port. &ndash;psd-hi-ports-weight weight Weight of the packet with non-priviliged destination port.</p> <h3 id="quota">quota</h3> <p>Implements network quotas by decrementing a byte counter with each packet. &ndash;quota bytes The quota in bytes. KNOWN BUGS: this does not work on SMP systems.</p> <h3 id="random">random</h3> <p>This module randomly matches a certain percentage of all packets. &ndash;average percent Matches the given percentage. If omitted, a probability of 50% is set.</p> <h3 id="realm">realm</h3> <p>This matches the routing realm. Routing realms are used in complex routing setups involving dynamic routing protocols like BGP. &ndash;realm [!]value[/mask] Matches a given realm number (and optionally mask).</p> <h3 id="recent">recent</h3> <p>Allows you to dynamically create a list of IP addresses and then match against that list in a few different ways. For example, you can create a &lsquo;badguy&rsquo; list out of people attempting to connect to port 139 on your firewall and then DROP all future packets from them without considering them.</p> <p>&ndash;name name Specify the list to use for the commands. If no name is given then &lsquo;DEFAULT&rsquo; will be used. [!] &ndash;set This will add the source address of the packet to the list. If the source address is already in the list, this will update the existing entry. This will always return success (or failure if &lsquo;!&rsquo; is passed in). [!] &ndash;rcheck Check if the source address of the packet is currently in the list. [!] &ndash;update Like &ndash;rcheck, except it will update the &ldquo;last seen&rdquo; timestamp if it matches. [!] &ndash;remove Check if the source address of the packet is currently in the list and if so that address will be removed from the list and the rule will return true. If the address is not found, false is returned. [!] &ndash;seconds seconds This option must be used in conjunction with one of &ndash;rcheck or &ndash;update. When used, this will narrow the match to only happen when the address is in the list and was seen within the last given number of seconds. [!] &ndash;hitcount hits This option must be used in conjunction with one of &ndash;rcheck or &ndash;update. When used, this will narrow the match to only happen when the address is in the list and packets had been received greater than or equal to the given value. This option may be used along with &ndash;seconds to create an even narrower match requiring a certain number of hits within a specific time frame. &ndash;rttl This option must be used in conjunction with one of &ndash;rcheck or &ndash;update. When used, this will narrow the match to only happen when the address is in the list and the TTL of the current packet matches that of the packet which hit the &ndash;set rule. This may be useful if you have problems with people faking their source address in order to DoS you via this module by disallowing others access to your site by sending bogus packets to you.</p> <p>Examples:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># iptables -A FORWARD -m recent --name badguy --rcheck --seconds 60 -j DROP</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># iptables -A FORWARD -p tcp -i eth0 --dport 139 -m recent --name badguy --set -j DROP</span> </span></span></code></pre></td></tr></table> </div> </div><p>Official website (<a href="http://snowman.net/projects/ipt_recent/">http://snowman.net/projects/ipt_recent/</a>) also has some examples of usage. /proc/net/ipt_recent/* are the current lists of addresses and information about each entry of each list.</p> <p>Each file in /proc/net/ipt_recent/ can be read from to see the current list or written two using the following commands to modify the list:</p> <p>echo xx.xx.xx.xx &gt; /proc/net/ipt_recent/DEFAULT to Add to the DEFAULT list echo -xx.xx.xx.xx &gt; /proc/net/ipt_recent/DEFAULT to Remove from the DEFAULT list echo clear &gt; /proc/net/ipt_recent/DEFAULT to empty the DEFAULT list. The module itself accepts parameters, defaults shown: ip_list_tot=100 Number of addresses remembered per table ip_pkt_list_tot=20 Number of packets per address remembered ip_list_hash_size=0 Hash table size. 0 means to calculate it based on ip_list_tot, default: 512 ip_list_perms=0644 Permissions for /proc/net/ipt_recent/* files debug=0 Set to 1 to get lots of debugging info</p> <h3 id="sctp">sctp</h3> <p>&ndash;source-port,&ndash;sport [!] port[:port] &ndash;destination-port,&ndash;dport [!] port[:port] &ndash;chunk-types [!] all|any|only chunktype[:flags][&hellip;] The flag letter in upper case indicates that the flag is to match if set, in the lower case indicates to match if unset. Chunk types: DATA INIT INIT_ACK SACK HEARTBEAT HEARTBEAT_ACK ABORT SHUTDOWN SHUTDOWN_ACK ERROR COOKIE_ECHO COOKIE_ACK ECN_ECNE ECN_CWR SHUTDOWN_COMPLETE ASCONF ASCONF_ACK</p> <p>chunk type available flags DATA U B E u b e ABORT T t SHUTDOWN_COMPLETE T t</p> <p>(lowercase means flag should be &ldquo;off&rdquo;, uppercase means &ldquo;on&rdquo;)</p> <p>Examples: iptables -A INPUT -p sctp &ndash;dport 80 -j DROP</p> <p>iptables -A INPUT -p sctp &ndash;chunk-types any DATA,INIT -j DROP</p> <p>iptables -A INPUT -p sctp &ndash;chunk-types any DATA:Be -j ACCEPT</p> <h3 id="set">set</h3> <p>This modules macthes IP sets which can be defined by ipset(8). &ndash;set setname flag[,flag&hellip;] where flags are src and/or dst and there can be no more than six of them. Hence the command iptables -A FORWARD -m set &ndash;set test src,dst will match packets, for which (depending on the type of the set) the source address or port number of the packet can be found in the specified set. If there is a binding belonging to the mached set element or there is a default binding for the given set, then the rule will match the packet only if additionally (depending on the type of the set) the destination address or port number of the packet can be found in the set according to the binding. state</p> <p>This module, when combined with connection tracking, allows access to the connection tracking state for this packet. &ndash;state state Where state is a comma separated list of the connection states to match. Possible states are INVALID meaning that the packet could not be identified for some reason which includes running out of memory and ICMP errors which don&rsquo;t correspond to any known connection, ESTABLISHED meaning that the packet is associated with a connection which has seen packets in both directions, NEW meaning that the packet has started a new connection, or otherwise associated with a connection which has not seen packets in both directions, and RELATED meaning that the packet is starting a new connection, but is associated with an existing connection, such as an FTP data transfer, or an ICMP error.</p> <h3 id="string">string</h3> <p>This modules matches a given string by using some pattern matching strategy. It requires a linux kernel &gt;= 2.6.14. &ndash;algo bm|kmp Select the pattern matching strategy. (bm = Boyer-Moore, kmp = Knuth-Pratt-Morris) &ndash;from offset Set the offset from which it starts looking for any matching. If not passed, default is 0. &ndash;to offset Set the offset from which it starts looking for any matching. If not passed, default is the packet size. &ndash;string pattern Matches the given pattern. &ndash;hex-string pattern Matches the given pattern in hex notation.</p> <h3 id="tcp">tcp</h3> <p>These extensions are loaded if &lsquo;&ndash;protocol tcp&rsquo; is specified. It provides the following options: &ndash;source-port [!] port[:port] Source port or port range specification. This can either be a service name or a port number. An inclusive range can also be specified, using the format port:port. If the first port is omitted, &ldquo;0&rdquo; is assumed; if the last is omitted, &ldquo;65535&rdquo; is assumed. If the second port greater then the first they will be swapped. The flag &ndash;sport is a convenient alias for this option. &ndash;destination-port [!] port[:port] Destination port or port range specification. The flag &ndash;dport is a convenient alias for this option. &ndash;tcp-flags [!] mask comp Match when the TCP flags are as specified. The first argument is the flags which we should examine, written as a comma-separated list, and the second argument is a comma-separated list of flags which must be set. Flags are: SYN ACK FIN RST URG PSH ALL NONE. Hence the command iptables -A FORWARD -p tcp &ndash;tcp-flags SYN,ACK,FIN,RST SYN will only match packets with the SYN flag set, and the ACK, FIN and RST flags unset. [!] &ndash;syn Only match TCP packets with the SYN bit set and the ACK,RST and FIN bits cleared. Such packets are used to request TCP connection initiation; for example, blocking such packets coming in an interface will prevent incoming TCP connections, but outgoing TCP connections will be unaffected. It is equivalent to &ndash;tcp-flags SYN,RST,ACK,FIN SYN. If the &ldquo;!&rdquo; flag precedes the &ldquo;&ndash;syn&rdquo;, the sense of the option is inverted. &ndash;tcp-option [!] number Match if TCP option set. &ndash;mss value[:value] Match TCP SYN or SYN/ACK packets with the specified MSS value (or range), which control the maximum packet size for that connection.</p> <h3 id="tcpmss">tcpmss</h3> <p>This matches the TCP MSS (maximum segment size) field of the TCP header. You can only use this on TCP SYN or SYN/ACK packets, since the MSS is only negotiated during the TCP handshake at connection startup time. [!] &ndash;mss value[:value]&quot; Match a given TCP MSS value or range.</p> <h3 id="time">time</h3> <p>This matches if the packet arrival time/date is within a given range. All options are facultative. &ndash;timestart value Match only if it is after &lsquo;value&rsquo; (Inclusive, format: HH:MM ; default 00:00). &ndash;timestop value Match only if it is before &lsquo;value&rsquo; (Inclusive, format: HH:MM ; default 23:59). &ndash;days listofdays Match only if today is one of the given days. (format: Mon,Tue,Wed,Thu,Fri,Sat,Sun ; default everyday) &ndash;datestart date Match only if it is after &lsquo;date&rsquo; (Inclusive, format: YYYY[:MM[:DD[:hh[:mm[:ss]]]]] ; h,m,s start from 0 ; default to 1970) &ndash;datestop date Match only if it is before &lsquo;date&rsquo; (Inclusive, format: YYYY[:MM[:DD[:hh[:mm[:ss]]]]] ; h,m,s start from 0 ; default to 2037)</p> <h3 id="tos">tos</h3> <p>This module matches the 8 bits of Type of Service field in the IP header (ie. including the precedence bits). &ndash;tos tos The argument is either a standard name, (use iptables -m tos -h to see the list), or a numeric value to match.</p> <h3 id="ttl">ttl</h3> <p>This module matches the time to live field in the IP header. &ndash;ttl-eq ttl Matches the given TTL value. &ndash;ttl-gt ttl Matches if TTL is greater than the given TTL value. &ndash;ttl-lt ttl Matches if TTL is less than the given TTL value.</p> <h3 id="u32">u32</h3> <p>U32 allows you to extract quantities of up to 4 bytes from a packet, AND them with specified masks, shift them by specified amounts and test whether the results are in any of a set of specified ranges. The specification of what to extract is general enough to skip over headers with lengths stored in the packet, as in IP or TCP header lengths. Details and examples are in the kernel module source.</p> <h3 id="udp">udp</h3> <p>These extensions are loaded if &lsquo;&ndash;protocol udp&rsquo; is specified. It provides the following options: &ndash;source-port [!] port[:port] Source port or port range specification. See the description of the &ndash;source-port option of the TCP extension for details. &ndash;destination-port [!] port[:port] Destination port or port range specification. See the description of the &ndash;destination-port option of the TCP extension for details.</p> <h3 id="unclean">unclean</h3> <p>This module takes no options, but attempts to match packets which seem malformed or unusual. This is regarded as experimental.</p> <h2 id="target-extensions">Target Extensions</h2> <p>iptables can use extended target modules: the following are included in the standard distribution.</p> <h3 id="balance">BALANCE</h3> <p>This allows you to DNAT connections in a round-robin way over a given range of destination addresses. &ndash;to-destination ipaddr-ipaddr Address range to round-robin over.</p> <h3 id="classify">CLASSIFY</h3> <p>This module allows you to set the skb-&gt;priority value (and thus classify the packet into a specific CBQ class). &ndash;set-class MAJOR:MINOR Set the major and minor class value.</p> <h3 id="clusterip">CLUSTERIP</h3> <p>This module allows you to configure a simple cluster of nodes that share a certain IP and MAC address without an explicit load balancer in front of them. Connections are statically distributed between the nodes in this cluster. &ndash;new Create a new ClusterIP. You always have to set this on the first rule for a given ClusterIP.</p> <p>&ndash;hashmode mode Specify the hashing mode. Has to be one of sourceip, sourceip-sourceport, sourceip-sourceport-destport &ndash;clustermac mac Specify the ClusterIP MAC address. Has to be a link-layer multicast address &ndash;total-nodes num Number of total nodes within this cluster. &ndash;local-node num Local node number within this cluster. &ndash;hash-init rnd Specify the random seed used for hash initialization.</p> <h3 id="connmark-1">CONNMARK</h3> <p>This module sets the netfilter mark value associated with a connection &ndash;set-mark mark[/mask] Set connection mark. If a mask is specified then only those bits set in the mask is modified. &ndash;save-mark [&ndash;mask mask] Copy the netfilter packet mark value to the connection mark. If a mask is specified then only those bits are copied. &ndash;restore-mark [&ndash;mask mask] Copy the connection mark value to the packet. If a mask is specified then only those bits are copied. This is only valid in the mangle table.</p> <h3 id="dnat">DNAT</h3> <p>This target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from those chains. It specifies that the destination address of the packet should be modified (and all future packets in this connection will also be mangled), and rules should cease being examined. It takes one type of option: &ndash;to-destination ipaddr[-ipaddr][:port-port] which can specify a single new destination IP address, an inclusive range of IP addresses, and optionally, a port range (which is only valid if the rule also specifies -p tcp or -p udp). If no port range is specified, then the destination port will never be modified. In Kernels up to 2.6.10 you can add several &ndash;to-destination options. For those kernels, if you specify more than one destination address, either via an address range or multiple &ndash;to-destination options, a simple round-robin (one after another in cycle) load balancing takes place between these addresses. Later Kernels (&gt;= 2.6.11-rc1) don&rsquo;t have the ability to NAT to multiple ranges anymore.</p> <h3 id="dscp-1">DSCP</h3> <p>This target allows to alter the value of the DSCP bits within the TOS header of the IPv4 packet. As this manipulates a packet, it can only be used in the mangle table. &ndash;set-dscp value Set the DSCP field to a numerical value (can be decimal or hex) &ndash;set-dscp-class class Set the DSCP field to a DiffServ class.</p> <h3 id="ecn-1">ECN</h3> <p>This target allows to selectively work around known ECN blackholes. It can only be used in the mangle table. &ndash;ecn-tcp-remove Remove all ECN bits from the TCP header. Of course, it can only be used in conjunction with -p tcp.</p> <h3 id="ipmark">IPMARK</h3> <p>Allows you to mark a received packet basing on its IP address. This can replace many mangle/mark entries with only one, if you use firewall based classifier. This target is to be used inside the mangle table, in the PREROUTING, POSTROUTING or FORWARD hooks.</p> <p>&ndash;addr src/dst Use source or destination IP address. &ndash;and-mask mask Perform bitwise &lsquo;and&rsquo; on the IP address and this mask. &ndash;or-mask mask Perform bitwise &lsquo;or&rsquo; on the IP address and this mask. The order of IP address bytes is reversed to meet &ldquo;human order of bytes&rdquo;: 192.168.0.1 is 0xc0a80001. At first the &lsquo;and&rsquo; operation is performed, then &lsquo;or&rsquo;. Examples:</p> <p>We create a queue for each user, the queue number is adequate to the IP address of the user, e.g.: all packets going to/from 192.168.5.2 are directed to 1:0502 queue, 192.168.5.12 -&gt; 1:050c etc.</p> <p>We have one classifier rule:</p> <p>tc filter add dev eth3 parent 1:0 protocol ip fw Earlier we had many rules just like below: iptables -t mangle -A POSTROUTING -o eth3 -d 192.168.5.2 -j MARK &ndash;set-mark 0x10502 iptables -t mangle -A POSTROUTING -o eth3 -d 192.168.5.3 -j MARK &ndash;set-mark 0x10503</p> <p>Using IPMARK target we can replace all the mangle/mark rules with only one: iptables -t mangle -A POSTROUTING -o eth3 -j IPMARK &ndash;addr=dst &ndash;and-mask=0xffff &ndash;or-mask=0x10000 On the routers with hundreds of users there should be significant load decrease (e.g. twice). IPV4OPTSSTRIP</p> <p>Strip all the IP options from a packet. The target doesn&rsquo;t take any option, and therefore is extremly easy to use :</p> <p><code># iptables -t mangle -A PREROUTING -j IPV4OPTSSTRIP</code></p> <h3 id="log">LOG</h3> <p>Turn on kernel logging of matching packets. When this option is set for a rule, the Linux kernel will print some information on all matching packets (like most IP header fields) via the kernel log (where it can be read with dmesg or syslogd(8)). This is a &ldquo;non-terminating target&rdquo;, i.e. rule traversal continues at the next rule. So if you want to LOG the packets you refuse, use two separate rules with the same matching criteria, first using target LOG then DROP (or REJECT). &ndash;log-level level Level of logging (numeric or see syslog.conf(5)). &ndash;log-prefix prefix Prefix log messages with the specified prefix; up to 29 letters long, and useful for distinguishing messages in the logs. &ndash;log-tcp-sequence Log TCP sequence numbers. This is a security risk if the log is readable by users. &ndash;log-tcp-options Log options from the TCP packet header. &ndash;log-ip-options Log options from the IP packet header. &ndash;log-uid Log the userid of the process which generated the packet.</p> <h3 id="mark-1">MARK</h3> <p>This is used to set the netfilter mark value associated with the packet. It is only valid in the mangle table. It can for example be used in conjunction with iproute2. &ndash;set-mark mark</p> <h3 id="masquerade">MASQUERADE</h3> <p>This target is only valid in the nat table, in the POSTROUTING chain. It should only be used with dynamically assigned IP (dialup) connections: if you have a static IP address, you should use the SNAT target. Masquerading is equivalent to specifying a mapping to the IP address of the interface the packet is going out, but also has the effect that connections are forgotten when the interface goes down. This is the correct behavior when the next dialup is unlikely to have the same interface address (and hence any established connections are lost anyway). It takes one option: &ndash;to-ports port[-port] This specifies a range of source ports to use, overriding the default SNAT source port-selection heuristics (see above). This is only valid if the rule also specifies -p tcp or -p udp.</p> <h3 id="mirror">MIRROR</h3> <p>This is an experimental demonstration target which inverts the source and destination fields in the IP header and retransmits the packet. It is only valid in the INPUT, FORWARD and PREROUTING chains, and user-defined chains which are only called from those chains. Note that the outgoing packets are NOT seen by any packet filtering chains, connection tracking or NAT, to avoid loops and other problems.</p> <h3 id="netmap">NETMAP</h3> <p>This target allows you to statically map a whole network of addresses onto another network of addresses. It can only be used from rules in the nat table. &ndash;to address[/mask] Network address to map to. The resulting address will be constructed in the following way: All &lsquo;one&rsquo; bits in the mask are filled in from the new &lsquo;address&rsquo;. All bits that are zero in the mask are filled in from the original address.</p> <h3 id="nfqueue">NFQUEUE</h3> <p>This target is an extension of the QUEUE target. As opposed to QUEUE, it allows you to put a packet into any specific queue, identified by its 16-bit queue number. &ndash;queue-num value This specifies the QUEUE number to use. Valud queue numbers are 0 to 65535. The default value is 0. It can only be used with Kernel versions 2.6.14 or later, since it requires the nfnetlink_queue kernel support.</p> <h3 id="notrack">NOTRACK</h3> <p>This target disables connection tracking for all packets matching that rule. It can only be used in the raw table.</p> <h3 id="redirect">REDIRECT</h3> <p>This target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from those chains. It redirects the packet to the machine itself by changing the destination IP to the primary address of the incoming interface (locally-generated packets are mapped to the 127.0.0.1 address). It takes one option: &ndash;to-ports port[-port] This specifies a destination port or range of ports to use: without this, the destination port is never altered. This is only valid if the rule also specifies -p tcp or -p udp.</p> <h3 id="reject">REJECT</h3> <p>This is used to send back an error packet in response to the matched packet: otherwise it is equivalent to DROP so it is a terminating TARGET, ending rule traversal. This target is only valid in the INPUT, FORWARD and OUTPUT chains, and user-defined chains which are only called from those chains. The following option controls the nature of the error packet returned: &ndash;reject-with type The type given can be icmp-net-unreachable icmp-host-unreachable icmp-port-unreachable icmp-proto-unreachable icmp-net-prohibited icmp-host-prohibited or icmp-admin-prohibited (<em>) which return the appropriate ICMP error message (port-unreachable is the default). The option tcp-reset can be used on rules which only match the TCP protocol: this causes a TCP RST packet to be sent back. This is mainly useful for blocking ident (113/tcp) probes which frequently occur when sending mail to broken mail hosts (which won&rsquo;t accept your mail otherwise). (</em>) Using icmp-admin-prohibited with kernels that do not support it will result in a plain DROP instead of REJECT</p> <h3 id="same">SAME</h3> <p>Similar to SNAT/DNAT depending on chain: it takes a range of addresses (&rsquo;&ndash;to 1.2.3.4-1.2.3.7&rsquo;) and gives a client the same source-/destination-address for each connection. &ndash;to <ipaddr>-<ipaddr> Addresses to map source to. May be specified more than once for multiple ranges. &ndash;nodst Don&rsquo;t use the destination-ip in the calculations when selecting the new source-ip</p> <h3 id="set-1">SET</h3> <p>This modules adds and/or deletes entries from IP sets which can be defined by ipset(8). &ndash;add-set setname flag[,flag&hellip;] add the address(es)/port(s) of the packet to the sets &ndash;del-set setname flag[,flag&hellip;] delete the address(es)/port(s) of the packet from the sets, where flags are src and/or dst and there can be no more than six of them. The bindings to follow must previously be defined in order to use multilevel adding/deleting by the SET target.</p> <h3 id="snat">SNAT</h3> <p>This target is only valid in the nat table, in the POSTROUTING chain. It specifies that the source address of the packet should be modified (and all future packets in this connection will also be mangled), and rules should cease being examined. It takes one type of option: &ndash;to-source ipaddr[-ipaddr][:port-port] which can specify a single new source IP address, an inclusive range of IP addresses, and optionally, a port range (which is only valid if the rule also specifies -p tcp or -p udp). If no port range is specified, then source ports below 512 will be mapped to other ports below 512: those between 512 and 1023 inclusive will be mapped to ports below 1024, and other ports will be mapped to 1024 or above. Where possible, no port alteration will occur. In Kernels up to 2.6.10, you can add several &ndash;to-source options. For those kernels, if you specify more than one source address, either via an address range or multiple &ndash;to-source options, a simple round-robin (one after another in cycle) takes place between these addresses. Later Kernels (&gt;= 2.6.11-rc1) don&rsquo;t have the ability to NAT to multiple ranges anymore.</p> <h3 id="tarpit">TARPIT</h3> <p>Captures and holds incoming TCP connections using no local per-connection resources. Connections are accepted, but immediately switched to the persist state (0 byte window), in which the remote side stops sending data and asks to continue every 60-240 seconds. Attempts to close the connection are ignored, forcing the remote side to time out the connection in 12-24 minutes. This offers similar functionality to LaBrea <a href="http://www.hackbusters.net/LaBrea/">http://www.hackbusters.net/LaBrea/</a> but doesn&rsquo;t require dedicated hardware or IPs. Any TCP port that you would normally DROP or REJECT can instead become a tarpit.</p> <p>To tarpit connections to TCP port 80 destined for the current machine:</p> <p>iptables -A INPUT -p tcp -m tcp &ndash;dport 80 -j TARPIT To significantly slow down Code Red/Nimda-style scans of unused address space, forward unused ip addresses to a Linux box not acting as a router (e.g. &ldquo;ip route 10.0.0.0 255.0.0.0 ip.of.linux.box&rdquo; on a Cisco), enable IP forwarding on the Linux box, and add: iptables -A FORWARD -p tcp -j TARPIT iptables -A FORWARD -j DROP</p> <p>NOTE: If you use the conntrack module while you are using TARPIT, you should also use the NOTRACK target, or the kernel will unnecessarily allocate resources for each TARPITted connection. To TARPIT incoming connections to the standard IRC port while using conntrack, you could:</p> <p>iptables -t raw -A PREROUTING -p tcp &ndash;dport 6667 -j NOTRACK iptables -A INPUT -p tcp &ndash;dport 6667 -j TARPIT</p> <h3 id="tcpmss-1">TCPMSS</h3> <p>This target allows to alter the MSS value of TCP SYN packets, to control the maximum size for that connection (usually limiting it to your outgoing interface&rsquo;s MTU minus 40). Of course, it can only be used in conjunction with -p tcp. It is only valid in the mangle table. This target is used to overcome criminally braindead ISPs or servers which block ICMP Fragmentation Needed packets. The symptoms of this problem are that everything works fine from your Linux firewall/router, but machines behind it can never exchange large packets: 1) Web browsers connect, then hang with no data received.</p> <ol start="2"> <li></li> </ol> <p>Small mail works fine, but large emails hang.</p> <ol start="3"> <li></li> </ol> <p>ssh works fine, but scp hangs after initial handshaking.</p> <p>Workaround: activate this option and add a rule to your firewall configuration like: iptables -t mangle -A FORWARD -p tcp &ndash;tcp-flags SYN,RST SYN <br> -j TCPMSS &ndash;clamp-mss-to-pmtu &ndash;set-mss value Explicitly set MSS option to specified value. &ndash;clamp-mss-to-pmtu Automatically clamp MSS value to (path_MTU - 40). These options are mutually exclusive.</p> <h3 id="tos-1">TOS</h3> <p>This is used to set the 8-bit Type of Service field in the IP header. It is only valid in the mangle table. &ndash;set-tos tos You can use a numeric TOS values, or use iptables -j TOS -h to see the list of valid TOS names.</p> <h3 id="trace">TRACE</h3> <p>This target has no options. It just turns on packet tracing for all packets that match this rule.</p> <h3 id="ttl-1">TTL</h3> <p>This is used to modify the IPv4 TTL header field. The TTL field determines how many hops (routers) a packet can traverse until it&rsquo;s time to live is exceeded. Setting or incrementing the TTL field can potentially be very dangerous, so it should be avoided at any cost. Don&rsquo;t ever set or increment the value on packets that leave your local network! mangle table. &ndash;ttl-set value Set the TTL value to &lsquo;value&rsquo;. &ndash;ttl-dec value Decrement the TTL value &lsquo;value&rsquo; times. &ndash;ttl-inc value Increment the TTL value &lsquo;value&rsquo; times.</p> <h3 id="ulog">ULOG</h3> <p>This target provides userspace logging of matching packets. When this target is set for a rule, the Linux kernel will multicast this packet through a netlink socket. One or more userspace processes may then subscribe to various multicast groups and receive the packets. Like LOG, this is a &ldquo;non-terminating target&rdquo;, i.e. rule traversal continues at the next rule. &ndash;ulog-nlgroup nlgroup This specifies the netlink group (1-32) to which the packet is sent. Default value is 1. &ndash;ulog-prefix prefix Prefix log messages with the specified prefix; up to 32 characters long, and useful for distinguishing messages in the logs. &ndash;ulog-cprange size Number of bytes to be copied to userspace. A value of 0 always copies the entire packet, regardless of its size. Default is 0. &ndash;ulog-qthreshold size Number of packet to queue inside kernel. Setting this value to, e.g. 10 accumulates ten packets inside the kernel and transmits them as one netlink multipart message to userspace. Default is 1 (for backwards compatibility).</p> <h3 id="xor">XOR</h3> <p>Encrypt TCP and UDP traffic using a simple XOR encryption &ndash;key string Set key to &ldquo;string&rdquo; &ndash;block-size Set block size</p> <h2 id="diagnostics">Diagnostics</h2> <p>Various error messages are printed to standard error. The exit code is 0 for correct functioning. Errors which appear to be caused by invalid or abused command line parameters cause an exit code of 2, and other errors cause an exit code of 1.</p> <h2 id="bugs">Bugs</h2> <p>Bugs? What&rsquo;s this? ;-) Well, you might want to have a look at <a href="http://bugzilla.netfilter.org/">http://bugzilla.netfilter.org/</a></p> <h2 id="compatibility-with-ipchains">Compatibility With Ipchains</h2> <p>This iptables is very similar to ipchains by Rusty Russell. The main difference is that the chains INPUT and OUTPUT are only traversed for packets coming into the local host and originating from the local host respectively. Hence every packet only passes through one of the three chains (except loopback traffic, which involves both INPUT and OUTPUT chains); previously a forwarded packet would pass through all three.</p> <p>The other main difference is that -i refers to the input interface; -o refers to the output interface, and both are available for packets entering the FORWARD chain.</p> <p>iptables is a pure packet filter when using the default &lsquo;filter&rsquo; table, with optional extension modules. This should simplify much of the previous confusion over the combination of IP masquerading and packet filtering seen previously. So the following options are handled differently:</p> <p>-j MASQ -M -S -M -L There are several other changes in iptables.</p> <h2 id="see-also">See Also</h2> <p>iptables-save(8), iptables-restore(8), ip6tables(8), ip6tables-save(8), ip6tables-restore(8), libipq(3).</p> <p>The packet-filtering-HOWTO details iptables usage for packet filtering, the NAT-HOWTO details NAT, the netfilter-extensions-HOWTO details the extensions that are not in the standard distribution, and the netfilter-hacking-HOWTO details the netfilter internals. See <a href="http://www.netfilter.org/">http://www.netfilter.org/</a>.</p> <h2 id="authors">Authors</h2> <p>Rusty Russell originally wrote iptables, in early consultation with Michael Neuling.</p> <p>Marc Boucher made Rusty abandon ipnatctl by lobbying for a generic packet selection framework in iptables, then wrote the mangle table, the owner match, the mark stuff, and ran around doing cool stuff everywhere.</p> <p>James Morris wrote the TOS target, and tos match.</p> <p>Jozsef Kadlecsik wrote the REJECT target.</p> <p>Harald Welte wrote the ULOG and NFQUEUE target, the new libiptc, as well as the TTL, DSCP, ECN matches and targets.</p> <p>The Netfilter Core Team is: Marc Boucher, Martin Josefsson, Jozsef Kadlecsik, Patrick McHardy, James Morris, Harald Welte and Rusty Russell.</p> <p>Man page originally written by Herve Eychenne <a href="mailto:[email protected]">[email protected]</a>. Referenced By arptables(8), brctl(8), collectd.conf(5), ebtables(8), ferm(1), firehol(1), firehol.conf(5), fwsnort(8), ip6tables-1.4.7(8), ipq_destroy_handle(3), ipq_get_msgerr(3), ipq_perror(3), ipq_read(3), ipq_set_mode(3), ipq_set_verdict(3), iptables-restore-1.4.7(8), iptables-save-1.4.7(8), iptables-xml-1.4.7(8), iptables_selinux(8), iptstate(8), ipvsadm(8), mountd(8), rpc.statd(8), shorewall(8), shorewall-lite(8), shorewall.conf(5), shorewall6-lite(8)</p> 解决git-flow 在 zsh 下没有 completions https://strrl.dev/post/before-2022/%E8%A7%A3%E5%86%B3git-flow%E5%9C%A8zsh%E4%B8%8B%E6%B2%A1%E6%9C%89completions/ Wed, 28 Nov 2018 18:41:40 +0000 https://strrl.dev/post/before-2022/%E8%A7%A3%E5%86%B3git-flow%E5%9C%A8zsh%E4%B8%8B%E6%B2%A1%E6%9C%89completions/ <p>当初用 Homebrew 安装 git-flow 时遇到过。<br> 网上流传的</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">brew remove git </span></span><span class="line"><span class="cl">brew install git --without-completions </span></span></code></pre></td></tr></table> </div> </div><p>已经不管用了,这个参数会被直接忽略掉。</p> <p>解决方法:删除<code>/usr/local/share/zsh/site-functions/_git</code></p> 生活近况 https://strrl.dev/post/before-2022/%E7%94%9F%E6%B4%BB%E8%BF%91%E5%86%B5/ Sat, 21 Jul 2018 11:36:36 +0000 https://strrl.dev/post/before-2022/%E7%94%9F%E6%B4%BB%E8%BF%91%E5%86%B5/ <p>来杭州差不多快一个月了,差不多也安顿下来了。</p> <p>稍微还有一点水土不服,公司事情不多,现在差不多 963 + 992。</p> <p>以后得更起来了,学校留下小尾巴的项目也得做起来了。</p> 使用OpenVPN建立4to6隧道 https://strrl.dev/post/before-2022/%E4%BD%BF%E7%94%A8openvpn%E7%9A%84tun%E6%A8%A1%E5%BC%8F%E5%BB%BA%E7%AB%8B4to6%E9%9A%A7%E9%81%93/ Thu, 24 May 2018 14:35:09 +0000 https://strrl.dev/post/before-2022/%E4%BD%BF%E7%94%A8openvpn%E7%9A%84tun%E6%A8%A1%E5%BC%8F%E5%BB%BA%E7%AB%8B4to6%E9%9A%A7%E9%81%93/ <h1 id="背景">背景</h1> <p>与朋友聊天时聊到了这个事情,然后根据他发给我的V2上的一个<a href="http://v2ex.com/t/234182">帖子</a>小小操作了一下。</p> <h1 id="需要">需要</h1> <p>一台有IPv6的机器,只需一个IPv6地址即可; OpenVPN;</p> <h1 id="操作一下">操作一下</h1> <p>我的手上有一台有v6地址的服务器,根据<a href="https://openvpn.net/index.php/open-source/documentation/howto.html#quick">文档</a>安装并配置OpenVPN。</p> <p>以下是custom的配置</p> <p>需要在ip6tables上设置一条规则:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ip6tables -t nat -A POSTROUTING -j SNAT --to-source xxxx:xxxx:xxxx::xxxx:xxxx </span></span></code></pre></td></tr></table> </div> </div><p>这里的xxxx:xxxx:xxxx::xxxx:xxxx是本机的v6地址。</p> <p>这里贴一下我的配置,与帖子中的配置还是有几出不通的:</p> <p>server.conf:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">server 10.0.8.0 255.255.255.0 </span></span><span class="line"><span class="cl">topology subnet </span></span><span class="line"><span class="cl">server-ipv6 fc00:aaff:ffac::13:0/64 </span></span><span class="line"><span class="cl">port 10666 </span></span><span class="line"><span class="cl">proto tcp </span></span><span class="line"><span class="cl">dev tun </span></span><span class="line"><span class="cl"># 这里修改了这一条,要不v4老不通 </span></span><span class="line"><span class="cl">push &#34;redirect-gateway autolocal def1 bypass-dhcp&#34; </span></span><span class="line"><span class="cl">push &#34;topology subnet&#34; </span></span><span class="line"><span class="cl">push &#34;dhcp-option DNS 114.114.114.114&#34; </span></span><span class="line"><span class="cl">push &#34;dhcp-option DNS 8.8.8.8&#34; </span></span><span class="line"><span class="cl"># 加入了v6的DNS </span></span><span class="line"><span class="cl">push &#34;dhcp-option DNS 2001:da8::666&#34; </span></span><span class="line"><span class="cl">push &#34;dhcp-option DNS 2001:4860:4860::8888&#34; </span></span><span class="line"><span class="cl">push &#34;ping 5&#34; </span></span><span class="line"><span class="cl">push &#34;ping-restart 30&#34; </span></span><span class="line"><span class="cl">keepalive 5 30 </span></span><span class="line"><span class="cl">duplicate-cn </span></span><span class="line"><span class="cl">persist-key </span></span><span class="line"><span class="cl">persist-tun </span></span><span class="line"><span class="cl">group nogroup </span></span><span class="line"><span class="cl">user nobody </span></span><span class="line"><span class="cl">tls-auth ta.key </span></span><span class="line"><span class="cl">ca ca.crt </span></span><span class="line"><span class="cl">cert server.crt </span></span><span class="line"><span class="cl">key server.key </span></span><span class="line"><span class="cl">dh dh2048.pem </span></span></code></pre></td></tr></table> </div> </div><p>client.conf</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">clients </span></span><span class="line"><span class="cl">proto tcp </span></span><span class="line"><span class="cl">dev tun </span></span><span class="line"><span class="cl">verb 3 </span></span><span class="line"><span class="cl">remote x.x.x.x 10666 tcp </span></span><span class="line"><span class="cl">keepalive 10 60 </span></span><span class="line"><span class="cl">route 0.0.0.0 0.0.0.0 net_gateway </span></span><span class="line"><span class="cl"># 新加了这一条 </span></span><span class="line"><span class="cl">route-ipv6 ::/0 net_gateway </span></span><span class="line"><span class="cl">script-security 2 </span></span><span class="line"><span class="cl">ca ca.crt </span></span><span class="line"><span class="cl">cert client.crt </span></span><span class="line"><span class="cl">key client.key </span></span><span class="line"><span class="cl">tls-auth ta.key </span></span></code></pre></td></tr></table> </div> </div><h1 id="效果">效果</h1> <p>可以使用IPv6访问google, ytb, 网速感人。</p> <p>tracert发现第一调是自己的server,而且通过<a href="http://ip.sb/">ip.sb</a>查看到的IP也是server的IP。</p> 病了 https://strrl.dev/post/before-2022/%E7%97%85%E4%BA%86/ Sun, 06 May 2018 02:48:55 +0000 https://strrl.dev/post/before-2022/%E7%97%85%E4%BA%86/ <p>估计是食物中毒了,5月3号吃了小面和烤冷面</p> <p>估计是烤冷面的问题</p> <p>4号一天吐了好多次,吐到喝水都吐,而且疯狂胀气</p> <p>5号好多了,但是还是胀气</p> <p>媳妇去医院看姐姐,带回来了面包 好吃 吃了胃里难受</p> <p>想吃肥宅快乐桶,肥宅快乐饼</p> <p>好累</p> <p>论文还要改</p> <p>不过项目总算是成功运行了</p> <p>心累</p> <p>现在就挺想跟媳妇出去旅游的 吃吃喝喝 看看风景</p> <p>但是不知道为什么白天就不想去</p> <p>唉</p> <p>还要自己写commit message。。</p> <p>我决定要在苏菲上装tim vscode node了。。。</p> <p>唉 “生产力工具”</p> 熬夜太多了 https://strrl.dev/post/before-2022/%E7%86%AC%E5%A4%9C%E5%A4%AA%E5%A4%9A%E4%BA%86/ Fri, 27 Apr 2018 03:43:55 +0000 https://strrl.dev/post/before-2022/%E7%86%AC%E5%A4%9C%E5%A4%AA%E5%A4%9A%E4%BA%86/ <p>已经连续熬了五天夜了,感觉有点不舒服了</p> <p>明天把初稿交掉,再也不熬夜了!</p> <p>emmmm,第一次直接拿在线的编辑器写博客,想想有点小激动呢。</p> <p>不过估计下次再写的时候肯定会忘记pull,哈哈哈哈哈哈哈哈哈。</p> Surface Pro 重装系统 https://strrl.dev/post/before-2022/surface-pro-%E9%87%8D%E8%A3%85%E7%B3%BB%E7%BB%9F/ Mon, 23 Apr 2018 21:42:58 +0000 https://strrl.dev/post/before-2022/surface-pro-%E9%87%8D%E8%A3%85%E7%B3%BB%E7%BB%9F/ <h1 id="记录一次作死的经历">记录一次作死的经历</h1> <p>由于 Surface 自带的是 Home 版系统,淘了一个码子然后升到了 Pro。</p> <h1 id="作死开始">作死开始</h1> <p>升级到 pro 后发现不能跑 wsl,然后去 msdn 下了个 win10。</p> <p>导致了 <strong>OEM 信息丢失</strong>,触控笔无法调节力度,Surface 应用也都不到序列号</p> <h1 id="开始修复">开始修复</h1> <p>只好又从官网用恢复镜像重新做。</p> <p>过程中由于过于自信直接去 diskpart 执行了 clean。</p> <p>官方的 1709 死活没有办法点重置,只好用 1703 版本。</p> <p>1703 版本成功安装,升级到 1709,可以食用了。</p> <p>再也没有烦人的补丁安装失败提示,WSL 也能用了。</p> <p>PS: 最主要的还是 OEM 信息回来了,令人怀念的 Surface 标识。</p> <p>前前后后折腾了两天一夜,心累。</p> First Blood https://strrl.dev/post/before-2022/first-blood/ Fri, 13 Apr 2018 15:53:47 +0000 https://strrl.dev/post/before-2022/first-blood/ <p>拖了太久了,终于有时间搞一搞自己的blog。</p> <p>主要原因还是在踩坑的过程中,感觉应该把过程记下来。</p> About https://strrl.dev/about/ Fri, 01 Nov 1996 21:57:48 +0800 https://strrl.dev/about/ <p>I realized that when I go to open someone&rsquo;s blog, I want to get to know that person spontaneously.</p> <p>And reading the &ldquo;About&rdquo; section is the most direct way to get to know someone. So I decided to write a little bit about myself.</p> <p>Hi, I&rsquo;m ZHOU Zhiqiang(周志强), my online ID is usually <code>STRRL</code>/<code>strrlthedev</code>. My email is <code>echo &quot;YmxvZ0BzdHJybC5kZXYK&quot; | base64 -d</code>.</p> <p>This site was built for recording my thoughts and notes. I haven&rsquo;t thought about what to provide for otherwise. If it helps you, it&rsquo;s really a coincidence.</p> <p>There would not lots of technical articles here, but I will put some of the things I am interested in or researching recently. I will also update the Weekly Reports irregularly. Occasionally, I will also put some solutions to the problems I encountered in daily computer usage (<code>reproduction times &gt;= 3</code>).</p> <p>There is my career path:</p> <ul> <li>Currently working at <a href="https://layerzero.network">LayerZero</a>, as an SRE. LayerZero is an omnichain interoperability protocol designed to connect blockchains seamlessly.</li> <li>Previously worked at <a href="https://gitroll.io">GitRoll</a>, as a software engineer. GitRoll helps evaluate the professional skills of developers by analyzing their code on GitHub, build a bridge between developers and companies.</li> <li>Previously worked at <a href="https://github.com/naturalselectionlabs">Natural Selection Labs</a>, as DevOps. But I found I am lost in web 3 so I choose to leave. I still keep passion on blockchain and web 3, but I need to learn more.</li> <li>Previously worked at <a href="https://limit.dev">Limit LAB</a>, as backend engineer &amp; DevOps. Also exploring as indie developer at <a href="https://boringboring.design/">Boring Design</a>.</li> <li>Previously worked at <a href="https://reddio.com">Reddio</a>, as a software engineer. I helped build SDKs for the Reddio platform, like Rust, Java, Unity/C#, iOS/Swift, and so on.</li> <li>Previously worked at <a href="https://pingcap.com">PingCAP</a>, as a member of the <a href="https://chaos-mesh.org/">Chaos Mesh</a> team, responsible for the development of the chaos engineering platform. Company would die, long live with Open Source!</li> <li>Before that, I worked as an SRE at <a href="https://weidian.com">Weidian</a>, a e-commerce company in China.</li> <li>A little more earlier, I was a SWE at <a href="https://www.bsfit.com.cn/">Bangsun Technology</a>, a startup company in China, majoring in streaming processing, big data, and decision flow.</li> <li>The main languages I use are Java, Go and TypeScript. I would explore more area with Kotlin, Swift, Rust.</li> </ul> <p>My <a href="https://strrl.dev/resume/Zhou_Zhiqiang_Resume.pdf">Resume</a>, <a href="https://strrl.dev/resume/Zhou_Zhiqiang_Resume__Chinese_.pdf">Resume in Chinese</a>.</p> <p>Ask Me Anything: <a href="https://cal.com/strrl/30min">https://cal.com/strrl/30min</a></p> 41382542902990923 41816203929818112