部署和运行
本章将详细介绍如何部署和运行 Sii 2 编译后的程序,包括不同编译目标的部署方式、运行时服务器配置和最佳实践。
部署概述
Sii 2 编译器支持多种编译目标,每种目标的部署方式不同:
- JavaScript/TypeScript:需要运行时服务器支持,在浏览器或 Node.js 中运行
- WebAssembly (WAT):需要转换为二进制格式,在浏览器或 WebAssembly 运行时中运行
- LLVM IR:中间表示,需要进一步编译
- 原生可执行文件:静态链接运行时库,可直接运行,无需额外运行时
JavaScript/TypeScript 部署
编译
# 编译为 JavaScript
siic app.sii app.js --js
# 编译为 TypeScript
siic app.sii app.ts --ts
# 编译为 TypeScript 并运行类型检查
siic app.sii app.ts --ts --tsc
运行时服务器
重要:编译为 JavaScript/TypeScript 的 Sii 代码如果使用了标准库功能(如 sii.io.print、sii.readText、sii.db、sii.get 等),需要启动运行时服务器。
启动运行时服务器
# 启动运行时服务器(默认端口 3000)
sii-runtime-server
运行时服务器提供以下功能:
- 文件系统操作(
sii.readText、sii.writeText、sii.exists等) - 数据库操作(
sii.db.table()等) - HTTP 服务器功能(
sii.get、sii.post等) - 命令执行(
sii.exec、sii.execOut等) - JSON 处理(
sii.jsonParse、sii.jsonStringify等)
浏览器部署
- 编译代码:
siic app.sii app.js --js
- 创建 HTML 文件:
<!DOCTYPE html>
<html>
<head>
<title>My Sii App</title>
</head>
<body>
<script src="app.js"></script>
</body>
</html>
- 注意:如果代码使用了运行时服务器功能,需要确保运行时服务器正在运行,并且代码能够访问到服务器(通常通过 HTTP 请求)。
Node.js 部署
# 编译
siic app.sii app.js --js
# 运行(需要运行时服务器)
node app.js
注意:Node.js 环境中,如果代码使用了标准库功能,同样需要运行时服务器支持。
开发模式
Sii 编译器提供了开发模式,方便开发时使用:
# watch 模式:文件变化时自动重新编译
siic watch app.sii app.js --js
# serve 模式:启动开发服务器(包含代理功能)
siic serve app.sii app.js --js --port=4173 --proxy=http://localhost:3000
WebAssembly 部署
编译
# 编译为 WebAssembly (WAT 文本格式)
siic app.sii app.wat --wasm
转换为二进制格式
WAT (WebAssembly Text) 格式需要转换为二进制 WASM 格式:
# 使用 wat2wasm 工具(需要安装 WebAssembly Binary Toolkit)
wat2wasm app.wat -o app.wasm
浏览器部署
<!DOCTYPE html>
<html>
<head>
<title>WASM App</title>
</head>
<body>
<script>
WebAssembly.instantiateStreaming(fetch('app.wasm'))
.then(obj => {
// 使用 WASM 模块
obj.instance.exports.main();
})
.catch(err => {
console.error('Failed to load WASM:', err);
});
</script>
</body>
</html>
命令行运行
# 使用 wasmtime(需要安装)
wasmtime app.wasm
# 或使用其他 WebAssembly 运行时
wasmer app.wasm
原生可执行文件部署
编译
原生编译将 Sii 代码编译为平台特定的可执行文件,静态链接运行时库,无需额外运行时:
# 编译为原生可执行文件(使用默认目标平台)
siic native app.sii -o app
# 指定目标平台(简化格式)
siic native app.sii -o app -t=x64-linux
siic native app.sii -o app -t=arm64-macos
siic native app.sii -o app.exe -t=x64-windows
# 使用完整 LLVM triple
siic native app.sii -o app --triple=x86_64-unknown-linux-gnu
支持的目标平台
简化格式:
x64-windows/x86_64-windows- Windows x86_64arm64-windows/aarch64-windows- Windows ARM64x64-linux/x86_64-linux- Linux x86_64arm64-linux/aarch64-linux- Linux ARM64x64-macos/x86_64-macos- macOS x86_64arm64-macos/aarch64-macos- macOS ARM64
完整 LLVM triple 格式:
x86_64-pc-windows-msvc- Windows x86_64 (MSVC)x86_64-unknown-linux-gnu- Linux x86_64aarch64-unknown-linux-gnu- Linux ARM64x86_64-apple-darwin- macOS x86_64aarch64-apple-darwin- macOS ARM64
运行
原生可执行文件可以直接运行,无需额外运行时:
# Linux/macOS
./app
# Windows
app.exe
原生编译要求
-
LLVM 工具链:
llc:LLVM 编译器(用于将 LLVM IR 编译为对象文件)clang:C/C++ 编译器(用于链接)
-
运行时库:
- 编译器会自动查找预编译的静态运行时库
- 库文件位置:安装包的
lib/目录 - Linux/macOS:
libsii_runtime.a - Windows:
libsii_runtime.a
-
自定义工具路径(可选):
siic native app.sii -o app --llc=/usr/local/bin/llc --clang=/usr/local/bin/clang
分发原生程序
原生可执行文件是自包含的,可以直接分发:
# 创建发布包
mkdir -p release/app-1.0.0
cp app release/app-1.0.0/
cp README.md release/app-1.0.0/
# 创建压缩包
cd release
tar -czf app-1.0.0-linux-x64.tar.gz app-1.0.0/
运行时服务器部署
作为独立服务
运行时服务器是一个独立的 HTTP 服务器,可以部署为系统服务:
systemd (Linux)
创建服务文件 /etc/systemd/system/sii-runtime.service:
[Unit]
Description=Sii Runtime Server
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/sii-app
ExecStart=/usr/local/bin/sii-runtime-server
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
启动服务:
sudo systemctl daemon-reload
sudo systemctl enable sii-runtime
sudo systemctl start sii-runtime
launchd (macOS)
创建 plist 文件 ~/Library/LaunchAgents/com.sii.runtime.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.sii.runtime</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/sii-runtime-server</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
加载服务:
launchctl load ~/Library/LaunchAgents/com.sii.runtime.plist
运行时服务器 API
运行时服务器提供以下 HTTP 端点:
GET /- 服务器信息GET /health- 健康检查POST /db/connect- 连接数据库POST /db/query- 执行数据库查询POST /fs/readText- 读取文件POST /fs/writeText- 写入文件POST /exec/exec- 执行命令POST /http/register- 注册 HTTP 路由POST /run/js- 运行 JavaScript 代码
Docker 部署
原生应用
FROM alpine:latest
WORKDIR /app
# 复制可执行文件
COPY app .
# 运行应用
CMD ["./app"]
构建和运行:
docker build -t my-sii-app .
docker run my-sii-app
运行时服务器
FROM debian:bookworm-slim
WORKDIR /app
# 复制运行时服务器
COPY sii-runtime-server .
# 暴露端口
EXPOSE 3000
# 运行服务器
CMD ["./sii-runtime-server"]
性能优化
原生编译优化
原生编译已经启用了优化:
- LLVM 优化级别:
-O3 - 链接时优化 (LTO):启用
- 代码生成单元:1(最大化优化)
运行时服务器优化
- 使用异步 I/O(基于 tokio)
- 连接池管理(数据库连接)
- 并发请求处理
故障排查
常见问题
问题 1:原生编译失败 - 找不到运行时库
错误:Cannot find runtime library
解决方案:
- 确保安装包包含
lib/libsii_runtime.a(或sii_runtime.lib) - 或设置
SII_RUNTIME_DIR环境变量指向运行时源码目录
问题 2:JavaScript 代码无法访问运行时服务器
错误:Failed to connect to runtime server
解决方案:
- 确保运行时服务器正在运行:
sii-runtime-server - 检查服务器端口(默认 3000)
- 检查防火墙设置
问题 3:原生可执行文件无法运行
错误:No such file or directory
解决方案:
- 检查文件权限:
chmod +x app - 检查动态库依赖:
ldd app(Linux) - 确保目标平台匹配
最佳实践
1. 选择正确的编译目标
- Web 应用:使用 JavaScript/TypeScript + 运行时服务器
- 命令行工具:使用原生编译
- 性能关键应用:使用原生编译
2. 开发环境
- 使用
siic watch进行开发 - 使用
siic serve启动开发服务器 - 保持运行时服务器运行
3. 生产环境
- 使用原生编译获得最佳性能
- 将运行时服务器部署为系统服务
- 配置日志和监控
4. 安全考虑
- 限制运行时服务器的访问
- 使用 HTTPS(如果支持)
- 验证用户输入
- 定期更新运行时服务器
小结
本章介绍了 Sii 2 程序的部署和运行:
- JavaScript/TypeScript 部署:需要运行时服务器支持
- WebAssembly 部署:转换为二进制格式后运行
- 原生可执行文件部署:静态链接,可直接运行
- 运行时服务器部署:作为独立服务运行
- Docker 部署:容器化部署方式
- 故障排查:常见问题和解决方案
下一章是附录,包含参考信息和常见问题解答。