⚙️ 服务端逻辑与 Agent 计算环境
核心定位: 后端是"大管家",负责逻辑计算、数据持久化与安全管理。本文档深入解析 Node.js/Libuv 异步机制、Python 后端选型、数据持久化、安全管理与 Docker 沙箱隔离。
关联文档: Full-Stack_AI_Engineering | 01-Web基础架构与通讯协议 | 05-AI云原生部署与托管实战(2026)
目录
- Node.js 的权力边界与职能定位
- Node.js 的内部架构:V8 与 Libuv
- 异步机制与事件循环]
- 数据持久化机制
- 安全管理与 API Key 保护
- Docker 容器化与沙箱隔离
- Python 后端选型与 FastAPI
- 知识要点总结
一、Node.js 的权力边界与职能定位
在 Web 全栈架构中,理解后端的第一步是理解 "权力边界"。
1.1 浏览器的"沙箱监狱"
在纯前端环境下(比如你用 Chrome 访问一个网页),JavaScript 被关在一个叫做 "沙箱 (Sandbox)" 的虚拟牢笼里。
- 物理限制:前端 JS 绝对不允许直接访问你的硬盘、查看你的文件夹或修改系统设置。
- 设计初衷:这是为了安全。否则,你随便点开一个恶意网站,它就能瞬间格式化你的 C 盘。
- 角色定位:前端是一个 "艺术家" ,它拥有极高的审美(CSS)和表现力(React),但它在物理层面是残疾的,不能触碰现实世界(硬件)。
关联文档: 02-现代前端工程:从V8到React - 浏览器渲染引擎
1.2 Node.js 的"监狱大门钥匙"
Node.js 的出现,本质上是把 V8 引擎从浏览器的沙箱里"提拔"了出来,并给它配上了一套能直接与操作系统对话的工具包。
- 角色定位:后端(主进程)是这栋建筑的 "大管家" 或 "安全主管" 。它不负责画画,但它手里拿着所有档案柜(硬盘)的钥匙。
- 实权体现:
- 文件系统 (File System):它可以绕过浏览器,直接在你的 D 盘创建一个
game_data.json文件。 - 网络管理 (Network):它可以直接开启网络服务器,监听端口,处理 HTTP 请求。
- 底层通讯:它可以直接连接串口、蓝牙等物理硬件。
- 进程管理:它可以创建子进程,执行系统命令。
- 文件系统 (File System):它可以绕过浏览器,直接在你的 D 盘创建一个
1.3 后端的"唯一性"与"健壮性"
在服务器架构中,后端服务通常以单实例或多实例集群的方式运行。
- 绝对核心:它是整个软件的生命中枢。如果前端页面报错了,可能只是某个按钮点不动;但如果后端逻辑崩溃了,整个服务会停止响应,因为主脑停止了工作。
- 高可用设计:生产环境通常使用负载均衡和多实例部署,确保单个实例崩溃时服务依然可用。
二、Node.js 的内部架构:V8 与 Libuv
你之前精准地察觉到,Node.js 能够识别后端指令,是因为它不仅有 V8,还有"助手"打通功能。这个助手的核心就是 Libuv。我们可以把 Node.js 的后端结构看作一个 "精密的人体系统"。
2.1 V8 引擎:纯粹的逻辑大脑
正如我们在前端专项中学到的,V8 是一个极其纯粹的"翻译官"。
- 它的视野:V8 眼中只有 JavaScript 语法。它知道什么是
if/else,什么是数组,什么是变量。 - 它的局限:它生活在数字的虚空里,完全不认识什么是"硬盘磁头",也不认识什么是"网卡"。如果你只给一个 V8 引擎运行
fs.readFile(),它会报错告诉你:"我不认识fs这个东西"。 - 一句话总结:V8 提供了智商(逻辑翻译),但没有提供体力(物理操作)。
关联文档: 02-现代前端工程:从V8到React - V8 引擎原理
2.2 Libuv:强壮的机械肌肉
这是 Node.js 能够成为"后端"的真正大功臣。Libuv 是一个用 C++ 编写的底层工具库。
- 打通物理世界:读写文件、网络连接、定时器,这些涉及操作系统的脏活累活,全是由 Libuv 负责执行的。
- 异步的秘诀:Libuv 内部有一个 "线程池"。当你让后端去读取一个巨大的文件时,Node.js 的主线程不会原地死等,而是把这个任务"外包"给 Libuv。Libuv 带着任务去敲操作系统的门,处理完后再回来汇报。
- 一句话总结:Libuv 提供了体力(系统交互),让 V8 的逻辑有了施展权力的空间。
2.3 协作全流程:一段 JS 代码的"修仙之路"
当我们编写一段后端代码 fs.writeFileSync('score.txt', '100') 时,内部发生了如下连锁反应:
- 翻译逻辑 (V8):V8 引擎读到这行字,明白你想调用一个叫
fs的模块里的写入函数。 - 寻找接口 (Bindings):Node.js 发现 V8 无法直接操作硬盘,于是通过 C++ Bindings(桥接器),找到了对应在 C++ 层面的
write功能。 - 分发任务 (Libuv):Node.js 把任务丢给 Libuv。Libuv 立刻指挥操作系统:"在当前目录下开辟一块扇区,写入文本 '100'"。
- 结果反馈:一旦硬盘写完了,Libuv 会发回一个信号。V8 接收信号,继续执行你代码里的下一步。
代码执行流程:
// 1. V8 解析 JS 代码
const fs = require('fs');
// 2. Node.js 通过 Binding 找到 C++ 实现
// 3. Libuv 执行系统调用
fs.writeFileSync('score.txt', '100');
// 4. Libuv 返回结果给 V8
// 5. V8 继续执行后续代码
console.log('文件写入完成');
2.4 为什么 Node.js 比浏览器里的 V8 强?
虽然大家用的都是同一个翻译官(V8),但 Node.js 在 V8 翻译的时候注入了更多的 "系统级词汇"。
- 浏览器环境:注入的是
document(画图词汇)、window(浏览器窗口词汇)。 - Node.js 环境:注入的是
fs(文件系统)、path(路径)、process(进程)、http(网络服务器)。 - 结果:环境给 V8 什么样的"外接插件",JS 就拥有什么样的权力。
Node.js 核心模块:
fs- 文件系统操作http/https- HTTP 服务器path- 路径处理crypto- 加密功能stream- 流处理events- 事件系统
三、异步机制与事件循环
3.1 单线程的挑战
Node.js 是单线程的,这意味着:
- 同一时间只能执行一个任务
- 如果某个任务耗时很长,会阻塞整个进程
- 无法利用多核 CPU 的优势
同步阻塞示例:
// ❌ 同步阻塞:会卡死整个进程
const data = fs.readFileSync('large-file.txt'); // 等待 5 秒
console.log('继续执行'); // 5 秒后才能执行
3.2 异步非阻塞的解决方案
Node.js 通过事件循环 (Event Loop) 实现了异步非阻塞:
异步非阻塞示例:
// ✅ 异步非阻塞:不卡死进程
fs.readFile('large-file.txt', (err, data) => {
if (err) throw err;
console.log('文件读取完成');
});
console.log('继续执行'); // 立即执行,不等待文件读取
3.3 事件循环机制详解
事件循环是 Node.js 的核心机制,它负责调度异步任务:
┌───────────────────────────┐
│ JavaScript 代码执行 │
└───────────┬───────────────┘
│
▼
┌───────────────────────────┐
│ Timers 阶段 │ 执行 setTimeout、setInterval
└───────────┬───────────────┘
│
▼
┌───────────────────────────┐
│ Pending Callbacks │ 执行延迟的 I/O 回调
└───────────┬───────────────┘
│
▼
┌───────────────────────────┐
│ Idle, Prepare │ 内部使用
└───────────┬───────────────┘
│
▼
┌───────────────────────────┐
│ Poll 阶段 │ 获取新的 I/O 事件
└───────────┬───────────────┘
│
▼
┌───────────────────────────┐
│ Check 阶段 │ 执行 setImmediate 回调
└───────────┬───────────────┘
│
▼
┌───────────────────────────┐
│ Close Callbacks │ 执行关闭回调(如 socket.on('close'))
└───────────┬───────────────┘
│
└───────────────┐
│
▼
(循环继续)
3.4 Promise 与 async/await
现代 Node.js 开发推荐使用 Promise 和 async/await,让异步代码更易读:
Promise 示例:
// Promise 方式
fs.promises.readFile('file.txt')
.then(data => {
console.log(data.toString());
})
.catch(err => {
console.error(err);
});
async/await 示例:
// async/await 方式(推荐)
async function readFile() {
try {
const data = await fs.promises.readFile('file.txt');
console.log(data.toString());
} catch (err) {
console.error(err);
}
}
四、数据持久化机制
在你的应用中,用户的每一个选项、每一分得分,最初都是存在内存里的。但内存是易失的,需要持久化到硬盘。
4.1 持久化:从"易失性内存"到"永恒性硬盘"
内存(RAM):绚丽但脆弱的舞台
- 物理特性:数据存储在电荷中。读写速度极快(纳秒级),足以支撑丝滑的 UI 动画。
- 致命弱点:易失性。只要软件关掉、断电、或者进程崩溃,内存里的所有数据会瞬间清空。
- 结论:前端的状态只是"瞬时记忆"。
硬盘(SSD/HDD):粗糙但坚固的档案室
- 物理特性:通过磁性或闪存单元存储。速度比内存慢千倍,但即使断电,数据依然存在。
- 后端的使命:Node.js 的核心工作之一,就是利用其
fs(File System) 模块,把内存里的"瞬时记忆"刻录进硬盘。
4.2 数据的"脱水"与"复活":JSON 序列化
硬盘不认识 JS 的"对象"或"数组",它只认识字符流。要完成持久化,必须经过一个物理转换过程。
序列化(Serialization)—— 脱水
当你告诉后端"存一下这组得分"时,后端会执行类似 JSON.stringify(data) 的操作。
- 逻辑本质:把一个活生生的、在内存里跳动的 JS 对象,压缩成一串死板的文本。
- 物理意义:这串文本就像是"脱水后的蔬菜干",它失去了运行时的灵活性,但变得极其易于运输和储存。
序列化示例:
const gameData = {
userId: '12345',
score: 95,
answers: ['A', 'B', 'C'],
timestamp: new Date()
};
// 序列化(脱水)
const jsonString = JSON.stringify(gameData);
// 结果:'{"userId":"12345","score":95,"answers":["A","B","C"],"timestamp":"2026-01-28T..."}'
// 写入文件
fs.writeFileSync('game-data.json', jsonString);
反序列化(Deserialization)—— 复活
当用户第二天重新打开应用:
- 后端先从硬盘读出那串死板的文本。
- 执行
JSON.parse(text),这串文本在内存中瞬间"吸水膨胀",变回了带属性、带方法的 JS 对象。 - 后端通过 API 把这个对象传给前端,React 拿到数据后重新渲染,用户会惊奇地发现:"昨天的进度还在!"
反序列化示例:
// 从文件读取
const jsonString = fs.readFileSync('game-data.json', 'utf-8');
// 反序列化(复活)
const gameData = JSON.parse(jsonString);
// 结果:{ userId: '12345', score: 95, answers: ['A', 'B', 'C'], ... }
// 使用数据
console.log(gameData.score); // 95
4.3 异步存取的"平衡艺术"
硬盘读写是"重活",如果后端在写大文件时原地死等,会发生什么?
阻塞(Blocking)的灾难
如果代码是同步运行的(readFileSync),后端主进程会被硬盘磁头拖住。此时,如果用户点击关闭按钮,或者前端发来新的 API 请求,后端将无法响应。在用户看来,服务"卡死了"。
同步阻塞示例:
// ❌ 同步阻塞:会卡死整个进程
const data = fs.readFileSync('large-file.txt'); // 等待 5 秒
// 这 5 秒内,无法处理其他请求
非阻塞(Non-blocking)的救赎
Node.js 默认推荐异步操作。
- 操作流程:后端发起写盘请求后,会立刻告诉系统:"你慢慢写,写完了发个通知给我,我先去处理别的业务了。"
- 物理结果:主进程始终保持清醒,随时准备接收前端的新请求。这就是为什么你的应用在后台悄悄存盘时,前台的响应依然流畅如初。
异步非阻塞示例:
// ✅ 异步非阻塞:不卡死进程
fs.readFile('large-file.txt', (err, data) => {
if (err) throw err;
console.log('文件读取完成');
});
// 立即继续执行,不等待文件读取
console.log('继续处理其他请求');
4.4 数据库 vs 文件系统
对于简单的数据存储,JSON 文件足够用。但对于复杂应用,需要使用数据库:
| 存储方式 | 适用场景 | 优势 | 劣势 |
|---|---|---|---|
| JSON 文件 | 小型应用、配置数据 | 简单、无需额外服务 | 并发写入困难、查询性能差 |
| SQLite | 中小型应用 | 轻量、无需服务器 | 并发性能有限 |
| PostgreSQL/MySQL | 大型应用 | 强大的查询能力、事务支持 | 需要单独部署 |
| MongoDB | 文档型数据 | 灵活的文档结构 | 内存占用较大 |
| Redis | 缓存、会话存储 | 极快的读写速度 | 数据易失(可配置持久化) |
五、安全管理与 API Key 保护
5.1 为什么 API Key 必须锁在"后端保险箱"?
如果你接入了 AI 大模型(如 DeepSeek 或 Gemini),你会获得一串 API Key。这串字符等同于你的支票签名。
前端是"透明的玻璃房"
- 代码可读性:无论你如何混淆压缩前端代码,只要用户按下
F12键打开开发者工具,或者通过网络抓包,前端发出的所有请求、包含的所有密匙都会赤裸裸地暴露。 - 风险模拟:如果你的 Key 在前端,黑客可以写个脚本偷走它,拿去倒卖或刷爆你的额度。你无法远程撤销这个泄露,只能注销 Key,导致所有正版用户也无法使用。
前端暴露 API Key 的风险:
// ❌ 危险做法:在前端直接使用 API Key
const apiKey = 'sk-1234567890abcdef'; // 任何人都能看到!
fetch('https://api.openai.com/v1/chat', {
headers: {
'Authorization': `Bearer ${apiKey}` // 在网络请求中暴露
}
});
后端是"实心的保险柜"
- 物理隔离:后端 Node.js 运行在独立的服务器进程中。用户物理上无法通过浏览器查看服务器的内存或源代码。
- 环境变量 (.env):我们将 Key 存在硬盘的一个隐藏配置文件里,只有后端管家有权限读取。
后端保护 API Key:
// ✅ 安全做法:在后端使用环境变量
require('dotenv').config();
const apiKey = process.env.OPENAI_API_KEY; // 从环境变量读取
// 前端请求后端 API
app.post('/api/chat', async (req, res) => {
// 后端使用 API Key 调用 OpenAI
const response = await fetch('https://api.openai.com/v1/chat', {
headers: {
'Authorization': `Bearer ${apiKey}` // Key 永远不会暴露给前端
},
body: JSON.stringify(req.body)
});
res.json(await response.json());
});
环境变量配置 (.env):
OPENAI_API_KEY=sk-1234567890abcdef
DATABASE_URL=postgresql://user:pass@localhost/db
5.2 后端中转逻辑(Backend Proxy):保镖式外交
为了保护 Key,我们不让前端直接和 AI 服务器对话。我们采用 "中转模式"。
协作流程的四步曲
-
前端提需求 (HTTP Request):用户输入"你是谁?",前端 React 通过 HTTP 请求告诉后端:"管家,用户有个问题要问 AI,请帮我转发一下。"(注意:此时不带任何 Key)。
-
后端接单:后端收到消息,从自己的"保险箱"里取出 API Key。
-
后端外交 (HTTP):后端拿着 Key 和问题,发起一个真正的网络请求(HTTP)去给 AI 服务器。
- AI 服务器看到的是后端的公章,它并不直接认识前端。
-
原路返回:AI 服务器把回答给后端,后端通过 HTTP 响应再把回答转交给前端艺术家进行渲染。
完整示例:
// 后端:Express.js 服务器
const express = require('express');
const app = express();
require('dotenv').config();
app.post('/api/chat', async (req, res) => {
// 1. 接收前端请求(不带 Key)
const { message } = req.body;
// 2. 后端使用自己的 Key 调用 AI API
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'gpt-4',
messages: [{ role: 'user', content: message }]
})
});
// 3. 返回结果给前端
const data = await response.json();
res.json(data);
});
app.listen(3000);
// 前端:React 组件
function ChatComponent() {
const [message, setMessage] = useState('');
const sendMessage = async () => {
// 前端只调用自己的后端 API,不直接调用 OpenAI
const response = await fetch('http://localhost:3000/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message })
});
const data = await response.json();
console.log(data);
};
return (
<div>
<input value={message} onChange={e => setMessage(e.target.value)} />
<button onClick={sendMessage}>发送</button>
</div>
);
}
5.3 这种模式的"物理优势"
- 身份隐匿:AI 平台的密匙永远不出后端的房门。
- 流量控制:后端可以在转发前检查用户是不是在"刷票"。比如:"这个用户一秒钟问了 100 次,一定是机器人,我不帮他转发了。" 这种逻辑在前端是做不到的,因为用户可以跳过前端逻辑直接调用接口。
- 成本控制:后端可以限制每个用户的调用次数,防止恶意刷 API。
限流示例:
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 分钟
max: 100 // 最多 100 次请求
});
app.use('/api/chat', limiter);
5.4 API 调用的异步陷阱:为什么界面不会转圈?
网络请求(HTTP)比写硬盘还要慢,而且受网速影响极大。
- 并发处理:Node.js 的事件循环(Event Loop)在这里发挥了巨大作用。
- 逻辑回执:当后端发起网络请求后,它会立刻挂起这个任务。此时,后端依然可以处理其他的 HTTP 请求(比如用户点击了其他功能)。
- 流式传输 (Streaming):就像看视频边下边播,后端可以把 AI 生成的文字,一个词一个词地通过 HTTP "吐"给前端,让用户看到那种逐字蹦出的打字机效果。
流式传输示例:
app.post('/api/chat/stream', async (req, res) => {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'gpt-4',
messages: req.body.messages,
stream: true
})
});
// 流式传输数据
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
res.write(`data: ${value}\n\n`);
}
res.end();
});
六、Docker 容器化与沙箱隔离
6.1 Docker:软件界的"标准集装箱"
如果你把代码比作"货物",那么 Docker 就是那个集装箱。
核心定义
Docker 是一种容器化技术。它不只是打包你的 Python 代码,而是把代码、运行环境(Python 3.10)、依赖库(LangChain, FastAPI)、甚至是操作系统最核心的文件全部封装在一起。
为什么开发者离不开 Docker?
- 解决环境差异:你的电脑是 Windows/Mac,服务器是 Linux。没有 Docker 时,你经常会遇到"在我电脑上明明能跑"的报错。有了 Docker,集装箱在哪打开都一样。
- 轻量化:相比传统的虚拟机(VM),Docker 容器非常小巧。它共用宿主机的内核,启动仅需几秒钟。
- 可移植性:你可以直接把在本地打包好的镜像(Image)推送到阿里云镜像仓库,然后在 ECS 上一键拉取运行。
关联文档: 05-AI云原生部署与托管实战(2026) - Docker 部署实践
6.2 Docker 与 AI Agent:不可或缺的"沙箱"
对于基于 ReAct 框架 的 Agent,Docker 有一个极其重要的用途:安全性隔离。
- 执行脚本风险:当你的 Agent 获得"执行 Python 脚本"的技能时,它可能会写出一些危险的代码(比如删除服务器文件)。
- 沙箱机制 (Sandboxing):如果你让 Agent 在 Docker 容器内运行,它就像是在一个密闭的玻璃房里操作。即便它写错了逻辑搞崩了系统,也只会影响这个容器,而不会伤到你的阿里云 ECS 宿主机。
Docker 沙箱示例:
# Dockerfile
FROM python:3.10-slim
WORKDIR /app
# 安装依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制代码
COPY . .
# 以非 root 用户运行(增强安全性)
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
# 运行应用
CMD ["python", "agent.py"]
# docker-compose.yml
version: '3.8'
services:
agent:
build: .
volumes:
- ./data:/app/data:ro # 只读挂载
- ./output:/app/output # 可写挂载
network_mode: "bridge"
restart: unless-stopped
6.3 关键术语:镜像 vs. 容器
为了方便你操作,请记住这对概念:
- 镜像 (Image):相当于一个"安装包"或"光盘"。它是静态的、只读的,包含了运行所需的所有文件。
- 容器 (Container):相当于从安装包里运行起来的"进程"。它是动态的,你的代码就在这里面实时跑着。
Docker 命令示例:
# 构建镜像
docker build -t my-agent:latest .
# 运行容器
docker run -d -p 8000:8000 --name my-agent my-agent:latest
# 查看运行中的容器
docker ps
# 查看容器日志
docker logs my-agent
# 停止容器
docker stop my-agent
# 删除容器
docker rm my-agent
6.4 Docker 在 ECS 上的部署
关联文档: 05-AI云原生部署与托管实战(2026) - ECS 部署与 Docker 容器化
七、Python 后端选型与 FastAPI
7.1 为什么选择 Python 作为 AI 后端?
- AI 生态丰富:Python 拥有最完善的 AI/ML 库生态(TensorFlow、PyTorch、LangChain、OpenAI SDK)
- 开发效率高:语法简洁,适合快速原型开发
- 异步支持:FastAPI 基于 asyncio,性能优秀
7.2 FastAPI 核心特性
FastAPI 是一个现代、快速的 Python Web 框架:
- 自动 API 文档:自动生成 Swagger/OpenAPI 文档
- 类型提示:基于 Python 类型提示,提供更好的 IDE 支持
- 异步支持:原生支持 async/await
- 高性能:性能接近 Node.js 和 Go
FastAPI 示例:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import os
app = FastAPI()
class ChatRequest(BaseModel):
message: str
@app.post("/api/chat")
async def chat(request: ChatRequest):
# 调用 AI API(API Key 从环境变量读取)
api_key = os.getenv("OPENAI_API_KEY")
# 这里调用 OpenAI API
# ...
return {"response": "AI 回复"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
7.3 Node.js vs Python:选型建议
| 维度 | Node.js | Python (FastAPI) |
|---|---|---|
| AI 生态 | 较弱 | 极强(LangChain、OpenAI SDK) |
| 性能 | 极高(V8 引擎) | 高(asyncio) |
| 开发效率 | 高 | 极高(语法简洁) |
| 适用场景 | 实时应用、微服务 | AI 应用、数据分析 |
建议:
- AI Agent 应用:选择 Python + FastAPI
- 实时 Web 应用:选择 Node.js + Express
- 混合架构:前端 Node.js,AI 后端 Python,通过 API 通信
八、知识要点总结
Node.js 的权力边界
| 概念 | 职能对位 | 物理本质 |
|---|---|---|
| 前端沙箱 | 安全限制 | 浏览器限制 JS 访问系统资源 |
| Node.js 后端 | 系统权限 | 通过 Libuv 访问文件系统、网络等 |
| 环境变量 | 配置管理 | 安全存储敏感信息(API Key) |
Node.js 的内部架构
| 组件 | 职能对位 | 核心作用 |
|---|---|---|
| V8 引擎 | 逻辑翻译 | 将 JS 代码翻译成机器指令 |
| Libuv | 系统交互 | 执行文件 I/O、网络操作等系统调用 |
| C++ Bindings | 桥接层 | 连接 JS 和 C++ 底层功能 |
异步机制与事件循环
| 概念 | 职能对位 | 核心价值 |
|---|---|---|
| 事件循环 | 任务调度 | 实现单线程下的异步非阻塞 |
| Promise | 异步抽象 | 更优雅的异步代码写法 |
| async/await | 语法糖 | 让异步代码看起来像同步 |
数据持久化机制
| 存储方式 | 适用场景 | 优势 |
|---|---|---|
| JSON 文件 | 小型应用 | 简单、无需额外服务 |
| 数据库 | 大型应用 | 强大的查询能力、事务支持 |
| 序列化 | 数据转换 | 内存对象与硬盘文本的桥梁 |
安全管理要点
| 环节 | 角色职能 | 核心目的 |
|---|---|---|
| API Key | 资产凭证 | 验证身份,需要存放在后端环境变量中 |
| Backend Proxy | 安全中转 | 物理隔离敏感信息,防止前端暴露密匙 |
| 限流 | 防护机制 | 防止恶意刷 API,控制成本 |
Docker 容器化
| 概念 | 职能对位 | 核心价值 |
|---|---|---|
| 镜像 | 静态模板 | 包含运行环境的所有文件 |
| 容器 | 运行实例 | 从镜像启动的进程 |
| 沙箱隔离 | 安全机制 | 防止 Agent 执行危险操作 |
下一步学习:
- 学习桌面应用开发:04-桌面端专题:Electron深度架构
- 学习部署实践:05-AI云原生部署与托管实战(2026)
- 回顾架构基础:01-Web基础架构与通讯协议