代码跨平台怎么实现?6大核心方案+场景选型,告别重复开发

代码跨平台实现方式


代码跨平台怎么实现?6大核心方案+场景选型,告别重复开发

做开发时最头疼的莫过于 “一套代码多端适配”——Windows、Mac、Linux 要适配,iOS、Android 要兼容,甚至还要兼顾浏览器和小程序。重复写多套代码不仅效率低,还容易出现兼容性 bug。其实跨平台开发早已不是新鲜事,不同技术方案各有优劣,关键是选对适配场景。今天就拆解代码跨平台的核心实现方式,帮你快速找准适合自己的方案。

一、编译适配型:一次编码,多平台编译
核心逻辑:编写统一源码,通过专用编译工具或语言特性,直接编译出不同平台的可执行文件,性能接近原生。
代表技术:
语言原生支持:Go(编译 + 运行时,直接编译为各平台二进制文件)、Rust(跨平台编译工具链,适配多系统)、Java(中间码 + JVM 运行时,一次编译多平台运行)、.NET Core(中间码 + 运行时,跨 Windows/Mac/Linux);
编译工具辅助:CMake(搭配标准库,统一管理多平台编译流程)、交叉编译 ToolChain(如 MinGW、Cygwin,实现跨系统编译);
优势:性能强,接近原生应用;代码复用率高,无需大幅修改;
适用场景:后端服务、工具类软件、高性能应用(如 Go 开发的跨平台服务器,C+++CMake 开发的桌面工具)。

二、跨平台框架型:框架封装,屏蔽平台差异
核心逻辑:基于统一框架开发,框架底层适配不同平台的 API,开发者无需关注平台细节,专注业务逻辑。
代表技术:
桌面 / 多端框架:QT(编译 + 跨平台框架,适配桌面 + 嵌入式,支持 C++/QML);
移动跨平台框架:React Native(JS 调用原生渲染,兼顾跨平台与原生体验)、Flutter(自绘渲染引擎,跨 iOS/Android/ 桌面 / 网页,UI 一致性强);
优势:开发效率高,一套代码覆盖多端;UI 适配性好,框架已处理平台差异;
适用场景:移动 APP(如电商 APP、工具类 APP)、桌面应用(如 QT 开发的跨平台客户端)、中小型项目(Flutter 快速迭代上线)。

三、虚拟层/模拟型:通过虚拟环境兼容多平台
核心逻辑:在目标平台上搭建虚拟层或模拟器,让原本不兼容的代码在虚拟环境中运行,无需修改源码。
代表技术:
虚拟机:VMware、VirtualBox、Parallels(在 Windows/Mac上虚拟出其他操作系统,运行对应平台软件);
兼容层:Wine(在Linux/Mac上模拟 Windows 运行环境,运行 Windows 程序)、WSL(Windows子系统,在Windows上运行 Linux 环境及软件);
模拟器:Android 模拟器(在PC上模拟Android环境,运行APP);
优势:无需修改原有代码,直接复用现有应用;门槛低,快速实现兼容;
注意点:性能有损耗,不如原生流畅;部分复杂应用可能出现兼容性问题;
适用场景:现有应用跨平台运行(如Windows软件在Linux上通过Wine运行)、开发测试(Android模拟器调试APP)。

四、超级APP生态型:依托生态,跨OS运行
核心逻辑:在微信、支付宝等超级APP提供的SDK或生态内开发,借助超级APP的跨平台能力,实现 “一次开发,多OS适配”。
代表技术:微信跨OS、支付宝跨OS(通过其提供的 SDK 开发小程序或内嵌应用,自动适配 iOS/Android);
优势:无需考虑底层平台适配,超级 APP 已完成兼容;流量红利,可直接触达超级 APP 的海量用户;
适用场景:小程序、内嵌应用(如微信小程序、支付宝生活号应用)、轻量级交互场景。

五、Web标准型:基于浏览器,跨平台无压力
核心逻辑:采用 HTML/CSS/JS 开发,依托浏览器的 Web 标准,实现 “一次开发,所有浏览器兼容”,间接跨所有支持浏览器的平台。
代表技术:浏览器 + Web 标准、H5 Hybrid(APP 内嵌 WebView,混合原生与 Web 页面);
优势:兼容性极强,覆盖 PC / 移动 / 平板所有浏览器;开发成本低,技术栈普及;
注意点:性能依赖浏览器,复杂交互体验不如原生;部分原生 API 需通过桥接调用;
适用场景:网页应用、轻量级 APP、跨平台展示型场景(如官网、数据可视化页面、Hybrid APP 的展示模块)。

