企業網站架構之Nginx詳解原理以及工作模組;原始碼Lnmp架構
Nginx詳解及lnmp環境架構
一、Nginx詳解以及優點
在當前網際網路環境下,一般高階的服務前端都採用nginx作為web前端,而更多的都是採用lnmp架構,真正的後端伺服器才會採用apache.
為什麼這麼做,要取決於nginx和apache兩者之間的優缺性.:
nginx與apache相比有以下優勢:在效能上,nginx佔用很少的系統資源,能支援更多的併發連結,達到更高的訪問率;在功能上,Nginx是優秀的代理伺服器和負載均衡器;在安裝配置上,簡單靈活。
nginx模組基本都是靜態編譯,同時對Fast-CGI支援比較好.在處理連結上,nginx支援epoll,而且體積小一般只有幾百K。
Nginx的優點有以下幾點:
1.作為Web伺服器,nginx處理靜態檔案、索引檔案以及自動索引效率非常高。
2.作為代理伺服器,Nginx可以實現無快取的反向代理加速,提高網站執行速度。
3.作為負載均衡伺服器,Nginx既可以在內部直接支援Rails和PHP,也可以支援HTTP代理伺服器,對外進行服務。同時支援簡單的容錯和利用演算法進行負載均衡。
4.在效能方面,Nginx是專門為效能優化而開發的,在實現上非常注重效率。它採用核心Poll模型,可以支援更多的併發連線,最大可以支援對50 000個併發連線數的響應,而且佔用很低的記憶體資源。
5.在穩定性方面,Nginx採取了分階段資源分配技術,使得對CPU與記憶體的佔用率非常低。Nginx官方表示Nginx保持10 000個沒有活動的連線,這些連線只佔2.5M記憶體,因此,類似DOS這樣的攻擊對Nginx來說基本上是沒有任何作用的。
6.在高可用性方面,Nginx支援熱部署,啟動速度特別迅速,因此可以在不間斷服務的情況下,對軟體版本或者配置進行升級,即使執行數月也無需重新啟動,幾乎可以做到7×24小時的不間斷執行。
二、Nginx工作原理以及工作模組介紹
Nginx的工作原理以及工作模組:
Nginx由核心和模組組成,其中,核心的設計非常微小和簡潔,完成的工作也非常簡單,僅僅通過查詢配置檔案將客戶端請求對映到一個location block(location是Nginx配置中的一個指令,用於URL匹配),而在這個location中所配置的每個指令將會啟動不同的模組去完成相應的工作。
Nginx的模組從結構上分為核心模組、基礎模組和第三方模組,HTTP模組、EVENT模組和MAIL模組等屬於核心模組,HTTP Access模組、HTTP FastCGI模組、HTTP Proxy模組和HTTP Rewrite模組屬於基本模組,而HTTP Upstream Request Hash模組、Notice模組和HTTP Access Key模組屬於第三方模組,使用者根據自己的需要開發的模組都屬於第三方模組。正是有了這麼多模組的支撐,Nginx的功能才會如此強大。
Nginx的模組從功能上分為三類,分別是:
- Handlers(處理器模組)。此類模組直接處理請求,並進行輸出內容和修改headers資訊等操作。handlers處理器模組一般只能有一個。
- Filters (過濾器模組)。此類模組主要對其他處理器模組輸出的內容進行修改操作,最後由Nginx 輸出。
- Proxies (代理類模組)。就是Nginx 的HTTP Upstream 之類的模組
這些模組主要與後端一些服務比如fastcgi 等操作互動,實現服務代理和負載均衡等功能。原理如下:
圖1:
在工作方式上,Nginx分為單工作程序和多工作程序兩種模式。
在單工作程序模式下,除主程序外,還有一個工作程序,工作程序是單執行緒的;
在多工作程序模式下,每個工作程序包含多個執行緒。
Nginx預設為單工作程序模式。
Nginx的模組直接被編譯進Nginx,因此屬於靜態編譯方式。啟動Nginx後,Nginx的模組被自動載入,不像在Apache一樣,首先將模組編譯為一個so檔案,然後在配置檔案中指定是否進行載入。在解析配置檔案時,Nginx的每個模組都有可能去處理某個請求,但是同一個處理請求只能由一個模組來完成。
如果由FastCGI或其它代理伺服器處理單頁中存在的多個SSI,則這項處理可以並行執行,而不需要相互等待。
三、Lnmp環境搭建
接下來就搭建一個LNMP環境:
所謂lnmp架構即為:linux +nginx +mysql+php/perl/python,本篇我們將只用linux(rhel6.5)+nginx+mysql+php構建企業web架構
環境:RHEL6.5
iptables -F
selinux is disabled
curl -I www.baidu.com 檢視百度web伺服器架構:
注意:在搭建lnmp環境前,必須檢測系統內部不能存在相關的軟體:(純淨搭建)
#rpm -qa | grep php
#rpm -qa | grep httpd
#rpm -qa | grep mysql
http://wiki.nginx.org 檢視中文支援頁面
##################################################################################
1.nginx原始碼編譯
nginx使用c編寫,因此在編譯的時候需要安裝gcc和make
#yum install make gcc -y
download:nginx-1.4.2.tar.gz mysql-5.5.12.tar.gz(www.mysql.org)
#tar zxf nginx-1.4.2.tar.gz
#cd nginx-1.4.2/src/core/
#vim nginx.h 修改版本號,名稱(每種版本都有bug)
#cd auto/cc/
#vim gcc
#CFLAGS="$CFLAGS -g" 註釋debug功能,可以減少編譯佔用資源
#./configure --prefix=/usr/local/lnmp/nginx --with-http_ssl_module --with-http_stub_status_module
注意:一般會缺少*-devel包
#make && make install
#vim /usr/local/lnmp/nginx/conf/nginx.conf nginx主配置檔案
use epoll; 高效模式
# ln -s /usr/local/lnmp/nginx/sbin/nginx /usr/sbin/ 便於之後的管理
#nginx -t 檢查nginx配置
#nginx -s reload 重新載入配置檔案
#netstat -antlp | grep 80 檢測nginx開放的80埠
nginx 預設會在/usr/bin下執行
訪問:http://nginx-server/ nginx的測試頁。
nginx的預設釋出目錄:/usr/local/lnmp/nginx/html
##################################################################################
2.mysql的編譯安裝
download:www.mysql.comcve網站
#tar zxf mysql-5.5.12.tar.gz
mysql會使用cmake進行原始碼編譯,過程中會顯示安裝進度,商業化的特色.
#yum install cmake -y
編譯選項儲存引擎可以選擇一個
#cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql #安裝目錄
-DMYSQL_DATADIR=/usr/local/mysql/data #資料庫存放目錄
-DMYSQL_UNIX_ADDR=/usr/local/mysql/data/mysql.sock #Unix socket 檔案路徑
-DWITH_MYISAM_STORAGE_ENGINE=1 #安裝myisam 儲存引擎
-DWITH_INNOBASE_STORAGE_ENGINE=1 #安裝 innodb 儲存引擎
-DWITH_ARCHIVE_STORAGE_ENGINE=1 #安裝 archive儲存引擎
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 #安裝 blackhole 儲存引擎
-DWITH_PARTITION_STORAGE_ENGINE=1 #安裝資料庫分割槽
-DENABLED_LOCAL_INFILE=1 #允許從本地匯入資料
-DWITH_READLINE=1 #快捷鍵功能
-DWITH_SSL=yes #支援SSL
-DDEFAULT_CHARSET=utf8 #使用utf8 字元
-DDEFAULT_COLLATION=utf8_general_ci #校驗字元
-DEXTRA_CHARSETS=all #安裝所有擴充套件字符集
-DMYSQL_TCP_PORT=3306 #MySQL 監聽埠(預設)
注意:myISAM引擎執行速度比較塊,時候查詢之類的inodb適合讀操作
1>開始編譯:
圖2
在編譯結束後會提示缺少相應的包依賴,順序安裝:(詳細看提示)
需要注意的是:每次編譯的時候會生成快取檔案,必須刪除後重新編譯
#rm -rf CmakeCache.txt
圖3
說明缺少gcc-c++
## yum install gcc-c++ -y
#make && make install
2>初始化mysql
useradd -M 不需要建立使用者家目錄,-d為新使用者建立家目錄,-s指定shell
# useradd -M -d /usr/local/lnmp/mysql/data/ -s /sbin/nologin mysql
指定base和data的目錄許可權和目錄選項唄
#cd /usr/local/lnmp/mysql
#chown -R mysql.mysql *
#cd support-files/
#file mysql.server 測試檔案(啟動指令碼)
# mv support-files/mysql.server /etc/init.d/mysqld
#cp my-medium.cnf /etc/my.cnf my-medium.cnf已經載入好了mysql的socket,根據記憶體選擇mysql的配置檔案
#cd /usr/local/lnmp/mysql/scripts
# ./mysql_install_db --user=mysql --basedir=/usr/local/lnmp/mysql/ --datadir=/usr/local/lnmp/mysql/data/
初始化mysql顯示兩個ok就說明好了啊
#vim .bash_profile 配置當前使用者環境
PATH=$PATH:$HOME/bin:/usr/local/lnmp/mysql/bin
#source .bash_profile 載入環境(只在當前使用者可用,區別/etc/profile)
#echo $PATH
#cd /usr/local/lnmp/mysql/
#chown root * -R
#chown mysql -R data/ 只允許data/目錄下的資料讓mysql修改
#/etc/init.d/mysqld restart 啟動mysqld開啟3306
#chkconfig mysqld on
#mysql登入驗證 mysql命令已經被載入到root使用者的環境裡了
# mysql_secure_installation 初始化mysql
###############################################################################
3.php原始碼編譯
1>先安裝php模組:
modules-download:ibiconv-1.13.1.tar.gz mhash-0.9.9.9.tar.bz2 libmcrypt-2.5.8.tar.bz2 mcrypt-2.6.8.tar.gz
#
tar zxf libiconv-1.13.1.tar.gz
cd libiconv-1.13.1
./configure --prefix=/usr/local/lnmp/modules/libiconv
make && make install
/usr/local/lnmp/modules/libiconv/lib lib庫檔案的位置
/usr/local/lnmp/modules/libiconv/include include標頭檔案位置
##
tar jxf libmcrypt-2.5.8.tar.bz2
cd libmcrypt-2.5.8
./configure --prefix=/usr/local/lnmp/modules/libmcrypt
make && make install
cd libltdl/ 支援ltdl
./configure --prefix=/usr/local/lnmp/modules/libmcrypt/ --enable-ltdl-install
make && make install
提示:
Libraries have been installed in:
/usr/local/lnmp/modules/libmcrypt/lib
###
tar jxf mhash-0.9.9.9.tar.bz2
cd mhash-0.9.9.9
./configure --prefix=/usr/local/lnmp/modules/mhash
make && make install
####
tar zxf mcrypt-2.6.8.tar.gz
cd mcrypt-2.6.8
./configure --prefix=/usr/local/lnmp/modules/mcrypt 依賴於前面的模組
提示不找不到libmcrypt
ln -s /usr/local/lnmp/modules/libmcrypt/include/* /usr/local/
ln -s /usr/local/lnmp/modules/libmcrypt/lib/* /usr/local/lib/
ln -s /usr/local/lnmp/modules/mhash/lib/* /usr/local/lib /
ln -s /usr/local/lnmp/modules/mhash/include/* /usr/local/include/
重新編譯
./configure --prefix=/usr/local/lnmp/modules/mcrypt --with-libmcrypt-prefix=/usr/local/lnmp/modules/libmcrypt/
make && make install
# cat /etc/ld.so.conf 開機自動載入動態連結庫檔案
include ld.so.conf.d/*.conf
/usr/local/lnmp/modules/libmcrypt/lib/
/usr/local/lnmp/modules/mhash/lib/
/usr/local/lib
將mhash的lib連結到/usr/local/lib/
mhash的include連結到/usr/local/include/
2>php原始碼編譯
#tar jxf php-5.4.12.tar.bz2
#cd php-5.4.12
#./configure --prefix=/usr/local/lnmp/php --with-config-file-path=/usr/local/lnmp/etc --with-mysql=/usr/local/lnmp/mysql/ --with-openssl --with-snmp --with-gd --with-zlib --with-curl --with-libxml-dir --with-png-dir --with-jpeg-dir --with-freetype-dir --without-pear --with-gettext --with-gmp --enable-inline-optimization --enable-soap --enable-ftp --enable-sockets --enable-mbstring --with-mysqli=/usr/local/lnmp/mysql/bin/mysql_config --enable-fpm --with-fpm-user=nginx --with-fpm-group=nginx (--with-libdir=lib64 --with-ldap --with-ldap-sasl)
libdir加上後會出現報錯libmysqlclient
snmp 進行網路監控 soap 支援動態 fpm 支援fast-CGI 效能更好
yum install libxml2-devel
yum install libcurl-devel -y
yum install libjpeg-devel -y (jpeg.h注意,一般要是提示缺少*.h就需要安裝devel包)
yum install libpng-devel -y
yum install freetype-devel -y
yum install gmp-devel -y
yum install openldap-devel -y
yum install net-snmp-devel -y
再次編譯會發現不能連結libmysqlclient under /usr/local/lnmp/mysql/.
# useradd -M -d /usr/local/lnmp/nginx/ -s /sbin/nologin nginx
# ./configure --prefix=/usr/local/lnmp/php --with-config-file-path=/usr/local/lnmp/etc --with-mysql=/usr/local/lnmp/mysql/ --with-openssl --with-snmp --with-gd --with-zlib --with-curl --with-libxml-dir --with-png-dir --with-jpeg-dir --with-freetype-dir --with-pear --with-gettext --with-gmp --enable-inline-optimization --enable-soap --enable-ftp --enable-sockets --enable-mbstring --with-mysqli=/usr/local/lnmp/mysql/bin/mysql_config --enable-fpm --with-fpm-user=nginx --with-fpm-group=nginx--with-mhash=/usr/local/lnmp/modules/mhash/ --with-mcrypt=/usr/local/lnmp/modules/libmcrypt
zend用來加快php執行程式碼的速度
# make ZEND_EXTRA_LIBS='-liconv' (有時候會提示找不到liconv)
#make install
3>.修改php配置
php的主配置檔案預設存在php的主目錄下
#cd php-5.4.12 去主目錄尋找主配置檔案
#cp php.ini-production /usr/local/lnmp/php/etc/php.ini 主配置檔案
#cd /root/php-5.4.12/sapi/fpm/
#cp init.d.php-fpm /etc/init.d/php-fpm 此檔案好像還不是指令碼
#vim /usr/local/lnmp/php/etc/php.ini
cgi.fix_pathinfo=0 防止nginx檢查漏洞
date.timezone = Asia/Shanghai
#vim /usr/local/lnmp/php/etc/php-fpm.conf
user=nginx group=nginx
pid = run/php-fpm.pid
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
上述引數選項必須得遵循一個公式,在生產環境下測試生成。
圖4:
#/etc/init.d/php-fpm restart (使用fastCGI啟動php成功)
#chkconfig php-fpm on
載入環境變數
#vim ~/.bash_profile
PATH=$PATH:$HOME/bin:/usr/local/lnmp/mysql/bin:/usr/local/lnmp/php/bin
#source ~/.bash_profile
4>.修改nginx,讓支援php和各種圖片格式。
#vim /usr/local/lnmp/nginx/conf/nginx.conf
pid logs/nginx.pid;
gzip on; 開啟壓縮個功能
server {
listen 80;
server_name lnmp.example.com;
location / {
root html;
index index.html index.htm index.php; 支援php ,先檢測html(不再檢查後面)
}
location ~ .php$ { 以php結尾的交給本機的9000
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf; 包含fastcgi介面檔案
}
location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ 圖片
{
expires 30d;
}
location ~ .*.(js|css)$ js|css支援
{
expires 1h;
}
location /status 後臺檢測功能 (增加驗證功能)
{
stub_status on;
access_log off;
auth_basic hello-login; 自定義驗證提示符
auth_basic_user_file /usr/local/lnmp/nginx/html/.htpasswd; 密碼檔案
}
#htpasswd -c /usr/loca/lnmp/nginx/html/.htpasswd admin 使用apache的加密演算法建立admin
重新載入nginx配置檔案
#nginx -s reload
編寫php測試檔案
#vim /usr/local/lnmp/nginx/html/index.php
<?phpinfo()
?>
測試:http://lnmp.example.com/index.php
http://lnmp.example.com/status 狀態檢測頁面(需要使用上面的認證功能哦)
至此:lnmp環境搭建完畢
####################################################################### ##########
4.LNMP的簡單應用(測試環境)
1>簡單使用lnmp環境搭建論壇
download:Discuz_X2.5_SC_UTF8.zip
不能用網站的擁有者(nginx或者php的擁有者)釋出網站
修改nginx先讓執行index.php
# unzip Discuz_X2.5_SC_UTF8.zip
# cp -r upload/ /usr/local/lnmp/nginx/html/bbs/
## less readme/readme.txt 檢視幫助,一步步安裝
提示修改config/和data/需要可寫許可權
# chown nginx config/ data/ -R
http://lnmp.xxb.com/bbs/ 提示什麼安裝什麼
一般使uc_client/和uc_server/沒有寫許可權 ,給需要的目錄檔案許可權,許可權不能給太大咯
# chown nginx -R uc_client/
# chown nginx -R uc_server/
圖5:
http://lnmp.xxb.com/bbs/ 重新安裝配置bbs論壇
成功後可以使用登入mysql測試訪問建立表的存在!
自己玩論壇吧!!!!!!!!!!
網站壓力測試:
# ab -c 5 -n 100 http://node1.example.com/ -c 制定併發數-n制定請求數
Requests per second: 2.00 [#/sec] (mean) 每秒處理的數量(吞吐量)
Time taken for tests: 36.555 seconds 總共花費的時間
Time per request: 2503.795 [ms] (mean) 使用者平均請求等待時間
Time per request: 500.759 [ms] (mean, across all concurrent requests) 伺服器平均處理時間
#################################################################################
5.nginx的其他功能
使用nginx的反向代理功能虛擬主機加密認證功能哦
正向代理:前端CDN加速(主要應用為區域網減輕網速壓力而使用,作為一個快取記憶體)
反向代理:後端快取(解決RS的真實壓力,將不同的請求分發給不同的伺服器)
反向代理其實就是使用nginx的負載均衡功能(應用層的,工作在7層)。
lvs是基於核心層次的負載均衡.
1.https加密認證功能
製作CA證書,linux下的CA證書預設識別的是.pem和.pem的key檔案
#cd /etc/pki/certs 預設使用Makefile進行製作(使用一系列的ssl加密命令生成)
cert.pem檔案必須位於nginx的主配置檔案目錄下conf/
#cd /etc/pki/tls/certs
#make nginx.pem
# cp -p nginx.pem /usr/local/lnmp/nginx/conf/
#vim /usr/local/lnmp/nginx/conf/nginx.conf
server {
listen 443;
server_name lnmp.xxb.com; 主機名稱
ssl on;
ssl_certificate nginx.pem; 指定認證檔案和key
ssl_certificate_key nginx.pem;
}
#nginx -t && nginx -s reload
訪問首次將會體現https認證
2.nginx的虛擬主機配置(實驗必須得給兩個虛擬主機設定解析哦)
# vim /usr/local/lnmp/nginx/conf/nginx.conf
server {
listen 80;
server_name www.xxb.com;
access_log logs/www.xxb.com.access.log main; 日誌格式,可以在全域性變數中定製,將開啟日誌的格式就ok
location / {
index index.html;
root /var/www/html/virtualhosts/xxb.com;
}
}
server {
listen 80;
server_name www.andy.com;
access_log logs/www.andy.com.access.log main;
location / {
index index.html;
root /var/www/html/virtualhosts/andy.com;
}
}
#mkdir -p /var/www/html/virtualhosts/xxb.com 建立虛擬主機發布目錄
#mkdir -p /var/www/html/virtualhosts/andy.com
#echo www.andy.com > xxb.com/index.html
#echo www.xxb.com > andy.com/index.html
#nginx -t && nginx -s reload
3.nginx的負載均衡功能
nginx只負責處理靜態的網頁,將php和jsp等交給後端的伺服器處理,從而實現方向代理
阿里:lvs+haproxy
nginx在作為負載均衡器的時候也具有健康檢查功能,能夠自動切換.
# vim /usr/local/lnmp/nginx/conf/nginx.conf
在全域性http{}中配置負載均衡器(24作為http和代理伺服器)
upstream linux {
server 192.168.0.24; 可以根據硬體的不同設定相應的weight
server 192.168.0.16;
}
在server{}中的location()新增使用反向代理
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://xxbandy;
}
#nginx -t && nginx -s reload
檢測配置檔案並且進行重新載入配置
測試訪問://www.example.com 預設會自動進行排程到24和16主機
分析:這樣還是沒有實現高校代理的個功能啊,要是讓nginx前端作為靜態網站,然後和後端動態rs相連,真正實現動靜分離的負載均衡。
########################作為web伺服器,必做的安全事項#############
4.防止錯誤訪問(web伺服器必做的事情,防止太多訪問進而病毒)
首先給使用者目錄最低的許可權,然後讓程式寫入檔案cache不可讀,使用者上傳目錄不可執行
應用程式的快取資料777,讓程式自動寫入快取資料
寫在php定義之前
location ~ "^/cache" { 程式自寫的網站使用者沒有許可權訪問
return 403
}
location ~ "^/upload" { 使用者上傳的目錄沒有許可權執行
}
#mkdir /usr/local/lnmp/nginx/html/upload/
#mkdir /usr/local/lnmp/nginx/html/cache
7.完善php相關模組,memcached
libevent動態非同步處理庫
Memcached是一個高效能的分散式記憶體物件快取系統,用於動態Web應用以減輕資料庫負載。通過在記憶體裡維護一個統一的巨大的Hash表,能夠用來儲存各種的資料。它通過在記憶體中快取資料和物件來減少讀取資料庫的次數,從而提供動態、資料庫驅動網站的速度。
php擴充套件的Memcache實際上是連結Memcache的方式。
memcached使用libevent庫,才能在系統上發揮其高效能。
memcached可以將記憶體的資料寫入I/O,同步到硬碟,不消耗cpu資源,但是隻會佔取一定記憶體
download:memcached-1.4.5.tar.gz memcache.tar.gz
使用telnet檢視,stat檢視memcached內部狀態
#yum install memcached -y
#vim /etc/sysconfig/memcached memcached使用者身份以及埠設定
#/etc/init.d/memcached restart
#telnet localhost 11211
add user 0 0 5 存資料(使用者標識 存活時間 儲存位元組數)
123
get user 獲取資料
1000個請求,500併發
#ab -n 1000 -n 500 http://lnmp.xxb.com apachce自帶壓力工具
在lnmp上安裝php的memcache支援
#get memcache.2.5.tgz
#/usr/local/lnmp/php/bin/phpize
#./configure --enable-memcache --with-php-config=/usr/local/lnmp/php/bin/php-config
#make && make install
#cd /usr/local/lnmp/php/etc/
#vim php.ini
extension=mysql.so
extension=memcache.so
#/etc/init.d/php-fpm reload
增加php的memcache支援了
#cp memcache.php /usr/local/lnmp/nginx/html/
#vim memcache.php 修改連結memcached和密碼
測試記憶體memcache
8.優化php,php-nginx的許可權關係
php不再虛擬主機中支援,
它只支援在同一個nginx中的server塊
如果需要虛擬主機也支援,可以加入
但是,這樣的化,相當與兩個網站都使用一個php的cgi請求
防止跨站訪問
vim /usr/local/lnmp/nginx/conf/fastcgi.conf
fastcgi param PHP_VALUE "open_basedir=$document_root";
# vim ../../php/etc/php.ini
open_basedir = /usr/local/lnmp/nginx/html
但是依然發現虛擬主機仍然可以訪問php