Apache
在互联网中浏览网页都需要使用HTTP(超文本传输协议),而Apache只是HTTP协议的一个实现程序 , HTTPD作为其主程序运行,目前常用有两个版本CentOS6(httpd 2.2)、CentOS7 (httpd 2.4)。
一次完整的HTTP请求(事务):
1)Client请求网页资源、与Server建立连接(三次握手)、Server处理请求(允许或拒绝)。
2) 如果Server接受来自Client的请求,则根据Apache的多进程处理模型(MPM),挑选一个子进程或线程根据http Request 报文中的Headers 进行分析处理。
3)Server根据Request headers中定义的方法(method)去访问并获取资源。
4)构建响应报文(Http Response),使用MIME编码方式将不同的资源类型编码,也可能是重定向资源。
5)发送响应报文, 到此步骤如果是短连接方式,一次http请求的过程就完成了,如果是长连接方式则继续请求资源。
6)记录日志。
Http Request报文:
|
Method 表示Client对资源的请求方法,常见的有:
Get 下载资源
Put 将请求报文中的”entity-body” 上传到服务器上
Head 从服务器获取请求资源的响应头部
Delete 在服务器上删除资源
Options 请求资源可使用的Method
Trace 追踪请求到达中间经过的代理服务器
Request-URL 表示资源在网络中的位置
格式:
协议://用户名:密码@域名:端口号/目录/文件名.文件后缀?参数=值#标志
Http_Version 表示HTTP协议使用的版本号,通常为:
http/1.0
http/1.1
Headers 包含请求或响应资源时需要协商的信息
通用首部:
Data 创建时间
Connection 连接状态是否为长连接
Via 显示报文经过的中间节点,是否存在代理
Cache-control 控制缓存
请求首部:
Accept-charset Client表示自己能接受的字符编码
Accept-Encoding Client表示自己能接收的编码格式
Accept-Language Client表示自己能接受的语言
信息类请求:
Client-IP 客户端IP地址
Host 表示请求服务器的名称和端口
Referer 告诉服务器Client是从哪个连接跳转过来的
User-Agent 表示客户端代理程序
Http Response 报文:
|
Version 为http协议的版本
Status 为本次响应结果的状态码
1XX: 100-101 信息类的响应码
2XX: 200-206 成功类的响应码
200 成功,OK
3XX: 300-305 重定向类的响应码
301 请求的资源已被删除,永久重定向
302 请求的资源已被删除,临时重定向
4XX: 400-415 错误类信息,客户端错误
401 需要认证,提供用户名、密码
404 请求的网页不存在
403 请求被禁止,Forbiden
5XX:500-505 错误类信息,服务端错误
500 服务器内部错误
Reason-phrase 为本次响应码的简要短语
Headers 响应头部
信息类:
Age 资源的有效时间
Server 服务器的软件名称
协商首部:
Accept-ranges: 服务器可接受的请求范围
Vary:服务器查看其它首部列表
安全响应首部:
Set-Cookie 向客户端设置Cookie
Set-Cookie2 向客户端设置Cookie2
长、短连接
通常一个网页包含多个资源,如果每个资源都需要一次建立连接、HTTP Request、Response 、拆除连接,这就叫短连接,这种方式比较浪费资源。
长连接,此方式建立连接后可以进行多次请求、响应资源。 但如果在高并发模式下,使用长连接,而用户又不请求资源因长连接方式占用着进程,别人也请求不了资源。
KeepAlive Off|ON ON表示开启长连接、OFF表示关闭
MaxKeepAliveRequests 100 限制进程当请求量到100时,需要重新建立连接
KeepAliveTimeout 15 限制进程当超时15秒后,需要重新建立连接
修改Apahce 服务器为长连接方式: [root@7-1 ]# vim /etc/httpd/conf/httpd.conf KeepAlive on MaxKeepaliveRequests 100 KeepAliveTimeOut 10 长连接测试,可以对资源进行多次请求,连接不会断: [root@7-1 conf]# telnet 172.16.1.50 80 Trying 172.16.1.50... Connected to 172.16.1.50. Escape character is '^]'. GET / HTTP/1.1 HOST:172.16.1.50
HTTP/1.1 200 OK Date: Tue, 22 May 2018 11:50:49 GMT Server: Apache/2.4.33 (Unix) Last-Modified: Tue, 22 May 2018 01:25:57 GMT ETag: "11-56cc14cd527d5" Accept-Ranges: bytes Content-Length: 17 Content-Type: text/html
hello httpd 2.4
GET / HTTP/1.1 HOST:172.16.1.50
HTTP/1.1 200 OK Date: Tue, 22 May 2018 11:51:02 GMT Server: Apache/2.4.33 (Unix) Last-Modified: Tue, 22 May 2018 01:25:57 GMT ETag: "11-56cc14cd527d5" Accept-Ranges: bytes Content-Length: 17 Content-Type: text/html
hello httpd 2.4 Connection closed by foreign host.
[root@7-1 ]# vim /etc/httpd/conf/httpd.conf KeepAlive OFF
[root@7-1 conf]# !sys systemctl restart httpd
短连接测试,一次连接只能有一个请求: [root@7-1 conf]# telnet 172.16.1.50 80 Trying 172.16.1.50... Connected to 172.16.1.50. Escape character is '^]'. GET / HTTP/1.1 HOST:172.16.1.50
HTTP/1.1 200 OK Date: Tue, 22 May 2018 11:54:26 GMT Server: Apache/2.4.33 (Unix) Last-Modified: Tue, 22 May 2018 01:25:57 GMT ETag: "11-56cc14cd527d5" Accept-Ranges: bytes Content-Length: 17 Connection: close Content-Type: text/html
hello httpd 2.4 Connection closed by foreign host. |
MPM (Multi-Processing Module) 多进程模型
1. perfork MPM
Perfork模型通过预先启动进程,由一个单独的控制进程(父进程)负责产生子进程,这些子进程用于监听请求并作出应答。并且Apache总是试图保持一些备用的(spare)或者是空闲的子进程用于迎接即将到来的请求。这样客户端就不需要在得到服务前等候子进程的产生,减少频繁创建、销毁进程的开销。
优点:响应速度快、稳定
缺点:进程占用系统资源过多、不适合高并发环境。
Apache中的配置方式:
[root@el6 ]# vim /etc/httpd/conf/httpd.conf StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 256 MaxClients 256 MaxRequestsPerChild 4000 |
StartServers 表示预先启动的进程数,不包含主进程
MinSpareServers 表示最少空闲进程数
MaxSpareServers 表示最多空闲进程数
ServerLimit 用于限制MaxClient
MaxClient 表示能处理最大并发请求数
MaxRequestsPerChild 限制进程处理多少个请求之后自动销毁,值为0 表示永不销毁
2. woker MPM
woker模型使用多进程和多线程的混合方式,也需要由主进程事先fork创建子进程(数量少),每个子进程可以建立ThreadsPerChild数量的服务线程和一个监听线程,该监听线程监听接入请求并将其传递给服务线程处理和应答。
之所以不完全使用多线程是因为线程之间内存共享,如果一个线程挂了,整个进程都挂了,所以还需要使用多进程,这样一个进程奔溃也只影响一部分内容。
优点:使用线程方式占用资源少,线程之间共享内存,支持更高的并发。
缺点:线程共享,稳定性差; 在长连接模式下
Apache中的配置方式:
[root@el6 ]# vim /etc/httpd/conf/httpd.conf StartServers 4 MaxClients 300 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25 MaxRequestsPerChild 0 |
StartServers 表示启动的进程数
MaxClient 表示能处理最大并发请求数
MiniSpareThreads 表示最少空闲的线程数
MaxSpareThreads 表示最大空闲的线程数
ThreadsPerChild 表示每个进程拥有对最大线程数
MaxRequestsPerChild 表示限制进程处理多少个请求之后自动销毁,值为0 表示永不销毁
3. event MPM
这个是Apache中最新的模式,在现在版本里的已经是稳定可用的模式。它和worker模式很像,最大的区别在于,它解决了keep-alive场景下,长期被占用的线程的资源浪费问题(某些线程因为被keep-alive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)。event MPM中,会有一个专门的线程来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力。
event MPM在遇到某些不兼容的模块时,会失效,将会回退到worker模式,一个工作线程处理一个请求。官方自带的模块,全部是支持event MPM的。
Apache中的配置方式:
[root@el6 ]# vim /etc/httpd/conf/httpd.conf StartServers 3 MinSpareThreads 75 MaxSpareThreads 250 ThreadsPerChild 25 MaxRequestWorkers 400 MaxConnectionsPerChild 0 |
想知道当前HTTPD工作在什么MPM模型下,使用以下命令查看
Httpd –M | grep mpm
Gzip 、 DEFLATE
DEFLATE是一个无专利的压缩算法,它可以实现无损数据压缩,有众多开源的实现算法。该标准的实施库大多数人用的是zlib的。zlib库提供用于压缩和解压缩使用DEFLATE/INFLATE的数据。zlib库还提供了一种数据格式,混淆的命名ZLIB,它包装DEFLATE压缩数据,具有报头和校验和。
GZIP是使用DEFLATE进行压缩数据的另一个压缩库。事实上,GZIP的大多数实现实际使用zlib库的内部进行DEFLATE/ INFLATE压缩操作。GZIP产生其自己的数据格式,混淆的命名GZIP,它包装DEFLATE压缩数据,具有报头和校验和。
客户端与服务器使用Accept-Encoding和Content-Encoding标头完成协商压缩方式。有两种常用的HTTP压缩:DEFLATE和GZIP。
Apache2.2加载模块 Vim /etc/httpd/conf/httpd.conf LoadModule deflate_module modules/mod_deflate.so LoadModule headers_module modules/mod_headers.so Apache2.4 加载模块 Vim /etc/httpd/conf.modules.d/00-base.conf LoadModule deflate_module modules/mod_deflate.so LoadModule headers_module modules/mod_headers.so |
DEFLATE 配置方式: [root@7-1 ]# vim /etc/httpd/conf/httpd.conf SetOutPutFilter DEFLATE SetEnvIfNoCase Request_URL .(?:gif|jpe?g|png)$ no-gzip dont-vary SetEnvIfNocase Request_URL .(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary SetEnvIfNoCase Request_URI .(?:pdf|doc|avi|mov|mp3|rm)$ no-gzip dont-vary AddOutPutFilterByType DEFLATE text/* AddOutPutFilterByType DEFLATE application/x-javascript application/xml application/x-javascript DeflateCompressionLevel 9
[root@7-1 conf]# !sys systemctl restart httpd
按F12打开Google浏览器的调试功能: 关闭压缩功能: # # SetOutPutFilter DEFLATE # SetEnvIfNoCase Request_URL .(?:gif|jpe?g|png)$ no-gzip dont-vary # SetEnvIfNocase Request_URL .(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary # SetEnvIfNoCase Request_URI .(?:pdf|doc|avi|mov|mp3|rm)$ no-gzip dont-vary # AddOutPutFilterByType DEFLATE text/* # AddOutPutFilterByType DEFLATE application/x-javascript application/xml application/x-javascript # DeflateCompressionLevel 9 # #
systemctl restart httpd
关闭Deflate功能后,发现响应头部已经没有gzip字样,并且响应大小也从276变为465了 |
装载模块 mod_gzip 可能需要自己编译,另外编译过程依赖httpd-devel包 ,因为需要APSX |
Gzip配置方式: # mod_gzip mod_gzip_on Yes mod_gzip_dechunk Yes mod_gzip_item_include file .(html?|txt|css|js|php|pl)$ mod_gzip_item_include handler ^cgi-script$ mod_gzip_item_include mime ^text/.* mod_gzip_item_include mime ^application/x-javascript.* mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.* |
Httpd配置文件组成:
/etc/httpd/conf/httpd.conf #主配置文件
/etc/httpd/conf.d/*.conf #额外提供的配置文件
[root@el6 ~]# grep 'Section' /etc/httpd/conf/httpd.conf
### Section 1: Global Environment 定义全局环境变量
### Section 2: 'Main' server configuration 定义Main Server站点
### Section 3: Virtual Hosts 定义虚拟主机,与Main Server冲突
站点访问控制:
在httpd中可基于两种类型的路径指明对哪些资源进行访问控制。
基于文件系统中的路径控制:
…
基于URL路径控制:
…
在
Options用于设定在定义的资源中,可使用选项
Options None ALL Indexes FollowSymLinks SymLinksIfOwnerMatch … None 表示不使用任何选项 ALL 表示使用所有选项 Indexes 表示使用”索引”,当目录中没有”DirectoryIndex”定义的主页时,是否列出文件索引,在创建文件下载站点时有用。如果不生效,则将welcome页面删除。 FollowSymLinks 表示如果在网站目录中有符号链接文件,是否跟踪 SymLinksIfOwnerMatch 表示符号链接的属主是本人时才跟踪
|
基于源IP对资源做访问控制:
Httpd2.2:
白名单,只允许被Allow from 匹配的地址访问
Oder allow,deny
Allow from ip/net
黑名单,被Deny from匹配的地址都无权访问资源
Oder deny,allow
Deny from IPADDR
IPADDR:
172.16.1.1 定义单个IP
172.16.0.0 根据地址主类自动判断网段掩码
172.16.0.0/16
172.16.0.0/255.255.0.0
Httpd2.4:
Require all granted 允许所有人访问
Require all deny 拒绝所有人访问
Require ip IPADDR 允许制定IP地址能访问
IPADDR:
172.16.1.1 定义单个IP
172.16.0.0 根据地址主类自动判断网段掩码
172.16.0.0/16
172.16.0.0/255.255.0.0
注意:在Httpd2.4中,每个目录都需要明确授权,否则是无法访问的
基于账号、密码做访问控制:
Basic——账号、密码明文传输方式认证:
AuthType Basic AuthName “ DOMAIN_NAME” #提示用户,此资源为什么需要认证 AuthUserFile “/PATH/TO/USER_FILE ” #用户、密码文件存放位置 Require user USERNAME1 USERNAME2 #允许那个用户访问 Require valid-user #允许AuthUserFile中所有有效用户访问
|
另外还可以基于组对用户控制:
AuthType Basic AuthNmae “DOMAIN_NAME” AuthUserFile “/PATH/TO/GROUP_FILE” AuthGrupFile “/PATH/TO/GROUP_FILE” Require group group_name1 group_name2
|
GroupFile 定义格式:
组名:用户名1 用户名2
UserFile需要使用htpasswd 命令生成:
htpasswd -c -m /etc/httpd/conf/.htaccess USER_NAME
-c 表示首次需要创建该文件,添加用户则不需要此选项
-m 表示存放的密码使用md5加密存放
-s 表示存放的密码使用sha1加密存放
-D 表示删除指定用户
Degist——账号、密码密文方式传输认证:
AuthType Degist AuthName “DOMAIN_NAME” AuthUserFile “/PATH/TO/USER_FILE” Require user USER_NAME1 USER_NAME2 |
USER_FILE需要使用htdigst命令生成:
Usage: htdigest [-c] passwordfile DOMAIN_NAME username
注意:DOMAIN_NAME要与配置文件中定义的AuthName匹配,否则验证无法通过
路径别名
Alias 用于在Apache 定义URL与本地文件系统中资源的映射关系。
Usage : Alias /URL /PATH/TO/SOMEDIR/
/URL 表示以根为起始位置的访问入口
/PATH/TO/SOMEDIR/ 本地资源的路径,路径结尾有/ ,最后URL后也接/
例如:
Alias /doc /usr/share/doc
Alias /doc/ /usr/share/doc/
Optiosn indexes FollowSymlinks
Require all granted
设置默认字符集
AddDefaultCharset UTF-8
Server-status
Apache 内置的状态页。
SetHandler server-status Order deny,allow Deny from all Allow from localhost |
日志:
错误日志: /var/log/httpd/error_log
访问日志:/var/log/httpd/access_log
日志中的内容都由一下配置定义:
ErrorLog "logs/error_log" LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common CustomLog "logs/access_log" combined |
ErrorLog 用于设定访问日志的存放路径
LogForat 用于自定义日志格式,在Apache2.4中还支持在模块定义日志功能
%h ClientIP %l Client 远程登录名字 来自Identd %u 认证时Client使用的认证名字 %t Client访问的时间 %r Request报文的第一行 %>s 记录最终请求的状态码(如果有重定向) %b 传送资源的大小 %{Referer}i 表示访问的来源,上一个链接 %{User-Agent}i 表示用户使用的Agent信息(浏览器) |
CustomLog 用于设定访问日志的存放路径与日志格式
虚拟主机:
注意:使用虚拟主机时,最好把Main Server停用,否则会冲突.
#DocumentRoot /var/www/html
定义虚拟主机的三种方式:
基于IP(前提是主机有多个IP地址):
Httpd2.4中定义虚拟主机: Httpd2.2中不需要Require all grantd DocumentRoot /www/vhdocs1/ DirectoryIndex index.html index.php Require all grantd
DocumentRoot /www/vhdocs2/ DirectoryIndex index.html index.php Require all grantd |
基于端口:
Httpd2.4中定义虚拟主机: Httpd2.2中不需要Require all grantd Listen 80 Listen 8080 DocumentRoot /www/vhdocs1/ DirectoryIndex index.html index.php Require all grantd
DocumentRoot /www/vhdocs2/ DirectoryIndex index.html index.php Require all grantd
|
基于域名:
Httpd2.2中还需要启用一条命令: NameVirtualHost *:80 不需要Require all grantd Httpd2.4定义方式: DocumentRoot /www/vhdocs1/ ServerName www.jying.com DirectoryIndex index.html index.php Require all grantd
DocumentRoot /www/vhdocs2/ ServerName web.jying.com DirectoryIndex index.html index.php Require all grantd
|