六、包管理与环境配置型:统一环境,简化适配
核心逻辑:通过包管理工具统一管理依赖,确保不同平台的开发环境一致,减少因环境差异导致的适配问题。
代表技术:MacPorts、Homebrew(Mac 平台包管理工具,快速安装适配 Mac 的开发依赖);
优势:简化环境配置,快速搭建跨平台开发所需依赖;统一依赖版本,避免 “本地能跑,线上报错”;
适用场景:辅助跨平台开发(如通过 Homebrew 在 Mac 上安装 CMake、MinGW 等跨平台编译依赖)。

总结:跨平台方案选型核心逻辑 ——“场景决定方案”
不用盲目追求 “万能方案”,选型时重点关注3点:
1、性能需求:高性能场景(后端、工具软件)选编译适配型(Go/Rust/CMake);中低性能需求(展示型 APP、小程序)选 Web 标准或超级 APP 生态;
2、多端覆盖范围:需覆盖移动 + 桌面选 Flutter/QT;仅移动端选 React Native/Flutter;仅桌面端选 QT/Go 编译;
3、开发效率:快速迭代选 Flutter/React Native;追求长期稳定、低维护成本选编译适配型或 QT。

跨平台开发的核心是 “用最低成本实现多端兼容”,不同方案没有绝对优劣,只有是否适配场景。选对方案,既能减少重复开发,又能保证产品体验。

你在跨平台开发中遇到过哪些兼容性坑?或者你更倾向于哪种实现方案?欢迎在评论区留言交流~

WSL2中apt升级systemd时报错:无法锁定passwd文件

1、环境:
Windows10+WSL2+Ubuntu24
PS:另一台电脑Windows11+WSL2+Ubuntu24,不会报错

2、再现方式及错误信息

# apt-get upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
...
...
Setting up systemd (255.4-1ubuntu8.8) ...
Initializing machine ID from random generator.
Failed to take /etc/passwd lock: Invalid argument
dpkg: error processing package systemd (--configure):
installed systemd package post-installation script subprocess returned error exit status 1
Errors were encountered while processing:
systemd
E: Sub-process /usr/bin/dpkg returned an error code (1)

3、错误发生原因
systemd升级的脚本,会调用systemd-sysusers,systemd-sysusers会尝试通过fcntl锁定文件,但WSL中fcntl实现效果与Linux中不同,导致脚本执行失败。
更进一步的解释:
Linux中文件锁是基于文件描述符的,子进程会自动继承该文件锁。
Windows中文件锁是基于进程的,子进程需要自行获取新的文件锁。
WSL中,实现方式,更接近与Windows,重复获取同一个文件的锁自然是失败的。

openat(AT_FDCWD, "/etc/.pwd.lock", O_WRONLY|O_CREAT|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC, 0600) = 3
fcntl(3, F_OFD_SETLKW, {l_type=F_WRLCK, l_whence=SEEK_SET, l_start=0, l_len=0}) = -1 EINVAL (Invalid argument)

4、如何绕过该错误

# 原文在此:https://github.com/microsoft/WSL/issues/10397

# 切换到/bin
# 将systemd-sysusers修改为systemd-sysusers.org
# 将systemd-sysusers做成一个echo的符号链接(用于欺骗升级脚本,让其以为得到了正确的结果)
# 切换回之前的目录
cd /bin && mv -f systemd-sysusers{,.org} && ln -s echo systemd-sysusers && cd -

# 修复包依赖
apt --fix-broken install

# 继续升级
apt-get upgrade

导致惨重代价的运维事故2025

2025年11月:Cloudflare大规模故障
事件经过:11月18日,Cloudflare CDN、安全服务等多款产品宕机,团队误判为DDoS攻击,回滚旧文件后,于19日凌晨01:06全部恢复。
事故原因:数据库权限调整后生成错误配置文件,引发核心代理系统异常。
造成损失:全球大量依赖Cloudflare服务的网站及业务受影响,平台承诺加速系统韧性升级。

