跳转至

StarryNet 源码剖析

源码面前, 了无秘密 -- 侯捷 (C++)

StarryNet 这个项目的核心组成皆在 $STARRYNET/starrynet 下:

从用户角度, 自顶向下依次是:

  • StarryNet (sn_synchronizer.py) - 主入口
  • Observer (sn_observer.py) - 计算卫星轨道/延迟
  • Utils (sn_utils.py) - 远程机器管理/多线程协调
  • Orchestrator (sn_orchestrater.py) - Docker资源操控

接下来, 本文将从系统层面, 自顶向上地解析这些文件, 在这一过程中体会其函数封装 / 高层函数对底层辅助函数的调用细节. 从而对该项目有更加直观且深入的理解.

PS: 非常建议新手先参考 DeepWiki - StarryNet 了解项目全貌

Orchestrator

最底层的执行引擎,基于 Docker / tc 等工具操控网络和容器

链路建立:

  • sn_ISL_establish - 为每颗卫星建立星间链路 (ISL)
    • 轨道内链路 (Le_): 同轨道相邻卫星
    • 轨道间链路 (La_): 不同轨道卫星
    • 使用 tc qdisc netem 模拟延迟、丢包、带宽
  • sn_establish_GSL - 建立卫星-地面站链路 (GSL)

网络配置:

Bash
1
2
3
4
# 创建 Docker 网络: 10.x.x.0/24 (ISL) 或 9.x.x.0/24 (GSL)
docker network create ISL_name --subnet 10.x.x.0/24
# 配置网卡延迟/丢包/带宽
tc qdisc add dev B1-eth2 root netem delay 10ms loss 1% rate 10Gbit

动态更新:

  • sn_update_delay - 更新链路延迟(卫星移动导致)
  • sn_damage_link / sn_recover_link - 模拟故障和恢复
积累结论

(1) IP:

  • ISL: 10.x.x.0/24
    • Intra-orbit ISL:
      • sat: .40
      • down_sat: .10
    • Inter-orbit ISL:
      • sat: .30
      • right_sat: .20
  • GSL: 9.x.x.0/24
    • Satellite: .50
    • GS: .60

(2) Calling conventions:

  • Network Name:

    • InterOrbit ISL: La_{current_sat_id}-{current_orbit_id}_{right_sat_id}-{right_orbit_id}
    • IntraOrbit ISL: Le_{current_sat_id}-{current_orbit_id}_{down_sat_id}-{down_orbit_id}
    • GSL: GSL_{sat_id}-{GS_id}
  • Network Interface:

    • B{global_id}-eth{peer_global_id}
  • Config Files:

    • B{global_id}.conf
源码解读: 这一部分最难, 也最重要

传送门 - 笔者的解读

Utils

中间层,管理多机器部署和多线程任务

远程机器管理:

  • sn_init_remote_machine - SSH 连接远程机器
  • sn_remote_cmd - 执行远程命令
  • 使用 paramiko 库实现 SSH/SFTP 操作

对象类管理:

  1. class sn_Node_Init_Thread: 初始化整个docker container
    • 步骤:
      • reset整个环境
      • 每个机器上的container聚合成一个list
      • 有list之后, 重新给这些container分配索引
    • 效果: 整个集群的container可以根据“集体索引”引用
      • 原来: 某容器called abcdef
      • 现在: 此容器called ovs_container_NUM
  2. class sn_Link_Init_Thread: 创建所有链路
    • 上传编排脚本到远程机器
    • 上传初始拓扑文件(第1秒的延迟矩阵)
    • 调用远程的sn_orchestrater.py建立链路
      • 回顾上述 Orchestrator 部分, 建立 network + 配置 tc
  3. sn_Routing_Init_Thread: 将BIRD配置文件拷贝到每个容器内,并启动路由进程
    • 上传编排脚本到远程机器
    • 调用远程脚本配置BIRD路由
  4. sn_Emulation_Start_Thread: 运行仿真主循环

重要的辅助函数:

  1. sn_reset_docker_env - 清理旧环境并创建新容器
  2. sn_ping / sn_perf - 测试工具
  3. sn_establish_new_GSL - 动态建立新 GSL 链路 [星地连接]
Danger

如果我们想自定义一些“底层操作”, 建议参考这些类和函数的接口和实现.

比如: 打印 routing path ...

Observer

数据计算层,负责卫星轨道预测和网络拓扑生成

轨道计算:

calculate_delay - 主函数

  • 使用 SGP4 模型计算卫星位置 [skyfield]
  • 计算 sat-sat、sat-gs 的延迟矩阵
  • 保存到 delay/1.txt, delay/2.txt ...

星地连接选择:

access_P_L_shortest: 计算可见性和最短路径

  • 使用天线仰角查看 visible satellite
  • 按"距离"排序选择最近的卫星

路由配置:

  • generate_conf - 生成 BIRD OSPF 配置文件
  • compute_conf - 为每个节点计算接口配置

拓扑变化检测:

matrix_to_change - 检测链路变化

输出到 Topo_leo_change.txt(文本格式: 时间 + 添加/删除的链路

Synchronizer

顶层 API, 用户访问的起点

初始化实验环境:

__init__():

  1. 加载配置 (config.json)
  2. 创建 Observer 计算轨道
  3. 连接远程机器 SSH
  4. 生成 BIRD 路由配置

操作类型的API: 其实就是调用在utils里定义的类

  • create_nodes(): 创建 Docker 容器
    • 调用utils.sn_Node_Init_Thread
  • create_links(): 建立所有链路
    • 调用utils.sn_Link_Init_Thread
  • run_routing_deamon(): 启动 BIRD 路由
    • 调用utils.sn_Routing_Init_Thread
  • start_emulation(): 开始仿真主循环
    • 调用utils.sn_Routing_Init_Thread
  • stop_emulation() 停止仿真 + 析构
    • 调用utils.sn_Emulation_Stop_Thread

查询类型的API: 积累

  • get_neighbors - 获取某卫星的邻居
  • get_GSes - 获取某卫星可见的地面站
  • get_position - 获取卫星经纬度
  • get_distance - 获取两颗卫星距离

测试 API: 积累

  • set_ping - 设置 ping 测试
    • set_ping(self, a, b, t): a ping b. starting from t.
  • set_perf - 设置 iperf3 带宽测试
    • set_perf(self, a, b, t): a iperf b. starting from t.
  • set_damage - 模拟节点故障
    • set_damage(self, a, t): link-i's link "damaging_ratio" is set to a from t.