尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

iFogSim边缘计算仿真:从环境部署到自定义拓扑的完整实践手册

发布时间:2026/9/26 4:27:14

资讯中心
01
ARTICLE

iFogSim边缘计算仿真:从环境部署到自定义拓扑的完整实践手册

iFogSim边缘计算仿真:从环境部署到自定义拓扑的完整实践手册
简介这是一套面向边缘计算研究与开发的 iFogSim 仿真平台完整源代码包主要服务高校师生、科研人员及物联网开发者用于模拟边缘网络中的设备分布、资源分配与任务调度评估不同架构下的延迟、吞吐量和负载表现。压缩包内共353个文件以289个 Java 源文件为核心辅以30余张架构图与运行效果图png/gif、7个依赖 jar 包、6个 Excel 和2个 ODS 实验数据表格以及多种拓扑定义、PDF/Markdown 说明文档整体约29.58MB。包内自带 cloudsim 相关依赖和多组可运行的仿真模块覆盖云、雾、边缘分层场景并附有实测结果文件便于对照资源利用率、响应时间等关键指标也方便复现论文中的仿真数据。资源已有1499人学习下载后解压导入 IDE 即可运行也可基于源码二次扩展节点类型与调度策略适合需要快速搭建边缘计算实验平台的初学者和研究人员。1. 边缘计算仿真绕不开 iFogSim这份 zip 把依赖和示例都备齐了做边缘计算的方案选型和论文实验最难的部分往往不是算法本身而是手上没有几十台真实设备让你验证节点部署和任务调度。iFogSim 就是这个场景下使用最广的开源仿真平台它把 CloudSim 的云数据中心模型扩展到了网络边缘让你在笔记本上就能模拟传感器、雾节点、云数据中心之间的数据流和任务执行。这份 iFogSim-master.zip 是 GitHub 上 master 分支的完整源码包解压后不用再到处找 CloudSim 依赖因为根目录已经放好了三个关键 jar导入 IDE 或命令行直接编译就能跑官方示例。它能解决的是边缘计算架构的前期评估节点该分几层、带宽给多大、任务放边缘还是放云跑一轮仿真就能拿到延迟、能耗和网络使用量这几类核心指标。适合做边缘计算毕设、投小论文、或者需要给团队一个部署预研结论的开发者。下面先拆模块边界再带你把它跑起来。2. 先拆模块边界从 CloudSim 到 FogDevice 的继承关系与 jar 清单2.1 这份压缩包里装了什么文件与 jar 的职责解压后第一眼不要被根目录下的文件搞乱它不是乱七八糟的附件包而是官方实验留下的拓扑描述、一张可视化图以及 iFogSim 编译运行必需的三个 jar。很多新手一进来就盯着 src 看忽略了对类路径影响最大的这几个文件后面编译时各种缺类才回头找。文件或目录实际作用src/iFogSim 全部源码核心实现都在这里Copy of vr_game_topo云游戏场景的拓扑定义vr 指游戏画面渲染的应用场景dcns_game_topo数据中心网络模拟场景的拓扑描述dcns 是 Data Center Network Simulator 的缩写dcnsCloud、dcnsFog对应 dcns 拓扑中的云节点与雾节点配置1.gif示例拓扑的可视化结果图跑实验前可以先看这张图建立直觉cloudsim-examples-3.0.3.jarCloudSim 3.0.3 官方示例 jar包含 iFogSim 运行时需要的 CloudSim 核心类cloudsim-examples-3.0.3-sources.jar上述 jar 的源码查 CloudSim API 时用guava-18.0.jarGoogle 的集合、缓存工具库iFogSim 内部数据结构依赖它commons-math3-3.5.jarApache Commons Math统计计算和随机数生成依赖.gitignoreGit 忽略规则导入工程时不用管这张表的核心信息是三个 jar 不是可选项是编译运行的必要依赖。iFogSim 是在 CloudSim 3.0.3 的基础上扩展出来的而 CloudSim 的示例运行依赖 guava 和 commons-math3。我见过有人只把 cloudsim-examples-3.0.3.jar 拖进 Build Path结果 guava 和 commons-math3 缺失报错信息像天书。正确做法是把这三个 jar 全部加入一个都不能少。如果你在 JDK 9 以上环境里跑还要注意模块化导致的包不可见问题这时候最省事的方案还是换回 JDK 8而不是跟模块权限死磕。另外根目录下的Copy of vr_game_topo、dcns_game_topo这类文件看起来像地图其实描述的是官方实验的拓扑结构。iFogSim 运行时不一定会自动读取它们官方示例通常把拓扑硬编码在 Java 代码里所以这些文件更像实验记录的辅助材料而不是运行时配置文件。真正决定仿真行为的是 src 目录下的 Java 类这一点后面会专门展开。2.2 核心类是怎么串起来的Datacenter、FogDevice、Sensor、Actuator 的关系要理解 iFogSim 的仿真粒度先要理解它站在 CloudSim 的肩膀上做了什么。CloudSim 的仿真实体是 Datacenter、Host、Vm、Cloudlet它假设所有算力都集中在数据中心iFogSim 新增了 FogDevice 这个类型它本质上是一个带边缘特征的 Datacenter有 CPU、内存、带宽、存储也有层级属性。层级level很关键level 为 0 通常是云端数据中心level 为 1 是省级雾节点level 为 2 是接入侧边缘节点越靠近传感器层level 越大。数据是怎么流动的iFogSim 里用 Sensor 模拟设备端的数据产生用 Actuator 模拟指令执行用 AppModule 描述一个计算任务用 AppEdge 描述计算任务之间的数据依赖。一个典型过程是Sensor 产生一个 Tuple通过网络链路到达某个 FogDevice 上的 AppModule处理完后要么返回给 Actuator要么继续上行到云端做聚合计算。整个过程的每个环节都会累加时间、能耗和网络占用这就是最后仿真报告里指标来源。想验证这些关系一个很直接的操作是打开 src/org/cloudbus/cloudsim/edge/core/EdgeDevice.java在源码里你会看到 FogDevice 直接继承了 Datacenter内部维护了 uplink/downlink 带宽、与父节点和子节点的连接。看这个类比看任何 UML 图都直观它把“边缘节点也是一类 Datacenter”这件事写在继承关系上。看完这个类再回头看 CloudSim 的 Datacenter 类你就能理解为什么官方文档强调 iFogSim 不是独立仿真器而是 CloudSim 的扩展。那为什么不在 CloudSim 上直接做因为 CloudSim 没有层级设备的概念所有主机对一个数据中心来说是平级的它也没有把应用拆成模块化数据流的能力更没有 Sensor/Actuator 这种物联网设备抽象。iFogSim 补齐的正是这三块FogDevice 的层级关系、AppModule/AppEdge 的应用拓扑、Sensor/Actuator 的数据出入口。这也是它能在边缘计算仿真里站住脚的原因。对新上手的人来说先把这三个模型记住后面看任何示例代码都不会迷路。3. 把 iFogSim-master 跑起来命令行编译、IDE 导入与参数修改3.1 环境准备JDK 版本和导入方式iFogSim 的源码风格偏老我踩过的版本坑是 JDK 9 环境下编译会碰到 java.xml.bind 模块缺失而且某些反射调用在模块化下直接被限制。所以第一步认准 JDK 8安装 JDK 8u202最后一个免费商用版本配置好 JAVA_HOME 和 PATH然后验证java -version javac -version看到 1.8.x 再继续。接下来把 iFogSim-master.zip 解压到一个没有中文和空格的路径下比如 D:\workspace\ifogsim 或 ~/workspace/ifogsim。路径里有空格和中文的话命令行传参容易出错尤其是我下面要给的find编译命令路径一复杂就会翻车。导入 IDE 的常见做法是Eclipse 里用 File - Import - Existing Projects into Workspace选根目录IntelliJ 里用 File - Open 直接选根目录然后右键根目录 Mark Directory as Sources Root。不管哪种 IDE都要把三个 jar 加到项目依赖里右键项目 - Build Path - Add External JARs选中 cloudsim-examples-3.0.3.jar、guava-18.0.jar、commons-math3-3.5.jar。不加全这三个后面编译就是连环报错。3.2 命令行编译与运行官方示例下面这条命令在 Linux/macOS 下可以直接跑Windows 上建议用 IDE因为find不是 Windows 原生命令除非你装了 Git Bash。先把环境变量指到 JDK 8然后在解压目录执行mkdir -p classes javac -encoding UTF-8 -cp .:cloudsim-examples-3.0.3.jar:guava-18.0.jar:commons-math3-3.5.jar -d classes $(find src -name *.java) java -cp classes:cloudsim-examples-3.0.3.jar:guava-18.0.jar:commons-math3-3.5.jar org.cloudbus.cloudsim.edge.Example1命令逻辑不复杂find把 src 下所有 .java 文件收集起来一次性编译-d classes指定输出目录后面 java 运行时的类路径必须同时包含编译输出的 classes 目录和三个依赖 jar顺序反了或漏一个都会出问题。类路径里的.是为了让代码里相对路径的资源文件能被找到iFogSim 有些示例会读取配置文件删掉.可能运行时报文件不存在。如果类名不对先用ls src/org/cloudbus/cloudsim/edge/看一下有哪些 Example 类然后替换成你看到的名字。第一次跑通后你会看到屏幕刷出一堆仿真事件记录里面有 Tuple 的发送接收、设备执行的日志最后会打印整体响应时间、总能耗这类汇总值。这一瞬间你就能体会到什么叫“仿真环境跑起来了”。需要注意的是cloudsim-examples-3.0.3.jar这个命名很容易让人以为它只是示例代码实际上它同时打包了 CloudSim 3.0.3 的核心类。所以不要因为名字里有 examples 就觉得可以不加。运行日志里如果出现ClassNotFoundException: org.cloudbus.cloudsim.cloudlet.Cloudlet基本就是运行类路径里少了它。3.3 修改仿真参数设备数量、拓扑延迟、服务质量指标官方示例把参数写在 Java 里而不是外置配置文件所以改参数要找到对应方法。以 Example1 为例打开 createFogDevices 方法你看到的每一个 new FogDevice(...) 都对应一个节点。构造参数里比较常用的是这几个参数含义常见调整值MIPS节点 CPU 能力1000 起步越高表示算力越强RAM内存大小MB512 / 1024 / 2048upBw上行带宽Mbps100 / 1000downBw下行带宽Mbps100 / 1000level节点层级0 云1 雾2 边缘修改后重新编译运行对比输出。很多人改完只按 Run 不动结果输出没变化就是因为 IDE 没有自动编译 src 下的改动或者运行的是旧的 classes。命令行场景下务必重新执行 javacIDE 场景下 Project - Clean 一次再跑。补充一个调度参数每个 FogDevice 的构造器最后一个参数是调度间隔单位是秒。默认 0.1 就够改成 0 会让仿真器拼命执行空闲调度表现为卡死或输出量爆炸。新手容易为了追求精度把间隔改成 0这是典型的翻车路径。精度不够时优先减小仿真时长的粒度而不是让调度间隔归零。4. 改造成自己的边缘场景从 vr_game_topo 到自定义 FogDevice4.1 识别官方拓扑vr_game_topo 和 dcns_game_topo 在模拟什么根目录下的 Copy of vr_game_topo、dcns_game_topo 这些文件名字看起来像地图其实描述的是官方实验的拓扑结构。vr_game_topo 模拟云游戏场景手机/终端产生操作指令经过边缘节点做画面渲染的预处理再上行到云数据中心做重度计算最后把渲染结果下发给显示器。它的特点是数据流双向性很强指令上行、画面下行带宽和延迟对结果的影响非常明显。dcns_game_topo 则把重点放在数据中心内部的网络结构上dcnsCloud 和 dcnsFog 两个配置分别定义云侧和雾侧的节点参数适合研究雾节点组网对游戏服务的影响。需要说明的是这些拓扑文件本质上是实验的辅助材料。iFogSim 运行时不一定会自动读取它们官方示例通常是把拓扑结构硬编码在 Java 方法里。所以你看到根目录这些文件不要误以为是配置文件想改变拓扑还是要回到代码里去改创建节点的逻辑。4.2 自定义拓扑的标准写法创建带层级的 FogDevice把官方示例改造成自有场景核心就是重写创建节点的代码。我一般会写一个辅助方法把节点参数统一收口方便后面跑多组实验。private FogDevice createFogDevice(String name, int mips, int ram, long upBw, long downBw, int level) { ListPe peList new ArrayList(); peList.add(new Pe(0, new PeProvisionerSimple(mips))); Host host new Host(0, new RamProvisionerSimple(ram), new BwProvisionerSimple(upBw downBw), 1000000, peList, new VmSchedulerTimeShared(peList)); FogDeviceCharacteristics characteristics new FogDeviceCharacteristics( Architecture.ARM, Linux, Xen, 0.0, 0.0, upBw, downBw, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0); FogDevice fogDevice new FogDevice(name, characteristics, new VmAllocationPolicySimple(), 1000000, 1000000, 0.1); fogDevice.setLevel(level); return fogDevice; }这段代码把官方示例的构造方式抽成了一个函数参数含义是mips 决定节点算力ram 是内存upBw 和 downBw 是上行/下行带宽level 决定节点层级。注意带宽总和给了 Host 的 BwProvisionerSimple这是为了让主机调度器知道总带宽上限最后的 1000000 是存储大小0.1 是调度间隔。这样创建出来的 FogDevice 再调 setLevel节点就有了边缘/云的身份。创建一个传感器和执行器也很直接Sensor sensor new Sensor(temp-sensor, TEMPERATURE, tupleCpuLength, tupleNwLength); sensor.setGatewayDeviceId(edgeNode.getId()); Actuator actuator new Actuator(temp-actuator, TEMP_CONTROL, edgeNode.getId());Sensor 的三个长度参数分别表示 Tuple 需要的 CPU 长度和网络占用你可以在仿真初始化时把这两个值定义成常量方便统一调整。Actuator 的构造器参数更简单名字、类型、所属节点 ID。把 sensor 挂在边缘节点上就模拟了传感器就近上报的场景。4.3 定义应用模块与数据流AppModule 和 AppEdge只有一个节点还不够iFogSim 里应用是由模块和数据流组成的。用 AppModule 定义一个计算任务用 AppEdge 把设备端的数据接到模块上。AppModule dataProcess new AppModule(data-process, tupleCpuLength, tupleNwLength); dataProcess.setPlacement(0, fogNode.getId()); AppEdge edge new AppEdge(sensor.getTupleType(), tupleCpuLength, tupleNwLength, data-process, 1000, 1000, SENSOR_DATA);setPlacement 的意思是第 0 个应用模块实例放在 fogNode 上。如果你不想让所有请求都打到一个节点可以创建多个 AppModule 实例分别挂到不同层级的 FogDevice 上模拟“边缘优先、云兜底”的调度策略。AppEdge 的构造参数指定了数据从哪来、到哪里去以及 Tuple 的长度和处理数据量。把这些 AppModule 和 AppEdge 加到应用拓扑里之后再跑仿真就能看到不同节点上的负载和延迟差异。这套写法和官方示例一致改完以后把 createFogDevices 返回的设备列表替换到主函数里保留原来的 Sensor/Actuator 注册逻辑即可。这就是从“跑通示例”到“跑自己的场景”的关键一步拓扑不是画出来的是节点、模块、数据流三条线搭出来的。5. iFogSim 避坑指南五个必踩的坑与解决步骤5.1 现象导入项目后大量红叉找不到 com.google.common.collect.Maps原因guava-18.0.jar 没有被加到 Build Path或者 IDE 自动把根目录 jar 忽略了。Eclipse 在导入仓库时不自动识别根目录 jar需要手动 Add External JARs。解决右键项目 - Build Path - Configure Build Path - Add External JARs把 guava-18.0.jar 加进去。加完以后还报缺 commons math就再补 commons-math3-3.5.jar。检查标准是项目视图里 External Libraries 能看到三个 jar且 source 包没有红色错误图标。这里多花两分钟检查后面能省掉半小时的排查时间。5.2 现象运行时报 ClassNotFoundException: org.cloudbus.cloudsim.cloudlet.Cloudlet原因运行时类路径里没有 cloudsim-examples-3.0.3.jar。这个 jar 不只是示例iFogSim 源码编译后运行时要加载 CloudSim 的 Datacenter、Host、Vm 等核心类而这些类都在它里面。有人用 IDEA 时把 jar 配在编译期运行配置里却漏了就会出现编译通过、运行报错的怪现象。解决检查 Run Configuration 的 classpath确保三个 jar 都在运行时依赖里。命令行场景就是 java -cp 那一串要完整复制不要精简。另外注意这个 jar 和 sources jar 名字很像但用途完全不同运行时只需要 .jar 不带 sources两个都加也没有坏处只是没必要。5.3 现象仿真结果全是 0或者延迟大得离谱原因参数单位混淆或网络配置错误。upBw/downBw 的单位是 Mbps如果你把 1000 写成 1000B仿真器会按 Mbps 解释但数值偏差不大不至于全 0全 0 更常见的原因是 Sensor 没有挂到任何 FogDevice或者 AppEdge 的类型不匹配导致数据根本没流动。延迟离谱通常是 level 设置错误比如传感器直接连云而不是就近接边缘所有请求都绕了一大圈。解决仿照官方示例检查 sensor.setGatewayDeviceId 是否指向正确的 FogDevice IDAppEdge 的 tupleType 是否和 Sensor 产生的一致。再把 createFogDevice 里 level 打出来确认边缘节点 level 大于云节点。排查时先把顶层云节点去掉如果结果出现明显变化说明数据流路径已经被你的拓扑影响了。5.4 现象改了代码但输出没有变化原因运行的不是新编译的类。IDE 的增量编译偶发不触发命令行下没有重新 javac或者存在多个版本的 classes 目录混在类路径里。还有一种情况是官方示例把配置写在另一个类里面你只改了 A 类的参数但主类用的是 B 类的常量。解决命令行先清空 classes 目录再重新执行 find 编译命令IDE 里 Project - Clean 后 Run。检查主类到底引用了哪个方法用 IDE 的 Find Usages 看参数来源。改完以后在代码里加一行 System.out.println 打印节点名称输出变了才算真正生效。5.5 现象仿真中途卡死或者直接 OutOfMemoryError原因设备数量多默认堆内存不够或者调度间隔设成了 0仿真循环空转。iFogSim 默认的仿真实体不少节点超过 20 个、每个节点带多个 AppModule 时内存占用很容易超过默认 512M。解决运行参数上加 -Xmx2048m必要时加 -Xms1024m。调度间隔从 0.1 起不要为了精度改成 0。如果还是卡检查 for 循环里是不是意外创建了无限增长的集合常见原因是把 FogDevice 加入了循环依赖图导致 getChildren 递归死循环。6. 让结果经得起审稿CSV 导出与多轮重复实验的固定做法6.1 把延迟和能耗导出成 CSV官方示例的输出是控制台文本做多组对比时翻日志太痛苦。我一般会改一下主类的收尾把每个 FogDevice 的结果写进 CSVStringBuilder sb new StringBuilder(device,level,energy,delay\n); for (FogDevice device : fogDevices) { double energy device.getPowerConsumption(); double delay device.getTotalDelay(); sb.append(device.getName()).append(,) .append(device.getLevel()).append(,) .append(energy).append(,) .append(delay).append(\n); } Files.write(Paths.get(result_ System.currentTimeMillis() .csv), sb.toString().getBytes());这段代码在仿真结束后遍历设备列表把名字、层级、能耗、延迟写进一个带时间戳的 CSV。时间戳加在文件名里很关键因为同一参数跑多轮时不覆盖旧结果后面做均值、画图都不用担心数据互相污染。如果你的策略比较了 N 个节点 vs M 个节点把节点数放在文件名里比如 topology_5nodes.csv比时间戳更直观。6.2 多轮重复实验固定随机种子和参数快照iFogSim 内部用到随机数的地方不少比如任务到达时间、资源竞争顺序。如果每轮实验都不固定种子结果波动可能比参数差异还大这在论文审稿人眼里是硬伤。常见做法是给主函数加一个可配置的种子每次初始化 CloudSim 之前用 Random 对象Random random new Random(42L);把 42L 换成每一轮实验的编号同一编号下结果即可复现。只固定 iFogSim 内部的随机不够还要把拓扑参数、调度间隔写进实验记录因为 iFogSim 没有自动记录参数的功能。我会在 CSV 文件开头或文件名里带上关键参数例如seed42_nodes10_bw1000.csv确保三个月后回来看还能对上号。多轮实验的正确姿势是对每组参数至少跑 10 轮取均值加标准差再把 10 轮结果全部保留而不是只留均值。保留原始数据的好处是审稿人如果要求看分布你随时能画箱线图如果只留均值遇到可疑结论连回溯的余地都没有。这个习惯是我第一次被导师打回来重做实验时长教训了现在每跑一组实验都会强制把种子、节点数、带宽、调度间隔写进文件名的前缀宁可文件名长一点也不让自己事后想不起参数。希望这套做法能帮你在 iFogSim 上少踩几个坑。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。