12

如何部署 Scala 代码

 3 years ago
source link: https://blog.oyanglul.us/scala/gist/modern-scala-deployment?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

如何部署 Scala 代码

如何部署 Scala 代码

Table of Contents

我们产品Scala用过很多种方式部署.

的代码库, 都是

  1. sbt-assembly 打成 uber jar(肥包, 也就是包含所有依赖), 大概 50-100M
  2. 把 jar 包 压到带 jvm 的 docker 里, push 到 register
  3. 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 种 安装包

  • 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:[email protected]" \
    coursier bootstrap com.abc:heheda_2.12:$version -o heheda

CMD ./heheda

Footnotes:

1

这对于新人来说是何等的 卧槽 黑人问号???

2

真正部署前根本不需要docker image, 而大部分时间 CI 只跑 Pull Request 的测试而不会部署

3

这完全可以扔 docker hub 上, 但是我懒


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK