nodejs循序渐进-高性能游戏服务器框架pomelo之启动流程和组件

本文涉及的产品
云原生网关 MSE Higress,422元/月
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
性能测试 PTS,5000VUM额度
简介: nodejs循序渐进-高性能游戏服务器框架pomelo之启动流程和组件

游戏启动过程

启动入口

在使用pomelo进行游戏开发时,工程目录下的app.js是整个游戏服务器的启动运行入口。app.js中创建项目,进行默认配置并启动服务器的代码如下:

var pomelo = require('pomelo');
var app = pomelo.createApp();
app.set('name', 'nameofproject');
app.start();

image.gif

从上面的代码可以看出,用户首先需要在项目中引入pomelo,然后创建application的实例app,接着完成一些基本的应用配置,最后应用就可以启动了。当app.js运行起来后,pomelo会根据游戏的配置启动不同的相关组件及服务器。

服务器与组件

服务器启动流程的主要工作就是逐一启动app.load注册的组件。组件是连接pomelo框架和当前服务器所依赖的服务之间的桥梁。不同的服务器可以选择加载不同的组件。Pomelo提供了一些系统默认的组件,主要包括:handler, filter, master, monitor, proxy, remote, server, sync, connection。开发者也可以根据需要,开发自己的组件,并加载到服务器进程中。

组件同时是具有生命周期的,其生命周期可以包括start, after start, stop等。在组件中可以实现这些方法,应用服务器会在不同的运行阶段执行组件不同生命周期的方法。

启动流程详述

应用创建及启动

所有服务器的启动都是从运行app.js开始。每一个服务器的启动都首先创建一个全局唯一的application对象,该对象中挂载了所在服务器的所有信息,包括服务器物理信息、服务器逻辑信息、以及pomelo的组件信息等。同时,该对象还提供应用管理和配置等基本方法。 在app.js中调用app.start()方法后,application对象首先会通过loadDefaultComponents方法加载默认的组件。

组件加载

