news 2026/8/8 23:51:19

如何基于Jupyter内核自研NoteBook

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何基于Jupyter内核自研NoteBook

简介

自研NoteBook如何高效地管理 Jupyter Kernel 的生命周期、处理代码执行请求,以及实现实时的消息推送,是其中的核心。本文将分享一套基于微服务架构的 Jupyter 内核管理系统的设计思路和实现方案。

租户Jupyter服务管理

1.使用miniforge管理python的依赖包

2.每个租户单独启动一个pod启动对应的jupyter服务,启动命令如下

/local/.miniforge3/bin/jupyter labextension disable @jupyterlab/docmanager-extension:download && /local/.miniforge3/bin/jupyter labextension disable @jupyterlab/filebrowser-extension:download && /local/.miniforge3/bin/jupyter labextension disable @jupyterlab/docmanager-extension:open-browser-tab && /local/.miniforge3/bin/jupyter labextension disable @jupyterlab/filebrowser-extension:open-browser-tab && //local/.miniforge3/bin/jupyter-lab --ServerApp.ip="*" --ServerApp.password="" --ServerApp.token="" --no-browser --allow-root --port=8888 --NotebookApp.base_url="/web/${IDE_CR_NAME}/jupyter" --NotebookApp.disable_check_xsrf=True

整体架构

系统采用微服务架构,将功能拆分为多个独立的服务模块,各司其职,

核心组件职责

  1. - **Web 服务层**: 提供 REST API 和 WebSocket 服务,处理前端请求,管理用户会话
  2. - **Gateway 层**: 作为中间层,管理内核连接池,转发消息,实现与 Jupyter Server 的解耦
  3. - **资源管理器**: 负责内核的路由和负载均衡,决定将请求分发到哪个 Gateway 实例
  4. - **Jupyter Kernel**: 实际执行代码的计算内核,一个pod部署一套jupyter服务

技术选型

  1. - **后端框架**: Spring Boot
  2. - **数据持久化**: MyBatis + MySQL
  3. - **实时通信**: WebSocket (JSR-356)
  4. - **消息中间件**: Redis Pub/Sub
  5. - **协议标准**: Jupyter Messaging Protocol 5.2

概念解释

1.Kernel (内核)

Kernel 是 Jupyter 生态系统的核心,它是一个独立的进程,负责执行用户提交的代码。每个 Kernel 都运行在独立的进程中,拥有自己的内存空间和执行环境。

Kernel 的特点:

  1. - **语言特定**: 每个 Kernel 对应一种编程语言,如 Python Kernel、Scala Kernel、Java Kernel 等
  2. - **状态保持**: Kernel 在运行期间会保持执行状态,变量、函数、导入的模块等都会保留在内存中
  3. - **独立进程**: 每个 Kernel 都是独立的进程,互不干扰,一个 Kernel 崩溃不会影响其他 Kernel
  4. - **生命周期管理**: Kernel 可以被创建、启动、停止、重启和删除

Kernel 的状态:

  1. - `idle`: 空闲状态,等待执行代码
  2. - `busy`: 正在执行代码
  3. - `starting`: 正在启动中
  4. - `dead`: 已停止或崩溃

**示例场景**:

```python # 在 Python Kernel 中执行 x = 10 y = 20 print(x + y) # 输出: 30 # 变量 x 和 y 仍然保留在 Kernel 的内存中 # 后续的代码可以继续使用这些变量

Session (会话)

Session 在 Jupyter 中有两层含义:

1. **WebSocket Session**: 客户端与服务器之间的 WebSocket 连接会话

2. **Jupyter Session**: Jupyter 协议中的会话标识,用于关联请求和响应

WebSocket Session:

- **连接会话**: 前端通过 WebSocket 与后端建立的长连接

- **双向通信**: 支持客户端和服务器之间的双向实时通信

- **状态管理**: 每个 Session 都有唯一的标识符,用于管理连接状态

- **生命周期**: Session 从连接建立开始,到连接关闭结束

Jupyter Session:

- **消息关联**: Jupyter 协议中,每个消息都有一个 `session` 字段,用于将请求和响应关联起来

- **执行上下文**: 通常使用 Cell ID 作为 Session ID,这样可以将执行结果与特定的代码单元关联

- **消息追踪**: 通过 Session ID 可以追踪一次代码执行的所有相关消息

**Session 的作用**:

```

