
Deno 无法在 Jupyter Notebook 中稳定启动 HTTP 服务,根本原因在于端口复用冲突与生命周期管理缺失:每次执行 Deno.serve() 会独占端口,而 Jupyter 单元格重运行不会自动关闭前序服务,导致 AddrInUse 错误。本文提供可落地的解决方案与工程化建议。
deno 无法在 jupyter notebook 中稳定启动 http 服务,根本原因在于端口复用冲突与生命周期管理缺失:每次执行 `deno.serve()` 会独占端口,而 jupyter 单元格重运行不会自动关闭前序服务,导致 `addrinuse` 错误。本文提供可落地的解决方案与工程化建议。
Jupyter Notebook 的设计初衷是交互式、状态隔离的代码执行环境,而非长期运行的服务容器。当你在单元格中调用 Deno.serve({ port: 80001 }, handler),Deno 会在后台启动一个阻塞式 HTTP 服务器(基于 Rust tokio runtime),该进程持续监听端口 80001 并保持 socket 打开。而 Jupyter 的 Python 内核(或 Deno 内核)并不具备自动终止子进程的能力——这意味着:
- ✅ 第一次运行:服务成功启动,但 Jupyter 前端不会自动跳转或弹窗(这是预期行为,
Deno.serve不触发浏览器导航); - ❌ 第二次运行:内核尝试再次绑定同一端口 → 触发系统级错误
AddrInUse: Only one usage of each socket address... (os error 10048)。
? 正确做法:显式控制服务生命周期
你不能依赖“重运行单元格”来热更新服务。必须将启动、停止、重启逻辑拆分为独立可控的操作。以下是推荐方案(适用于 Deno + Jupyter,如 jupyter-deno-kernel 或通过 deno run --watch 外部集成):
✅ 方案一:使用 AbortController 主动终止(推荐)
// 【单元格 1】定义并启动服务(带可取消能力)
let server: Deno.HttpServer | undefined;
const controller = new AbortController();
async function startServer() {
if (server) await server.shutdown(); // 确保先清理旧服务
server = Deno.serve({
port: 80001,
signal: controller.signal, // 关联中断信号
handler: (_req) => new Response("Hello, World! ?", {
headers: { "Content-Type": "text/plain" }
})
});
console.log("✅ Server running at http://localhost:80001");
}
await startServer();// 【单元格 2】手动停止服务(运行此单元格后再修改 handler)
if (server) {
await server.shutdown();
console.log("⏹️ Server stopped.");
}
controller.abort(); // 中断 signal,确保资源释放? 提示:修改
handler后,务必先运行【单元格 2】,再运行【单元格 1】——这才是安全的“重启”。
⚠️ 方案二:换用非阻塞开发模式(更符合 Jupyter 范式)
避免在 Notebook 中长期驻留 HTTP 服务。改用 Deno 的 --watch 模式配合外部终端:
# 在系统终端(非 Jupyter 单元格)中执行 deno run --allow-net --watch server.ts
其中 server.ts 内容为:
const handler = (req: Request) => new Response("Hello from Deno! ?");
Deno.serve({ port: 80001 }, handler);此时 Jupyter 仅用于编写、调试 handler 逻辑,而服务由独立进程托管——既规避端口冲突,又支持文件保存即自动重启。
? 重要注意事项
-
端口选择:Windows 默认限制
1024以下端口需管理员权限,建议使用8000+(如80001可行,但8080/3000更通用); -
防火墙与浏览器:首次访问
http://localhost:80001需手动在浏览器中输入(Jupyter 不会自动打开);若遇连接拒绝,请检查 Windows 防火墙是否放行该端口; -
内核兼容性:截至 2026 年,官方尚未发布 Deno 原生 Jupyter 内核(
jupyter-deno-kernel仍属社区维护)。生产环境建议优先使用 VS Code + Deno 扩展,或转向 JupyterLab + NodeJS Kernel 配合express进行类比验证; -
替代思路:对教学/演示场景,可用
Deno.serve返回的Promise结合setTimeout模拟短时服务(不推荐线上),或直接使用Deno.inspect()输出 HTML 片段在 Notebook 中渲染静态内容。
✅ 总结
Jupyter 是探索性计算的利器,但不是 Web 服务的运行时。在 Deno 与 Jupyter 协同工作中,应恪守「逻辑分离」原则:
? Notebook 负责 handler 编写、数据构造与 API 响应测试;
? 终端/脚本负责服务启停、端口管理与进程监控。
唯有如此,才能兼顾交互效率与系统稳定性——这也是现代前端与 AI 工程师在 LLM 开发、本地模型 API 封装等场景中的通用实践范式。

















