【工具和配置】Ngnix配置

来源:互联网 发布:美空网怎么约 知乎 编辑:程序博客网 时间:2024/06/08 11:30


本文主要参考了《实战Ngnix》;同时结合工作中实际使用的Ngnix部署配置进一步阐述

主要涉及如下几个部分:

1)ngnix的安装配置,这里的配置大多也可以在安装后通过配置文件置顶。

实践中TB也是在安装后进行配置的

2)ngnix的启动与停止操作。

实践中TB使用默认启动,以及-s退出。

3)ngnix的基本配置。包括:日志格式设置,虚拟主机设置,压缩设置,浏览器缓存设置。

实践中TB对于这几点也有配置,其中日志格式、虚拟主机的设置时重点。其中虚拟主机设置还与ngnix反向代理等配置相关,在后面会详述。

4)ngnix配置中常用的rewirte功能。

实践中TB也有这样的配置,比如针对爬虫的处理......

5)  ngnix反向代理,负载均衡配置。

包括反向代理、负载均衡、虚拟主机的概念解释。

明确了当前业内负载均衡的方案。

给出了Ngnix通过反向代理实现负载均衡的配置方法。

分析了实践中TB线上和日常、预发环境都没有使用Ngnix负载均衡配置;日常中仅仅使用了虚拟主机配置。

但是依据TB的Ngnix配置框架,已经可以轻松的完成完整的虚拟主机+负载平衡配置了;结合上面介绍的概念和配置理论足够自己在别的场景下使用了!

6)ngnix配置reference


Part 1 ngnix安装配置

这里的安装配置是指通过源码configure时进行的,然后make &&make install;

可以通过yum或者rpm进行安装

1)日志

要保证启动nginx的权限,与安装nginx时创建这些默认log文件的权限的可读写

--http-log-path 默认<prefix>/logs/access.log

--error-log-path 默认<prefix>/logs/error.log

2)安装路径

如果通过yum或者rpm进行默认安装,则可以使用rpm -ql来查询安装路径

--prefix

3)Nginx可执行文件

taobao serachngin-search版本在<prefix>/bin/nginx

--sbin-path  默认<prefix>/sbin/ngnix

4) 配置文件路径

taobao serachngin-search版本在<prefix>/conf/nginx-search

--conf-path  默认<prefix>/conf/nginx.conf

5)nginx进程号保存文件

这些也可以在配置文件中指定

--pid-path  默认<prefix>/logs/ngnix.pid


Part 2 ngnix启停

1)启动 <prefix>/sbin/ngnix-c  <prefix>/conf/ngnix.conf -t检查配置文件语法

taobao Web应用部署文件jbossctl.sh脚本中启动nginx的命令很简单,仅仅是/home/admin/nginx/bin/ningx

2)停止 kill -信号类型  <prefix>/logs/ngnix.pid

ngnix命令将信号类型进行了封装,即只要指明行为,自动会发出相应的信号给ngnix进程

-s signal     : send signal to a master process: stop, quit,reopen, reload

taobao web部署脚本jbossctl.sh脚本中关闭nginx的命令就是/home/admin/ngnix/bin/ngnix -s quit

另外

常见的4Linux信号类型以及应用场景:

HUP

挂起信号,编号为1,有两种解释:
守护进程理解HUP为重新设置的请求,如果守护进程能够不用重新启动就能够重新读取它自己的配置文
件并调整自己以适应变化的话,那么HUP信号通常可以用来触发这种行为

HUP
信号有时有终端驱动程序生成,试图用来清除(也就是终止)跟某个特定终端相连接的那些进程。例如
当一个终端会话结束时,或者当一个Modem的连接不经意的断开时,就可能出现这种情况。
如果需要某些进程在会话结束之后继续运行,那么在C Shell中设法让这些进程变成后台程序,
ksh或者bash中可以用nohup来模拟这种行为。 

INT
中断信号,编号为2
当用户输入Ctrl+C时由终端驱动程序发送INT信号
INT信号是终止当前操作的请求,简单程序捕获到INT信号时应该退出,拥有命令行或者输入模式的那些
程序应该停止他们正在做的事情,清除状态,并等待用户再次输入。

TERM
软件终止信号,编号为15
TERM是请求彻底终止某项操作的信号,它期望进程清楚自己的状态并退出

QUIT
退出信号,编号为3
与TERM类似,不同之处在于QUIT信号的默认处理是内存转储,而TERM信号的默认处理没有内存转储。


Part 3 ngnix 基本配置

1)ngnix配置文件格式

2)虚拟主机配置

虚拟主机 提供了在一台物理服务器上,通过同一组Ngnix进程运行多个网站。

与Apache一样,Ngnix可以配置:每个虚拟主机的配置对应于配置文件中的一个server{...}

——基于IP的虚拟主机

——基于端口的虚拟主机 

这么做的话需要多个IP,每个IP对应不同的域名,由此对于用户来说就像多个Web网站。

然后将多个IP绑定在一台物理主机上,实现一台物理主机上的一个ngnix应用服务多个网站。

但是这样做的不足时浪费IP

