PHP在IIS8 Apache Nginx 哪個性能更好?

PHP在IIS8 Apache Nginx下的性能問題

要部署一台伺服器 因性能受限所以需要效率最大化。

請問在Windows Server 2012 R2平台下 這三種HTTP Server 執行PHP哪種效率最高。

CentOS7 下呢?

謝謝


Nginx:

嚴格來說不是Nginx在跑PHP,Nginx只做轉發給php-fpm,是php-fpm在維持PHP跑…

php-fpm現在穩定性算可以了,但還是無法釋放內存,所以一般的配置是500次後子進程不接收任務,本身任務完成自己結束掉,另開個新的繼續跑,這個任務就是php-fpm在管理…

IIS:

IIS和Apache就是作為模塊跑,釋放內存什麼的自動的,但IIS那貨跑PHP這種東西還是不太靠譜,這是相對Nginx和Apache來說,所以別考慮IIS了…

Apache:

Apache性能挺好,以前一直用。但現在Nginx的發展很NB了,促進了php-fpm的發展也很完善穩定了,php-fpm是大家都力捧的東西,不用考慮作為模塊跑的兼容之類(很多PHP擴展偶爾會出問題),未來是主流PHP的運行方式,佔用內存也小。Apache的太龐大,不解決一些痛點導致Nginx的崛起。比如我關心的Apache下的限速只有cband還比較好用,但是第三方做的,雖然也不錯,但經常這個版本不支持,那個版本支持。而Nginx此類功能已經作為基本功能自帶了,而且非常強大…

Win下:

如果Win平台下就別用Nginx了,因為Win下沒php-fpm管理PHP進程,所以只能用php-cgi,而php-cgi沒有進程管理,所以偶爾出現錯誤進程死掉你的PHP就掛了,就要手工啟動進程。你也可以自己寫個監測程序來管理,這一般維護伺服器的人也沒法做到的。而Linux/BSD下php-fpm可以設定好參數自動啟動幾個進程,請求多少次淘汰並重啟新進程,另外還有好多種其他方式管理PHP進程,一切都是php-fpm自動進行管理的。至於Win下Nginx使用原生Win32 API,用select實現,而Win下比較先進的技術I/O Completion Ports據我所知有第三方做過,但官方Nginx貌似還沒有用IOCP,所以性能肯定沒有Linux的epoll和BSD的kqueue好。其實感覺Win搭伺服器大部分就是個企業站,沒多少訪問量,如果海量訪問大部分都用Linux/BSD來做集群了。關鍵點是Win下沒有php-fpm,所以Win下就不要用Nginx了…

其實關於不推薦用Win伺服器還有一點:你的Win伺服器是正版嗎?可能大部分伺服器都不是,但萬一遇到得罪別人被舉報,還有大公司上市之類的,被查的可能性還是有的…

Win下我本機開發測試一直用Apache,因為Apache用了10多年,熟悉Apache,也穩定,作為服務來跑基本不用管,開發機用Apache更加省事,你對IIS熟悉或者有情懷可用IIS,否則推薦用Apache,基本不會出啥問題。運行起來也非常穩定。但我現在Win開發機測試用Nginx+php-cgi,哈哈,保持統一,我測試又沒事,偶爾一個月出現一兩次調試PHP代碼的時候PHP進程死掉,進服務啟動下就好。Win下生產環境你別用Nginx,用Apache吧…

最後說下結論:

伺服器如果用asp/.net就用Win,否則盡量要用Linux或BSD,如果需要性能最大化一定要用Linux或BSD…

Win下首推Apache+PHP,其次IIS+PHP…

Linux或BSD下首推用Nginx+PHP,其次用Apache+PHP…

PHP推薦用PHP7,爽就一個字,理由就不說了,到處都有介紹升級到PHP7的爽…


瀉藥.....

首先性能有限的情況下絕對不推薦用Win server跑Web服務,那麼可以排除IIS。

如果用Linux的話,nginx肯定比Apache快不少,不過疑似不太穩定?(我見過不少是LANMP動態和靜態分開的,nginx只用於處理靜態內容)

當然如果非要用win平台的話,那麼IIS是首選。因為php在NT上面本身就不算原生,如果再搞一層非原生的apache/nginx出來效果可能會慘不忍睹。反正我沒有見過生產環境用WAMP/WNMP

跑的。(除了某些非專業的個人站長)


