Nginx教程

Nginx教程


1.背景


介绍
Nginx是一个高性能的HTTP服务器,以及反向代理服务器

组成
Ngnix有内核和模块组成。微结构的内核根据配置文件将一个请求映射到一个location块中,该location内的指令会启动模块来工作。

模块分类(结构上)
核心类
HTTP、EVENT,以及MAIL模块。
基础类
HTTP的Access、FastCGI、Proxy,以及Rewrite模块。
第三方类
HTTP的 Upstream Request Hash、Access Key模块,以及Notice模块。

模块分类(功能上)
Handlers(处理器):处理请求并输出和修改handlers信息,一般只能有一个。
Filters(过滤器):对Handlers处理过的内容进行修改,最后由Nginx输出,可以有多个。
Proxies(代理类):HTTP Upstream之类,常与后端的服务,如fastcgi交互,实现服务代理和负载均衡功能。
处理请求的过程所经过的模块: --> 处理器 --> 过滤器1 [--> 过滤器2 -->过滤器n] --> 

工作模式
工作模式有单工作进程和多工作进程两种。前者是除主进程外,只有一个单线程的工作进程;而后者是多个工作进程,每个进程是多线程的。Nginx默认是单工作进程模式。

优势

作为Web服务器,处理静态文件时索引效率很高
作为代理服务器,实现高效的代理
作为负载均衡服务器,既内部直接支持PHP,也支持代理服务器;同时支持容错和利用算法负载均衡
性能好,采用了Poll模型支持大并发,而且内存占用少
稳定性好,采用分阶段资源分配方式,让CPU和内存占用少
高可用性好,支持热部署,配置修改以及版本更新无需重启服务器

2.Nginx安装运行和测试(CentOS6)


在Centos/Redhat上先配置yum
#/etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
参考自:http://nginx.org/en/linux_packages.html#stable

安装完已经是开机启动的,所以安装完手动启动一下即可
# yum -y install nginx 
# service nginx start 


补充:高级编译安装(下面的实验会用到里面的增强功能)

ngx_cache_purge:http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
google-perftools:https://codeload.github.com/gperftools/gperftools/zip/master


安装正则表达式工具
yum -y install pcre-devel
cd /usr/local/src

安装缓存清理插件
tar xf ngx_cache_purge-2.3.tar.gz

安装高性能组件
tar xf libunwind-1.1.tar.gz
cd libunwind-1.1
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install
cd ..
unzip gperftools-master.zip 
cd gperftools-master
./autogen.sh 
./configure 
make
make install
echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
ldconfig

编译安装nginx
tar xf nginx-1.10.2.tar.gz
ln -s nginx-1.10.2 nginx
cd nginx
./configure --user=nginx --group=nginx
--prefix=/usr/local/nginx
--with-http_stub_status_module
--with-http_gzip_static_module
--with-http_ssl_module
--with-google_perftools_module
--add-module=/usr/local/src/ngx_cache_purge-2.3
make
make install
在做./configure前优化编译过程,将auto/cc/gcc文件下面两行注释掉,不用debug方式编译
# debug
#CFLAGS="$CFLAGS -g"


3.配置文件


层次结构

main
events
HTTP
server1
upstream1
upstream2..n
location1
location2..n
server2..n
main:全局设置
server:主机设置,指定主机和端口
upstream:负载均衡设置,指定一系列后端服务器
location:URL匹配特定位置设置,指定匹配的网页
它们之间的继承关系为:location -> server -> main;而upstream与这三者没有关系
这4个部分包含若干指令,这些指令主要位于主模块、EVENT模块以及HTTP模块中,同时每个部分还可以使用其他HTTP模块命令,例如HTTP SSL、HTTPGzip、HTTPAddition等模块

配置详解

全局配置
user  nginx; 
worker_processes  auto;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
worker_processes: auto会根据主机CPU线程数启动对应数量的工作进程

events配置
events {
    worker_connections  65535;
}
use epoll:已经没有了此配置,因为这是安装包默认的,会根据当前OS平台选择最优的event机制。
worker_connections:每个工作进程打开的连接数。此参数受Linux的进程最大打开文件数限制,需要用ulimit -n 65535对应修改。
客户端最大连接数 = worker_processes * worker_connections。

