CentOS 7.*編譯安裝PHP8


原文: https://typecodes.com/web/centos7compilephp8.html?utm_source=tuicool&utm_medium=referral
PHP官方:http://php.net/
Github源:https://github.com/php/php-src/releases
 
1 創建php用戶和用戶組,並在github下載php8源碼
#######新建php用戶和php組
[root@typecodes ~]# groupadd -r www && useradd -r -g www -s /bin/false -d /usr/local/php8 -M php

#####安裝編譯php8時需要的依賴包
[root@typecodes ~]# yum -y install libxml2 libxml2-devel curl-devel libjpeg-devel libpng-devel freetype-devel libmcrypt-devel sqlite-devel oniguruma-devel

###wget下載必備軟件
cd /mnt/wget
wget https://www.php.net/distributions/php-8.0.0.tar.bz2
wget https://github.com/phpredis/phpredis/archive/5.3.2.tar.gz -O phpredis-5.3.2.tar.gz
wget https://github.com/swoole/swoole-src/archive/v4.5.9.tar.gz -O swoole-src-4.5.9.tar.gz
wget http://pecl.php.net/get/mcrypt-1.0.3.tgz

wget https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.16.tar.gz
wget https://github.com/Kitware/CMake/releases/download/v3.16.0/cmake-3.17.2.tar.gz
wget https://libzip.org/download/libzip-1.5.2.tar.xz
###編譯安裝 libiconv1.16 和 CMAKE 3.17.2 和 libzip 1.5.2 ###
cd /mnt/wget && tar zxvf libiconv-1.16.tar.gz && cd libiconv-1.16 && ./configure --prefix=/usr/local/libiconv && make && make install
ln -s /usr/local/libiconv/lib/libiconv.so.2 /usr/lib64/libiconv.so.2


