当前位置: 首页 > news >正文

[OS_27] 现代应用程序架构

进程 (运行的程序),一直以来都是操作系统中的核心抽象。

作为应用程序的主体,运行进程的方式却在多年的发展中历经了许多变化。

本文内容应用程序是如何运行在数据中心上的。

27.1 虚拟机和容器

虚拟化与隔离

Full System Emulation

  • 这个简单,就是 NEMU 啊:取指令、译码、执行
    • 致命的是性能: 性能不及 native 的 10%

Full System Emulation 的黄金时代

黄金时代的起点

  • Disco (1997): “brings back an idea popular in the 1970s: virtual machine monitors”
  • VMWare (1998): 我们能把这个技术做成产品!

Hack: Guest Ring 3 直接运行在 Host Ring 3

  • System call 会 trap 到 VMM
    • Windows Subsystem for Linux (2016)

  • Xen and the art of virtualization (2003)
    • Intel: VT-x (2005) →→ VT-d (2006) →→ EPT (2008)
    • (我们之前讲过 /dev/kvm)

为什么会有黄金时代?

Dot-com bubble 时代 (2000)

  • ISP (Internet Service Provider) 提供的是物理机
  • 虚拟机:和物理机用起来完全一样,但一台能当 n 台卖
    • 商人:我们都是 oversubscribe 的 💴

完整系统模拟器的高效性原理

完整系统模拟器(full system emulator)能够高效运行的核心在于硬件虚拟化技术的优化和现代处理器的强大算力。通过动态二进制翻译、直接硬件访问等机制,模拟器可以接近原生性能。

硬件加速技术

现代模拟器利用CPU的虚拟化扩展(如Intel VT-x、AMD-V)直接执行部分指令,避免软件翻译开销。GPU虚拟化技术(如VirGL)将图形指令转为宿主机的OpenGL调用,显著提升图形性能。

动态二进制翻译

模拟器实时将目标平台的机器代码转换为宿主机的等效指令,通过缓存翻译结果减少重复工作。QEMU等模拟器还会优化热代码路径,提升关键代码的执行效率。

内存与I/O优化

采用影子页表技术减少内存访问的转换层数,对磁盘和网络设备采用半虚拟化驱动(如virtio),避免完全模拟硬件设备的性能损耗。内存预取和缓存策略进一步降低延迟。

实际性能表现

在配备SSD的现代主机上,模拟器运行轻量级操作系统(如Linux)可达原生性能的70-90%。游戏主机模拟器(如Dolphin)通过特定硬件优化,已能流畅运行多数3D游戏。云服务商的虚拟实例更是基于类似技术提供接近物理机的性能。


Everything is a State Machine...