单一网卡的的服务器上运行多个基于IP的虚拟主机

将网卡绑定多个IP别名;即单一网卡监听多个IP地址

通过ifconfig或route命令添加IP别名;编辑/etc/rc.local

【补充知识ifconfig命令会看到:lo是本地回环的虚拟网卡;常用来测试本机网卡和IP协议;或者本地调试CS程序】

Ngnix基于IP的虚拟主机,只要完成了网卡多IP别名绑定即可用

 ——基于域名的虚拟主机

这么做可以节省IP,同时实现了数你主机的功能,即多个域名,每个域名对外用户来看就是不同的网站。

这样通过一台物理机上的一个nginx应用就可以实现多网站运行

共享一个IP地址;多域名的虚拟主机,只要配置DNS服务器上的路由表;

这样一个物理机器可以对应多个域名;

然后Ngnix基于域名的虚拟主机就很好配置了

3)Ngnix日志配置

——定义日志文件中日志记录的格式,语法 log_format name [......]

$remote_addr 请求者IP;

$http_x_forwarded_for经过负载均衡或者反向代理的原请求者地址,通过负载均衡或反向代理器将这些信息放在HTTP头信息X-Frowarded-For中来实现的;

$remote_user 请求者客户端类型

$time_local 访问时间和时区

$request 请求URL和HTTP协议

$status 响应状态

$body_bytes_sent 

$http_refer 用于记录从哪个页面链接过来的这个用户做Web应用的统计很拥有!!

$http_user_agent 浏览器类型

......

举例来说,log_format combined '$remote_addr - $remote_user[$time_local] ' 

                                             '"$request" $status $body_bytes_sent '

                                             '"$http_referer" "$http_user_agent"';

taobao ngnix中的配置时如下定义的

——定义好日志文件格式后,需要进行配置

    accese_log path [format [buffer=size | off]]

——注意如果日志文件路径中有变量:比如TAOBAO ngnix日志路径配置

    那么存在一些限制:

    a)日志文件读写权限问题

    设置时要注意Ngnix进程设置的用户和组必须有对应日志路径中创建文件的权限。加入Ngnixuser指令设置的用户名和用户组都是www,而日志目录的用户名和用户组为root,那么日志文件无法被创建

     这个问题在部署advise应用中也遇到了

    b) 缓冲间不会被使用,每一条日志记录,都需要打开日志记录、写入、关闭过程

    对应的使用配置 open_log_file_cache来优化    taobao nginx配置没有做这个优化

——日志文件的切割

    a)nginx access.log文件不支持自动切割。

    b)需要通过如下方式手工切割:

         mv <prefix>/logs/access.log <prefix>/logs/20090318.log

         kill -USER1 `cat <path>/ngnix.pid`

     c)如果需要定时切割日志,需要借助crontab

     写一个手工切割日志的脚本,然后配置crontab让他每天定时执行

    

    d)tabao nginx配置时这么做的

         pipe: /home/admin/cronolog/sbin/cronolog /home/admin/web/logs/search/%Y/%m/%d/access-%Y-%m-%d_%H.log

4)Ngnix压缩输出

需要服务器和浏览器双方支持;但是不用担心现代浏览器啦~~~

taobao nginx是这样配置的



5)Ngnix 浏览器本地缓存设置

      将部分补偿变化的内容告诉浏览器缓存在浏览器本地,可以接受网络通信,加快访问

     Http协议通过Expires 和 Cache-Control来实现

    Ngnix配置语法 expries[time|epoch|max|off]

  taobao ngnix是这么配置的   

 


Part 4 ngnix Rewrite规则与实例

0) 通过Rewrite规则可以实现规范的URL/根据变量来做URL转向及选择配置

应用场景举例:  

    ——将一些动态URL地址伪装成静态HTML,便于搜索引擎抓取

    ——由于目录结构、域名变化的旧URL,需要跳转到新的URL


1)  NgnixRewite规则依赖PCRE库(Perl CompatibleRegular Extressions)

 

2)核心指令

    if(condition) {}

    其中,可以被指定为条件的信息:

              变量名

              = != :比较

              ~ ~* :正则匹配

              !~ !~*

              -f  !-f -d !-d -e !-e -x !-x

    set variable value

    return 

    break

    rewrite regex replacement flag


Part 5 Ngnix Http负责均衡和反向代理的配置与优化

1)概念介绍

     负载均衡概念

     反向代理概念(正向代理、普通代理和包过滤方式)

     虚拟主机概念


——个人总结这几个概念之间的关系是:     

    a)反向代理是负载均衡的一个好的实现方案。

    b)虚拟主机和负载均衡是一个相对的概念。虚拟主机是通过单部署实现对外多应用形式的服务。

       负载均衡是通过软、硬件,实现对后台集群的负载管理。

 

2)常见Web负载均衡思路

a)用户手动选择方式:eg:下载业务网站

b)DNS轮询:同一个主机名添加多条A记录

    ——可靠性低,由于DNS信息的缓存功能,所以如果一个IP的服务挂了,请求还可能被路由过来;

    ——其实无法实现真正的负载均衡

