Egg: Azure App service底下無法使用

Created on 6 Jul 2018  ·  19Comments  ·  Source: eggjs/egg

  • Node Version: 8.4
  • Egg Version: 2.9.1
  • Plugin Name:
  • Plugin Version:
  • Platform: windows
  • Mini Showcase Repository:

egg-script不支援 windows,Azure的 App service是Windows base,最省錢的微服務方式

請問還有什麼方式在 windows底下 run eggjs 呢?

egg-scripts

Most helpful comment

const startCluster = require('egg').startCluster;
startCluster({
  baseDir: '/path/to/app',
  framework: '/path/to/framework',
});

参数可以参考 https://github.com/eggjs/egg-cluster/#options

All 19 comments

Translation of this issue:


Azure App service cannot be used under

  • Node Version: 8.4
  • Egg Version: 2.9.1
  • Plugin Name:
  • Plugin Version:
  • Platform: windows
  • Mini Showcase Repository:

Egg-script does not support windows, Azure's App service is Windows base, the most cost-effective micro-service

Is there any way to run eggjs under windows?

自己写个入口文件即可,几行代码。

最近 windows 的问题比较多,部署的地方加个简化版的部署方案?

@atian25 @popomore 有相關的文件可參考嗎?
我是先轉成純 koa2的架構執行

const startCluster = require('egg').startCluster;
startCluster({
  baseDir: '/path/to/app',
  framework: '/path/to/framework',
});

参数可以参考 https://github.com/eggjs/egg-cluster/#options

下周我看看,加下文档或者改下 egg-scripts

egg-scripts 现在不支持 win 主要是 2 个原因:

  • 启动时轮询日志用了 tail -f,不过这个可以随便找个包。
  • win 下没有好用的纯 JS 模块去检索 pid

    • 之前我用 findprocess 这个包

    • wmic 在我本地一台 win10 上报错,似乎是一个 BUG (不过如果你们其他机器没问题,那就可以无视掉)

    • 当时还遇到一个问题就是在 appveyor 上精确判断进程的时候,\\ 的转义把我搞晕了。

image

https://support.microsoft.com/en-us/help/2664203/-invalid-xml-content-error-message-when-you-run-a-wmic-command-in-wind?sd=rss&spid=14019

就目前而言,可以有几种方案:

  1. 把我没解决的问题解决掉(可以无视掉部分 win)
  2. 使用 vscode 等的 native 版的 pid 模块 (就要独立一个工具了,如 egg-scripts-win)
  3. 不解决,在文档上面注明如何自己写启动文件即可。

@atian25 方案3不錯,Azure的App Service只是一個很簡易的Windows系統,不具有完整的Win功能,單純的使用node來啟動是可以的。
只是不知道如何不使用 egg-script,單純使用egg的mvc架構來啟動微服務

其实 egg-scripts 没做啥,你看下源码就知道了,

https://github.com/eggjs/egg-scripts/blob/master/lib/cmd/start.js
https://github.com/eggjs/egg-scripts/blob/master/lib/start-cluster

就是配置下环境变量,处理入参,然后丢给 startCluster 而已。

改用 startCluster 啟動

//index.js
const startCluster = require('egg').startCluster;
startCluster({}, () => {
    console.log('started');
  });
// node index.js
2018-07-07T03:13:24  Welcome, you are now connected to log-streaming service.
2018-07-07 03:13:40,803 INFO 9244 [master] =================== egg start =====================

2018-07-07 03:13:40,819 INFO 9244 [master] node version v8.9.4

2018-07-07 03:13:40,834 INFO 9244 [master] egg version 2.9.1

2018-07-07 03:13:40,834 INFO 9244 [master] start with options:

{
  "framework": "D:\\home\\site\\wwwroot\\node_modules\\egg",
  "baseDir": "D:\\home\\site\\wwwroot",
  "workers": 1,
  "plugins": null,
  "https": false,
  "key": "",
  "cert": ""
}

2018-07-07 03:13:40,850 INFO 9244 [master] start with env: isProduction: true, EGG_SERVER_ENV: undefined, NODE_ENV: production

2018-07-07 03:13:40,899 INFO 9244 [master] agent_worker#1:9332 start with clusterPort:49927

2018-07-07 03:13:46,361 ERROR 9244 nodejs.AgentWorkerDiedError: [master] agent_worker#1:9332 died (code: 1, signal: null)
    at Master.onAgentExit (D:\home\site\wwwroot\node_modules\egg-cluster\lib\master.js:321:17)
    at emitOne (events.js:116:13)
    at Master.emit (events.js:211:7)
    at Messenger.sendToMaster (D:\home\site\wwwroot\node_modules\egg-cluster\lib\utils\messenger.js:122:17)
    at Messenger.send (D:\home\site\wwwroot\node_modules\egg-cluster\lib\utils\messenger.js:87:12)
    at ChildProcess.agentWorker.once (D:\home\site\wwwroot\node_modules\egg-cluster\lib\master.js:220:22)
    at Object.onceWrapper (events.js:317:30)
    at emitTwo (events.js:126:13)
    at ChildProcess.emit (events.js:214:7)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:198:12)