虚拟机:更容易管理状态了

  • ReVirt: Enabling intrusion analysis through virtual-machine logging and replay (OSDI'02)
    • 时间转移:“replay the long-term, instruction-by-instruction execution of a computer system.”
  • Optimizing migration of virtual computers (OSDI'02)
    • 空间转移:“a system that moves a computer's state over a slow (384kbps) DSL link in minutes rather than hours.”

Hackers 的时代

  • 华为操作系统首席科学家;上海交通大学 IPADS 所长 _ 陈海波教授
    • Live updating operating systems using virtualization (VEE'06)

浪潮过后……

操作系统:我自己就能虚拟化自己啊

  • 应用程序只能看到系统调用 API
    • 操作系统:“假装” 在虚拟机里执行系统调用
    • 例子:虚拟的 pstree
      • pid = 1: init (systemd)

pid 可以不再是整个操作系统唯一的

  • 给每个进程增加一个 “osid”,增加系统调用 vos(fs_root)
    • 创建一个新的 osid
    • pid 从 1 开始分配
    • fork() 继承父进程的 osid

祝贺,你发明了 Linux Namespaces!

只要想 “操作系统里有什么对象” 就行了

(一层不行,那就再加一层)

  • 需要为 osid 区别实现的对象
    • pid: (刚才讲了)
    • user: 用户和组 (这个很重要)
    • mnt: 文件系统和设备
    • ipc: 信号量、消息队列、共享内存
    • net: 网络设备、协议栈、端口 (localhost:5000)
    • time: 系统时间和时区
    • uts: 主机名和域名
  • Linux namespaces: /proc/[pid]/ns/
    • lsns 可以查看 (strace)

Namespaces (7)

clone

  • 创建进程时可以带 CLONE_NEW_xxx (PID, IPC, ...) 选项

setns, unshare

  • 改变某一个项目的 “osid”

ioctl

  • Windows Subsystem for Linux: 听我说谢谢谢你
    • (选择放弃)

再进一步:资源调度

实现资源的控制

  • “圈一些进程”,设定资源使用策略
  • 祝贺,你发明了 cgroups
    • cat /proc/*/cgroup
    • /sys/fs/cgroup

这是一个和 namespaces 正交的机制

  • 共同使用,你就得到了容器
    • 例子:只有 busybox 的 “系统中的系统”
    • 祝贺,你发明了 docker!

云时代的虚拟机

如果只需要 Linux

  • 容器就和虚拟机完全一样
  • 开销比虚拟机低很多,安全性略低
    • 这样不就可以在一台物理上部署更多的服务了吗
      • 商人: 💴的机会来啦!

Kubernetes: “容器编排”

  • 跨主机、弹性自动编排
  • 自动容错:这是云厂商最爱看到的

https://github.com/lvy010/operating-system_code/tree/main/cgroups

cgroups: 我们可以在 sysfs 中观察 cgroups 的状态,看到 cgroups 的层次结构。


27.2 云原生与微服务

云原生、微服务和 Serverless

舞台已经搭好了……

我们有容器 (虚拟机) 了

  • 本来虚拟机里也是 HTTP Server (httpd)
  • 干脆把程序拆成 Microservices?
    • Cloud Native: 云会负责容器管理、API Gateway、负载均衡……

Serverless: “容器” 的概念都可以不要了

  • 只需要实现 int foo() {}
  • 剩下的都交给云厂商
    • 商人:都不需要 oversubscribe 了,直接按量计费,最大程度榨干机器性能

Function-as-a-Service (FaaS)

Remote Procedure Call (RPC) 调用远程函数

  • apt install ffmpeg; ffmpeg -i a.mp4 -f ffmetadata -
def get_media_data(object_key):client = fc2.Client(endpoint="https://<id>.cn-hangzhou.fc.aliyuncs.com",accessKeyID="xxxxxxxx", accessKeySecret="yyyyyy")return client.invoke_function("FcOssFFmpeg","GetMediaMeta",payload=json.dumps({"bucket_name": "test-bucket","object_key": object_key})).dataget_media_data('/object/key/to/a.mp4')

再加上 CI/CD

  • 你只需要 git push,剩下都是自动的
    • 例子:git push 会触发 http 请求 hook (X-Gitlab-Token 的 header),服务器就获得控制权了
    • 本地测试好,git push 等一等,应用就上线了

“计算机” 会消失吗?

只需要云和终端?

response = OpenAI().responses.create(model="gpt-4.1-mini",input="Generate an image of ...",tools=[{"type": "image_generation"}],
)image_data = [output.result for output in response.outputif output.type == "image_generation_call"]if image_data:image_base64 = image_data[0]with open("cat_and_otter.png", "wb") as f:f.write(base64.b64decode(image_base64))
  • “AI inference” 占程序运行时长的比例会越来越高吗?
    • 计算机视觉应用中,推理耗时占比可达90%以上。自然语言处理场景中,大模型推理可能占据服务端75%-85%的计算资源。

26.3 总结

Take-away messages: 透过虚拟化发展的历史浪潮,从虚拟机到容器,再到 Serverless,我们看到 “计算机系统” 作为支撑性技术给应用世界带来的变革。

有些时候,革命性的技术建立在极简的动机上,例如 “full system emulator 真的可以运行得很快”,或是 “给每个操作系统对象加一个 osid”,世界就会就此改变。

http://www.lqws.cn/news/527617.html

相关文章:

  • ESP32 VSCODE进入menuconfig时ESP-IDF idf.py menuconfig卡进度条,setuptools版本太高解决方法
  • 小程序学习笔记:实现上拉触底加载随机颜色案例全解析
  • 深度剖析 Apache Pulsar:架构、优势与选型指南
  • 图像质量对比感悟
  • [论文阅读] 人工智能 + 软件工程 | AI 与敏捷开发的破局之路:从挫败到成功的工作坊纪实
  • 推荐一个前端基于vue3.x,vite7.x,后端基于springboot3.4.x的完全开源的前后端分离的中后台管理系统基础项目(纯净版)
  • HTML 按钮单击事件示例
  • 2-深度学习挖短线股-4-预测数据计算
  • 前端项目3-01:登录页面
  • 实测推荐:一款能看4K直播的万能播放器,支持多端同步
  • 全面比较帮你确定何时选择SLM而非LLM
  • C# .NET Framework 中的高效 MQTT 消息传递
  • React HOC(高阶组件-补充篇)
  • Django 零基础起步:开发你的网站第一步
  • IDE如何快速切换JLINK版本
  • Redis 持久化
  • Axure版AntDesign 元件库-免费版
  • 广州华锐互动:技术与创意双驱动的 VR 先锋​
  • Python 中的 random 模块
  • 49-有效的字母异位词
  • 设计模式精讲 Day 14:命令模式(Command Pattern)
  • Web基础关键_001_HTML(一)
  • docker环境下java参数传递与获取
  • FANUC机器人教程:用户坐标系标定及其使用方法
  • 学习永无止境
  • 程序的更新总结
  • 简易服务器(TCP)
  • 川翔云电脑全新上线:三维行业高效云端算力新选择
  • Kotlin环境搭建与基础语法入门
  • 鸿蒙边缘智能计算架构实战:多线程图像采集与高可靠缓冲设计