最近需要在数据库存储一批复杂的配置文件,需要原子化更新配置的内部字段的能力。一开始打算用 MySQL,有两个方案:
1. 整个数据结构序列化后塞在一行的一个字段里面。更新的时候在开事务(上行锁)整个读出来更新好写回去。
2. 根据数据结构,老老实实建模,各种 list 表,relation 表,每一个字段都是一列……多数情况下不需要用事务就能单独更新内部字段。
前者省事,但是不优雅;后者足够教条,但太麻烦了。
最后,还是换成了用 MongoDB,整个配置作为 document 写到库里,想怎么原子更新子字段就 怎么更新。虽然 MongoDB 更新文档本质上也是单行事务,但局部更新的语义支持确实比 MySQL 优雅。
1. 整个数据结构序列化后塞在一行的一个字段里面。更新的时候在开事务(上行锁)整个读出来更新好写回去。
2. 根据数据结构,老老实实建模,各种 list 表,relation 表,每一个字段都是一列……多数情况下不需要用事务就能单独更新内部字段。
前者省事,但是不优雅;后者足够教条,但太麻烦了。
最后,还是换成了用 MongoDB,整个配置作为 document 写到库里,想怎么原子更新子字段就 怎么更新。虽然 MongoDB 更新文档本质上也是单行事务,但局部更新的语义支持确实比 MySQL 优雅。
https://github.com/topgrade-rs/topgrade
一条命令更新各种包管理中的包,包括 homebrew/zsh插件/pip/npm/docker镜像等等,不更新会死星人感到舒适。
一条命令更新各种包管理中的包,包括 homebrew/zsh插件/pip/npm/docker镜像等等,不更新会死星人感到舒适。
最近体验 railway.app ,试着部署了些服务,说一些感受:
⁃ 类似 Heroku,服务实例不会被销毁,不会出现冷启动的问题。
⁃ 计费是按照 CPU 和内存用量+耗时来计算,每个月消费低于 $5 不收费。
⁃ 不启用付费计划(绑定信用卡)的话,每个月也有 $5 的额度,但是会限制实例每月总在线时长 500 小时(21 天),也就是说想长期部署服务必须启用付费计划。
⁃ 可以部署数据库 (PG、MySQL、Redis、MongoDB),还支持在前端访问和操作数据库。不过目前没有看到数据库扩容、备份等功能,感觉就是单纯的提供一个数据库容器实例,不适合用于生产。
⁃ Railway 当中有 Project 的概念,一个 Project 可以有多套环境、部署多个服务/数据库,很像 K8S 的 Namespace,适合用来做业务隔离。
⁃ 会自动识别项目中的 Dockerfile 构建镜像部署,构建速度也比较快。
⁃ 和 Vercel 一样,不支持 VPC,也就是说如果做服务间调用,服务只能通过公网域名来互相访问,比较不安全。不过这个功能在 roadmap 中已经是 WIP 状态,可期。
⁃ 不保留历史日志,需要依赖像 logtail 这类外部日志服务做日志存储。
⁃ 不支持 cronjob,文档里给的解决方案是起一个实例自己调度……
总的来说,对于个人开发来说,Railway 体验还可以。但毕竟是一家只有两年的创业公司,平台功能和文档建设还是不够完善。
⁃ 类似 Heroku,服务实例不会被销毁,不会出现冷启动的问题。
⁃ 计费是按照 CPU 和内存用量+耗时来计算,每个月消费低于 $5 不收费。
⁃ 不启用付费计划(绑定信用卡)的话,每个月也有 $5 的额度,但是会限制实例每月总在线时长 500 小时(21 天),也就是说想长期部署服务必须启用付费计划。
⁃ 可以部署数据库 (PG、MySQL、Redis、MongoDB),还支持在前端访问和操作数据库。不过目前没有看到数据库扩容、备份等功能,感觉就是单纯的提供一个数据库容器实例,不适合用于生产。
⁃ Railway 当中有 Project 的概念,一个 Project 可以有多套环境、部署多个服务/数据库,很像 K8S 的 Namespace,适合用来做业务隔离。
⁃ 会自动识别项目中的 Dockerfile 构建镜像部署,构建速度也比较快。
⁃ 和 Vercel 一样,不支持 VPC,也就是说如果做服务间调用,服务只能通过公网域名来互相访问,比较不安全。不过这个功能在 roadmap 中已经是 WIP 状态,可期。
⁃ 不保留历史日志,需要依赖像 logtail 这类外部日志服务做日志存储。
⁃ 不支持 cronjob,文档里给的解决方案是起一个实例自己调度……
总的来说,对于个人开发来说,Railway 体验还可以。但毕竟是一家只有两年的创业公司,平台功能和文档建设还是不够完善。
Railway
Railway is an infrastructure platform where you can provision infrastructure, develop with that infrastructure locally, and then deploy to the cloud.
BFF 这个概念,宣传上要接管各种仅为前端服务的脏活累活,让业务服务专注运行逻辑。但是实践上 BFF 层又推崇尽可能薄。
往往会能看到两个极端。业务服务定义了一堆专为前端服务的 RPC 接口,BFF 沦为 API Gateway。或者是 BFF 包含了非常重的业务逻辑,业务服务沦为 CRUD 执行器。
往往会能看到两个极端。业务服务定义了一堆专为前端服务的 RPC 接口,BFF 沦为 API Gateway。或者是 BFF 包含了非常重的业务逻辑,业务服务沦为 CRUD 执行器。
日常技术碎碎念
最近体验 railway.app ,试着部署了些服务,说一些感受: ⁃ 类似 Heroku,服务实例不会被销毁,不会出现冷启动的问题。 ⁃ 计费是按照 CPU 和内存用量+耗时来计算,每个月消费低于 $5 不收费。 ⁃ 不启用付费计划(绑定信用卡)的话,每个月也有 $5 的额度,但是会限制实例每月总在线时长 500 小时(21 天),也就是说想长期部署服务必须启用付费计划。 ⁃ 可以部署数据库 (PG、MySQL、Redis、MongoDB),还支持在前端访问和操作数据库。不过目前没有看到数据库扩…
前几天对信用卡账单的时候,惊讶地发现上个月 MongoDB Atlas 托管数据库扣了将近 200 刀。可能是因为上个月部署了些 cronjob,对数据库用量比较大。但几个小服务产生这么高的消费还是不能接受的。
想着 MongoDB Atlas 是用不起了。但暂时找不到 MongoDB 托管的替代品,试着在 Railway 上起了台 MongoDB 托管实例。把老数据 dump 过去并重启了所有相关服务,完成迁移也就十分钟。
刚看了一眼 Railway 的 Usage 统计,根据每分钟的 CPU/MEM 的平均用量,预估了当月费用,一个月不超过 5 刀 🫠 (比根据读写次数计费划算多了)。
不过如之前所说,Railway 对数据库的可用性没有强的保证,也没有显式的数据备份解决方案。打算先用 Github Action 写个定时 dump 数据库保存到 S3 的脚本,临时先用着。
想着 MongoDB Atlas 是用不起了。但暂时找不到 MongoDB 托管的替代品,试着在 Railway 上起了台 MongoDB 托管实例。把老数据 dump 过去并重启了所有相关服务,完成迁移也就十分钟。
刚看了一眼 Railway 的 Usage 统计,根据每分钟的 CPU/MEM 的平均用量,预估了当月费用,一个月不超过 5 刀 🫠 (比根据读写次数计费划算多了)。
不过如之前所说,Railway 对数据库的可用性没有强的保证,也没有显式的数据备份解决方案。打算先用 Github Action 写个定时 dump 数据库保存到 S3 的脚本,临时先用着。
之前通过 DHCP,把全家的所有设备的网关指向软路由(openclash),从而实现翻墙。不过最近发现 homekit 的稳定性不太好,家居中枢经常掉线。想了一下大概是 openclash 连接代理服务器本身稳定性不够。
于是在路由器上通过 dnsmasq,调整了 DHCP 配置,只将部分设备的网关指向软路由。考虑 homekit 本身可能也有翻墙需要,故两个家居中枢,一个(homepod)留在了墙内,一个(apple tv)开启了翻墙。
这样一来,整体稳定多了。
于是在路由器上通过 dnsmasq,调整了 DHCP 配置,只将部分设备的网关指向软路由。考虑 homekit 本身可能也有翻墙需要,故两个家居中枢,一个(homepod)留在了墙内,一个(apple tv)开启了翻墙。
这样一来,整体稳定多了。
发现自己各种后端服务部署有点混乱,在 Vercel、Railway、Digital Ocean 等 PaaS 上都有部署,对应了不一样的羊毛使用场景。但是发现服务间互相调用会非常麻烦,代码里面需要关心目标服务的具体位置,维护成本和心智负担都不小。
于是写了个“服务发现”机制。使用一个服务发现服务 Discovery Service,通过 Vercel、Railway、Digital Ocean 的 API,不断拉取部署相应平台上部署信息,并存储下来。然后每一个服务会定时从 Discovery 上获取全量的服务列表,然后根据服务的唯一标识映射获取对应的公网地址。这样以来只要保证在 PaaS 上部署服务并暴露公网,客户端就能通过服务名称直接访问。
于是写了个“服务发现”机制。使用一个服务发现服务 Discovery Service,通过 Vercel、Railway、Digital Ocean 的 API,不断拉取部署相应平台上部署信息,并存储下来。然后每一个服务会定时从 Discovery 上获取全量的服务列表,然后根据服务的唯一标识映射获取对应的公网地址。这样以来只要保证在 PaaS 上部署服务并暴露公网,客户端就能通过服务名称直接访问。
最近要在 Redis 上做一个超大 QPS 的指标统计功能。考虑到重试幂等,没法直接用 INCR 来累加。于是想用 Set 结构存储,用 SCARD 查总量。这就涉及到占用过大的存储空间的问题。然后就各种折腾,写了一堆代码逻辑来尽可能降低存储占用,还把 Redis 换成了磁盘大容量存储的类 Redis 存储。
刚才和 ChatGPT 讨论的时候,被指出可以使用 HyperLogLog。雀食 🙈。技术还是得常用常新,不用不复习太容易忘。
刚才和 ChatGPT 讨论的时候,被指出可以使用 HyperLogLog。雀食 🙈。技术还是得常用常新,不用不复习太容易忘。
https://www.bitestring.com/posts/2023-03-19-web-fingerprinting-is-worse-than-I-thought.html
TIL,原来清除网站数据或者开匿名模式,并不能避免浏览器指纹标记。
TIL,原来清除网站数据或者开匿名模式,并不能避免浏览器指纹标记。
日常技术碎碎念
最新 Next.js13 appdir文档 中, Vercel 引入 Comments 组件,只需要登录 Vercel,就能在页面的任意位置评论。非常像 Figma 的评论系统,只不过把画布换成了网页。 Vercel 也将这个能力开发给了 Vercel 用户,所有 Preview Deployment(非主分支)可以直接开启。默认情况下,只有当前 Deployment 所属组织的成员才能评论,也可以开放权限到任意用户。 一旦发生评论,Vercel 会将评论同步到对应分支的 PR 下面,可以很自然地融入开发流程。…
https://cord.com/ 果然有了,画布评论SaaS
cord.com
A more human job search - cord
cord is the job search platform that gives you direct access to hiring teams inside technology companies in the UK, USA and remote across Europe.
日常技术碎碎念
https://buf.build/blog/connect-a-better-grpc Protobuf 管理工具 Buf 团队发布名为 Connect 的 RPC 套件. 他们罗列了一些 gRPC 的问题: ⁃ 过于复杂, 难以调试, 而且庞大的代码库容易出现漏洞 ⁃ 不使用 net/http 标准库 ⁃ 不支持浏览器 而 Connect 是在 gRPC 的基础上, 对其进行优化, 一些特性: ⁃ 精简代码, 包括生成的代码也更加可读 ⁃ 使用 net/http 标准库, 兼容性更好 ⁃ 支持…
connect server 支持 HTTP GET 了,只需要设置幂等级别为无副作用,就会自动为对应 method 配置 GET router。
在 RPC 场景中,只要是幂等就代表 Client 端可以安全地重试 RPC 调用,至于是否有副作用指导意义不强。
但是放到 http restful 接口上,GET 往往就等价于无副作用,以此判断是否支持 HTTP GET 还是比较合理且巧妙的。
https://github.com/bufbuild/connect-go/releases/tag/v1.7.0
service ElizaService {
rpc Say(stream SayRequest) returns (SayResponse) {
option idempotency_level = NO_SIDE_EFFECTS;
}
}
idempotency_level
是 protobuf 内置的 method 属性,分为 unknown/idempotent/no_side_effects,后两者都是幂等的意思。在 RPC 场景中,只要是幂等就代表 Client 端可以安全地重试 RPC 调用,至于是否有副作用指导意义不强。
但是放到 http restful 接口上,GET 往往就等价于无副作用,以此判断是否支持 HTTP GET 还是比较合理且巧妙的。
https://github.com/bufbuild/connect-go/releases/tag/v1.7.0
GitHub
Release Prepare for v1.7.0 (#496) · bufbuild/connect-go
Prepares for the Connect v1.7.0 release, featuring Connect Get support.
Changes the IsAtLeastVersion1_6_0 constant to IsAtLeastVersion1_7_0
too, since it actually is from changes that only landed a...
Changes the IsAtLeastVersion1_6_0 constant to IsAtLeastVersion1_7_0
too, since it actually is from changes that only landed a...
之前使用 mackup 把 mac 上的各种配置文件备份到 icloud 了,今天发现 icloud 中的 mackup 目录被错误删除了,在 icloud 上使用文件恢复也找不到……然后 icloud 默默同步文件把本地版本也给删除了,各类配置都是软链接到 icloud 目录的,导致本地所有配置都没了
现在看着唯一一个还开着的加载了之前 .zshrc 的 zsh,再犹豫要不要放弃恢复重新配置一份 .zshrc,积累了几年的配置全都没了😩
现在看着唯一一个还开着的加载了之前 .zshrc 的 zsh,再犹豫要不要放弃恢复重新配置一份 .zshrc,积累了几年的配置全都没了😩
GitHub
GitHub - lra/mackup: Keep your application settings in sync (OS X/Linux)
Keep your application settings in sync (OS X/Linux) - lra/mackup
周末倒腾了一下 Surge5 新加入的 Ponte 组网能力。相比一直在使用的 Tailscale 有一个明显的优势,就是不需要自己搭建 DERP 中转服务器了,可以直接使用机场作为中转服务器。
我是用的香港节点作为中转,在公司访问家中mac延迟稳定低于 100ms。因为机场往往是不限速的,使用 VNC 开远程桌面也不需要压缩画质。
通过一些简单的规则就可以实现在外访问家中内网服务:
反过来,也可以在家直接通过公司的 mac 作为跳板访问公司内网,非常方便。
我是用的香港节点作为中转,在公司访问家中mac延迟稳定低于 100ms。因为机场往往是不限速的,使用 VNC 开远程桌面也不需要压缩画质。
通过一些简单的规则就可以实现在外访问家中内网服务:
HOME = select, DIRECT, DEVICE:mymac
IP-CIDR,192.168.50.0/24,HOME
反过来,也可以在家直接通过公司的 mac 作为跳板访问公司内网,非常方便。
Nssurge
Surge Ponte 指引 | Surge Knowledge Base
昨晚折腾了一晚上的 jetbrains gateway,想着用 goland 远程开发。
整体体验下来就是烂,各种功能和插件需要区分 Host 和 Client,有些插件需要两侧同时安装才能使用,心智负担很高;很多插件本身就是面向客户端模式设计的,在这种前后端分离模式下根本没法使用。
性能的话倒是可以接受,开个 golang 的 monorepo,8c16g 的开发机,索引的时候会打满 CPU,平峰期差不多占用 2c8g。
总的来说,我宁愿使用 neovim 来远程开发,各种体验至少是原生的。
整体体验下来就是烂,各种功能和插件需要区分 Host 和 Client,有些插件需要两侧同时安装才能使用,心智负担很高;很多插件本身就是面向客户端模式设计的,在这种前后端分离模式下根本没法使用。
性能的话倒是可以接受,开个 golang 的 monorepo,8c16g 的开发机,索引的时候会打满 CPU,平峰期差不多占用 2c8g。
总的来说,我宁愿使用 neovim 来远程开发,各种体验至少是原生的。
The JetBrains Blog
A Deep Dive Into JetBrains Gateway | The JetBrains Blog
Let’s take a deeper look at the remote development workflow managed by the new JetBrains Gateway app.
日常技术碎碎念
之前使用 mackup 把 mac 上的各种配置文件备份到 icloud 了,今天发现 icloud 中的 mackup 目录被错误删除了,在 icloud 上使用文件恢复也找不到……然后 icloud 默默同步文件把本地版本也给删除了,各类配置都是软链接到 icloud 目录的,导致本地所有配置都没了 现在看着唯一一个还开着的加载了之前 .zshrc 的 zsh,再犹豫要不要放弃恢复重新配置一份 .zshrc,积累了几年的配置全都没了😩
最终返璞归真,在 Github 上开了个仓库存了各种配置文件,clone 到本地手动 ln -s 创建软链接。
这类不是天天都要变动的配置文件,确实没有必要用 icloud 之类云盘实时同步。
分享下重写的 .zshrc,用在我的多个 macos/linux 环境下,使用 Github Action 从我的配置仓库当中自动同步到 Gist,https://gist.github.com/sorcererxw/238f7068c18ba148337f32f9a08d0dbd
这类不是天天都要变动的配置文件,确实没有必要用 icloud 之类云盘实时同步。
分享下重写的 .zshrc,用在我的多个 macos/linux 环境下,使用 Github Action 从我的配置仓库当中自动同步到 Gist,https://gist.github.com/sorcererxw/238f7068c18ba148337f32f9a08d0dbd
Gist
My .zshrc file
My .zshrc file. GitHub Gist: instantly share code, notes, and snippets.