c)/七层负载均衡设备

    现在负载均衡技术通常操作与OSI网络模型的第四层或者第七层

    ——第四层负载均衡

     将一个Internet上的合法IP地址映射为内部服务器的IP地址,对每次TCP连接请求动态使用其中一个内部IP地址,达到负载均衡的目的。

    整个应用以集群方式提供服务,对外暴露所有连接到服务器集群的请求数据包需要经过的交换机地址,以此作为整个服务集群的VIP。

    交换机根据请求端的IP地址、TCP或UDP端口号和一定的负载均衡策略,映射此VIP到集群内部某条服务器的IP上,使对应的服务器进行请求响应。

    ——第七层负载均衡控制

    通过检查HTTP报头,根据报头内信息进行负载均衡,实现对访问流量的高层控制方式。

 

3)负载均衡思路的具体实现方案

    ——软件四层负载均衡:LVS

 

    ——软件实现第七层负载均衡

    基于软件实现的第七层负载均衡大多基于HTTP反向代理方式,典型的就有Ngnix。

    Ngnix 的反向代理负载均衡可以按照轮询、IP哈希、URL哈希、权重等多种方式对后端服务器进行负载均衡

    ——硬件四/七层负载均衡交换机

      

 

4)当前大规模网站负载均衡解决方案

     a)地区只能DNS解析

     b)DNS轮询到服务集群VIP

     c)4、7层负载均衡处理

    

    TAOBAO应该使用的解决方案是......

    a)针对一个Web应用申请多台线上机器,这个集群是整个淘宝主站集群中的某两天物理/虚拟机,是有内部IP的。

    b)  这几台集群中的服务器,对外提供一个服务,需要VIP提供给用户,用户通过VIP访问,然后通过TB的集群负载均衡方案将请求VIP映射到请求者几个内部IP上来。

 


5)Ngnix反向代理实现负载平衡

a)Ngnix方向代理实现负载平衡可以和虚拟主机功能结合起来

    虚拟集群的作用是:对外通过一个Ngnix服务提供多个Web站点服务

    结合反向代理的负载均衡功能后:可以使用一个Ngnix服务管理一个服务器集群对外提供多个Web站点服务,并且保证服务器集群中集群的负载均衡

 

b) Ngnix配置虚拟主机的方法

    server{listen server_name} server{} server()............

     每个虚拟主机通过listen和server_name区别开来

 

c)每个虚拟主机配置内通过proxy_pass和fastcgi_pass指令来进行反向代理设置,具体见下:

proxy_set_header 用于反向代理的后端Web服务器发起请求时添加指定Header头信息

比如:

 proxy_set_headerHost $host; 告知后端服务器,这个请求是由Ngnix哪个虚拟主机转发过来的

 proxy_set_headerX-Forwarded-For $remote_addr; 告知后端服务器,这个请求的真实请求者地址

proxy_next_upstream 指定如果指定的负载均衡某台机器出错,那么自动转发请求到负载池中的另外一台服务器,实现故障转移

比如:

proxy_next_upstreamhttp_502 http_504 error timeout invalid_header;

upstream 可以定义负载均衡服务器集群,以及负载均衡策略,默认通过轮询方式进行负载均衡


在upstream{}中使用的指令

ip_hash指令

server指令 weight max_fails fail_timeout down backup

 


6)实际工作中的总结

TAOBAO 用这个方案解决单物理机上的多JBOSS实例的负载均衡;

真正的TB web应用负载均衡是通过四、七层负载均衡方案做的?

或者,直接的说——TB没有用Ngnix来实现web服务的负载均衡!!!

仅仅在部署线上、特别是预发和日常时用了Ngnix虚拟主机的配置。

 

举例:

在部署一淘个性化项目advise线上环境时,一台机器部署一个ngnix实例.

整个服务器对外只提供一个Web服务,就是个性化推荐服务,所以不需要使用多个虚拟主机配置,只需要一个。

同时当前个性化服务只运行一个jboss实例,所以名义上的负载均衡池只有一台主句就是本机。


 tb ngnix配置中的核心 虚拟主机配置:

其实虽然用到了虚拟主机配置,但是一般线上每个ngnix配置只有一个虚拟主机;

同时在虚拟主机配置中也没有用到真正的负载均衡, 线上一般是一个ngnix对一个jboss。

另外,预发和日常往往是多个虚拟主机配置,为的是多个应用公用一个ngnix;但是每个虚拟主机中也没用用到负载平衡配置,仅仅是一一对应一个jboss


在明确了实际情况下,给出具体配置。

尽管当前的配置是伪虚拟主机配置、和负载均衡的,但是利用这个配置文件中的框架,也可以完整的定义真正的虚拟主机+负载均衡。

其中proxy_pass即将请求反向代理给jboss,只不过当前应用没有集群部署jboss,并且单JBOS还是是部署在和ngnix一台主机上的

7)尽管TB工作中没有用到Ngnix来实现负载均衡,那么自己用一个例子来试试怎么利用Ngnix和其他实现负载均衡

..............



Part 6 Ngnix 核心模块语法