2025年11月:亚马逊云服务重大事故
事件经过:美国太平洋时间凌晨2:01,AWS因运营问题导致近70项自有服务受影响,亚马逊、迪士尼+、Canva等平台及多款云游戏瘫痪。
事故原因:未公开披露具体技术原因,确认与美国东部1号区域相关。
造成损失:全球多家知名平台服务中断,影响用户使用及企业业务营收。

2025年10月:亚马逊AWS北弗吉尼亚区域崩溃
事件经过:AWS US-EAST-1区域中断长达15小时,波及全球。
事故原因:核心依赖服务失效,DynamoDB DNS解析异常引发连锁故障。
造成损失:数千个服务瘫痪,潜在经济损失高达百亿美元。

2025年10月 微软Azure配置错误,导致全球中断
事件经过:Azure Front Door错误配置变更,Azure全网瘫痪,引发Office 365、Teams等核心服务全球性中断,持续数小时。
事故原因:网络配置变更失误,触发底层逻辑缺陷致级联故障。
造成损失:全球用户无法使用核心服务,企业远程办公中断,微软赔付客户,声誉受损。

2025年9月:韩国政府数据中心火灾
事件经过:数据中心锂离子电池迁移维护时爆炸起火,858TB核心数据丢失,160多项公共服务受影响,一周仅恢复18%系统。
事故原因:运维操作引发的基础设施事故。
造成损失:政府服务瘫痪,修复成本高,公信力受损。

2025年8月:上海医保系统故障
事件经过:8月11日,上海医保系统因电信云平台机房供电故障无法正常结算,应急备份系统接管后,本地门急诊结算恢复,大病、住院及异地结算受影响。
事故原因:电信运营管理的云平台机房供电系统故障。
造成损失:患者就医结算受阻,异地参保人需自费后报销,影响民生服务。

2025年6月:谷歌云全球性服务中断
事件经过:6月12日,谷歌云遭遇全球性服务中断,持续约13小时。期间,谷歌工作空间(Google Workspace)、安全运营产品等外部API请求大量失败。
事故原因:服务控制组件高负载处理失效。“服务控制”组件是谷歌云策略检查系统的核心,负责读取配额和政策信息。该组件未能有效应对高负载情况,导致API请求处理堵塞,进而引发了全局性的服务中断。
造成损失:大量企业客户业务受阻,谷歌为此向客户致歉并推出了服务控制改进计划,重建客户信任。

2025年3月:华金期货交易系统长达7.5小时宕机
事件经过:3月10日,华金期货的交易系统突发异常,客户无法通过文华财经等主流交易端登录账户。故障持续了整整7小时26分钟,直到半日过去才被修复。
事故原因:软件故障与应急处置不当。虽然具体技术原因因“证据灭失”未能完全查清,但监管调查发现其在应急处置中未妥善保护现场,且暴露出灾备系统性能不足、过度依赖外部供应商等问题。
造成损失:达到“一般网络安全事件”标准;期货市场瞬息万变,长时间的交易中断导致客户面临巨大的穿仓风险和亏损,公司也因此收到监管罚单。

2025年1月:埃隆·马斯克旗下X公司数据中心火灾
事件经过:X公司租用的俄勒冈州希尔斯伯勒数据中心发生火灾。
事故原因:储能设备管理问题,电池房间存在运维漏洞。
造成损失:影响X平台部分服务稳定性。

记一次存储Inode数量引发的生产故障

前一段时间,突然收到了系统报警,某上传服务异常。

经过排查,上传服务正常,但存储无法正常写入,一直写入失败,表现为:
1、一块新盘,32T,已使用2T,可用30T,控制台和命令行操作结果一直
2、服务写入时,一直报“no space left on device”
3、没有收到任何存储报警

立刻找了云服务厂商的老师,解决了问题:
1、除了限制写入文件总量的大小、并发写入的速度,同时还限制了inode数量
2、上传服务,写入了大量小文件,耗尽了inode数量
3、上传服务,再次写入后,inode申请失败,导致写入失败
4、存储组的老师,紧急扩展了inode数量,解决了问题

经排查,云服务商反馈:
1、为了控制成本,我们之前买了一块较小的硬盘,然后进行了扩容
2、而存储的底层协议为FlexGroup
3、而FlexGroup的普通卷,在扩容的时候,只要超过了1T,默认的Inode数量就一直为21251126,不再提升
4、而我们的上传服务,一个小文件只有几百k,很快就把Inode数量耗尽了
5、对于Inode数量限制,云服务商没有提供任何监控

