LNMP架構介紹、安裝PHP(php-fpm)

12.1 LNMP架構介紹

LNMP表明的就是:Linux系統下Nginx+MySQL+PHP這種網站服務器架構。Nginx中的PHP是以fastcgi的方式結合Nginx的,能夠理解爲Nginx代理了PHP的fastcgi。php

LNMP工做模式

  • 和LAMP不一樣的是,LNMP中提供web服務的是Nginx。
  • 在LNMP架構中PHP是做爲一個獨立的服務存在的,這個服務叫作php-fpm。
  • Nginx直接處理靜態請求(支持的併發更高,速度比Apache快),動態請求轉發給php-fpm處理。

CGI、FastCGI、PHP-CGI與PHP-FPM概念

CGI

CGI全稱是「公共網關接口」(Common Gateway Interface),HTTP服務器與你的或其它機器上的程序進行「交談」的一種工具,其程序須運行在網絡服務器上。
CGI能夠用任何一種語言編寫,只要這種語言具備標準輸入、輸出和環境變量。如php,perl,tcl等。css

FastCGI

FastCGI像是一個常駐(long-live)型的CGI,它能夠一直執行着,只要激活後,不會每次都要花費時間去fork一次(這是CGI最爲人詬病的fork-and-execute 模式)。它還支持分佈式的運算,即FastCGI程序能夠在網站服務器之外的主機上執行而且接受來自其它網站服務器來的請求。
FastCGI是語言無關的、可伸縮架構的CGI開放擴展,其主要行爲是將CGI解釋器進程保持在內存中並所以得到較高的性能。衆所周知,CGI解釋器的反覆加載是CGI性能低下的主要緣由,若是CGI解釋器保持在內存中並接受FastCGI進程管理器調度,則能夠提供良好的性能、伸縮性、Fail-Over特性等等。python

FastCGI特色:mysql

  1. FastCGI具備語言無關性
  2. FastCGI在進程中的應用程序,獨立於核心web服務器運行,提供了一個比API更安全的環境。APIs把應用程序的代碼與核心的web服務器連接在一塊兒,這意味着在一個錯誤的API的應用程序可能會損壞其餘應用程序或核心服務器。 惡意的API的應用程序代碼甚至能夠竊取另外一個應用程序或核心服務器的密鑰。
  3. FastCGI技術目前支持語言有:C/C++、Java、Perl、Tcl、Python、SmallTalk、Ruby等。相關模塊在Apache, ISS, Lighttpd等流行的服務器上也是可用的。
  4. FastCGI的不依賴於任何Web服務器的內部架構,所以即便服務器技術的變化, FastCGI依然穩定不變。

FastCGI工做原理:nginx

  1. Web Server啓動時載入FastCGI進程管理器(IIS ISAPI或Apache Module)
  2. FastCGI進程管理器自身初始化,啓動多個CGI解釋器進程(可見多個php-cgi)並等待來自Web Server的鏈接。
  3. 當客戶端請求到達Web Server時,FastCGI進程管理器選擇並鏈接到一個CGI解釋器。Web server將CGI環境變量和標準輸入發送到FastCGI子進程php-cgi。
  4. FastCGI子進程完成處理後將標準輸出和錯誤信息從同一鏈接返回Web Server。當FastCGI子進程關閉鏈接時,請求便告處理完成。FastCGI子進程接着等待並處理來自FastCGI進程管理器(運行在Web Server中)的下一個鏈接。 在CGI模式中,php-cgi在此便退出了。

在上述狀況中,你能夠想象CGI一般有多慢。每個Web請求PHP都必須從新解析php.ini、從新載入所有擴展並重初始化所有數據結構。使用FastCGI,全部這些都只在進程啓動時發生一次。一個額外的好處是,持續數據庫鏈接(Persistent database connection)能夠工做。c++

FastCGI的不足:
由於是多進程,因此比CGI多線程消耗更多的服務器內存,PHP-CGI解釋器每進程消耗7至25兆內存,將這個數字乘以50或100就是很大的內存數。
Nginx 0.8.46+PHP 5.2.14(FastCGI)服務器在3萬併發鏈接下,開啓的10個Nginx進程消耗150M內存(15M* 10=150M),開啓的64個php-cgi進程消耗1280M內存(20M *64=1280M),加上系統自身消耗的內存,總共消耗不到2GB內存。若是服務器內存較小,徹底能夠只開啓25個php-cgi進程,這樣php-cgi消耗的總內存數才500M。web

PHP-CGI

