crystal-chinaChina
  • 本站源码
  • 注册
  • 登录
目录
  • 前言
  • 简介
  • 安装 ➤
    • 包管理
  • 写给 Rubyists ➤
    • 类型
    • 方法
    • 代码块
    • 杂项
    • 性能因素
    • 迁移 Ruby 代码到 Crystal
  • 基础知识
  • 交叉编译

前言写在开始之前

创建于:2025年03月13日 最后编辑于: 2025年06月22日
💡 小提示

Crystal 是一门受 Ruby 高度启发的计算机程序语言,并且最终编译到 LLVM。

对于同时具备系统编程经验(例如 C)以及 Ruby 开发经验的程序员来说,Crystal 是一门 很容易掌握的语言。

💡 小提示

目前这个版本,写作计划为具有 Ruby (或类似经验) 的开发者的 Crystal 介绍,因此, 现阶段不会特意讲解 Ruby 相关的基础知识,代之,会使用类似当前 "小提示" 对话框的方式 指出 Crystal 和 Ruby 的异同。

建议在学习 Crystal 文档之前,掌握一些 Ruby 的基本概念,会减少很多摩擦。

一直以来,为 Crystal 在中国的普及做贡献,都是自己的一个美好愿望,但一直因故未能实现, 这次,以翻译 Crystal 官方文档作为开始,将笔者学习 Crystal 过程中大量的笔记进行整理, 也算是对自己之前的知识的一个学习和再掌握。

正如 Ruby 一样,在看似简单的外表下,Crystal 又绝非一门简单的语言,希望笔者根据自己的 经验,能将这一门让人惊叹、并且唯一的的语言讲解清楚,对读者学习掌握 Crystal 带来帮助。

如有错误,欢迎提出勘误指正, 或在下面留言,我会及时更正,保证不对对读者产生误导。

§ 本站技术栈

本站 自然使用 Crystal 编写,目前用到的库(shard)有:

  • baked_file_system_mounter, 用于将本站所需的 assets 文件 (包含 js, css, 字体,markdown 等)打包进可执行文件,并在部署到新机器后自动 mount。
  • lucky 是一个全功能的 web 框架,用来搭建本站以及计划中的论坛。
  • magic-haversack 使用 zig cc 来 build 一个 Crystal 静态 bianry(无需 docker)
  • markd 用于转换 markdown 格式到网页。
  • tartrazine, 用于高亮 markdown 中的代码块。

更多的 shard,查看 shard.yml。

前端部分,基于本人的喜好,本站最大限度避免编写Javascript, 并且本人也基本不会写 CSS, 有希望拿本项目练手的前端小将,欢迎报名!

下面笔者介绍的本站用到的前端项目,都是属于同一个 github 组织 Big Sky Software 下的项目。 他们组织的介绍老有意思了:我们会发现行业中的***新兴热点**趋势,然后创造出与之相反的东西。

  • htmx 高效率的 HTML 工具(high power tools for HTML),这个官方介绍很模糊,其实 作者专门写了本书介绍 hypermedia 的概念,建议读一读,非常有意思,这绝对是像我 这种服务端工程师的最爱。
  • hyperscript 专门写在页面标签中的 script 或 _ 属性中的脚本,语法非常接近于 口语话的英文,是 htmx 一个非常好的补充,见本站 src/components/doc/form.cr 中的例子。
  • missing.css 一个非常简陋的 CSS 框架,非常轻量
  • stork 很好用的本地全文搜索库,会编译为 wasm 因此性能很好,缺点是中文支持差一点, 另外,作者不维护了,有点可惜,目前够用吧。

更多用到的前端库,查看 pacakge.json。

§ 本站如何部署

本站部署机器是 azure HK v2ts(1c/2g), 低负载情况下,内存占用在 35M 左右, 包含 (共享内存 11M + 独占物理内存 24M),因为资源占用很低,同时部署了好几个站点。

部署流程相较于 Ruby 也简单到爆!见项目 README 以及有关 交叉编译 的说明。

整个部署过程是非常简单而且快速的。

  1. shards run index 创建所需的索引
  2. yarn prod 打包 assets 文件到 ./dist 文件夹。
  3. 交叉编译,生成一个静态的 binary (所有所需的 assets 文件也会被加入二进制文件)
  4. 和服务器上最后部署版本比较,并生成 binary patchfile.
  5. 复制 patchfile 到服务器,并应用。(相较于文件覆盖,服务器无需停止,既可以打 patch)
  6. 成功后,本地做一个刚刚部署版本的备份

此网站编译后的 binary 大小大约 15M 左右(包含所有 assets 文件),修改不多的情况下, 生成的 patch 文件大小在 500K 左右, 大部分部署时间花在了编译 release 版本的静态 binary。

   1  
   2  sb_static --production --no-debug --link-flags="-s" --link-flags="-pie" --release crystal_china
   3  

如果还处在开发过程中,可以暂时移除 --release 参数,前者其实等价于: -O3 --single-module -O 用来指定为了生成 最优代码 的 代码生成(codegen) 工作量,默认不指定是 -O0 无优化,-O3 最高级别优化。 较高的优化级别拥有更好的运行时(runtime)性能,但是需要花费更多的编译时间。

这是一个权衡,事实上,在开发阶段,总是使用 -O1 是一个不错的主意,除非项目是简单的 hello world,否则默认不优化相较于 -O1 不会有明显的提升。

下面是来自 PR 作者 不同优化级别的性能比较:

   1  
   2  default: 初次编译: 7.4s, 增量编译(修改一个文件): 5.3s, 启动时间: 23.5s
   3  -O1: 初次编译: 12s, 增量编译(修改一个文件): 5.2s, 启动时间: 7.5s
   4  -O2: 初次编译: 12.6s, 增量编译(修改一个文件): 5.3s, 启动时间: 7s
   5  --release: 初次编译: 61s, 增量编译(修改一个文件): 61s, 启动时间: 2s
   6  

可以看到,除了第一次编译时(只需要执行一次,对吧?)default 比 -O1 快不少 (7.4s -> 12s), 但增量编译阶段,-O1 甚至还比 default 快了一点点 (5.3s -> 5.2s)。但是运行时性能, 则有显著的提升, (23.5s -> 7.5s), 足足快了三倍多,所以,对于 Web 开发这种 非常频繁的增量编译 的项目,或者 需要反复运行 spec 的情况,使用 -O1 是一个 不错的注意,-O1 会输出较少的 backtrace, 但是带来大约 15% 的性能提升,需要加 --debug 参数来输出和 default 同样的 backtrace, 所以,一切都是权衡。

   1  
   2   ╰──➤ $ binary_patch_crystal_china bin/crystal_china
   3  Calculating patch file ... Done.
   4  crystal_china.patchfile								100%  469KB 900.1KB/s   00:00
   5  Patching file ... Done
   6  deploy successful
   7  'bin/crystal_china' -> 'latest_released/bin/crystal_china'
   8  

最后一步,ssh 登录服务器,重启 web 服务,例如,Crystal China 站点使用 systemd,

   1  
   2   ╰──➤ $: systemctl restart crystal_china
   3  

如有数据库表改动, 会在第一次启动时执行,部署完成!

previous_page没有上一页了

前言

next_page简介
欢迎在评论区留下你的见解、问题或建议

正在预览...
正在读取评论...
Crystal Chinaadmin@crystal-china.org
githubx.comcrystal-lang