虽然FlexGroup的超大卷默认会提升Inode数量,但我们一开始购买的服务确是普通卷,然后进行扩容,扩容后仍是普通卷,就触发了Inode数量不会自动增加这个问题。

后续,我们做了两个约定:
1、尽量采购超大卷
2、如果要采购普通卷,同时提单,增加Inode数量
3、云服务商同步进行产品更新,后续产品迭代时,从根源上解决这个问题

PS:
最近发现,他们居然做了一个inode扩容的功能,默认是最小值,可以手工扩展,也能设置为自动扩展。
不知道是谁定的需求,默认选项不应该是自动扩展吗?

导致惨重代价的运维事故2024

2024年12月:OpenAI故障
事件经过:12月11日,OpenAI发生故障,影响依赖其服务的用户及企业。
事故原因:未公开披露具体原因。
造成损失:成为2024年主要信息系统故障之一,干扰AI相关业务及研发工作。

2024年11月:华为云华南地域部分服务异常
事件经过:因网络设备升级失误,导致华为云华南地域部分云服务访问异常,持续约2小时。
事故原因:内部设备升级操作失误。
造成损失:客户业务短暂中断,华为云快速修复并致歉。

2024年11月:支付宝交易故障
事件经过:11月11日,支付宝发生交易故障,影响用户支付及交易行为。
事故原因:未公开披露具体原因。
造成损失:成为2024年主要信息系统故障之一,干扰用户日常支付及商业交易。

2024年11月:Snowflake云服务逻辑故障
事件经过:11月,云数据平台Snowflake发生严重的服务中断,持续长达13小时。
事故原因:软件更新引发的逻辑冲突。软件更新引入了向后不兼容的数据库架构更新,导致版本不匹配错误。更糟糕的是,其“区域冗余”机制在逻辑故障面前失效,导致10个区域同时瘫痪。
造成损失:大量企业无法执行数据查询,暴露了云服务在面对“逻辑层面”故障时,物理冗余机制可能完全失效的风险。

2024年9月:甲骨文云基础设施故障
事件经过:甲骨文云某区域存储系统故障,导致部分客户数据无法访问,持续超6小时。
事故原因:存储系统运维故障。
造成损失:客户业务中断,甲骨文面临索赔,声誉下滑。

2024年9月:阿里云新加坡数据中心火灾
事件经过:9月10日上午,阿里云新加坡可用区C数据中心发生火灾,导致17项服务异常,Lazada、字节跳动等业务中断。
事故原因:锂电池起火引发故障。
造成损失:多家企业业务中断,阿里云海外服务稳定性受质疑。

2024年9月:上交所交易故障
事件经过:9月27日,上海证券交易所发生交易故障,影响证券交易正常开展。
事故原因:未公开披露具体原因。
造成损失:成为2024年主要信息系统故障之一,干扰资本市场交易秩序。

2024年8月:网易云音乐故障
事件经过:8月19日,网易云音乐发生故障,排查耗时近2小时后恢复。
事故原因:疑似与云存储扩容、贵州机房迁移相关,官方未披露确切原因。
造成损失:用户无法正常使用音乐服务,平台用户体验受影响。

2024年8月:上海电信城域网设备故障
事件经过:8月26日,上海电信城域网设备发生故障,影响区域网络服务。
事故原因:未公开披露具体原因。
造成损失:成为2024年主要信息系统故障之一,干扰民众网络使用及商业活动。

2024年7月:微软系统蓝屏事件
事件经过:7月19日,使用了Windows操作系统的设备大面积蓝屏,导致850万设备受到影响。
事故原因:微软安全供应商CrowdStrike推送了错误的软件配置。
造成损失:成为2024年主要信息系统故障之一,对大量用户工作及使用造成影响。

2024年7月:阿里云故障
事件经过:7月2日,阿里云发生故障,具体影响范围覆盖多款服务。
事故原因:未公开披露具体原因。
造成损失:成为2024年主要信息系统故障之一,影响依赖阿里云服务的客户业务。