在加载组件时,系统会根据application对象中服务器的信息,针对不同的服务器加载不同的组件,从而使得不同服务器进程对外提供不同个服务。对于master服务器,主要加载的组件是master组件。Master组件主要负责根据根据servers.json文件中的配置信息和启动参数去启动其他服务器。对于其它服务器默认加载proxy、channel、sync、backendSession和server组件,特定的服务器还需要加载特定的组件,例如前端服务器会加载统计客户端连接数量的connection组件。具体组件的说明如下:

    • master: master组件主要负责启动master服务器。
    • monitor: monitor组件主要负责启动各个服务器的monitor服务,该服务负责收集服务器的信息并定期向master进行消息推送,保持master与各个服务器的心跳连接。
    • proxy: proxy组件主要负责生成服务器rpc客户端,由于系统中存在多个服务器进程,不同服务器进程之间相互通信需要通过rpc调用(master服务器除外)。
    • remote: remote组件主要负责加载后端服务器的服务并生成服务器rpc服务端。
    • server:server组件主要负责启动所有服务器的用户请求处理服务。
    • connector: connector组件主要负责启动前端服务器的session服务和接收用户请求。
    • sync: sync组件主要负责启动数据同步模块并对外提供数据同步功能。
    • connection: connection组件主要负责启动用户连接信息的统计服务。
    • channel: channel组件主要负责启动channelService服务,该服务主要提供channel相关的功能包括创建channel,通过channel进行消息推送等。
    • session: session组件主要负责启动sessionService服务,该服务主要用来对前端服务器的用户session进行统一管理。
    • backendSession: backendSession组件主要负责启动backendSession服务,该服务主要负责维护服务器本地session并与前端服务器进行交互。
    • dictionary: dictionary组件主要负责生成handler的字典。
    • protobuf: protobuf组件主要负责解析服务端和客户端的proto buffer的定义,从而对客户端和服务端的通信内容进行压缩。

    组件概述

    我们知道,pomelo的应用程序执行的全部过程,就是对其相应组件的生命周期的管理,实际的所有逻辑功能均由pomelo组件提供。pomelo内建提供了十多个组件,这些组件适用于不同的服务器,提供不同的功能。有些组件提供的功能比较复杂,有些则比较简单。下面我们将以提供的功能为主线来阐述pomelo提供的内建组件。

    master组件

    master组件仅仅由master服务器加载,它主要的功能包括启动所有的应用服务器、管理和监控所有的应用服务器和接受管理客户端的请求与响应。

    master服务器总是率先启动,master组件在其start调用的最后才会调用Starter.start,Starter.start才会启动所有的应用服务器,因此Master组件总是最先start。在Master组件的start调用中,会完成以下几步:

      • 加载注册Module到MasterConsoleService,Module的导出方式有两种,可以导出工厂函数,也可以导出对象,如果导出工厂函数的话,其签名应该是 FacFunc(opts, ConsoleServicee),其中opts是用户调用app.registerAdmin的时候传入的,ConsoleService则是具体的加载注册Module的MasterConsoleService。
      • 在加载注册完所有的Module后,会开启MasterAgent对端口的监听,此时,master就已经可以接收来自monitor和client的request和notify了。
      • 开启监听后,MasterConsoleService会enable所有的module,这步操作主要是看看有没有module配置了周期性地拉去monitor信息,也就是module的配置中有type选项和interval选项,且type的值为'pull',interval指定了周期,则认为其配置了周期性监控操作,此时会完成周期性事件的调度,使得master可以周期性地获取监控信息。
      • 最后如果有Module定义了start回调,将会在这里调用,一般在start回调里会做一些初始化信息。 经历了这些步骤后,master完成启动。

      在master组件的start方法里,会根据用户提供的服务器配置信息,启动用户配置的所有的具体应用服务器。

      当master组件start结束后,他将开启一个socket监听端口,接受应用服务器和监控客户端的连接和注册,收集应用服务器上报的监控信息,给应用服务器推送一些消息,并对管理客户端发出的管理请求给予响应。管理客户端如pomelo-cli可能发出的请求包括查看某个服务器进程状态,增加一个服务器,停掉一个服务器等。以增加一个服务器为例,当管理客户端发出增加服务器请求时,会提供相应的服务器参数,如服务器类型,主机ip,开启的端口等。此时,master组件接受后,会启动相应的服务器,并将新增加的服务器信息广播通知给其他已经启动的服务器。

      master组件无配置项。

      monitor组件

      monitor组件由所有的包括master服务器在内的服务器都会加载,它的主要功能就是与master建立连接进行通信,从而对整个应用服务器群进行管理和监控。master服务器本身也会加载monitor服务器,因为master服务器也会收集其本身自己的监控信息。

      由于应用服务器是在master组件启动后期才创建,因此monitor总是后于master启动。monitor的启动过程与master类似,唯一不同的就是,monitor会发起到master的连接,而不是监听接口。monitor中同样也会使用与master完全相同的方式,加载注册Module,如果有Module配置了周期性地推送监控数据到master的话,即其配置type的值为'push',这里也会调度对应的事件,使得能够周期地推送数据。最后如果有Module定义了start的话,则会回调start。Monitor的启动过程与master基本一致。

      monitor会通过master接受一些命令,比如关闭整个服务器等。对于一些周期性监控的信息,pomelo提供了两种收集方式,即pull方式和push方式。pull方式要求master周期地去与monitor通信,拉取相应的监控信息;push方式,则是由monitor周期地主动地向master报告其监控信息。

      monitor组件无配置项。

      filter

      pomelo内建了常见的一些filter,用户可以通过如下的方式启用:

      app.filter(pomelo.filters.<filterName>(<args>));

      image.gif

      下面介绍一下这几个fitler:

      serial

      这个filter是用来对用户请求做串行化的,可以使得用户的请求只有在第一个请求被处理完后,才会处理第二个请求。serial中使用了一个taskManager,当用户请求到来时,在beforeFilter中,将用户的请求放到taskManager中,taskManager中维护着一个task队列。在对应的afterFilter中,如果taskManager还有未处理的请求,将会处理其请求,即在一个请求的afterFilter里启动在taskManager中还没处理的下一个请求,这样就实现了请求的序列化。

      timeout

      这个filter是用来对服务端处理超时进行警告的,在beforeFilter中会启动一个定时器,在afterFilter中清除。如果在其定时器时间内,afterFilter被调用,定时器将会被清除,因此不会出现超时警告。如果定时器超时时,afterFilter还没有执行到,则会引发超时警告,并记录日志。默认的处理超时是3秒,可以在加载timeout的时候作为参数传入。

      time

      这个filter使用来记录服务器处理时间的,在beforeFilter中会记录一下当前的时间戳,在afterFilter中再次获取当前的时间戳,然后两个时间戳相减,得到整个处理时间,然后记录日志。

      toobusy

      这个filter中,一旦检测到node.js中事件循环的请求等待队列过长,超过一个阀值时,就会触发toobusy。一旦触发了toobusy,那么toobusy的filter中将终止此请求处理链,并在next调用中,传递错误参数。

      connector组件

      connector组件是一个重量级的组件,它会依赖于session组件,server组件,pushScheduler组件和connection组件。connector组件仅仅被前端服务器加载,它主要用来管理客户端的连接。connector组件会加载底层的connector,创建端口监听,绑定事件响应。当有客户端连接请求时,connector组件会请求session组件,获得当前连接的session,如果session组件中没有相应的session的话,session组件会为这个新连接创建新的session,并维护相应的连接;然后connector组件还会向connection组件上报连接信息,供统计使用;最后,将拿到的session以及客户端的请求,一起抛给server组件,由server组件进行请求处理。当server组件处理完请求后,又会通过connector组件将响应返回给客户端。在返回响应给客户端的时候,connector组件做了一个缓存选择,这个缓存实现依赖于pushScheduler组件,也就是说connector组件并不是直接将响应发给客户端,而是将响应给pushScheduler组件。pushScheduler组件根据相应调度策略,可能不缓存直接通过session组件维护的连接,将响应发出去,也可能进行缓存,并按时flush。这是可以配置的。

      connector组件支持如下配置项:

        • connector: 底层使用的通信connector,不配置的话,会默认使用sioconnector;
        • useProtobuf: 目前仅仅支持connector配置使用hybridconnector的情况,配置其为true,将开启消息的protobuf功能;
        • useDict: 目前仅仅支持connector配置使用hybridconnector的情况,配置其为true时,将会开启基于字典的路由消息压缩;
        • useCrypto: 目前仅仅支持connector配置为hybridconnector的情况,配置其为true时,将会启用通信时的数字签名;
        • encode/decode: 消息的编码解码方式,如果不配置的话,将会默认使用connector配置中,底层connector提供的相应的编码解码函数。
        • transports:这个配置选项是用于sioconnector的,因为socket.io的通信方式可能会有多种,如websocket,xhr-polling等等。通过这个配置选项可以选择需要的方式。

        配置connector组件,通过调用如下方式进行:

        app.set('connectorConfig', opts);

        image.gif

        session组件

        session组件跟connector相关,也是仅仅被前端服务器加载,为sessionService提供一个组件包装, 加载session组件后,会在app的上下文中增加sessionService,可以通过app.get('sessionService')获取。它主要用来维护客户端的连接信息,以及生成session并维护session。如果与经典TCP进行类比的话,那么session中维护的连接就可以粗略地认为就是TCP服务器端accept返回的socket句柄。一个连接与一个session对应,同时session组件还维护具体登录用户与session的绑定信息。一个用户可以有多个客户端登录,对应于多个session。当需要给客户端推送消息或者给客户端返回响应的话,必须通过session组件拿到具体的客户端连接来进行。

        session组件支持如下配置项:

          • singleSession: 如果这个配置项配置为true的话,那么将将不允许一个用户同时绑定到多个session,在绑定用户一次后,后面的绑定将会失败。

          配置session组件,通过调用如下方式进行:

          app.set('sessionConfig', opts);

          image.gif

          connection组件

          connection组件是一个功能相对简单的组件,也是仅仅被前端服务器加载,为connectionService提供一个组件包装,他主要进行连接信息的统计,connector组件接收到客户端连接请求以及有客户端离线时,以及用户登录下线等等情况,都会向其汇报。

          connection组件无配置项。

          server组件

          server组件也是一个功能比较复杂的组件,它被除master外的服务器加载。server组件会加载并维护自身的Filter信息和Handler信息。server组件会从connector组件的回调里获得到相应的客户端请求或者通知,然后会使用自己的before filters对其消息进行过滤,再次调用自己的相应Handler进行请求的逻辑处理,然后将响应通过回调的方式发给connector处理。最后调用after filters进行一些清理处理。

          当然,如果客户请求的服务本来就是前端服务器提供的话,会是上面的那种处理流程。如果客户请求的服务是后端服务器提供的服务的话,则将不是上面的那种处理流程,此时会出现sys rpc调用。前面那种前端服务器自己处理的情况具体调用为doHandle,而发起rpc调用的情况则为doForward。这两种处理流程的不同点是,对于自身的请求,调用自己的filter-handler链进行处理,对于不是前端服务器自己提供的服务,则是发起一个sys rpc,然后将rpc调用的结果作为响应,发给connector进行处理。关于这个rpc调用则是pomelo内建的msgRemote实现的。

          对于后端服务器来说,其客户请求不是直接来源于真实的客户端,而是来源于前端服务器对其发起的sys rpc调用,这个rpc调用的实现就是pomelo内建的msgRemote,在msgRemote的实现里,会将来自前端服务器的sys rpc调用请求派发给后端服务器的server组件,然后后端服务器会启用filter-handler链对其进行处理,最后通过rpc调用的返回将具体的响应返回给前端服务器。

          在前端服务器将客户端请求向后端服务器分派时,由于同类型的后端服务器往往有很多,因此需要一个路由策略router,一般情况下用户通过Application.route调用为后端服务器配置router。

          server组件无配置项。

          pushScheduler组件

          pushScheduler组件也是一个功能较为简单的组件,它仅仅被前端服务器加载,与connector组件的关系密切。当connector组件收到server组件的对客户端请求的响应后,connector并不直接将此响应返回给客户端,而是将这个给客户端发送响应的操作调度给scheduler组件。pushScheduler组件完成最后通过session组件拿到具体的客户端连接并将请求的响应发送给客户端的任务。因此,通过pushScheduler组件可以对发给用户的响应进行缓冲,从而提高通信效率。pomelo实现了两种调度策略,一种是不进行任何缓冲,直接将响应发送给客户端,一种是进行缓冲,并定时地将已缓冲的响应发送给对应的客户端。

          pushScheduler配置项:

            • scheduler: scheduler组件的具体调度策略配置,默认的是直接将响应发给客户端,同时pomelo还提供了有缓冲并且定时刷新的调度策略。用户也可以自定义自己的调度策略。

            配置pushScheduler组件,通过调用如下:

            app.set('pushSchedulerConfig', opts);

            image.gif

            如果要启用使用缓冲的scheduler的话,可以在app.js中增加:

            app.set('pushSchedulerConfig', {scheduler: pomelo.pushSchedulers.buffer, flushInterval: 20});

            image.gif

            flushInterval是刷新周期,默认为20毫秒。

            proxy组件

            proxy组件是一个重量级的组件,它被除master外的所有服务器加载。proxy组件会扫描具体应用服务器的目录,抽取其中的remote部分,由于javascript语言的动态性,可以很轻易地获得到remote中的关于远程调用的元信息,生成stub,并将这些调用都挂到app.rpc下面,当用户发起rpc调用时,proxy组件会查看其扫描到的stub信息,以此决定此远程调用是否合法。同时,proxy又会创建一个RpcClient,当发起远程调用时,负责与远端的remote进行通信,并得到远程调用的结果供调用者使用。当进行远程调用时,由于同类型的远程服务器可能有多个,所以这里同样需要配置相应的router。

            proxy的配置项:

              • cacheMsg, 配置cacheMsg为true的话,将开启rpc调用时的对消息的缓冲,而不是直接一旦有rpc请求就发出。
              • interval, 与配置参数cacheMsg配合使用,设置flush缓存的周期
              • mailBoxFactory, rpc底层实现需要的,用户可以定义自己的mailBoxFactory,我们将在rpc原理里面详述。

              另外,可以开启rpc的调用日志,通过如下的调用:

              app.enable('rpcDebugLog');

              image.gif

              配置proxy使用:

              app.set('proxyConfig', opts);

              image.gif

              remote组件

              remote组件是与proxy组件对等的组件,它用来提供rpc调用服务。rpc组件完成对当前服务器的remote的加载,并开启监听端口,等待rpc客户端的连接及相应的rpc调用。当接收到具体的调用请求时,会根据调用请求中描述的调用请求信息,调用相应的remote中的相应方法。然后再将具体的处理结果返回给rpc客户端。rpc服务端还支持对调用请求的filter,也就是说跟server组件处理客户端请求一样,rpc服务端处理具体请求时也会使用filter-remote链进行处理。

              remote组件配置项:

                • cacheMsg, 与proxy组件的含义相同
                • interval, 与proxy组件的含义相同
                • acceptorFactory, rpc底层实现需要的,可以认为跟proxy配置中的mailBoxFactory是对等的,我们将在rpc原理里面详述。

                跟proxy组件一样,用户可以开启rpcDebugLog来得到所有的rpc调用过程的日志。 配置remote组件使用:

                app.set('remoteConfig', opts);

                image.gif

                dictionary组件

                dictionary组件是一个可选组件,不会被默认加载,只有当connector组件的配置中开启了useDict的时候,此组件才会被加载。此组件会遍历所有handler的route字符串,还会从config/dictionary.json中读取客户端的route字符串,然后对这些字符串进行编码,给予每一个路由赋予一个唯一的小整数,实现route信息压缩,当客户端与前端服务器通信时需要路由信息时,将不会再使用很长的那个字符串,而仅仅使用一个小整数。

                dictionary的配置项:

                  • dict, 客户端路由字符串文件的位置,默认使用的是config/dictionary.json 配置dictionary组件使用:
                    app.set('dictionaryConfig', opts);

                  protobuf组件

                  protobuf组件也是一个可选组件,不会被默认加载,只有当connector组件的配置中开启了useProtobuf的时候,此组件才会被加载。此组件会加载对应的proto文件,并完成消息的基于protobuf的编解码。默认的proto文件的配置信息在config/serverProtos.json和config/clientProtos.json中。具体会在详细介绍pomelo-protobuf中详细介绍。

                  protobuf组件无配置项。

                  channel组件

                  channel组件维护channel信息,可以被除了master之外的服务器加载。channel组件可以看作是channelService的组件包装,加载该组件后,会在app上下文中加入channelService,可以通过app.get('channelService')获取。可以认为一个channel就是一个用户的集合,每一个用户大致对应于前端服务器中的一个session,用户可以通过channel组件向一个channel里面的所有用户推送消息。当然,由于后端服务器并不与客户端直接相连,故后端服务器会发起一个sys rpc来表示向客户端推送消息,接受这个远程调用的是pomelo已经实现的ChannelRemote。

                  channel组件的配置项:

                    • broadcastFilter, broadcast的过滤函数。会在执行channel的broadcast的时候,在前端服务器上,在消息发送给每个session之前,进行一个过滤。其函数签名为
                      broadcastFilter(session, msg, filterParam)

                    其中filterParam参数由在channelService的broadcast调用时传入,如下:

                    channelService.broadcast(type, route, {filterParam: param}, cb);

                    image.gif

                    可以通过如下方式对Channel组件进行配置:

                    app.set('channelConfig', opts)

                    image.gif

                    backendSession组件

                    BackendSession组件可以看作是BackendSessionService的组件包装,加载该组件后,会在app的上下文中加入backendSessionService,可以通过app.get('backendSessionService')调用获取。可以被除了master之外的服务器加载。它主要为后端服务器提供BackendSession信息,并通过远程过程调用完成一些比如对原始session绑定uid等操作。

                    backendSession组件无配置项。

                    相关实践学习
                    日志服务之使用Nginx模式采集日志
                    本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
                    相关文章
                    |
                    15天前
                    |
                    域名解析 弹性计算 负载均衡
                    新手上云教程参考:阿里云服务器租用、域名注册、备案及域名解析流程图文教程
                    对于想要在阿里云上搭建网站或应用的用户来说,购买阿里云服务器和注册域名,绑定以及备案的流程至关重要。本文将以图文形式为您介绍阿里云服务器购买、域名注册、备案及绑定的全流程,以供参考,帮助用户轻松上手。
                    |
                    1月前
                    |
                    弹性计算 JavaScript 前端开发
                    一键安装!阿里云新功能部署Nodejs环境到ECS竟然如此简单!
                    Node.js 是一种高效的 JavaScript 运行环境,基于 Chrome V8 引擎,支持在服务器端运行 JavaScript 代码。本文介绍如何在阿里云上一键部署 Node.js 环境,无需繁琐配置,轻松上手。前提条件包括 ECS 实例运行中且操作系统为 CentOS、Ubuntu 等。功能特点为一键安装和稳定性好,支持常用 LTS 版本。安装步骤简单:登录阿里云控制台,选择扩展程序管理页面,安装 Node.js 扩展,选择实例和版本,等待创建完成并验证安装成功。通过阿里云的公共扩展,初学者和经验丰富的开发者都能快速进入开发状态,开启高效开发之旅。
                    |
                    1月前
                    |
                    弹性计算 JavaScript 前端开发
                    一键安装!阿里云新功能部署Nodejs环境到ECS竟然如此简单!
                    一键安装!阿里云新功能部署Nodejs环境到ECS竟然如此简单!
                    一键安装!阿里云新功能部署Nodejs环境到ECS竟然如此简单!
                    |
                    1月前
                    |
                    存储 弹性计算 安全
                    阿里云服务器购买后设置密码、安全组、基础安全服务、挂载云盘等流程简介
                    对于初次选购阿里云服务器的用户来说,通过阿里云推出的各类活动买到心仪的云服务器仅仅是第一步。为了确保云服务器能够正常运行并承载您的应用,购买之后还需要给云服务器设置远程登录密码、设置安全组规则、设置基础安全、购买并挂载云盘等操作之后,我们才能使用并部署自己的应用到云服务器上。本文将详细介绍在阿里云的活动中购买云服务器后,您必须完成的几个关键步骤,助您快速上手并充分利用云服务器的强大功能。
                    |
                    2月前
                    |
                    监控 前端开发 应用服务中间件
                    小游戏源码开发搭建技术栈和服务器配置流程
                    近些年不同场景游戏层出不穷,现就小游戏开发技术应用及功能详细剖析!
                    |
                    2月前
                    |
                    弹性计算 运维 Ubuntu
                    使用阿里云服务器自动搭建WordPress网站流程,超简单by系统运维管理OOS
                    本教程介绍如何使用阿里云服务器(ECS)和系统运维管理OOS自动搭建WordPress网站,支持Ubuntu、CentOS及Alibaba Cloud Linux等操作系统。前提条件包括ECS实例处于运行中、有公网IP且安全组已开启80端口。安装步骤简单:进入ECS快速购买控制台选择预装WordPress,确认下单后通过管理控制台查看实例详情并开放安全组端口。最后,通过实例公网IP访问,出现WordPress登录页即表示安装成功。
                    |
                    2月前
                    |
                    弹性计算 Linux 数据安全/隐私保护
                    阿里云服务器最新购买流程与试用流程参考,购买与试用图文教程和注意事项
                    如何购买和试用阿里云服务器,教程参考来了。阿里云服务器分为免费版和收费版,新用户可免费领取一台云服务器作为试用,轻量应用服务器2核2G目前38元1年,云服务器ECS2核2G3M的价格为99元1年,2核4G5M配置199元1年,下面小编来介绍一下2025年我们购买和试用阿里云服务器的详细流程,以图文形式展示给大家,适合新手用户参考。
                    阿里云服务器最新购买流程与试用流程参考,购买与试用图文教程和注意事项
                    |
                    3月前
                    |
                    域名解析 弹性计算 安全
                    阿里云服务器租用、注册域名、备案及域名解析完整流程参考(图文教程)
                    对于很多初次建站的用户来说,选购云服务器和注册应及备案和域名解析步骤必须了解的,目前轻量云服务器2核2G68元一年,2核4G4M服务器298元一年,域名注册方面,阿里云推出域名1元购买活动,新用户注册com和cn域名2年首年仅需0元,xyz和top等域名首年仅需1元。对于建站的用户来说,购买完云服务器并注册好域名之后,下一步还需要操作备案和域名绑定。本文为大家展示阿里云服务器的购买流程,域名注册、绑定以及备案的完整流程,全文以图文教程形式为大家展示具体细节及注意事项,以供新手用户参考。
                    |
                    3月前
                    |
                    存储 Oracle 安全
                    服务器数据恢复—LINUX系统删除/格式化的数据恢复流程
                    Linux操作系统是世界上流行的操作系统之一,被广泛用于服务器、个人电脑、移动设备和嵌入式系统。Linux系统下数据被误删除或者误格式化的问题非常普遍。下面北亚企安数据恢复工程师简单聊一下基于linux的文件系统(EXT2/EXT3/EXT4/Reiserfs/Xfs) 下删除或者格式化的数据恢复流程和可行性。
                    |
                    3月前
                    |
                    SQL 弹性计算 安全
                    阿里云服务器产品详情介绍:云服务器是什么、应用场景、租用流程、使用教程参考
                    对于很多新手用户来说,阿里云服务器是什么、阿里云服务器可以干嘛、阿里云服务器租用价格表、阿里云服务器新手教程是很多用户对于阿里云服务器最为关心的问题。同时,面对琳琅满目的服务器配置和优惠活动,如何选择最适合自己的服务器并充分利用其资源,成为许多用户面临的难题。本文将从阿里云服务器的定义、应用场景、价格、租用流程以及使用技巧等方面进行全面解析,帮助用户更好地了解和应用阿里云服务器。
                    212 14