Nginx配置篇1-基本使用(负载均衡、动静分离)

481 阅读8分钟

欢迎大家关注 github.com/hsfxuebao ,希望对大家有所帮助,要是觉得可以的话麻烦给点一下Star哈

1. 目录结构

  • conf :用来存放配置文件相关

  • html: 用来存放静态文件的默认目录 html、css等

  • sbin: nginx的主程序

Nginx主配置文件nginx.conf是一个纯文本类型的文件,在安装目录下的conf目录下。配置文件以区块的形式组织的。每个区块以一个大括号“{}”来表示,整个配置文件中,Main区位于最上层,在Main区下面可以有Events区、HTTP区等层级,在HTTP区中又包含有一个或多个server区,每个server区中又可有一个或多个location区。

主配置文件组织结构:

主配置文件结构:四部
main block:主配置段,即全局配置段,对http,mail都有效
event {
...
} 事件驱动相关的配置

http {
...
} http/https 协议相关配置段

mail {
...
} mail 协议相关配置段

stream {
...
} stream 服务器相关配置段

http配置段

http {
     ...
     ... 各server的公共配置
     server { 每个server用于定义一个虚拟主机
          ...
     }
     server {
          ...
          server_name 虚拟主机名
          root 主目录
          alias 路径别名
          location [OPERATOR] URL { 指定URL的特性
               ...
               if CONDITION {
                     ...
               }
          }
      }
}

重要参数说明

#启动进程,通常设置成和cpu的数量相等
worker_processes  8;
#worker_processes  auto;

#为每个进程分配cpu
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

