操作系统基础知识

操作系统基础知识汇总

进程和线程

进程和线程有什么区别

  • 进程(Process)是系统进行资源分配和调度的基本单位,线程(Thread)是CPU调度和分配的基本单位;

  • 线程依赖于进程而存在,一个进程至少有一个线程;

  • 进程有自己的独立地址空间,线程共享所属进程的地址空间;

  • 进程是拥有系统资源的一个独立单位,而线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(
    如程序计数器,一组寄存器和栈),和其他线程共享本进程的相关资源如内存、I/O、cpu等;

  • 在进程切换时,涉及到整个当前进程CPU环境的保存环境的设置以及新被调度运行的CPU环境的设置,而线程切换只需保存和设置少量的寄存器的内容,并不涉及存储器管理方面的操作,可见,进程切换的开销远大于线程切换的开销;

  • 线程之间的通信更方便,同一进程下的线程共享全局变量等数据,而进程之间的通信需要以进程间通信(IPC)的方式进行;

  • 多线程程序只要有一个线程崩溃,整个程序就崩溃了,但多进程程序中一个进程崩溃并不会对其它进程造成影响,因为进程有自己的独立地址空间,因此多进程更加健壮

同一进程中的线程可以共享哪些数据

  • 进程代码段

  • 进程的公有数据(全局变量、静态变量…)

  • 进程打开的文件描述符

  • 进程的当前目录

  • 信号处理器/信号处理函数:对收到的信号的处理方式

  • 进程ID与进程组ID

线程独占哪些资源?

  • 线程ID

  • 一组寄存器的值

  • 线程自身的栈(堆是共享的)

  • 错误返回码:线程可能会产生不同的错误返回码,一个线程的错误返回码不应该被其它线程修改;

  • 信号掩码/信号屏蔽字(Signal mask):表示是否屏蔽/阻塞相应的信号(SIGKILL,SIGSTOP除外)

进程间通信方式有哪些

每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为
进程间通信(IPC)

  1. 管道(Pipe)
    可用于具有亲缘关系的父子进程间的通信

    • 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;
    • 一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据;
    • 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程
  2. 命名管道(FIFO)
    有名管道除了具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;

    • 有名管道的名字存在于文件系统中,内容存放在内存中。不支持定位读写。
    • 匿名管道是单向的,只能在有亲缘关系的进程间通信;有名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信。
  3. 消息(Message)队列
    消息队列是消息的链接表,它克服了上两种通信方式中信号量有限的缺点,具有写权限得进程可以按照一定得规则向消息队列中添加新信息;对消息队列有读权限得进程则可以从消息队列中读取信息;

    • 消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除一个消息队列时,该消息队列才会被真正的删除。

    • 消息队列允许一个或多个进程向它写入与读取消息.

    • 管道和消息队列的通信数据都是先进先出的原则。

    • 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比FIFO更有优势。

  4. 信号(Signal)
    信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生;

    • 信号是Linux系统中用于进程间互相通信或者操作的一种机制,信号可以在任何时候发给某一进程,而无需知道该进程的状态。

    • 如果该进程当前并未处于执行状态,则该信号就有内核保存起来,直到该进程恢复执行并传递给它为止。

    • 如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消是才被传递给进程。

  5. 共享内存
    可以说这是最有用的进程间通信方式。它使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据得更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等;

    • 为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间。进程就可以直接读写这一块内存而不需要进行数据的拷贝,从而大大提高效率。
  6. 信号量(Semaphore)
    主要作为进程之间及同一种进程的不同线程之间得同步和互斥手段;

    • 初始化操作、P操作、V操作;P操作:信号量-1,检测是否小于0,小于则进程进入阻塞状态;V操作:信号量+1,若小于等于0,则从队列中唤醒一个等待的进程进入就绪
  7. 套接字(Socket)
    这是一种更为一般得进程间通信机制,它可用于网络中不同机器之间的进程间通信,应用非常广泛。
    套接字的特性由3个属性确定,它们分别是:域、端口号、协议类型。