lnmp


這要考慮公司站點的訪問量。

訪問量稍大的話,推薦nginx,它有著低消耗、高穩定性等優點並且可以實現高並發的訪問。

(當然,超大訪問就要需要HPC分散式了)

其次,是Apache,它的穩定性眾所周知,它和nginx相比,資源消耗較大,並且不支持高並發,一旦訪問量較大,web站點可能就掛了,其他方面Apache比nginx好些。

(當然以上說的都是在linux環境下跑的,此外提供web服務的,還有如tomcat等。)

在叨嘮一句,看需求選擇,如今大多數企業用的基本都是nginx了,一般用的都是LNMP或者lanmp架構。LNMP=linux+nginx+MySQL+PHP

lanmp=linux+Apache+nginx+MySQL+PHP

最後在說說,iis,Windows下選他無誤,但現如今有幾個公司的web站點還跑在Windows下?Windows的安全性和穩定性,和linux是沒法比的。


做VFS的強答一下

首先排除和windows Server和IIS。題主說因性能受限所以需要效率最大化,windows在伺服器端的效率,穩定性,實例都比較少,不符合題主要求,而windows Server不管是跑Apache還是nginx都有點蛋疼。本人天生對伺服器的windows絕緣,就好像天生對桌面端的Linux不感冒一樣

其次,比較Apache和nginx。Apache體積龐大,功能複雜,跑小網站或者做開發效率不高,不是太合適

nginx輕量級,處理靜態效率很高,處理PHP代碼是埠轉發給php-fpm,相比Apache的PHP作為組件個人感覺更好配置。

所以,推薦題主用LNMP(Linux nginx MySQL PHP)這四個好基友吧

翻箱倒櫃找出來了以前寫的搭建lnmp的筆記,順便發出來

安裝準備環境,包括編譯環境,以及nginx和php7依賴的一些包。
編譯環境我安裝了以下三個
yum install gcc gcc-c++ autoconf openssl openssl-devel zlib zlib-devel libxml2 libxml2-devel pcre-deve libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers gdbm-devel libXpm-devel libmcrypt libmcrypt-devel libxslt-devel*
最後的pcre centos7中應該默認是安裝了一個,devel是pcre的開發包,我們需要的是這個包,如果沒有安裝-devel的包,編譯的時候一樣會提示沒有安裝pcre。

MySQL編譯安裝
# rpm -qa | grep mysql #是否安裝了mysql
# rpm -e mysql  // 普通刪除模式
# rpm -e --nodeps mysql  // 強力刪除模式,如果使用上面命令刪除時,提示有依賴的其它文件,則用該命令可以對其進行強力刪除#
#
# groupadd -g 3306 mysql
# useradd mysql -u 3306 -g 3306 -d /nonexistent -s /sbin/nologin
#
# cd /usr/local/src
# wget http://mirrors.sohu.com/mysql/MySQL-5.6/mysql-5.6.29.tar.gz
# tar xvf mysql-5.6.29.tar.gz
# cd mysql-5.6.29
# cmake . -DCMAKE_INSTALL_PREFIX=/data/mysql -DMYSQL_UNIX_ADDR=/data/mysql/run/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_READLINE=1 -DENABLED_LOCAL_INFILE=1 -DMYSQL_DATADIR=/data/mysql/data -DMYSQL_USER=mysql -DMYSQL_TCP_PORT=3306 -DWITH_EXTRA_CHARSETS=all
# make make install make clean
#
注意:在啟動MySQL服務時,會按照一定次序搜索my.cnf,先在/etc目錄下找,找不到則會搜索"$basedir/my.cnf",在本例中就是 /data/mysql/my.cnf,這是新版MySQL的配置文件的默認位置!
注意:在CentOS 6.4版操作系統的最小安裝完成後,在/etc目錄下會存在一個my.cnf,需要將此文件更名為其他的名字,如:/etc/my.cnf.bak,否則,該文件會干擾源碼安裝的MySQL的正確配置,造成無法啟動。
注意:在使用"yum update"更新系統後,需要檢查下/etc目錄下是否會多出一個my.cnf,如果多出,將它重命名成別的。否則,MySQL將使用這個配置文件啟動,可能造成無法正常啟動等問題。
#
# rm /etc/my.cnf
#
# vi /data/mysql/my.cnf
#
###################### start my.cnf ###########################
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html
# *** DO NOT EDIT THIS FILE. Its a template which will be copied to the
# *** default location during install, and will be replaced if you
# *** upgrade to a newer version of MySQL.