PHP-CGI是PHP自帶的FastCGI管理器。
PHP-CGI的不足:sql

  1. php-cgi變動php.ini配置後需重啓php-cgi才能讓新的php-ini生效,不能夠平滑重啓。
  2. 直接殺死php-cgi進程,php就不能運行了。(PHP-FPM和Spawn-FCGI就沒有這個問題,守護進程會平滑重新生成新的子進程。)

PHP-FPM

PHP-FPM是一個PHP FastCGI管理器,是隻用於PHP的,能夠在 http://php-fpm.org/download 下載。
PHP-FPM實際上是PHP源代碼的一個補丁,旨在將FastCGI進程管理整合進PHP包中。必須將它patch到你的PHP源代碼中,在編譯安裝PHP後纔可使用。
PHP5.3.3已經集成php-fpm了,再也不是第三方的包了。PHP-FPM提供了更好的PHP進程管理方式,能夠有效控制內存和進程、能夠平滑重載PHP配置,比spawn-fcgi具備更多有點,因此被PHP官方收錄了。在./configure的時候帶 –enable-fpm參數便可開啓PHP-FPM。數據庫

Spawn-FCGI

Spawn-FCGI是一個通用的FastCGI管理服務器,它是lighttpd中的一部份,不少人都用Lighttpd的Spawn-FCGI進行FastCGI模式下的管理工做,不過有很多缺點。而PHP-FPM的出現多少緩解了一些問題,但PHP-FPM有個缺點就是要從新編譯,這對於一些已經運行的環境可能有不小的風險(refer),在php 5.3.3中能夠直接使用PHP-FPM了。
Spawn-FCGI目前已經獨成爲一個項目,更加穩定一些,也給不少Web 站點的配置帶來便利。已經有很多站點將它與nginx搭配來解決動態網頁。
注: 最新的Spawn-FCGI能夠到lighttpd.net網站搜索「Spawn-FCGI」找到它的最新版本發佈地址。vim

PHP-FPM與spawn-CGI對比

PHP-FPM的使用很是方便,配置都是在PHP-FPM.ini的文件內,而啓動、重啓均可以從php/sbin/PHP-FPM中進行。更方便的是修改php.ini後能夠直接使用PHP-FPM reload進行加載,無需殺掉進程就能夠完成php.ini的修改加載。
結果顯示使用PHP-FPM可使php有不小的性能提高。PHP-FPM控制的進程cpu回收的速度比較慢,內存分配的很均勻。
Spawn-FCGI控制的進程CPU降低的很快,而內存分配的比較不均勻。有不少進程彷佛未分配到,而另一些卻佔用很高。多是因爲進程任務分配的不均勻致使的。而這也致使了整體響應速度的降低。而PHP-FPM合理的分配,致使整體響應的提到以及任務的平均。

本節選自: http://www.nowamagic.net/librarys/veda/detail/1319/

12.2 安裝MySQL

卸載MySQL

直接刪除MySQL安裝時的相關文件。

[root@1 ~]# rm -rf /usr/local/mysql 
[root@1 ~]# rm -rf /etc/init.d/mysqld 
[root@1 ~]# rm -rf /data/mysql

安裝MySQL

在LNMP環境和LAMP環境安裝MySQL的方法同樣。

12.3-12.4 PHP安裝

和LAMP安裝PHP有區別,須要開啓php-fpm服務。

準備工做

安裝包卸載&解壓

[root@1 ~]# cd /usr/local/src/

下載安裝包:
[root@1 src]# wget http://cn2.php.net/distributions/php-5.6.30.tar.gz  

解壓:
[root@1 src]# tar zxvf php-5.6.30.tar.gz

建立帳號

[root@1 src]# useradd -s /sbin/nologin php-fpm

說明: 該帳號用來運行php-fpm服務,由於在LNMP環境中,PHP是以一種服務的形式獨立存在的。

安裝php

若是以前安裝過PHP,須要清除其原有配置:

[root@1 src]# cd php-5.6.30
[root@1 src]# make clean

環境配置

[root@1 src]# cd php-5.6.30

[root@1 src]# ./configure --prefix=/usr/local/php-fpm --with-config-file-path=/usr/local/php-fpm/etc --enable-fpm --with-fpm-user=php-fpm --with-fpm-group=php-fpm --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-pdo-mysql=/usr/local/mysql --with-mysql-sock=/tmp/mysql.sock --with-libxml-dir --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir --with-iconv-dir --with-zlib-dir --with-mcrypt --enable-soap --enable-gd-native-ttf --enable-ftp --enable-mbstring --enable-exif --with-pear --with-curl  --with-openssl

報錯:
錯誤1:

configure: error: xml2-config not found. Please check your libxml2 installation.