孤儿进程和僵尸进程

  • 父进程调用fork,返回两个值,

  • 父进程和子进程是异步运行,父进程并不知道子进程的状态

  • 父进程提前结束,子进程(孤儿)会被init的一个进程回收

  • 子进程提前结束,但是父进程在结束之前没有调用waitpid来获得子进程的状态,没有进行回收端口,导致端口一直被占用。

  • 大量的僵尸进程会导致无法继续创建进程,没有可用的端口号。

进程同步问题

通信方式

进程的同步是目的,而进程间通信是实现进程同步的手段

  1. 管程 Monitor

    管程将共享变量以及对这些共享变量的操作封装起来,形成一个具有一定接口的功能模块,这样只能通过管程提供的某个过程才能访问管程中的资源。进程只能互斥地使用管程,使用完之后必须释放管程并唤醒入口等待队列中的进程。

    当一个进程试图进入管程时,在入口等待队列等待。若P进程唤醒了Q进程,则Q进程先执行,P在紧急等待队列中等待。(HOARE管程)

    wait操作:执行wait操作的进程进入条件变量链末尾,唤醒紧急等待队列或者入口队列中的进程;
    signal操作:唤醒条件变量链中的进程,自己进入紧急等待队列,若条件变量链为空,则继续执行。(HOARE管程)

  2. MESA管程
    :将HOARE中的signal换成了notify(或者broadcast通知所有满足条件的),进行通知而不是立马交换管程的使用权,在合适的时候,条件队列首位的进程可以进入,进入之前必须用while检查条件是否合适。优点:没有额外的进程切换

临界区

各个进程中对临界资源(互斥资源/共享变量,一次只能给一个进程使用)进行操作的程序片段。

同步与互斥的概念?

  • 同步:多个进程因为合作而使得进程的执行有一定的先后顺序。比如某个进程需要另一个进程提供的消息,获得消息之前进入阻塞态;

  • 互斥:多个进程在同一时刻只有一个进程能进入临界区

并发、并行、异步的区别?

  • 并发:在一个时间段中同时有多个程序在运行,但其实任一时刻,只有一个程序在CPU上运行,宏观上的并发是通过不断的切换实现的;

  • 多线程:并发运行的一段代码。是实现异步的手段

  • 并行(和串行相比):在多CPU系统中,多个程序无论宏观还是微观上都是同时执行的

  • 异步(和同步相比):同步是顺序执行,异步是在等待某个资源的时候继续做自己的事

进程同步有哪几种机制

原子操作、信号量机制、自旋锁管程、会合、分布式系统

线程同步方式

为什么需要线程同步:线程有时候会和其他线程共享一些资源,比如内存、数据库等。当多个线程同时读写同一份共享资源的时候,可能会发生冲突。因此需要线程的同步,多个线程按顺序访问资源。

  • 互斥量
    Synchronized/Lock:采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问;当前拥有互斥对象的线程处理完任务后必须将互斥对象交出,以便其他线程访问该资源;

  • 信号量 Semphare:它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量。

  • 事件(信号),Wait/Notify:允许一个线程在处理完一个任务后,主动唤醒另外一个线程执行任务。事件分为手动重置事件和自动重置事件。通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作。

进程有哪几种状态

  • 就绪状态:进程已获得除处理机以外的所需资源,等待分配处理机资源

  • 运行状态:占用处理机资源运行,处于此状态的进程数小于等于CPU数

  • 阻塞状态: 进程等待某种条件,在条件满足之前无法执行

线程有哪几种状态

在 Java虚拟机 中,线程从最初的创建到最终的消亡,要经历若干个状态:创建(new)、就绪(runnable/start)、运行(running)、阻塞(
blocked)、等待(waiting)、时间等待(time waiting) 和 消亡(dead/terminated)。在给定的时间点上,一个线程只能处于一种状态,各状态的含义如下图所示:

线程各状态之间的转换如下:

什么是IO多路复用

单个进程/线程可以同时处理多个IO请求。

实现原理:
用户将想要监视文件描述符添加到select/poll/epoll函数中,由内核进行监视,函数阻塞。一旦有文件描述符就绪(读就绪或者写就绪),或者超时(设置),函数就会返回,然后该进程可以进行相应的读/写操作。

