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

Skynet入门(一)

概念

skynet 是一个为网络游戏服务器设计的轻量框架。但它本身并没有任何为网络游戏业务而特别设计的部分,所以尽可以把它用于其它领域。

设计初衷

如何充分利用它们并行运作数千个相互独立的业务。

模块设计建议

在 skynet 中,用服务 (service) 这个概念来表达某项具体业务,它包括了处理业务的逻辑以及关联的数据状态。使用 skynet 实现游戏服务器时,不建议把业务状态同步到数据库中,而是存放在服务的内存数据结构里。服务、连同服务处理业务的逻辑代码和业务关联的状态数据,都是常驻内存的。

可以把 skynet 理解为一个简单的操作系统,它可以用来调度数千个 lua 虚拟机,让它们并行工作。每个 lua 虚拟机都可以接收处理其它虚拟机发送过来的消息,以及对其它虚拟机发送消息。每个 lua 虚拟机,可以看成 skynet 这个操作系统下的独立进程,你可以在 skynet 工作时启动新的进程、销毁不再使用的进程、还可以通过调试控制台监管它们。skynet 同时掌控了外部的网络数据输入,和定时器的管理;它会把这些转换为一致的(类似进程间的消息)消息输入给这些进程。

网络

我们不建议你在 skynet 的服务中再使用任何直接和系统网络 api 打交道的模块,因为一旦这些模块被网络 IO 阻塞,影响的就不只是该服务本身,而是 skynet 里的工作线程了。skynet 会被配置成固定数量的工作线程,工作线程数通常和系统物理核心数量相关,而 skynet 所管理的服务数量则是动态的、远超过工作线程数量。skynet 内置的网络层可以和它的服务调度器协同工作,使用 skynet 提供的网络 API 就可以在网络 IO 阻塞时,完全释放出 CPU 处理能力

我们通常建议使用一个网关服务,专门监听端口,接受新连接。在用户身份确定后,再把真正的业务数据转交给特定的服务来处理。同时,网关还会负责按约定好的协议,把 TCP 连接上的数据流切分成一个个的包,而不需要业务处理服务来分割 TCP 数据流。业务处理的服务不必直接面对 socket 句柄,而由 skynet 正常的内部消息驱动即可。

运行原理

服务service运行的三个阶段

  1. 服务加载阶段,当服务的源文件被加载时,就会按 lua 的运行规则被执行到。这个阶段不可以调用任何有可能阻塞住该服务的 skynet api 。因为,在这个阶段中,和服务配套的 skynet 设置并没有初始化完毕。
  2. 服务初始化阶段,由 skynet.start 这个 api 注册的初始化函数执行。这个初始化函数理论上可以调用任何 skynet api 了,但启动该服务的 skynet.newservice 这个 api 会一直等待到初始化函数结束才会返回。
  3. 服务工作阶段,当你在初始化阶段注册了消息处理函数的话,只要有消息输入,就会触发注册的消息处理函数。这些消息都是 skynet 内部消息,外部的网络数据,定时器也会通过内部消息的形式表达出来。

从 skynet 底层框架来看,每个服务就是一个消息处理器。但在应用层看来并非如此。它是利用 lua 的 coroutine 工作的。当你的服务向另一个服务发送一个请求(即一个带 session 的消息)后,可以认为当前的消息已经处理完毕,服务会被 skynet 挂起。待对应服务收到请求并做出回应(发送一个回应类型的消息)后,服务会找到挂起的 coroutine ,把回应信息传入,延续之前未完的业务流程。

同一个 skynet 服务处理很多消息,处理这些消息的流程永远不会真正的并行,它们只是在轮流工作。一段业务会一直运行到下一个 IO 阻塞点,然后切换到下一段逻辑。你可以利用这一点,让多条业务线在处理时共享同一组数据,这些数据在同一个 lua 虚拟机下时,读写起来都比通过消息交换要廉价的多。

两次阻塞 API 调用之间,运行过程是原子的,利用这个特性,会比传统多线程程序更容易编写。如果一条用户线程永远不调用阻塞 API 让出控制权,那么它将永远占据系统工作线程。skynet 并不是一个抢占式调度器,没有时间片的设计,不会因为一个工作线工作时间过长而强制挂起它。

消息