2024年4月:腾讯云控制台故障
事件经过:4月8日15点23分,腾讯云云API服务异常,导致云函数、文字识别等依赖服务无法使用,持续87分钟,1957个客户报障。
事故原因:配置数据错误,经紧急数据修复恢复服务。
造成损失:影响客户业务正常开展,平台服务可靠性受质疑。

导致惨重代价的运维事故2023

2023年12月:谷歌云新加坡区域故障
事件经过:因网络配置错误,导致谷歌云新加坡区域服务中断超3小时,影响大量企业客户。
事故原因:内部网络配置失误。
造成损失:客户业务中断,谷歌云赔付客户,市场竞争力受影响。

2023年11月:阿里云全线产品故障
事件经过:11月12日下午,阿里产品全线崩溃,波及全球多个地域全部云用户,持续事件达3.5小时。
事故原因:具说是鉴权服务出了问题。
造成损失:凸显云计算集中化部署风险,影响全球多地客户业务。
小插曲:两周后,在2023年11月27日,阿里云再次遭遇了近两小时的中断,影响到中国和美国的客户。然后当天晚上,滴滴就来了个大的。

2023年11月:滴滴崩溃
事件经过:11月27日晚间,滴滴崩溃,致APP地图无法加载、无法叫车,持续约12小时,影响多地用户。
事故原因:底层系统软件故障。
造成损失:订单流失,品牌形象和用户信任度下降。

2023年10月:新加坡Equinix数据中心制冷故障
事件经过:新加坡Equinix数据中心承包商误关闭冷冻水阀门,导致制冷系统误操作,造成2.5万笔银行交易失败、8.1万次登录失败。
事故原因:承包商操作失误,误关冷冻水阀门。
造成损失:金融交易及用户登录受严重影响,暴露运维管理漏洞。

2023年10月:语雀重大服务故障
事件经过:10月23日14时左右,语雀发生重大服务中断,在线文档和官网无法访问,当晚22时完全恢复,持续近8小时。
事故原因:内部运维工具缺陷,新上线升级工具bug导致华东生产环境存储服务器误下线,造成大面积服务中断。
造成损失:定性为P0级重大事故,影响数千万用户工作与知识管理,引发对运维自动化工具安全性的反思。

2023年6月:中国电信广东网络故障
事件经过:6月8日中国电信广东区域遭遇大规模网络服务中断,用户普遍无信号、无法通话上网,故障约4小时后恢复。
事故原因:网络设备故障。
造成损失:影响广东省内商务活动和民众生活,具体损失数据未公布。

2023年5月:苹果iCloud全球服务中断
事件经过:5月11日,苹果全球服务遭遇“史诗级”宕机,持续约55分钟。大量用户的Apple ID突然登出,无法访问iCloud照片、文件和备忘录等关键数据。
事故原因:数据中心严重故障。虽然苹果未详细披露,但此类核心服务中断通常源于数据中心底层存储或认证服务的配置错误或硬件集群故障。
造成损失:数千万苹果用户数据访问受阻,打破了苹果生态“稳定可靠”的神话,引发了对苹果云服务能力的广泛质疑。

2023年5月:微软Azure故障
事件经过:5月24日,微软Azure DevOps在巴西的一处scale-unit发生故障,导致宕机约10.5个小时。
事故原因:导致该中断的原因为一个简单的拼写错误,最终导致17个生产级数据库被删除。
造成损失:大量用户无法使用云服务。

2023年4月:中信证券APP交易阻塞
事件经过:4月期间,中信证券APP出现严重的交易阻塞现象,客户无法正常下单或撤单。
事故原因:系统软件缺陷与容量规划不足。在市场交易活跃期,系统未能有效处理高并发请求,暴露出软件逻辑缺陷和灾备能力的不足。
造成损失:直接影响客户交易,导致客户资金错失交易时机,引发大量客户投诉,对券商的声誉造成了直接的负面影响。

2023年3月:推特全球大规模宕机
事件经过:平台代码更新错误,导致全球用户无法登录或使用推特功能,持续超5小时。
事故原因:内部代码更新失误。
造成损失:用户体验差,广告收入受损,平台声誉下滑。

2023年3月:广州某电信机房制冷故障
事件经过:广州某电信机房水冷系统破裂引发制冷故障,微信、QQ及政务云系统瘫痪,机房被迫采用冰块临时降温。
事故原因:水冷系统破裂,制冷功能失效。
造成损失:国民级应用及政务服务中断,影响范围广、社会影响大。