前端发送执行请求

消息头中包含 session: "cell-123"

Kernel 执行代码并返回结果

响应消息中也包含相同的 session: "cell-123"

前端可以根据 session 将结果匹配到对应的代码单元

```

Cell (代码单元)

**什么是 Cell?**

Cell 是 Notebook 中的基本组成单位,是用户编写和执行代码的容器。

**Cell 的类型**:

- **Code Cell**: 代码单元,包含可执行的代码

- **Markdown Cell**: 文档单元,用于编写说明文档

- **Raw Cell**: 原始文本单元,不会被执行

**Cell 的生命周期**:

```

创建 Cell

编辑代码内容

执行 Cell (发送到 Kernel)

Kernel 执行代码

返回执行结果

显示结果 (输出、错误、状态等)

保存执行历史

```

Cell 的执行状态:

  1. - `idle`: 未执行或执行完成
  2. - `running`: 正在执行中
  3. - `queued`: 等待执行
  4. - `error`: 执行出错

Cell 与 Kernel 的关系

- 一个 Notebook 可以绑定一个 Kernel

- 一个 Kernel 可以执行多个 Cell 的代码

- Cell 的执行是顺序的,但可以通过异步机制实现并发

- 所有 Cell 共享同一个 Kernel 的执行环境(变量、函数等)

**示例**:

```python

# Cell 1

import pandas as pd

df = pd.DataFrame({'A': [1, 2, 3]})

# Cell 2 (可以访问 Cell 1 中定义的变量)

print(df.head()) # 输出 DataFrame 的前几行

内核创建流程详解

完整请求流程

关键设计点

内核创建接口

**接口设计**:

```http POST /api/kernel/bind Content-Type: application/json { "kernelName": "python3", "notebookId": "notebook-uuid" } ```

**响应示例**:

```json { "code": 0, "data": { "kernelId": "kernel-uuid", "status": "idle" } } ```

2.2.2 内核规格查询

系统支持查询可用的内核类型,前端可以根据此信息展示内核选择界面

```http GET /api/kernel/specs ```

返回所有已注册的内核规格,包括 Python、Scala、Java 等。

Session 管理机制

3.1 双层 Session 架构

系统采用双层 Session 管理,将用户会话和内核会话分离:

3.1.1 用户级 WebSocket Session

**连接端点**: `ws://host/api/user/{userId}`

**职责**:

- 用户级别的消息推送通道

- 接收前端发送的业务请求

- 通过 Redis Pub/Sub 接收系统推送的消息

**Session 管理**:

```java

// 使用线程安全的 Map 存储活跃的 WebSocket Session

private static final Map<String, Session> SESSIONS_MAP = new ConcurrentHashMap<>();

// 在线用户计数

private static final AtomicInteger ONLINE_COUNT = new AtomicInteger(0);

```

**关键特性**:

- **自动订阅**: 连接建立时自动订阅用户专属的 Redis Channel

- **心跳检测**: 支持心跳机制,保持连接活跃

- **优雅关闭**: 连接关闭时自动清理资源和监听器

#### 3.1.2 内核级 WebSocket Session

**连接端点**: `ws://host/api/kernel/{kernelId}`

**职责**:

- 内核级别的消息推送通道

- 接收内核执行结果的实时推送

- 每个内核有独立的订阅通道

Gateway 层连接池管理

Gateway 层维护一个 WebSocket 连接池,管理所有与 Jupyter Kernel 的连接:

@Service public class WebSocketPool { // 内核ID -> WebSocket连接的映射 private final static Map<String, WebSocketConnection> connectionMap = new ConcurrentHashMap<>(); public void addConnection(String kernelId, WebSocketConnection connection) { connectionMap.put(kernelId, connection); } public WebSocketConnection getConnection(String kernelId) { return connectionMap.get(kernelId); } public static void removeConnection(String kernelId) { connectionMap.remove(kernelId); }

核心 API 设计

内核管理 API

