備註:php
2013年5月29,初稿(基於LEMP+FastCGI+Xcache構建web開發平臺),若有增長會作詳細說明html
2013年6月02,基於LEMP平臺添加nginx提供負載均衡、健康情況監測功能python
第一部分:《Nginx相關知識介紹,其內容參見搜索引擎及筆者理解》mysql
第二部分:《LEMP+FastCGI+Xcache編譯安裝案例》linux
第一部分:nginx
Nginx功能介紹:
web
Nginx是一個高性能的HTTP和反向代理服務器,自己是由一個核心和一系列的模塊組成, 核心主要用於提供Web Service的基本功能,以及Web和 Mail反向代理的功能;還用於啓用網絡協議,建立必要的運行時環境以及確保不一樣的模塊之間平滑地進行交互。 Nginx大多跟協議相關的功能和某應用特有的功能都是由nginx的模塊實現的。這些功能模塊大體能夠分爲事件模塊、階段性處理器、輸出過濾器、 變量處理器、協議、upstream和負載均衡幾個類別,這些共同組成了nginx的http功能。事件模塊主要用於提供OS獨立的(不一樣操做系統的事件機制有所不一樣) 事件通知機制如kqueue或epoll等。協議模塊則負責實現nginx經過http、tls/ssl、smtp、pop3以及imap與對應的客戶端創建會話。
Nginx的優點:sql
做爲web服務器:Nginx處理靜態文件、索引文件、自動索引的效率很是高 做爲代理服務器:Nginx能夠實現無緩存的反向代理加速,提升網站運行速度 做爲負載均衡:Nginx便可在內部直接支持Rails和PHP,也能夠支持HTTP代理服務器對外進行服務。 性能:Nginx是專門爲性能優化所開發,最重要的是效率,它採用poll模型,能夠支持更多的併發鏈接 穩定性:Nginx採用了分階段資源分配技術,使得CPU與內存的佔用率很是低 高可用:Nginx支持熱部署,啓動速度特別迅速,所以能夠再不間斷服務的狀況下,對版本進行升級。
Nginx模塊與工做:apache
Nginx是又內核和模塊組成,模塊一般分爲三大模塊: 核心模塊、基礎模塊、第三方模塊 核心模塊:HTTP模塊、EVENT模塊、MAIL模塊等 基礎模塊:HTTP Access模塊、HTTP FastCGI模塊、HTTP Proxy模塊、HTTP Rewrite模塊等 第三方模塊:HTTP Upstream Request Hash模塊、Notice模塊、HTTP Access Key模塊等 Nginx的模塊從功能上分爲三類: Handlers(處理器模塊):處理用戶請求,並進行輸出內容和修改headers信息等操做。 Filters(過濾器模塊):對處理器輸出的內容進行過濾,而後交給nginx,由Nginx響應請求。 Proxies(代理類模塊):主要與後端的服務進行交互,實現服務的代理和負載均衡等相關功能。 Nginx工做方式,默認工做在單工做進程模式下 單工做進程:除主進程外的一個進程,工做進程是單線程的 多工做進程:每一個工做進程都包含更多的線程。
Nginx配置文件主要分爲四個部分:vim
main(全局設置)、server(主機設置)、upstream(負載均衡服務器設置)、location(URL匹配特定位置的設置) main部分設置的指令將影響其餘全部設置; server部分的指令主要用於指定主機和端口; upstream指令主要用於負載均衡,設置一系列的後端服務器; location部分用於匹配網頁位置;
Nginx安裝環境及模塊的依賴性
準備開發環境"Development Tools" "Server Platform Deveopment" gzip模塊須要->zlib 庫 rewrite模塊須要->pcre 庫 ssl功能須要->openssl庫
Nginx目前可分爲三個版本:開發版、穩定版、歷史穩定版
開發板:開發版更新較快,包含新功能及修復Bug,同時可能會產生新的Bug。 穩定版:穩定版更新較慢,各類功能健全,可用於生產環境。 歷史版:歷史版是穩定版的彙總,不包含開發版的新功能。
案例構建
第一步:準備開發環境、編譯安裝pcre(支持HTTP Rewrite功能)及解決編譯安裝Nginx所依賴的軟件包
# yum groupinstall "Development Tools" "Server Platform Deveopment" -y # yum install openssl-devel pcre-devel # tar xf pcre-8.10.tar.gz # cd pcre-8.10 # ./configure # make && make install
第二步:源碼編譯安裝Nginx
◆ 首先添加用戶nginx,實現以之運行nginx服務進程:
# groupadd -r nginx # useradd -r -g nginx nginx
◆ 修改Nginx相關屬性信息及編譯安裝Nginx
# ./configure \ --prefix=/usr \ --sbin-path=/usr/sbin/nginx \ --conf-path=/etc/nginx/nginx.conf \ --error-log-path=/var/log/nginx/error.log \ --http-log-path=/var/log/nginx/access.log \ --pid-path=/var/run/nginx/nginx.pid \ --lock-path=/var/lock/nginx.lock \ --user=nginx \ --group=nginx \ --with-http_ssl_module \ --with-http_flv_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --http-client-body-temp-path=/var/tmp/nginx/client/ \ --http-proxy-temp-path=/var/tmp/nginx/proxy/ \ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \ --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \ --http-scgi-temp-path=/var/tmp/nginx/scgi \ --with-pcre # make && make install
第三步:爲Nginx提供編寫SysV 腳本
#!/bin/sh # # nginx - this script starts and stops the nginx daemon # # chkconfig: - 85 15 # description: Nginx is an HTTP(S) server, HTTP(S) reverse \ # proxy and IMAP/POP3 proxy server # processname: nginx # config: /etc/nginx/nginx.conf # config: /etc/sysconfig/nginx # pidfile: /var/run/nginx.pid # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ "$NETWORKING" = "no" ] && exit 0 nginx="/usr/sbin/nginx" prog=$(basename $nginx) NGINX_CONF_FILE="/etc/nginx/nginx.conf" [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx lockfile=/var/lock/subsys/nginx make_dirs() { # make required directories user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -` options=`$nginx -V 2>&1 | grep 'configure arguments:'` for opt in $options; do if [ `echo $opt | grep '.*-temp-path'` ]; then value=`echo $opt | cut -d "=" -f 2` if [ ! -d "$value" ]; then # echo "creating" $value mkdir -p $value && chown -R $user $value fi fi done } start() { [ -x $nginx ] || exit 5 [ -f $NGINX_CONF_FILE ] || exit 6 make_dirs echo -n $"Starting $prog: " daemon $nginx -c $NGINX_CONF_FILE retval=$? echo [ $retval -eq 0 ] && touch $lockfile return $retval } stop() { echo -n $"Stopping $prog: " killproc $prog -QUIT retval=$? echo [ $retval -eq 0 ] && rm -f $lockfile return $retval } restart() { configtest || return $? stop sleep 1 start } reload() { configtest || return $? echo -n $"Reloading $prog: " killproc $nginx -HUP RETVAL=$? echo } force_reload() { restart } configtest() { $nginx -t -c $NGINX_CONF_FILE } rh_status() { status $prog } rh_status_q() { rh_status >/dev/null 2>&1 } case "$1" in start) rh_status_q && exit 0 $1 ;; stop) rh_status_q || exit 0 $1 ;; restart|configtest) $1 ;; reload) rh_status_q || exit 7 $1 ;; force-reload) force_reload ;; status) rh_status ;; condrestart|try-restart) rh_status_q || exit 0 ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}" exit 2 esac
◆ 爲此腳本賦予執行權限、並添加至服務列表中,而後執行此腳本
# chmod +x /etc/rc.d/init.d/nginx # chkconfig --add nginx # chkconfig nginx on # service nginx restart # netstat -tpln
◆測試Nginx是否提供WEB服務(test:Windows:192.168.0.39)
第四步:安裝MySQL(這裏採用通用二進制安裝MySQL做爲演示)
◆ 建立邏輯卷用於存放MySQL安裝目錄
# fdisk /dev/sda [/dev/sda5(type:8e)] # reboot # pvcreate /dev/sda5 # vgcreate myvg /dev/sda5 # lvcreate -L 1G -n mydata myvg # lvscan ##查看邏輯卷相關信息 # mkfs.ext4 /dev/myvg/mydata
◆ 建立目錄用於掛載邏輯卷,用於存放mysql數據目錄並建立mysql組和mysql用戶,主要用於啓動、中止mysqld進程
# mkdir /mydata # vim /etc/fstab ##開機自動掛載 /dev/myvg/mydata /mydata ext4 default 0 0 # mount -a ##從新讀取/etc/fstab文件,並從新掛載 # mkdir /mydata/data # groupadd -g 3306 mysql # adduser -g 3306 -u 3306 -s /sbin/nologin mysql # chown -R mysql.mysql /mydata/data
◆ 下載mysql通用二進制,並解壓,修改屬主和數組,並完成初始化工做
# tar xf mysql-5.6.10-linux-glibc2.5-x86_64.tar.gz -C /usr/local/ # cd /usr/local # ln -sv mysql-5.6.10-linux-glibc2.5-x86_64 mysql # cd mysql # chown -R root.mysql ./* # scripts/mysql_install_db --user=mysql --datadir=/mydata/data/
◆ 將mysql本地變量改成環境變量
手動建立配置文件/etc/profile.d/mysql.sh,添加以下內容: export PATH=$PATH:/usr/local/mysql/bin # . /etc/profile.d/mysql.sh ##重讀配置文件,使之生效
◆ 爲mysql提供配置文件及SysV腳本
# pwd /usr/local/mysql # vim /etc/my.cnf ##添加以下內容 datadir = /mydata/data ##數據目錄 innodb_file_per_table = ON # cp support-files/mysql.server /etc/rc.d/init.d/mysqld # chkconfig --add mysqld # service mysqld restart # netstat -tupln | grep 3306
◆ 導出頭文件及庫文件,主要用於二次編譯開發所使用
導出頭文件 # ln -sv /usr/local/include /usr/include/mysql 導出庫文件,編輯配置文件: # vim /etc/ld.so.conf.d/mysql.conf添加以下內容 /usr/local/mysql/bin # ldconfig -v ##從新加載庫文件 導出man文檔,編輯配置文件: # vim /etc/man.config 添加以下內容 MANPATH /usr/local/mysql/man
◆ 鏈接mysql服務器,測試下:
第五步:源碼編輯安裝PHP,實現FastCGI
◆ 安裝環境:能夠到附件中下載安裝
若是想讓編譯的php支持mcrypt、mhash擴展和libevent,須要安裝如下軟件包 libmcrypt-2.5.8-9.el6.x86_64.rpm libmcrypt-devel-2.5.8-9.el6.x86_64.rpm mcrypt-2.6.8-3.el6.x86_64.rpm mhash-0.9.9.9-3.el6.x86_64.rpm mhash-devel-0.9.9.9-3.el6.x86_64.rpm
◆ 編譯安裝php
# tar xf php-5.4.13.tar.bz2 # cd php-5.4.13 # ./configure --prefix=/usr/local/php \ --with-mysql=/usr/local/mysql --with-openssl --enable-fpm \ --enable-sockets --enable-sysvshm --with-mysqli=/usr/local/mysql/bin/mysql_config \ --enable-mbstring --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib-dir \ --with-libxml-dir=/usr --enable-xml --with-mhash --with-mcrypt --with-config-file-path=/etc \ --with-config-file-scan-dir=/etc/php.d --with-bz2 --with-curl
注:因爲平臺環境不同,可能在修改屬性的時候,報各類各樣的錯誤,你們能夠根據錯誤信息進行排查,通常均可以解決。
筆者在安裝的時候提示須要依賴這些軟件包:libxml2-devel、zlib-devel、bzip2-devel、xml2-config、python-magic
◆ 下一步,編譯及編譯安裝
# make && make install
◆ 爲php提供主配置文件
# cp php.ini-production /etc/php.ini
◆ 爲php-fpm提供Sysv init腳本,並將其添加至服務列表:
# pwd /root/php-5.4.13 # 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的配置文件,配置fpm的相關選項爲你所須要的值,並啓用pid文件:
pm.max_children = 150 pm.start_servers = 8 pm.min_spare_servers = 5 pm.max_spare_servers = 10 pid = /usr/local/php/var/run/php-fpm.pid
◆ 啓動php-fpm進程,並使用以下命令來驗正(若是此命令輸出有中幾個php-fpm進程就說明啓動成功了):
# service php-fpm restart # ps aux | grep php-fpm
◆ 編輯/etc/nginx/nginx.conf,整合nginx和php,並啓用以下選項:
# vim /etc/nginx/nginx.conf ##啓用以下選項: location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; include fastcgi_params; }
◆ 編輯/etc/nginx/fastcgi_params,將其內容更改成以下內容:
編輯/etc/nginx/fastcgi_params,將其內容更改成以下內容: fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name;
◆ 並在所支持的主頁面格式中添加php格式的主頁:
location / { root /web/htdocs; index index.php index.html index.htm; }
◆ 當配置文件發生變化時,需從新載入nginx的配置文件
# service nginx reload
◆ 建立php測試頁面:
# mkdir /web/htdocs -pv # cat > /web/htdocs/index.php << EOF <h1>PHP Test Page</h1> <?php phpinfo(); ?>
◆ 經過window瀏覽器測試,看Nginx是否支持php頁面:
第六步:PHP與MySQL結合,測試MySQL是否提供服務(提供測試頁面)
◆ 設置MySQL的登陸root密碼及建立測試頁面:
# mysqladmin -u root -h localhost password 'mysql' -p ##設置MySQL的root用戶密碼 編輯/web/htdocs/index.php,修改以下內容: <h1>PHP Test Page</h1> <?php $conn=mysql_connect('localhost','root','mysql'); if ($conn) echo "<h2> Mysql Working....</h2>"; else echo "<h2> Mysql not Working...</h2>"; phpinfo(); ?>
◆ 當前mysql進程處於運行狀態,測試:
[root@master ~]# service mysqld status MySQL running (17494) [ OK ] [root@master ~]#
◆ 當前mysql進程處於中止狀態,測試:
[root@master mysql]# /etc/init.d/mysqld stop Shutting down MySQL.. [ OK ]
注:以上測試,說明MySQL正常運行,並且屬於工做狀態!!!
第七步:、安裝Xcache,爲php加速:
◆ 編譯安裝Xcache
# tar xf xcache-3.0.1.tar.bz2 # cd xcache-3.0.1 # /usr/local/php/bin/phpize # ./configure --enable-xcache --with-php-config=/usr/local/php/bin/php-config # make && make install
◆ 編輯php.ini,整合php和xcache
首先將xcache提供的樣例配置導入php.ini # mkdir /etc/php.d # cp xcache.ini /etc/php.d
◆ 編輯/etc/php.d/xcache.ini,找到extension開頭的行,修改成以下行:
extension = /usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/xcache.so
◆ 從新啓動php-fpm進程
# service php-fpm restart # chkconfig php-fpm on
◆ 測試
一:添加upstream模塊提供後端服務器負載均衡及健康情況監測:
環境:新增兩臺基於apache提供的web服務,基於安全因素、性能考慮,經過nginx反向代理upstream模塊實現負載均衡及SSL功能:
◆ 兩臺web程序服務器IP地址分配狀況:
webserver1 172.16.88.10/16 webserver2 172.16.88.11/16
◆ 安裝http軟件包提供測試頁面
注:前提兩臺web應用程序服務器提供ssh互信及並將主機名與IP地址對應關係,添加到/etc/hosts文件中,不然在啓動httpd進程會有警告信息。
webserver1 # yum install httpd -y # echo "webserver1.example.com" > /var/www/html/index.html # service httpd restart && chkconfig httpd on # ssh webserver2 'yum install httpd -y " # ssh webserver2 "echo "webserver2.example.com" > /var/www/html/index.html" # ssh webserver2 'service httpd restart && chkconfig httpd on'
◆ 修改nginx主配置文件,添加upstream模塊來提供後端web應用程序負載均衡
# vim /etc/nginx/nginx.conf upstream services { server 172.16.88.10 weight=1 max_fails=2 fail_timeout=2; server 172.16.88.11 weight=1 max_fails=2 fail_timeout=2; } server { location / { proxy_pass http://services/; } } # nginx -t && service nginx reload ##檢查語法並從新加載配置文件
◆ 相關知識點補充:
HTTP Upstream模塊中,能夠經過server指令來指定後端服務器的IP地址和端口,同時還能夠設定每一個後端服務器在負載均衡調度中的狀態。 down:表示當前的server暫時不參與負載均衡 backup:預留的備份機器。當其餘全部的非backup機器出現故障或者繁忙時,纔會請求backup機器,所以backup機器的壓力最輕。 max_fails:容許請求失敗的最大次數,默認爲1.當超過最大次數時,則返回proxy_next_upstream模塊定義的錯誤。 fail_timeout:當max_fails失敗後,所暫停服務器的時間。max_fails能夠和fail_timeout一塊兒使用。
◆ 測試(Windows-192.168.0.212):
在瀏覽器上輸入:http://172.16.88.88/,nginx代理服務器會將請求發日後端web服務器組中的某臺應用服務器,由後端的某臺應用服務器給予響應。 由於兩臺web服務在同一個組中,並且權值同樣,因此會平均提供web服務。當其中一臺web服務發生故障,另外一臺正常提供web服務,不影響用戶請求。當web服務從 故障狀態轉換爲正常狀態時,nginx會自動添加到組裏面,並提供服務。
◆ 模擬其中一臺web程序服務器宕機,而後在進行測試,咱們會發現只有一臺應用服務器提供web服務器
webserver1->172.16.88.10 # service httpd stop
◆ 若是兩臺web應用程序服務器都發生宕機,那該如何提供web響應頁面呢:
那麼只要添加一臺備用服務器,接收用戶請求並響應web錯誤頁面給用戶(這裏使用nginx代理服務器自己做爲backup服務器)
# vim /etc/nginx/nginx.conf 添加以下內容 server 127.0.0.1:8080 weight=1 backup; # nginx -t && service nginx reload
◆ 在niginx代理服務器上提供web服務器,並提供錯誤頁面信息
# mkdir /web/erro # echo "Erro Page Please Try Later" > /web/erro/index.html
◆ 模擬天台web應用程序服務器宕機並測試
webserver1# service httpd stop # ssh webserver2 'service httpd stop'