select、poll、epoll三者的区别

  • select
    :将文件描述符放入一个集合中,调用select时,将集合从用户空间拷贝到内核空间(缺点1:每次都要复制,开销大),由内核根据就绪状态修改该集合的内容(缺点2:集合大小有限制,32位机默认大小1024,64位机2048),采用水平触发的机制,select返回后需要通过遍历这个集合,找到就绪的文件描述符(缺点3:轮询的方式效率比较低),当文件描述符的数量增加时,效率会线性下降。

  • poll:和select几乎没区别,存储的方式由集合变为了链表,没有最大限制了。

  • epoll:通过内核和空间共享内存,避免的不断复制
    的问题,支持同时连接数上限很高(1G左右支持10W左右的连接数);文件描述符就绪时,采用了回调机制,避免了轮询(回调函数将就绪的描述符添加到一个链表中,执行epoll_wait时,返回这个链表),采用边缘触发时,只有活跃的文件描述符才会触发回调函数。

    • 水平触发:当epoll_wait监测到描述符事件发生时,epoll_wait()将此事件通知应用程序,应用程序可以不立即处理该事件,下次调用epoll_wait时,会再次响应应用程序并通知此事件;
      如果这一次没把数据一次性全部读写完(读写缓冲区太小),下次调用epoll_wait时,还会通知你会在没读写完的文件描述符上继续读写。

    • 边缘触发:当epoll_wait检测到文件描述符事件发生时,epoll_wait()
      将此事件通知应用程序,应用程序必须立即处理该事件。如果不处理,下次调用epoll_wait时,不会再次响应应用程序并通知此事件;
      如果一次没把数据全部读完(读写缓冲区太小),下次调用epoll_wait()
      时,他不会通知你,也就是它只会通知你一次,直到该文件描述符出现二次可读写事件才会通知你。这种模式比水平触发的效率高,系统不会充斥大量你不关心的就绪文件描述符。

三者区别

  • 一个线程/进程所能打开的最大连接数

  • 文件描述符的传递方式(内存共享还是复制)

  • 水平触发还是边缘触发

  • 查询就绪的描述符时的效率(是回调还是轮询)

什么时候使用select、poll、epoll

当连接数较少并且十分活跃的情况下,由于epoll需要很多回调性能可能会低于前两者,如果连接数较多,并且都不太活跃的情况下,epoll的效率会高于前两者很多。

什么是文件描述符

文件描述在形式上是一个非负整数,实际上是一个索引值,指向内核为每一个进程所维护的进程所打开的文件的记录表,当程序打开一个现有文件或者创建一个新文件的时候,内核向该进程返回一个文件描述符。

还有哪些常见的IO模型?

  • 同步阻塞IO:用户线程发起IO读写操作后,程序阻塞,直到可以开始处理数据,对CPU资源利用不够。
  • 同步非阻塞IO:发起IO请求后可以立即返回,没有就绪的数据,需要不断地发起请求直到数据就绪,不断重复请求消耗了大量的CPU资源。
  • IO多路复用
  • 异步IO:当用户线程发出IO请求之后又,继续执行,由内核进行数据的读取并放在用户指定的缓冲区内,在IO完成之后,通知用户线程直接使用。

什么是用户态和内核态

为了限制不同程序的访问能力,防止一些程序访问其他程序的的内存数据,CPU划分了用户态和内核态两个权限等级。
用户态只能受限的访问内存,且不允许访问外围设备,没有占有CPU的能力,CPU资源可以被其他资源获取。
内核态可以访问内存所有数据以及外围设备,也可以进行程序的切换。

所有用户程序都运行在用户态,但有时需要进行一些内核态的操作,比如从硬盘或者键盘读取数据,这个时候需要进行系统调用,使用陷阱指令,CPU切换到内核态执行相应的服务,再切换为用户态并返回系统调用的结果。

为什么要分用户态和内核态

  1. 防止用户程序恶意或者不小心破坏系统,内存,硬件资源
  2. 用户程序不需要去实现更加底层的代码
  3. 如果多个用户程序都在等待键盘输入,这个时候就需要进行调度,统一交给操作系统进行调度更加方便。

