`
liuzhaomin
  • 浏览: 207686 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Apache中的进程剖析(4)

阅读更多

//转载请注明来源:http://blog.csdn.net/tingya
//版权声明:
//本书是《Apache源代码全景分析》的草稿部分,
//读者可以自由浏览和打印
//未经本文允许,不得以任何形式出现在盈利印刷品中,否则将追究法律责任!!!

6.2.2 Window系统中进程创建
6.2.2.1进程创建概述
Window系统中创建进程毫无疑问,肯定是使用CreateProcess函数,或者是Unicode版本的CreateProcessW,或者是ASCII版本的CreateProcessA。不过与Unix中创建进程不单是调用fork一样,Window中创建进程也不仅是调用CreateProcess这么简单而已。事实上Window中对进程的创建要比Unix中还要复杂的多,一方面是Window操作系统的版本比较多,为了考虑移植性,必须考虑到多个操作系统;另一方面,Window中对。。。。
在大部分的Window相关的程序中我们都会看到下面几个预处理宏,这里有必要解释一下。
_WIN32_WCE
该宏意味着当前的应用程序运行在Window CE平台上;因此宏内部的代码仅仅适用于Window CE平台。
APR_HAS_UNICODE_FS
该宏意味着当前的文件系统支持Unicode。对于Window系统而言,则主要只Window NT以上的版本;
APR_HAS_ANSI_FS
该宏意味着当前的文件系统是ASCII编码,对于Window系统而言,则主要指Window 9X系列,包括Window 95,Window 98以及Window ME。
Window中进程的创建过程可以用下面的伪码描述整体概况:
apr_proc_create
{
if (attr->errchk)
对attr做有效性检查,让错误尽量发生在parent process中,而不是留给child process; ----(1)
fork子进程;
{ /* 在子进程中 */
清理一些不必要的从父进程继承下来的描述符等,为exec提供一个“干净的”环境;------(2)
关闭attr->parent_in、parent_out和parent_err,
并分别重定向attr->child_in、child_out和child_err为STDIN_FILENO、
STDOUT_FILENO和STDERR_FILENO; -----(3)
判断attr->cmdtype,选择执行exec函数; ------(4)
}
/* 在父进程中 */
关闭attr->child_in、child_out和child_err;
}
下面的部分我们将针对每一部分详细展开描述。
6.2.2.2创建过程
new->in = attr->parent_in;
new->out = attr->parent_out;
new->err = attr->parent_err;
if (attr->detached) {
if (apr_os_level >= APR_WIN_NT) {
dwCreationFlags |= DETACHED_PROCESS;
}
}
DETACHED_PROCESS标志是一个与控制台相关的创建标志。默认情况下,如果应用程序创建一个控制台应用程序,那么该进程将继承共享父进程的控制台,并且该子进程的所有的输出信息都将在父进程的控制台中显示,而且交互也只能通过父进程的控制台显示。不过这并不能保证一定会成功。
有的时候并不希望子进程继承父进程的控制台,而是拥有自己的控制台。此时有几种途径可以实现这种效果:
1)、A GUI or console process can use the CreateProcess function with CREATE_NEW_CONSOLE to create a console process with a new console. (By default, a console process inherits its parent's console, and there is no guarantee that input is received by the process for which it was intended.)
2)、A graphical user interface (GUI) or console process that is not currently attached to a console can use the AllocConsole function to create a new console. (GUI processes are not attached to a console when they are created. Console processes are not attached to a console if they are created using CreateProcess with DETACHED_PROCESS.)
不过只有Window NT以上的版本才能支持新的DETACHED_PROCESS标志,而Win9X系列的操作系统则无能为力。
if (progname[0] == '\"') {
progname = apr_pstrndup(pool, progname + 1, strlen(progname) - 2);
}
Window中不允许传入的运行程序名称中包含双引号””,因此如果发现程序名称被””包含,则首先必须将””剔除,才能继续往下操作。
if (attr->cmdtype == APR_PROGRAM || attr->cmdtype == APR_PROGRAM_ENV) {
char *fullpath = NULL;
if ((rv = apr_filepath_merge(&fullpath, attr->currdir, progname,
APR_FILEPATH_NATIVE, pool)) != APR_SUCCESS) {
if (attr->errfn) {
attr->errfn(pool, rv,
apr_pstrcat(pool, "filepath_merge failed.",
" currdir: ", attr->currdir,
" progname: ", progname, NULL));
}
return rv;
}
progname = fullpath;
}
else {
char *fullpath = NULL;
if ((rv = apr_filepath_merge(&fullpath, "", progname,
APR_FILEPATH_NATIVE, pool)) == APR_SUCCESS) {
progname = fullpath;
}
}
在前面的部分我们曾经描述过五种应用程序类型的实际含义。对于一些应用类型,用户只需要指定应用程序的名称,而不需要指定完整的路径名称就可以执行,比如APR_SHELLCMD、APR_SHELLCMD_ENV和APR_PROGRAM_PATH。但是不管哪一种应用程序类型,最终它们的执行都是CreateProcess函数,而该函数需要完整的程序路径作为参数,因此函数内部必须能够根据传入的程序名称和程序类型确定出完整的。不同的程序类型,绝对路径确定的方法可以用下表描述:
程序类型cmd_type
确定绝对路径的方法
APR_PROGRAM
使用启动进程的当前路径作为路径
APR_PROGRAM_ENV
使用启动进程的当前路径作为路径
APR_PROGRAM_PATH
查找环境变量”PATH”指定的路径下是否存在该程序,如果存在,使用该路径作为绝对路径
APR_SHELLCMD
使用”COMSPEC”指定的路径作为绝对路径
APR_SHELLCMD_ENV
使用”COMSPEC”指定的路径作为绝对路径
从上表中可以看出,对于APR_PROGRAM和APR_PROGRAM_ENV类型的程序,它们的绝对路径实际上是执行进程的当前路径currdir和程序名称的组合,即currdir+progname。而对于其余三种类型,暂时只是简单的处理,在后面的部分它们将被继续处理。
if (has_space(progname)) {
argv0 = apr_pstrcat(pool, "\"", progname, "\"", NULL); u
}
else {
argv0 = progname;
}
/* Handle the args, seperate from argv0 */
cmdline = "";
for (i = 1; args && args[i]; ++i) {
if (has_space(args[i])) {
cmdline = apr_pstrcat(pool, cmdline, " \"", args[i], "\"", NULL);
} v
else {
cmdline = apr_pstrcat(pool, cmdline, " ", args[i], NULL);
}
}
对于CreateProcess函数,Window规定如果传入的启动程序名称和参数中包含空格,那么这些名称和参数在传入给CreateProcess函数之前必须用双引号””进行包含,比如c:\program files\sub dir\program name,如果不用””包含,则Window可能会产生歧异,因为解释有多种(黑体部分为可执行程序名称,而细体部分为参数):
c:\program.exe files\sub dir\program name
c:\program files\sub.exe dir\program name
c:\program files\sub dir\program.exe name
c:\program files\sub dir\program name.exe
u中,函数首先判断程序名称中是否包含空格,如果是,则将各部分用””包含起来。同样在v中,对于传入的执行程序需要的参数列表args,应用程序也必须检查各个参数中是否包含空格,比如如果某个参数为”hello world”,那么直接传入,可能会被程序误解为两个不同的参数”hello”和”world”,因此,对于这些包含空格的参数也必须使用””包含起来。这些处理后的参数最终保存在cmdline中。
if (attr->cmdtype == APR_SHELLCMD || attr->cmdtype == APR_SHELLCMD_ENV) {
char *shellcmd = getenv("COMSPEC");
if (!shellcmd) {
if (attr->errfn) {
attr->errfn(pool, APR_EINVAL, "COMSPEC envar is not set");
}
return APR_EINVAL;
}
if (shellcmd[0] == '"') {
progname = apr_pstrndup(pool, shellcmd + 1, strlen(shellcmd) - 2);
}
else {
progname = shellcmd;
if (has_space(shellcmd)) {
shellcmd = apr_pstrcat(pool, "\"", shellcmd, "\"", NULL);
}
}
/* Command.com does not support a quoted command, while cmd.exe demands one.
*/
i = strlen(progname);
if (i >= 11 && strcasecmp(progname + i - 11, "command.com") == 0) {
cmdline = apr_pstrcat(pool, shellcmd, " /C ", argv0, cmdline, NULL);
}
else {
cmdline = apr_pstrcat(pool, shellcmd, " /C \"", argv0, cmdline, "\"", NULL);
}
}
在前面我们描述过,对于APR_SHELLCMD和APR_SHELLCMD_ENV类型的应用程序,它的绝对路径由环境变量COMSPEC指定。如果COMSPEC环境变量不存在,则执行将失败。如果存在,则同样将其中的空格字符串用””包围起来。
shell应用程序的程序名称或者是cmd.exe(Window NT以上版本)或者是command.com(Window 9X系列)command.com程序不支持命令中出现双引号,而cmd.exe则必须用双引号将命令包括起来。
i = strlen(progname);
if (i >= 4 && (strcasecmp(progname + i - 4, ".bat") == 0
|| strcasecmp(progname + i - 4, ".cmd") == 0))
{
char *shellcmd = getenv("COMSPEC");
if (!shellcmd) {
if (attr->errfn) {
attr->errfn(pool, APR_EINVAL, "COMSPEC envar is not set");
}
return APR_EINVAL;
}
if (shellcmd[0] == '"') {
progname = apr_pstrndup(pool, shellcmd + 1, strlen(shellcmd) - 2);
}
else {
progname = shellcmd;
if (has_space(shellcmd)) {
shellcmd = apr_pstrcat(pool, "\"", shellcmd, "\"", NULL);
}
}
i = strlen(progname);
if (i >= 11 && strcasecmp(progname + i - 11, "command.com") == 0) {
cmdline = apr_pstrcat(pool, shellcmd, " /C ", argv0, cmdline, NULL);
}
else {
cmdline = apr_caret_escape_args(pool, cmdline);
if (*argv0 != '"') {
cmdline = apr_pstrcat(pool, shellcmd, " /C \"\"", argv0, "\"", cmdline, "\"", NULL);
}
else {
cmdline = apr_pstrcat(pool, shellcmd, " /C \"", argv0, cmdline, "\"", NULL);
}
}
}
如果应用程序是批处理程序(.bat)或者命令程序(.com),则处理过程是一样的。
为了创建一个新的进程,至少必须具备下面的几个要素:
1、程序所在的所在的绝对路径
2、进程所需要的环境变量
在下面的函数中代码将会因为操作系统编码的不同而导致差异。Window 9X系列的操作系统是基于ASCII编码,而Window NT以上版本则是基于Unicode编码,这由宏APR_HAS_UNICODE_FS和APR_HAS_ANSI_FS区分:
#if APR_HAS_UNICODE_FS
……
#endif
#if APR_HAS_ANSI_FS
……
#endif
我们首先讨论简单的Window 9X操作系统中的细节。
if (!env || attr->cmdtype == APR_PROGRAM_ENV ||
attr->cmdtype == APR_SHELLCMD_ENV) {
pEnvBlock = NULL;
}
Window在调用CreateProcess的时候需要传递一个环境变量块,如果为NULL,则新进程将使用调用进程的环境变量。
An environment block consists of a null-terminated block of null-terminated strings. Each string is in the form:
name=value
Because the equal sign is used as a separator, it must not be used in the name of an environment variable.
An environment block can contain either Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains Unicode characters, be sure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT.
Note that an ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block.
对于APR_PROGRAM_ENV和APR_SHELLCMD_ENV程序类型,它们使用父进程的环境变量。因此传递给CreateProcess的环境变量块pEnvBlock为NULL。
else {
apr_size_t iEnvBlockLen;
i = 0;
iEnvBlockLen = 1;
while (env[i]) {
iEnvBlockLen += strlen(env[i]) + 1;
i++;
}
if (!i)
++iEnvBlockLen;
{
char *pNext;
pEnvBlock = (char *)apr_palloc(pool, iEnvBlockLen);
i = 0;
pNext = pEnvBlock;
while (env[i]) {
strcpy(pNext, env[i]);
pNext = strchr(pNext, '\0') + 1;
i++;
}
if (!i)
*(pNext++) = '\0';
*pNext = '\0';
}
}
由于CreateProcess所需要的环境变量块实际上是一个字符串,而传入的参数env则是字符串数组,因此必须完成转换。转换的过程对于ASCII操作系统而言,无非是执行strcpy进行拷贝而已。转换前后示意如下所示:
new->invoked = cmdline;
{
STARTUPINFOA si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
if (attr->detached) {
si.dwFlags |= STARTF_USESHOWWINDOW; u
si.wShowWindow = SW_HIDE;
}
if ((attr->child_in && attr->child_in->filehand)
|| (attr->child_out && attr->child_out->filehand)
|| (attr->child_err && attr->child_err->filehand))
{
si.dwFlags |= STARTF_USESTDHANDLES;
si.hStdInput = (attr->child_in)
? attr->child_in->filehand v
: INVALID_HANDLE_VALUE;
si.hStdOutput = (attr->child_out)
? attr->child_out->filehand
: INVALID_HANDLE_VALUE;
si.hStdError = (attr->child_err)
? attr->child_err->filehand
: INVALID_HANDLE_VALUE;
}
rv = CreateProcessA(progname, cmdline, /* Command line */
NULL, NULL, /* Proc & thread security attributes */
TRUE,w /* Inherit handles */
dwCreationFlags, /* Creation flags */
pEnvBlock, /* Environment block */
attr->currdir, /* Current directory name */
&si, &pi);
}
if (!rv)
return apr_get_os_error();
new->hproc = pi.hProcess;
new->pid = pi.dwProcessId;
if (attr->child_in) {
apr_file_close(attr->child_in);x
}
if (attr->child_out) {
apr_file_close(attr->child_out);
}
if (attr->child_err) {
apr_file_close(attr->child_err);
}
CloseHandle(pi.hThread);
return APR_SUCCESS;
与Unix下的操作相似,创建子进程的最后一个任务就是创建父进程和子进程之间的通信管道。不过由于Unix和Window中产生进程以及进程执行的机制不同,而导致通信管道的建立也存在差异。
我们回忆一下,在Unix中,起始的时候主进程中连同管道描述符,一共拥有九个描述符,而子进程从父进程fork之后将继承所有九个描述符。由于fork之后,子进程和父进程同时可以执行,因此对于它们来说,可以在各自的代码中进行重定向以及关闭多余的描述符,流程可以用下图描述:

但是对于Window而言,则并没有fork这样的机制。Window中调用CreateProcess创建进程之后,尽管进程也可以运行,但是与Unix相比,父进程并无法在自己的代码中过多的进行控制,如果想控制,只能由子进程本身去完成。在Unix下,管道的建立由父进程和子进程协作创建,而在Window中,更多的则必须由父进程完成。对于Window下的父进程,创建管道包括下面的三个步骤:
1)、默认情况下,子进程将继承父进程中所有的句柄。不过有些句柄对于子进程并不需要,比如parent_XXX,只用于父进程,因此它就没有必要被子进程继承。因此父进程在创建管道的时候就必须指定所有parent_xxx不被子进程继承。不需要继承的描述符在函数apr_create_nt_pipe中由函数apr_file_inherit_unset指定,比如父进程在创建管道child_in-parent_in的时候同时指定parent_in不被子进程进程,代码如下:
if (in) {
stat = apr_create_nt_pipe(&attr->child_in, &attr->parent_in, in,
attr->pool);
if (stat == APR_SUCCESS)
stat = apr_file_inherit_unset(attr->parent_in);
}
因此当子进程创建后,实际的描述符如下图的(b)所示,其内部只有六个描述符。
2)、设置父进程的继承标志。
子进程默认情况下并不会继承父进程中的句柄。为了允许继承,父进程必须设置进程标志。通过两种方法可以设置继承标志,或者在创建句柄的时候设置SECURITY_ATTRIBUTES参数中的bInheritHandle成员为TRUE,或者在使用CreateProcess创建子进程的时候设置函数的bInheritHandles参数为TRUE,如w所示。
3)、子进程中描述符重定向
正如前面所分析的,子进程中不允许直接从控制台接受输入或者进行输出,而必须通过父进程来完成这些。因此子进程的标准输入,标准输出,以及标准错误都必须重定向到child_xxx中。在CreateProcess创建过程中,通过设置STARUUPINFO参数可以实现子进程的重定向。不过子进程重定向必须具备下面的几个条件:
▉ STARTUPINFOA结构中的dwFlags必须设置STARTF_USESTDHANDLES标志位。该标志位的设立允许进程将它的标准输入、标准输出以及标准错误设备用该结构中的指定的输入hStdInput、输出hStdOutput以及错误设备hStdError替换,从而实现重定向。如果该标志位不设定,hStdInput,hStdOutput和hStdError将被忽略。
▉ CreateProcess函数中的fInheritHandles参数必须设置为TRUE。
重定向代码如v所示。
4)、父进程关闭多余的child_xxx描述符。
最终在创建管道的过程中,父进程和子进程中的描述符的变化如下图所示。
上面的描述只是针对Window 9X的ASCII版本的操作系统,对于Unicode版本的操作系统,比如window NT,Window 2003等处理则存在一些差异。ASCII和Unicode版本对进程创建的差异包括在下面两个方面:
1)、环境变量块的差异
2)、进程路径的差异
3)、进程在安全性方面的考虑。
首先我们看第一个差异:环境变量块的差异。
如前所述,使用CreateProcess的过程中可能需要传递环境变量。环境变量块中既允许包含ANSI字符,又允许包含Unicode字符。对于Unicode的操作系统,环境变量块总是Unicode编码的,但是如果要CreateProcess将传递的环境变量当Unicode编码处理,则CreateProcess的dwCreationFlags标志必须包含CREATE_UNICODE_ENVIRONMENT,否则即使环境变量块是Unicode编码,也会被视为ANSI处理。
对于ANSI编码环境变量块,它总是以两个’\0’作为结束符:一个作为最后一个字符串的结束符,另一个作为整个环境变量块的结束符。而由于Unicode是双字节编码,因此Unicode编码的环境变量块则以四个’\0’做为结束标志:两个’\0’作为最后一个字符的结束符,另外两个则作为整个环境变量块的结束符。
ANSI中使用char定义一个字符类似,Unicode版本则用apr_wchar_t定义一个双字节字符,它的原始定义为apr_uint16_tUnicode存在两种编码方式:UTF或者UCSUTF-8通常使用进行网络传输,比如网页的传输,URL的传输,路径的传输。主要的原因就是对于本地编码为Unicode的系统,由于网络传输以字节作为单位,因此如果传输中某个字节为0的话,将会干扰正常传输。这在Window中页不例外,Window中的环境变量块和路径名称都是基于UTF-8编码,因此必须将它们转换为本地的Unicode编码。转换由apr_conv_utf8_to_ucs2函数完成。反之,当使用路径的时候,则必须使用apr_conv_ucs2_to_utf8将本地Unicode编码转换为UTF-8
环境变量块的处理如下所示:
#if APR_HAS_UNICODE_FS
IF_WIN_OS_IS_UNICODE
{
apr_wchar_t *pNext;
pEnvBlock = (char *)apr_palloc(pool, iEnvBlockLen * 2);
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
i = 0;
pNext = (apr_wchar_t*)pEnvBlock;
while (env[i]) {
apr_size_t in = strlen(env[i]) + 1;
if ((rv = apr_conv_utf8_to_ucs2(env[i], &in,
pNext, &iEnvBlockLen))
!= APR_SUCCESS) {
if (attr->errfn) {
……
}
return rv;
}
pNext = wcschr(pNext, L'\0') + 1;
i++;
}
if (!i)
*(pNext++) = L'\0';
*pNext = L'\0';
}
#endif /* APR_HAS_UNICODE_FS */
路径的处理过程与之类似,此处不在赘述。
我们现在来看ANSIUnicode版本在进程安全性方面的差异。Unicode版本的进程创建代码如下所示:
if (attr->user_token) {
si.lpDesktop = L"Winsta0\\Default"; u
if (!ImpersonateLoggedOnUser(attr->user_token)) {
rv = apr_get_os_error();
CloseHandle(attr->user_token); v
attr->user_token = NULL;
return rv;
}
rv = CreateProcessAsUserW(attr->user_token,
wprg, wcmd,
attr->sa, w
NULL,
TRUE,
dwCreationFlags,
pEnvBlock,
wcwd,
&si, &pi);
RevertToSelf();
}
else {
rv = CreateProcessW(wprg, wcmd, /* Executable & Command line */
NULL, NULL, /* Proc & thread security attributes */
TRUE, /* Inherit handles */ x
dwCreationFlags, /* Creation flags */
pEnvBlock, /* Environment block */
wcwd, /* Current directory name */
&si, &pi);
}
如果指定了模拟用户,即user_token不为NULL,那么进程将进行用户模拟。模拟又分两种,进程内使用线程模拟和创建新进程模拟。这两种模拟方法在Apache中都有使用。只不过在该函数中是创建新进程,因此函数使用后一种方法。在进程内的通常使用 ImpersonateLoggedOnUser函数模拟用户时,这个线程就是该模拟令牌代表的用户的身份,处理完成后使用 RevertToSelf函数恢复自己的身份。如果该用户能够模拟成功,则立即使用该用户身份创建一个新的进程。这由函数 CreateProcessAsUser完成,与CreateProcess相比, CreateProcessAsUser 函数多一个主要令牌的参数,这样启动的新进程就不是父进程的身份,而是user_token令牌代表的登录用户。
当然,如果不需要进行用户模拟,则只要在调用CreateProcess的时候将进程的安全属性设置为NULL就可以了。

关于作者
张中庆,目前主要的研究方向是嵌入式浏览器,移动中间件以及大规模服务器设计。目前正在进行Apache的源代码分析,计划出版《Apache源代码全景分析》上下册。Apache系列文章为本书的草案部分,对Apache感兴趣的朋友可以通过flydish1234 at sina.com.cn与之联系!

如果你觉得本文不错,请点击文后的“推荐本文”链接!!

分享到:
评论

相关推荐

    重启apache进程脚本

    这个脚本的主要功能是检测当前系统中 Apache 进程的数量,如果数量超过 60 个,则重启 Apache 服务器,以释放系统资源。同时,如果系统中可用内存小于 20%,则清理系统缓存,释放更多的内存资源。 下面我们来详细...

    Apache Server源代码分析(PDF)

    7. **错误处理和异常恢复**:Apache如何处理错误,如404找不到文件或500内部服务器错误,以及如何优雅地恢复异常状态,都是源代码分析中的重要部分。 8. **并发和线程模型**:Apache的多路复用模型允许高效地处理...

    Apache工作机制分析

    - **多处理模块(MPM)**:决定Apache如何处理客户端请求,包括使用进程或线程模型来处理并发连接。 - **可移植运行库(APR)**:提供一个平台独立的接口,使得Apache能够在多种操作系统上运行。 #### Apache+...

    Apache日志分析手册

    6. 查看进程和端口连接:手册中提到了使用ps和netstat命令来查看Apache进程和80端口的TCP连接数。这些命令有助于了解Apache服务的运行状态。 7. 分析日志中的异常行为:比如,通过过滤日志来查看特定IP地址在特定...

    Apache2中文使用手册

    8. **性能优化**:优化Apache2涉及调整工作进程模型(如prefork或event),限制并发连接,缓存静态内容,以及使用负载均衡等技术。理解服务器负载和资源消耗对于提供高效服务至关重要。 9. **故障排查**:当遇到...

    Apache源代码全景分析

    - **进程间通信**:在多进程模型中,Apache使用管道、信号和共享内存等机制实现进程间的通信与协调。 - **请求处理流程**:Apache接收到请求后,会经历接收、解析、路由、执行模块、响应等步骤,最后返回结果给...

    apache架构设计原理剖析

    1. 连接管理(监听):Apache监听指定端口的连接请求,一旦有新的连接到来,它会创建一个新的进程或线程来处理该连接。 2. 请求读取:Apache接收并解析HTTP请求,包括请求行、头和数据。 3. 找到表示形式:根据请求...

    apache中文帮助文档

    6. **多线程与MPM(多进程模块)**:了解Apache的MPM机制,如prefork、worker和event模型,以及如何根据服务器需求选择合适的MPM。 7. **虚拟主机**:设置和管理基于域名、IP或端口的多个虚拟主机,允许在一个...

    apache源代码解析--基于Apache0.6.5

    在 Apache 0.6.5 版本中,守护进程的创建和管理是非常重要的。 知识点4: Apache 生命周期 Apache 生命周期是指 Apache 服务器从启动到关闭的整个过程。在这个过程中,Apache 服务器会经历多个阶段,包括初始化、...

    Apache Server源代码分析

    本篇将围绕"Apache Server源代码分析"这一主题,详细介绍Apache服务器的核心概念、架构设计以及关键模块。 Apache服务器的源代码结构主要分为以下几个部分: 1. **主程序(Main Program)**:Apache服务器的启动点...

    Apache官方中文文档教程

    6. **性能优化**:Apache有多种性能优化策略,如使用MPM(多进程模块)如prefork或worker,设置合适的MaxKeepAliveRequests和KeepAliveTimeout,以及开启缓存模块mod_cache等。 7. **HTTPS与SSL/TLS**:在当前网络...

    apache中文手册

    4. **性能优化**:Apache手册也会包含性能调优技巧,例如如何配置预加载进程(Prefork或Event MPM)、调整KeepAlive设置、使用缓存模块提高响应速度等。 5. **日志和错误处理**:了解如何解析和分析Apache的日志...

    Apache中文手册20

    5. **日志分析**:如何解读Apache的日志文件,以及如何使用工具进行日志分析,以监控服务器状态、发现潜在问题。 6. **多线程与事件模型**:Apache有 prefork 和 worker 两种多进程/多线程模型,手册会介绍它们的优...

    Apache中文手册

    6. **CGI和FastCGI**:Apache支持Common Gateway Interface(CGI)来运行服务器端脚本,而FastCGI是CGI的一种更高效实现,可以持久运行进程,提高响应速度。 7. **SSI(Server Side Includes)**:Apache还支持...

    APACHE 2.2 中文参考手册

    2. **多线程支持**:通过MPM(Multi-Processing Module)机制,Apache 2.2 支持多线程和多进程模型,提高了并发处理能力。 3. **更好的性能**:相比之前的版本,Apache 2.2 在性能上有所提升,优化了内存使用,降低...

    apache 配置中文详解

    虚拟主机设置部分定义了 Apache 服务器进程中的不同 IP 地址和主机名。在这个部分,我们可以设置虚拟主机的各种参数,如 ServerName、ServerAdmin 和 DocumentRoot 等。 配置文件命名和路径 配置文件的命名和路径...

    Apache2.22源代码

    4. **跨平台移植**:了解源代码后,可以更容易地将Apache移植到其他操作系统或硬件平台上。 总的来说,Apache2.22源代码是理解和开发Web服务器的重要资料,它提供了丰富的学习和实践机会,帮助开发者提升技能,解决...

    apache中文文档

    2. **核心功能**:介绍Apache的核心特性,如多进程模型(MPM)、请求处理机制、模块加载等。 3. **安全设置**:讲解如何配置SSL/TLS以确保网站通信的安全,以及如何设置防火墙规则和权限控制来防止未授权访问。 4....

    apache启动不了的解决办法

    Apache 启动不了的解决办法 Apache 服务器是一种流行的 Web 服务器软件,然而,在实际应用中,Apache 服务器的启动问题是非常常见的。...Apache 服务器无法启动的解决办法有多种,需要根据具体情况进行分析和解决。

    APACHE COOKBOOK中文版

    4. **性能优化**:提供关于如何调整Apache的性能来应对不同规模的网站流量,包括工作进程管理、并发连接数优化、模块加载优化等。 5. **安全性**:探讨如何保护Apache服务器免受常见的网络攻击和安全威胁,包括SSL/...

Global site tag (gtag.js) - Google Analytics