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


Nginx教程的更多相关文章

  1. Nginx教程(四) Location配置与ReWrite语法

    Nginx教程(四) Location配置与ReWrite语法 1 Location语法规则 1.1 Location规则 语法规则: location [=|~|~*|^~] /uri/ {- } ...

  2. Nginx教程(三) Nginx日志管理

    Nginx教程(三) Nginx日志管理 1 日志管理 1.1 Nginx日志描述 通过访问日志,你可以得到用户地域来源.跳转来源.使用终端.某个URL访问量等相关信息:通过错误日志,你可以得到系统某 ...

  3. Nginx教程(二) Nginx虚拟主机配置

    Nginx教程(二) Nginx虚拟主机配置 1 虚拟主机管理 1.1 Nginx管理虚拟主机 虚拟主机使用的是特殊的软硬件技术,它把一台运行在因特网上的服务器主机分成一台台“虚拟”的主机,每台虚拟主 ...

  4. Nginx教程(一) Nginx入门教程

    Nginx教程(一) Nginx入门教程 1 Nginx入门教程 Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like协议下发行.由 ...

  5. Nginx 教程(1):基本概念

    简介 嗨!分享就是关心!所以,我们愿意再跟你分享一点点知识.我们准备了这个划分为三节的<Nginx教程>.如果你对 Nginx 已经有所了解,或者你希望了解更多,这个教程将会对你非常有帮助 ...

  6. nginx教程从入门到精通

    [转]nginx教程从入门到精通 nginx教程写了一段时间,无意中发现,nginx相关文章已经达到了近100篇了.觉得很有必要汇总到一起,它是我们运维生存时间的一片心血,他是学习nginx的同学必看 ...

  7. Nginx教程收集

    学习要系统,最推荐的方式是看书. 下面是收集的一些Nginx教程: https://www.gitbook.com/book/yinsigan/nginx/details http://www.ngi ...

  8. agentzh 的 Nginx 教程(版本 2019.07.31)

    agentzh 的 Nginx 教程(版本 2019.07.31) agentzh 的 Nginx 教程(版本 2019.07.31) https://openresty.org/download/a ...

  9. Nginx 教程 (1):基本概念

      简介 嗨!分享就是关心!所以,我们愿意再跟你分享一点点知识.我们准备了这个划分为三节的<Nginx教程>.如果你对 Nginx 已经有所了解,或者你希望了解更多,这个教程将会对你非常有 ...

随机推荐

  1. 2017.4.18 putty和fileZilla的使用

    putty:用来连接环境. fileZila:用来传递文件. (1)连接环境 centOS 7 点击putty.exe,输入地址.用户名.密码进行连接.端口输入22.用账号和密码登录. 进入到目录下, ...

  2. Linux 常见安全检查方法

    Linux 常见安全检查方法进行概要说明: 一.检查系统密码文件,查看文件修改日期 # ls -l /etc/passwd 二.查看 passwd 文件中有哪些特权用户 # awk -F: '$3= ...

  3. GROUP BY和HAVING 以及mysql中常用的日期函数

    一.mysql中的GROUP BY和HAVINGGROUP BY常见的是和聚合函数(SUM,MIN,MAX,COUNT)搭配使用. 比如:SELECT category,SUM(money) AS ` ...

  4. django项目搭建

    参见https://www.imooc.com/video/13931 1.安装python,从官网python.org下载msi安装2.7,安装完后,输入python可以看到版本 2.djangop ...

  5. Au cs6怎样才能导入和导出m4a或者就是aac格式的文件呢?

        [求解]Au cs6怎样才能导入和导出m4a或者就是aac格式的文件呢?   汉化版;解决发法----首选项------常规------媒体与暂存盘-----动态链接媒体下面的启动DLMS格式 ...

  6. vue vue-router beforeRouteEnter

    beforeRouteEnter (to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 因为当守卫执行前,组件实 ...

  7. odoo12新特性: 会计改进

    改进分析会计 分析会计层级结构 分析分配 分析分录增加了表格视图     ============== SPECIFICATIONS ============== a. Hierarchy  - Cr ...

  8. Nginx:解析HTTP配置的流程

    参考资料:深入理解Nginx(陶辉) 书中有详细的讲解,这里只用本人的理解梳理一下该流程. 一点提议:对于像我这样的新手,面对暂时看不懂章节,建议先往下看一下(可能就会有新的理解或灵感),而不要死磕在 ...

  9. 后期给项目加入Git版本控制

    一.为项目加上Git 1.进入对应文件夹 2.git init(初始化一个空的代码仓库) 3.git add .(将当前目录和子目录的文件标记为要添加到代码仓库) 4.git commit -m &q ...

  10. kafka 0.8.1 新producer 源码简单分析

    1 背景 最近由于项目需要,需要使用kafka的producer.但是对于c++,kafka官方并没有很好的支持. 在kafka官网上可以找到0.8.x的客户端.可以使用的客户端有C版本客户端,此客户 ...