如何从用户态切换到内核态

  1. 系统调用:比如读取命令行输入。本质上是通过中断去实现
  2. 程序发生异常时:比如缺页异常
  3. 外围设备中断时:外围设备完成用户请求之后,会想CPU发出中断信号,这个时候CPU会转去处理对应的中断处理程序。

死锁

什么是死锁

在两个或者多个并发进程中,每个进程持有某种资源而又等待其它进程释放它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁(
deadlock)。

死锁产生的必要条件

  • 互斥:一个资源一次只能被一个进程使用;

  • 占有并等待:一个进程至少占有一个资源,并在等待另一个被其它进程占用的资源;

  • 非抢占:已经分配给一个进程的资源不能被强制性抢占,只能由进程完成任务之后自愿释放;

  • 循环等待:若干进程之间形成一种头尾相接的环形等待资源关系,该环路中的每个进程都在等待下一个进程所占有的资源。

死锁处理方法

  • 鸵鸟策略
    直接忽略死锁。因为解决死锁问题的代价很高,因此鸵鸟策略这种不采取任务措施的方案会获得更高的性能。当发生死锁时不会对用户造成多大影响,或发生死锁的概率很低,可以采用鸵鸟策略。*
    死锁预防
    基本思想是破坏形成死锁的四个必要条件:

  • 破坏互斥,条件破坏占有并等待条件,破坏非抢占条件,破坏循环等待条件,允许某些资源同时被多个进程访问。但是有些资源本身并不具有这种属性,因此这种方案实用性有限;

  • 实行资源预先分配策略(当一个进程开始运行之前,必须一次性向系统申请它所需要的全部资源,否则不运行);

  • 只允许进程在没有占用资源的时候才能申请资源(申请资源前先释放占有的资源)

    • 缺点:很多时候无法预知一个进程所需的全部资源;同时,会降低资源利用率,降低系统的并发性,允许进程强行抢占被其它进程占有的资源。会降低系统性能;
  • 对所有资源统一编号,所有进程对资源的请求必须按照序号递增的顺序提出,即只有占有了编号较小的资源才能申请编号较大的资源。这样避免了占有大号资源的进程去申请小号资源。

死锁避免

动态地检测资源分配状态,以确保系统处于安全状态,只有处于安全状态时才会进行资源的分配。所谓安全状态是指:即使所有进程突然请求需要的所有资源,也能存在某种对进程的资源分配顺序,使得每一个进程运行完毕。

如何检测死锁

检测有向图是否存在环;或者使用类似死锁避免的检测算法。

  • 利用抢占:挂起某些进程,并抢占它的资源。但应防止某些进程被长时间挂起而处于饥饿状态;
  • 利用回滚:让某些进程回退到足以解除死锁的地步,进程回退时自愿释放资源。要求系统保持进程的历史信息,设置还原点;
  • 利用杀死进程:强制杀死某些进程直到死锁解除为止,可以按照优先级进行。

内存管理

分页和分段有什么区别

  1. 页式存储:是一种用户视角内存与物理内存相分离的内存分配管理方案。用户空间划分为大小相等的部分称为页(page),内存空间划分为同样大小的区域称为页框,分配时以页为单位,按进程需要的页数分配,逻辑上相邻的页物理上不一定相邻;
  2. 段式存储:是一种符合用户视角的内存分配管理方案。用户进程地址空间按照自身逻辑关系划分为若干个段(segment)(如代码段,数据段,堆栈段),内存空间被动态划分为长度不同的区域,分配时以段为单位,每段在内存中占据连续空间,各段可以不相邻;
  3. 段页式存储:用户进程先按段划分,段内再按页划分,内存划分和分配按页。

区别

  • 目的不同:分页是由于系统管理的需要而不是用户的需要,它是信息的物理单位;分段的目的是为了能更好地满足用户的需要,它是信息的逻辑单位,它含有一组其意义相对完整的信息;

  • 大小不同:段的大小不固定,由其所完成的功能决定;页的大小固定,由系统决定;

  • 地址空间维度不同:分段是二维地址空间(段号+段内偏移),分页是一维地址空间(每个进程一个页表/多级页表,通过一个逻辑地址就能找到对应的物理地址);

  • 信息共享:分段便于信息的保护和共享;分页的共享收到限制;

  • 内存碎片:分段没有内碎片,但会产生外碎片;分页没有外碎片,但会产生内碎片(一个页填不满)