组成

  • 消息类型:回应消息、网络消息、调试消息、文本消息、Lua 消息、错误。
  • session
  • 发起服务地址
  • 接收服务地址
  • 消息 C 指针
  • 消息长度
消息类型
  • 回应消息通常不需要特别处理,它由 skynet 基础库管理,用来调度服务内的 coroutine 。
  • 网络消息也不必直接处理它,skynet 提供了 socket 封装库,封装管理这类消息,改由一组更友好的 socket api 方便使用。
  • 调试消息已经被默认的 skynet 基础库处理了。它使得所有 skynet 服务都提供有一些共同的能力。
  • 真正的业务逻辑是由文本类消息和 Lua 类消息驱动的。它们的区别仅在于消息的编码形式不同,文本类消息主要方便一些底层的,直接使用 C 编写的服务处理,它就是简单字节串;而 Lua 类消息则可以序列化 Lua 的复杂数据类型。大多数情况下,我们都只使用 lua 类消息。
  • 接管某类消息需要在服务的初始化过程中注册该消息的序列化及反序列化函数,以及消息回调函数。

Actor模型

组成

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

消息调度机制


文章转载自:

http://jY0HuWwq.gnjtg.cn
http://LTbPxlgD.gnjtg.cn
http://QdSYHNd5.gnjtg.cn
http://Fw0UyVE8.gnjtg.cn
http://PoJMImL5.gnjtg.cn
http://ithZqBZd.gnjtg.cn
http://pfPFOBVr.gnjtg.cn
http://x0SWNLmg.gnjtg.cn
http://1lKywCAO.gnjtg.cn
http://xHDrjTAu.gnjtg.cn
http://aDFSxDdK.gnjtg.cn
http://UQ2fVFjt.gnjtg.cn
http://XSZgNmis.gnjtg.cn
http://NxdQYTds.gnjtg.cn
http://dAaUJU8B.gnjtg.cn
http://cuODtY10.gnjtg.cn
http://3TqHycQF.gnjtg.cn
http://eXNgnt1M.gnjtg.cn
http://2OlXm7dO.gnjtg.cn
http://OjxSI5Nh.gnjtg.cn
http://uSRAvOQW.gnjtg.cn
http://Mi23DUYr.gnjtg.cn
http://hGk9IO5a.gnjtg.cn
http://3uz7dE4l.gnjtg.cn
http://vQvJKd4d.gnjtg.cn
http://wLEhMvg4.gnjtg.cn
http://OIrUvlv9.gnjtg.cn
http://aZx3NqZ1.gnjtg.cn
http://ly7p7Hn7.gnjtg.cn
http://MbSYtu3u.gnjtg.cn
http://www.dtcms.com/a/45707.html

相关文章:

  • JavaScript系列02-函数深入理解
  • Android SDK与NDK的区别
  • LeetCode第58题_最后一个单词的长度
  • 进行性核上性麻痹患者的生活护理指南
  • tableau之标靶图、甘特图和瀑布图
  • CI/CD与容器化技术核心知识点的QA
  • SQL 语言基础:日期和时间处理
  • ES怎么查询大于10000条数据
  • 在一台win10专业版设备上使用docker的怪现象
  • 本地部署DeepSeek-R1(Dify发件邮箱、找回密码、空间名称修改)
  • mysql中的的锁
  • 05 英雄C++ STL 编程(下)
  • 【补充】RustDesk一键部署及账号登录配置
  • 算法-二叉树篇20-二叉搜索树中的众数
  • 探索分布式事务与Seata:构建可靠的Spring微服务架构
  • MySQL零基础教程11—拼接/计算
  • 监控视频流web端播放
  • Vue.js 组件开发全面详解及应用案例
  • 【量化金融自学笔记】--开篇.基本术语及学习路径建议
  • Hive配置
  • 计算机毕业设计SpringBoot+Vue.js人口老龄化社区服务与管理平台 (源码+文档+PPT+讲解)
  • PHP实现登录和注册(附源码)
  • 如何通过rust实现自己的web登录图片验证码
  • react 中,使用antd layout布局中的sider 做sider的展开和收起功能
  • 对于运维稳定性建设的一些思考
  • Let‘s Encrypt 获取免费SSL证书
  • 如何在 IntelliJ IDEA 中集成 DeepSeek
  • DeepSeek实操教程(清华、北大)
  • MATLAB环境下从信号中去除60Hz工频干扰噪声
  • git push失败