[client]
port=3306
socket=/data/mysql/run/mysql.sock

[mysqld]

# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M

# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin

# These are commonly set, remove the # and set as required.
user = mysql
basedir = /data/mysql
datadir = /data/mysql/data
port=3306
server-id = 1
socket=/data/mysql/run/mysql.sock

character-set-server = utf8
log-error = /log/mysql/error.log
pid-file = /data/mysql/run/mysql.pid
general_log = 1
skip-name-resolve
#skip-networking
back_log = 300

max_connections = 1000
max_connect_errors = 6000
open_files_limit = 65535
table_open_cache = 128
max_allowed_packet = 4M
binlog_cache_size = 1M
max_heap_table_size = 8M
tmp_table_size = 16M

read_buffer_size = 2M
read_rnd_buffer_size = 8M
sort_buffer_size = 8M
join_buffer_size = 28M
key_buffer_size = 4M
thread_cache_size = 8
query_cache_type = 1
query_cache_size = 8M
query_cache_limit = 2M
ft_min_word_len = 4
log_bin = mysql-bin
binlog_format = mixed
expire_logs_days = 30
performance_schema = 0
explicit_defaults_for_timestamp
#lower_case_table_names = 1
myisam_sort_buffer_size = 8M
myisam_repair_threads = 1
interactive_timeout = 28800
wait_timeout = 28800
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

# Recommended in standard MySQL setup
sql_mode=NO_ENGINE_SUBSTITUTION,NO_AUTO_CREATE_USER,STRICT_TRANS_TABLES

[mysqldump]
quick
max_allowed_packet = 16M

[myisamchk]
key_buffer_size = 8M
sort_buffer_size = 8M
read_buffer = 4M
write_buffer = 4M
########################## end my.cnf ############################
#
# mkdir /log/mysql/
# mkdir /data/mysql/run
# chown -R mysql:mysql /data/mysql/

# /data/mysql/scripts/mysql_install_db --user=mysql --basedir=/data/mysql --datadir=/data/mysql/data
# /data/mysql/bin/mysqld_safe
# /data/mysql/bin/mysql -uroot -p #輸入密碼的時候,直接回車
mysql&> use mysql;
mysql&> UPDATE `user` SET `Password`=PASSWORD(123456) WHERE `User`=root;
mysql&> flush privileges;
#
# ps -ef | grep mysql #查找mysql的pid
mysql 54778 54702 0 15:59 pts/1 00:00:00 /data/mysql/bin/mysqld
# cat /data/mysql/run/mysql.pid #查找mysql的pid
54778
# kill 54778 #結束mysql進程
#
# ps -aux | grep mysql
#

PHP編譯安裝
#
# cd /usr/local/src/
# wget http://mirrors.sohu.com/php/php-7.0.4.tar.gz
# tar -zxvf php-7.0.4.tar.gz
# cd php-7.0.4
# ./configure --prefix=/data/php --with-gdbm --with-fpm-group=www --with-fpm-user=www --with-gettext --with-pear --enable-pcntl --enable-ftp --enable-sysvsem --enable-shmop --enable-bcmath --enable-shared --disable-rpath --enable-debug --with-openssl --with-mhash --with-mcrypt --with-mysql-sock=/data/mysql/run/mysql.sock --with-config-file-path=/data/php/etc --mandir=/data/php/man --libdir=/data/php/lib --includedir=/data/php/include --sbindir=/data/php/sbin --bindir=/data/php/bin --with-gd --with-jpeg-dir --with-freetype-dir --enable-sockets --enable-fpm --enable-mbstring --enable-soap --with-iconv-dir --with-png-dir --with-zlib --with-libxml-dir --with-curl --enable-gd-native-ttf --with-xmlrpc --enable-zip --enable-mysqlnd --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd --with-bz2 --with-xsl --with-xpm-dir
#
# make clean make make test make install make clean
#
# mkdir /log/php
# mkdir /data/php/session
# mkdir /data/php/run
# groupadd -g 80 www
# useradd www -u 80 -g 80 -d /nonexistent -s /sbin/nologin
#
# cp php.ini-production /data/php/etc/php.ini
# cp sapi/fpm/init.d.php-fpm /data/php/etc/php-fpm #因為php5.3開始自帶fpm,使用自帶的管理腳本
# cd /data/php/etc/
# chmod 755 php-fpm
# cp php-fpm.conf.default php-fpm.conf
# vi php-fpm.conf
#
############### php-fpm.conf相關內容改成如下 ##############
pid = /data/php/run/php-fpm.pid
error_log = /log/php/php-fpm.log
##############################################################
#
# chown -R www:www /data/php
# chown -R www:www /log/php
# vi php.ini
#
################## php.ini相關內容改成如下 ################
error_log = /log/php/php_errors.log
upload_max_filesize = 8M
extension_dir = "/data/php/include/php/ext"
cgi.fix_pathinfo=0
###############################################################
#
# cp /data/php/etc/php-fpm.d/www.conf.default /data/php/etc/php-fpm.d/www.conf
# vi /data/php/etc/php-fpm.d/www.conf
#
################## www.conf相關內容改成如下 ################
access.log = /log/php/$pool.access.log
################## www.conf end ################
#
# vi /data/php/etc/php-fpm
################## php-fpm ################
php_fpm_PID=${prefix}/run/php-fpm.pid
################## php-fpm end ################
# /data/php/etc/php-fpm start
#
#