进程调度策略有哪些

可以分为抢占式和非抢占式

非抢占:先来先去,短作业优先,最高相应比优先

抢占式:最短剩余时间优先,时间片轮转,多级队列调度算法,多级反馈队列调度算法。

两者都有:优先级调度算法

批处理系统

  • 先来先服务 first-come first-serverd(FCFS)

按照请求的顺序进行调度。非抢占式,队列实现,开销小,无饥饿问题,响应时间不确定(可能很慢);
对短进程不利,对IO密集型进程不利。

  • 最短作业优先 shortest job first(SJF)

按估计运行时间最短的顺序进行调度。非抢占式,吞吐量高,开销可能较大,可能导致饥饿问题;
对短进程提供好的响应时间,对长进程不利。

  • 最短剩余时间优先 shortest remaining time next(SRTN)

按剩余运行时间的顺序进行调度。(最短作业优先的抢占式版本)。吞吐量高,开销可能较大,提供好的响应时间;
可能导致饥饿问题,对长进程不利。

  • 最高响应比优先 Highest Response Ratio Next(HRRN)

响应比 = 1+ 等待时间/处理时间。同时考虑了等待时间的长短和估计需要的执行时间长短,很好的平衡了长短进程。非抢占,吞吐量高,开销可能较大,提供好的响应时间,无饥饿问题。

交互式系统

交互式系统有大量的用户交互操作,在该系统中调度算法的目标是快速地进行响应。

  • 时间片轮转 Round Robin

将所有就绪进程按 FCFS 的原则排成一个队列,用完时间片的进程排到队列最后。抢占式(时间片用完时),开销小,无饥饿问题,为短进程提供好的响应时间;
若时间片小,进程切换频繁,吞吐量低;若时间片太长,实时性得不到保证。

  • 优先级调度算法(抢占/非抢占)

为每个进程分配一个优先级,按优先级进行调度。为了防止低优先级的进程永远等不到调度,可以随着时间的推移增加等待进程的优先级(老化)。

  • 多级队列调度算法

将就绪队列分成多个独立的队列,每个队列都有自己的调度算法,队列之间采用固定优先级抢占调度。其中,一个进程根据自身属性被永久地分配到一个队列中。

  • 多级反馈队列调度算法 Multilevel Feedback Queue

与多级队列调度算法相比,其允许进程在队列之间移动:若进程使用过多CPU时间,那么它会被转移到更低的优先级队列;在较低优先级队列等待时间过长的进程会被转移到更高优先级队列,以防止饥饿发生。

什么是虚拟内存

每个程序都拥有自己的地址空间,这个地址空间被分成大小相等的页,这些页被映射到物理内存;但不需要所有的页都在物理内存中,当程序引用到不在物理内存中的页时,由操作系统将缺失的部分装入物理内存。这样,对于程序来说,逻辑上似乎有很大的内存空间,只是实际上有一部分是存储在磁盘上,因此叫做虚拟内存。

虚拟内存的优点是让程序可以获得更多的可用内存,而且是连续的。

注意,请求分页系统、请求分段系统和请求段页式系统都是针对虚拟内存的,通过请求实现内存与外存的信息置换。

如上图,虚拟内存实际上可以比物理内存大。当访问虚拟内存时,会访问MMU(内存管理单元)去匹配对应的物理地址(比如图5的0,1,2)。如果虚拟内存的页并不存在于物理内存中(如图5的3,4),会产生缺页中断,从磁盘中取得缺的页放入内存,如果内存已满,还会根据某种算法将磁盘中的页换出,如下:

页面置换算法

进程运行时,若其访问的页面不在内存而需将其调入,但内存已无空闲空间时,就需要从内存中调出一页程序或数据,送入磁盘的对换区。选择调出页面的算法就称为页面置换算法。好的页面置换算法应有较低的页面更换频率,也就是说,应将以后不会再访问或者以后较长时间内不会再访问的页面先调出。

