后端技术栈选取原则有二个:

  • 第一是尽量靠近 Scala 语言本身(第一性原则),外加最简单的 FP 概念。避免引入复杂的抽象而美丽的概念如 Monad, Higher Kinded Type,Transformer 等等。
  • 第二是新的东西需要自己完全可以掌控(团队具备源代码级的理解和修改能力)。

1 Overview

计划用的 Scala 后端技术栈:

mill 作为 build 工具(不到 1.0) quill 数据库访问(成熟) ZIO 做 FP 的基础库(马上 1.0) 日志用 Blindsight Logging(刚 1.0) PureConfig 配置管理 ZIO testing 做测试(未验证) 依赖注入用 ZIO 的 ZLayer (马上 1.0) Http server 用 Vert.x HTML Page: ScalaTag, 非常简洁、高效、好用。 uPickle JSON marshalling (circe 作为备选)(刚 1.0) JS: jquery + bootstrap, form data for SSR.

这些 1.0 前后的东西都是看过源码并尝试后做的选择。我们放弃现有的 Akka 和 Cats 二大主流成熟阵营,选择了回归 Scala 语言本身和最简单的 FP 开发库(ZIO)。选择最简单的,Scala 开发的大趋势也向这个方向走。

actor 这个概念很好使,Haoyi 的 Cask , Vert.x 里面都有用:消息队列外加单线程的任务来解决并发编程。 Akka Actor 本身解决的问题还属于技术层面的偶然复杂性 (accidental complexity),不应该在应用层面看到。

Akka Actor 太重太复杂,Cask 和 Vert.x 都是自己开发的轻量 Actor。 其上的 Akka HTTP, Akka Play 就过于复杂了。

作为应用层面的概念,就是 Kafak,消息总线加各种处理。

No to scala.js.

2 Http Server

Http server 的选择很苦恼,akka http 和 akka play 都过于复杂,不适合 ZIO 编程模式。尝试做了 Cask 和 ZIO 集成,发现 Cask 封装了 undertow,不是很好使,边边角角问题多, undertow 的开发力量不足。 现在 Java 生态里,Quarkus 立志要代替 spring 作为 cloud java 的解决方案,其内置了 vert.x (基于 netty)。 几条线索下来,我们也用 ZIO 内置 vert.x 来做网站和 REST API 的开发,解决了成熟性(vert.x 五年半了比较成熟)与简单性(内置 vert.x lib,没有框架负担)的二难。

3 FP

ZIO encapsultes side effects and provides a concurrency library. The computation and scheduling are part of the program description. It divides errors into recoverable errors and programming defects (or catastrophic errors). Here is the design motivation. The communcation can use queue provided by the lib or a custom one. The queue is shared by communicating parties. ZIO effects are auto-cancellable, resource safe and can be optionally supervised.

ZIo switches thread pools only in two scenarios: in the main thread, call fork to swtich to the async pool. It stays on main after fork. An effect can use on to switch pool. After the switch, it shits back to the async pool.

An actor encapsulates and manages state, statless actors are considered anti-pattern. Actors communicate via async mesage passing and manage errors. You need the reference of another actor.