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.www58058.com/70741
前面的理論題都是面試經常問到,希望你能牢記~~~加油?。?!