强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

02 - 环境搭建

第 02 章:环境搭建

工欲善其事,必先利其器。本章介绍 Erlang/OTP、rebar3 构建工具及 IDE 的安装与配置。


2.1 安装 Erlang/OTP

2.1.1 各平台安装方式总览

平台推荐方式命令
Ubuntu/Debianaptapt install erlang
CentOS/RHELyum / dnfdnf install erlang
macOSHomebrewbrew install erlang
Windows官方安装包下载 .exe 安装
通用asdf 版本管理asdf install erlang 27.0
通用kerl源码编译安装

2.1.2 Ubuntu / Debian

# 方式一:系统包(版本可能较旧)
sudo apt update
sudo apt install erlang

# 方式二:Erlang Solutions 官方仓库(推荐)
wget https://binaries2.erlang-solutions.com/ubuntu/pool/contrib/e/esl-erlang/esl-erlang_27.0-1~ubuntu~jammy_amd64.deb
sudo dpkg -i esl-erlang_27.0-1~ubuntu~jammy_amd64.deb

# 验证安装
erl -version
erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().' -noshell

2.1.3 macOS (Homebrew)

# 安装
brew install erlang

# 安装特定版本(使用 kerl 或 asdf)
brew install kerl

# 验证
erl -version
which erl

2.1.4 Windows

  1. 访问 Erlang 官网下载页
  2. 下载 Windows 64-bit 安装包(OTP_win64_27.0.exe)
  3. 运行安装程序,按默认选项安装
  4. C:\Program Files\erl-27.0\bin 添加到 PATH
# PowerShell 验证
erl -version

2.1.5 使用 asdf 版本管理(推荐)

asdf 可以管理多个 Erlang 版本,非常适合需要切换版本的场景:

# 安装 asdf(如果尚未安装)
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.0
echo '. "$HOME/.asdf/asdf.sh"' >> ~/.bashrc

# 添加 Erlang 插件
asdf plugin add erlang https://github.com/asdf-vm/asdf-erlang.git

# 查看可用版本
asdf list all erlang

# 安装指定版本
asdf install erlang 27.0
asdf global erlang 27.0

# 验证
erl -version

2.1.6 使用 kerl 源码编译

# 下载 kerl
curl -O https://raw.githubusercontent.com/kerl/kerl/master/kerl
chmod +x kerl
sudo mv kerl /usr/local/bin/

# 列出可用版本
kerl list releases

# 构建并安装
kerl build 27.0 27.0
kerl install 27.0 ~/erlang/27.0

# 激活
. ~/erlang/27.0/activate

# 验证
erl -version

💡 注意:源码编译需要先安装依赖:

# Ubuntu/Debian
sudo apt install build-essential autoconf libncurses5-dev \
    libssl-dev flex libwxgtk3.0-gtk3-dev libgl1-mesa-dev \
    libglu1-mesa-dev libpng-dev

# CentOS/RHEL
sudo dnf install gcc make autoconf ncurses-devel openssl-devel \
    flex wxGTK3-devel mesa-libGL-devel mesa-libGLU-devel libpng-devel

2.2 安装 rebar3

rebar3 是 Erlang 生态中最主流的构建工具(类似 Java 的 Maven、Node.js 的 npm)。

2.2.1 安装方式

# 方式一:官方脚本(推荐)
wget https://s3.amazonaws.com/rebar3/rebar3
chmod +x rebar3
sudo mv rebar3 /usr/local/bin/

# 方式二:从源码构建
git clone https://github.com/erlang/rebar3.git
cd rebar3
./bootstrap
sudo cp rebar3 /usr/local/bin/

# 方式三:Homebrew (macOS)
brew install rebar3

# 验证
rebar3 version

2.2.2 rebar3 核心命令

命令作用
rebar3 new app <name>创建新的 OTP 应用
rebar3 new lib <name>创建纯库项目
rebar3 new release <name>创建带 release 的项目
rebar3 compile编译项目
rebar3 eunit运行 EUnit 测试
rebar3 ct运行 Common Test
rebar3 dialyzer静态类型分析
rebar3 shell启动交互式 Shell(含依赖)
rebar3 release构建发布包
rebar3 tar打包发布包
rebar3 hex publish发布到 Hex.pm
rebar3 deps获取依赖

2.2.3 创建第一个项目

# 创建 OTP 应用
rebar3 new app myapp
cd myapp

# 查看项目结构
tree .
# myapp
# ├── README.md
# ├── rebar.config
# ├── src
# │   ├── myapp.app.src
# │   ├── myapp_app.erl
# │   └── myapp_sup.erl
# └── test
#     └── (测试文件)

# 编译
rebar3 compile

# 运行
rebar3 shell

2.2.4 rebar.config 配置示例

%% rebar.config

