[eggjs/egg]关于eggjs正式启动后,多worker下单例如何实现的问题

2024-08-05 776 views
6

在eggjs框架中,当服务正式上线后采用npm run start运行,会依靠服务器cpu参数建立多个worker ,在app.js中挂在grpc的服务端,由于多个worker加载,grpc会出现端口被占用的情况,请问有没有类似在多个worker下面实现单例的方法,保证grpc服务端建立后,其他worker里面的不会创建???

我尝试监听端口,判断bind的值,但是效果不是很明显

回答

5

你可以使用 Agent 进程来启动 grpc 服务

3

你可以 监听 egg-ready 事件的

// agent.js
module.exports = agent => {
  // 等待 App Worker 启动成功后才能发送
  agent.messenger.on('egg-ready', () => {
    ...start you grpc server
  });
};
4

@jjeejj 如果在agent中监听,egg-ready事件,我无法拿到app对象,因为bind是需要app对象中的方法,甚至是一些插件~ 有单例的方法吗?

1

@mmdapl 你如果只想启动一个 worker 的话,可以在启动的时候指定 --workers=1

具体可以看看这个文档: https://eggjs.org/zh-cn/core/deployment.html

还有就是 目前应该没有指定 某个 worker 单独做某件事情,现在的多 worker 是为了充分利用多核 CPU,对外提供的功能是一样的。

目前有的解决方案:

  1. grpc 服务在 Agent 进程中启动,然后利用 IPC 通讯

  2. 启动的时候只启动一个 worker

  3. 把 grpc 服务单独分离出来

0

@jjeejj ,文档有了解过单个worker配置,在正式环境下启动一个worker肯定不利于并发;把grpc分离出来,也是需要提供grpc服务端的,矛盾就是在grpc服务端上.

2

可以问问 @atian25 ,现在的框架是否有这样场景的解决方案?

3

@atian25 @jjeejj 我记得有单例吧,类似Java多线程下,单例模式,我之前考虑用redis之类的,增加一个多worker锁,那样不是很友好

1

@atian25 @jjeejj 目前不考虑集群,单机去部署,多worker下,grpc启动会存在端口冲突,且grpc的bind也需要app对象,agent做好像不太行;

3

一样的,你单机一个进程,然后你集群怎么办?还是要靠前面的负载

6

集群可以不同映射吧 ,但这个单机下,多worker,grpc的启动端口被占,需要考虑到app对象的使用去bind egg框架下的service方法,可以搞个有效方案、思路吗? 不然这正式环境下,都不能友好启动了.

5

只能参考下类似 egg-socket.io 类似的做法。不过都很别扭。

8

我这里的用法都是workers=1,需要多进程时就从Docker上解决。 另外,如果写gRPC服务的话就没必要再用框架了吧,我觉得建个空白文件直接写还更简单清爽些。如果gRPC服务需要和egg通信的话,也是从微服务的角度彻底分开来开发和部署,没必要纠缠不清。 另外弱弱地问一下,彻底单进程版的egg3.0不知道今年能不能出来呢…

9

@mmdapl 所以我随后就说了需要多进程时就用Docker容器去开多个实例。