elli 生产环境部署终极指南:rebar3 构建、OTP Release 与性能监控
【免费下载链接】elliSimple, robust and performant Erlang web server项目地址: https://gitcode.com/gh_mirrors/ell/elli
elli 是一款简单、稳健且高性能的 Erlang Web 服务器,专为构建高吞吐、低延迟的 HTTP API 而生。如果你正在为 Erlang/OTP 项目寻找一个轻量级的 HTTP 服务层,本文将从 rebar3 构建、OTP Release 打包到性能监控,带你一步步完成 elli 的生产环境部署,让线上服务稳定又高效。
为什么选择 elli:简单、稳健、高性能的 Erlang Web 服务器 🚀
elli 的设计哲学是"小而美",整个项目只有十几个源文件,核心代码集中在一个 acceptor 管理进程和若干 HTTP 处理进程中,学习成本极低。它不依赖 Cowboy、Mochiweb 等重型框架,也没有复杂的路由系统,而是把控制权完全交给你:
- 极简回调模型:只需要实现
handle/2和handle_event/3两个回调即可跑起来 - 原生支持 SSL:基于 Erlang/OTP 内置的 ssl 应用,无需额外依赖
- 中间件机制:支持请求预处理与响应后处理,例如内置的 gzip 压缩
- 极致性能:默认 20 个 acceptor 并发接受连接,backlog 高达 32768
elli 核心概念速览 📚
在动手部署之前,先花 1 分钟了解 elli 的组成模块,这有助于你理解后文的配置项:
| 模块 | 职责 |
|---|---|
src/elli.erl | acceptor 管理进程,负责监听 socket 与连接池调度 |
src/elli_http.erl | 每个连接的 HTTP 请求解析与响应处理 |
src/elli_request.erl | 请求参数、请求头、chunk 发送等便捷 API |
src/elli_middleware.erl | 中间件链,实现请求预处理与响应后处理 |
src/elli_middleware_compress.erl | 响应体自动 gzip 压缩 |
src/elli_test.erl | 为 handler 编写单元测试的辅助模块 |
其中,src/elli_handler.erl定义了回调行为(behaviour),所有业务回调模块都需要遵循它。
第一步:使用 rebar3 构建 elli 项目 🔨
1. 获取项目源码
首先将 elli 克隆到本地并编译:
git clone https://gitcode.com/gh_mirrors/ell/elli cd elli2. 使用 rebar3 编译
虽然项目自带了 rebar 与 Makefile,但生产环境更推荐使用 rebar3 进行构建:
rebar3 compile编译完成后,.beam文件会输出到_build/default/lib/elli/ebin目录。项目的rebar.config里配置了debug_info、xref 检查等选项,也可以直接运行项目自带的./rebar xref skip_deps=true做静态交叉引用检查,及早发现未定义函数调用等隐患。
3. 运行单元测试
部署前先跑一遍测试,确保一切正常:
rebar3 eunit测试用例集中在test/目录下,包括elli_http_tests.erl、elli_middleware_tests.erl、elli_tests.erl等,覆盖了 HTTP 解析、中间件、SSL 与 handover 等核心场景。
第二步:理解并调优 elli 启动参数 ⚙️
elli 通过elli:start_link(Opts)启动,常用配置项如下(默认值见src/elli.erl):
- port:监听端口,默认 8080
- ip:监听地址,默认
{0,0,0,0} - min_acceptors:初始 acceptor 数量,默认 20,高并发场景可调大
- ssl / keyfile / certfile:启用 HTTPS 及证书配置
- accept_timeout:accept 超时,默认 10000ms
- request_timeout:请求超时,默认 60000ms
- header_timeout / body_timeout:请求头与请求体读取超时
- max_body_size:最大请求体大小,默认 1024000 字节
- callback / callback_args:指定业务回调模块
一个典型的 HTTPS 启动配置示例:
elli:start_link([ {callback, my_http_handler}, {callback_args, []}, {port, 8443}, {ssl, true}, {keyfile, "priv/ssl/server_key.pem"}, {certfile, "priv/ssl/server_cert.pem"}, {min_acceptors, 50}, {max_body_size, 5242880} ]).测试证书可以参考test/server_cert.pem与test/server_key.pem。
第三步:打包 OTP Release 的最佳实践 📦
单靠rebar3 compile无法支撑生产环境,你需要把 elli 与业务代码一起打包成可独立发布的 OTP Release。
1. 添加 rebar3 release 插件
在项目的rebar.config中引入rebar3_relx(或使用relx),并配置 release 描述:
{plugins, [rebar3_hex, rebar3_run]}. {relx, [{release, {myapp_release, "0.1.0"}, [myapp, elli]}, {dev_mode, false}, {include_erts, true}, {extended_start_script, true}]}.2. 生成 Release
rebar3 release生成的产物位于_build/prod/rel/myapp_release,包含 ERTS 运行时与全部依赖,可直接拷贝到生产服务器解压运行:
bin/myapp_release foreground3. 使用 systemd 守护进程
生产环境推荐用 systemd 管理 elli 服务,实现开机自启与崩溃自动拉起:
[Unit] Description=Elli HTTP Server After=network.target [Service] ExecStart=/opt/myapp/bin/myapp_release foreground Restart=always User=erlang [Install] WantedBy=multi-user.target第四步:编写稳健的业务回调 🛡️
elli 的回调模块只需实现handle/2与handle_event/3(参考src/elli_example_callback.erl)。几个生产要点:
- 返回格式:
{ok, Headers, Body}或{Code, Headers, Body},Body 可以是 binary 或 iolist - 静态文件:返回
{file, Filename}可走 sendfile 零拷贝,支持 Range 断点续传 - 流式响应:返回
{chunk, Headers}后通过elli_request:send_chunk/2推送数据,适合 SSE 实时推送 - 异常兜底:在
handle_event中捕获request_throw、request_error等事件,避免进程异常退出影响连接池
使用中间件时,将callback指向elli_middleware,并通过mods参数串联各中间件,例如把elli_middleware_compress放在业务回调之前,响应体超过 1KB 时自动 gzip。
第五步:性能监控的四种实用方法 📊
elli 内置了轻量的监控接口,无需引入外部 APM 也能掌握服务健康状态。
方法一:查看 acceptor 数量
elli:get_acceptors/1返回当前存活的 acceptor 进程列表,数量持续低于min_acceptors说明连接池在收缩:
{ok, Acceptors} = elli:get_acceptors(ServerRef), length(Acceptors).方法二:统计在途请求数
elli:get_open_reqs/1返回正在处理的请求数,这是判断系统是否过载的关键指标。当该值长期接近进程上限时,说明需要扩容或调优:
{ok, OpenReqs} = elli:get_open_reqs(ServerRef, 5000).方法三:利用 request_complete 事件采集耗时
elli 在每次请求完成后会触发request_complete事件,Timings参数携带了从连接建立、请求解析到回调返回的完整时间戳。在handle_event/3中把这些数据写入 ETS 或上报到 Prometheus,即可构建请求耗时分布图,这是最细粒度的性能监控手段。
方法四:配合 observer 可视化观察
用observer:start()打开内置监控面板,观察 elli 各进程的 CPU、内存与消息队列,快速定位慢请求与内存泄漏。
常见问题与排错锦囊 🧰
Q1:SSL 握手失败,acceptor 耗尽?升级到 1.0.1 以上版本,该版本修复了 SSL acceptor 池因握手失败而耗尽的问题。
Q2:请求体过大被拒绝?调整max_body_size,同时监听bad_request事件(reason 为{body_size, ContentLength})做业务告警。
Q3:文件描述符耗尽?elli 检测到emfile会自动关停,请提前调大系统的ulimit -n。
Q4:如何优雅热更新业务逻辑?使用elli:set_callback/3可在不重启服务的情况下替换回调模块,配合 OTP release 的热升级机制实现零停机发布。
总结 ✨
elli 用最少的代码实现了稳健的 HTTP 服务能力。从 rebar3 构建、OTP Release 打包,到 acceptor 与请求级别的性能监控,本文覆盖了生产环境部署的全流程。记住两个核心监控指标:get_acceptors看连接池、get_open_reqs看负载,配合request_complete事件采集耗时,你的 elli 服务就能从容应对线上流量。现在就动手,把 elli 部署到你的生产环境吧!
【免费下载链接】elliSimple, robust and performant Erlang web server项目地址: https://gitcode.com/gh_mirrors/ell/elli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考