• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

浅出 eggjs

武飞扬头像
一一1720一一
帮助1

eggjs是什么

为企业级框架和应用而生

1、专注于提供 Web 开发的核心功能和一套灵活可扩展的插件机制

2、Egg 奉行『约定优于配置』:没有约定的团队,沟通成本是非常高的,比如有人会按目录分栈而其他人按目录分功能,开发者认知不一致很容易犯错

特性

多进程管理

我们知道 JavaScript 代码是运行在单线程上的,换句话说一个 Node.js 进程只能运行在一个 CPU 上。那么如果用 Node.js 来做 Web Server,就无法享受到多核运算的好处。作为企业级的解决方案,我们要解决的一个问题就是:

学新通

如何榨干服务器资源,利用上多核 CPU 的并发优势?

  • Worker 进程异常退出以后该如何处理?
  • 多个 Worker 进程之间如何共享资源?
  • 多个 Worker 进程之间如何调度?

agent

  1. Master 启动后先 fork Agent 进程
  2. Agent 初始化成功后,通过 IPC 通道通知 Master
  3. Master 再 fork 多个 App Worker
  4. App Worker 初始化成功,通知 Master
  5. 所有的进程初始化成功后,Master 通知 Agent 和 Worker 应用启动成功

学新通

通信

  • app.messenger.broadcast(action, data):发送给所有的 agent / app 进程(包括自己)

  • app.messenger.sendToApp(action, data): 发送给所有的 app 进程

    • 在 app 上调用该方法会发送给自己和其他的 app 进程
    • 在 agent 上调用该方法会发送给所有的 app 进程
  • app.messenger.sendToAgent(action, data): 发送给 agent 进程

    • 在 app 上调用该方法会发送给 agent 进程
    • 在 agent 上调用该方法会发送给 agent 自己
  • agent.messenger.sendRandom(action, data):

    • app 上没有该方法(现在 Egg 的实现是等同于 sentToAgent)
    • agent 会随机发送消息给一个 app 进程(由 master 来控制发送给谁)
  • app.messenger.sendTo(pid, action, data): 发送给指定进程

  • app.messenger.on(action, data)

// 发消息
// app.js
module.exports = app => {
  // 注意,只有在 egg-ready 事件拿到之后才能发送消息
  app.messenger.once('egg-ready', () => {
    app.messenger.sendToAgent('agent-event', { foo: 'bar' });
    app.messenger.sendToApp('app-event', { foo: 'bar' });
  });
}
 
// 收消息
app.messenger.on(action, data => {
  // process data
});
app.messenger.once(action, data => {
  // process data
});

扩展extend

框架提供了多种扩展点扩展自身的功能:

  • Application
  • Context
  • Request
  • Response
  • Helper

插件开发plugin

{
  "name": "egg-rpc",
  "eggPlugin": {
    "name": "rpc",
    "dependencies": [ "registry" ],
    "optionalDependencies": [ "vip" ],
    "env": [ "local", "test", "unittest", "prod" ]
  }
}
  • {String} name - 插件名(必须配置),具有唯一性,配置依赖关系时会指定依赖插件的 name。
  • {Array} dependencies - 当前插件强依赖的插件列表(如果依赖的插件没找到,应用启动失败)。
  • {Array} optionalDependencies - 当前插件的可选依赖插件列表(如果依赖的插件未开启,只会 warning,不会影响应用启动)。
  • {Array} env - 只有在指定运行环境才能开启,具体有哪些环境可以参考运行环境。此配置是可选的,一般情况下都不需要配置。

定制上层框架framework

{
  "name": "framework-example",
  "version": "1.0.0",
  "dependencies": {
    "egg": "^2.31.0",
    "yadan": "^2.0.0"
  },
  "devDependencies": {
    "egg-bin": "^4.16.4",
    "egg-mock": "^3.26.0"
  },
  "scripts": {
    "dev": "egg-bin dev",
    "test": "egg-bin test"
  },
  "egg": {
    "framework": "yadan"
  }
}

渐进式开发

  1. 最初始的状态
  2. 插件的雏形
  3. 抽成独立插件
  4. 沉淀到框架

说明:

  • 一般来说,当应用中有可能会复用到的代码时,直接放到 lib/plugin 目录去,如例子中的 egg-ua
  • 当该插件功能稳定后,即可独立出来作为一个 node module 。
  • 如此以往,应用中相对复用性较强的代码都会逐渐独立为单独的插件。
  • 当你的应用逐渐进化到针对某类业务场景的解决方案时,将其抽象为独立的 framework 进行发布。
  • 当在新项目中抽象出的插件,下沉集成到框架后,其他项目只需要简单的重新 npm install 下就可以使用上,对整个团队的效率有极大的提升。

eggjs 启动流程

框架启动在多进程模型Loader插件中或多或少都提过,这里系统的梳理下启动顺序。

  • startCluster 启动传入 baseDir 和 framework,Master 进程启动
  • Master 先 fork Agent Worker
    • 根据 framework 找到框架目录,实例化该框架的 Agent 类
    • Agent 找到定义的 AgentWorkerLoader,开始进行加载
    • AgentWorkerLoader,开始进行加载 整个加载过程是同步的,按 plugin > config > extend > agent.js > 其他文件顺序加载
    • agent.js 可自定义初始化,支持异步启动,如果定义了 beforeStart 会等待执行完成之后通知 Master 启动完成。
  • Master 得到 Agent Worker 启动成功的消息,使用 cluster fork App Worker
    • App Worker 有多个进程,所以这几个进程是并行启动的,但执行逻辑是一致的
    • 单个 App Worker 和 Agent 类似,通过 framework 找到框架目录,实例化该框架的 Application 类
    • Application 找到 AppWorkerLoader,开始进行加载,顺序也是类似的,会异步等待,完成后通知 Master 启动完成
  • Master 等待多个 App Worker 的成功消息后启动完成,能对外提供服务。

初始化项目

hello word

npm init egg --type=simple

eggjs的部署

github.com/eggjs/egg-s…

写在最后

eggjs 框架是一个适合 nodejs 企业级生产环境中使用,可以应对大多数业务场景

eggjs源码:github.com/eggjs/egg

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgaigbi
系列文章
更多 icon
同类精品
更多 icon
继续加载