简介
微内核 vs 宏内核
什么是微内核架构设计?微内核是这样一种内核:它只完成内核不得不完成的功能,包括时钟中断、进程创建与销毁、进程调度、进程间通信,而其他的诸如文件系统、内存管理、设备驱动等都被作为系统进程放到了用户态空间。说白了,微内核是相对于宏内核而言的,像Linux就是典型的宏内核,它除了时钟中断、进程创建与销毁、进程调度、进程间通信外,其他的文件系统、内存管理、输入输出、设备驱动管理都需要内核完成。
也就是说,微内核是相对宏内核而言的,宏内核是一个包含非常多功能的底层程序,也就是我们现在讲的Monolith。它干的事情非常多,而且不是可插拔的,修改一些小的功能,都会涉及到整个程序的重新编译等,比如一个功能出现了一个小bug,可能导致整个内核都出问题。这也是很多人将Linux称为monolithic OS的原因。而微内核只负责最核心的功能,其他功能都是通过用户态独立进程以插件方式加入进来,然后微内核负责进程的管理、调度和进程之间通讯,从而完成整个内核需要的功能。基本一个功能出现问题,但是该功能是以独立进程方式存在的,不会对其他进程有什么影响从而导致内核不可用,最多就是内核某一功能现在不可用而已。PS:有了ebpf,linux也有点这意思
微内核就是一个运行在最高级别的程序片段,它能完成用户态程序不能完成的一些功能。微内核通过进程间通信来协调各个系统进程间的合作,这就需要系统调用,而系统调用需要切换堆栈以及保护进程现场,比较耗费时间;而宏内核则是通过简单的函数调用来完成各个模块之间的合作(PS:比如一个进程访问文件,在内核空间就是一个函数调用),所以理论上宏内核效率要比微内核高。这个和微服务的架构设计一样,我们将Monolith应用划分为多个小应用后,系统的设计就变得比较复杂了,之前都是应用内部函数调用,现在要涉及网络通讯、超时等问题,同时响应时间会被拉长。
但是这里还有一个问题,那就是进程间通讯。你可能会问,这个有什么好疑问的,就是两个进程之间相互发消息呗。但是这里有一个最大的疑问,那就是进程间通讯是否有第三者介入?如下图:
当然在操作系统的内核设计中,一定是通过内核进行转发的,就是我们理解的总线架构,内核负责协调各个进程间的通讯。这个大家也能理解,如果进程A直接发给另外一个进程B,必然要了解对应的内存地址,微内核中的服务是可以被随时替换的,如果服务不可用或者被替换,这个时候要通知和其通讯的其他进程,是不是太复杂?刚才已经提到,只有send和receive接口,没有其他通知下线、服务不可用的接口。在微内核的设计中,一定是通过总线结构,进程向Kernel发送消息,然后kernel再发送给对应的进程,这样的一个总线设计。实际上很多应用内部在做Plug-in组件解耦时,都会使用EventBus的结构,其实就是总线的设计机制。
艺术性
- 指令是稳定的,但指令序列是变化的,只有这样计算机才能够实现 “解决一切可以用 ‘计算’ 来解决的问题” 这个目标。计算是稳定的,但数据交换是多变的,只有这样才能够让计算机不必修改基础架构却可以适应不断发展变化的交互技术革命。
- 通过引入缺页中断,CPU 将自身与多变的外置存储设备,以及多变的文件系统格式进行了解耦。
- 中断机制,我们可以简单把它理解为 CPU 引入的回调函数。通过中断,CPU 把对计算机外设的演进能力交给了操作系统。