Lagom基于sbt和Maven的开发环境允许通过一个命令运行任意数量的服务。
这行命令还会在代码更改时重新加载服务,这样您就不必手动重新启动它们。您可以专注于自己的工作,让Lagom来编译和重新加载。
在Maven中运行所有服务
要在Maven中运行所有服务,只需运行lagom:runAll
命令:
$ cd <path to your Lagom project>
$ mvn lagom:runAll
INFO ...
INFO Service hello-impl listening for HTTP on 127.0.0.1:24266
INFO Service hello-impl listening for HTTPS on 127.0.0.1:50695
INFO Service hello-stream-impl listening for HTTP on 127.0.0.1:26230
INFO Service hello-stream-impl listening for HTTPS on 127.0.0.1:58440
(Services started, press enter to stop and go back to the console...)
启动sbt开发控制台
假设你有一个sbt项目,现在是时候启动你的Lagom项目目录的控制台了:
$ cd <path to your Lagom project>
$ sbt
[info] ...
>
要运行所有Lagom服务,并自动重新加载,只需在sbt控制台中输入runAll
:
> runAll
[info] ...
[info] Service hello-impl listening for HTTP on 127.0.0.1:24266
[info] Service hello-impl listening for HTTPS on 127.0.0.1:50695
[info] Service stream-impl listening for HTTP on 127.0.0.1:26230
[info] Service stream-impl listening for HTTPS on 127.0.0.1:58440
(Services started, press enter to stop and go back to the console...)
热加载
出现“Services started”消息之后,如果你对源代码做了更改,你将在控制台中看到如下输出:
[info] Compiling 1 Java source to /<project-path>/target/scala-2.12/classes...
--- (RELOAD) ---
管理自定义服务
默认情况下,Lagom除了运行你的服务外,还会启动一个服务定位器、一个Cassandra服务器和一个Kafka服务器。如果使用sbt,您可以自定义Lagom启动什么,包括添加其他数据库和基础设施服务。
注意:Maven目前不支持管理自定义服务,因为Maven无法任意添加行为,比如启动和停止外部进程所需的逻辑。这通常不是一个大问题,它只是意味着开发人员必须自己手动安装、启动和停止这些服务。
要添加自定义服务,首先需要定义一个任务来启动build.sbt
中的服务。该任务应生成一个Closeable
结果,该结果可用于停止服务。以下是[Elastic Search](https://www.elastic.co/cn/elasticsearch/)
的一个例子:
import java.io.Closeable
val startElasticSearch = taskKey[Closeable]("Starts elastic search")
startElasticSearch in ThisBuild := {
val esVersion = "5.4.0"
val log = streams.value.log
val elasticsearch = target.value / s"elasticsearch-$esVersion"
if (!elasticsearch.exists()) {
log.info(s"Downloading Elastic Search $esVersion...")
IO.unzipURL(url(s"https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-$esVersion.zip"), target.value)
IO.append(elasticsearch / "config" / "log4j2.properties", "\nrootLogger.level = warn\n")
}
val binFile = if (sys.props("os.name") == "Windows") {
elasticsearch / "bin" / "elasticsearch.bat"
} else {
elasticsearch / "bin" / "elasticsearch"
}
import scala.sys.process._ // if on sbt 0.13, don't import this
val process = Process(binFile.getAbsolutePath, elasticsearch).run(log)
log.info("Elastic search started on port 9200")
new Closeable {
override def close(): Unit = process.destroy()
}
}
现在我们可以启动Elastic Search了,我们需要将这个任务添加到Lagom的基础设施服务列表中,这样Lagom在运行runAll时就会启动它。这可以通过修改lagomInfrastructureServices设置来实现:
lagomInfrastructureServices in ThisBuild += (startElasticSearch in ThisBuild).taskValue
背后原理
当你执行runAll
时,幕后发生了什么?
- 嵌入的服务定位器被启动
- 嵌入式服务网关被启动
- Cassandra服务器被启动
- Kafka服务器被启动
- 你的服务开始
- …注册到服务定位器
- …在服务网关中注册公共访问路径
这一切都是自动发生的,不需要特殊的代码或额外的配置。
您可以通过在web浏览器中(或使用curl等命令行工具)查看[http://localhost:9008/services](http://localhost:9008/services)
来验证您的服务是否正在运行。运行在9008端口上的Service Locator将返回如下JSON:
[
{
"name":"cas_native",
"url":"tcp://127.0.0.1:4000/cas_native",
"portName":null
},
{
"name":"kafka_native",
"url":"tcp://localhost:9092/kafka_native",
"portName":null
},
{
"name":"hello",
"url":"http://127.0.0.1:65499",
"portName":null
},
{
"name":"hello",
"url":"http://127.0.0.1:65499",
"portName":"http"
}
]
cas_native
是Cassandra服务。正如您将在编写持久性和集群服务的文档中了解到的,Cassandra是Lagom中的默认数据库,它是开发环境的一个组成部分。
服务定位器、Cassandra和Kafka将在下一节中详细介绍。