Nginx入门教程

一、Nginx的介绍

1、什么是Nginx

Nginx是一个使用c语言开发的高性能的http服务器及反向代理服务器。Nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。由俄罗斯的程序设计师Igor Sysoev所开发,官方测试nginx能够支支撑5万并发链接,并且cpu、内存等资源消耗却非常低,运行非常稳定。

2、Nginx的应用场景

  • http服务器。Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器。
  • 虚拟主机。可以实现在一台服务器虚拟出多个网站。例如个人网站使用的虚拟主机。
  • 反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。

3、Nginx的安装

Nginx一般推荐安装到linux系统,而且要安装c语言的编译环境gcc。

3.1、下载

进入官网,下载nginx1.8.0版本(当前最新稳定版本),官网地址:http://nginx.org/en/download.html

3.2、安装nginx依赖的包

nginx是C语言开发,建议在linux上运行,本教程使用Centos6.4作为安装环境。

  • gcc:安装nginx需要先将官网下载的源码进行编译,编译依赖gcc环境,如果没有gcc环境,需要安装gcc:yum install gcc-c++
  • PCRE:PCRE(Perl Compatible Regular Expressions)是一个Perl库,包括 perl 兼容的正则表达式库。nginx的http模块使用pcre来解析正则表达式,所以需要在linux上安装pcre库。yum install -y pcre pcre-devel。注:pcre-devel是使用pcre开发的一个二次开发库。nginx也需要此库。
  • zlib:zlib库提供了很多种压缩和解压缩的方式,nginx使用zlib对http包的内容进行gzip,所以需要在linux上安装zlib库。yum install -y zlib zlib-devel
  • openssl:OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。nginx不仅支持http协议,还支持https(即在ssl协议上传输http),所以需要在linux安装openssl库。yum install -y openssl openssl-devel

3.3、安装步骤

  • 把nginx的源码上传到linux系统
  • 把压缩包解压缩
  • 进行configure
./configure --prefix=/usr/local/nginx14 --pid-path=/var/run/nginx14/nginx14.pid --lock-path=/var/lock/nginx14.lock --error-log-path=/var/log/nginx14/error.log --http-log-path=/var/log/nginx14/access.log --with-http_gzip_static_module --http-client-body-temp-path=/var/temp/nginx14/client --http-proxy-temp-path=/var/temp/nginx14/proxy --http-fastcgi-temp-path=/var/temp/nginx14/fastcgi --http-uwsgi-temp-path=/var/temp/nginx14/uwsgi --http-scgi-temp-path=/var/temp/nginx14/scgi

注意:上边将临时文件目录指定为/var/temp/nginx,需要在/var下创建temp及nginx目录

  • make
  • make install

3.4、Nginx目录结构

...conf 配置文件 
...html 网页文件
...logs 日志文件
...sbin 主要二进制程序

4、Nginx的启动、停止

4.1、启动

进入nginx的sbin目录,./nginx就可以启动,如果访问不到,首先查看防火墙是否关闭
9680832.png

4.2、关闭

可以使用kill命令,但是不推荐使用。

推荐使用:./nginx -s stop

4.3、刷新配置

./nginx -s reload

二、Nginx信号量控制

1、常用信号量

信号量注释
TERM,INTQuick shutdown
QUITGraceful shutdown 优雅的关闭进程,即等请求结束后再关闭
HUPConfiguration reload ,Start the new worker processes with a new configuration Gracefully shutdown the old worker processes 改变配置文件,平滑的重读配置文件
USR1Reopen the log files 重读日志,在日志按月/日分割时有用
USR2Upgrade Executable on the fly 平滑的升级
WINCHGracefully shutdown the worker processes 优雅关闭旧的进程(配合USR2来进行升级)
  • USR1主要用于日志切割(新版本1.8已经不需要使用USR1即可实现文件切割)
    Linux中文件存储主要根据磁盘地址来决定,因此改变文件的名称还是会写入到该文件中,因此需要使用USR1信号量
  • 模拟刷新日志,在index.html中的body最后加入如下代码,重复访问Nginx主页
<script>
    window.location.href = "/";
</script> 
  • 再改变原有的access.log的名称,创建新的access.log