解決辦法:

[root@1 php-5.6.30]# yum list |grep libxml2  

查找相關庫的安裝包:
[root@1 php-5.6.30]# yum list |grep libxml2
libxml2.x86_64                          2.9.1-6.el7_2.3                @anaconda
libxml2.i686                            2.9.1-6.el7_2.3                base     
libxml2-devel.i686                      2.9.1-6.el7_2.3                base     
libxml2-devel.x86_64                    2.9.1-6.el7_2.3                base     
libxml2-python.x86_64                   2.9.1-6.el7_2.3                base     
libxml2-static.i686                     2.9.1-6.el7_2.3                base     
libxml2-static.x86_64                   2.9.1-6.el7_2.3                base     

選擇包進行安裝:  
[root@1 php-5.6.30]# yum install -y libxml2 libxml2-devel

錯誤2:

configure: error: Cannot find OpenSSL's <evp.h>

解決辦法:

[root@1 php-5.6.30]# yum install -y openssl openssl-devel

錯誤3:

configure: error: Please reinstall the libcurl distribution -
    easy.h should be in <curl-dir>/include/curl/

解決辦法:

[root@1 php-5.6.30]# yum install -y libcurl libcurl-devel

錯誤3:

configure: error: jpeglib.h not found.

解決辦法:

[root@1 php-5.6.30]# yum install -y libjpeg libjpeg-turbo-devel

錯誤4:

configure: error: png.h not found.

解決辦法:

[root@1 php-5.6.30]# yum install -y libpng libpng-devel

錯誤5:

configure: error: freetype-config not found.

解決辦法:

[root@1 php-5.6.30]# yum install -y freetype freetype-devel

錯誤6:

configure: error: mcrypt.h not found. Please reinstall libmcrypt.

解決辦法:

[root@1 php-5.6.30]# yum install -y libmcrypt libmcrypt-devel

說明: 每次報錯後根據提示查找相應的庫的安裝包,選擇包進行安裝,安裝完成後從新配置便可!

配置完成後進行檢測:

[root@1 php-5.6.30]# echo $?
0

總結一下須要安裝的包:

[root@1 php-5.6.30]#  yum install  -y  gcc gcc-c++ libxml2-devel openssl-devel libcurl-devel libjpeg-devel libpng-devel freetype libmcrypt-devel

編譯&安裝

編譯:

[root@1 php-5.6.30]# make

報錯: virtual memory exhausted: Cannot allocate memory #虛擬內存耗盡:沒法分配內存

解決辦法:
一、停掉虛擬機中未在使用的進程
二、臨時增長swap分區內存:

[root@1 ~]# dd if=/dev/zero of=/tmp/newdisk bs=1M count=100  手動建立一個新分區
記錄了100+0 的讀入
記錄了100+0 的寫出
104857600字節(105 MB)已複製,5.72931 秒,18.3 MB/秒
[root@1 ~]# du -sh /tmp/newdisk
100M	/tmp/newdisk
[root@1 ~]# mkswap /tmp/newdisk  格式化該swap分區
正在設置交換空間版本 1,大小 = 102396 KiB
無標籤,UUID=d42e907a-aae0-4d5f-bf58-586fac415f48
[root@1 ~]# free -m  
              total        used        free      shared  buff/cache   available