===========升級CMake(CMAKE官網:https://cmake.org/download/)===========================
cd /mnt/wget && tar -zxvf cmake-3.17.2.tar.gz && cd cmake-3.17.2
./bootstrap && gmake && gmake install

cmake -version
===========升級curl && libcurl(https://curl.haxx.se/download.html)===========================
cd /mnt/wget && tar xf curl-7.73.0.tar.gz && cd curl-7.73.0

./configure --prefix=/usr/local/curl/ --without-nss --with-ssl=/usr/local/openssl && make && make install

mv /usr/bin/curl /usr/bin/curl.bak
mv /usr/bin/curl-config /usr/bin/curl-config.bak
ln -s /usr/local/curl/bin/curl /usr/bin/curl
cp /usr/local/curl/bin/curl-config /usr/bin/curl-config

source /etc/profile && ldconfig
curl -V


===========升級libzip(https://libzip.org/download/)===========================
cd /mnt/wget && tar xvJf libzip-1.5.2.tar.xz && cd libzip-1.5.2
mkdir build && cd build/
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/libzip ..
make && make install

2 php8編譯參數的配置

准備工作做好后,就開始正式配置php8的安裝明細了。注意,操作時一定要先把下面反斜杠“\”后面添加的注釋文字去掉!!!

cd /mnt/wget && tar -xjvf php-8.0.0.tar.bz2 && cd php-8.0.0
######開始配置 ./configure \ --prefix=/usr/local/php8 --exec-prefix=/usr/local/php8 --bindir=/usr/local/php8/bin --sbindir=/usr/local/php8/sbin \
--includedir=/usr/local/php8/include --libdir=/usr/local/php8/lib/php --mandir=/usr/local/php8/php/man \
--with-config-file-path=/usr/local/php8/etc \
--with-mysql-sock=/dev/shm/mysql.sock --with-mysqli=shared,mysqlnd --with-mhash \
--with-openssl=/usr/local/openssl --with-curl=/usr/local/curl \
--with-pdo-mysql=shared,mysqlnd --with-iconv --with-zlib \
--enable-inline-optimization \
--disable-debug --disable-rpath --enable-shared \
--enable-xml --enable-bcmath --enable-shmop --enable-sysvsem --enable-mbregex --enable-mbstring --enable-ftp \
--enable-pcntl --enable-sockets --with-xmlrpc --enable-soap --without-pear --with-gettext --enable-session \
--enable-opcache --enable-fpm --without-gdbm --disable-fileinfo --with-fpm-user=www --with-fpm-group=www

執行上面的配置命令的結果:

configure: WARNING: unrecognized options: --with-mysql, --enable-fastcgi

若報錯:configure: error: off_t undefined; check your library configuration,需執行以下命令:

echo '/usr/local/lib64
/usr/local/lib
/usr/lib
/usr/lib64
/usr/local/mysql/lib' >> /etc/ld.so.conf && ldconfig -v

 

3 開始編譯和安裝php8
# make && make install

部分編譯出錯的環境請使用

make ZEND_EXTRA_LIBS='-L/usr/local/libiconv/lib/ -liconv -L/usr/local/openssl/lib/ -L/usr/local/curl/lib/ -lssl -lcrypto' && make install

編譯安裝完成php8!

 

5 查看編譯成功后的php8安裝目錄

由於需要和MySQL進行通信,所以需要特別查看php8安裝后的lib擴展庫目錄(/usr/local/php8/lib/php/extensions/no-debug-non-zts-20190902/),需要確保至少存在mysqli.sopdo_mysql.so這兩個動態庫文件。

 

6 開始設置php8的配置文件php.ini、php-fpm.conf、www.conf和php-fpm腳本

可以用編譯后的配置文件復制到php8的配置目錄(/usr/local/php8/etc/),推薦使用《php8中php.ini、php-fpm和www.conf的配置》文中整理的3個php8配置文件和php-fpm服務控制腳本。

find /usr -name *php.ini*

#######直接使用編譯后未經優化處理的配置
cp /mnt/wget/php-8.0.0/php.ini-production /usr/local/php8/etc/php.ini
cp /usr/local/php8/etc/php-fpm.conf.default /usr/local/php8/etc/php-fpm.conf
cp /usr/local/php8/etc/php-fpm.d/www.conf.default /usr/local/php8/etc/php-fpm.d/www.conf
cp /mnt/wget/php-8.0.0/sapi/fpm/php-fpm.service /lib/systemd/system/php-fpm.service

#######安裝redis(https://github.com/phpredis/phpredis/releases#用phpize生成configure配置文件
cd /mnt/wget && tar zxvf phpredis-5.3.2.tar.gz && cd phpredis-5.3.2
/usr/local/php8/bin/phpize && ./configure --with-php-config=/usr/local/php8/bin/php-config && make && make install
#######選擇安裝swoole(https://github.com/swoole/swoole-src/releases)
cd /mnt/wget && tar zxvf swoole-src-4.5.9.tar.gz && cd swoole-src-4.5.9
/usr/local/php8/bin/phpize && ./configure --with-php-config=/usr/local/php8/bin/php-config && make && make install

#######安裝mcrypt(http://pecl.php.net/package/mcrypt)7.2移除mcrypt導致兼容性問題
cd /mnt/wget && tar zxvf mcrypt-1.0.3.tgz && cd mcrypt-1.0.3
/usr/local/php8/bin/phpize && ./configure --with-php-config=/usr/local/php8/bin/php-config && make && make install

==========安裝fileinfo擴展=====================
cd /mnt/wget/php-8.0.0/ext/fileinfo && /usr/local/php8/bin/phpize && ./configure --with-php-config=/usr/local/php8/bin/php-config && make && make install

#######去掉文件中的注釋、空行
vi /usr/local/php8/etc/php-fpm.conf
vi /usr/local/php8/etc/php-fpm.d/www.conf
vi /usr/local/php8/etc/php.ini

:g/^;/d
:g/^$/d

替換/lib/systemd/system/php-fpm.service 中的 /usr/local/php8/var/run/php-fpm.pid 為 /run/php-fpm.pid
1. 配置/usr/local/php8/etc/php-fpm.conf

php-fpm.conf是php-fpm進程服務的配置文件:

######Pid file的默認前綴是/usr/local/php8/var
pid = /run/php-fpm.pid
error_log = /var/log/php/fpm-error.log
include=/usr/local/php8/etc/php-fpm.d/*.conf
2. 配置/usr/local/php8/etc/php-fpm.d/www.conf

www.conf這是php-fpm進程服務的擴展配置文件:[php-fpm配置詳解]

######設置用戶和用戶組
user = www
group = www

######根據nginx.conf中的配置fastcgi_pass unix:/dev/shm/php-fpm.sock;設置PHP監聽
; listen = 127.0.0.1:9000   #####不建議使用
listen = /dev/shm/php-fpm.sock
listen.owner = www
listen.group = www
listen.mode = 0777
listen.allowed_clients = /dev/shm/php-fpm.sock

######使用靜態進程數max_children=內存/512
pm = static
pm.max_children = 200
pm.max_requests = 0

pm.status_path = /FpmStatus

######開啟慢日志
slowlog = /var/log/php/fpm-$pool-slow.log
request_slowlog_timeout = 30s
request_slowlog_trace_depth = 20
request_terminate_timeout = 0
3. 配置/usr/local/php8/etc/php.ini

php.ini是php運行核心配置文件:

######避免PHP信息暴露在http頭中
expose_php = Off

######常用配置
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
display_errors = Off
log_errors = On
html_errors = Off
error_log = /var/log/php/cli-error.log
ignore_repeated_errors = On
ignore_repeated_source = On

memory_limit = 512M
max_execution_time = 600 (0為不限制)
max_input_time = -1
post_max_size = 128M
max_input_vars = 1000000
file_uploads = On
upload_tmp_dir = /tmp/www
upload_max_filesize = 100M
session.gc_maxlifetime = 14400
default_socket_timeout = 600 (-1為不限制)
######設置PHP的擴展
extension_dir = "/usr/local/php8/lib/php/extensions/no-debug-non-zts-20190902"
zend_extension=opcache.so
extension=mcrypt.so
extension=mysqli.so
extension=pdo_mysql.so
extension=redis.so
extension=swoole.so ######設置PHP的時區 date.timezone = "Asia/Shanghai" ######開啟opcache [opcache] opcache.enable=1
opcache.enable_cli=1
opcache.huge_code_pages=1
opcache.file_cache=/tmp
######設置PHP腳本允許訪問的目錄(需要根據實際情況配置)
;open_basedir = /usr/share/nginx/html;

session.save_handler = redis
session.save_path = "tcp://*****.aliyuncs.com:6379?auth=******"

[MySQLi]
mysqli.reconnect = On
4 在配置文件中使用到的路徑或文件,配置權限
mkdir -p /var/log/php/
mkdir -p /var/log/php-fpm/
mkdir -p /run/php-fpm/
mkdir -p /var/lib/php/session

touch /dev/shm/php-fpm.sock
touch /run/php-fpm.pid
chown www:www /dev/shm/php-fpm.sock
chmod 777 /dev/shm/php-fpm.sock
chown -R www:www /var/lib/php

######配置PHP連接MySQL的端口監聽文件
touch /dev/shm/mysql.sock
chmod 777 /dev/shm/mysql.sock
5 測試php-fpm配置,設置開機自啟動
######測試配置
/usr/local/php8/sbin/php-fpm -t

######修改文件權限
chmod 745 /lib/systemd/system/php-fpm.service

######設置為開機啟動
systemctl enable php-fpm.service

######啟動php-fpm
systemctl start php-fpm.service

######強制php-fpm用root啟動
/usr/local/php8/sbin/php-fpm -R
若fpm因權限問題不能啟動,需以root身份強制啟動:
在/etc/rc.d/rc.local尾部增加 /usr/local/php8/sbin/php-fpm -R --fpm-config /usr/local/php8/etc/php-fpm.conf
為文件增加執行權限:chmod +x /etc/rc.d/rc.local

 通過命令 ps -ef | grep php 查看是否成功(圖中的php-fpm進程數和進程用戶www都是由www.conf中pm.start_servers和user的值分別決定的):

vi /etc/profile  底部加入

export PATH=$PATH:/usr/local/php8/bin

 

11 查看php8版本信息

最后,可以通過命令php -v查看當前PHP版本信息,圖中可以看到當前php8還使用了Zend OPcache緩存,是因為在php.ini文件中添加了zend_extension=opcache.so配置。

systemctl restart php-fpm
systemctl restart nginx

kill -USR2 `cat /run/php-fpm.pid`
/usr/local/nginx/sbin/nginx -s reload

==============================================================
分配512個預留的大頁內存,優化PHP-opcache:
sysctl vm.nr_hugepages=512

 

 特別優化:

1、修改/usr/local/nginx/conf/nginx.conf 文件
worker_processes  設置為cpu個數或cpu的核數
查看CPU核數:cat /proc/cpuinfo | grep "cpu cores" | uniq

worker_connections  設置為進程打開文件句柄數量
ulimit -n進行查看, 默認1024,建議修改為65535 【修改/etc/security/limits.conf,最后增加一行記錄 * - nofile 65535】

http中
client_max_body_size 100m;
client_body_buffer_size 2048k;

 

=====================================================================================================

對於進程的管理存在兩種風格——static和dynamic。

如果設置成static,php-fpm進程數自始至終都是pm.max_children指定的數量,不再增加或減少。

如果設置成dynamic,則php-fpm進程數是動態的,最開始是pm.start_servers指定的數量,如果請求較多,則會自動增加,保證空閑的進程數不小於pm.min_spare_servers,如果進程數較多,也會進行相應清理,保證多余的進程數不多於pm.max_spare_servers。

這兩種不同的進程管理方式,可以根據服務器的實際需求來進行調整。

這里先說一下涉及到這個的幾個參數,他們分別是pmpm.max_childrenpm.start_serverspm.min_spare_serverspm.max_spare_servers

pm表示使用那種方式,有兩個值可以選擇,就是static(靜態)或者dynamic(動態)。

下面4個參數的意思分別為:

pm.max_children:static模式下創建的子進程數或dynamic模式下同一時刻允許最大的php-fpm子進程數量。 
pm.max_requests:php-fpm子進程能處理的最大請求數。 
pm.start_servers:動態方式下的起始php-fpm進程數量。 
pm.min_spare_servers:動態方式下服務器空閑時最小php-fpm進程數量。 
pm.max_spare_servers:動態方式下服務器空閑時最大php-fpm進程數量。

如果dm設置為static,那么其實只有pm.max_children這個參數生效。系統會開啟設置數量的php-fpm進程(專用服務器推薦使用)。

如果dm設置為dynamic,那么pm.max_children參數失效,后面3個參數生效。系統會在php-fpm運行開始的時候啟動pm.start_servers個php-fpm進程,然后根據系統的需求動態在pm.min_spare_servers和pm.max_spare_servers之間調整php-fpm進程數。

那么,對於我們的服務器,選擇哪種執行方式比較好呢?事實上,跟Apache一樣,運行的PHP程序在執行完成后,或多或少會有內存泄露的問題。這也是為什么開始的時候一個php-fpm進程只占用3M左右內存,運行一段時間后就會上升到20-30M的原因了。

對於內存大的服務器(比如8G以上)來說,指定靜態的max_children實際上更為妥當,因為這樣不需要進行額外的進程數目控制,會提高效率。因為頻繁開關php-fpm進程也會有時滯,所以內存夠大的情況下開靜態效果會更好。數量也可以根據 內存/30M 得到,比如8GB內存可以設置為100,那么php-fpm耗費的內存就能控制在 2G-3G的樣子。如果內存稍微小點,比如1G,那么指定靜態的進程數量更加有利於服務器的穩定。這樣可以保證php-fpm只獲取夠用的內存,將不多的內存分配給其他應用去使用,會使系統的運行更加暢通。

那么對於一般的服務器,怎么設置這些值呢,也是有值可參考的。
一般一個php-cgi進程占用20~30m左右的內存,php-fpm稍多一點,就按30m算吧。你的物理mem大小/30m差不多就是可以設置的php-fpm進程數了,當然實際肯定要比這個少點。比如我8G的內存,大概設置100~200之間,也就是pm.max_children=100 是一個比較合適的值。

這里面還有一個問題,php-fpm因為一些第三方庫可能會引起內存泄漏,時間長了,占用的內存會比較多,像我們的服務器現在就是50m左右,還好,有pm.max_requests這個參數,這個參數指定了一個php-fpm子進程執行多少次之后重啟該進程。這個可能就要根據你的實際情況調整了

php-fpm有一個參數 max_requests,該參數指明了,每個children最多處理多少個請求后便會被關閉,默認的設置是500。因為php是把請求輪詢給每個children,在大流量下,每個childre到達max_requests所用的時間都差不多,這樣就造成所有的children基本上在同一時間被關閉,這樣會導致此時nginx發給php的請求無法得到相應,會出現短時間的502.解決方法:

增加children的數量,並且將 max_requests 設置未 0 或者一個比較大的值

單php-fpm占用內存 = 內存占用總量 / php-fpm進程數

查看內存使用量: free -m

 

static :表示在 `php-fpm` 運行時直接 `fork` 出 `pm.max_chindren` 個子進程,
dynamic:表示,運行時 `fork` 出 `start_servers` 個進程,隨着負載的情況,動態的調整,最多不超過 `max_children` 個進程。

一般推薦用 static。
    優點是不用動態的判斷負載情況,提升性能;
    缺點是多占用些系統內存資源。

 PHP-FPM 子進程數量,是不是越多越好?
 當然不是,pm.max_chindren,進程多了,增加進程管理的開銷以及上下文切換的開銷。
 更核心的是,能並發執行的 php-fpm 進程不會超過 cpu 個數。
 如何設置,取決於你的代碼
    如果代碼是 CPU 計算密集型的,pm.max_chindren 不能超過 CPU 的內核數。
    如果不是,那么將 pm.max_chindren 的值大於 CPU 的內核數,是非常明智的。

 國外技術大拿給出這么個公式:
 在 N + 20% 和 M / m 之間。
    N 是 CPU 內核數量。
    M 是 PHP 能利用的內存數量。
    m 是每個 PHP 進程平均使用的內存數量。

 適用於 dynamic 方式。
 static方式:M / (m * 1.2)

 當然,還有一種保險的方式,來配置 max_children。適用於 static 方式。
    先把 max_childnren 設置成一個比較大的值。
    穩定運行一段時間后,觀察 php-fpm 的 status 里的 max active processes 是多少
    然后把 max_children 配置比它大一些就可以了。

 pm.max_requests:指的是每個子進程在處理了多少個請求數量之后就重啟。
 這個參數,理論上可以隨便設置,但是為了預防內存泄漏的風險,還是設置一個合理的數比較好。

 

=====================================================================================================

php-fpm管理,master進程可以理解以下信號:
INT,TERM 立刻終止
QUIT 平滑終止
USR1 重新打開日志文件
USR2 平滑重載所有worker進程並重新載入配置和二進制模塊

示例:
php-fpm 關閉:
kill -INT `cat /run/php-fpm.pid`

php-fpm 重啟:
kill -USR2 `cat /run/php-fpm.pid`

查看php-fpm進程數:
ps -ef | grep -c php-fpm

 

php-fpm status詳解

pool – fpm池子名稱,大多數為www
process manager – 進程管理方式,值:static, dynamic or ondemand. dynamic
start time – 啟動日期,如果reload了php-fpm,時間會更新
start since – 運行時長
accepted conn – 當前池子接受的請求數
listen queue – 請求等待隊列,如果這個值不為0,那么要增加FPM的進程數量
max listen queue – 請求等待隊列最高的數量
listen queue len – socket等待隊列長度
idle processes – 空閑進程數量
active processes – 活躍進程數量
total processes – 總進程數量
max active processes – 最大的活躍進程數量(FPM啟動開始算)
max children reached - 大道進程最大數量限制的次數,如果這個數量不為0,那說明你的最大進程數量太小了,請改大一點。
slow requests – 啟用了php-fpm slow-log,緩慢請求的數量

 

 

yum Update之后,若有報錯“error while loading shared libraries: libonig.so.2”,需執行:
ln -s /usr/lib64/libonig.so /usr/lib64/libonig.so.2

 

 

姊妹篇:

編譯安裝Tengine: https://www.cnblogs.com/doseoer/p/6257939.html
編譯安裝Redis6:https://www.cnblogs.com/doseoer/p/9975022.html
編譯安裝MySQL5.7.25: https://www.cnblogs.com/doseoer/p/13995204.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM