httpd2.2的编译安装实现
1、Centos7系统下实现httpd-2.2的安装,并分别实现prefork、worker、event等几种工作方式
2、简述request报文请求方法和状态响应码
3、详细描述httpd虚拟主机、站点访问控制、基于用户的访问控制、持久链接等应用配置实例
1、Centos7系统下实现httpd-2.2的安装,并分别实现prefork、worker、event等几种工作方式
在实现http的这几种工作模式前,我们需要知道最基本的网络IO模型,以及prefork、worker、event三种工作模式的原理。简单的来说就是
-
prefork:多进程模型,每个进程响应一个请求;一个主进程:负责生成子进程及回收子进程;负责创建套接字;负责接收请求,并将其派发给某子进程进行处理;每个子进程处理一个请求;会预先生成几个空闲进程,随时等待用于响应用户请求;最大空闲和最小空闲;
-
worker:多进程多线程模型,每线程处理一个用户请求;一个主进程:负责生成子进程;负责创建套接字;负责接收请求,并将其派发给某子进程进行处理;每个子进程负责生成多个线程;每个线程:负责响应用户请求;
-
event:事件驱动模型,多进程模型,每个进程响应多个请求;主进程负责生成子进程创建套接字,接收请求,并将其派发给某子进程进行处理;子进程基于事件驱动机制直接响应多个请求;
然后接下来就可以开始实验了,编译安装httpd-2.2
安装前需要准备安装环境,安装开发组件
yum -y groupinstall "Development Tools" "Serverplatform Development"
wget http://archive.apache.org/dist/httpd/httpd-2.2.32.tar.gz
注意httpd的安装需要依赖于两个包apr和apr-util所以我们需要先安装这两个包
wget http://mirror.bit.edu.cn/apache/apr/apr-1.6.5.tar.bz2
wget http://mirror.bit.edu.cn/apache/apr/apr-util-1.6.1.tar.bz2
./configure --prefix=/usr/local/apr
make && make install
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr
make && make install
上面两个包安装完后我们就可以开始安装httpd了
./configure --prefix=/usr/local/httpd2.2 --with-apr=/usr/local/apr --with-apr-uil=/usr/local/apr-util
--with-mpm=prefork
make && make install
还需要设置环境变量以及我们编译安装的http并不受systemd的管理,所以我们需要自己创建unit文件。
export PATH=$PATH:/usr/local/httpd2.2/bin
cat /usr/lib/systemd/system/httpd.service
Description=The httpd service
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/httpd2.2/bin/apachectl start
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/usr/local/httpd2.2/bin/apachectl stop
Restart=/usr/local/httpd2.2/bin/apachectl restart
[Install]
WantedBy=multi-user.target
然后我们可以看到systemd已经可以管理httpd了
systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since 六 2018-12-08 16:23:47 CST; 1s ago
Docs: man:httpd(8)
man:apachectl(8)
Main PID: 54254 (httpd)
Status: "Processing requests..."
CGroup: /system.slice/httpd.service
├─54254 /usr/sbin/httpd -DFOREGROUND
├─54255 /usr/sbin/httpd -DFOREGROUND
├─54256 /usr/sbin/httpd -DFOREGROUND
├─54257 /usr/sbin/httpd -DFOREGROUND
├─54258 /usr/sbin/httpd -DFOREGROUND
├─54259 /usr/sbin/httpd -DFOREGROUND
└─54260 /usr/sbin/httpd -DFOREGROUND
如果我们在安装的时候想转变模式可以在./configuer后面加上--with-mpm=prefork|worker|events
如果是安装后想改变模式我们只需要修改配置文件
vim /etc/httpd/conf.modules.d/00-mpm.conf
# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
#LoadModule mpm_worker_module modules/mod_mpm_worker.so
# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
#LoadModule mpm_event_module modules/mod_mpm_event.so
2、简述请求报文请求方法和状态响应码
method:
- GET:从服务器获取一个资源;
- HEAD:只从服务器获取文档的响应首部;
- POST:向服务器发送要处理的数据;
- PUT:将请求的主体部分存储在服务器上;
- DELETE:请求删除服务器上指定的文档;
- TRACE:追踪请求到达服务器中间经过的代理服务器;
- OPTIONS:请求服务器返回对指定资源支持使用的请求方法;
status:
- 200: 成功,请求的所有数据通过响应报文的entity-body部分发送;OK
- 301: 请求的URL指向的资源已经被删除;但在响应报文中通过首部Location指明了资源现在所处的新位置;Moved Permanently
- 302: 与301相似,但在响应报文中通过Location指明资源现在所处临时新位置; Found
- 304: 客户端发出了条件式请求,但服务器上的资源未曾发生改变,则通过响应此响应状态码通知客户端;Not Modified
- 401: 需要输入账号和密码认证方能访问资源;Unauthorized
- 403: 请求被禁止;Forbidden
- 404: 服务器无法找到客户端请求的资源;Not Found
- 500: 服务器内部错误;Internal Server Error
- 502: 代理服务器从后端服务器收到了一条伪响应;Bad Gateway
3、详细描述httpd虚拟主机、站点访问控制、基于用户的访问控制、持久链接等应用配置实例
(1)httpd的虚拟主机就是在一台主机上基于IP,端口,FQDN来虚拟出不同的主机,就像一台主机上运行了多个网站一样。
基于IP的虚拟主机
<VirtualHost 192.168.31.200:80>
...
</VirtualHost>
<VirtualHost 192.168.31.201:80>
...
</VirtualHost>
相同的端口也会被识别为不同的主机
基于端口的虚拟主机
<VirtualHost 192.168.31.200:80>
...
</VirtualHost>
<VirtualHost 192.168.31.200:8080>
...
</VirtualHost>
相同的ip地址但是端口不同所以也会被识别为不同的主机
基于FQDN的虚拟主机
<VirtualHost *:80>
ServerName node1.lvqing.com
...
</VirtualHost>
<VirtualHost *:80>
ServerName node2.lvqing.com
...
</VirtualHost>
相同的ip地址但是FQDN不同所以也会被识别为不同的主机
站点访问控制
推荐使用白名单的形式,来自指定IP的请求全部拒绝掉
<VirtualHost *:80>
ServerName node1.lvqing.com
DocumentRoot "/var/www/vhost1"
<Directory "/var/www/vhost1">
Order deny,allow
allow from 192.168.31.200
Deny from all
</Directory>
</VirtualHOST>
curl http://node1.lvqing.com/aaa
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /aaa
on this server.</p>
</body></html>
curl http://node1.lvqing.com
<h1> test page </h1>
另一种形式
<RequireAll>
Require all denied
Require ip 192.168.31.200
</RequireAll>
基于用户的访问控制
首先需要创建用户
htpasswd -c /tmp/test.users lvqing
New password:
Re-type new password:
Adding password for user lvqing
然后将文件放在conf.d目录下
mv /tmp/test.users /etc/httpd/conf.d/.htpasswd
在配置文件中添加
AuthType basic
AuthName "Please Input Admin Passwd"
AuthUserFile "/etc/httpd/conf.d/.htpasswd"
Require user lvqing
在来测试看看
curl http://node1.lvqing.com
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>401 Unauthorized</title>
</head><body>
<h1>Unauthorized</h1>
<p>This server could not verify that you
are authorized to access the document
requested. Either you supplied the wrong
credentials (e.g., bad password), or your
browser doesn't understand how to supply
the credentials required.</p>
</body></html>
加上账户密码
curl -u lvqing:123456 http://node1.lvqing.com
<h1> test page </h1>
持久连接
tcp连续建立后,每个资源获取完成后不全断开连接,而是继续等待其它资源请求的进行;
1、基于请求数量
2、基于连接的时间
在配置文件中添加三段
KeepAlive On
KeepAliveTimeout 15
MaxKeepAliveRequests 100
然后进行测试
[root@lvq-node1 ~]# telnet node1.lvqing.com 80
Trying 192.168.31.206...
Connected to node1.lvqing.com.
Escape character is '^]'.
GET /index.html HTTP/1.1
Host:node1.lvqing.com
HTTP/1.1 408 Request Timeout
Date: Sat, 08 Dec 2018 10:05:18 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5
Content-Length: 221
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>408 Request Timeout</title>
</head><body>
<h1>Request Timeout</h1>
<p>Server timeout waiting for the HTTP request from the client.</p>
</body></html>
Connection closed by foreign host.
可以看到连接持续了15秒后才断开