#一个nginx进程可以打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n的值保持一致。
worker_rlimit_nofile  102400;
#模块加载配置文件
include /usr/share/nginx/modules/*.conf;
#指明要加载的模块的路径
/usr/lib64/nginx/modules/
#定worker进程的nice值,设定worker进程优先级:[-20,20]
worker_priority number;

#全局错误日志及PID文件
#错误日志定义等级,[ debug | info | notice | warn | error | crit ]
error_log  /usr/local/nginx/logs/error.log info; 
#PId文件
pid/usr/local/nginx/nginx.pid;

events {

    #epoll是多路复用IO(I/O Multiplexing)中的一种方式,可以大大提高nginx的性能。
    use   epoll;     

    #单个后台worker process进程的最大并发链接数 (最大连接数=连接数*进程数)
    worker_connections  10000;    

    #尽可能多的接受请求.
    multi_accept  on; 

    #事件驱动相关的配置
    #处理新的连接请求的方法;on指由各个worker轮流处理新请求,Off指每个新请求的到达都会通知(唤醒)所有的worker进程,但只有一个进程可获得连接,造成“惊群”,影响性能,默认值为off,可优化为on
    accept_mutex on | off;
    #此指令默认为off,即默认为一个worker进程只能一次接受一个新的网络连接, on表示每个woker进程可以同时接受所有新的网络连接
    multi_accept on|off;

    #调试和定位问题
    #是否以守护进程方式运行,默认是on,即守护进程方式,off 用于调试或docker环境
    daemon on|off;
    #是否以master/worker模型运行nginx,默认为on,当指定off 将不启动worker
    master_process on|off;

}

#设定http服务器,利用它的反向代理功能提供负载均衡支持
http {

    #设定mime类型,类型由mime.type文件定义,在响应报文中将指定的文件扩展名映射至MIME对应的类型
    include   mime.types;
    #除上面指定的类型外,就为默认的MIME类型,浏览器一般会提示下载
    default_type   application/octet-stream;
    #浏览器直接打开内容,不下载
    #default_type   test/html;


    #设定日志格式,可以自定义
    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/usr/local/nginx/log/nginx/access.log;

    #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用必须设为 on
    #如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的uptime。
    #是否启用sendfile功能,在内核中封装报文直接发送,默认Off
    sendfile  on;

    #在开启sendfile,on时合并响应头和数据体在一个包中一起发送
    tcp_nopush on;  

    #开启目录列表访问,适合下载服务器,默认关闭。
    #autoindex  on;  

    #是否在响应报文中的Content-Type显示指定的字符集,默认off不显示
    charset charset off;

    #是否在响应报文的Server首部显示nginx版本
    server_tokens on | off | build | string;


    #keepalive超时时间,客户端到服务器端的连接持续有效时间,当出现对服务器的后继请求时,keepalive-timeout功能可避免建立或重新建立连接。(节省服务器资源、CPU、内存、网卡)
    keepalive_timeout  65;

    #keepalive超时时间内,客户端到服务器端的最大连接次数为100次,超过100次则重新建立连接。
    keepalived_requests 100;

    #在keepalived模式下的连接是否启用TCP_NODELAY选项,即Nagle算法,当为off时,延迟发送,每发送一个包就需要确认ACK,才发送下一个包,默认On时,不延迟发送,多个包一次性确认
    tcp_nodelay   on; 
    #开启gzip压缩
    gzip on;
    gzip_min_length  1k;
    gzip_buffers 4 128k;
    gzip_http_version 1.1;
    gzip_comp_level  4; 
    #压缩级别大小,最大为9,值越小,压缩后比例越小,CPU处理更快。
    #值越大,消耗CPU比较高。
    gzip_types   text/plain application/x-javascript text/css application/xml;
    gzip_vary on;

    #允许客户端请求的最大单文件字节数
    client_max_body_size 10m;  

    #缓冲区代理缓冲用户端请求的最大字节数
    client_body_buffer_size 128k; 

    #nginx跟后端服务器连接超时时间(代理连接超时)
    proxy_connect_timeout 300;  

    #后端服务器数据回传时间(代理发送超时)
    proxy_send_timeout 300; 

    #连接成功后,后端服务器响应时间(代理接收超时)
    proxy_read_timeout 300; 

    #设置代理服务器(nginx)保存用户头信息的缓冲区大小
    proxy_buffer_size 4k;  

    #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
    proxy_buffers 4 32k;   

    #高负荷下缓冲大小(proxy_buffers*2) 
    proxy_busy_buffers_size  64k;   

    #设定请求缓冲
    large_client_header_buffers  4 16k;

    #客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k
    #不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。
    client_header_buffer_size 4k;

    #这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。
    open_file_cache max=102400 inactive=20s;

    #这个是指多长时间检查一次缓存的有效信息。
    open_file_cache_valid 30s;

    #open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive
    open_file_cache_min_uses 1;

    #包含其它配置文件,如自定义的虚拟主机
    include vhost/*.conf;

}

核心参数说明:

  • worker_processes:worker_processes 1; 默认为1,表示开启一个业务进程

  • worker_connections 1024 : 单个业务进程可接受连接数

  • include mime.types; 引入http mime类型

  • `default_type application/octet-stream : 如果mime类型没匹配上,默认使用二进制流的方式传输。

  • sendfile on: 使用linux的 sendfile(socket, file, len) 高效网络传输,也就是数据零拷贝。详见:IO系列1-零拷贝原理

  • use epoll: IO多路复用,详见IO系列3-详解IO多路复用(select、poll、epoll)

2. 虚拟主机配置

虚拟主机使用的是特殊的软硬件技术,它把一台运行在因特网上的服务器主机分成一台台“虚拟”的主机,每台虚拟主机都可以是一个独立的网站,可以具有独立的域名,具有完整的Internet服务器功能(WWW、FTP、Email等),同一台主机上的虚拟主机之间是完全独立的。

从网站访问者来看,每一台虚拟主机和一台独立的主机完全一样。利用虚拟主机,不用为每个要运行的网站提供一台单独的Ngix服务器或单独运行一组Nginx进程。虚拟主机提供了在同一台服务器、同一组Nginx进程上运行多个网站的功能。参数配置如下:

server {
    listen 80; 监听端口号
    server_name localhost; #域名、主机名
    location / { 匹配路径
        root html; 文件根目录
        index index.html index.htm; 默认页名称
    }
    error_page 500 502 503 504 /50x.html; 报错编码对应页面
    location = /50x.html {
        root html;
    }
}

注意:虚拟主机技术server中,相同的主机端口号会报错。

2.1 域名解析规则

  • servername匹配规则

我们需要注意的是servername匹配分先后顺序,写在前面的匹配上就不会继续往下匹配了。

  • 完整匹配

我们可以在同一servername中匹配多个域名

server_name vod.mmban.com www1.mmban.com;

  • 通配符匹配

server_name *.mmban.com

  • 通配符结束匹配

server_name vod.*;

  • 正则匹配

server_name ~^[0-9]+.mmban.com$;

3. 负载均衡和反向代理

3.1 正向代理和反向代理

3.1.1 反向代理

描述:反向代理是指以代理服务器来接受连接请求,然后将请求转发给内部网络上的服务器并将从服务器上得到的结果返回给请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器,而且整个过程对于客户端而言是透明的

隧道式代理:一进一出一个口

3.1.2 正向代理

描述:正向代理意思是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后由代理向原始服务器转交请求并将获得的内容返回给客户端。简单的说类似于采用VPN来访问google:

区别正向代理、反向: 都是站在客户端的角度,看代理服务器是帮客户端代理,还是帮服务端代理

3.2 LVS模型

详见:LVS负载均衡1-NAT、FULLNAT、DR、TUN模型原理

3.3 负载均衡

描述:负载均衡也是Nginx常用的一个功能。简单而言就是当有2台或以上服务器时,根据规则随机的将请求分发到指定的服务器上处理,负载均衡配置一般都需要同时配置反向代理,通过反向代理跳转到负载均衡

而Nginx目前支持自带3种负载均衡策略还有2种常用的第三方策略。

3.4 使用proyx_pass代理配置

浏览器访问localhost就会跳转到 www.baidu.com, 同时域名没有变化(不支持https)。可以有多个server。然后根据策略、调度。

server {
    listen 80;
    server_name localhost;
    location / {
        proxy_pass http://www.baidu.com;
        # root html;
        # index index.html index.htm;
    }
}

3.5 负载均衡upstream模块(轮询)

Upstream模块是Nginx负载均衡的主要模块,它提供了一个简单方法来实现在轮询和客户端IP之间的后端服务器负载均衡,并可以对后端服务器进行健康检查。

keepalive_timeout 65;
upstream httpds{
    server192.168.44.102:80;
    server192.168.44.103:80;
}

server{
    listen 80:
    server_name localhost;
    location/{
        proxy_pass http://httpds;
        #
        root html;
        #
        index index.html index.htm;
    }
}

3.5.1 负载均衡策略

  • weight:权重

  • down : 当前server暂不参与负载均衡

  • backup : 预留的备份服务器; 其它所有的非backup机器down或者忙的时候,请求backup机器。

  • max_fails : 请求失败次数限制

  • fail_timeout : 经过max_fails后服务暂停时间

  • max_conns : 限制最大的连接数

简单实例:

upstrem weiyigeek {
  server weiyigeek.top:8080 down;
  server weiyigeek.top:8081 backup;
  server weiyigeek.top:8082 max_fails=1 fail_timeout=10s max_conns=1024;
  server weiyigeek.top:8083 weight=1
  server weiyigeek.top:8084 weight=2
  server unix:/tmp/backend3;
} 

3.5.2 负载均衡调度算法

  • 轮询:默认算法按时间顺序逐一分配到不同的后端服务器;

  • 加权轮询:Weight值越大,分配到访问几率越高;

  • ip_hash:为每一个请求访问的IP的hash结果分配,可以将来自一个IP的固定访问一个后端服务器;

  • url_hash:需要安装模块安装访问的URL的hash结果来分配,这样每个URL定向到同一个后端服务器

  • least_conn:按照某台机器最少连接数的进行分配访问;

  • hash关键数值: hash 自定义 KEY

方式1: 轮询

RR(默认轮询)每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉能自动剔除。

upstream test {
  server weiyigeek.top:8080;
  server weiyigeek.top:8081;
}

server {
  listen  81;
  server_name  weiyigeek.top;
  client_max_body_size 1024M;
  location / {
    proxy_pass http://test;
    proxy_set_header Host $host:$server_port;
  }
} 

方式2:权重

权重指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 例如

upstream test {
  server weiyigeek.top:8081 weight=1;
  server weiyigeek.top:8080 weight=9;  #那么10次一般只会有1次会访问到8081,而有9次会访问到8080
} 

方式3: ip_hash

ip_hash 会话粘连, 上面的2种方式都有一个问题,那就是下一个请求来的时候请求可能分发到另外一个服务器,当我们的程序不是无状态的时候(采用了session保存数据),这时候就有一个很大的很问题了,比如把登录信息保存到了session中,那么跳转到另外一台服务器的时候就需要重新登录了,所以很多时候我们需要一个客户只访问一个服务器,那么就需要用iphash了,iphash的每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

# 会话粘粘可以理解为用户持续访问一个后端机器
upstream test {
  ip_hash;
  server weiyigeek.top:8080;
  server weiyigeek.top:8081;
} 

方式4:fair

fair(第三方)按后端服务器 的响应时间来分配请求,响应时间短的优先分配。

upstream backend {
  fair;
  server weiyigeek.top:8080;
  server weiyigeek.top:8081;
} 

方式5:url_hash

url_hash(第三方):按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。

在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法

upstream backend {
  hash $request_uri;
  hash_method crc32;
  server weiyigeek.top:8080;
  server weiyigeek.top:8081;
} 

方式6:least_conn

描述: 将请求分配到连接数最少的服务上。

upstream  dalaoyang-server {
  least_conn;
  server    weiyigeek.top:10001;
  server    weiyigeek.top:10002;
} 

以上6种负载均衡各自适用不同情况下使用,所以可以根据实际情况选择使用哪种策略模式,不过fair和url_hash需要安装第三方模块才能使用.

4. 动静分离

动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,这就是网站静态化处理的核心思路;

upstream test{
  server weiyigeek.top:8080;
  server weiyigeek.top:8081;
}

server {
  listen       80;
  server_name  weiyigeek.top;
  location / {
      root   e:wwwroot;//文件夹路径
      index  index.html;
  }

  # 所有静态请求都由nginx处理,存放目录为nginx中的html
  location ~ .(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
      root    e:wwwroot;
  }
  # 例子,比如
  #location /css{
  	#root html;
    #index index.html index.htm;
  #}
  

  # 所有动态请求都转发给tomcat处理
  location ~ .(jsp|do)$ {
      proxy_pass  http://test;
  }
  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
      root   e:wwwroot;
  }
} 

HTML以及图片和css以及js放到wwwroot目录下,而tomcat只负责处理jsp和请求,

例如当我们后缀为gif的时候,Nginx默认会从wwwroot获取到当前请求的动态图文件返回,当然这里的静态文件跟Nginx是同一台服务器,我们也可以在另外一台服务器,然后通过反向代理和负载均衡配置过去就好了,只要搞清楚了最基本的流程,很多配置就很简单了

4.1 location匹配顺序

  • 多个正则location直接按书写顺序匹配,成功后就不会继续往后面匹配
  • 普通(非正则)location会一直往下,直到找到匹配度最高的(最大前缀匹配)
  • 当普通location与正则location同时存在,如果正则匹配成功,则不会再执行普通匹配
  • 所有类型location存在时,“=”匹配 > “^~”匹配 > 正则匹配 > 普通(最大前缀匹配)
location ~*/(css|img|js) {
  root /usr/local/nginx/static;
  index index.html index.htm;
}

