一、Nginx介绍
Nginx(发音同 engine x)是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,。
最早由俄罗斯的程序设计师Igor Sysoev所开发,并在一个BSD-like 协议下发行。
其特点是轻量级,占有内存少,并发能力强,目前发展势头强劲.
web领域最经典的lamp组合已变成lnmp组合.
编译安装:
到官方网站 http://nginx.org 寻找最新stable版,下载
例当前最新: http://nginx.org/download/nginx-1.4.7.tar.gz
安装准备: nginx依赖于pcre库,要先安装pcre,因为nginx要在rewrite时要解析正则表达式,PCRE是正则解析库
#yum install pcre pcre-devel #cd /usr/local/src/ #wget http://nginx.org/download/nginx-1.4.2.tar.gz # tar zxvf nginx-1.4.2.tar.gz #cd nginx-1.4.2 ./configure --prefix=/usr/local/nginx #make && make install
nginx目录介绍:
cd /ulsr/local/nginx, 看到如下4个目录
./
....conf 配置文件
... html 网页文件
...logs 日志文件
...sbin 主要二进制程序
启动nginx
# cd /usr/local/nginx
# ./sbin/nginx
没有出现错误提示,则启动成功了.
如果有错误,则根据错误提示再做处理.
常见的错误是”80端口被占用
Nginx命令参数
nginx程序也可以一些参数,达到效果 如: nginx -t 测试配置是否正确 nginx -s reload , 作用:加载最新配置 nginx -s stop 作用: 立即停止 nginx -s quit 作用: 优雅停止 nginx -s reopen 作用: 重新打开日志
二、Nginx配置
conf文件详解
// 全局区 // 有1个工作的子进程,可以自行修改,但太大无益,因为要争夺CPU, // 一般设置为 CPU数*核数 worker_processes 1; Events { // 一般是配置nginx连接的特性 // 如1个worker能同时允许多少连接 worker_connections 1024; // 这是指 一个子进程最大允许连1024个连接 } http { //这是配置http服务器的主要段 Server1 { // 这是虚拟主机段 Location { //定位,把特殊的路径或文件再次定位 ,如image目录单独处理 } /// 如.php单独处理 } Server2 { } }
Nginx配置虚拟主机
1: 基于域名的虚拟主机
server { listen 80; #监听端口 server_name a.com; #监听域名,如有多个,空格隔开 location / { root /var/www/a.com; #根目录定位 index index.html; #默认索引页 } }
2: 基于端口的虚拟主机配置
server { listen 8080; server_name a.com; location / { root /var/www/html8080; index index.html; } }
日志管理
我们观察nginx的server段,可以看到如下类似信息
access_log logs/access.log main;
这说明 该server, 它的访问日志的文件是 logs/host.access.log ,
日志格式”main”格式.
main格式是什么? log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; 除了main格式,你可以自定义其他格式. log_format mylog '$remote_addr [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent"';
server { listen 80; #下面声明a.com使用mylog格式日志,并保存在logs/a.com.log文件中 access_log logs/a.com.log mylog; server_name a.com www.a.com; .... }
main格式是我们定义好一种日志的格式,并起个名字,便于引用.
以上面的例子, main类型的日志,记录的 remote_addr.... http_x_forwarded_for等选项.
1: 日志格式 是指记录哪些选项
默认的日志格式: main
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
如默认的main日志格式,记录这么几项
远程IP- 远程用户/用户时间 请求方法(如GET/POST) 请求体body长度 referer来源信息
http-user-agent用户代理/蜘蛛 ,被转发的请求的原始IP
http_x_forwarded_for:在经过代理时,代理把你的本来IP加在此头信息中,传输你的原始IP
实际应用: shell+定时任务+nginx信号管理,完成日志按日期存储
分析思路:
凌晨00:00:01,把昨天的日志重命名,放在相应的目录下
再USR1信息号控制nginx重新生成新的日志文件
具体脚本:
#!/bin/bash base_path='/usr/local/nginx/logs' log_path=$(date -d yesterday +"%Y%m") day=$(date -d yesterday +"%d") mkdir -p $base_path/$log_path mv $base_path/access.log $base_path/$log_path/access_$day.log #echo $base_path/$log_path/access_$day.log /usr/local/nginx/sbin/nginx -s reopen
定时任务
Crontab 编辑定时任务 01 00 * * * /xxx/path/b.sh 每天0时1分(建议在02-04点之间,系统负载小)
三、Nginx 与PHP整合
nginx+php的编译:
apache一般是把php当做自己的一个模块来启动的.
而nginx则是把http请求变量(如get,user_agent等)转发给 php进程,即php独立进程,与nginx进行通信. 称为 fastcgi运行方式.
因此,为apache所编译的php,是不能用于nginx的.
注意: 我们编译的PHP 要有如下功能:
连接mysql, gd, ttf, 以fpm(fascgi)方式运行
./configure --prefix=/usr/local/fastphp \ --with-mysql=mysqlnd \ --enable-mysqlnd \ --with-gd \ --enable-gd-native-ttf \ --enable-gd-jis-conv \ --enable-fpm
编译完毕后, copy配置文件
cp /path/to/php-fpm.conf.default /path/to/php-fpm.conf
nginx+php的配置比较简单,核心就一句话----
把请求的信息转发给9000端口的PHP进程,
让PHP进程处理 指定目录下的PHP文件.
如下例子: location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
说明:
1:碰到php文件,
2: 把根目录定位到 html,
3: 把请求上下文转交给9000端口PHP进程,
4: 并告诉PHP进程,当前的脚本是 $document_root$fastcgi_scriptname
Nginx与Rewrite规则
Rewrite语法
Rewrite 正则表达式 定向后的位置 模式
例子:Goods-3.html ---->Goods.php?goods_id=3
goods-([\d]+)\.html ---> goods.php?goods_id =$1 location / { index index.php; rewrite goods-([\d]+)\.html$ /ecshop/goods.php?id=$1; }
注意:用url重写时, 正则里如果有”{}”,正则要用双引号包起来
pathinfo支持
# 典型配置 location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $DOCUMENT_ROOT$fastcgi_script_name; include fastcgi_params; } # 修改第1,5,6行,支持pathinfo location ~ \.php(.*) { # 正则匹配.php前后的script_name和pathinfo部分 root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $DOCUMENT_ROOT$fastcgi_script_name; fastcgi_param PATH_INFO $1; # 把pathinfo部分赋给PATH_INFO变量 include fastcgi_params; }
四、优化
用nginx做反向代理用proxy_pass
以反向代理为例, nginx不自己处理图片的相关请求,而是把图片的请求转发给apache来处理.

----这就是传说的”动静分离”,动静分离不是一个严谨的说法,叫反向代理比较规范.
配置如下:
location ~ \.(jpg|jpeg|png|gif)$ { proxy_pass HTTP://IP:port; }
1: 反向代理导致了后端服务器接到的客户端IP,为前端服务器的IP,而不是客户真正的IP,怎么办?
答: 代理服务器通过设置头信息字段,把用户IP传到后台服务器去.
如:
location ~ \.(jpg|jpeg|png|gif)$ { proxy_set_header X-Forwarded-For $remote_addr; proxy_pass IP:port; }
2:在apache的日志格式里加上X-forwarded-For,如下:
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b" common
3: 如果后端的服务器非常多,该如何写? 又如何均匀的分发任务?(负载均衡)
Nginx集群与负载均衡
反向代理+负载均衡
在nginx中做集群与负载均衡,步骤都是一样的
Upstream {}模块 把多台服务器加入到一个组
然后 memcached_pass, fastcgi_pass, proxy_pass ==> upstream组
具体配置步骤:
1:配置upstream
upstream imageserver { server 192.168.1.204:8080 weight=1 max_fails=2 fail_timeout=30s; server 192.168.1.204:8081 weight=1 max_fails=2 fail_timeout=30s; }
2: 下游调用
location ~ \.(jpg|jpeg|png|gif)$ { proxy_set_header X-Forwarded-For $remote_addr; proxy_pass http://imageserver; }
默认的负载均衡的算法:
是设置计数器,轮流请求N台服务器.
可以安装第3方模式,来利用不同参数把请求均衡到不同服务器去
如基于cookie值区别用户做负载均衡(nginx sticky 模块)
或基于URI利用一致性哈希算法做均衡(NginxHttpUpstreamConsistentHash模块)
或基于IP做负载均衡等.
番外篇
1、静态代理



2、负载均衡架构案例
1、架构图

2、负载均衡服务器配置(nginx.conf)


3、静态资源服务器配置(nginx81.conf,nginx82.conf)


浙公网安备 33010602011771号