Nginx ("engine x") 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器
在高并发连接的情况下,Nginx是Apache服务器不错的替代品。Nginx同时也可以作为7层负载均衡服务器来使用
Nginx 0.8.46 + PHP 5.2.14 (FastCGI) 可以承受3万以上的并发连接数,相当于同等环境下Apache的10倍
为什么Nginx的性能要比Apache高得多?这得益于Nginx使用了最新的epoll(Linux 2.6内核)和kqueue(freebsd)网络I/O模型,而Apache则使用的是传统的select模型。目前Linux下能够承受高并发访问的Squid、Memcached都采用的是epoll网络I/O模型。
处理大量的连接的读写,Apache所采用的select网络I/O模型非常低效。下面用一个比喻来解析Apache采用的select模型和Nginx采用的epoll模型进行之间的区别:
假设你在大学读书,住的宿舍楼有很多间房间,你的朋友要来找你。select版宿管大妈就会带着你的朋友挨个房间去找,直到找到你为止。而epoll版宿管大妈会先记下每位同学的房间号,你的朋友来时,只需告诉你的朋友你住在哪个房间即可,不用亲自带着你的朋友满大楼找人。如果来了10000个人,都要找自己住这栋楼的同学时,select版和epoll版宿管大妈,谁的效率更高,不言自明。同理,在高并发服务器中,轮询I/O是最耗时间的操作之一,select和epoll的性能谁的性能更高,同样十分明了
Lnmp的部署
Linux+ Nginx + Mysql + Php
*.html---> Nignx ----> clients
*.php ---> Nginx -----tcp/ip 或 socket ---> php-cgi进程 ---> Nginx ---> clients
建议部署顺序: Nginx ----> mysql-server----> php和相关模块
一、安装nginx时必须先安装相应的编译工具
yum -y install gcc gcc-c++ autoconf automake
yum -y install zlib zlib-devel openssl openssl-devel pcre-devel
建立nginx 组
groupadd -r nginx
useradd -s /sbin/nologin -g nginx -r nginx
id nginx
zlib:nginx提供gzip模块,需要zlib库支持
openssl:nginx提供ssl功能
pcre:支持地址重写rewrite功能
一、安装Nginx
pcre-8.12.tar.gz
# tar xvf pcre-8.12.tar.gz -C /usr/src
# cd /usr/src/pcre-8.12/
# ./configure && make &&make install
nginx-1.0.15.tar.gz
# ./configure --prefix=/usr/local/nginx--with-pcre --user=daemon --group=daemon --with-http_stub_status_module
# make -j4 && make install
为了方便执行该命令:
# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
简单配置nginx,能够简单运行静态页面
# cd /usr/local/nginx
# vim conf/nginx.conf
user daemon;
worker_processes 1;
error_log logs/error.log info;
pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local]"$request" '
'$status $body_bytes_sent"$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
access_log logs/host.access.log main;
location / {
root html; 《---网站根目录
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
启动nginx:
启动之前,80端口没有被apache 占用
如果占用 kill -9 uid.
# /usr/local/nginx/sbin/nginx
# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 5915 root 6u IPv4 36698 0t0 TCP *:http (LISTEN)
nginx 5916 daemon 6u IPv4 36698 0t0 TCP *:http (LISTEN)
测试:
# elinks http://localhost
关闭和重载配置文件
# nginx -s stop
# nginx -s reload
二、部署mysql-server
源码包:略
rpm包: mysql mysql-servermysql-devel mysql-libs
确保数据库能够使用
三、部署php
1、安装一些依赖的模块包
# yum install -y libtool libtool-libsautoconf libjpeg libjpeg-devel libpnglibpng-devel freetype freetype-devellibxml2 libxml2-devel zlib zlib-devel glib2 glib2-devel bzip2 bzip2-develncurses ncurses-devel curl curl-devel libidn libidn-devel openssl openssl-devel gmp-devel unzip libcap fontconfig fontconfig-devel libXpm libXpm-devel--nogpgcheck
64位平台php不能识别libXpm的64位版本,所以安装32位
# yum install libXpm.i686 libXpm-devel.i686libjpeg.i686 libjpeg-devel.i686 libpng.i686 libpng-devel.i686 freetype.i686 freetype-devel.i686 -y
后面很多依赖包都是以库文件的形式出现,让第三方程序调用,所以很多时候需要告诉操作系统,这些库文件的存放(想操作系统注册该库文件):
# vim /etc/ld.so.conf
...
/usr/local/lib <---增加
...
# ldconfig <---让操作系统刷新主库库的列表
libevent-1.4.11-stable.tar.gz
# ./configure && make -j4&& make install
libmcrypt-2.5.8.tar.gz
# cd /usr/src/libmcrypt-2.5.8/
# ./configure && make -j4&& make install
# cd libltdl/ <---特别说明:进入子目录继续编译两外一个源码
# ./configure --enable-ltdl-install && make -j4 && make install
mhash-0.9.9.9.tar.gz
# ./configure && make -j4&& make install
mcrypt-2.6.8.tar.gz
# ./configure && make -j4&& make install
libiconv-1.14.tar.gz
# ./configure && make -j4&& make install
gd-2.0.35.tar.gz
# ./configure --with-libiconv-prefix=/usr
如果报错,报和libiconv相关的错误,那么就先执行ldconfig更新以下注册库,然后在./configure
# make -j4 && make install
# ldconfig
2、编译全新的php
如果之前编译过,删除编译过的源码包
# cd /usr/src/php-5.4.8
# make uninstall
# rm -rf /usr/src/php-5.4.8/
# rm -rf /usr/local/php/
新版本: php-5.4.8.tar.bz2
# tar xvf php-5.4.8.tar.gz-C /usr/src
# cd /usr/src/php-5.4.8/
# ./configure --prefix=/usr/local/php --with-zlib --with-curl --enable-ftp--with-gd --with-jpeg-dir --with-png-dir --with-zlib-dir --with-xpm-dir--with-freetype-dir --enable-mbstring --with-mcrypt --with-mhash --with-ncurses --with-libxml-dir--with-iconv-dir=/usr --enable-zip --enable-mysqlnd --with-mysql=mysqlnd --with-mysqli=mysqlnd--with-pdo-mysql=mysqlnd --enable-fpm --with-fpm-user=daemon --with-fpm-group=daemon --with-config-file-scan-dir=/usr/local/etc/ --with-config-file-path=/usr/local/php/lib/
参数说明
今天使用 --enable-mysqlnd --with-mysql=mysqlnd--with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd
--enable-mysqlnd 使用的是php-5.3版本以后自身带的连接mysql数据库的代码,不再依赖mysql接口文件。
--enable-fpm 是php的一个附带功能,该功能可以实现平滑地启动php-cgi进程,就像启动/关闭服务一样,非常方便。
--with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd
@@@@@@@@@@@
# make ZEND_EXTRA_LIBS='-liconv' -j4 <---- 一定带这样的参数编译
# make install
拷贝php的模板配置文件到php能够识别的路径中:
# cp /usr/src/php-5.4.8/php.ini-production/usr/local/php/lib/php.ini
注意: rpm包安装的php,读取的配置文件实在/etc/php.ini
我们自己安装的源码包读取的路径得看具体的编译参数,如果没有指定,一般就在/path/to/install-dir/lib/目录
/path/to/install-dir是由--prefix=....指定
# vim /usr/local/php/lib/php.ini
display_errors = On <---目前还在测试环境,所以把错误输出功能打开,部署在生产环境的时候应该关闭
mysql.default_socket =/data/mysqld.sock <---根据实际情况指定本机上数据库的socket文件路径
mysqli.default_socket =/data/mysqld.sock <---根据实际情况指定本机上数据库的socket文件路径
配置php-fpm
# cp /usr/src/php-5.4.8/sapi/fpm/php-fpm.conf /usr/local/php/etc/php-fpm.conf
# vim /usr/local/php/etc/php-fpm.conf
...
listen = 127.0.0.1:9000 不用修改,原本就有
....
# cp /usr/src/php-5.4.8/sapi/fpm/init.d.php-fpm /etc/rc.d/init.d/php-fpm
# chmod 755 /etc/rc.d/init.d/php-fpm
启动php-fpm服务(其实就是启动php相关进程,接受nginx的请求)
# service php-fpm start
# lsof -i:9000
如果在此时报错找不到 uid ,到vim /usr/local/php/etc/php-fpm.conf 将user 和group 改为naginx的用户和组。
添加软连接,方便执行
# ln -s /usr/local/php/bin/* /usr/local/bin/
3、在编译完成php之后,安装一些php的动态模块
1)让php支持连接memcached分布式内存/缓存服务器
# tar xvf memcache-3.0.6.tgz-C /usr/src/
# cd /usr/src/memcache-3.0.6/
# /usr/local/php/bin/phpize
Configuring for:
PHP Api Version: 20041225
Zend Module Api No: 20060613
Zend Extension Api No: 220060519
# ./configure--with-php-config=/usr/local/php/bin/php-config
# make -j4 && make install
....安装后的提示
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/ <---编译好的memcache.so模块安装在该目录下
2)安装php加速模块eaccelerator
# tar xvfeaccelerator-eaccelerator-42067ac.tar.gz -C /usr/src
# cd/usr/src/eaccelerator-eaccelerator-42067ac/
# /usr/local/php/bin/phpize
# ./configure--with-php-config=/usr/local/php/bin/php-config
# make -j4 && make install
# make install
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/
3)告诉php去加载刚才编译的扩展模块
# vim /usr/local/php/lib/php.ini
extension_dir ="/usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/" <---把原来的extension_dir = "./" 修改
extension = memcache.so <---自己添加的
[eaccelerator] <--整段都是自己添加的
zend_extension="/usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/eaccelerator.so"
eaccelerator.shm_size="16"
eaccelerator.cache_dir="/tmp/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
# mkdir /tmp/eaccelerator
# chmod 0777 /tmp/eaccelerator
验证php之否识别或者加载了刚才指定的模块
# /usr/local/php/bin/php -m
...
memcache
...
[Zend Modules]
eAccelerator <---
四、把php和nginx整合,需要修改nginx的配置文件
# vim /usr/local/nginx/conf/nginx.conf
user daemon;
worker_processes 1;
error_log logs/error.log info;
pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local]"$request" '
'$status $body_bytes_sent"$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
access_log logs/host.access.log main;
location / {
root html; <--- root 定义网站根目录的参数
index index.php index.html index.htm; <---添加index.php
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000; <---unix://tmp/php.sock
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; <---记得修改$document_root
include fastcgi_params;
}
}
}
修改了配置文件,在重载配置之前,先检测语法是否正确
# nginx -t
nginx: the configuration file/usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file/usr/local/nginx/conf/nginx.conf test is successful
重新,按照新配置运行
# nginx -s reload
建立测试页面:
# vim /usr/local/nginx/html/test.php
<?php
phpinfo();
?>
例子:以虚拟主机的形式新建一个网站,部署一个论坛 ????????????????
网站目录定义在/web/bbs.upl.com/wwwroot
# vim /usr/local/nginx/conf/nginx.conf
.....
http{
server {
.....
}
server {
listen 80;
server_name bbs.upl.com;
access_log logs/bbs.access.log main;
location / {
root /web/bbs.upl.com/wwwroot;
index index.html index.htmindex.php;
}
location ~ \.php$ {
root /web/bbs.upl.com/wwwroot;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
include fastcgi_params;
}
location/status
{
stub_status on;
}
}
}
# nginx -s reload
# mkdir -p /web/bbs.upl.com/wwwroot
# unzip phpwind_UTF8_8.7.zip
# mv phpwind_UTF8_8.7/upload/* /web/bbs.upl.com/wwwroot/
# chown daemon:daemon -R/web/bbs.upl.com/wwwroot/
建立相应的数据库
mysql>create database phpwind default charset utf8;
mysql>use phpwind;
mysql>create table users(
id int unsinged not null primary key auto_increment,
name varchar2(32),
passwd varchar2(64));
mysql>insert into users values (null,'admin',password('123'));
mysql> grant all on phpwind.* to admin@'localhost' identified by 'admin';
mysql>flush privileges;
mysql -u admin -padmin
mysql>show databases;
=================================================================
http://bbs.upl.com /
http://bbs.upl.com /images/log.png
http://bbs.upl.com /index.php.ini
按以上步骤结果报错了:
我已经建立了phpwind 数据库了。
错误在于php.ini 配置错误。
重新配置 /usr/local/php/lib/php.ini
由于在编译php时候将配置文件指定在/etc 下,所以将/usr/local/php/lib/php.ini 文件cp到/etc下 在编译。
如果想看php再那块 则需要,在网站目录下建立 测试页面test.php
重启 php-fpm。
location
syntax: location [=|~|~*|^~|@] /uri/ { ...}
default: no
context: server
~ 大小写敏感的正则表达式匹配
^~ 以什么开头的
~* 忽略大小写的正则表达式匹配
优先级:精确匹配 = ---> 正则表达式 ---> 正则表达式之间优先级是按先后 --> 没有符号的location
location = / { 《--- = 精确匹配,只能http://bbs.upl.com/
#matches the query / only.
[configuration A ]
}
location / { 《--- 优先级最低的匹配,但是所有请求都几乎匹配它(除了精确匹配),因为所有的请求都是要从“/”开始
#matches any query, since all queries begin with /, but regular
#expressions and any longer conventional blocks will be
#matched first.
[configuration B ]
}
location ^~ /images/ { <--- 匹配 http://bbs.upl.com /images/xxxxxx
#matches any query beginning with /images/ and halts searching,
#so regular expressions will not be checked.
[configuration C ]
}
location ~* \.(gif|jpg|jpeg)$ { <--- 匹配以 .gif等结尾的请求
#matches any request ending in gif, jpg, or jpeg. However, all
#requests to the /images/ directory will be handled by
#Configuration C.
[configuration D ]
Example requests:
*/ -> configuration A 《---http://bbs.upl.com/
*/documents/document.html -> configuration B
*/images/1.gif -> configuration C
*/documents/1.jpg -> configuration D
通过查看官档。实现访问控制
1、某些目录的访问需要输入用户名和密码
/admin.php 需要输入帐号为uplooking,密码为12345678
2、某些目录的访问禁止某些ip的访问
/secret/只允许10.1.1.0/24访问。
# htpasswd -c /usr/local/nginx/conf/htpasswduplooking
# vim /usr/local/nginx/conf/nginx.conf
....
location = /admin.php {
auth_basic "Restricted";
auth_basic_user_file htpasswd;
root /web/bbs.upl.com/wwwroot;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
include fastcgi_params;
}
location ^~ /secret/ {
root /web/bbs.upl.com/wwwroot;
allow 10.1.1.0/24;
deny all;
}