页面置换算法的主要目标是使页面置换频率最低(也可以说缺页率最低)。

  • FIFO 先进先出算法:在操作系统中经常被用到,比如作业调度;置换在内存中驻留时间最长的页面。缺点:有可能将那些经常被访问的页面也被换出,从而使缺页率升高;

  • LFU(Least frequently use)最少使用次数算法:根据使用次数来判断;

  • LRU(Least recently use)最近最少使用算法
    :置换出未使用时间最长的一页;实现方式:维护时间戳,或者维护一个所有页面的链表。当一个页面被访问时,将这个页面移到链表表头。这样就能保证链表表尾的页面是最近最久未访问的。

  • OPT(Optimal replacement)最优页面置换算法:置换以后不需要或者最远的将来才需要的页面,是一种理论上的算法,是最优策略;

  • 时钟算法 Clock:SCR中需要将页面在链表中移动(第二次机会的时候要将这个页面从链表头移到链表尾),时钟算法使用环形链表,再使用一个指针指向最老的页面,避免了移动页面的开销;

  • NRU(Not Recently Used)最近未使用算法:检查访问位R、修改位M,优先置换R=M=0,其次是(R=0, M=1);

  • NFU 最不经常使用算法:置换出访问次数最少的页面

什么是颠簸现象?

颠簸本质上是指频繁的页调度行为。进程发生缺页中断时必须置换某一页。然而,其他所有的页都在使用,它置换一个页,但又立刻再次需要这个页。因此会不断产生缺页中断,导致整个系统的效率急剧下降,这种现象称为颠簸。内存颠簸的解决策略包括:

  • 修改页面置换算法;

  • 降低同时运行的程序的数量;

  • 终止该进程或增加物理内存容量。

什么是局部性原理?

  • 时间上的局部性:最近被访问的页在不久的将来还会被访问;

  • 空间上的局部性:内存中被访问的页周围的页也很可能被访问。

堆和栈的区别

  • 空间分配

堆栈一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。由操作系统(编译器)自动分配释放
,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

  • 缓存方式

堆栈存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。使用的是一级缓存,
它们通常都是被调用时处于存储空间中,调用完毕立即释放。

微服务和分布式

微服务是架构设计方式,分布式是系统部署方式,两者概念不同

微服务概念

微服务就是很小的服务,小到一个服务只对应一个单一的功能,只做一件事。这个服务可以单独部署运行,服务之间可以通过RPC来相互交互,每个微服务都是由独立的小团队开发,测试,部署,上线,负责它的整个生命周期。

微服务架构概念

在做架构设计的时候,先做逻辑架构,再做物理架构,当你拿到需求后,估算过最大用户量和并发量后,计算单个应用服务器能否满足需求,如果用户量只有几百人的小应用,单体应用就能搞定,即所有应用部署在一个应用服务器里,如果是很大用户量,且某些功能会被频繁访问,或者某些功能计算量很大,建议将应用拆解为多个子系统,各自负责各自功能,这就是微服务架构。

分布式概念

分布式服务顾名思义服务是分散部署在不同的机器上的,一个服务可能负责几个功能,是一种面向SOA架构的,服务之间也是通过rpc来交互或者是webservice来交互的。逻辑架构设计完后就该做物理架构设计,系统应用部署在超过一台服务器或虚拟机上,且各分开部署的部分彼此通过各种通讯协议交互信息,就可算作分布式部署,生产环境下的微服务肯定是分布式部署的,分布式部署的应用不一定是微服务架构的,比如集群部署,它是把相同应用复制到不同服务器上,但是逻辑功能上还是单体应用。

总结:

微服务相比分布式服务来说,它的粒度更小,服务之间耦合度更低,由于每个微服务都由独立的小团队负责,因此它敏捷性更高,分布式服务最后都会向微服务架构演化,这是一种趋势, 不过服务微服务化后带来的挑战也是显而易见的,例如服务粒度小,数量大,后期运维将会很难


操作系统基础知识
https://zhyyao.me/2023/06/01/system/system_basic/
作者
zhyyao
发布于
2023年6月1日
许可协议