Elixir 的诞生
Elixir 由巴西工程师 José Valim 创建,于 2012 年正式发布。Valim 曾是 Ruby on Rails 核心团队成员,他深入研究了 Erlang/OTP 之后,决定在其上创建一门更现代、更友好的语言——保留 BEAM VM 的全部威力,同时引入 Ruby 的优雅语法与强大的元编程能力。
为什么从 Ruby on Rails 转向 Erlang? Valim 在优化 Rails 并发性能时遭遇了 GIL(全局解释器锁)的限制——Ruby 的多线程无法真正并行。他在研究各种解决方案时发现了 Erlang,被其天生并发、容错设计深深折服,随即投身 BEAM 生态。
BEAM VM:为电信而生的虚拟机
BEAM(Bogdan/Björn's Erlang Abstract Machine)由爱立信(Ericsson)在 1980 年代为电话交换机开发。电信系统对可靠性的要求极为苛刻:
- 容错设计 进程间完全隔离,一个进程崩溃不影响其他进程。"Let it crash"哲学:不必预防所有错误,让进程崩溃后由 Supervisor 自动重启即可。
- 热代码升级 系统运行中直接替换代码,零停机部署。爱立信 AXD301 电话交换机曾达到 99.9999999%(九个九)的可用性,每年停机不到 31 毫秒。
- 百万轻量进程 BEAM 进程不是 OS 线程,初始堆仅约 2KB,可在单机创建数百万个进程。每个进程有独立堆,GC 是进程级别的,不会出现全局 Stop-The-World 停顿。
- 分布式内置 多个 BEAM 节点可透明地互相通信,向远程节点的进程发送消息与本地无异,天生支持分布式系统。
- 软实时特性 BEAM 调度器使用抢占式调度(reduction 计数),防止长时间运行的进程饿死其他进程,保证响应延迟的可预期性。
Elixir vs Go vs Node.js:并发模型对比
| 特性 | Elixir / BEAM | Go | Node.js |
|---|---|---|---|
| 并发原语 | Actor 模型(进程 + 消息) | CSP(goroutine + channel) | 事件循环(单线程) |
| 进程/协程开销 | ~2KB 初始堆 | ~8KB 初始栈 | 无真正并行(GIL 类似) |
| 容错机制 | Supervisor 树,内置 | 需手动实现 | 需手动实现 |
| 状态共享 | 不可变,消息传递 | 共享内存 + mutex | 共享内存(单线程) |
| 热更新 | 原生支持 | 不支持 | 不支持 |
| 垃圾回收 | 进程级(无全局 STW) | 并发 GC(低延迟) | V8 GC(偶发 STW) |
| 典型案例 | Discord、WhatsApp | Kubernetes、Docker | 大量 Web 应用 |
Discord 的 Elixir 实践:Discord 在 2017 年分享了他们用 Elixir 支撑 500 万并发用户的架构。每个 Discord 服务器(Guild)就是一个 GenServer 进程,彼此完全隔离。当某个 Guild 进程崩溃,Supervisor 会在毫秒级重启,其他 Guild 完全不受影响。
安装 Elixir
方案一:asdf(推荐,版本管理)
asdf 是通用的运行时版本管理器,支持 Elixir、Erlang、Node.js 等几乎所有语言。
# 1. 安装 asdf(macOS)
brew install asdf
# 2. 添加 Erlang 和 Elixir 插件
asdf plugin add erlang
asdf plugin add elixir
# 3. 安装 Erlang(Elixir 依赖 Erlang)
asdf install erlang 27.0
asdf global erlang 27.0
# 4. 安装 Elixir
asdf install elixir 1.17.0-otp-27
asdf global elixir 1.17.0-otp-27
# 5. 验证
elixir --version
# Erlang/OTP 27 [erts-15.0] ... Elixir 1.17.0
方案二:Homebrew(macOS 快速安装)
# Homebrew 会自动安装 Erlang 依赖
brew install elixir
# 验证
elixir --version
iex --version
方案三:Windows
# 使用 Chocolatey 包管理器
choco install elixir
# 或下载官方安装包:
# https://elixir-lang.org/install.html#windows
Erlang 版本兼容性:Elixir 版本与 Erlang/OTP 版本有对应关系。使用 asdf 安装时,请确保 Elixir 版本标注了对应的 OTP 版本(如 1.17.0-otp-27)。查看兼容矩阵:https://hexdocs.pm/elixir/compatibility-and-deprecations.html
iex:交互式 REPL
iex(Interactive Elixir)是 Elixir 的交互式 Shell,类似 Python 的 REPL。它是学习和调试 Elixir 的最佳工具。
# 启动 iex
iex
# 在 iex 中尝试:
iex> 1 + 2
3
iex> "Hello, " <> "Elixir!"
"Hello, Elixir!"
iex> [1, 2, 3] |> Enum.map(&(&1 * 2))
[2, 4, 6]
iex> i "hello" # 查看数据类型信息
iex> h Enum.map # 查看文档
iex> v(1) # 获取第1行结果
在 iex 中运行项目
# 在项目根目录启动,加载项目模块
iex -S mix
# 连接到运行中的 Phoenix 服务器(远程调试)
iex --remsh myapp@localhost
mix:Elixir 的构建工具
mix 是 Elixir 的官方构建工具,类似 Node.js 的 npm/Cargo,集项目管理、依赖管理、代码生成、测试于一身。
# 创建新项目
mix new hello_world
cd hello_world
# 项目结构:
# ├── lib/
# │ └── hello_world.ex — 主模块
# ├── test/
# │ └── hello_world_test.exs
# ├── mix.exs — 项目配置(类似 package.json)
# └── .formatter.exs — 代码格式化配置
# 常用 mix 命令
mix deps.get # 安装依赖(类似 npm install)
mix compile # 编译项目
mix test # 运行测试
mix format # 格式化代码
mix docs # 生成文档
mix hex.search xxx # 搜索 Hex 包(Elixir 包仓库)
mix.exs 项目配置
# mix.exs
defmodule HelloWorld.MixProject do
use Mix.Project
def project do
[
app: :hello_world,
version: "0.1.0",
elixir: "~> 1.17",
deps: deps()
]
end
defp deps do
[
{:jason, "~> 1.4"}, # JSON 解析库
{:httpoison, "~> 2.0"} # HTTP 客户端
]
end
end
第一个 Hello World 程序
# lib/hello_world.ex
defmodule HelloWorld do
@moduledoc """
第一个 Elixir 模块
"""
def greet(name) do
"Hello, #{name}! Welcome to Elixir 💜"
end
def greet(:world) do
"Hello, World!"
end
end
# 在 iex 中运行:
# iex> HelloWorld.greet("José")
# "Hello, José! Welcome to Elixir 💜"
# iex> HelloWorld.greet(:world)
# "Hello, World!"
# 直接运行脚本文件(.exs 是脚本,不编译)
# hello.exs
IO.puts("Hello, World!")
IO.puts(HelloWorld.greet("Elixir"))
# 运行:
elixir hello.exs
核心名词解释
- BEAM Bogdan/Björn's Erlang Abstract Machine,Erlang 语言的虚拟机。Elixir、Erlang、Gleam、LFE 等多门语言都运行在 BEAM 上,共享其并发与容错能力。
- OTP Open Telecom Platform,爱立信为 Erlang 开发的中间件框架,包含 GenServer、Supervisor、Application 等核心行为(Behaviour)模式。OTP 是构建可靠分布式系统的工程实践结晶。
- Actor 模型 一种并发计算范式:计算单元(Actor)通过发送/接收消息进行通信,Actor 之间没有共享内存。BEAM 的进程就是 Actor 的实现,天生线程安全,无需锁。
- 进程隔离 每个 BEAM 进程有独立的内存堆,进程间不能直接访问对方内存,只能通过消息传递通信。这使得一个进程崩溃不会污染其他进程的状态。
-
Hex
Elixir/Erlang 的包仓库,类似 npm registry。
mix deps.get从 hex.pm 下载依赖。Hex 包质量普遍较高,因为 Elixir 社区有强烈的文档文化(ExDoc 文档是标配)。 - Mix Elixir 官方构建工具。集成了项目创建、依赖管理、编译、测试、代码格式化、自定义任务等功能。Phoenix 等框架在 mix 之上添加了大量代码生成命令(mix phx.gen.*)。
- Reduction BEAM 调度的基本单位,大约对应一次函数调用。BEAM 调度器让每个进程运行固定数量的 reduction 后切换,实现公平的抢占式调度,防止单个进程独占 CPU。
本章小结:Elixir 是构建在 BEAM VM 之上的现代函数式语言,继承了 Erlang 数十年的电信级可靠性经验。其 Actor 并发模型、进程隔离、Supervisor 容错机制使其天生适合高并发、高可用系统。mix 和 iex 是开发过程中最常用的工具。下一章我们深入 Elixir 的语法基础。