> 文档中心 > skynet设计原理

skynet设计原理


先说说多核并发编程

可以分情况讨论

线程

创建CPU核心数的线程数量,memcached就是使用多线程。
多个线程在同一个进程中,涉及到很多临界资源的访问,所以要考虑到加锁。
如下图。
在这里插入图片描述

多进程

和多线程类似,都是创建CPU核心数量个进程。Nginx就是使用多进程的。
Nginx通过共享内存来进行共享数据,也需要考虑使用锁。
如下图。
在这里插入图片描述

CSP

以go语言作为代表,并发实体是协程(用户态线程、轻量级线程),内部也可以使用多个核心开启内核线程去充分使用多核。
可以借鉴我的前面博客写的协程框架。

Actor

这个也是skynet最主要的使用多核并发模型。

erlang语言层面支持actor并发模型,并发实体是actor(在skynet中称为服务);
在skynet中就是采用C+lua来实现actor并发模型,底层通过采用核心绑定内核线程来充分利用多核。

先说说actor模型是如何

并发编程的几个概念
  1. 保证数据的一致性、隔离性、正确性和并发性
  2. 通信策略有两种:共享数据、消息传递
  3. 粒度
actor出现是解决什么问题

使用共享数据的并发编程面临最大的问题就是数据条件的竞争,需要处理各种锁和死锁的问题。因此可以使用消息传递来减弱这种数据竞争的状态。
其次就是随着项目增大,业务代码越来越多,不可避免的大量使用低效的锁,并没有规范的额编程模型,是最后肯定也会出现问题,最根本的原因就是没有将系统的任务调度抽象出来,由于任务调度和业务逻辑耦合在一起了,很难高度的抽象保证任务调度的有序。

actor特点(后面根据这些特点讲述skynet的actor是如何实现的)

优点

  • 强隔离性
  • 更易于管理

缺点

  • 弱一致性
  • 很难保证各个actor之间粒度,会出现单个actor出现阻塞的情况
  • actor之间的通信慢

在skynet中的actor(服务)的特点

  • 并行执行、强隔离性
  • 单个actor是一个服务,每个服务都是独立的一个抽象进程
  • 基于消息进行计算,actor通过消息进行共享数据

skynet的组成

  • 隔离的环境
  • 消息队列
  • 回调函数

大体的运行过程:
用户态中含有多个抽象进程(隔离的环境),一个fd对应一个进程,从消息队列中取出一个消息,消息作为回调函数的参数运行,每个消息都是在抽象进程中独立运行。

隔离的环境

是指一个独立的lua虚拟机。

消息队列

消息分类:

  1. 网络的消息:客户端的消息
  2. actor之间的消息
  3. 定时线程的消息

消息队列有全局的消息队列和actor的消息队列。全局的消息队列重要用来接收网络中的待处理的全部消息类型。actor中的消息队列用来储存属于自己的消息,当actor中有消息时就说明这个actor是活跃的,需要被调度的。

回调函数

当actor是活跃的,回调函数会从actor中消息队列中取出消息,并作为回调函数的参数运行actor。一个actor就是一个lua虚拟机,代表一个抽象的进程。

网络IO的管理

skynet同样使用epoll来对网络IO进行管理,skynet是基于reactor的网络模型。
在这里插入图片描述

整个框架的模型

在这里插入图片描述

整个框架如何运行?

采用生产者和消费者模型

产品

  • 消息

生产者:

  • 网络线程
  • actor工作线程
  • 定时器线程
    消费者
  • actor工作线程

调度流程

核心:线程池
生产

  1. 网络线程收集出网络事件,将事件包装成消息发送到对应的actor的消息队列中
  2. actor在执行中可能会使用到一些延时任务,将任务交由定时线程,当一段时间过后,定时线程又会将消息返回给actor的消息队列当中

消费

  1. 线程池的工作线程去检查活跃的actor(消息队列当中有消息),消息队列是并发执行的
  2. 分权重,前4个线程会先执行一个消息,后面4个线程会执行完所有消息 ,错位执行:优化,避免某个actor堆积大量消息。

工作线程执行流程

工作线程从全局队列中 pop 出单个 Actor 消息队列;从 Actor 消息队列中按照规则 pop 出一定数量的消息进行执行;若 Actor 消息队列中仍有消息继续放入全局队列队尾;若 Actor 消息队列中没有消息则不放入全局队列中;全局队列只存活跃的 Actor 消息队列;

工作线程会按照各自的权重按照不同的执行规则分发消息。

总结

skynet大致的工作过程和原理大概如此,后续会翻看源码再总结。

学习来源:零声学院 免费公开课程,个人觉得老师讲得不错,分享给大家Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容