一、請描述一次完整的http請求處理過程
(1).建立或處理連接:接收請求或拒絕請求;
(2).接收請求:接收來自于網絡上的主機請求報文中對某特定資源的一次請求的過程;
接收請求的模型:
并發訪問響應模型:
單進程I/O模型:啟動一個進程處理用戶請求;這意味著,一次只能處理一個請求,多個請求被串行響應;
多進程I/O結構:并行啟動多個進程,每個進程響應一個請求;
復用的I/O結構:一個進程響應n個請求;
多線程模式:一個進程生成n個線程,一個線程處理一個請求;
事件驅動(event-driven):一個進程直接n個請求;
復用的多進程I/O結構:啟動多個(m)個進程,每個進程生成(n)個線程;
響應的請求的數量:m*n
(3).處理請求:對請求報文進行解析,獲取客戶端請求的資源及請求方法等相關信息;
處理請求:分析請求報文的http請求報文首部http協議:http請求報文首部 http響應報文首部請求報文首部的格式。
<method><URL><VERSION>
HEADERS:(name:value)
<request body>
(4).訪問資源:獲取請求報文中請求的資源;
訪問資源:獲取請求報文中請求的資源。web服務器,即存放了web資源的主機,負責向請求者提供對方請求的靜態資源,或動態資源運行生成的結果;這些資源通常應該放置于本地文件系統某路徑下;此路徑稱為DocRoot
(5).構建響應報文:
(6).發送響應報文:
(7).記錄日志:
二、httpd所支持的處理模型有哪些,他們的分別使用于哪些環境
MPM:Multipath processing Modules (多路處理模塊)
(1).prefork:多進程模型,每個進程響應一個請求;
一個主進程:負責生成子進程及回收子進程;負責創建套接字;負責接收請求,并將其派發給某子進程進行處理;
n個子進程:每個子進程處理一個請求;
工作模型:會預先生成幾個空閑進程,隨時等待用于響應用戶請求;最大空閑和最小空閑;
(2).worker:多進程多線程模型,每線程處理一個用戶請求;
一個主進程:負責生成子進程;負責創建套接字;負責接收請求,并將其派發給某子進程進行處理;
多個子進程:每個子進程負責生成多個線程;
每個線程:負責響應用戶請求;
并發響應數量:m*n
m:子進程數量
n:每個子進程所能創建的最大線程數量;
(3).event:事件驅動模型,多進程模型,每個進程響應多個請求;
一個主進程 :負責生成子進程;負責創建套接字;負責接收請求,并將其派發給某子進程進行處理;
子進程:基于事件驅動機制直接響應多個請求;
httpd-2.2: 仍為測試使用模型;
httpd-2.4:event可生產環境中使用;
三、源碼編譯安裝LAMP環境(基于wordpress程序),并寫出詳細的安裝、配置、測試過程。
首先安裝開發環境:
yum?groupinstall?“Development?Tools”?“Server?Platform?Development”?-y
1.編譯安裝Apache
解決依賴關系
1).編譯安裝apr
tar?xf?apr-1.5.0.tar.bz2
cd?apr-1.5.0
./configure?–prefix=/usr/local/apr
make?&&?make?install
2).編譯安裝apr-util
tar?xf?apr-util-1.5.3.tar.bz2
cd?apr-util-1.5.3
./configure?–prefix=/usr/local/apr-util?–with-apr=/usr/local/apr
make?&&?make?install
3).httpd-2.4.9編譯過程也要依賴于pcre-devel軟件包,需要事先安裝。
yum?install?-y?pcre-devel
tar?xf?httpd-2.4.9.tar.bz2
cd?httpd-2.4.9
./configure?–prefix=/usr/local/apache?–sysconfdir=/etc/httpd24?–enable-so?–enable-ssl?–enable-cgi?–enable-rewrite?–with-zlib?–with-pcre?–with-apr=/usr/local/apr?–with-apr-util=/usr/local/apr-util?–enable-modules=most?–enable-mpms-shared=all?–with-mpm=prefork
make?&&?make?install
提供SysV服務腳本/etc/rc.d/init.d/httpd,內容如下:
#!/bin/bash
#
#?httpdStartup?script?for?the?Apache?HTTP?Server
#
#?chkconfig:?–?85?15
#?description:?Apache?is?a?World?Wide?Web?server.??It?is?used?to?serve
#HTML?files?and?CGI.
#?processname:?httpd
#?config:?/etc/httpd/conf/httpd.conf
#?config:?/etc/sysconfig/httpd
#?pidfile:?/var/run/httpd.pid
#?Source?function?library.
.?/etc/rc.d/init.d/functions
if?[?-f?/etc/sysconfig/httpd?];?then
.?/etc/sysconfig/httpd
fi
#?Start?httpd?in?the?C?locale?by?default.
HTTPD_LANG=${HTTPD_LANG-“C”}
#?This?will?prevent?initlog?from?swallowing?up?a?pass-phrase?prompt?if
#?mod_ssl?needs?a?pass-phrase?from?the?user.
INITLOG_ARGS=””
#?Set?HTTPD=/usr/sbin/httpd.worker?in?/etc/sysconfig/httpd?to?use?a?server
#?with?the?thread-based?“worker”?MPM;?BE?WARNED?that?some?modules?may?not
#?work?correctly?with?a?thread-based?MPM;?notably?PHP?will?refuse?to?start.
#?Path?to?the?apachectl?script,?server?binary,?and?short-form?for?messages.
apachectl=/usr/local/apache/bin/apachectl
httpd=${HTTPD-/usr/local/apache/bin/httpd}
prog=httpd
pidfile=${PIDFILE-/var/run/httpd.pid}
lockfile=${LOCKFILE-/var/lock/subsys/httpd}
RETVAL=0
start()?{
echo?-n?$”Starting?$prog:?”
LANG=$HTTPD_LANG?daemon?–pidfile=${pidfile}?$httpd?$OPTIONS
RETVAL=$?
echo
[?$RETVAL?=?0?]?&&?touch?${lockfile}
return?$RETVAL
}
stop()?{
echo?-n?$”Stopping?$prog:?”
killproc?-p?${pidfile}?-d?10?$httpd
RETVAL=$?
echo
[?$RETVAL?=?0?]?&&?rm?-f?${lockfile}?${pidfile}
}
reload()?{
echo?-n?$”Reloading?$prog:?”
if?!?LANG=$HTTPD_LANG?$httpd?$OPTIONS?-t?>&/dev/null;?then
RETVAL=$?
echo?$”not?reloading?due?to?configuration?syntax?error”
failure?$”not?reloading?$httpd?due?to?configuration?syntax?error”
else
killproc?-p?${pidfile}?$httpd?-HUP
RETVAL=$?
fi
echo
}
#?See?how?we?were?called.
case?“$1″?in
start)
start
;;
stop)
stop
;;
status)
status?-p?${pidfile}?$httpd
RETVAL=$?
;;
restart)
stop
start
;;
condrestart)
if?[?-f?${pidfile}?]?;?then
stop
start
fi
;;
reload)
reload
;;
graceful|help|configtest|fullstatus)
$apachectl?$@
RETVAL=$?
;;
*)
echo?$”Usage:?$prog?{start|stop|restart|condrestart|reload|status|fullstatus|graceful|help|configtest}”
exit?1
esac
exit?$RETVAL
由于腳本中涉及到pid的設置,在/etc/httpd24/httpd.conf主配置文件中添加
PidFile??“/var/run/httpd.pid”
給腳本執行權限
chmod?+x?/etc/rc.d/init.d/httpd
添加服務到開機啟動里
chkconfig??–add?httpd
chkconfig?httpd?on
完成操作后就可以使用service?httpd?start/stop?等命令來起停服務。
2.編譯安裝MySQL
添加mysql用戶
groupadd?–r?mysql
useradd?–g?mysql?–r?–s?/sbin/nologin?–M?–d?/mydata/data?mysql
創建數據存放目錄?/mydata/data
mkdir?–pv?/mydata/data
修改目錄所屬主及所屬組
chown?–R?mysql:mysql?/mydata/data
1). 安裝并初始化mysql-5.5.33
tar?xf?mysql-5.5.33-linux2.6-x86_64-C?/usr/local
cd?/usr/local/
ln?-sv?mysql-5.5.33-linux2.6-x86_64??mysql
cd?mysql
chown?-R?root.mysql?.
2).執行mysql初始化:
/usr/local/mysql/scripts/mysql_install_db?–datadir=/mydata/data?–user=mysql
為mysql提供主配置文件
mkdir?/etc/mysql
cd?/usr/local/mysql
cp?support-files/my-large.cnf??/etc/mysql/my.cnf
并修改此文件中thread_concurrency的值為你的CPU個數乘以2,比如這里使用如下行:
thread_concurrency?=?2
另外還需要添加如下行指定mysql數據文件的存放位置:
datadir?=?/mydata/data
添加
?innodb_file_per_table?=?on???skip_name_resolve?=?on
3). 為mysql提供sysv服務腳本
cd?/usr/local/mysql
cp?support-files/mysql.server??/etc/rc.d/init.d/mysqld
chmod?+x?/etc/rc.d/init.d/mysqld
添加至服務列表:
chkconfig?–add?mysqld
chkconfig?mysqld?on
3.??編譯安裝php-5.4.26
解決依賴關系
yum?-y?install?bzip2-devel?libmcrypt-devel?libxml2-devel
1). 編譯安裝php-5.4.26
tar?xf?php-5.4.26.tar.bz2
cd?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
make?&&?make?install
為php提供配置文件:
cp?php.ini-production?/etc/php.ini
2). 編輯apache配置文件/etc/httpd24/httpd.conf,以使apache支持php
a、添加如下二行
AddType?application/x-httpd-php??.php
AddType?application/x-httpd-php-source??.phps
b、定位至DirectoryIndex?index.html
修改為:
DirectoryIndex??index.php??index.html
測試頁面:在/usr/local/apache/htdoc/下添加index.php頁面
<?php
phpinfo();
?>
4.wordpress程序的安裝
解壓WordPress到/usr/local/apache/htdoc/wordpress
unzip?wordpress-3.3.1-zh_CN.zip?–d?/usr/local/apache/htdoc/wordpress
啟動msyql服務,進入mysql
systemctl start httpd.service
cd /usr/local/mysql/bin
./mysql -uroot -p
新建數據庫wordpress
create?database?wordpress;
修改root用戶的密碼
進入mysql數據庫,use?mysql;
修改root密碼,update?user?set?password=PASSWORD(‘magedu’)?where?User=’root’;
重啟msqld服務
在瀏覽器中輸入http://192.168.4.240/wordpress
根據提示填寫數據庫名稱,用戶名,密碼。完成后根據提示創建wp-config.php文件。設置admin的密碼等。完成WordPress的安裝。
四、建立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);
配置文件位置
首先要在主配置文件中找到Include?/etc/httpd24/extra/httpd-vhosts.conf,去掉其前面的注釋,或者復制一行,使得配置文件能讀取到vhosts.conf文件。
訪問控制命令:
htpasswd?–c?–m?/etc/httpd24/extra/.htpasswd?status
/etc/httpd24/extra/httpd-vhosts.conf
DocumentRoot?“/web/vhosts/www1”
ServerName?www1.stuX.com
ErrorLog?“/var/log/httpd/www1.err”
CustomLog?“/var/log/httpd/www1.access”?common
SetHandler?server-status
Order?deny,allow
Deny?from?all
Allow?from?192.168.194
Options?None
AllowOverride?None
AuthType?Basic
AuthName?“Warring~~~~~~~~~~~”
AuthUserFile?“/etc/httpd24/extra/.htpasswd”
Require?user?status
DocumentRoot?“/web/vhosts/www2”
ServerName?www2.stuX.com
ErrorLog?“/var/log/httpd/www2.err”
CustomLog?“/var/log/httpd/www2.access”?common
五、為第4題中的第2個虛擬主機提供https服務,使得用戶可以通過https安全的訪問此web站點;
(1)要求使用證書認證,證書中要求使用的國家(CN)、州(HA)、城市(ZZ)和組織(MageEdu);
(2)設置部門為Ops,主機名為www2.stuX.com,郵件為admin@stuX.com;
在主配置文件/etc/httpd24/httpd.conf中找到Include?/etc/httpd24/extra/httpd-ssl.conf,取消注釋或者復制一行。
相關的模塊LoadModule?ssl_module?modules/mod_ssl.so取消注釋
配置文件/etc/httpd24/extra/httpd-ssl.conf
修改配置文件
DocumentRoot?“/web/vhosts/www2”
ServerName?www2.stuX.com:443
SSLCertificateKeyFile?“/etc/httpd24/ssl/httpd.key”
SSLCertificateFile?“/etc/httpd24/ssl/www2.httpd.crt”
在/etc/httpd24/?創建目錄ssl
mkdir?/etc/httpd24/ssl
生成證書請求
umask?077;?openssl?genrsa?-out?/etc/httpd24/ssl/httpd.key?2048
openssl?req?-new?-key?/etc/httpd24/ssl/httpd.key?-days?365?-out?/etc/httpd24/ssl/httpd.csr
openssl?req?-new?-key?/etc/httpd24/ssl/httpd.key?-days?365?-out?/etc/httpd24/ssl/httpd.csr
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]:MagEdu
Organizational?Unit?Name?(eg,?section)?[]:Ops
Common?Name?(eg,?your?name?or?your?server’s?hostname)?[]:www2.stuX.com
Email?Address?[]:admin@stuX.com
Please?enter?the?following?‘extra’?attributes
to?be?sent?with?your?certificate?request
A?challenge?password?[]:
An?optional?company?name?[]:
將請求文件發送給CA,在CA服務器上生成www2.httpd.crt,并把證書發還回來
六、在LAMP架構中,請分別以php編譯成httpd模塊形式和php以fpm工作為獨立守護進程的方式來支持httpd,列出詳細的過程。
php以fpm方式工作的LAMP架構,編譯過程如下:
首先安裝開發環境:
yum?groupinstall?“Development?Tools”?“Server?Platform?Development”?-y
1.??編譯安裝Apache
1). 編譯安裝apr,apr-util
tar?xf?apr-1.5.0.tar.bz2
cd?apr-1.5.0
./configure?–prefix=/usr/local/apr
make?&&?make?install
tar?xf?apr-util-1.5.3.tar.bz2
cd?apr-util-1.5.3
./configure?–prefix=/usr/local/apr-util?–with-apr=/usr/local/apr
make?&&?make?install
2).編譯安裝Apache
tar?xf?httpd-2.4.9.tar.bz2
cd?httpd-2.4.9
./configure?–prefix=/usr/local/apache?–sysconfdir=/etc/httpd24?–enable-so?–enable-ssl?–enable-cgi?–enable-rewrite?–with-zlib?–with-pcre?–with-apr=/usr/local/apr?–with-apr-util=/usr/local/apr-util?–enable-modules=most?–enable-mpms-shared=all?–with-mpm=prefork
#?make?&&?make?install
3).提供SysV服務腳本/etc/rc.d/init.d/httpd
#!/bin/bash
#
#?httpdStartup?script?for?the?Apache?HTTP?Server
#
#?chkconfig:?–?85?15
#?description:?Apache?is?a?World?Wide?Web?server.??It?is?used?to?serve?\
#HTML?files?and?CGI.
#?processname:?httpd
#?config:?/etc/httpd/conf/httpd.conf
#?config:?/etc/sysconfig/httpd
#?pidfile:?/var/run/httpd.pid
#?Source?function?library.
.?/etc/rc.d/init.d/functions
if?[?-f?/etc/sysconfig/httpd?];?then
.?/etc/sysconfig/httpd
fi
#?Start?httpd?in?the?C?locale?by?default.
HTTPD_LANG=${HTTPD_LANG-“C”}
#?This?will?prevent?initlog?from?swallowing?up?a?pass-phrase?prompt?if
#?mod_ssl?needs?a?pass-phrase?from?the?user.
INITLOG_ARGS=””
#?Set?HTTPD=/usr/sbin/httpd.worker?in?/etc/sysconfig/httpd?to?use?a?server
#?with?the?thread-based?“worker”?MPM;?BE?WARNED?that?some?modules?may?not
#?work?correctly?with?a?thread-based?MPM;?notably?PHP?will?refuse?to?start.
#?Path?to?the?apachectl?script,?server?binary,?and?short-form?for?messages.
apachectl=/usr/local/apache/bin/apachectl
httpd=${HTTPD-/usr/local/apache/bin/httpd}
prog=httpd
pidfile=${PIDFILE-/var/run/httpd.pid}
lockfile=${LOCKFILE-/var/lock/subsys/httpd}
RETVAL=0
start()?{
echo?-n?$”Starting?$prog:?”
LANG=$HTTPD_LANG?daemon?–pidfile=${pidfile}?$httpd?$OPTIONS
RETVAL=$?
echo
[?$RETVAL?=?0?]?&&?touch?${lockfile}
return?$RETVAL
}
stop()?{
echo?-n?$”Stopping?$prog:?”
killproc?-p?${pidfile}?-d?10?$httpd
RETVAL=$?
echo
[?$RETVAL?=?0?]?&&?rm?-f?${lockfile}?${pidfile}
}
reload()?{
echo?-n?$”Reloading?$prog:?”
if?!?LANG=$HTTPD_LANG?$httpd?$OPTIONS?-t?>&/dev/null;?then
RETVAL=$?
echo?$”not?reloading?due?to?configuration?syntax?error”
failure?$”not?reloading?$httpd?due?to?configuration?syntax?error”
else
killproc?-p?${pidfile}?$httpd?-HUP
RETVAL=$?
fi
echo
}
#?See?how?we?were?called.
case?“$1″?in
start)
start
;;
stop)
stop
;;
status)
status?-p?${pidfile}?$httpd
RETVAL=$?
;;
restart)
stop
start
;;
condrestart)
if?[?-f?${pidfile}?]?;?then
stop
start
fi
;;
reload)
reload
;;
graceful|help|configtest|fullstatus)
$apachectl?$@
RETVAL=$?
;;
*)
echo?$”Usage:?$prog?{start|stop|restart|condrestart|reload|status|fullstatus|graceful|help|configtest}”
exit?1
esac
exit?$RETVAL
給腳本執行權限
chmod?+x?/etc/rc.d/init.d/httpd
將服務加入運行級別
chkconfig?–add?httpd
修改httpd的主配置文件,設置其Pid文件的路徑
編輯/etc/httpd24/httpd.conf,添加如下行即可:
PidFile??“/var/run/httpd.pid”
2.??編譯安裝mysql
添加mysql用戶
groupadd?–r?mysql
useradd?–g?mysql?–r?–s?/sbin/nologin?–M?–d?/mydata/data?mysql
創建數據存放目錄?/mydata/data
mkdir?–pv?/mydata/data
修改目錄所屬主及所屬組
chown?–R?mysql:mysql?/mydata/data
1). 安裝并初始化mysql-5.5.33
tar?xf?mysql-5.5.33-linux2.6-x86_64-C?/usr/local
cd?/usr/local/
ln?-sv?mysql-5.5.33-linux2.6-x86_64??mysql
cd?mysql
chown?-R?root.mysql?.
2).執行mysql初始化:
/usr/local/mysql/scripts/mysql_install_db?–datadir=/mydata/data?–user=mysql
為mysql提供主配置文件
mkdir?/etc/mysql
cd?/usr/local/mysql
cp?support-files/my-large.cnf??/etc/mysq/my.cnf
并修改此文件中thread_concurrency的值為你的CPU個數乘以2,比如這里使用如下行:
thread_concurrency?=?2
另外還需要添加如下行指定mysql數據文件的存放位置:
datadir?=?/mydata/data
添加?innodb_file_per_table?=?on???skip_name_resolve?=?on
3). 為mysql提供sysv服務腳本
cd?/usr/local/mysql
cp?support-files/mysql.server??/etc/rc.d/init.d/mysqld
chmod?+x?/etc/rc.d/init.d/mysqld
添加至服務列表:
chkconfig?–add?mysqld
chkconfig?mysqld?on
3.??編譯安裝fpm方式工作的php
tar?xf?php-5.4.26.tar.bz2
cd?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?–enable-fpm?–with-mcrypt??–with-config-file-path=/etc?–with-config-file-scan-dir=/etc/php.d?–with-bz2
其中—enable-fpm??選項指定php為使用fpm工作方式
make
make?intall
1).配置php-fpm
為php-fpm提供SysV?init腳本,并將其添加至服務列表:
cp?sapi/fpm/init.d.php-fpm??/etc/rc.d/init.d/php-fpm
給腳本執行權限
chmod?+x?/etc/rc.d/init.d/php-fpm
將腳本加入運行級別并設置為開機啟動
chkconfig?–add?php-fpm
chkconfig?php-fpm?on
為php-fpm提供配置文件:
cp?/usr/local/php/etc/php-fpm.conf.default?/usr/local/php/etc/php-fpm.conf
編輯php-fpm的配置文件:
vim?/usr/local/php/etc/php-fpm.conf
配置fpm的相關選項為你所需要的值,并啟用pid文件(如下最后一行):
pm.max_children?=?50
pm.start_servers?=?5
pm.min_spare_servers?=?2
pm.max_spare_servers?=?8
pid?=?/usr/local/php/var/run/php-fpm.pid
接下來就可以啟動php-fpm了:
service?php-fpm?start
默認情況下,fpm監聽在127.0.0.1的9000端口
netstat?-nltp?|?grep?php-fpm
tcp0??0?127.0.0.1:9000??0.0.0.0:*???LISTEN??10720/php-fpm
2).配置httpd-2.4.9
啟用httpd的相關模塊
在Apache?httpd?2.4以后已經專門有一個模塊針對FastCGI的實現,此模塊為mod_proxy_fcgi.so,它其實是作為mod_proxy.so模塊的擴充,因此,這兩個模塊都要加載
LoadModule?proxy_module?modules/mod_proxy.so
LoadModule?proxy_fcgi_module?modules/mod_proxy_fcgi.so
編輯apache配置文件httpd.conf,讓apache能識別php格式的頁面,并支持php格式的主頁
#?vim?/etc/httpd/httpd.conf
a、添加如下二行
AddType?application/x-httpd-php??.php
AddType?application/x-httpd-php-source??.phps
b、定位至DirectoryIndex?index.html
修改為:
DirectoryIndex??index.php??index.html
c、添加php頁面重定向,使得php頁面的請求都轉到php-fpm服務
ProxyRequests?Off
ProxyPassMatch?^/(.*\.php)$?fcgi://127.0.0.1:9000/usr/local/apache/htdocs/$1
在/usr/local/apache/htdocs/index.php里添加測試代碼,測試php
<?php
phpinfo();
?>
本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/88356
寫的不錯,搭建過程很清晰,mysql連接那一步應該寫上。以后注意。