作者: meathill

  • 升级 Sentry 自主部署实例

    升级 Sentry 自主部署实例

    Sentry 使用日历版本(CalVer)生成版本号,即按照特定时间来发布版本,比如今年是 2022 年,在刚刚过去的 10 月份,他们就发布了 22.10 版本。按照这种方式,很快 22.11 也会发布。

    每个版本都会有一些问题修复、新功能添加。而且,作为一个错误管理平台,里面存储数据,很多都跟我们的代码有关,所以我们也很关注它的安全问题。所以,我建议大家及时升级到新版本。

    按照 Sentry 的设计,升级其实很简单:

    1. 下载最新版本:https://github.com/getsentry/self-hosted/releases/
    2. 解压缩到目标文件夹
    3. 执行 ./install.sh 即可

    不过考虑到 清理 Sentry 磁盘占用 时需要安装 pg_repack 插件,这个过程实际要复杂一些。否则,可能会安装失败,到时候,恢复也很麻烦。

    升级 Sentry self-hosted 实例

    停用 pg_repack

    • 进入 sentry 配置目录,对于我来说,就是 ~/sentry
    • 登录 Postgresql 容器:sudo docker compose exec postgres bash
    • 之前我们已经装过 vim,所以不用再装。否则话,需要先安装一个文本编辑器:apt update && apt install vim
    • 修改配置:
      • su postgres
      • cd $PGDATA
      • vim postgresql.conf
      • shared_preload_libraries = 'pg_repack' <– 找到并注释这一句
      • 保存并退出 wq
    • 进入 postgresql shell:psql postgres
      • psql postgres
      • 执行 SQL:DROP EXTENSION pg_repack;

    更新配置文件

    • 下载新版本之后,解压缩到新目录 sentry_new
    • 备份之前的配置文件,对于我而言,需要备份三个文件:
      • ~/entry/docker-compose.yml 里面关于 Kafka 的配置
      • ~/sentry/sentry/config.yml 里的邮箱配置
      • ~/sentry/sentry/sentry.conf.py 最后面的其它配置
    • sentry_new 复制到原本的 sentry
    • 将备份的配置复制回去

    安装新版本

    接下来安装新版本:sudo ./install.sh

    安装脚本会自动停止服务,然后拉新的镜像,然后部署新的容器。这个过程会持续一段时间,与网络状态、机器性能都有关,需要提前做好准备。

    这个过程如果断开连接,会出错失败。所以建议用 screentmux 等工具保持进程运行。

    安装成功后,正常启动服务即可:sudo docker compose up -d,然后就可以使用新版本的 Sentry 了。

    清理老的镜像和容器

    一般来说,这个过程不是很必要,至少不用每次升级都做。为了避免未来的使用问题,可以先留一阵子,我建议最多清理一年前的残留镜像和容器。

    (过程方法待补充)

    常见更新失败及解决

    container for service "postgres" is unhealthy

    这就是我前面说到的原因:因为事前在 Postgresql 容器里启动过 pg_repack 插件,升级之后的容器里并没有这个插件,但因为继承了以前的存储卷(Volume),所以启动容器时还是会查找这个插件,因为容器里没有,就挂了。

    解决方案是:

    1. 回滚到之前的版本,其实就是把比老版本配置文件拷回来
    2. 因为我们并没有清理镜像和容器,所以此时老版本是可以正常启动的
    3. 不用完全启动,启动 postgresql 即可:sudo docker compose start postgres
    4. 然后登入 postgres 容器,执行前面的操作,清理 pg_repack 插件
    5. 退出并关闭 postgres 容器
    6. 重复上面的新版本安装过程

    总结

    作为一名土前端,我对 docker 不太熟悉,对 Kafka、Postgresql 也知之甚少。使用 Sentry 之后,迫不得已必须学习很多新知识,我觉得很有意思。如今我已经尽量使用 Docker Desktop 去使用和管理一些软件,我觉得很方便。接下来好好学习,争取把 Docker 生态的工具也为我所用。

    如果你有任何问题、建议,欢迎留言讨论。

  • 聊聊前端入门(1):HTML+CSS

    聊聊前端入门(1):HTML+CSS

    最近有一些新老同学入门前端,找我问问题,我从他们身上发现了一些共性问题,今天拿出来总结一下,希望后来者能吸取经验。

    前端三大件:HTML、CSS、JavaScript。这三位是根本,万变不离其宗,不管用多先进的技术,最终浏览器里跑的还是他们(不考虑 WASM、WebGL)。所以前端入门应该以这三种语言为基础,慢慢扩展到其它领域。

    当然有些同学可能上来就用框架,拜现代化前端技术所赐,有些同学可能完全没认真学习过这三门语言,也怼出了功能、甚至怼出了产品。但我建议,无论从上限考虑还是从下限考虑,都应该好好学习这三门语言本身。

    声明式语言

    入门一般都从 HTML、CSS 开始,因为它们很简单,简单的原因是因为它俩是声明式语言。那什么是声明式语言呢?标准定义咱们略过不谈,简单来说有两大特点:

    1. 需要什么你就写什么,需要这里有一个文字,那就写一个文字;需要有一张图片,就写一张图片。
    2. 不写的就不会出现。没有逻辑推演、计算,不会因为环境变量而有所不同,没写的就没有。

    于是它们有好处也有坏处:

    • 好处:没有心智负担,不用理解全局,就看某一行、某一段,写了就是有,没写就是没有。
    • 坏处:需要 100 个字就要写 100 个字。有 100 个元素共用一个属性,可能也要写 100 遍。

    如何学习 HTML+CSS

    有些同学上学期间学过编程,比如 C 语言、Java 语言。它们都是命令式语言,有更强的逻辑性,它们就像一本推理小说,你必须从头看到尾,不漏过一个线索,层层推理,才能得到结论。

    他们会套用自己在命令式语言方面的经验去学习 HTML+CSS,然后发现,好难……命令式语言的语法元素很少,难在组合出合适的逻辑、设计合适的数据结构。声明式语言能实现的效果总数是固定的,没有预先设计的部分,就是实现不了,谁都实现不了。但是每种效果的实现可能都是不同的,需要大量经验和记忆。用上一段的类比,声明式语言就像诗歌,甚至上一行跟下一行都没联系,但是连到一起还真有点意思。

    所以学习 HTML+CSS 就要有合适的方法。我个人的经验如下,

    1. 首先要知道

    HTML 标签 100+,CSS 属性 200+,这些都是知识性的内容,不知道就是不知道;不知道但是要用,那就做不出来。所以第一步是知道这些内容,方法大概是:

    1. 浏览文档,比如 MDN
    2. 自己实验,加深记忆和理解
    3. 跟背单词一样,要经常性重复这个过程,才能真的记住

    这个过程不需要了解的很透,重点在于知道这些标签和属性的存在,当你面对需求的时候,才会想到解决方案。

    2. 接下来要多尝试

    经常浏览 codepen.io 这样的网站,上面有很多别人做的范例,可以长很多见识,让你恍然大悟,原来可以这样做那个东西。

    同时,也可以反过来用看到的范例指导自己的学习。比如,看到一个 css 规则,这个你刚好不熟悉,就可以找来文档仔细阅读理解一下,或者在论坛上询问其他前辈。

    一段时间之后,相信你会对大部分 html、css 属性都了如指掌,看到人家的网站,也大概知道该怎么做。但是给你一个实际项目,你可能还做不出来,或者做不好。没关系,那是下一步的目标。

    3. 紧跟社区步伐

    跟其它语言不一样,声明式语言从诞生开始,语法上不会有太大变化,语法元素也很固定。升级换代主要来自增砖添瓦,即新规则、新属性。

    比如 CSS,早年我们布局只能依靠 float。很难用,有各种诘屈聱牙的概念需要记忆。后来就有了 display:flex,也就是弹性盒模型,好用的多。后来又有了网络布局。然后因为各种内部弹性外部弹性,又有了 min-contentmax-contentfit-content 等新属性。

    这些东西,很新,有时候没有办法找到合适的学习资料。于是就要紧跟社区来,通过技术账号了解到新知识,通过技术文档学习新知识。

    4. 突破自己

    自学里面,最难的一件事其实就是突破自己。就好像我今天看到一个帖子,楼主说准备找到工作后就办张健身卡去健身,然后下面一群人歪楼,说“为什么健身要办健身卡?”

    因为自己监督自己很难,自己给自己打分更难。所以学校才要安排各种考试,给学生打分,让大家知道自己的位置。

    所以,做出来自己看觉得还行,没有用。这里有几个建议:

    1. 瞄准一个产品,比如微信,做到像素级复制。可以截图然后调到 50% 透明度,叠到一起慢慢看。
    2. 选择最合适的技术,坚持到底,不要因为某些环节难以突破就乱来。
    3. 邀请比较有经验的前辈帮自己做 code review

    附加:最好找个靠谱的前辈做引路人

    (我想了想还是把这条加上。)

    互联网是个好地方,我们能免费获取几乎所有有价值的资料。但是对于 Web 开发、前端开发这种领域,长期积累的海量知识储备也可能成为大家学习的障碍——东西太多,不知道从何处下手。

    所以,有个靠谱的引路人也很重要,会帮你节省很多时间。笔者不才,亦好为人师,有需要的可以找我:

    新人常犯的错误

    新人难免会犯错,这里列举一些常见的、可以规避的问题:

    1. 沉迷细节无法自拔

    有些同学沉迷细节,喜欢抠字眼,经常会提出一些奇奇怪怪的问题。很多问题其实没有准确答案,也不需要准确答案,尤其是对于新人来说,可能三两年内都不会真的需要解决。

    尤其是 HTML、CSS,因为是声明式语言,很多时候,它们的行为就是这么设计的,不需要也没办法深究;有些设计,可能来自二十年前甚至更早,现在早已没有那个应用场景,新人难以理解也是正常的。

    所以我建议大家以记用法积累经验为主,辅以实操验证,不需要像学命令式语言那样去强迫自己理解。

    2. 遇到问题生拼硬凑

    有些同学遇到问题就发慌,然后开始百度,看到一个方案就复制粘贴试一试,能行就继续,不能行就复制粘贴下一个。结果代码就补丁摞补丁,各种解决方案混合在一起,毛病越来越多。到最后可能完全超出掌控、无法解决。

    这里大家需要明白,语言元素很多,组合方式也很多。同样的问题,可能来自不同的根源;类似的组合,也会产生不同的问题。绝大部分时候,我们都要先选择方案,然后围绕方案组织代码,解决遇到的问题。在不同方案间左右横跳,最后结果多半不是好处均沾,而是问题集中爆发。

    如果能够找到最佳实践,那就坚持。如果几个方案都差不多,那就选好一个,坚持下去。遇到问题,面对多个搜索结果,要分析它们是怎么做的,解决了什么问题,不要直接拷过来试。坚持一段时间,会有很好的结果。

    总结

    我当年也是自学成才,走过不少弯路,希望这系列分享能帮大家节省一些时间。

    有任何问题和建议,欢迎留言评论。下次聊聊 JS 方面的学习。

  • Turbopack 发布后的各方反应:Vite/Webpack/围观群众

    Turbopack 发布后的各方反应:Vite/Webpack/围观群众

    上周整理了一下 Turbopack 发布后的各方反应,以便让自己和各位同学下一步做决策的时候能有所参考。接着忙碌的一周过去,我发现博客这周还没更,于是赶紧来补一下。

    0. TL;DR

    1. Turbopack 的宣传语更多还是“宣传”,实际效果提升并没有那么巨大。
    2. Turbopack 目前只支持 Next.js + React,且没有建立健全插件机制,所以没有生态可言,如果我们的主要开发环境不一致,可能暂时用不到。
    3. Turbopack 基于 Rust 开发,性能提升主要来自 SWC,所以有时间、有兴趣的话,直接使用 SWC 替换编译工具就好。
    4. 非目标开发者群体建议先不考虑迁移。
    5. Turbopack 对于打包过程有不小的改进,值得持续关注。
    6. 如果你日常使用 React,且想在新技术出现时斩获先机,早点动手也挺好。

    2022-10-26

    首先,10月26日,Vercel 发布了 Turbopack,自命 Webpack 继任者,号称速度比 Wepback 快 700 倍,比 Vite 快 10 倍。

    这些是官推亮点:

    • ~700x faster than Webpack -> 比 Webpack 快 700 倍
    • 10x faster than Vite -> 比 Vite 快 10 倍
    • Native incremental architecture built with Rust -> 基于 Rust,具备原生可增长架构
      ◆ Support for React Server Components -> 支持 React 服务器组件
      ◆ Support for TS, JSX, CSS & more -> 支持 TS、JSX、CSS,以及更多

    尤大观点

    很快,Vite 作者 @youyuxi 就跟进表达反驳:

    “10x faster than Vite” isn’t entirely accurate

    “‘比 Vite 快 10 倍’并不完全准确”,他说。

    然后他进一步介绍了自己的理由:

    1. Vite’s default React HMR is still babel-based, while Next/turbopack use swc/rust-based transform, so the HMR performance difference is a bit of apples to oranges.

    因为 Vite 默认的 HMR 仍然基于 Babel,而Next/Turbopack 使用的是基于 Rust 平台的 SWC,所以这里 HMR 的性能差异是关公战秦琼(这个 thread 后面还有若干理由,我就不一一翻译了):

    Vite can switch to the swc/rust transform if necessary, we currently chose not to do that because adding swc to the deps list is extra weight, and even without it HMR is fast enough.

    Vite 当然可以在必要时切换到 swc/rust,但 Vite 开发团队并不想这样做,因为即使只用 Babel(不那样做),HMR 也足够快。使用 SWC 替换 Babel 只是平添开发负担。

    1. turbopack does address Vite’s request congestion issue on large apps. On Vite side we are also exploring how we can solve this via upcoming browser features like web bundles.
    1. Turbopack 确实解决了 Vite 在大型应用上的请求拥塞问题。我们 Vite 团队这边,也在探索如何解决这个问题,比如,是否可以借助即将推出的浏览器功能(Web Bundles)。

    In the long run we may also consider using turbopack under the hood to replace esbuild/Rollup (where suitable), due to its strong caching capabilities.

    1. 从长远来看,由于 Turbopack 强大的缓存能力,我们也会考虑在底层使用 Turbopack 来替换 esbuild/Rollup。如果合适的话。
    1. I’m glad vercel is investing its resources into a proper native-speed successor to webpack (as it should), and that our work on Vite has pushed this to happen. It’ll be interesting to see how it evolves – my hope is it can be made truly framework agnostic, not Next-first.
    1. 我很高兴 Vercel 愿意投入资源,打造 Webpack 的继任者,并着力提升它们的速度表现(应该如此),我们在 Vite 上的努力也达到了这样的目的。我对它们未来的演变很感兴趣——我希望它不要和框架捆绑在一起,不要 Next-first。

    Sean Larkin 观点

    (Sean Larkin 是 Webpack 的核心团队成员。目前好像在 LinkedIn 工作,好像。)

    Sean Larkin 也表达了自己的观点:

    Few thoughts: 几点想法:

    1. Love the innovation but it looks moderately SWC powers and wish there was some more callout there.
    2. Disappointed how entangled this is with next/turborepo. But Vercel needs to make.
    3. The path of migration from webpack for the avg user will be hard.
    4. I like that the dev server is still bundling modules because ESM slower than raw ESM. I need to peel back more layers to try and get a standalone implementation working.
    5. It’s all in alpha so we need to still look at the broader view but I hope we’re selling less going fwd
    1. 我喜欢创新。但看起来,Turbopack 更多是借力于 SWC,希望对方能表达得清楚一些。
    2. 我对 Turborepo 与 Next 的绑定程度感到失望。但是 Vercel 需要挣到更多的 (天使资金),没办法。
    3. 普通用户想 Webpack 迁移过去,会很艰难。
    4. 我倾向于开发服务器上的模块仍然是打包后的,因为 ESM 比原始 ESM 慢。我需要剥离更多层,才能让独立的实现工作。
    5. 目前它还处于 alpha 阶段,所以我们要看开一点,但我仍然希望,销售手腕少一些,好好干开发。

    2022-10-27 ~ 2022-10-28

    这段时间,@youyuxi 觉得 Turbopack 的数据有问题,因为 Vercel benchmark 的设计有问题,于是他尝试调整测试方式,给出了一些数据。不过后来他删除了这些推文,因为数字不太对。

    2022-10-27

    Vite 核心成员之一,@antfu7 在知乎上表达了自己的观点:

    他认为 Vite 更吸引人的是其插件系统,和构建在上面的生态系统。这样才能将改进快速带给其他领域。Turbopack 方面,静观其变吧。

    https://zhihu.com/question/562349205/answer/2733040669
    如何评价Vercel开源的使用Rust实现的Turbopack? – Anthony Fu的回答 – 知乎

    2022-10-29

    经过几天实验,Vite 作者 @youyuxi 发表了新的推文,新推文介绍了他进一步比较 Turbopack 和 Vite 之间性能之后,得到的新结论。

    I updated the vite vs next/turbo benchmark by using swc to transform React refresh for vite. To avoid confusion, I have deleted the previous two tweets with outdated numbers.

    Latest numbers:

    • root: vite 338.2ms / next 334.6ms
    • leaf: vite 141.8ms / next 84.4ms

    我通过搭配 Vite+SWC,重新评测 React 转换之后,更新 Vite vs Next/Turbopack 的基准测试。为避免混淆,我删除了前两条带有过时数字的推文。

    最新的对比数字:

    • 根:Vite 338.2ms / Next 334.6ms
    • 叶:Vite 141.8ms / Next 84.4ms

    The swc transform helps a lot in the root component case because the file is big, and previously cost 300ms in babel transforms alone. This makes vite almost exactly the same speed with turbopack.

    SWC 转换在根组件时候提供了很大帮助。因为文件很大,以前仅在 Babel 中转换就要花费 300 毫秒。替换之后,Vite 的速度几乎与 Turbopack 完全相同。

    Interestingly, in leaf scenarios turbopack is still 69% faster – this entails that Vite HMR actually caught up with turbopack as the file gets bigger, potentially scaling better in larger apps.

    有趣的是,在叶子场景中,Turbopack 的速度仍然更快,提升约有 69%。——这意味着随着文件变大,Vite HMR 实际上赶上了 Turbopack,在较大的应用程序中可能会有更好的扩展性。

    测试用仓库:https://github.com/yyx990803/vite-vs-next-turbo-hmr

    Because we are now testing the HMR of the same framework with the same set of transforms, the result is more relevant for other frameworks compared to previously posted numbers.

    现在,因为我们使用相同的转换集测试同一框架的 HMR,与之前发布的数字相比,结果的相关度更高。

    Just to add a bit of context – in this benchmark, even before using swc for React transforms, turbo is only 2x compared to vite (compared to marketed 10x). So the difference wasn’t that drastic to begin with.

    顺便讲点相关前提:这套基准测试,甚至在替换使用 SWC 转换 React 之前,与 Vite 相比,Turbo 也会仅 2 倍(他们市场宣称要快 10 倍)。所以其实一直以来,差异都没有那么大。

    2022-10-31 及之后

    本文主体整理于 10 月 31 日,之后 @youyuxi 还在孜孜不倦的跑 benchmark,与各路支持、反对、吃瓜者或讨论或争论。但是他的观点变化不大,所以我也就偷懒不继续翻译了,相信大家看完都能做出自己的判断。

    N 神有一些观点,摘录于此:

    vite 为了提升速度,利用了浏览器的特性,在 dev 阶段不打包而用 esbuild 预编译 esm 小包投送给浏览器, 在 build时候用 rollup 再打包。这样 dev 就会非常快(因为无需打包),但写插件就很分裂,要考虑 dev 和 build 两种情况。并且理论上如果依赖小包过多会肯定会遇到浏览器并发瓶颈减慢速度。

    按 Turbopack 的说法,他 dev 和 build 同样走打包流程,还能比 vite 快,那么铁定是更好的。只是太早期了,现在还没有开放插件生态。而且自命 webpack 继任者没毛病,看 github 上就是 webpack 作者主力搞的。

    但另一方面如果未来 non-bundler 成为主流,前端不再需要打包。turbopack就没用了。vite 抛弃 rollup,build 也走 dev 流程就更美了。

    https://twitter.com/nshen121/status/1587333382362763264

    SWC 作者和 Webpack 作者

    这二位目前都在 Vercel 工作,可能受公司公关限制,都只转发了官推,并没有发表更多意见。


    总结

    Turbopack 可能不如官方所说的那么好。它的确带来了 HMR 的提升,但代价是不健全的插件机制和生态环境,以及难以被前端团队掌握的 Rust 平台。

    未来一段时间,我们还要继续坚持在 Vite 平台上。

  • Sentry 清理磁盘经验分享

    Sentry 清理磁盘经验分享

    Sentry 使用一段时间之后,磁盘占用非常厉害,普通云服务器初始的 40/50G 云盘完全不够用,所以就得定时清理维护。

    通过阅读一些相关技术文档(见后),我们知道:

    • Sentry 使用 Postgresql 存储数据
    • Sentry 使用 Kafka 存储上传的日志
    • Kafka 默认的硬盘操作策略比较粗放,会占很多空间
    • Postgresql 也会存很多数据

    其实 Sentry 里的历史数据的价值不大:上周上报的错误,处理完也就没用了,我们可以放心大胆地把它们清理掉。Sentry 也提供了一些方案,大概来说两条:

    1. 限制 Kafka,让 Kafka 自动清理
    2. 清理 Postgres

    经过实践,我发现官方网站有一些内容不太具体;而因为历史悠久,网上信息噪音太多,所以我当时也折腾了不少时间。今天把经验分享出来,希望对大家有用。

    限制 Kafka 磁盘用量

    这个部分比较简单,我们有很多方案,目前我是把配置添加到 docker-compose.yml Kafka 的环境变量里,内容如下:

    kafka:
      environment:
        KAFKA_LOG_RETENTION_HOURS: "24"
        KAFKA_LOG_RETENTION_BYTES: "10737418240" # 10G
        KAFKA_LOG_SEGMENT_BYTES: "1073741824" #1G
        KAFKA_LOG_RETENTION_CHECK_INTERVAL_MS: "300000"
        KAFKA_LOG_SEGMENT_DELETE_DELAY_MS: "60000"

    这样做的坏处是必须重新部署环境才能生效。也可以修改 .env 文件,我没试过,所以略过不提。

    删除 Postgres 的老数据

    官方只说了这两句,清理掉 7 天之前的数据,然后使用 pg_repack 热重建 Postgres 的索引,即可。命令如下:

    // 在 web 容器里执行 `cleanup` 命令清除 7 天前的数据
    docker-compose run -T web cleanup --days 7 -m nodestore -l debug
    
    // 在 postgres 容器里使用 pg_repack 重建索引
    docker-compose run -T postgres bash -c "apt update && apt install -y --no-install-recommends postgresql-9.6-repack && su postgres -c 'pg_repack -E info -t nodestore_node'"

    实际我在操作时遇到不少问题。经过摸索,更完整的过程是这样的:

    1. docker-compose => sudo docker compose

    docker-compose 是 1.x 版本,我厂安装的是 docker + docker-compose-plugin,即 2.x 版本,所以不能使用 docker-compose,要用 docker compose。且因为云服务器的默认用户不是 root,所以一定要加 sudo

    2. 安装 pg_repack 插件

    安装配置好 Sentry 之后,要安装 pg_repack 和配置插件。

    # 登录 Postgres 容器,现在的云服务器,默认用户应该都不是 root,所以要注意加 sudo
    $ sudo docker compose exec postgres bash
    root@f615d8742634:/#
    
    # 安装 pg_repack 插件,同时,为编辑文件,需要安装 vim
    root@f615d8742634:/# apt update
    root@f615d8742634:/# apt install -y --no-install-recommends postgresql-9.6-repack
    root@f615d8742634:/# apt install vim
    
    # 切换到 postgres 用户
    root@f615d8742634:/# su postgres
    # 验证一下 pg_repack 插件
    postgres@f615d8742634:/$ pg_repack --version
    pg_repack 1.4.7 # 返回这个就是成功了
    
    # 将 pg_repack 加入 Postgres 启动配置
    postgres@f615d8742634:/$ cd $PGDATA
    postgres@f615d8742634:~/data$ vim postgresql.conf
    shared_preload_libraries = 'pg_repack'
    :wq!
    
    # 将 pg_repack 在仓库里注册
    postgres@f615d8742634:~/data$ psql postgres
    psql (9.6.24)
    Type "help" for help.
     
    postgres=# CREATE EXTENSION pg_repack;
    CREATE EXTENSION
    postgres=# \dx
                                      List of installed extensions
       Name    | Version |   Schema   |                         Description                          
    -----------+---------+------------+--------------------------------------------------------------
     citext    | 1.3     | public     | data type for case-insensitive character strings
     pg_repack | 1.4.7   | public     | Reorganize tables in PostgreSQL databases with minimal locks
     plpgsql   | 1.0     | pg_catalog | PL/pgSQL procedural language
    (3 rows)
     
    postgres=# \q

    最后,记得要重启容器才能生效:sudo docker compose restart postgres

    2. 执行清理

    可以按照官方建议,使用 sudo docker compose run,不过我一般会登录到 Postgres 容器,然后手动执行清理。

    $ sudo docker compose exec postgres bash
    root@f615d8742634:/# su postgres
    postgres@f615d8742634:/$ pg_repack -E info -t nodestore_node

    后续注意事项

    这样操作之后,会产生一个新问题:升级镜像之后,因为新镜像没有 pg_repack 插件,所以可能会无法启动。所以记得升级 sentry 前先把插件移除。

    方案基本相当于前面的逆操作:

    1. postgresql.conf 里移除配置
    2. 从数据库中移除插件

    具体命令就懒得敲了,兴许下次升级吧。


    如果各位读者老爷有关于 Sentry 的问题,敬请留言;有任何经验要分享也非常欢迎。希望这篇文章对大家有帮助。


    参考文档:

  • TiDB Hackathon 2022 参赛小记

    TiDB Hackathon 2022 参赛小记

    今年的 TiDB Hackathon 来的比去年早一些,赶在 1024 前举行。去年我参加 TiDB Hackathon 2021 之后,感觉非常好:组织给力、参赛选手水平高、技术分享氛围好,能学到很多东西。于是今年毫不犹豫,再次报名参加。

    我其实一直想搞个移植类的项目,把某个能用但不够好用的项目移植到 TiDB 上,得奖倒在其次,主要是为了将来自己用或者给别人用。但是我也知道,这类作品的技术含量有限,除非做得很好或者很有特点,否则多半连决赛都很难入围。于是我韬光养晦,卧底在群里,等待抱大腿的机会。

    然而,赛前创意脑爆会,CTO 黄东旭说了一些跟我很接近的想法——当然,也可能是我听错了,我当时一边搬砖一边开着直播,注意力不集中;后来我又听了一遍,没能找到印象中的那几点。

    本来想抱大腿,但是经历上次思否 Hackathon 之后,必须得说,哥们儿飘了,哥们儿觉得自己行了,哥们儿觉得自己也是个角儿了。于是我甩掉了前面已经蹭进去的队伍,拉大旗谋虎皮,邀请赋闲在家的竹子一起,组了自己的队伍,准备携余威再下一城。

    正所谓黄粱美梦,终有一醒。很快教训就来了。

    0. 开场 brief

    由黄东旭(TiDB CTO + CoFounder)演讲。

    TiDB 的诞生

    • 三个后端基建程序员,厌倦了分库分表的枯燥生活,决定造福大家。
    • 一腔热血+盲目自信,开始动手
    • Why TiDB?(自吹的部分省略,哈哈

    TiDB 的未来

    • From OLTP to HTAP
    • From SQL to API
    • From TiDB to TiDB-as-a-Service
    • From Infrastructure to Applications
    • From Code to You

    TiDB 近景展示

    基于云的高速动态 Scale 能力,把 TiDB 从数据库变成 end-point,让用户对底层无感,应该是未来的发展方向。

    1. 密集 coding

    开幕式结束后,各支队伍开始 coding。今年规定比较严,必须在入围决赛后才能写代码,杜绝有人拿一年的大项目 hackathon 上改个字体就参赛的行为。

    我们团队其实有一些前期的调研和摸索,比如我的 NocoDB + TiDB 实例很早就部署了,然后队伍的日常管理也在上面。不过事后来看,我们还是太轻敌了,各方面的。

    1. 行级权限控制(Row Level Security / Row Based ACL)

    首先我要确定 NocoDB 怎么支持行级权限控制,因为 idea 脑爆会上东旭有提到,所以得重视起来(面向 CTO 编程)。结果比较令人失望,NocoDB 并不直接支持类似 LeanCloud 那种 row based ACL。

    用一些比较复杂的方式似乎能够实现。比如:

    1. 生成主表
    2. 为用户创建不同的视图
    3. 用户通过特定表单提交信息

    总之这个方向进展不顺利。

    2. Vercel Template

    我们计划做的第二个东西(也是脑爆会上提到的),是 Vercel Template,即可以让用户在 Vercel 上一键部署实例的东西。

    临近中午,竹子找我说可能做不了,于是我赶紧去看。Vercel 本身主要提供静态内容托管,从 GitHub 拉纯前端仓库然后部署。后端服务只提供 serverless functions,支持文件路由映射。next.js 和 nuxt.js 不知道是主动还是被动,都提供了类似的方案去适配。

    NocoDB 前端是基于 Vue3+nuxt.js 打造的,所以并不难搞。困难的是服务端。我们面临两个选择:

    1. 手动把 API map 到文件路由(比如 /api/user => /api/user.get.js
    2. 直接用入口 js 作为 serverless function

    竹子开始尝试了方案(1),觉得可能超出 hackathon 的时间要求。我也觉得方案(1)不太靠谱,于是开始尝试方案(2)。由于依赖的问题、Vercel 的问题,我们一直折腾到凌晨 00:30,最终推翻了方案(2)……由于 serverless functions 的无状态特性,没有优化过的程序完全没法跑。

    3. SaaS

    最后我们只剩下来原本计划中 Nice to have 的功能:SaaS 平台。这个部分我们本来只想在 PPT 里提一嘴,算是对未来的展望,希望评委老师感兴趣。并没打算做,毕竟 hackathon 里俩人做 SaaS,怎么看也不靠谱,但是现在,这竟然是我们唯一可能的交付物了,真的是……

    当然完整交付是不可能的,我们的目标就是让评委相信我们能做出这样的东西来。

    其实说白了,这垂死挣扎,就是高考前,语文/英语老师说:“你们作文不会写,就把前面阅读理解打乱顺序抄一遍,不要空着!”,那个意思。

    2. 小转机

    没想到真的有转机,虽然不大。

    竹子 mock 了几个 API,仿真了在 Vercel 上使用 Template 部署应用的过程,录成视频,准备在 demo 的时候播。我一看,咦?反正都是模拟 API,我那儿(测试服)有现成的啊。这样一想,我整理出一个似乎还可以的想法:

    1. 部署 nocodb-gui
    2. 使用我的测试服作为 server API
    3. 完成演示

    这样可以演示一些效果,而且很容易带出来我们接下来要做的:基于 NocoDB+TiDB 的 SaaS。哎,昨天真是被 Vercel 部署消耗掉太多体力脑力了,竟然没想到这么直接的解法。

    3. 答辩

    其实事后想想,上面也称不上什么转机,顶多就算是把阅读题抄了一遍,只是稍微打乱了一下顺序。

    答辩时评委问我:你们这个有什么优势呢?有什么是你们做了,但别人难以做到的?扪心自问,其实没有。我甚至没来得及做 Vercel Integration。如果我们事先准备好,让用户能够通过 Vercel Integration 得到独立的 NocoDB Backend API 与 独立的 TiDB 实例,也许算是个完整的产品,但目前这个完成度,也就比交白卷强那么一丢丢。

    哎,打回原形,再次寄望于来年吧。

    4. 赛事组织点评

    TiDB Hackathon 的组织一如既往的给力。首先参赛过程非常舒服,纪念品诚意满满。CTO 的开场 brief 让人动力十足。后勤保障非常给力:包三餐、零食饮料下午茶管够;有些同学从外地来,想在公司打地铺,组委会也尽力帮忙满足。组委会还准备了一些活动,让大家能放松心情,加强交流,可惜我一直在跟 Vercel 搏斗,没空参加。哥们儿好歹也在 Just Dance 有 MegaDancer 的表现。

    哦对,美中不足,空调不够给力,只有风没有制冷。猜测是大厦周末不供冷,不能全怪主办方。

    这次我还动员了一些同学来参赛,不知道他们战果如何,希望比我好。相信他们也会收获颇丰。

    5. 其它收获和感想

    1. NocoDB 输入体验不行,但其它体验挺好,值得长期使用
    2. TiDB 的确挺快,developer tier 足够我现在的用量,准备继续白嫖下去
    3. 学会了 Vercel 生态的知识
      • deploy button
      • template
      • integration
      • deploy API
      • cli
    4. 新概念:HTAP

    总结

    今年的项目方向多半还是对的。降低用户门槛,提升产品可用性,应该是受主办方欢迎的方向。可惜我们选择的执行方式不够得当,可以帮用户薅羊毛,但要能薅到羊毛才行,目前这个方案,其实还有一段路要走。

    考虑到厂里年底要突击,姆伊用药助手 0.2 版本还没开始动工,以及其它一些开发需求,我估计会把这个项目放一放,先用着我的 NocoDB + TiDB 实例。等待时机,再动手折腾折腾。

    感谢 TiDB,举办这么棒的 Hackathon;感谢组委会,尽心尽力尽责,把活动办得这么好;感谢我老婆,给我放假让我在外面肝了两天代码;感谢竹子,跟我一起辛辛苦苦折腾半天,最后铩羽恶而归。生活还要继续,下周继续努力,大家一起加油。

  • Code for Better _ Hackathon 礼物返图

    Code for Better _ Hackathon 礼物返图

    时间过得真快,距离参加 2022 Code for Better _ Hackathon 活动已经过去一个月了。现在的我,除了等待发工资之外,也在等待奖金下发,毕竟已经下单好几个大件了……

    Anyway,这些天,参赛纪念品陆陆续续到位,周末闲来无事,拍几张图返给主办方吧。感谢各位的辛勤付出,方有这么好的写码机会。希望我们都再接再厉,明天又筑新辉煌。

    (更多…)
  • 喜获 Code for Better _ Hackathon 二等奖,简单复盘

    喜获 Code for Better _ Hackathon 二等奖,简单复盘

    2022 年 9 月 16 日,以 CODE FOR BETTER_ 为主题,以 2022 Google 开发者大会为契机举办的 Hackathon 大赛进行了线上颁奖仪式。多支优秀参赛队伍在赛程中展示了出色的开发能力,为心中所期待的美好生活,挑战开发潜能,探索代码塑造美好生活的多重可能,并最终获得一、二、三等奖及优秀奖,为本期 Hackathon 大赛画上圆满句号。

    ……

    roudan.io 团队的“姆伊用药助手”基于 Web 、ChromeOS 技术,通过 PWA (Progressive Web Application) 带来能够有效预防疾病、增强治疗效果的解决方案。

    代码构建美好生活:聚焦 Code For Better _ Hackathon 大赛的精彩与感动

    0. 创意来源

    时间倒退到一年前。我在张大妈上申请到一款智能药盒,试用之后,感觉并不满意:它只能提醒我几点几分吃药;但是很多药,尤其是糖尿病相关药物,并不是按时吃就可以的,必须根据吃饭的时间来调整。如果我吃饭时间不固定,那这款药盒的价值就会大打折扣。

    我也顺便试了试其它的 App,发现各家的想法都差不多,关注点主要在社交和家庭成员关怀上,而不是准确科学用药。毕竟前者有更大概率可以带来收入。

    于是我就想自己做一个产品,满足根据吃饭的时间来定时提醒的需求。我跟几位产品经理朋友聊过这个想法,可惜这几位朋友和那些做用药助手的产品经理一样,本身没有慢性病,没有这方面的需求,对慢性病药物也不是很了解,所以对我的想法一笑置之。

    1. 参加 Hackathon

    我与思否有一些渊源,日常活跃在 segmentfault.com,偶然看到 Hackathon 的招募信息。我一下就被这次 hackathon 吸引了:

    1. 线下活动,即日起到参赛日都可以写代码,对于我这种中年慢性病患者来说很友好;
    2. 使用 Google 技术,沾边就可以,对于我这种 Web 开发者来说,等于没限制;
    3. 主题是 Code for Better _,很明显,_ 的意思是大家自己来填,正好可以做前文的用药助手,非常切题。

    于是我立刻就报名了。十分坦率地说,我对获奖完全不抱任何期待,只想借助这个机会,把想象里的产品做出来。我也询问了之前的产品经理朋友,他们对 hackathon 兴趣寥寥,于是只能自组一队。

    我的参赛作品就是:姆伊用药助手。

    2. 技术选型

    首先,毫无疑问,这个产品要能运行在移动平台上。

    接下来,最重要的选择点是:推送和提醒。我国的移动环境比较难搞:Android 手机品牌太多,并没有统一的推送接口;苹果倒是有,但是市占率太有限;因为超级应用微信的存在,微信小程序和公众号的到达率比较理想,但是实际运营都需要公司实体,作为 hackathon 作品太重。

    想来想去,我打算试试 PWA。我的考虑是:

    1. 浏览器大部分基于 chromium 内核二次开发,PWA 可以近似认为全普及
    2. PWA 基于 service worker,保活能力应该强于普通应用
    3. PWA 一贯是 Google 主推的技术,符合参赛题目

    于是,我准备基于 PWA notification API 实现功能。

    3. 开发

    开发的过程就比较平淡。前面说了,我其实没打算得奖,目标就两个:

    1. 做出自己想要的产品
    2. 体验 PWA Notification API

    于是我选择 Vite + Vue3 + TailwindCSS 作为前端框架,利用晚上下班后的时间,开直播写了大概 4、5 个小时,就初步完成了计划的功能。代码在这个仓库:meathill/muidicine: 姆伊用药助手 (github.com),大家有兴趣可以看下。

    比较遗憾,因为时间关系,还没找到合适的 Service worker 计时方法,就该提交作品了。所以提醒功能没有能达到预期目标。

    4. 小插曲

    我没拉到队友,姆伊用药助手的产品规划也比较克制,所以我没打算再找帮手。不过我也挺想趁这个机会社交一把,于是,当我在群里看到有人想做浏览器扩展,就马上报名了。

    那个主创的想法跟我另一个创意:共享首页 有些相像,于是我很想也掺一脚——当然,是在开发完姆伊用药助手之后。可惜的是,这个团队的开发进展很慢。他们犯了 hackathon 草台班子的大忌:目标定得太高,边界画的太远,需求远超一般业余时间能覆盖。于是商量好做啥之后,大家就各自上班搬砖,一直到最后都只有 PPT。

    5. 得奖

    我要再次强调,我没想到能得奖。得知入围决赛之后,我按部就班地准备 PPT、完成路演,接着便把这件事放在一边,继续干活搬砖。接着得到通知,入围获奖名单,我很开心,可也没抱什么幻想,觉得了不起就是个优秀奖,便按照要求写了获奖感言,继续边搬砖边等待颁奖。

    现在想想有点后悔,应该抓紧时间把上面说的 service worker 计时方案搞定,说不定还能赶上一波宣传。

    颁奖那天,我半开玩笑给姆伊许愿,说得奖了就给它吃牛排。本以为会是空头支票,没想到出乎意料,喜获二等奖。那自然不能食言,姆伊得到一大块牛排。

    姆伊喜获牛排一块

    得奖感言见:2022 Code for Better _ Hackthon 获奖感言

    6. 总结

    这应该是我参加的第三次 hackathon,终于不再陪跑,喜获大奖。但是我并不觉得掌握到取胜密码,下次参加可能还是无功而返。话说回来,我觉得我心态调整挺好的,本来也不图得奖,关键在于做了自己想做的东西、实践了平时没用到的技术,给自己的将来探索了更多可能性。

    考虑到获奖感言里已经充分感谢过主办方和协办方,我这里就简单再感谢下 Google 和思否两家良心企业,为广大开发者举办这样好的 hackathon,希望将来越来越好。

    我将来会继续参加类似的活动,希望能把自己的想法逐个付诸实施,创造的乐趣真的很棒。下一站:TiDB Hackathon 2022

  • E2E 测试用例的一般要求

    E2E 测试用例的一般要求

    周会上,聊到我们需要普及自动化 E2E 测试,用自动化 E2E 测试回归降低研发成本。老板问:

    测试同学已经准备了不少 E2E 测试用例,能否直接用上?

    这个问题需要具体来看。

    0. E2E 测试

    E2E 测试即端到端测试,一般用来描述一套完整的用户交互行为,要求在这一系列操作中,所有环节工作正常。E2E 测试比较关注操作的完整性,不太关注边界条件的覆盖范围。

    前端代码、重前端的产品比较适合用 E2E 测试,因为模仿的是用户实际操作,所以往往能比较好的照顾到主要使用场景,性价比比较高。

    之前在 OR 厂,我负责的产品就跟 E2E 测试有关,在几年时间里很好的保障了 OR 厂各商业产品的产品质量。本着拿着锤子找钉子的原则,我也想在我厂推广这种做法。

    1. E2E 测试用例

    下面示范一下 E2E 测试用例。比如我们要基于 WordPress 博客软件写一个发布文章的测试用例,那么用伪代码描述大概如此:

    打开网站后台 https://blog.meathill.com/wp-admin
    输入用户名
    输入密码
    点击登录按钮
    从菜单里打开文章列表页
    新建文章
    填写随机标题
    填写随机内容
    点击发布
    回到列表页
    查看内容是否存在

    2. 自动化 E2E 测试用例的要求

    上面这个测试用例放在自己的环境里跑就没有问题,但是如果要自动化运行,往往还有一些特殊的要求。

    一般来说,自动化测试更关注效率,尽量在最短的时间内完成全部测试。所以通常来说,自动化测试一般会多任务并行测试;甚至会部署多个节点一起跑。那么产生以下要求就很合理:

    • 独立性
      每个测试用例要能够独立运行,不依赖其它测试用例产生的环境,也不能因为其它测试产生的环境而失败。
    • 随机性
      为了能够独立运行,很多时候我们要给测试用例增加足够的随机性,比如上面例子里的标题,就应该是随机的,这样我们多个用例一起跑的时候,不会互相冲突。
    • 完整闭环
      为了不影响其它用例,E2E 测试用例一般要实现完整闭环。比如创建了文章,最后要把这篇文章删掉。这样一方面可以测试“删除功能”;另一方面不会产生太多垃圾,影响后面的测试。
    • 尽量不依赖非软件功能
      有时候我们会写一些清理、重置脚本,跑完几个测试或者开始跑测试之前制备环境。这样的做法也不好,因为这部分脚本没有被测试覆盖,可能产生新的问题。

    3. 总结

    所以,最后回到老板的问题上,我的答案是:

    可以尝试,但恐怕不行。


    希望今年我厂能扛住,希望我也能扛住,把自动化测试体系搭建起来。如果大家对自动化测试、E2E 测试有什么想法,欢迎留言与我交流。

  • Ubuntu 22.04 部署 Sentry 笔记

    Ubuntu 22.04 部署 Sentry 笔记

    Sentry 可能是目前最流行的缺陷管理软件,它可以帮我收集线上产品的问题,帮我们发现各种缺陷。除了 SaaS 服务以外,它还提供独立部署版本,相信大多数用户跟我一样,都觉得独立部署比较安全,这里就分享下前阵子帮我厂搭建 Sentry 的经验。

    0. 准备

    Sentry 号称需要 4核 8G 以及 20G 硬盘,但 20G 其实完全不够,我厂产品接入一半,一周就产生 20+G 的数据量。建议至少准备 100G。

    1. 安装 Docker + Compose 插件

    Sentry 私有部署版使用 docker compose 作为部署方案,所以我们要先安装 Docker 和 Compose 插件。建议先阅读上面的文档,然后可以配合下面的步骤操作。

    卸载旧版本

    sudo apt-get remove docker docker-engine docker.io containerd runc

    配置 Docker 预编译包仓库

    推荐用这种方式来安装,方便日后升级。

    $ sudo apt-get update
    
    $ sudo apt-get install \
        ca-certificates \
        curl \
        gnupg \
        lsb-release
    
    $ sudo mkdir -p /etc/apt/keyrings
    
    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    
    $ echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    安装 Docker 和 Compose 插件

     $ sudo apt-get update
     $ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

    测试 Docker

    此时,正常来说,Docker 和 Compose 插件均安装完毕,我们可以跑个 hello-world 测试一下:

    $ sudo service docker start # 启动 docker engine 服务
    $ sudo docker run hello-world

    安装 Sentry

    下载

    https://github.com/getsentry/self-hosted/releases/latest

    下载完成后,解压到安装目录。以后所有操作都在这个目录完成,建议修改下目录名,并且放在公共目录里,方便大家管理。

    我用的目录名是 ~/sentry

    安装

    执行 sudo ./install.sh。如果你的当前用户不是 root,那么 sudo 就非常重要,否则可能会报告各种奇奇怪怪的错误。

    注意:以后的 sudo 也都是必须的。

    安装过程会比较久,要拉很多个镜像并生成容器。这个过程建议保持网络畅通,或者使用 screentmux 等工具保活,否则不小心断联就可能会前功尽弃。

    启动

    安装完成之后,执行 sudo docker compose up -d 启动服务即可。

    配置 Nginx 反向代理 9000 端口

    这段不详细解释了,有人提问的话再补充。总之:

    1. Nginx 反向代理 9000 端口
    2. 使用 Certbot 启动 https
    3. 或者申请个免费证书然后启动 https

    配置邮箱

    修改 ~/sentry/sentry/config.yml,完成邮箱配置。我们用的是腾讯企业邮箱,配置不复杂,就按照 SMTP 教程即可。需要注意的是,mail.from 要跟用户名一致,否则会发不出去。

    修改配置之后,都要重启整个 compose 集群才能生效。

    配置项目

    进入 Sentry,完成首次登录配置。

    然后创建项目,选好项目类型,就能看到配置教程,非常方便。


    总结

    Sentry 开源搞得很好,文档健全,基本能解决大部分问题。

    可惜版本比较多,互联网上有很多内容已经过期,大家阅读时要稍加分辨。

    有其它部署和使用的问题,可以留言交流。

  • 【视频】Vue3 开发扫雷游戏 Workshop 视频录像

    【视频】Vue3 开发扫雷游戏 Workshop 视频录像

    经过连续几周的奋斗,终于把这套教程做完了,共四期,从入门开始,直到在本地搭建开发环境,并使用 pinia 记录游戏成绩。所有视频都在 B 站,欢迎各位读者观看,敬请三连。

    第一期:启动项目,基础知识

    1. Vue 组件开发游乐场,免环境学开发的神器
    2. 什么是 MVVM 框架
    3. Vue3 基础
    4. 使用 display:grid 画地图
    5. 生成地雷
    6. 生成游戏地图

    第二期:组件式开发

    1. 父子组件间传递数据的方式
    2. defineEmitsdefinePropsdefineExpose 的使用
    3. 使用变量切换状态
    4. 递归变更节点状态(最后拼错了导致翻车

    第三期:游戏逻辑 => 数理逻辑

    1. 添加胜利效果
    2. 添加难度选择

    第四期:本地开发 Vite,状态管理 Pinia

    1. 总结,梳理回顾代码
    2. 修改布雷时机,让游戏更好玩
    3. 将项目迁移到本地,使用 Vite 搭建开发环境
    4. 使用 pinia 存储记录

    参考代码

    扫雷相关代码在这个仓库:meathill/minesweeper: yet another minesweeper game (github.com),欢迎学习,有任何问题均欢迎提问。目前我也时不时更新一下。

    想试玩的话这里有 DEMO


    写在第一期之后

    周日,Workshop 如期开始。有 5、6 位同学到场,出勤率 50%,还不错。

    这次 Workshop 我选择用浏览器 SFC Playground 的形式,减少环境部署的需求,希望大家集中精神在其它技术内容上。

    Vue3 开发扫雷游戏比想象中复杂,一节课讲不完,这节课的知识点有:

    1. Vue 组件开发游乐场,免环境学开发的神器
    2. 什么是 MVVM 框架
    3. Vue3 基础
    4. 使用 display:grid 画地图
    5. 生成地雷
    6. 生成游戏地图

    没有到现场的同学可以看录像,敬请一键三连:

    (视频挪到上面了)

    因为我上午清理 Sentry 的时候不小心断网,把服务器搞挂了,所以提前下播加班维护服务器,所以时间比预期要少,只有 1.5 小时。但是我觉得强度还是太大了,对我对同学来说都是。下次理想时间是讲 1 小时,分析和作业 半小时;课间休息 10 分钟。

    不出意外的话,本周日下午 3 点继续,欢迎听过的没听过的同学一起来参加。没来过的同学可以加我微信:wakabanga。

    布置一个作业:我计算每个砖块四周有几个炸弹的算法,可以优化。提出你的优化点并实现它,发给我,我就送你一本技术类书籍。大家都来试试吧。