Mem:            984         114         626           6         244         706
Swap:          2047           0        2047
[root@1 ~]# swapon /tmp/newdisk  掛載到原swap分區
swapon: /tmp/newdisk:不安全的權限 0644,建議使用 0600。
[root@1 ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:            984         114         626           6         244         707
Swap:          2147           0        2147
[root@1 ~]# chmod 0600 /tmp/newdisk  更改權限以保安全

待PHP編譯完成後要卸載掉該分區
[root@1 ~]# swapoff /tmp/newdisk   卸載分區

安裝:

[root@1 php-5.6.30]# make install

php-fpm相關命令:

執行PHP相關命令的兩種方式:

方法1:
[root@1 php-fpm]# /usr/local/php-fpm/sbin/php-fpm -m

方法2:
[root@1 php-fpm]# /usr/local/php-fpm/bin/php -m

php-fpm配置文件語法檢測:

[root@1 php-fpm]# /usr/local/php-fpm/sbin/php-fpm -t

配置

添加配置文件

將配置文件添加到php-fpm配置文件目錄:

[root@1 php-5.6.30]# cp php.ini-production /usr/local/php-fpm/etc/php.ini

配置文件調試

切換至配置文件所在目錄:
[root@1 php-5.6.30]# cd /usr/local/php-fpm/etc/  

手動添加配置文件,寫入以下內容:
[root@1 etc]# vim php-fpm.conf

[global]
#定義全局參數
pid = /usr/local/php-fpm/var/run/php-fpm.pid
error_log = /usr/local/php-fpm/var/log/php-fpm.log
[www]
listen = /tmp/php-fcgi.sock
#監聽地址,也能夠寫:listen = 127.0.0.1::9000,本地監聽,也能夠監聽其餘IP:port
#此處格式會影響配置Nginx和PHP結合時Nginx尋址PHP的路徑
listen.mode = 666
#當監聽的爲socket文件時該部分才生效,用於指定.sock文件的權限
user = php-fpm
group = php-fpm
#定義php-fpm服務的用戶
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
#以上部分爲進程相關信息

配置啓動腳本

切換至文件源目錄:
[root@1 etc]# cd /usr/local/src/php-5.6.30

添加啓動腳本到系統配置:
[root@1 php-5.6.30]#  cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm

更改文件權限:
[root@1 php-5.6.30]# chmod 755 /etc/init.d/php-fpm

添加到系統服務:
[root@1 php-5.6.30]# chkconfig --add php-fpm
設置開機啓動:
[root@1 php-5.6.30]# chkconfig php-fpm on  

啓動php-fpm服務:
[root@1 php-5.6.30]# service php-fpm start
Starting php-fpm  done

12.5 Nginx介紹

Nginx("engine x")是一款輕量級的Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,並在一個BSD-like 協議下發行。其特色是佔有內存少,併發能力強,事實上nginx的併發能力確實在同類型的網頁服務器中表現較好,中國大陸使用nginx網站用戶有:百度、新浪、網易、騰訊、 淘寶等。

Nginx應用場景:

web服務器、反向代理、負載均衡

Nginx分支

淘寶基於Nginx開發的Tengine,使用上和Nginx一致,服務名,配置文件名都同樣,和Nginx的最大區別在於Tengine增長了一些定製化模塊,在安全限速方面表現突出,另外它支持對js,css合併。

Nginx核心+lua相關的組件和模塊組成了一個支持lua的高性能web容器openresty,參考http://jinnianshilongnian.iteye.com/blog/2280928

OpenResty

OpenResty是一個基於Nginx與Lua的高性能Web平臺,其內部集成了大量精良的Lua庫、第三方模塊以及大多數的依賴項。用於方便地搭建可以處理超高併發、擴展性極高的動態 Web 應用、Web 服務和動態網關。
OpenResty經過匯聚各類設計精良的Nginx模塊(主要由OpenResty團隊自主開發),從而將Nginx有效地變成一個強大的通用Web應用平臺。這樣,Web開發人員和系統工程師可使用Lua腳本語言調動Nginx支持的各類C以及Lua模塊,快速構造出足以勝任10K乃至1000K以上單機併發鏈接的高性能Web應用系統。
OpenResty® 的目標是讓你的Web服務直接跑在 Nginx 服務內部,充分利用 Nginx 的非阻塞 I/O 模型,不只僅對 HTTP 客戶端請求,甚至於對遠程後端諸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都進行一致的高性能響應。
本節摘自: http://openresty.org/cn/

Lua

Lua是一種輕量級、可嵌入式的腳本語言,這樣能夠很是容易的嵌入到其餘語言中使用。另外Lua提供了協程併發,即以同步調用的方式進行異步執行,從而實現併發,比起回調機制的併發來講代碼更容易編寫和理解,排查問題也會容易。Lua還提供了閉包機制,函數能夠做爲First Class Value 進行參數傳遞,另外其實現了標記清除垃圾收集。
由於Lua的小巧輕量級,能夠在Nginx中嵌入Lua VM,請求的時候建立一個VM,請求結束的時候回收VM。

ngx_lua

ngx_lua是Nginx的一個模塊,將Lua嵌入到Nginx中,從而可使用Lua來編寫腳本,這樣就可使用Lua編寫應用腳本,部署到Nginx中運行,即Nginx變成了一個Web容器;這樣開發人員就可使用Lua語言開發高性能Web應用了。 ngx_lua提供了與Nginx交互的不少的API(API就是操做系統留給應用程序的一個調用接口,應用程序經過調用操做系統的API而使操做系統去執行應用程序的命令/動做。),對於開發人員來講只須要學習這些API就能夠進行功能開發,而對於開發web應用來講,若是接觸過Servlet的話,其開發和Servlet相似,無外乎就是知道接收請求、參數解析、功能處理、返回響應這幾步的API是什麼樣子的。

相關文章
相關標籤/搜索