/ Kanro

Kanro:Cluster - 利用多核 CPU

Kanro:Cluster 是 Kanro 1.1.2 版本新加的内容,自带了 Cluster 模式,在配置中开启即可享受运行在集群模式下的 Kanro 应用。开启集群模式之后 Kanro 会利用上所有 CPU 的核心资源,为高并发提供支持。Kanro:Cluster 会自动的创建工作进程,同步各个进程的状态,不需要额外的特异性的更改。

How it work

Kanro:Cluster 基于 Node.js 的 cluster 模块,在 1.1.2 版本中集成进了 Kanro 中,只需要在 kanro.json 配置文件中开启 cluster 模块,即可享受多核 CPU 带来的性能提升。

Kanro 在集群模式下,会创建符合当前 CPU 核心数的工作进程,由多个工作进程分工响应请求。而主进程会负责调度工作进程,并且提供日志打印服务。当有工作进程被终止,手动终止或者被强制杀死,主进程则会立即创建一个新的工作进程来保证集群的健康状态。

由于日志是全部交给主进程打印,所以日志会依然保持可读状态,并不会由于多个进程共享 stdout 导致日志混乱。但是这会导致一定的效率问题,在并发密集阶段,主进程可能会由于忙于打印访问日志,而导致主进程与工作进程之间通信被阻塞,进而导致工作进程被阻塞。

我在这部分尝试了很多优化,例如:异步优化,日志缓存在工作进程/主进程,但是效果都不怎么样,最后想到可能是原因应该是主进程在一直输出 log,不能分配更多的 Tick 给后续的进程通信,导致工作进程也会由次卡住。所以解决方案可能是需要有与 Kanro 独立的一个中间缓存,这样即时 Kanro 主进程由于大量 log 被卡住,工作进程仍然可以像中间缓存里面写 log,然后 Kanro 会以一个普通的负载的速度输出 log。在密集请求时,这个中间缓存可能会堆积很多 log。但是,在低峰的时候,Kanro 则会处理堆积的数据。保持一个平衡即可。但是能够考虑到最坏的情况,可能就是 24 小时,全部属于高峰,这样中间缓存会堆积越来越多,在这种情况下,可以考虑只向文件写日志,或者关闭 HTTP 请求日志。再或者增加 Kanro 实例,做负载均衡。

Quick start

想要在 Kanro 中使用 Cluster 模式十分简单,只需要在 kanro.json 中加入一行设置:

{
    "cluster": true
 }

重新启动 Kanro 应用,看到以下日志:

λ npm start                
> kanro.quickstart@1.0.0 start E:\Development\WorkSpaces\Kanro\Kanro.QuickStart       
> node bin/index.js    
[07/04 23:55:38]  Kanro:App        - [·] Booting... +0ms              
[07/04 23:55:38]  Kanro:App        - [·] Create application context... +0ms 
[07/04 23:55:39]  Kanro:Config     - [·] Unspecified config, searching for configs... +610ms
[07/04 23:55:39]  Kanro:App        - [·] Pre-initialize module manager... +39ms  
[07/04 23:55:39]  Kanro:NPM        - [·] Set NPM registry to 'http://localhost:4873'. +32ms 
[07/04 23:55:39]  Kanro:App        - [·] Install module and fill nodes... +0ms  
[07/04 23:55:39]  Kanro:Router     - [+] Router node '/' added. +3ms         
[07/04 23:55:39]  Kanro:Router     - [+] Router node '/public/**' added. +0ms  
[07/04 23:55:39]  Kanro:Cluster    - [·] Running with cluster mode, forking workers. +1ms 
[07/04 23:55:39]  Kanro:App        - [+] Kanro is ready. +44ms      
[07/04 23:55:40]  Worker:3:HTTP    - [+] Http server listening on '80'. +1.02s   
[07/04 23:55:40]  Worker:6:HTTP    - [+] Http server listening on '80'. +0ms  
[07/04 23:55:40]  Worker:3:App     - [+] Worker(3) is ready. +0ms       
[07/04 23:55:40]  Worker:6:App     - [+] Worker(6) is ready. +0ms   
[07/04 23:55:40]  Worker:5:HTTP    - [+] Http server listening on '80'. +15ms    
[07/04 23:55:40]  Worker:5:App     - [+] Worker(5) is ready. +0ms  
[07/04 23:55:40]  Worker:2:HTTP    - [+] Http server listening on '80'. +3ms    
[07/04 23:55:40]  Worker:4:HTTP    - [+] Http server listening on '80'. +0ms  
[07/04 23:55:40]  Worker:2:App     - [+] Worker(2) is ready. +0ms  
[07/04 23:55:40]  Worker:4:App     - [+] Worker(4) is ready. +0ms  
[07/04 23:55:40]  Worker:7:HTTP    - [+] Http server listening on '80'. +16ms  
[07/04 23:55:40]  Worker:7:App     - [+] Worker(7) is ready. +1ms      
[07/04 23:55:40]  Worker:1:HTTP    - [+] Http server listening on '80'. +4ms  
[07/04 23:55:40]  Worker:1:App     - [+] Worker(1) is ready. +0ms      
[07/04 23:55:40]  Worker:8:HTTP    - [+] Http server listening on '80'. +2ms   
[07/04 23:55:40]  Worker:8:App     - [+] Worker(8) is ready. +0ms    

Kanro:Cluster 模块开始工作,并创建了很多工作进程,工作进程会向主进程汇报状态。主进程会负责工作进程的调度,与健康状态保持。