Nginx編譯安裝
#
# cd /usr/local/src
# wget http://mirrors.sohu.com/nginx/nginx-1.9.9.tar.gz
# tar -zxvf nginx-1.9.9.tar.gz
# cd nginx-1.9.9
# ./configure --prefix=/data/nginx --sbin-path=/data/nginx/sbin/nginx --conf-path=/data/nginx/conf/nginx.conf --error-log-path=/log/nginx/error.log --pid-path=/data/nginx/run/nginx.pid --lock-path=/data/nginx/run/nginx.lock --http-log-path=/log/nginx/access.log --user=www --group=www --with-http_ssl_module --with-http_dav_module --with-http_flv_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_stub_status_module --with-http_sub_module --with-http_random_index_module --with-http_degradation_module --with-http_secure_link_module --with-http_gzip_static_module --with-http_perl_module --with-pcre --with-file-aio --with-mail --with-mail_ssl_module --http-client-body-temp-path=/data/nginx/run/client_body --http-proxy-temp-path=/data/nginx/run/proxy --http-fastcgi-temp-path=/data/nginx/run/fastcgi --http-uwsgi-temp-path=/data/nginx/run/uwsgi --http-scgi-temp-path=/data/nginx/run/scgi --with-stream --with-ld-opt="-Wl,-E" --with-debug
# make make install make clean
#
# cat /proc/cpuinfo #查看cpu核心數
修改Nginx配置文件nginx.conf
#
# mv /data/nginx/conf/nginx.conf /data/nginx/conf/nginx_bak.conf
# vi /data/nginx/conf/nginx.conf
添加以下內容
#
################ nginx.conf #########################
user www www;
worker_processes 2; #進程數,與CPU核心數對應(包括邏輯核心),IO開銷不大的設置為1也沒問題
#error_log /data/nginx/logs/error.log crit;
error_log /log/nginx/error.log info;
pid /data/nginx/run/nginx.pid;

#Specifies the value for maximum file descriptors that can be opened by this process.
worker_rlimit_nofile 51200;

events
{
use epoll;
worker_connections 51200; #單進程最大連接數
#debug_connection 192.168.1.161; #只對來自192.168.1.161的連接進行調試信息的記錄
}

