clinic 启动 eggjs 进行代码性能分析

154 阅读1分钟

背景

eggjs 默认是 cluster 模式启动服务,而 clinic 不支持 cluster 模式,找了一下网上的文章尝试解决问题,并未找到直接清晰的结论,最终翻阅源码找到解决方式记录分享以期为后来者节省时间。

先说结论

通过重写一个单进程启动文件进行性能分析代码如下:

const path = require('path')
const egg = require('egg')

const singleProcessApp = async (options = {}) => {
    options.env = options.env || 'local'
    options.baseDir = path.resolve('./')
    const app = await egg.start(options)
    app.listen(7001)
    return app
}

singleProcessApp()

npm clinc script

"clinic":"clinic doctor --on-port 'autocannon -c 100 -d 10 -p 10 localhost:$PORT' -- node singleProcess.js"

对应源码

竟然五年前就存在了,有种知识断层的感觉!

image.png github.com/eggjs/egg/b…

'use strict';

const path = require('path');

module.exports = async (options = {}) => {

  options.baseDir = options.baseDir || process.cwd();
  options.mode = 'single';

  // get agent from options.framework and package.egg.framework
  if (!options.framework) {
    try {
      options.framework = require(path.join(options.baseDir, 'package.json')).egg.framework;
    } catch (_) {
      // ignore
    }
  }
  let Agent;
  let Application;
  if (options.framework) {
    Agent = require(options.framework).Agent;
    Application = require(options.framework).Application;
  } else {
    Application = require('./application');
    Agent = require('./agent');
  }

  const agent = new Agent(Object.assign({}, options));
  await agent.ready();
  const application = new Application(Object.assign({}, options));
  application.agent = agent;
  agent.application = application;
  await application.ready();

  // emit egg-ready message in agent and application
  application.messenger.broadcast('egg-ready');

  return application;
};

对应测试代码

github.com/eggjs/egg/b…

/**
 * start app with single process mode
 *
 * @param {String} baseDir - base dir.
 * @param {Object} [options] - optional
 * @return {App} app - Application object.
 */
exports.singleProcessApp = async (baseDir, options = {}) => {
  if (!baseDir.startsWith('/')) baseDir = path.join(__dirname, 'fixtures', baseDir);
  options.env = options.env || 'unittest';
  options.baseDir = baseDir;
  const app = await egg.start(options);
  app.httpRequest = () => request(app.callback());
  return app;
};