1、 请描述一次完整的http请求处理过程;
(1)建立和处理连接:接收请求或者拒绝请求;
(2)接收请求:接收来自于网络上的主机请求报文中对某特定的资源的一次请求的过程;
(3)处理请求:对请求报文进行解析,获取客户端请求的资源及请求方法等相关信息
(4)访问资源:获取请求报文中请求的资源
(5)构建响应报文;
(6)发送响应报文;
(7)记录日志;
TCP/IP协议三次握手与四次握手流程解析
一、TCP报文格式

图1 TCP报文格式
上图中有几个字段需要重点介绍下:
(1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
(2)确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
(3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
(A)URG:紧急指针(urgent pointer)有效。
(B)ACK:确认序号有效。
(C)PSH:接收方应该尽快将这个报文交给应用层。
(D)RST:重置连接。
(E)SYN:发起一个新连接。
(F)FIN:释放一个连接。
需要注意的是:
(A)不要将确认序号Ack与标志位中的ACK搞混了。
(B)确认方Ack=发起方Req+1,两端配对。
三次握手(three
times handshake;three-way handshake)所谓的”三次握手”即对每次发送的数据量是怎样跟踪进行协商使数据段的发送和接收同步,根据所接收到的数据量而确定的数据确认数及数据发送、接收完毕后何时撤消联系,并建立虚连接。
为了提供可靠的传送,TCP在发送新的数据之前,以特定的顺序将数据包的序号,并需要这些包传送给目标机之后的确认消息。TCP总是用来发送大批量的数据。当应用程序在收到数据后要做出确认时也要用到TCP。
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize
Sequence Numbers)。
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
四次挥手
所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发,整个流程如下图所示:


由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
(1) TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。
(2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
(3) 服务器关闭客户端的连接,发送一个FIN给客户端。
(4) 客户端发回ACK报文确认,并将确认序号设置为收到序号加1。
2、 httpd所支持的处理模型有哪些,他们的分别使用于哪些环境。
httpd所支持的事务处理模型主要有:
prefork,worker,event
他们分别使用于以下场景:
prefork:多进程模型,每个进程负责响应一个请求。prefork模型在工作时,由一个主进程负责生成n个子进程,即工作进程。每个工作进程响应一个用户请求,即使当前没有用户请求,它亦会预先生成多个空闲进程,随时等待请求连接,这样的好处是,服务器不用等到请求到达时,才去临时建立进程,缩短了进程创建的时间。提高连接效率。但受限于linux的特性,工作进程数上限为1024个,如果超出该数量,服务器性能会急剧降低。因而,prefork模型的最大并发连接数量为1024.由于每个工作进程相对独立,就算崩溃了,也不会对其它进程有明显影响。所以,该模型的特点是稳定可靠,适合于并发量适中而又追求稳定的用户使用。
worker:多线程模型,每个线程响应一个请求。worker模型在工作时,主进程负责生成多个子进程, 同时每个子进程负责生成多个线程,每个线程响应一个用户请求。同时,worker模型也会预先创建一些空闲线程来等待用户连接。并发连接数,如果生成进程数为m,线程数为n,则并发数可达到m*n个。但由于在linux中,原生不支持线程,且进程本身就足够轻量化,与线程的区别不是很大,因而,worker模型在linux环境中的实际性能表现与prefork相差无几。
event:事件驱动模型,每个线程响应n个用户请求。event模型工作时,由主进程生成m个子进程,每 个单独的子进程可响应n个用户请求。因而,event的并发数量可达到m*n个,同时,因为event的子进程为一对多,节省大量CPU进程切换上下文的时间,也没有了linux系统的1024个进程限制,所以,event模型是三种模型中效率最高的一种。可以突破10K的限制(即并发数1W),对海量的系统特别适用
3、源码编译安装LAMP环境(基于wordpress程序),并写出详细的安装、配置、测试过程。
安装编译环境:
# yum -y groupinstall "Development Tools" "Server Platform Development"
(1)安装httpd
# yum -y install pcre-devel apr-devel apr-util-devel openssl-devel
# tar xf httpd-2.4.23.tar.bz2
# cd httpd-2.4.23
# ./configure --prefix=/usr/local/apache24 --sysconfdir=/etc/apache24 --enable-so --enable-ssl --enable-rewrite --with-zlib
--with-pcre --with-apr=/usr --with-apr-util=/usr --enable-modules=most --enable-mpms-shared=all --with-mpm=prefork
# make && make install
# vim /etc/profile.d/httpd.sh
添加
export PATH=/usr/local/apache24/bin:$PATH
# . /etc/profile.d/httpd.sh
# ln -sv /usr/local/apache24/include /usr/include/httpd
# apachectl start
(2)安装mairadb通用二进制格式
# yum install ncurses-devel cmake –y
# useradd -r mysql
# mkdir -pv /mydata/data
# chown -R mysql:mysql /mydata/data
# tar xf mariadb-5.5.54.tar.gz -C /usr/local
# cd /usr/local
# ln -sv mariadb-5.5.54 mysql
# cd /usr/local/mysql
# chown -R root:mysql ./*
# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/mydata/data -DMYSQL_USER=mysql -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci
# make && make install
cp support-files/my-large.cnf /etc/my.cnf
# chkconfig --add mysqld
# vim /etc/mysql/my.cnf,在[mysqld]段添加如下三个选项:
datadir=/mydata/data
innodb_file_per_table = ON
skip_name_resolve = ON
# scripts/mysql_install_db --user=mysql --datadir=/mydata/data
#cp support-files/mysql.server /etc/init.d/mysqld
# chkconfig --add mysqld
# chmod +x /etc/init.d/mysqld
# service mysqld start
测试配置文件语法:
# service mysqld configtest
# service mysqld start
# vim /etc/profile.d/mysql.sh
export PATH=/usr/local/mysql/bin:$PATH
# . /etc/profile.d/mysql.sh
# vim /etc/ld.so.conf.d/mysql.conf
/usr/local/mysql/lib
# ldconfig
# ln -sv /usr/local/mysql/include /usr/include/mysql
三、编译安装php-5.4.26
1.安装编译php时需要的包
[root@web ~]# yum install bzip2-devel libmcrypt-devel libxml2-devel -y
2.编译安装php
[root@web ~]# tar xf php-5.4.26.tar.bz2
[root@web ~]# cd php-5.4.26/
[root@web php-5.4.26]# ./configure --prefix=/usr/local/php --with-mysql=/usr/local/mysql
--with-openssl --with-mysqli=/usr/local/mysql/bin/mysql_config
--enable-mbstring --with-freetype-dir --with-jpeg-dir
--with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml
--enable-sockets --with-apxs2=/usr/local/apache/bin/apxs
--with-mcrypt --with-config-file-path=/etc
--with-config-file-scan-dir=/etc/php.d --with-bz2
--enable-maintainer-zts
说明:
(1)这里为了支持apache的worker或event这两个MPM,编译时使用了--enable-maintainer-zts选项。
(2)如果使用PHP5.3以上版本,为了链接MySQL数据库,可以指定mysqlnd,这样在本机就不需要先安装MySQL
或MySQL开发包了。mysqlnd从php 5.3开始可用,可以编译时绑定到它(而不用和具体的MySQL客户端库
绑定形成依赖),但从PHP 5.4开始它就是默认设置了。
[root@web php-5.4.26]# ./configure --with-mysql=mysqlnd --with-pdo-mysql=mysqlnd
--with-mysqli=mysqlnd
[root@web php-5.4.26]# make
[root@web php-5.4.26]# make test
[root@web php-5.4.26]# make intall
3.为php提供配置文件:
[root@web php-5.4.26]# cp php.ini-production /etc/php.ini
4.编辑apache配置文件httpd.conf,以apache支持php
[root@web php-5.4.26]# vim /etc/httpd/httpd.conf
添加如下二行
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
定位至DirectoryIndex index.html
修改为:
DirectoryIndex index.php index.html
5.重启httpd24服务
[root@web php-5.4.26]# service httpd24 restart
四、编译安装wordpress
1.解压wordpress包到/usr/local/appache/htdocs
[root@web ~]# tar -xf wordpress-4.7-zh_CN.tar.gz -C /usr/local/apache/htdocs
2.创建数据库并授权登录用户
[root@web ~]# mysql
mysql> create database wordpress;
mysql> grant all on wordpress.* to wpuser@'192.168.%.%' identified by 'password';
3.编辑wordpress的配置文件
# vim /etc/httpd/httpd.conf
修改
DocumentRoot "/usr/local/apache/htdocs"
<Directory "/usr/local/apache/">
# cd /usr/local/apache/htdocs/wordpress/
#cp wp-config-sample.php wp-config.php
# vim wp-config.php
/** WordPress数据库的名称 */
define('DB_NAME', 'wordpress');
/** MySQL数据库用户名 */
define('DB_USER', 'wpuser');
/** MySQL数据库密码 */
define('DB_PASSWORD', 'password');
/** MySQL主机 */
define('DB_HOST', '192.168.171.136');
4.在浏览器中访问并配置
http://192.168.171.136/wordpress/
4、建立httpd服务器(基于编译的方式进行),要求:
提供两个基于名称的虚拟主机:
(a)www1.stuX.com,页面文件目录为/web/vhosts/www1;错误日志为/var/log/httpd/www1.err,访问日志为/var/log/httpd/www1.access;
(b)www2.stuX.com,页面文件目录为/web/vhosts/www2;错误日志为/var/log/httpd/www2.err,访问日志为/var/log/httpd/www2.access;
(c)为两个虚拟主机建立各自的主页文件index.html,内容分别为其对应的主机名;
(d)通过www1.stuX.com/server-status输出httpd工作状态相关信息,且只允许提供帐号密码才能访问(status:status);
# mkdir -pv /web/vhosts/{www1,www2}
# mkdir /var/log/httpd
# echo "<h1>www1.stuX.com</h1>" > /web/vhosts/www1/index.html
# echo "<h1>www2.stuX.com</h1>" > /web/vhosts/www2/index.html
# vim /etc/apache/httpd.conf
注释中心主机 #DocumentRoot "/usr/local/apache/htdocs"
引用虚拟主机配置文件:Include /etc/apache/extra/httpd-vhosts.conf
# vim /etc/apache/extra/httpd-vhosts.conf
注释默认配置,添加如下两个虚拟主机:
<VirtualHost *:80>
ServerName www1.stuX.com
DocumentRoot "/web/vhosts/www1"
ErrorLog "/var/log/httpd/www1.err"
CustomLog "/var/log/httpd/www1.access" combined
<Directory "/web/vhosts/www1">
Options None
AllowOverride None
Require all granted
</Directory>
<Location /server-status>
SetHandler server-status
AuthType Basic
AuthName "server-status"
AuthUserFile "/etc/apache/.status_pwd"
Require valid-user
</Location>
</VirtualHost>
<VirtualHost *:80>
ServerName www2.stuX.com
DocumentRoot "/web/vhosts/www2"
ErrorLog "/var/log/httpd/www2.err"
CustomLog "/var/log/httpd/www2.access" combined
<Directory "/web/vhosts/www2">
Options None
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
# htpasswd -c /etc/apache/.status_pwd status
# apachectl -t
# apachectl restart
测试主机:
# vim /etc/hosts
192.168.171.136 www1.stuX.com www2.stuX.com
在浏览器进行访问测试:
http://www1.stuX.com
http://www2.stuX.com
5、为第4题中的第2个虚拟主机提供https服务,使得用户可以通过https安全的访问此web站点;
(1)要求使用证书认证,证书中要求使用的国家(CN)、州(HA)、城市(ZZ)和组织(MageEdu);
(2)设置部门为Ops,主机名为www2.stuX.com,邮件为admin@stuX.com;
构建私有CA颁发SSL证书
# (umask 077; openssl genrsa -out /etc/pki/CA/private/cakey.pem 4096)
# openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.pem -days 3650
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:HA
Locality Name (eg, city) [Default City]:ZZ
Organization Name (eg, company) [Default Company Ltd]:MageEdu
Organizational Unit Name (eg, section) []:Ops
Common Name (eg, your name or your server's hostname) []:www2.stuX.com
Email Address []:admin@stuX.com
# mkdir -pv /etc/pki/CA/{certs,crl,newcerts}
# touch /etc/pki/CA/{serial,index.txt}
# echo 01 > /etc/pki/CA/serial
在请求主机生成私钥,并向CA申请签署证书
# (umask 077; openssl genrsa -out /etc/apache/ssl/httpd.key 2048)
# openssl req -new -key /etc/apache/ssl/httpd.key -out /etc/apache/ssl/httpd.csr -days 365
CA签署证书
# openssl ca -in /etc/apache/ssl/httpd.csr -out /etc/pki/CA/certs/httpd.crt
# cp /etc/pki/CA/certs/httpd.crt /etc/apache/ssl/
# vim /etc/apache/httpd.conf
引用SSL配置文件:Include /etc/apache/extra/httpd-ssl.conf
加载如下模块:
LoadModule ssl_module modules/mod_ssl.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
# vim /etc/apache/extra/httpd-ssl.conf
<VirtualHost _default_:443>
DocumentRoot "/web/vhosts/www2"
ServerName www2.stuX.com
ErrorLog "/var/log/httpd/www2.ssl.err"
TransferLog "/var/log/httpd/www2.ssl.access"
<Directory "/web/vhosts/www2">
Options None
AllowOverride None
Require all granted
</Directory>
SSLEngine on
SSLCertificateFile "/etc/apache/ssl/httpd.crt"
SSLCertificateKeyFile "/etc/apache/ssl/httpd.key"
</VirtualHost>
# apachectl -t
# apachectl restart
在浏览器进行访问测试:
https://www2.stuX.com
6、在LAMP架构中,请分别以php编译成httpd模块形式和php以fpm工作为独立守护进程的方式来支持httpd,列出详细的过程。"
(1)php编译成httpd模块的形式在第3题中已实现。
(2)php编译成以fpm形式工作为独立守护进程的详细步骤如下:
注意:首先配置好EPEL源
安装编译环境:
# yum -y groupinstall "Development Tools" "Server Platform Development"
编译安装php-fpm:
# yum -y install libxml2-devel libmcrypt-devel bzip2-devel
# tar xf php-5.4.45.tar.gz
# cd php-5.4.45
# ./configure --prefix=/usr/local/phpfpm --with-mysql=/usr/local/mysql --with-openssl --enable-mbstring --with-png-dir
--with-mysqli=/usr/local/mysql/bin/mysql_config --with-jpeg-dir --with-freetype-dir --with-zlib --with-libxml-dir=/usr --enable-xml --enable-sockets --with-mcrypt --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-bz2 --enable-fpm
# make && make install
# cp php-5.4.45/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
# chmod +x /etc/init.d/php-fpm
# chkconfig --add php-fpm
# cp /usr/local/phpfpm/etc/php-fpm.conf.default /usr/local/phpfpm/etc/php-fpm.conf
# vim /usr/local/phpfpm/etc/php-fpm.conf
pid = run/php-fpm.pid
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
# service php-fpm start
# ss -tnl
若tcp的9000端口处于监听状态,表明php-fpm启动成功。
# vim /etc/apache/httpd.conf
DirectoryIndex index.php index.html
加载如下模块:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
# vim /etc/apache/extra/httpd-vhosts.conf
<VirtualHost *:80>
ServerName 192.168.0.200
DocumentRoot "/usr/local/apache/htdocs"
ErrorLog "/usr/local/apache/logs/httpd_fpm.error"
CustomLog "/usr/local/apache/logs/httpd_fpm.access" combined
ProxyRequests Off
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/usr/local/apache/htdocs/$1
<Directory "/usr/local/apache/htdocs">
Options None
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
# apachectl -t
# apachectl restart
在浏览器进行访问测试:
http://192.168.0.200/phpinfo.php
若Server API为FPM/FastCGI,表明php-fpm安装成功。
原创文章,作者:victorli88,如若转载,请注明出处:http://www.178linux.com/70741


评论列表(1条)
前面的理论题都是面试经常问到,希望你能牢记~~~加油!!!