2023年3月:腾讯云机房事故
事件经过:23年3月29日凌晨,腾讯云广州五区部分云服务异常,导致微信、QQ、支付等核心功能受到影响,故障在当天中午基本恢复。
事故原因:官方反馈为“本次事故由广州电信机房冷却系统故障导致”。
造成损失:核心应用不可用。

2023年3月:B站双重崩溃
事件经过:2023年B站经历了两次较为严重的全站级宕机。一次是3月5日,用户无法访问视频详情页、收藏夹;另一次是8月4日,视频封面无法加载、视频缓冲失败。
事故原因:底层服务依赖故障与机房电力问题。虽然具体细节未完全公开,但此类大型视频平台的崩溃通常源于核心微服务依赖失效或机房电力/网络架构的单点故障。
造成损失:数亿用户无法正常观看视频,严重影响用户体验和社区活跃度,尤其在流量高峰期的崩溃对品牌形象损害较大。

2023年3月:唯品会P0级宕机事故
事件经过:3月29日凌晨00:14至中午12:01,唯品会南沙IDC冷冻系统故障,机房温度骤升导致大规模宕机,线上商城停服12小时。
事故原因:制冷设备故障。
造成损失:影响800万人次客户,直接业绩损失超亿元,定性为最高级别P0级故障。
小插曲:事故后,对基础平台部负责人予以免职。

2023年2月:甲骨文多日长故障
事件经过:2月13日至15日,甲骨文云基础设施(OCI)遭遇持续长达数天的服务中断,这是OCI历史上罕见的长时间故障。同时,其子公司NetSuite也因关联故障停摆。
事故原因:DNS后端基础设施性能问题。支持OCI公共域名系统的后端API基础设施出现性能瓶颈,导致无法处理传入的服务请求;此外,NetSuite的故障还叠加了合作伙伴数据中心(Cyxtera)的物理电力故障。
造成损失:客户业务连续数天无法使用云资源,甲骨文“永不宕机”的宣传口号受挫,大量依赖其数据库服务的企业陷入停滞。

2023年1月:美国民航系统瘫痪
事件经过:1月11日美国联邦航空管理局飞行任务通知系统因关键文件损坏瘫痪,备份系统也检测到相同损坏,重启系统导致全美航班禁飞。
事故原因:系统文件损坏。
造成损失:超4000架次航班延误,698架次取消,数十万旅客受阻,经济损失巨大,暴露单点故障风险。

导致惨重代价的运维事故2022

2022年12月:阿里云香港Region大规模宕机
事件经过:12月18日,阿里云香港Region可用区C发生大规模服务中断,持续数小时,为其运营十多年来最长大规模故障,新购ECS等管控操作全部失败,整个处置过程超过15小时。
事故原因:机房冷却系统失效,现场包间温度逐渐升高,导致一机房包间温度达到临界值触发消防系统喷淋,电源柜和多列机柜进水,部分机器硬件损坏。
造成损失:严重影响香港及澳门客户业务,品牌信誉受损,事后发布事故说明及改进措施。
小插曲:事故后,阿里云总裁、CTO都被更换。

2022年12月:达美航空(Delta)行李系统故障
事件经过:12月28日,达美航空的行李处理系统突发严重故障,导致全球多个主要机场的行李传送带停摆,大量行李无法被正确分拣和装载。
事故原因:硬件维护不当与软件集成失效。由于行李处理系统的物理传感器和分拣机械臂出现故障,且后台管理系统未能及时切换至备用模式,导致系统“死锁”。
造成损失:数千名旅客的行李丢失或延误,圣诞节假期返程高峰受阻,达美航空被迫手动处理行李,运营陷入混乱。

2022年12月:腾讯云北京地域部分服务器故障
事件经过:因网络设备故障,导致北京地域部分云服务器、数据库等服务访问异常,持续约3小时。
事故原因:网络设备故障引发的运维事故。
造成损失:部分企业业务中断,腾讯云紧急修复并赔付客户。

2022年8月:谷歌爱荷华州数据中心电气爆炸
事件经过:谷歌美国爱荷华州数据中心发生电气爆炸,造成3名电工严重烧伤,全球1338台服务器中断,谷歌地图、搜索服务宕机。
事故原因:电弧闪光引发爆炸。
造成损失:人员受伤,设施损毁,核心服务中断影响全球用户。

