跳到主要内容

部署和运行

本章将详细介绍如何部署和运行 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.printsii.readTextsii.dbsii.get 等),需要启动运行时服务器。

启动运行时服务器

# 启动运行时服务器(默认端口 3000)
sii-runtime-server

运行时服务器提供以下功能:

  • 文件系统操作(sii.readTextsii.writeTextsii.exists 等)
  • 数据库操作(sii.db.table() 等)
  • HTTP 服务器功能(sii.getsii.post 等)
  • 命令执行(sii.execsii.execOut 等)
  • JSON 处理(sii.jsonParsesii.jsonStringify 等)

浏览器部署

  1. 编译代码
siic app.sii app.js --js
  1. 创建 HTML 文件
<!DOCTYPE html>
<html>
<head>
<title>My Sii App</title>
</head>
<body>
<script src="app.js"></script>
</body>
</html>
  1. 注意:如果代码使用了运行时服务器功能,需要确保运行时服务器正在运行,并且代码能够访问到服务器(通常通过 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_64
  • arm64-windows / aarch64-windows - Windows ARM64
  • x64-linux / x86_64-linux - Linux x86_64
  • arm64-linux / aarch64-linux - Linux ARM64
  • x64-macos / x86_64-macos - macOS x86_64
  • arm64-macos / aarch64-macos - macOS ARM64

完整 LLVM triple 格式

  • x86_64-pc-windows-msvc - Windows x86_64 (MSVC)
  • x86_64-unknown-linux-gnu - Linux x86_64
  • aarch64-unknown-linux-gnu - Linux ARM64
  • x86_64-apple-darwin - macOS x86_64
  • aarch64-apple-darwin - macOS ARM64

运行

原生可执行文件可以直接运行,无需额外运行时:

# Linux/macOS
./app

# Windows
app.exe

原生编译要求

  1. LLVM 工具链

    • llc:LLVM 编译器(用于将 LLVM IR 编译为对象文件)
    • clang:C/C++ 编译器(用于链接)
  2. 运行时库

    • 编译器会自动查找预编译的静态运行时库
    • 库文件位置:安装包的 lib/ 目录
    • Linux/macOS: libsii_runtime.a
    • Windows: libsii_runtime.a
  3. 自定义工具路径(可选):

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

解决方案

  1. 确保安装包包含 lib/libsii_runtime.a(或 sii_runtime.lib
  2. 或设置 SII_RUNTIME_DIR 环境变量指向运行时源码目录

问题 2:JavaScript 代码无法访问运行时服务器

错误:Failed to connect to runtime server

解决方案

  1. 确保运行时服务器正在运行:sii-runtime-server
  2. 检查服务器端口(默认 3000)
  3. 检查防火墙设置

问题 3:原生可执行文件无法运行

错误:No such file or directory

解决方案

  1. 检查文件权限:chmod +x app
  2. 检查动态库依赖:ldd app(Linux)
  3. 确保目标平台匹配

最佳实践

1. 选择正确的编译目标

  • Web 应用:使用 JavaScript/TypeScript + 运行时服务器
  • 命令行工具:使用原生编译
  • 性能关键应用:使用原生编译

2. 开发环境

  • 使用 siic watch 进行开发
  • 使用 siic serve 启动开发服务器
  • 保持运行时服务器运行

3. 生产环境

  • 使用原生编译获得最佳性能
  • 将运行时服务器部署为系统服务
  • 配置日志和监控

4. 安全考虑

  • 限制运行时服务器的访问
  • 使用 HTTPS(如果支持)
  • 验证用户输入
  • 定期更新运行时服务器

小结

本章介绍了 Sii 2 程序的部署和运行:

  • JavaScript/TypeScript 部署:需要运行时服务器支持
  • WebAssembly 部署:转换为二进制格式后运行
  • 原生可执行文件部署:静态链接,可直接运行
  • 运行时服务器部署:作为独立服务运行
  • Docker 部署:容器化部署方式
  • 故障排查:常见问题和解决方案

下一章是附录,包含参考信息和常见问题解答。