mv nginx14/access.log nginx14/access.2016.4.18.log
touch nginx14/acces.log
  • 但是通过命令发现日志仍写入到该变名称后的文件上
ll nginx14
total 140
-rw-r--r--. 1 root   root      0 Apr 18 22:25 acces.log
-rw-r--r--. 1 nobody root 136800 Apr 18 22:25 access.2016.4.18.log
-rw-r--r--. 1 nobody root    370 Apr 18 22:10 error.log

total 456
-rw-r--r--. 1 root   root      0 Apr 18 22:29 acces.log
-rw-r--r--. 1 nobody root 459840 Apr 18 22:29 access.2016.4.18.log
-rw-r--r--. 1 nobody root    370 Apr 18 22:10 error.log 
  • 需要使用USR1信号量进行重读日志
ps aux|grep nginx

kill -USR1 5220
ll nginx14
total 584
-rw-r--r--. 1 root   root      0 Apr 18 22:29 acces.log
-rw-r--r--. 1 nobody root 576480 Apr 18 22:30 access.2016.4.18.log
-rw-r--r--. 1 nobody root  14640 Apr 18 22:30 access.log
-rw-r--r--. 1 nobody root    370 Apr 18 22:10 error.log

官网参考:https://www.nginx.com/resources/wiki/start/topics/tutorials/commandline/#

2、具体语法

ps aux|grep nginx 查看nginx进程
Kill -信号选项 nginx的主进程号
Kill -HUP 4873
Kill -信号控制 `cat /xxx/path/log/nginx.pid` 注意是反引号
Kil; -USR1 `cat /xxx/path/log/nginx.pid`

3、替代信号量的写法

[root@localhost nginx14]# ./sbin/nginx -h
nginx version: nginx/1.4.7
Usage: nginx [-?hvVtq] [-s signal] [-c filename] [-p prefix] [-g directives]
Options:
  -?,-h         : this help
  -v            : show version and exit
  -V            : show version and configure options then exit
  -t            : test configuration and exit
  -q            : suppress non-error messages during configuration testing
  -s signal     : send signal to a master process: stop, quit, reopen, reload
  -p prefix     : set prefix path (default: /usr/local/nginx14/)
  -c filename   : set configuration file (default: conf/nginx.conf)
  -g directives : set global directives out of configuration file

三、Nginx虚拟主机配置

1、Nginx配置段

nginx.conf是nginx的配置文件

// 全局区
worker_processes 1; // 有1个工作的子进程,可以自行修改,但太大无益,因为要争夺CPU,一般设置为CPU数*核数
event {
  // 一般是配置nginx连接的特性
  // 如1个worker能同时允许多少连接
  worker_connections  1024; // 这是指 一个子进程最大允许连1024个连接
}
http {  //这是配置http服务器的主要段
   server { // 这是虚拟主机段
      location {  //定位,把特殊的路径或文件再次定位 ,如image目录单独处理
      }             /// 如.php单独处理
   }
   server {
   }
}

2、基于域名的虚拟主机

server {
    listen 80;  #监听端口
    server_name a.com; #监听域名
    location / {
        root /var/www/a.com;   #根目录定位
        index index.html;
    }
}

3、基于端口的虚拟主机

当访问的地址在nginx配置中不存在时,会默认访问第一个server

server {
    listen 8080;
    server_name 192.168.1.204;

    location / {
        root /var/www/html8080;
        index index.html;
    }
}

四、Nginx日志管理

1、日志格式

我们通过观察server段发现如下信息:

server {
        listen       80;
        server_name  localhost;
        #charset koi8-r;

        #access_log  logs/host.access.log  main;
        location / {
            root   html;
            index  index.html index.htm;
        }   

这说明该server,它的访问日志的文件是logs/host.access.log,使用的格式main格式。除了main格式,你可以自定义其他格式进行日志输出。
main格式是什么?
在server段的前面定义了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格式是我们定义好一种日志的格式,并起名字便于引用。上面的例子,main类型的日志,记录的remote_addr....http_x_forwarded_for等选项,格式中每一项具体含义如下:

  • remote_addr:远程IP
  • remote_user [$time_local]:远程用户[用户访问时间]
  • request:请求方法(如GET/POST)
  • status:请求状态
  • body_bytes_sent:请求体body长度
  • http_referer:referer来源信息
  • http-user-agent用户代理/蜘蛛
  • http_x_forwarded_for:被转发的请求的原始IP,在经过代理时,代理把你的本来IP加在此头信息中,传输你的原始IP

日志中的结果如下:

192.168.56.1 - - [18/Apr/2016:22:30:48 +0800] "GET / HTTP/1.1" 304 0 "http://192.168.56.102/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36 QQBrowser/3.9.3943.400"
192.168.56.1 - - [18/Apr/2016:22:30:48 +0800] "GET / HTTP/1.1" 304 0 "http://192.168.56.102/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36 QQBrowser/3.9.3943.400" 

2、声明一个日志格式log_format

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

log_format  myformat '$time_local:$remote_addr $request $http_user_agent'; 

在下面的server中引用myformat,格式如下:

server {
    listen  80;
    server_name test.nginx.com;
    access_log /var/log/nginx14/test.nginx.com.log myformat;
    //声明log       log位置                log格式;
    location / {
       root html/test/nginx;
       index index.html;
    }
}

注意:Nginx允许针对不同的server做不同的Log (有的web服务器不支持,如lighttp)

3、实际应用:Nginx定时切割日志

  • linux中常用的日期命令
date
#查看当前时间:Wed Apr 20 01:51:09 CST 2016
date -d yesterday
#查看昨天时间:Tue Apr 19 01:51:54 CST 2016
date -s '2016-04-19 23:35:00'
#修改系统当前时间
clock -w
#将当前系统时间写入到CMOS中,使设置的时间重启之后仍然有效
date -d yesterday +%Y%m%d
#以数字格式查看昨天时间(年月日)20160419 
date -d yesterday +%Y%m%d%M
#以数字格式查看昨天时间(年月日分)2016041955
  • 编写shell脚本文件:vim log_data.sh
#!/bin/bash
LOGPATH='/var/log/nginx14'
#日志文件路径
BASEPATH='/log_data'
#备份日志路径
DAY=$(date -d yesterday +%Y%m%d%M)
#获取昨天的日期数,精确到天
MONTH=$(date -d yesterday +%Y%m%d)
#获取昨天的日期数,精确到月
#echo $LOGPATH
#输出变量进行测试 引用变量加上$
mkdir -p $BASEPATH/$MONTH
#按月创建备份文件夹
mv $LOGPATH/test.log $BASEPATH/$MONTH/test.$DAY.log
#将日志文件剪切到备份目录下,并且按照日期命名
touch $LOGPATH/test.log
#在原日志路径下重新创建日志文件
kill -USR1 `cat /var/run/nginx14/nginx14.pid` 
#重读日志文件
  • 执行shell脚本,可以在命令行输入sh log_data.sh
  • 利用Linux系统的定时任务来执行shell脚本进行文件复制
crontab -e
*/1 * * * * sh /log_data/log_data.sh
#分 时 日 月 周 命令

#每天0时1分(建议在02-04点之间,系统负载小) 
01 00 * * * sh /xxx/path/b.sh 

五、Location详解

1、Location语法

location有“定位”的意思,根据Uri来进行不同的定位。在虚拟主机的配置中,是必不可少的,location可以把网站的不同部分,定位到不同的处理方式上。比如, 碰到.php,如何调用PHP解释器?--这时就需要location。

  • location 的语法
location [=|~|~*|^~] patt {
}

中括号可以不写任何参数,此时称为一般匹配,也可以写参数,因此,大类型可以分为3种:

location = patt {} [精准匹配]
location patt{}  [一般匹配]
location ~ patt{} [正则匹配]

2、三种匹配解析的顺序

  • 首先看有没有精准匹配,如果有,则停止匹配过程:
location = patt {
    config A
}

如果 $uri == patt,匹配成功,使用configA。

  • 示例一:
location = / {
    root   /var/www/html/;
    index  index.html;
}
location / {
    root   /usr/local/nginx/html;
    index  index.html index.htm;
}

如果访问192.168.56.102,匹配的流程如下:1.精准匹配/,得到index=index.html的页面,去/var/www/html/index.html找对应文件,文件不存在;2.再次访问/index.html,被一般匹配获取到,内部转跳uri=/index.html,根目录为/usr/local/nginx/html;3.最终会访问的路径为/usr/local/nginx/html/index.html

  • 示例二:
location /abc.txt {
    root   html/test/nginx;
    index  index.htm;
}
location = /abc.txt {
    root   html;
    index  index.html;
}

精确匹配的优先级高,如果访问192.168.56.102/abc.txt,则优先访问精确匹配对应的文件。

  • 再来看,正则匹配同时存在:
location / {
    root   /usr/local/nginx/html;
    index  index.html index.htm;
}
location ~ image {
    root /var/www/image;
    index index.html;
}

如果我们访问http://xx.com/image/logo.png,此时,“/”与“/image/logo.png” 匹配,同时,“image”正则与”image/logo.png”也能匹配,谁起作用:正则表达式的匹配结果将会被使用。
图片真正会访问/var/www/image/logo.png
注:下载图片(文件命令):wget url

  • 一般匹配不同精准度的比较
location / {
    root   /usr/local/nginx/html;
    index  index.html index.htm;
} 
location /foo {
    root /var/www/html;
    index index.html;
}

我们访问http://xxx.com/foo,对于uri “/foo”,两个location的patt,都能匹配他们,即 ‘/’能从左前缀匹配 ‘/foo’,‘/foo’也能左前缀匹配’/foo’,此时, 真正访问/var/www/html/index.html,原因:/foo匹配的更长,因此使用它。

3、三种解析匹配图解

6000099.png

六、ReWrite重写

1、重写中用到的指令

if  (条件) {}  设定条件,再进行重写 #注意if和()之间要留一个空格
set #设置变量
return #返回状态码
break #跳出rewrite
rewrite #重写

2、if语法格式

if 空格 (条件) {
    重写模式
}
  • 条件的写法
=:来判断相等,用于字符串比较
~:用正则来匹配(此处的正则区分大小写)
~*:不区分大小写的正则
-f -d -e:来判断是否为文件,为目录,是否存在

3、示例

location /{
    #远程访问的主机地址为192.168.56.1,就返回403forbidden状态码
    if  ($remote_addr = 192.168.56.1) {
        return 403;
    }
    #访问的用户代理是chrome就重写到chrome.html
    if ($http_user_agent ~* chrome) {
        rewrite ^.*$ /chrome.html;
        break; #(不break会循环重定向)
    }
    #如果访问的文件不存在,就重写到404页面
    if (!-e $document_root$fastcgi_script_name) {
        rewrite ^.*$ /404.html break;
    }
    root   html;
    index  index.html; 
}

,此处还要加break,以192.168.56.102/abc.html这个不存在页面为例,我们观察访问日志, 日志中显示的访问路径,依然是GET /abc.html HTTP/1.1
原理:服务器内部的rewrite和302跳转不一样,302跳转URL会随之变化,变成新的http请求——404.html,而内部rewrite,发送的请求没变,只是访问的结果编程了rewrite页面的内容。就是说 fastcgi_script_name仍然是abc.html,因此会循环重定向。解决方法:在rewrite末尾加上redirect。

  • set是设置变量用的,可以用来达到多条件判断时作标志用
if ($http_user_agent ~* chrome){
    set $isChrome 1;
}
if ($fastcgi_script_name = /chrome.html){
    set $isChrome 0;
}
if ($isChrome = 1){
    rewrite ^.*$ /chrome.html redirect;
} 

4、带参数的ReWrite重写

#跳转到商品详情页:http://192.168.56.102/group-oa-portal/goods/init/341410154901
location ~ /group-oa-portal/goods/init {
    rewrite "(\d{12})$" http://test.10010.com:8011/group-oa-portal/goodsDetail/info?gId=$1 redirect;
}
#登陆跳转到集客首页:192.168.56.102/group-oa-portal/Index/init?groupId=1614073000005881&acronym=zgltx&provSimple=js
#${arg_paramName}:取URL中的参数值
location /group-oa-portal/Index/init {
    rewrite ^ http://test.10010.com:8011/${arg_provSimple}/${arg_acronym}/index.html? redirect;
}
#伪装成静态页面访问:192.168.56.102/group-oa-portal/goods-341410154901.html
location ~ /group-oa-portal {
    rewrite "goods-(\d{12}).html$" http://test.10010.com:8011/group-oa-portal/goodsDetail/info?gId=$1;
}

注意:用url重写时,正则里如果有”{}”,正则要用双引号包起来

七、Nginx的gzip压缩

1、gzip配置的常用参数

gzip on|off;  #是否开启gzip
gzip_buffers 32 4K| 16 8K #缓冲(压缩在内存中缓冲几块? 每块多大?)
gzip_comp_level [1-9] #推荐6 压缩级别(级别越高,压的越小,越浪费CPU计算资源)
gzip_disable #正则匹配Uri,匹配的Uri不进行gzip
gzip_min_length 200 # 开始压缩的最小长度(再小就不要压缩了)
gzip_http_version 1.0|1.1 # 开始压缩的http协议版本(可以不设置,目前几乎全是1.1协议)
gzip_proxied          # 设置请求者代理服务器,该如何缓存内容
gzip_types text/plain  application/xml # 对哪些类型的文件用压缩。如txt,xml,html,css
gzip_vary on|off  # 是否传输gzip压缩标志 

注意:图片/mp3这样的二进制文件,不必压缩,因为压缩率比较小,比如100->80字节,而且压缩也是耗费CPU资源的,比较小的文件不必压缩。

2、示例

server {
    listen       80;
    server_name  localhost;
    gzip on;
    gzip_comp_level 6;
    gzip_min_length 20;
    gzip_types text/css application/x-javascript;
}

开启缓存和不开启缓存前后大小分别是:113KB/308KB

八、Nginx的缓存设置

对于网站的图片,尤其是新闻站,图片一旦发布,改动的可能是非常小的。我们希望能否在用户访问一次后,图片缓存在用户的浏览器端,且时间比较长的缓存,这样能够提高网站的性能。可以通过设置nginx的expires进行设置,可以在location或if段里来写。

1、格式

expires 30s;
expires 30m;
expires 2h;
expires 30d;

注意:服务器的日期要准确,如果服务器的日期落后于实际日期,可能导致缓存失效

2、示例

location ~ image {
    expires 1m;
    root   /usr/local/nginx14;
    index  index.html;
} 

给图片进行缓存:发现第二次访问时,图片的请求链接返回的状态码是304,浏览器已经做了缓存。

3、原理

服务器响应文件内容是,同时响应etag标签(内容的签名,内容一变也跟着变化),和last_modified_since2个标签值。浏览器下次去请求时,头信息发送这两个标签,服务器检测文件有没有发生变化,没有变化,直接头信息返回etag,last_modified_since。浏览器知道内容无改变,于是直接调用本地缓存。这个过程,也请求了服务器,但是传着的内容极少。对于变化周期较短的,如静态html,js,css比较适于用这个方式。

九、Nginx的反向代理和负载均衡

用nginx做反向代理和负载均衡非常简单,支持两个用法1个proxy_pass,1个upstream,分别用来做反向代理和负载均衡。

1、反向代理示例

  • 反向代理到Nginx官网
location / {
    proxy_pass http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass;
}

2、负载均衡示例

http:
upstream PortalServer{
        server 10.142.132.18:8000 weight=2 fail_timeout=30s;#weight default 1
        server 10.142.132.36:8000 fail_timeout=15s;#default 10s
        server 10.142.132.6:8000;
        server 10.142.164.147:8000;
}        
server {
        location /mashgo {
                proxy_pass http://PortalServer;
        }
}

反向代理后端如果有多台服务器,自然可形成负载均衡,但proxy_pass如何指向多台服务器?
把多台服务器用upstream指定绑定在一起并起个组名,然后proxy_pass指向该组。
:默认的均衡的算法很简单,就是针对后端服务器的顺序,逐个请求。也有其他负载均衡算法,如一致性哈希,需要安装第3方模块。

转载于:https://www.cnblogs.com/duanmublog/p/5470439.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值