2022年7月:Twitter全球大规模宕机
事件经过:7月14日上午8:10左右开始,Twitter突发全球性大规模服务中断,持续约1小时。
事故原因:内部系统配置与软件故障,引发了连锁反应。
造成损失:全球数万用户受影响。
小插曲:正值Twitter起诉马斯克违约的敏感时期,加剧了外界对其内部管理混乱的猜测。

2022年7月:B站713事故
事件经过:2022年7月13日,B站崩了5个小时。
事故原因:根据B站的事故分析报告,是SLB故障导致。本次SLB故障,是OpenResty中,计算gcd的lua代码传入了0值,被lua判定为nan,陷入了死循环。这段lua代码已经稳定运行了一段事件,但一个新发布模式,却触发了这个bug。
造成损失:B站核心业务中断。

2022年7月:Oracle Cloud(甲骨文)核心故障
事件经过:7月19日,甲骨文云服务(Oracle Cloud Infrastructure, OCI)发生严重故障,导致其核心金融、ERP等SaaS服务在全球范围内无法访问。
事故原因:关键配置错误。运维人员在对核心网络基础设施进行配置更新时,引入了错误的路由策略,导致控制平面(Control Plane)瘫痪,客户无法管理或访问其云端资源。
造成损失:依赖甲骨文系统的大型企业财务和运营流程中断,凸显了传统企业级云服务在运维操作上的风险。

2022年3月~5月:招商证券交易系统连环崩溃
事件经过:3月14日开盘后系统突发故障,用户无法成交、撤单;5月16日系统再次崩溃,电脑端、手机端均无法登录。
事故原因:交易系统技术缺陷。
造成损失:严重扰乱交易秩序,引发投资者不满和监管关注,母公司对相关负责人问责,质疑券商IT系统稳定性。

2022年3月:富途证券(Futu)全球大宕机
事件经过:3月14日,互联网券商富途证券(牛牛APP)发生全球范围内的服务中断。用户无论是通过网页端还是手机APP,都无法登录交易系统,也无法查看持仓和进行交易,故障持续了数小时。
事故原因:底层架构扩容引发的连锁故障。在进行系统扩容升级时,运维团队对流量预估不足,且核心网关组件未能正确处理扩容带来的配置变更,导致负载均衡失效,流量无法分发至后端服务器。
造成损失:正值美股交易时段,大量投资者无法操作,引发用户强烈不满和投诉,对券商口碑造成负面影响。

Linux虚拟化管理

1、内核模块初始化

module_init(vmx_init)->kvm_init
module_init(svm_init)->kvm_init

//其中,kvm_init
->kvm_arch_init
->kvm_irqfd_init
->kvm_arch_hardware_setup
->misc_register(&kvm_dev)

2、从数据结构角度,又可以看到了设备皆为文件的思想

static struct miscdevice kvm_dev = {
    KVM_MINOR,
    "kvm",
    &kvm_chardev_ops,
};

static struct file_operations kvm_chardev_ops = {
    .unlocked_ioctl = kvm_dev_ioctl,
    .llseek     = noop_llseek,
    KVM_COMPAT(kvm_dev_ioctl),
};

//初始化时,通过misc_register,实现了操作的绑定。

3、通过上面的数据结构,我们就可以找到创建虚拟机的方法,并生成控制文件
kvm_dev.kvm_chardev_ops.kvm_dev_ioctl
或者,ioctl系统调用KVM_CREATE_VM,效果也是一样的:

SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
->vfs_ioctl,会用到vfs_ioctl.unlocked_ioctl也就是kvm_dev_ioctl

->case KVM_CREATE_VM:
->        r = kvm_dev_ioctl_create_vm(arg);
->file = anon_inode_getfile("kvm-vm", &kvm_vm_fops, kvm, O_RDWR);

//其中,kvm_dev_ioctl_create_vm
->kvm_create_vm
->->kvm_arch_init_vm
->->hardware_enable_all
->->kvm_arch_post_init_vm
->->list_add(&kvm->vm_list, &vm_list);

4、生成虚拟CPU套路很相似,仍是文件操作