  1. | `/api/kernel/specs` | GET | 获取可用内核列表 |
  2. | `/api/kernel/list` | GET | 获取运行中的内核列表 |
  3. | `/api/kernel/bind` | POST | 创建并绑定内核到 Notebook |
  4. | `/api/kernel/delete` | DELETE | 删除内核 |

代码执行 API

  1. | `/api/cell/add` | POST | 添加新的代码单元 |
  2. | `/api/cell/save` | POST | 保存代码单元内容 |
  3. | `/api/cell/run` | POST | 执行代码单元 |
  4. | `/api/cell/result` | GET | 获取执行结果 |

Gateway 层 API

  1. | `/api/gateway/kernel/create` | POST | 创建内核实例 |
  2. | `/api/gateway/kernel/connect` | POST | 建立 WebSocket 连接 |
  3. | `/api/gateway/message/send` | POST | 发送代码执行请求 |
  4. | `/api/gateway/kernel/status` | GET | 检查内核状态 |

连接池管理

Gateway 层维护 WebSocket 连接池,避免重复创建连接:

```java WebSocketConnection connection = pool.getConnection(kernelId); if (connection == null) { connection = new WebSocketConnection(kernelId, endpoint); pool.addConnection(kernelId, connection); } ```
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/8 23:48:29

基于 RPA 的企业微信外部群主动调用:技术实现底层逻辑拆解摘要

企业微信官方未公开支持对外部群进行主动消息推送和批量管理的 API&#xff0c;导致运营和管理效率低下。本文将深入拆解实现外部群主动调用的两大技术底层逻辑&#xff1a;高效率、高风险的非官方 API 调用与低效率、相对合规的 RPA UI 自动化模拟。重点探讨 RPA 如何通过模拟…

作者头像 李华
网站建设 2026/8/8 23:47:00

RPA 的跨平台部署与统一自动化策略

一、引言&#xff1a;跨平台兼容性的必要性挑战&#xff1a; 企业内部用户可能使用 Windows 或 Mac 操作系统&#xff1b;而 Web 客户端因其轻量化和易于调试的特性&#xff0c;也是重要的自动化目标。痛点&#xff1a; 针对 Windows UI 编写的自动化脚本无法直接在 Mac 上运行…

作者头像 李华
网站建设 2026/8/8 23:45:37

爬虫爬了3亿URL去重标记炸了?Python布尔数组从set到位数组的踩坑实录

「部分情节为虚构演绎&#xff0c;仅供参考」做爬虫的同行都知道一个经典问题&#xff1a;URL去重。你爬一个大站&#xff0c;链接之间互相引用&#xff0c;爬虫很容易在同一个URL上反复抓取。所以你需要一个「已访问集合」——每抓到一个URL&#xff0c;先查一下有没有访问过&…

作者头像 李华
网站建设 2026/8/8 23:45:10

非官方API调用的随机化延迟(Jittering)调度优化

一、 背景&#xff1a;性能与风控的矛盾焦点 在执行批量任务&#xff08;如批量创建 $1000$ 个外部群&#xff09;时&#xff0c;自动化系统会连续发送大量的 API 请求。如果请求间隔是固定的&#xff08;例如&#xff0c;每 $1000\text{ms}$ 一次&#xff09;&#xff0c;这种…

作者头像 李华
网站建设 2026/8/8 23:39:49

安信可PB-03F蓝牙模块烧录全攻略:从工具选择到实战避坑

1. 项目概述&#xff1a;安信可PB-03F模块烧录入门 如果你手头有一块安信可的PB-03F蓝牙模块&#xff0c;想要让它跑起来&#xff0c;第一件绕不开的事就是“烧录”。这听起来有点技术门槛&#xff0c;但说白了&#xff0c;就是把你写好的程序或者官方提供的固件&#xff0c;像…

作者头像 李华
网站建设 2026/8/8 23:37:56

解锁微信聊天数据的三种魔法:从记忆碎片到AI伙伴的奇妙旅程

解锁微信聊天数据的三种魔法&#xff1a;从记忆碎片到AI伙伴的奇妙旅程 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/…

作者头像 李华