http
{
include mime.types;
default_type application/octet-stream;
charset utf-8;
#charset gb2312;
server_names_hash_bucket_size 128;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;

#fastcgi_connect_timeout 60;
#fastcgi_send_timeout 180;
#fastcgi_read_timeout 180;
#20080730 by milala
#for 502 error (bad gateway)
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
client_max_body_size 100m;

#20090114 by milala for 400 error
client_header_buffer_size 128k;
large_client_header_buffers 4 128k;

fastcgi_buffer_size 128k;
fastcgi_buffers 4 128k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
fastcgi_temp_path /tmp;

gzip on;
gzip_min_length 1k;
gzip_buffers 4 8k;
gzip_http_version 1.1;
gzip_comp_level 3;
#20090304milala
#gzip_types text/plain application/x-javascript text/css text/html application/xml application/x-httpd-php !application/x-httpd-jphp;
#gzip_types text/plain text/css application/xml;
gzip_types text/plain text/css application/xml text/javascript application/javascript application/x-javascript application/x-httpd-php;
gzip_disable "MSIE [1-6].";

#log_format access $remote_addr $server_name - $remote_user [$time_local] "$request"
log_format access $remote_addr - $remote_user [$time_local] $server_name "$request"
$status $body_bytes_sent "$http_referer"
"$http_user_agent";
#access_log /data/nginx/logs/nginx.log access;
access_log /log/nginx/nginx.log access;

index index.html index.htm index.php;
#error_page 404 http://www.lg69.com/404.html;

include /data/nginx/conf/pub/*.conf;
#include pub/*.conf;
#include private/*.conf;
}
################ nginx.conf #########################
#
添加一個網站配置文件localhost.conf
#
#
# mkdir /data/nginx/conf/pub
# vi /data/nginx/conf/pub/localhost.conf
#
################ localhost.conf #########################
server
{
listen 80;
server_name localhost 127.0.0.1 192.168.1.220;
root /site/domain/localhost/htdocs;
index index.php index.html index.htm;
location ~ .*.(php|jphp)?$
{
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}
# if ($request_filename !~ "s|g|fckeditor|new.(js|htc|ico|gif|jpg|png|css|php|htm)$")
# {
# rewrite ^/(.*) /public_index.php?k=$1 last;
# }
rewrite "^/(.*).pl" /init.php?$1 last;
access_log /log/domain/localhost/access.log access;
}
################ localhost.conf #########################
#
#
配置nginx的fastcgi.conf文件
#
# mv /data/nginx/conf/fastcgi.conf /data/nginx/conf/fastcgi.conf.bak
# vi /data/nginx/conf/fastcgi.conf
################ fastcgi.conf #########################
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 only, required if PHP was built with --enable-force-cgi-redirect force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
################ fastcgi.conf end ##########################
#
# mkdir /log/domain
# mkdir /log/domain/localhost
# mkdir /site/domain/localhost
# mkdir /site/domain/localhost/htdocs
# chown -R www:www /log/domain
# chown -R www:www /log/nginx
# vi /site/domain/localhost/htdocs/index.htm
#
################ index.htm #########################
1234
################ index.htm #########################
#
# /data/nginx/sbin/nginx
# 測試一下頁面能否打開
#


普通公司什麼都不管就那麼寫的php代碼的話,apache性能最高,代碼可以針對優化的話,nginx(php-fpm)最高。


Windows 下跑 IIS 是首選;Nginx 在 Windows 下性能不佳,不用考慮;Apache 的並發性能不如 IIS,但也不是不能用。

Linux 下 Nginx 和 Apache 都是很成熟很穩定的 HTTP server。Nginx 並發性能比 Apache 好,還比 Apache 省內存。

關於 LANMP,那是因為以前用 Apache 跑 mod_php 的性能比 Nginx 用 fastcgi 要好,而 Nginx 並發高,所以有人 Nginx Apache 混著用。但現在都 PHP7 了,再開個 opcache,單純用 Nginx 跑 PHP 性能也很好了。

另外我曾經看到過一個調侃:「為什麼偶爾能看到用 Nginx 的網站報 502,而幾乎看不到用 Apache 的網站報 502?」——「那是因為如果把 Nginx 換成 Apache 的話,Apache 早就死翹翹了。」

另外用 F5 刷新測性能什麼鬼。。。

2G 內存不算大,建議用 Linux + Nginx + php-fpm,最好是 PHP7,性能比 PHP5 高太多。


基本不會考慮IIS,這年頭生產環境用windows跑php的網站都是奇葩。apache與nginx個人覺得不太有可比性,只能說nginx處理靜態資源更好,它跑php用的還是phpfpm。


其實我感覺都差不多。。如果能不ts的話應該性能會高點?還有就是cgi和fcgi差別什麼的了


推薦閱讀:

你覺得最實用的linux腳本哪些?
像蘋果Time Machine 一樣備份Linux伺服器(基於rsync)
你的Ubuntu還可以這麼美
重磅推薦:10個你非常熟悉的Linux終端遊戲
Linux 下的 C++ 開發和 Windows 環境下的開發有什麼區別?

TAG:Web開發 | PHP | Linux | 運維 | Linux運維 |