`
baiguomeng
  • 浏览: 957808 次
文章分类
社区版块
存档分类
最新评论

Apache中预创建Preforking MPM 机制剖析(2)

 
阅读更多
6.3.3.4空闲子进程维护
6.3.3.4.1概述
主服务进程一方面除了必须维护平稳启动之外,另外一个最重要的职责就是对空闲子进程的数目进行管理,整个空闲管理功能在perform_idle_server_maintenance()中描述。
空闲进程的整个内部是示意图可以用下面的图进行描述。
6.3.3.4.2代码分析
static void perform_idle_server_maintenance(apr_pool_t *p)
{
int i;
int to_kill;
int idle_count;
worker_score *ws;
int free_length;
int free_slots[MAX_SPAWN_RATE];
int last_non_dead;
int total_non_dead;
/* initialize the free_list */
free_length = 0;
to_kill = -1;
idle_count = 0;
last_non_dead = -1;
total_non_dead = 0;
在分析具体的空闲子进程维护过程之前,函数中的几个重要的变量需要解释一下:
ap_daemons_limit,该值描述了当前Apache中允许存在的子进程的最多数目,或者是空闲进程、非空闲进程数目以及公告板中空闲的插槽数目的总和、或者是公告板中插槽的总和。
ap_daemons_max_free,该值描述了当前系统中允许存在的空闲子进程的最大数目。如果空闲子进程数目过多,那么在每一次循环中都会有一个空闲进程被杀死。
ap_daemons_min_free该值描述了系统中至少必须存在的空闲子进程的数目。如果当前的空闲子进程数目过低,那么主服务进程将创建新的子进程。如果当前公告板中没有可用插槽(因为ap_daemons_limit已经达到),此时将产生一个警告。
如果在短时间内系统中创建了太多的子进程,一些操作系统可能会性能降低。因此主服务进程并不是立即调用make_child()创建所需的所有子进程。相反,它采用递增创建的策略:在第一次循环中创建一个子进程;在第二次循环中创建二个子进程,第三次创建四个,第N次创建2N个。下一个循环中需要创建的子进程数目用变量idle_spawn_rate进行记录,每次循环中都会对该变量进行递增直到其达到极限值。
举例说明:如果给定的ap_daemons_min_free的值为5,但是系统中的空闲进程数目仅为1。因此主服务进程此时创建一个新的进程,同时进行等待。当然两个进程是不够的,因此主进程在第二次循环中创建2个进程同时继续等待。如果此时一个新的客户端连接发生,那么一个空闲进程将转换忙碌进程。因此主服务进程统计的空闲进程数目为3,同时创建四个空闲进程。当超时的时候,主服务进程统计出7个空闲子进程同时重新设置idle_spawn_rate为1。
ap_max_daemons_limit Necessary to deal with MaxClients changes across AP_SIG_GRACEFUL restarts.尽管Apache内部允许生成的最大进程数为ap_daemons_limit,但是实际上每次产生的进程数目不一定会有这么多。每一个进程都对应记分板中的一个插槽。为了了解各个进程的状态,MPM必须逐一循环遍历记分板中的每一个插槽,这样共计ap_daemons_limit次。显然一些无效的插槽也进行了遍历,这部分本来可以避免的。为此,MPM中使用ap_max_daemons_limit记录记分板中曾经使用的最大的插槽号,一旦记录下来,遍历不再是从0到ap_daemons_limit,而是从0到ap_max_daemons_limit,可以省去ap_daemons_limit - ap_max_daemons_limit-1次的循环。这是一种优化策略。
last_non_dead与ap_max_daemons_limit的含义非常的相近。
idle_count:当前服务器中的空闲进程的数目。
totaol_non_dead:当前服务器中的活动进程的数目,包括空闲进程和非空闲进程。
last_non_dead:
idle_spawn_rate:这是另外一个重要的变量。当MPM模块发现空闲子进程数目current_num少于ap_min_daemons_limit的时候,它将会产生足够的进程ap_min_daemons_limit-current_num个。一般的操作系统允许一次性的产生所需要的进程。不过一些操作系统则不然,如果一次性在很短的时间内产生大量的系统进程,操作系统性能会明显的降低,从而导致服务器响应变慢。这种情况要尽量避免。因此Apache并没有采用这种“激进”的创建措施,而是采取了折衷的温和的逐步递增创建策略:在第一次循环中创建一个,第二次循环中创建二个,第三次循环中创建四个,第N次循环中创建2N个,直到1+2+4+…+2N值达到所需要的进程数。idle_spawn_rate指示下一个循环中必须创建的进程数目,记住不是本次循环中
两个变量就是free_length和free_slots,这两个变量我们在稍后描述。
只有对这些变量的含义有了清晰的认识之后我们才能进行分析。
for (i = 0; i < ap_daemons_limit; ++i) {
int status;
if (i >= ap_max_daemons_limit && free_length == idle_spawn_rate)
break;u
ws = &ap_scoreboard_image->servers[i][0];
status = ws->status;
if (status == SERVER_DEAD) {
if (free_length < idle_spawn_rate) {
free_slots[free_length] = i;
++free_length;
}
}
else {
if (status <= SERVER_READY) {
++ idle_count;
to_kill = i;
}
++total_non_dead;
last_non_dead = i;
}
}
Apache所作的第一件事情就是要统计当前运行的各类进程的信息,包括空闲进程,终止进程以及忙碌进程的数目。为此它必须能够逐一访问记分板中的每一个插槽并读取相应的进程信息,其中我们最关心的就是进程的状态信息:
如果插槽的状态SERVER_DEAD,则意味着对应的进程已经终止,该插槽可以被再次利用;所有可以被再次利用的插槽统一的保存在free_slot数组中。数组中仅仅保存插槽的索引号。其能保存的最多数目为32个,但是通常情况下不是所有的元素都会被使用,因此配合free_slots数组,free_length用于记录当前的最高可用的元素的索引。因此free_slots的操作更像是一个堆栈,每次的元素总是压入最顶部。

比如上图的free_slots就反映了当前记分板中插槽索引为2,3,7,13,14的进程已经终止。
如果插槽的状态为SERVER_STARTING或者是SERVER_READY,则意味着当前的进程处于空闲状态;在遍历过程中,一旦发现空闲进程,idle_count的值将递增1,因此当上面的整个循环结束的时候,idle_count则就是实际的空闲进程数。
另外在Linux中,进程编号如果较低的话,在调度的时候其被命中的概率也就越高,因此如果需要终止某些进程的话,Apache会倾向于终止那些编号较高的进程,为此模块中使用to_kill变量跟踪当前的最高进程编号,这样下次终止进程直接终止to_kill指定的即可。
如果进程状态既不是SERVER_DEAD,也不是SERVER_READY,则意味着该线程正在处理客户端的请求。对于这些进程直接累计total_non_dead变量并设置last_non_dead。
不过如前所叙,经过优化后,MPM不需要遍历所有的记分板插槽了,只需要遍历ap_max_daemons_limit即可。
free_length == idle_spawn_rate意味着
ap_max_daemons_limit = last_non_dead + 1;
if (idle_count > ap_daemons_max_free) {
ap_mpm_pod_signal(pod);
idle_spawn_rate = 1;
}
一旦获取了系统中空闲进程的数目,模块则开始对进程进行调整:
ap_daemons_max_free是Apache中允许的空闲进程的最大值,如果当前的空闲进程数目idle_count超过该值,那么多余的空闲进程必须退出。一般情况下,父进程可以强制子进程立即退出,但是如果某些进程正在处理客户端的请求,那么该连接将会被粗鲁的终止,造成数据丢失,为此Apache使用“终止管道(Pipe of Death)”通知空闲子进程退出,这样需要退出的子进程可以执行平稳的退出,以防止连接数据丢失。ap_mpm_pod_signal函数用于在终止管道中写入终止数据。不过需要注意的是,每次循环只能退出一个子进程,因此如果需要终止的线程有N个,那么至少需要循环N次才能全部退出。这种策略称之为“缓慢退出”,有利于防止进程“创建/终止”摆动。
else if (idle_count < ap_daemons_min_free) {
if (free_length == 0) {
static int reported = 0;
if (!reported) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
"server reached MaxClients setting, consider"
" raising the MaxClients setting"); u
reported = 1;
}
idle_spawn_rate = 1;
}
else {
if (idle_spawn_rate >= 8) {
ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
"server seems busy, (you may need "
"to increase StartServers, or Min/MaxSpareServers), "
"spawning %d children, there are %d idle, and "
"%d total children", idle_spawn_rate,
idle_count, total_non_dead); v
}
如果当前空闲进程的数目低于允许的最少进程数目,那么此时MPM必须增加空闲进程数目。在前面的部分,我们曾经说过,idle_spawn_rate表示本次循环中需要产生的子进程的数目。如果idle_spawn_rate为8,则意味着本次循环需要产生8个子进程。至此,系统必须连续产生1+2+4+8=15个进程,显然如果出现这种情况则意味着系统实在太忙了。这可能是因为初始启动的服务太低或者允许的空闲进程指标Min/MaxSpareServers太小,因此此时必须增加这些参数的值,并在日志中写入警告。如v所示。
如果free_length=0,意味着当前free_slots中没有可用的插槽,这表明当前系统中的所有的进程都处于活动状态:或者忙碌或者空闲等待请求。这种情况的出现可能是因为MaxClient参数设置过低,因此有必要增加MaxClient的值。
for (i = 0; i < free_length; ++i) {
#ifdef TPF
if (make_child(ap_server_conf, free_slots[i]) == -1) {
if(free_length == 1) {
shutdown_pending = 1;
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, ap_server_conf,
"No active child processes: shutting down");
}
}
#else
make_child(ap_server_conf, free_slots[i]);
#endif /* TPF */
}
尽管原则上第N次可以产生2N的进程,但是实际上真正能够产生的进程数目还得由记分板中的空闲插槽数目free_length决定。生成具体的子进程使用make_child例程,在后面的部分会详细的对其进行分析。
if (hold_off_on_exponential_spawning) {
--hold_off_on_exponential_spawning;
}
else if (idle_spawn_rate < MAX_SPAWN_RATE) {
idle_spawn_rate *= 2;
}
在进程产生后紧接着的任务就是设置下一循环中需要产生的进程数目:idle_spawn_rate*2;当然这个值不能超出允许产生的最大值MAX_SPAWN_RATE。
}
}
else {
idle_spawn_rate = 1;
}
6.3.3.4.3子进程创建
主进程的一个很重要的任务就是在空闲进程不够的情况下创建足够的子进程。子进程的创建在函数make_child中进行。
static int make_child(server_rec *s, int slot)
对于任何一个创建的子进程,其都必须在计分板中占据一个插槽来保存自己的信息,slot就是创建的进程在计分板中的插槽索引,不过有一点需要确保的slot的值不能超过系统中允许的进程极限数,即slot必须满足slot <= ap_max_daemons_limit -1
整个子进程的创建过程可以分割为下面二个步骤:
(1)、更新计分板。一旦进程创建,它的状态将被设置为SERVER_STARTING,表明该进程开始运行。
(2)、调用fork()真正生成子进程。如果生成子进程失败,还得将原先的计分板SERVER_STARTING状态更新为SERVER_DEAD。一旦更新完毕,该插槽将再次变得可用。当fork函数调用失败的时候,为了防止系统不停的尝试去重新fork从而将CPU资源耗尽,因此一旦如果fork失败,那么Apache将等待10毫秒后再去尝试新的fork。
对于子进程而言,一旦其创建完毕,除了正常了父子进程之间的通信,子进程不应该再受到父进程的其余的无端打断,因此子进程必须重新SIGHUP和SIGTERM信号。任何时候子进程接受到SIGHUP和SIGTERM信号之后,除了退出之外,再退出之前还需要完成几个清除工作,包括:
■ 关闭父子进程之间通信的“终止管道”
尽管父进程会发送AP_SIG_GRACEFUL给子进程,但子进程并不对其进行处理:apr_signal(AP_SIG_GRACEFUL, SIG_IGN);一旦子进程处理完所有的准备工作,其将开始进入子进程的内部处理过程child_main()。
另一方面,在生成子进程之后,主进程则必须将子进程号填入记分板的相关插槽中:
ap_scoreboard_image->parent[slot].pid = pid;
如果服务器是单进程运行模式,那么处理的工程要简单的多。由于不涉及到创建子进程,因此实际上主进程本身直接进入内部循环操作。另外与多进程相比,它仅仅处理三种信号:SIGINT、SIGTERM、SIGQUIT。
另外一种子进程生成方式就是批量子进程生成,即函数static void startup_children(int number_to_start)。number_to_start是批量产生的进程的数目。
static void startup_children(int number_to_start)
{
int i;
for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
continue;
}
if (make_child(ap_server_conf, i) < 0) {
break;
}
--number_to_start;
}
}
在计分板中,如果某个进程的状态为SRVER_DEAD,则意味着当前的记分板插槽可用。因此对于需要创建的number_to_start个进程,需要通过逐一遍历计分板从而才可以给创建的进程分配插槽。一旦分配成功,那么函数将调用make_child创建进程。
分享到:
评论

相关推荐

    Starman, Starman是高性能的preforking Perl PSGI web服务器.zip

    Starman, Starman是高性能的preforking Perl PSGI web服务器 电子邮件名称Starman - 高性能 preforking psgi/Plack网络服务器概要# Run app.psgi with the default settings&gt; starman# run w

    Monoceros, psgi/Plack服务器,带有事件驱动的连接管理器,preforking员工.zip

    Monoceros, psgi/Plack服务器,带有事件驱动的连接管理器,preforking员工 电子邮件名称Monoceros - psgi/Plack服务器,带有事件驱动的连接管理器,preforking工作者概要% plackup -s Monoceros --max-keepalive-...

    PSGI的HTTP服务器Starman.zip

    Starman 是一个高性能、preforking 和 PSGI 兼容的 HTTP 服务器,支持 HTTP/1.1、多网络接口支持以及 Unix Domain 套接字支持,可无缝进行重启,支持通过操作系统信号进行动态的worker池配置。 标签:...

    软考-考生常见操作说明-202405101400-纯图版.pdf

    软考官网--2024常见操作说明:包括如何绘制网络图、UML图、表格等 模拟作答系统是计算机技术与软件专业技术资格(水平)考试的电子化考试系统界面、作答过程的仿真系统,为各级别、各资格涉及输入和页面显示的部分题型提供体验性练习。

    setuptools-34.0.3.zip

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    基于遗传优化GA的三目标优化仿真【包括程序,注释,操作步骤】

    1.版本:matlab2022A。 2.包含:程序,中文注释,仿真操作步骤(使用windows media player播放)。 3.领域:遗传优化 4.仿真效果:仿真效果可以参考博客同名文章《基于遗传优化GA的三目标优化仿真》 5.内容:基于遗传优化GA的三目标优化仿真。遗传算法(Genetic Algorithm, GA)是一种模拟自然选择和遗传机制的全局搜索优化方法,广泛应用于解决复杂优化问题,包括具有多个目标的优化问题,即多目标遗传算法(Multi-Objective Genetic Algorithm, MOGA)。在这里,将三个目标函数进行统一的编码,通过单目标遗传优化的方式,同步求解三个目标函数的最优值。 6.注意事项:注意MATLAB左侧当前文件夹路径,必须是程序所在文件夹位置,具体可以参考视频录。

    基于单通道脑电信号的自动睡眠分期研究.zip

    本项目使用了Sleep-EDF公开数据集的SC数据进行实验,一共153条整晚的睡眠记录,使用Fpz-Cz通道,采样频率为100Hz 整套代码写的较为简洁,而且有添加相应的注释,因此进行分享,而且不仅仅说是睡眠分期,也可以作为学习如何使用神经网络去进行时序数据分类问题的一个入门项目,包括怎么用GRU、LSTM和Attention这些经典网络结构。 网络结构(具体可查看network.py文件): 网络整体结构类似于TinySleepNet,对RNN部分进行了修改,增加了双向RNN、GRU、Attention等网络结构,可根据参数进行调整选择。 定义了seq_len参数,可以更灵活地调整batch_size与seq_len。 数据集加载(具体可查看dataset.py文件) 直接继承自torch的Dataset,并定义了seq_len和shuffle_seed,方便调整输入,并复现实验。 训练(具体可查看train.py文件):

    setuptools-27.3.1.tar.gz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    setuptools-12.0-py2.py3-none-any.whl

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    setuptools-11.0.tar.gz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    setuptools-5.8-py2.py3-none-any.whl

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    5.3.1_1二叉树的先中后序遍历.mp420240404-134540.png

    5.3.1_1二叉树的先中后序遍历.mp420240404-134540.png

    setuptools-1.3.1-py2.py3-none-any.whl

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    setuptools-40.1.1-py2.py3-none-any.whl

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    基于JSP在线图书销售商城网站项目源码.zip

    这个是一个JSP在线图书销售商城网站项目,管理员角色包含以下功能:管理员登录,管理员账号管理,会员用户管理,订单管理,图书分类管理,图书管理,新闻管理,评价管理等功能。用户角色包含以下功能:用户首页,最新图书查看,会员登录注册,商城公告新闻查看,查看图书详情,查看评论以及发表评论,查看购物车,查看我的订单等功能。

    基于springboot的就业信息管理系统

    开发语言:Java JDK版本:JDK1.8(或11) 服务器:tomcat 数据库:mysql 5.6/5.7(或8.0) 数据库工具:Navicat 开发软件:idea 依赖管理包:Maven 代码+数据库保证完整可用,可提供远程调试并指导运行服务(额外付费)~ 如果对系统的中的某些部分感到不合适可提供修改服务,比如题目、界面、功能等等... 声明: 1.项目已经调试过,完美运行 2.需要远程帮忙部署项目,需要额外付费 3.本项目有演示视频,如果需要观看,请联系我v:19306446185 4.调试过程中可帮忙安装IDEA,eclipse,MySQL,JDK,Tomcat等软件 重点: 需要其他Java源码联系我,更多源码任你选,你想要的源码我都有! https://img-blog.csdnimg.cn/direct/e73dc0ac8d27434b86d886db5a438c71.jpeg

    setuptools-38.6.0-py2.py3-none-any.whl

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    毕设-基于STM32的物联网农业监测与控制系统源码.zip

    毕设-基于STM32的物联网农业监测与控制系统源码.zip毕设-基于STM32的物联网农业监测与控制系统源码.zip毕设-基于STM32的物联网农业监测与控制系统源码.zip毕设-基于STM32的物联网农业监测与控制系统源码.zip毕设-基于STM32的物联网农业监测与控制系统源码.zip毕设-基于STM32的物联网农业监测与控制系统源码.zip毕设-基于STM32的物联网农业监测与控制系统源码.zip

    基于STM32F4系列单片机,开发了一款手持热成像仪.zip

    基于单片机的系统

    JAVA五子棋手机网络对战游戏的设计与实现(源代码).zip

    JAVA五子棋手机网络对战游戏的设计与实现(源代码)

Global site tag (gtag.js) - Google Analytics