分布式系统
南科大 CS328 分布式系统课程的一组项目,涵盖三个相互关联的部分:一个不依赖 java.rmi 的自定义 Java RMI 框架、基于 Docker 的多服务部署,以及对约 97 万条真实停车数据的 PySpark 分析流水线。
亮点
- 从头实现 Java RMI 风格框架——服务注册表、动态代理存根(
java.lang.reflect.Proxy)、骨架线程以及通过 socket 传输的序列化InvocationMsg/ReturnMsg——不使用java.rmi - 以具体的
MatrixCalculator远程服务演示框架,服务端和客户端通过自定义注册表和存根层通信 - 使用 Docker 多阶段构建和 Docker Compose 将完整系统容器化;三个独立服务(注册表、服务器、客户端)通过环境变量互相发现
- 使用 PySpark 处理约 97 万条真实停车数据,产出包括时间窗口利用率和 Spark DAG 可视化在内的五项分析结果
- 在 Java 代码库(约 700 行)中全面应用 CheckStyle 保证代码质量
MyRMI — 从头实现远程方法调用
核心工作是实现一个不依赖内置 java.rmi 库的 Java RMI 风格远程调用框架,手工构建了 RMI 栈的每一层:
- 注册表 —
RegistryImpl处理对象的bind和lookup;LocateRegistry提供客户端工厂;注册表调用本身也通过RegistryStubInvocationHandler经网络代理 - 存根 —
StubInvocationHandler实现java.lang.reflect.InvocationHandler,拦截远程接口上的任意方法调用,将其序列化为InvocationMsg发送 - 骨架 —
SkeletonReqHandler线程接收传入消息,反序列化后通过反射分发调用,并将结果以ReturnMsg返回 - 消息 —
InvocationMsg和ReturnMsg通过 socket 连接传递方法名、参数类型、参数值和返回值 - 异常 —
RemoteException、AlreadyBoundException、NotBoundException镜像标准 RMI 异常层次
源码结构:6 个包中的 16 个 Java 文件
服务端日志:存根创建、注册表绑定与查找
测试服务暴露了一个带有两个实现的 MatrixCalculator 远程接口,允许多个服务通过同一注册表实例按名称注册和解析。
MyRMI_Docker — 容器化部署
框架进一步扩展为使用 Docker 和 Docker Compose 的真实多服务部署。注册表、服务器和客户端各运行在独立容器中:
- 每个服务使用多阶段
Dockerfile:Maven 在构建阶段编译,最小化 OpenJDK 镜像用于运行时 -
docker-compose.yaml定义启动顺序(注册表 → 服务器 → 客户端)及服务间依赖 - 服务发现使用环境变量(
REGISTRY_HOST、SERVER_PORT)——无硬编码地址
三个容器启动并完成端到端 RMI 调用——注册表绑定 Mortgage 服务,客户端查找并执行远程计算
SparkProcessing — 大规模停车数据分析
PySpark 流水线分析深圳停车数据(约 97 万行,1,930 个车位,43 条路段)。
五项分析任务:
- 每条路段的车位数量
- 唯一车位与路段的映射关系
- 每个车位的平均停车时长
- 分时段利用率及百分比
- 各路段高峰时段识别
样例输出:各路段车位数量统计
某任务的 Spark DAG——早期阶段(CSV 扫描、排序聚合)因结果缓存被跳过;AQE 优化最终 shuffle
技术概览
| 语言 | Java 8, Python 3 |
| 基础设施 | Docker, Docker Compose |
| 框架 | PySpark, Maven |
| 关键概念 | RPC、动态代理、序列化、服务注册、容器编排、DAG 执行 |
| 数据集 | 约 97 万条真实停车数据 |
| 代码质量 | Java 代码库全面应用 CheckStyle |