HTTP配置
http {
    include       /etc/nginx/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"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    tcp_nopush     on;
    keepalive_timeout  65;
    gzip  on;
    include /etc/nginx/conf.d/*.conf;
}
log_format:定义日志格式,这里定义了一个名为main的格式;下面的access_log日志文件的内容由main日志格式定义
sendfile:on开启高效的文件传输模式
tcp_nopush:on开启防止网络阻塞

server配置
server {
    listen              80;
    server_name         localhost;
    charset UIF-8;
    access_log          /var/log/nginx/log/host.access.log  main;
    location / {
        root            /web/wwwroot/localhost;
        index           index.html index.htm;
    }
    location ~ .(gif|jpg|jpeg|png|bmp)$ {
        root            /web/wwwroot/localhost;
        expires         30d;
    }
    location ~ ^/(upload|html) {
        root            /web/wwwroot/localhost;
        expires         30d;
    }
    location ~ .jsp$ {
        proxy_pass              http://localhost:8080;
        index                   index.jsp;
    }
    location /NginxStatus {
        stub_status             on;
        access_log              /var/log/nginx/log/NginxStatus.log;
    }   
error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
从上到下分别是静态文件、动态文件、服务器状态信息、网站错误页面的设置


维护技巧


配置文件校验
检查配置文件语法是否有无
nginx -t [-c $nginx.conf] 
查看nginx版本号
nginx -v
查看编译的模块
nginx -V

启动、关闭,以及重启
几个跟nginx有关的信号
QUIT:处理完请求关闭工作进程
WINCH: 从容关闭工作进程
HUP: 重新加载配置文件,平滑重启
USR1: 日志切换
USR2:平滑升级可执行文件

启动
service nginx start
ps aux | grep nginx
平滑重启
kill -HUP `cat /var/run/nginx.pid`

4.常用功能


反向代理

反向代理服务器能代表所有外部客户端访问,请求内部网络服务,由于它不保存数据,因此能令后端服务器很安全。
反向代理服务器具有本地缓存后就称为web服务加速器


多域名跳转
实现多个域名的访问跳转到后端同一台服务器。
例子,以反向代理服务器A和后端服务器B为例说名,请求以www.tb.com域名从A跳转到B的/web目录,而请求以www.tb.com/admin的URL从A跳转到B的/admin目录,另外请求m.tb.com则从A跳转到B的/wap目录。配置文件代码主要如下:
server {
    listen              80;
    server_name         www.tb.com;
    location / {
        proxy_pass      http://127.0.0.1:8080/web/;
    }
    location /admin {
        proxy_pass      http://127.0.0.1:8080/admin;
    }
}
server {
    listen              80;
    server_name         m.tb.com;
    location / {
        proxy_pass      http://127.0.0.1:8080/wap/;
    }
}
注意,proxy_pass指令启动代理功能,要重点掌握。如果location匹配的是/根目录,则proxy_pass的目标路径需要以/结尾,如果location匹配的是/根目录下的子目录,则此子目录末尾和proxy_pass指定目标路径末尾都不能以/结尾

新旧域名重定向
常见需要重定向的场景有:新旧域名的替换,目录结构、网页文件名,以及文件后续名的变更。例子要求如果客户端访问www.taob.com,则自动跳转到新域名www.tb.com,下面是实现代码
方式一:
server {
    listen       80;
    server_name   www.tb.com;
    location / {
        proxy_pass http://127.0.0.1:8080/web/;
    }
}
server {
    listen       80;
    server_name   www.taob.com;
    rewrite /(.*)$ http://www.tb.com/$1 permanent;
}
启动两个主机,一个做反向代理,一个做重定向

方式二:
server {
    listen       80;
    server_name   www.taob.com www.tb.com;
    location / {
if ( $host != 'www.tb.com' ){
rewrite ^/(.*)$ http://www.tb.com/$1 permanent;
}
    proxy_pass http://127.0.0.1:8080/web/;
    }
}
这里使用了内置的$host变量比较主机名,作为判断是否重定向的条件

注意,rewrite指令启动了重定向功能,需要终点掌握,其最后的参数 permanent 表示永久重定向。


本地访问


别名
server{
listen  80;
server_name     www.tb.com;
location / {
root    /mysite/web/;
}
location /i {
alias /mysite/web/images;
}
}
注意,alias指令启动了别名的功能。
此例中访问http://www.tb.com会指向/mysite/web/目录,而访问http://www.tb.com/i/hello.jpg会指向/mysite/web/images/hello.jpg文件。
通常给子路径指定本地目录需要用到alias指令,也就是常说的起别名。我们通常在配置/目录时使用root指定路径,而配置/xxx子目录时使用alias指定路径。


location的优先级


location [ = | ~ | ~* | ^~ ] uri { ... }
=:表示精确匹配
~:正则表达式匹配,区分大小写
~*:正则表达式匹配,不区分大小写
^~:URI前半部分匹配,可省略

优先级顺序
字符字面量精确匹配 -> 正则表达式匹配 -> 按字符字面量左侧开始匹配
如果存在多个正则表达式同时匹配,优先选择最前面那个,如果存在URI前半部分多个匹配同时存在,优先选择最长前半部分那个匹配。
举例
location = / {
    [ configuration A ]
}
location / {
    [ configuration B ]
}
location /documents/ {
    [ configuration C ]
}
location ^~ /images/ {
    [ configuration D ]
}
location ~* .(gif|jpg|jpeg)$ {
    [ configuration E ]
}
讲解:
/匹配A
/index.html匹配B
/documents/document.html匹配C
/images/1.gif匹配D
/documents/1.jpg匹配E


权限

这里列出了目录权限、IP访问权限,以及文件权限
例一 允许172.16.0.0/24和192.168.68.0/24网段的用户访问,但是192.168.68.1和其他来源IP的用户是不允许的
location / {
root    /mysite/web/;
deny 192.168.68.1;
allow 172.16.0.0/24;
allow 192.168.68.0/24;
deny all;
}
这里重点以allow和deny指令为主

例二 将网页以目录的形式展示
location / {
root   /mysite/web/;
    autoindex on;
autoindex_exact_size on;
autoindex_localtime on;
}
这里重点以autoindex指令为主

例三 禁止访问/WEB-INF/目录
location /WEB-INF/ {
deny all;
}

例三 禁止访问资料文件
location ~* .(txt|doc)$ {
root   /mysite/web/;
deny all;
}


与URL重写相关的命令


if指令

判断表达式1,正则类
~:如果匹配正则表达式,则条件为真
~*:如果匹配正则表达式且不区分大小写,则条件为真
!~:如果不匹配正则表达式,则条件为真
!~*:如果与不区分大小写的正则表达式不匹配,则条件为真
判断表达式2,文件类
-f和!-f:判断是否文件
-d和!-d:判断是否目录
-e和!-e:判断文件或目录是否存在
-x和!-x:判断是否可执行

跟if指令一起使用常见内置变量
$limit_rate:用来限制连接的速度
$request_method
$host:请求头部中的Host
$uri:请求的URI
$request_uri:含有完整参数的初始URI
$args:请求行中的参数
$rquery_string:与$args相等
$request_filename:请求的本地文件绝对路径,有URI与alias、root组成
$document_root:对应当前请求的root指定路径
$document_uri:相当于$uri5gg3

$remote_addr:客户端的IP
$remote_port
$remote_user:用户名,由auth_basic认证
$server_name:请求达到的服务器名
$server_port

例子
server{
listen  80;
server_name     www.tb.com;
location ~* .(jpg|jpeg|bmp|gif|css|js|html|htm)$ {
root    /mysite/web/images/;
if ( !-f $request_filename ) {
root    /mysite/web/css/;
}
if ( !-f $request_filename ) {
root    /mysite/web/js/;
}
if ( !-f $request_filename ) {
root    /mysite/web/static/;
}
}
location ~* .(txt)$ {
root    /mysite/web/pages/ ;
if ( !-f $request_filename ) {
root /mysite/web/admin/ ;
}
# proxy_pass http://172.16.0.1:8080 ;
}
}
使用if条件和root来查找匹配文件,在第一个location,如果在/mysite/web/images/找不到,则在/mysite/web/css/找,如果也没有,接着在/mysite/web/js/,如果仍旧没有,最后在/mysite/web/static/查找。在第二个location,要注意的是,proxy不能和root一起使用,两者只能存一。

rewrite指令

rewrite regex replacement [flag];
flag标记有下面四个
last
break
redirect
permanent
其中,last和break,它们与URL重写有关,也就是说客户端看不到地址发生变化,前者表示后面继续搜索URL或location,而后者表示后面不再匹配。
而redirect和permanent,它们与URL重定向有关,也就是客户端能看到地址变化,前者表示临时重定向,后者表示永久重定向。

例子一:访问http://www.tb.com/best/test.html,重写为http://www.tb.com/test/test.html
location /best {
rewrite /best/(.*) /test/$1 break;
proxy_pass http://127.0.0.1:8080/test/;
}
这个例子先重写RUI然后转发出去
下面是更有代表意义的URI重写例子
rewrite ^/users/(.*)$ /show?user=$1? last;

set指令
用来设置一个变量

location / {
proxy_pass http://127.0.0.1:8080/;
set $query $query_string;
rewrite /wp     /wordpress/?$query?;
}
这个例子将/wp/?p=abc重写为/wordpress/?p=abc,利用到了自定义变量,这里要注意一点是rewrite指令的第二个问号表示查询字符串的结束。


5.做WEB缓存服务器


安装插件

缓存插件默认已安装,另外要单独安装清除缓存的插件proxy_cache_purge,见前面的安装过程

配置:

在HTTP段加入两个定义
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache_one:512m inactive=1d max_size=3g;
proxy_temp_path /var/cache/nginx/proxy_temp;
proxy_cache_path表示缓存的目录,levels表示用两层目录结构--第一次单字符目录名而第二层双字符目录名,keys_zone表示缓存对象键的区域名以及分配的内存大小,inactive表示缓存时间d、h、m表示日、时、分,max_file表示内存满后写入磁盘缓存的最大大小
proxy_temp_path表示临时缓存的目录,它需要跟proxy_cache_path在同一分区

server段的完整定义如下:
server {
listen              80;
server_name         www.tb.com;
charset UIF-8;
location / {
proxy_cache cache_one;
proxy_cache_valid 200 304 12h;
proxy_cache_key $host$uri$is_args$args;

proxy_set_header Host $Host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://127.0.0.1:8080;
expires 1d;
}

location ~ /purge(/.*) {
allow 127.0.0.1;
allow 172.16.0.0/24;
deny all;
proxy_cache_purge cache_one $host$1$is_args$args;
}

location ~ .*.(jsp|php|jspx)$ {
proxy_set_header Host $Host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://127.0.0.1:8080;
}

access_log off;
}
proxy_cache:表示当前location所使用的缓存区域
proxy_cache_valid:对哪些状态的页面缓存多久,例如对200和304缓存12小时
proxy_cache_key:缓存的对象名字是什么组合
proxy_cache_purge:对哪个缓存区域的缓存对象做清除

测试:

启动nginx会看到多了一个cache manager process进程,说明缓存已启动。
访问http://www.tb.com/cache/test.html,修改test.html后再访问,仍能看到修改前的内容则表示缓存有效,清楚缓存用地址http://www.tb.com/purge/cache/test.html,在原来地址的主机名后加多一层目录purge表示做清除缓存操作,补充一下,这个清除操作支持通配符

利用TCMalloc优化Nginx性能


TCMalloc是谷歌的google-perftools中的成员,比glibc的malloc在内存分配效率方面高很多,能提升服务器在并发时的性能,安装TCMalloc需要安装libunwind和google-perftools两个包,前者提供基本函数调用链和函数调用寄存器

安装libunwind和google-perftools
见前面的编译安装章节

创建线程目录
mkdir /tmp/tcmalloc
chown nginx:nginx /tmp/tcmalloc
chmod 0777 /tmp/tcmalloc

修改配置
在main区域的pid下添加一行
google_perftools_profiles /tmp/tcmalloc;

查看运行结果
重启ngins
[root@node5 sbin]# ps aux | grep nginx
root     63937  0.0  0.1 581572  1344 ?        Ss   23:42   0:00 nginx: master process ./nginx
nginx    63938  0.1  3.0 612364 30372 ?        S    23:42   0:00 nginx: worker process
nginx    63939  0.1  3.1 612364 32000 ?        S    23:42   0:00 nginx: worker process
nginx    63940  0.0  3.0 612364 30372 ?        S    23:42   0:00 nginx: worker process
nginx    63941  0.1  3.0 612364 30372 ?        S    23:42   0:00 nginx: worker process
nginx    63942  0.0  0.3 585924  3976 ?        S    23:42   0:00 nginx: cache manager process
root     63951  0.0  0.0 103256   844 pts/3    S+   23:43   0:00 grep nginx
[root@node5 sbin]# lsof -n | grep tcmalloc
nginx     63938   nginx   12w      REG              253,0        0    1048645 /tmp/tcmalloc.63938
nginx     63939   nginx   14w      REG              253,0        0    1048643 /tmp/tcmalloc.63939
nginx     63940   nginx   16w      REG              253,0        0    1048635 /tmp/tcmalloc.63940
nginx     63941   nginx   18w      REG              253,0        0    1048646 /tmp/tcmalloc.63941
nginx     63942   nginx   18w      REG              253,0        0    1048632 /tmp/tcmalloc.63942
启动tcmalloc,每个tcmalloc线程跟一个nginx工作进程关联一起,例如 63938 与 /tmp/tcmalloc.63938






原文地址:https://www.cnblogs.com/tsw1107/p/3f1d6928c0b0a117fee286e517c41c2a.html