从 pm2 看 node 多进程管理(一):进程创建
pm2 是 Node 社区中领先的进程管理工具。本文基于 pm2 v4.5.0 的进程进程源码,聚焦于功能层面,守护守护深入探讨其模块结构和进程创建流程。源码源码源码位置查找
pm2 的进程进程核心模块包含 API 类的实例,API 初始化时会设置默认配置、守护守护用户传入配置,源码源码并生成 Client 实例。进程进程pm2 多进程管理支持两种创建入口:脚本文件或 JSON 配置,守护守护依据用户输入自动选择。源码源码
在系统中无 pm2 创建的进程进程守护进程时,使用 cluster 模式执行脚本后,守护守护pm2 将执行如下操作:确定进程创建入口、源码源码创建守护进程、建立与 rpc 服务的连接、启动工作进程和执行应用。
确定进程创建入口时,pm2 会根据脚本文件或 JSON 配置选择启动方式。_startJson 方法作为入口,初始化配置并启动应用进程。
创建守护进程前,pm2 调用 Client.executeRemote('getMonitorData') 方法获取系统存活进程信息。java 并发队列源码若无守护进程,pm2 优先创建守护进程,通过创建 rpc.Client 实例与 rpc.Server 连接,实现与 Daemon 模块交互。在 Daemon 初始化时,pm2 会根据传入参数判断是否直接启动或作为守护进程启动。
pm2 使用 child_process.spawn 启动 Daemon 进程,之后绑定 PubEmitter 和 RepSocket socket,实现与 Client 和 God 模块的通信。一旦 socket 连接成功,pm2 会通知 Client 建立与 RepSocket server 的连接,供后续操作。
建立好 Daemon 进程和 rpc 连接后,pm2 通过 Client.executeRemote('prepare') 方法创建新进程,实现与 God 模块的直接调用。
pm2 支持 cluster 和 fork 模式启动应用进程,具体实现细节不在本文赘述。值得注意的是,pm2 提供了优雅启动功能,允许应用在依赖环境准备完成后才启动,只需在准备就绪后向 pm2 发送 'ready' 消息。
pm2 从头创建进程的一般过程可总结为:确定入口、创建守护进程、汽车美容营销源码建立 rpc 连接、启动应用进程。此流程确保了高效、灵活的进程管理。
django有什么进程(django的工作原理)
今天首席CTO笔记来给各位分享关于django有什么进程的相关内容,其中也会对django的工作原理进行详细介绍,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录一览:1、Django源码阅读(一)项目的生成与启动2、supervisor拉起Django为什么会多出一个进程3、django一个请求对应一个进程4、Django与supervisor管理进程Django源码阅读(一)项目的生成与启动诚实的说,直到目前为止,我并不欣赏django。在我的认知它并不是多么精巧的设计。只是由功能堆积起来的"成熟方案"。但每一样东西的崛起都是时代的选择。无论你多么不喜欢,但它被需要。希望有一天,python能有更多更丰富的chrome内核指标源码成熟方案,且不再被诟病性能和可维护性。(屁话结束)
取其精华去其糟粕,django的优点是方便,我们这次源码阅读的目的是探究其方便的本质。计划上本次源码阅读不会精细到每一处,而是大体以功能为单位进行解读。
django-adminstartprojectHelloWorld即可生成django项目,命令行是exe格式的。
manage.py把参数交给命令行解析。
execute_from_command_line()通过命令行参数,创建一个管理类。然后运行他的execute()。
如果设置了reload,将会在启动前先check_errors。
check_errors()是个闭包,所以上文结尾是(django.setup)()。
直接看最后一句settings.INSTALLED_APPS。从settings中抓取app
注意,这个settings还不是我们项目中的settings.py。而是一个对象,位于django\conf\__init__.py
这是个Settings类的懒加载封装类,直到__getattr__取值时才开始初始化。然后从Settings类的烈火战车指标源码实例中取值。且会讲该值赋值到自己的__dict__上(下次会直接在自己身上找到,因为__getattr__优先级较低)
为了方便debug,我们直接写个run.py。不用命令行的方式。
项目下建个run.py,模拟runserver命令
debug抓一下setting_module
回到setup()中的最后一句apps.populate(settings.INSTALLED_APPS)
开始看apps.populate()
首先看这段
这些App最后都会封装成为AppConfig。且会装载到self.app_configs字典中
随后,分别调用每个appConfig的import_models()和ready()方法。
App的装载部分大体如此
为了方便debug我们改写下最后一句
res的类型是Commanddjango.contrib.staticfiles.management.commands.runserver.Commandobjectat0xEDA0
重点是第二句,让我们跳到run_from_argv()方法,这里对参数进行了若干处理。
用pycharm点这里的handle会进入基类的方法,无法得到正确的走向。实际上子类Commond重写了这个方法。
这里分为两种情况,如果是reload重载时,会直接执行inner_run(),而项目启动需要先执行其他逻辑。
django项目启动时,实际上会启动两次,如果我们在项目入口(manage.py)中设置个print,会发现它会打印两次。
第一次启动时,DJANGO_AUTORELOAD_ENV为None,无法进入启动逻辑。会进入restart_with_reloader()。
在这里会将DJANGO_AUTORELOAD_ENV置为True,随后重启。
第二次时,可以进入启动逻辑了。
这里创建了一个django主线程,将inner_run()传入。
随后本线程通过reloader.run(django_main_thread),创建一个轮询守护进程。
我们接下来看django的主线程inner_run()。
当我们看到wsgi时,django负责的启动逻辑,就此结束了。接下来的工作交由wsgi服务器了
这相当于我们之前在fastapi中说到的,将fastapi的app交由asgi服务器。(asgi也是django提出来的,两者本质同源)
那么这个wsgi是从哪来的?让我们来稍微回溯下
这个settings是一个对象,在之前的操作中已经从settings.py配置文件中获得了自身的属性。所以我们只需要去settings.py配置文件中寻找。
我们来寻找这个get_wsgi_application()。
它会再次调用setup(),重要的是,返回一个WSGIHandler类的实例。
这就是wsgiapp本身。
load_middleware()为构建中间件堆栈,这也是wsgiapp获取setting信息的唯一途径。导入settings.py,生成中间件堆栈。
如果看过我之前那篇fastapi源码的,应该对中间件堆栈不陌生。
app入口→中间件堆栈→路由→路由节点→endpoint
所以,wsgiapp就此构建完毕,服务器传入请求至app入口,即可经过中间件到达路由进行分发。
supervisor拉起Django为什么会多出一个进程
知道是是Django自己reload的原因了,我在supervisor中给Django加了--noreload后,就不会有两个进程了。但这样,Django就不能自动载入修改的文件。
django一个请求对应一个进程uwsgi部署方式下,一个请求会进一个进程,但一个进程同时"接待"的不止一个请求。
Django与supervisor管理进程在Django项目中,我们需要用到一些独立于Django框架外的脚本。这样一些脚本可能需要独立的持续运行,且具有很强的可维护性,这个时候supervisor就可以排上用场了。
直接使用pip进行
使用supervisor很简单,只需要修改一些配置文件,就可以使用了。
运行
即可看到默认配置情况,但是一般情况下,我们都不要去修改默认的配置,而是将默认配置重定向到另外的文件中,不同的进程运用不同的配置文件去对默认文件进行复写即可。
默认配置说明
配置文件都有说明,且很简单,就不做多的描述了,在上面有一些建议修改的目录,若做了修改,则应先创建这些文件,需要注意权限问题,很多错误都是没有权限造成的。
现在,让我们来启动supervisor服务。
查看supervisord是否运行:
上面我们已经把supervisrod运行起来了,现在可以添加我们要管理的进程的配置文件。可以把所有配置项都写到supervisord.conf文件里,但并不推荐这样做,而是通过include的方式把不同的程序(组)写到不同的配置文件里,对,就是默认配置中的最后的那个include。下面来对项目进行简单的配置。
假设我们把项目配置文件放在这个目录中:/etc/supervisor/
则我们需要修改/etc/supervisord.conf中的include为:
测试py文件:
以下为配置文件目录/etc/supervisor/test.conf:
配置完成以后,即可运行:
查看运行状态
打开浏览器,输入.0.0.,输入用户名与密码(如果配置文件中inet_/linux/centos/docker-ce.repo
2)安装docker-ce
yuminstalldocker-ce
3)启动并加入开机启动
systemctlstartdocker.servicesystemctlenabledocker.service
linuxsupervisor作用?
Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。
它是通过fork/exec的方式把这些被管理的进程当作supervisor的子进程来启动,这样只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去即可。也实现当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,可以选择是否自己启动和报警。
supervisor还提供了一个功能,可以为supervisord或者每个子进程,设置一个非root的user,这个user就可以管理它对应的进程。
守护线程的作用?
守护线程以及其作用
通常来说,守护线程经常被用来执行一些后台任务,但是呢,你又希望在程序退出时,或者说JVM退出时,线程能够自动关闭,此时,守护线程是你的首选。
“只要当前JVM实例中尚存任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束是,守护线程随着JVM一同结束工作,Daemon作用是为其他线程提供便利服务,守护线程最典型的应用就是GC(垃圾回收器),他就是一个很称职的守护者。”
2024-11-14 10:54
2024-11-14 10:45
2024-11-14 10:10
2024-11-14 09:18
2024-11-14 08:34