如何部署 Scala 代码
我们产品Scala用过很多种方式部署.
两年多前
的代码库, 都是
- sbt-assembly 打成 uber jar(肥包, 也就是包含所有依赖), 大概 50-100M
- 把 jar 包 压到带 jvm 的 docker 里, push 到 register
- K8s 从 register 拉 docker
用过的同学都知道, 这个打肥包的过程非常非常的慢, 而且还需要一个诡异的配置告诉assembly如何merge
这对于新人来说是何等的 卧槽 黑人问号???
assemblyMergeStrategy in assembly := {
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
所以, 一点也不好用, 没用过的也不要用它了
- 打包慢
- 包大
- uber jar包不能放registry, 只能给部署用, 所以别的服务怎么依赖这个jar
- merge策略可能会导致诡异的运行时问题
一年前
的代码用的是 sbt-native-packager
这个工具很强大, 能打成 N 种 安装包
- tar
- deb
- dmg
- msi
- docker
- graalvm
这也太强了, 马上就觉得 assembly什么破烂玩意, 这个才是真正的打包工具.
用法非常简单, 对于我们来说只要docker, 安装插件然后
sbt docker:publishLocal
就完事了, push 到 register 就用了.
真是省事!
现在
用的是 Coursier
都说了 sbt-native-packager 那么好用了, 为啥还要换?
Coursier 相对 native packager 有更多的好处
- 快: 有缓存, 而且sbt用的也是coursier, 共享缓存, 一起快
- 快: 只打包应用, 不是 uber jar, 小了非常多, 打包速度也快, 上传也快
- 还是快: CI 在部署前都不需要打包成docker, 这样前面的测试会很快,他们只用拉应用jar包,非常小,所有依赖又有缓存
然我们来看看怎么用 coursier 打包.
你不需要任何插件来发布 jar 包
直接:
sbt publish
假设你发布的包叫 `com.abc:heheda2.12:1.0`
如果跑测试要运行这个jar包只需要
coursier launch com.abc:heheda_2.12:1.0
所以大量的时间就省下来了 真正部署前根本不需要docker image, 而大部分时间 CI 只跑 Pull Request 的测试而不会部署 .
而在真正 master 部署时, 我们可以用 coursier 在 docker 里把依赖先安装好.
首先需要一个 coursier 的 docker image 这完全可以扔 docker hub 上, 但是我懒
FROM openjdk:8u222-slim ARG VERSION RUN apt update && apt install -y curl WORKDIR /usr/local/bin RUN curl -Lo coursier https://git.io/coursier-cli && chmod +x coursier # Add and use user coursieruser RUN groupadd --gid 1001 coursieruser && useradd --gid 1001 --uid 1001 coursieruser --shell /bin/bash RUN chown -R coursieruser:coursieruser /opt RUN mkdir /home/coursieruser && chown -R coursieruser:coursieruser /home/coursieruser RUN mkdir /logs && chown -R coursieruser:coursieruser /logs USER coursieruser WORKDIR /home/coursieruser RUN coursier --help
在给应打包docker时
FROM mycoursier ARG version RUN coursier bootstrap com.abc:heheda_2.12:$version -o heheda CMD ./heheda
如果你的包在私有registry
FROM mycoursier ARG version ARG csuser ARG cstoken RUN env COURSIER_REPOSITORIES="central|sonatype:releases|https://$csuser:$cstoken@my.jarregistry.com" \ coursier bootstrap com.abc:heheda_2.12:$version -o heheda CMD ./heheda