5. Rewrite规则和实例

Rewrite主要的功能就是实现URL的重写,Nginx的Rewrite规则采用PCRE(Perl Compatible Regular Expressions)Perl兼容正则表达式的语法进行规则匹配,如果您需要Nginx的Rewrite功能,在编译Nginx之前,须要编译安装PCRE库。

正则表达式(英文:Regular Expression)在计算机科学中,是指一个用来描述或匹配一系 列符合某个句法规则的字符串的单个字符串。

通过Rewrite规则,可以实现规范的URL、根据变量来做URL转向及选择配置。例如,一些使用MVC框架的程序只有一个入口,可以通过Rewrite来实现。一些动态URL地址须要伪装成静态HTML,便于搜索引擎抓取,也需要Rewrite来处理。一些由于目录结构、域名变化的旧URL,须要跳转到新的URL上,也可以通过Rewrite来处理。

server(
    listen 80;
    server name localhost;
    location/ {
        rewrite ^/2.htmls /index.jsp?pageNum=2 break;
        proxy_pass http/192168.44.104:8080
    }
}

rewrite是实现URL重写的关键指令,根据regex (正则表达式)部分内容,重定向到replacement,结尾是flag标记。

rewrite   <regex>   <replacement>   [flag];
关键字     正则        替代内容      flag标记

参数如下:

  • 关键字:其中关键字error_log不能改变

  • 正则:perl兼容正则表达式语句进行规则匹配

  • 替代内容:将正则匹配的内容替换成replacement

  • flag标记:rewrite支持的flag标记

  • rewrite参数的标签段位置: server,location,if

  • flag标记说明

    • ast #本条规则匹配完成后,继续向下匹配新的location URI规则\
    • break #本条规则匹配完成即终止,不再匹配后面的任何规则\
    • redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址 (防爬虫)\
    • permanent #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址\

例子: rewrite ^/([0-9]+).html$ /index.jsp?pageNum=$1 break;

参考资料

深入先出Nginx实战 第三、六、七章
深入理解Nginx模块开发与架构解析
Nginx基本使用