1. 程式人生 > >LNMP架構 安裝PHP

LNMP架構 安裝PHP

LNMP架構

第十一章 LNMP架構

12.1 LNMP架構介紹

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

LNMP工作模式

mark

和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等。

FastCGI

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

FastCGI特點:

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

FastCGI工作原理:

Web Server啟動時載入FastCGI進程管理器(IIS ISAPI或Apache Module)
FastCGI進程管理器自身初始化,啟動多個CGI解釋器進程(可見多個php-cgi)並等待來自Web Server的連接。
當客戶端請求到達Web Server時,FastCGI進程管理器選擇並連接到一個CGI解釋器。Web server將CGI環境變量和標準輸入發送到FastCGI子進程php-cgi。
FastCGI子進程完成處理後將標準輸出和錯誤信息從同一連接返回Web Server。當FastCGI子進程關閉連接時,請求便告處理完成。FastCGI子進程接著等待並處理來自FastCGI進程管理器(運行在Web Server中)的下一個連接。 在CGI模式中,php-cgi在此便退出了。
在上述情況中,你可以想象CGI通常有多慢。每一個Web請求PHP都必須重新解析php.ini、重新載入全部擴展並重初始化全部數據結構。使用FastCGI,所有這些都只在進程啟動時發生一次。一個額外的好處是,持續數據庫連接(Persistent database connection)可以工作。

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。

PHP-CGI

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

php-cgi變更php.ini配置後需重啟php-cgi才能讓新的php-ini生效,不可以平滑重啟。
直接殺死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”找到它的最新版本發布地址。

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@centos-01inux ~]# rm -rf /usr/local/mysql
[root@centos-01inux ~]# rm -rf /etc/init.d/mysqld
[root@centos-01inux ~]# rm -rf /data/mysql
安裝MySQL

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

12.3-12.4 PHP安裝

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

準備工作

安裝包卸載&解壓

[root@centos-01inux ~]# cd /usr/local/src/

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

解壓:
[root@centos-01inux src]# tar zxvf php-5.6.30.tar.gz
創建賬號

[root@centos-01inux src]# useradd -s /sbin/nologin php-fpm
說明: 該賬號用來運行php-fpm服務,因為在LNMP環境中,PHP是以一種服務的形式獨立存在的。

安裝php

如果之前安裝過PHP,需要清除其原有配置:

[root@centos-01inux src]# cd php-5.6.30
[root@centos-01inux src]# make clean
環境配置

[root@centos-01inux src]# cd php-5.6.30

[root@centos-01inux 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@centos-01inux php-5.6.30]# yum list |grep libxml2

查找相關庫的安裝包:
[root@centos-01inux 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@centos-01inux php-5.6.30]# yum install -y libxml2 libxml2-devel
錯誤2:

configure: error: Cannot find OpenSSL‘s <evp.h>
解決辦法:

[root@centos-01inux 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@centos-01inux php-5.6.30]# yum install -y libcurl libcurl-devel
錯誤3:

configure: error: jpeglib.h not found.
解決辦法:

[root@centos-01inux php-5.6.30]# yum install -y libjpeg libjpeg-turbo-devel
錯誤4:

configure: error: png.h not found.
解決辦法:

[root@centos-01inux php-5.6.30]# yum install -y libpng libpng-devel
錯誤5:

configure: error: freetype-config not found.
解決辦法:

[root@centos-01inux php-5.6.30]# yum install -y freetype freetype-devel
錯誤6:

configure: error: mcrypt.h not found. Please reinstall libmcrypt.
解決辦法:

[root@centos-01inux php-5.6.30]# yum install -y libmcrypt libmcrypt-devel
說明: 每次報錯後根據提示查找相應的庫的安裝包,選擇包進行安裝,安裝完成後重新配置即可!

配置完成後進行檢測:

[root@centos-01inux php-5.6.30]# echo $?
0
總結一下需要安裝的包:

[root@centos-01inux php-5.6.30]# yum install -y gcc gcc-c++ libxml2-devel openssl-devel libcurl-devel libjpeg-devel libpng-devel freetype libmcrypt-devel
編譯&安裝

編譯:

[root@centos-01inux php-5.6.30]# make
報錯: virtual memory exhausted: Cannot allocate memory #虛擬內存耗盡:無法分配內存

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

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

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

[root@centos-01inux php-5.6.30]# make install
php-fpm相關命令:

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

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

方法2:
[root@centos-01inux php-fpm]# /usr/local/php-fpm/bin/php -m
php-fpm配置文件語法檢測:

[root@centos-01inux php-fpm]# /usr/local/php-fpm/sbin/php-fpm -t
配置

添加配置文件

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

[root@centos-01inux php-5.6.30]# cp php.ini-production /usr/local/php-fpm/etc/php.ini
配置文件調試

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

手動添加配置文件,寫入如下內容:
[root@centos-01inux 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@centos-01inux etc]# cd /usr/local/src/php-5.6.30

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

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

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

啟動php-fpm服務:
[root@centos-01inux 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是什麽樣子的。

LNMP架構 安裝PHP