提供应用服务
运行函数式 Web 服务器。
提供应用服务 是 CoddyKit 上的免费 Scala for Backend Engineering & Functional Programming 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Scala for Backend Engineering & Functional Programming 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。
Ember 服务器
http4s 会在后端上运行您的 HttpApp[F]。现代应用的默认选择是 Ember:这是一个基于 cats-effect 和 fs2 构建的纯 Scala 服务器,可通过 org.http4s.ember.server.EmberServerBuilder 使用。
较旧的应用可能使用 Blaze,但今后推荐使用 Ember。
// build.sbt
// "org.http4s" %% "http4s-ember-server" % http4sV构建服务器
EmberServerBuilder.default[F] 会提供一个构建器,您可以流式配置它:绑定主机和端口、附加应用,然后调用 .build 获取 Resource[F, Server]。
使用 Resource 可以确保套接字在关闭时得到释放。
import com.comcast.ip4s._
import org.http4s.ember.server.EmberServerBuilder
EmberServerBuilder.default[IO]
.withHost(ipv4"0.0.0.0")
.withPort(port"8080")
.withHttpApp(app)
.buildip4s 字面量
Ember 使用 ip4s 类型实现类型安全的网络编程。ipv4"..." 和 port"..." 插值器会在编译时进行验证,因此无效地址或超出范围的端口无法通过编译。
导入 com.comcast.ip4s._ 即可使用它们。
import com.comcast.ip4s._
val host = host"localhost"
val p = port"8080"资源生命周期
服务器属于 Resource,因为它拥有必须正确打开和关闭的套接字。resource.use(_ => ...) 会让服务器在内部效果持续期间保持运行。
使用 IO.never 可以一直运行到进程被中断。
server.use(_ => IO.never).voidIOApp 入口点
http4s 应用的主类会扩展 IOApp,由它提供受管理的 cats-effect 运行时。您需要实现返回 IO[ExitCode] 的 run。
IOApp 会为您处理线程池、信号处理和优雅关闭。
import cats.effect.{IO, IOApp, ExitCode}
object Main extends IOApp {
def run(args: List[String]): IO[ExitCode] = ???
}完整的主程序
把这些组合起来:先构建服务器资源,然后使用 IO.never 调用 use,让进程保持运行,并返回 ExitCode.Success。
这是 http4s 标准的入口点。
def run(args: List[String]): IO[ExitCode] =
EmberServerBuilder.default[IO]
.withPort(port"8080")
.withHttpApp(app)
.build
.use(_ => IO.never)
.as(ExitCode.Success)组合资源
实际应用获取的不只是服务器,还可能包括数据库连接池、HTTP 客户端和配置。请在针对 Resource 的单个 for 推导中组合它们,这样所有资源都会按相反顺序释放。
将获取到的客户端传入路由构建过程。
for {
client <- EmberClientBuilder.default[IO].build
app = buildApp(client)
srv <- serverResource(app)
} yield srv优雅关闭
由于服务器位于 Resource 中,取消纤程(例如 IOApp 在收到 SIGTERM 时)会运行终结器,停止接受连接并关闭套接字。
Ember 会在可配置的关闭超时时间内处理完正在进行的请求。
EmberServerBuilder.default[IO]
.withShutdownTimeout(30.seconds)
.withHttpApp(app)
.build服务器中间件
将最终的 HttpApp 交给构建器之前,先用服务器中间件将其包装起来。常见的中间件包括 Logger、CORS、GZip 和 ErrorHandling。
顺序很重要:最外层的包装器最先看到请求,最后看到响应。
import org.http4s.server.middleware._
val finalApp = Logger.httpApp(true, false)(
CORS.policy.withAllowOriginAll(app)
)配置
使用 ciris 或 pureconfig 等配置库从环境中读取主机、端口和密钥,并将配置作为 Resource 或效果的一部分返回。
避免将端口硬编码,这样同一个二进制文件就能在不同环境中运行。
val port = sys.env.get("PORT")
.flatMap(Port.fromString)
.getOrElse(port"8080")健康检查与可观测性
提供类似 GET /health 的存活探针路由并返回 200,让编排器能够探测进程。添加请求日志和指标中间件,以便了解系统运行情况。
健康检查应保持开销低且不依赖其他服务,从而反映进程自身的状态,而不是下游服务的状态。
val health = HttpRoutes.of[IO] {
case GET -> Root / "health" => Ok("UP")
}快速检查
回忆一下服务器为什么要建模为 Resource。
回顾
您使用 EmberServerBuilder 提供了应用,通过 ip4s 字面量绑定地址,并在 IOApp 中使用 build.use(_ => IO.never) 运行它。
您组合了资源、包装了中间件、从环境中读取了配置、添加了健康检查路由,并依靠 Resource 实现优雅关闭。
常见问题解答
「提供应用服务」课时是免费的吗?
是的 — 「提供应用服务」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Scala for Backend Engineering & Functional Programming 课程的其余内容,请升级到 CoddyKit PRO。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。
「提供应用服务」这节课中我会学到什么?
运行函数式 Web 服务器。 你通过在浏览器中直接运行的动手代码来练习 Scala for Backend Engineering & Functional Programming,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Scala for Backend Engineering & Functional Programming 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Scala for Backend Engineering & Functional Programming 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「提供应用服务」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Scala for Backend Engineering & Functional Programming 课中编写并运行代码吗?
能。每节 Scala for Backend Engineering & Functional Programming 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。