name: 'AgentWorkerDiedError'
pid: 9244
hostname: RD0003FF6EABA8


2018-07-07 03:13:46,391 ERROR 9244 [master] agent_worker#1:9332 start fail, exiting with code:1

2018-07-07 03:13:46,391 ERROR 9244 [master] exit with code:1

看错误日志

@atian25
Log文件夾是空的,但有看到錯誤訊息了

D:\home\site\wwwroot\node_modules\node-homedir\index.js:7
  if (os.userInfo && os.userInfo().homedir) {
                        ^

Error: ENOENT: no such file or directory, uv_os_get_passwd
    at module.exports (D:\home\site\wwwroot\node_modules\node-homedir\index.js:7:25)
    at AgentWorkerLoader.getHomedir (D:\home\site\wwwroot\node_modules\egg-core\lib\loader\egg_loader.js:160:36)
    at AgentWorkerLoader.getAppInfo (D:\home\site\wwwroot\node_modules\egg-core\lib\loader\egg_loader.js:171:23)
    at new EggLoader (D:\home\site\wwwroot\node_modules\egg-core\lib\loader\egg_loader.js:86:25)
    at new AgentWorkerLoader (D:\home\site\wwwroot\node_modules\egg\lib\loader\agent_worker_loader.js:9:1)
    at new EggCore (D:\home\site\wwwroot\node_modules\egg-core\lib\egg.js:120:19)
    at new EggApplication (D:\home\site\wwwroot\node_modules\egg\lib\egg.js:42:5)
    at new Agent (D:\home\site\wwwroot\node_modules\egg\lib\agent.js:22:5)
    at Object.<anonymous> (D:\home\site\wwwroot\node_modules\egg-cluster\lib\agent_worker.js:22:15)
    at Module._compile (module.js:643:30)

看来是因为你的系统阉割版的问题,这个是 Node 自己的 API 来着。

cc @ngot 你那个库,估计要 try catch 兼容下。

解決了!
在 win底下
node-homedir/index.js,直接輸出 os.homedir()

'use strict';

const os = require('os');

module.exports = () => {
  if (process.env.MOCK_HOME_DIR) return process.env.MOCK_HOME_DIR;
  if (os.homedir) {
    return os.homedir();
  }
  return process.env.HOME;
};

服務可以start,不過workers沒有反應,我有寫個 app.js 但沒有任何callback,同樣的code 在mac是正常的

//app.js
module.exports = app => {
    app.beforeStart(async () => {
      // 应用会等待这个函数执行完成才启动
      console.log("beforeStart")
    });
  };
2018-07-07 10:39:36,203 INFO 8564 [master] =================== egg start =====================

2018-07-07 10:39:36,250 INFO 8564 [master] node version v8.9.4

2018-07-07 10:39:36,250 INFO 8564 [master] egg version 2.9.1

2018-07-07 10:39:36,265 INFO 8564 [master] start with options:

{
  "framework": "D:\\home\\site\\wwwroot\\node_modules\\egg",
  "baseDir": "D:\\home\\site\\wwwroot",
  "workers": 1,
  "plugins": null,
  "https": false,
  "key": "",
  "cert": ""
}

2018-07-07 10:39:36,265 INFO 8564 [master] start with env: isProduction: true, EGG_SERVER_ENV: undefined, NODE_ENV: production

2018-07-07 10:39:36,328 INFO 8564 [master] agent_worker#1:8716 start with clusterPort:49376

2018-07-07 10:39:42,613 INFO 8564 [master] agent_worker#1:8716 started (6314ms)

2018-07-07 10:39:42,626 INFO 8564 [master] start appWorker with args ["{\"framework\":\"D:\\\\home\\\\site\\\\wwwroot\\\\node_modules\\\\egg\",\"baseDir\":\"D:\\\\home\\\\site\\\\wwwroot\",\"workers\":1,\"plugins\":null,\"https\":false,\"key\":\"\",\"cert\":\"\",\"clusterPort\":49376}"]

2018-07-07 10:39:42,690 INFO 8564 [master] app_worker#1:9432 start, state: none, current workers: ["1"]

2018-07-07 10:39:50,879 INFO 8564 [master] app_worker#1:9432 started at 7001, remain 0 (8253ms)

2018-07-07 10:39:50,892 INFO 8564 [master] egg started on http://127.0.0.1:7001 (14611ms)

started

You should set EGG_SERVER_ENV=prod

總算解了

step by step

  1. 先在本機run egg-init --type=simple bug-report,創建最小模組

  2. 修改 node_modules 的 node-homedir

// node-homedir/index.js
'use strict';
const os = require('os');
module.exports = () => {
  if (process.env.MOCK_HOME_DIR) return process.env.MOCK_HOME_DIR;
  if (os.homedir) {
    return os.homedir();
  }
  return process.env.HOME;
};
  1. 入口代碼
const startCluster = require('egg').startCluster;
startCluster({}, () => {
    console.log('started');
  });
  1. 啟動指令
set EGG_SERVER_ENV=prod && node index.js

node-homedir 那个可以提个 PR 兼容下,直接改源码是不好的。

Was this page helpful?
0 / 5 - 0 ratings