目录
apache的三种MPM模式
a、prefork
为了减少频繁创建和销毁进程的开销,apache在启动之初,就预先fork一些子进程,然后等待请求进来。每个子进程只有一个线程,在一个时间点内,只能处理一个请求。
优点
成熟稳定,兼容所有新老模块。同时,不需要担心线程安全的问题。
缺点
一个进程相对占用更多的系统资源,消耗更多的内存。而且,它并不擅长处理高并发请求,在这种场景下,它会将请求放进队列中,一直等到有可用进程,请求才会被处理。
b、worker
使用了多进程和多线程的混合模式。也预先fork了几个子进程(数量比较少),一个子进程创建很多线程,同时包括一个监听线程。每个请求过来,会被分配到1个线程来服务。线程比起进程会更轻量,因此,内存的占用会减少一些。在高并发的场景下,比起prefork有更多的可用线程,表现会更优秀一些。
至于为什么不使用单进程多线程,还要引入多进程。
是考虑稳定性,如果一个线程异常挂了,会导致父进程及父进程下的其他的正常子线程都挂了。为了防止全盘崩溃,就使用多进程多线程,这样如果某个线程出现异常,受影响的只有它父进程下的线程
优点
占据更少的内存,高并发下表现更优秀。
缺点
必须考虑线程安全的问题,因为多个子线程是共享父进程的内存地址的。如果使用keep-alive的长连接方式,某个线程会一直被占据,也许中间几乎没有请求,需要一直等待到超时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用。(该问题在prefork模式下,同样会发生)
c、event
这个模式是Apache中最新的模式,在现在版本里已经稳定可用了。它和worker模式很像。
但是,它解决了keep-alive场景下,长期被占用的线程的资源浪费问题(某些线程因为被keep-alive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)。
在event MPM中,会有一个专门的线程来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力。
event MPM在遇到某些不兼容的模块时,会失效,将会回退到worker模式,一个工作线程处理一个请求。官方自带的模块,全部是支持event MPM的。
注意一点,event MPM需要Linux系统(Linux2.6+)对EPoll的支持,才能启用。
Apache和PHP三种结合方法
a、模块化模式:
apache和php安装在同一台服务器中,把PHP编译为Apache模块,也是用的最多的一种方法
b、CGI模式[CGI:Common Gateway Interface]
以一种CGI模式, 将apache服务递交给PHP服务器,共同网关接口,是HTTP服务器与机器上其他程序进行通信的一个接口,让WEb服务器必要时启动额外的程序处理动态内容。
c、fastCGI模式
动态服务器和静态服务器分离,让CGI解释器得意更快实现,可以提供良好的性能、伸缩性、Fail-Over特性等
解析漏洞
在apache/conf目录下有个mime.types文件,这里记录了大量的文件后缀和mime类型,当客户端请求一个文件时,如果后缀在这个列表里,那么Apache就返回对应的content-type给浏览器。如果不在列表,Apache不会返回content-type给浏览器,而是直接返回文件内容。
很多web服务器使用默认的 application/octet-stream 来发送未知类型
Apache文件解析漏洞涉及到一个文件解析的特性:Apache默认一个文件可以有多个以点分割的后缀,从右往左识别,当最右边的后缀无法识别(即不在mime.types内),就继续向左识别,直到全部识别完毕。
举个例子,如果有这么一个文件1.php.txt.abc.xyz,最末尾的.xyz无法识别,向左移;.abc还是无法识别,向左移;.txt可以识别,于是就把它当做txt文档。虽然.php也同样可以识别,但是因为.txt在它前面,所以还轮不到它
使用module模式与php结合的所有版本 apache存在未知扩展名解析漏洞,使用fastcig模式与php结合的所有版本apache不存在此漏洞。
所以,想利用此漏洞必须保证文件扩展名中 至少带有一个“.php”,否则有可能被当作默认的txt/html文档处理。