{erl_opts, [
    debug_info,           %% 包含调试信息
    warnings_as_errors,   %% 警告视为错误
    {parse_transform, lager_transform}  %% lager 日志转换
]}.

{deps, [
    {cowboy, "2.12.0"},             %% HTTP 服务器
    {jsx, "3.1.0"},                 %% JSON 库
    {gun, "2.1.0"},                 %% HTTP 客户端
    {jiffy, "1.1.1"}                %% JSON (NIF 实现)
]}.

{relx, [
    {release, {myapp, "0.1.0"}, [myapp, sasl]},
    {dev_mode, true},
    {include_erts, false},
    {sys_config, "config/sys.config"},
    {vm_args, "config/vm.args"}
]}.

{profiles, [
    {prod, [
        {relx, [
            {dev_mode, false},
            {include_erts, true}
        ]}
    ]},
    {test, [
        {deps, [
            {meck, "0.9.2"},
            {proper, "1.4.0"}
        ]}
    ]}
]}.

{dialyzer, [
    {warnings, [
        error_handling,
        underspecs,
        unmatched_returns
    ]},
    {plt_extra_apps, [mnesia]}
]}.

2.3 IDE 与编辑器配置

2.3.1 编辑器对比

编辑器/IDEErlang 支持推荐度特点
VS Code插件支持⭐⭐⭐⭐⭐最流行,erlang-ls 集成
IntelliJ IDEAErlang 插件⭐⭐⭐⭐重构能力强
Vim/Neovimerlang-ls⭐⭐⭐⭐高效,需配置
Emacserlang-mode⭐⭐⭐⭐原生支持好
Sublime Text插件⭐⭐⭐轻量

2.3.2 VS Code 配置(推荐)

安装步骤:

  1. 安装 VS Code
  2. 安装 erlang-ls 扩展(Erlang Language Server)
  3. 可选:安装 Erlang/OTP 语法高亮扩展
// .vscode/settings.json
{
    "erlang.erlangPath": "/usr/local/bin",
    "erlang.rebar3Path": "/usr/local/bin/rebar3",
    "erlang.linting": true,
    "editor.tabSize": 4,
    "editor.insertSpaces": false,
    "files.associations": {
        "*.erl": "erlang",
        "*.hrl": "erlang",
        "*.app.src": "erlang"
    }
}

erlang-ls 安装:

# 安装 erlang-ls(语言服务器)
git clone https://github.com/erlang-ls/erlang_ls.git
cd erlang_ls
rebar3 compile
rebar3 escriptize
cp _build/default/bin/erlang_ls /usr/local/bin/

# 或者使用 Erlang LS 预编译版本
# 从 GitHub Releases 下载

工作区配置(erlang_ls.config):

# erlang_ls.config(放在项目根目录)
apps_dirs:
  - "lib/*"
deps_dirs:
  - "_build/default/lib/*"
  - "_checkouts/*"
include_dirs:
  - "include"
  - "_build/default/lib/*/include"
diagnostics:
  - dialyzer
  - elvis
  - compiler

2.3.3 Vim / Neovim 配置

使用 nvim-lspconfig + erlang_ls

-- init.lua (Neovim)
require('lspconfig').erlang_ls.setup{
    cmd = { "erlang_ls" },
    filetypes = { "erlang" },
    root_dir = require('lspconfig').util.root_pattern("rebar.config", ".git"),
    settings = {
        erlang_ls = {
            dialyzerEnabled = true,
            elvisEnabled = true
        }
    }
}

2.3.4 Emacs 配置