static struct file_operations kvm_vm_fops = {
    .release        = kvm_vm_release,
    .unlocked_ioctl = kvm_vm_ioctl,
    .llseek     = noop_llseek,
    KVM_COMPAT(kvm_vm_compat_ioctl),
};

//创建虚拟机时,通过anon_inode_getfile,实际上就把文件和kvm_vm_fops绑定了起来。
anon_inode_getfile("kvm-vm", &kvm_vm_fops, kvm, O_RDWR)

5、在调用ioctl时

SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
->vfs_ioctl,会用到vfs_ioctl.unlocked_ioctl也就是kvm_vm_ioctl

kvm_vm_ioctl->kvm_vm_ioctl_create_vcpu
->kvm_arch_vcpu_precreate
->kvm_vcpu_init
->kvm_arch_vcpu_create
->kvm_get_kvm
->create_vcpu_fd,生成设备文件inode
->kvm_arch_vcpu_postcreate

//其中,kvm_arch_vcpu_create
->kvm_mmu_create
->vcpu->arch.user_fpu = kmem_cache_zalloc(x86_fpu_cache, GFP_KERNEL_ACCOUNT);
->kvm_pmu_init(vcpu);
->kvm_hv_vcpu_init(vcpu);
->kvm_x86_ops.vcpu_create(vcpu);
->kvm_vcpu_mtrr_init(vcpu);
->vcpu_load(vcpu);
->kvm_vcpu_reset(vcpu, false);
->kvm_init_mmu(vcpu, false);  //包括init_kvm_tdp_mmu和init_kvm_softmmu两种虚拟化方式

6、启动虚拟机,还是文件操作

static struct file_operations kvm_vcpu_fops = {
    .release        = kvm_vcpu_release,
    .unlocked_ioctl = kvm_vcpu_ioctl,
    .mmap           = kvm_vcpu_mmap,
    .llseek     = noop_llseek,
    KVM_COMPAT(kvm_vcpu_compat_ioctl),
};

7、在调用ioctl时KVM_RUN

SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
->vfs_ioctl,会用到vfs_ioctl.unlocked_ioctl也就是kvm_vcpu_ioctl

kvm_vcpu_ioctl->
case KVM_RUN: 
  kvm_arch_vcpu_ioctl_run

//其中,
kvm_arch_vcpu_ioctl_run->vcpu_run->vcpu_enter_guest

8、IO同样有虚拟化和半虚拟化两种
一个处理函数为kvm_fast_pio,另一个为kvm_emulate_instruction

Linux系统调用03

Linux系统调用的整体流程为:
1、应用程序【用户态】通过syscall或glibc进行内核功能调用,这一部分在glibc源码中进行的
2、CPU收到syscall,Linux内核响应syscall调用【内核态】,这一部分在linux源码中进行的
3、返回结果到应用程序【用户态】

本节,给Linux系统,增加一个新系统调用功能,获取cpu数量。

1、新建一个源码编译目录

mkdir kernelbuild

2、下载源码,解压

wget https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.10.59.tar.gz   

tar -xzf linux-5.10.59.tar.gz   

cd linux-5.10.59

3、清理

make mrproper

4、修改文件

4.1、arch/x86/entry/syscalls/syscall_64.tbl
#在440后面增加一行
441  common  get_cpus    sys_get_cpus

4.2、include/linux/syscalls.h
#在最后一个asmlinkage增加一行
asmlinkage long sys_get_cpus(void);

4.3、kernel/sys.c  
#在最后一个SYSCALL_DEFINE0后面增加下面几行
//获取系统中有多少CPU
SYSCALL_DEFINE0(get_cpus)
{
    return num_present_cpus();
}

5、内核配置

make menuconfig
make oldconfig

6、修改.config,去掉一个证书

CONFIG_SYSTEM_TRUSTED_KEYS=“”

7、编译

make -j4

8、安装

sudo make modules_install
sudo make install

9、测试
9.1、新建文件cpus.c

#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
int main(int argc, char const *argv[])
{
    //syscall就是根据系统调用号调用相应的系统调用
    long cpus = syscall(441);
    printf("cpu num is:%d\n", cpus);//输出结果
    return 0;
}

9.2、编译

gcc main.c -o cpus

9.3、运行

./cpus
在没有修改的内核上返回是-1
在修改过的为num_present_cpus数量

极客时间 操作系统实战45讲 Linux系统调用源码