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 | |
动态更新:
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
- sat:
- Inter-orbit ISL:
- sat: .30
- right_sat:
.20
- Intra-orbit ISL:
- GSL:
9.x.x.0/24- Satellite:
.50 - GS:
.60
- Satellite:
(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}
- InterOrbit ISL:
-
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 操作
对象类管理:
class sn_Node_Init_Thread: 初始化整个docker container- 步骤:
- reset整个环境
- 每个机器上的container聚合成一个list
- 有list之后, 重新给这些container分配索引
- 效果: 整个集群的container可以根据“集体索引”引用
- 原来: 某容器called
abcdef - 现在: 此容器called
ovs_container_NUM
- 原来: 某容器called
- 步骤:
class sn_Link_Init_Thread: 创建所有链路- 上传编排脚本到远程机器
- 上传初始拓扑文件(第1秒的延迟矩阵)
- 调用远程的
sn_orchestrater.py建立链路- 回顾上述 Orchestrator 部分, 建立 network + 配置 tc
sn_Routing_Init_Thread: 将BIRD配置文件拷贝到每个容器内,并启动路由进程- 上传编排脚本到远程机器
- 调用远程脚本配置BIRD路由
sn_Emulation_Start_Thread: 运行仿真主循环
重要的辅助函数:
sn_reset_docker_env- 清理旧环境并创建新容器sn_ping / sn_perf- 测试工具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__():
- 加载配置 (config.json)
- 创建 Observer 计算轨道
- 连接远程机器 SSH
- 生成 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 fromt.
set_perf- 设置 iperf3 带宽测试set_perf(self, a, b, t):a iperf b. starting fromt.
set_damage- 模拟节点故障set_damage(self, a, t):link-i's link "damaging_ratio" is set toafromt.