;; .emacs 或 init.el
;; Erlang 官方模式(通常随 Erlang 安装)
(setq load-path (cons "/usr/local/lib/erlang/lib/tools-3.5/emacs" load-path))
(require 'erlang-start)

;; 自动加载
(add-to-list 'auto-mode-alist '("\\.erl\\'" . erlang-mode))
(add-to-list 'auto-mode-alist '("\\.hrl\\'" . erlang-mode))

;; 缩进设置
(setq erlang-indent-level 4)

;; Erlang LS 集成
(require 'lsp-mode)
(add-hook 'erlang-mode-hook #'lsp)

2.4 Erlang Shell (REPL)

2.4.1 基础使用

%% 启动 Shell
$ erl
Erlang/OTP 27 [erts-14.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1]

Eshell V14.0  (abort with ^G)
1> 1 + 1.
2
2> "Hello, Erlang!".
"Hello, Erlang!"
3> halt().

2.4.2 Shell 常用快捷键

快捷键功能
Ctrl+C中断当前操作 / 进入 BREAK 菜单
Ctrl+GJCL 模式(切换 Shell)
Ctrl+D退出 Shell
Tab自动补全
Up/Down历史命令
Ctrl+A行首
Ctrl+E行尾

2.4.3 Shell 特殊命令

%% 查看历史
1> h().

%% 使用历史结果
2> 1 + 1.
2
3> v(2).     %% 引用第 2 行的结果
2

%% 编译并加载模块
4> c(my_module).

%% 查看模块导出函数
5> m(io).

%% 查看进程信息
6> i().

%% 退出
7> q().

2.4.4 Shell 限制

⚠️ 注意:Shell 中有些语法与源文件不同

%% Shell 中定义函数需要这样写:
1> Double = fun(X) -> X * 2 end.
#Fun<erl_eval.44.123456789>
2> Double(5).
10

%% Shell 中不能直接使用 -module, -export 等属性
%% 这些只能在 .erl 源文件中使用

2.5 项目结构详解

2.5.1 标准 OTP 项目结构

myapp/
├── rebar.config              # 构建配置
├── config/
│   ├── sys.config            # 应用配置
│   └── vm.args               # VM 启动参数
├── src/
│   ├── myapp.app.src         # 应用描述文件
│   ├── myapp_app.erl         # Application 回调模块
│   ├── myapp_sup.erl         # Supervisor 模块
│   └── myapp_server.erl      # 业务模块
├── include/
│   └── myapp.hrl             # 头文件
├── test/
│   ├── myapp_SUITE.erl       # Common Test
│   └── myapp_server_tests.erl # EUnit 测试
├── priv/
│   └── static/               # 静态资源
└── _build/                   # 构建输出(自动生成)
    ├── default/
    │   └── lib/
    └── default/
        └── rel/

2.5.2 应用描述文件

%% src/myapp.app.src
{application, myapp, [
    {description, "My Erlang Application"},
    {vsn, "0.1.0"},
    {registered, [myapp_server]},
    {mod, {myapp_app, []}},     %% 启动模块
    {applications, [
        kernel,
        stdlib,
        cowboy    %% 依赖
    ]},
    {env, [
        {port, 8080},           %% 配置项
        {pool_size, 10}
    ]},
    {modules, []},              %% rebar3 自动填充
    {licenses, ["Apache-2.0"]},
    {links, []}
]}.

2.5.3 VM 启动参数

%% config/vm.args
## 节点名称
-name myapp@127.0.0.1

## Cookie(集群认证)
-setcookie myapp_cookie

## 调度器数量(默认等于 CPU 核心数)
## +S 8:8 表示 8  CPU 调度器 + 8  IO 调度器

## 最大进程数
+P 1048576

## 最大 ETS 表数量
+e 65536

## 异步线程池大小
+A 128

## 垃圾回收参数
+MBas aobf
+MBacul 0

2.6 Dialyzer 配置

Dialyzer 是 Erlang 的静态类型分析工具,可以在编译期发现类型错误。

2.6.1 类型规范(Type Spec)

-module(math_utils).
-export([add/2, divide/2]).

%% 类型规范:接受两个 integer,返回 integer
-spec add(integer(), integer()) -> integer().
add(A, B) ->
    A + B.

%% 可能返回错误的情况
-spec divide(number(), number()) -> {ok, float()} | {error, string()}.
divide(_A, 0) ->
    {error, "division by zero"};
divide(A, B) ->
    {ok, A / B}.

2.6.2 运行 Dialyzer

# 构建 PLT(持久查找表,首次运行较慢)
rebar3 dialyzer

# 或手动构建 PLT
dialyzer --build_plt --apps erts kernel stdlib crypto

# 分析单个文件
dialyzer my_module.erl

# 分析项目
dialyzer _build/default/lib/myapp/ebin/

2.7 Observer 可视化工具

Observer 是 Erlang 内置的图形化监控工具:

%% 在 Shell 中启动
1> observer:start().

%% 或从菜单启动
%% 应用程序 → observer

Observer 提供:

  • System:系统概览(CPU、内存、进程数)
  • Processes:进程列表和详情
  • Ports:端口信息
  • ETS:ETS 表浏览器
  • Applications:应用监控树
  • Graphs:实时性能图表

2.8 注意事项

⚠️ 版本兼容性

问题说明
OTP 版本不同版本之间 API 可能有变化,注意文档版本
rebar3 版本保持 rebar3 更新到最新稳定版
系统包版本apt/yum 的 Erlang 版本通常较旧,建议用 asdf/kerl
NIF 兼容使用 NIF 时注意 OTP 版本匹配

💡 最佳实践

  1. 使用 asdfkerl 管理 Erlang 版本,避免系统包
  2. 每个项目固定 Erlang 版本(.tool-versions 文件)
  3. 新项目优先使用 rebar3 new release 模板
  4. 安装完后立即运行 rebar3 dialyzer 建立 PLT
# .tool-versions(asdf 版本固定文件)
erlang 27.0

2.9 扩展阅读


上一章:01 - Erlang 简介 下一章:03 - Hello World