ZhouXiangの博客 后端工程师&机器学习爱好者

Nginx简介


Nginx简介。

Nginx是什么

Nginx是一款轻量级、高性能的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少,并发能力强,稳定性高、功能与示例配置文件丰富和系统资源占用低。

Nginx相对于Apache 优点以及不同点:

  • 高并发响应性能非常好,官方 Nginx 处理静态文件并发 5w/s
  • 反向代理性能非常强。(可用于负载均衡)
  • 内存和 cpu 占用率低。(为 Apache 的 1/5-1/10)
  • 对后端服务有健康检查功能
  • 支持 PHP cgi 方式和 fastcgi 方式
  • 配置代码简洁且容易上手
  • Apache采用Select模型;Nginx采用Epoll模型
  • Apache是阻塞型;Nginx是异步非阻塞型
  • Apache是同步多进程模型,一个连接对应一个进程;Nginx是异步,多个连接(万级别)可以对应一个进程

Nginx的优点

  • 跨平台、配置简单
  • 非阻塞、高并发连接:处理2-3万并发连接数,官方监测能支持5万并发
  • 内存消耗小:开启10个nginx才占150M内存,Nginx采取了分阶段资源分配技术
  • nginx处理静态文件好,耗费内存少
  • 内置的健康检查功能:如果有一个服务器宕机,会做一个健康检查,再发送的- 请求就不会发送到宕机的服务器了。重新将请求提交到其他的节点上。
  • 节省宽带:支持GZIP压缩,可以添加浏览器本地缓存
  • 稳定性高:宕机的概率非常小
  • master/worker结构:一个master进程,生成一个或者多个worker进程
  • 接收用户请求是异步的:浏览器将请求发送到nginx服务器,它先将用户请求- 全部接收下来,再一次性发送给后端web服务器,极大减轻了web服务器的压力 一边接收web服务器的返回数据,一边发送给浏览器客户端
  • 网络依赖性比较低,只要ping通就可以负载均衡
  • 可以有多台nginx服务器
  • 事件驱动,通信机制采用epoll模型

Nginx如何处理一个请求

  • 首先,nginx在启动时,会解析配置文件,得到需要监听的端口与ip地址,然后在nginx的master进程里面先初始化好这个监控的socket,再进行listen 然后再fork出多个子进程出来, 子进程会竞争accept新的连接。
  • 随后,客户端就可以向nginx发起连接了。当客户端与nginx进行三次握手,与nginx建立好一个连接后,某一个子进程会accept成功,然后创建nginx对连接的封装,即ngx_connection_t结构体
  • 接着,根据事件调用相应的事件处理模块,如http模块与客户端进行数据的交换
  • 最后,nginx或客户端来主动关掉连接,到此,一个连接就寿终正寝了

Nginx 工作原理

Nginx 由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个 location block(location 是 Nginx配置中的一个指令,用于 URL 匹配),而在这个 location 中所配置的每个指令将会启动不同的模块去完成相应的工作。

Nginx模块结构

结构上分为:

  • 核心模块:HTTP模块、EVENT模块和MAIL模块
  • 基础模块: HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块
  • 第三方模块:HTTP Upstream Request Hash模块、 Notice模块和 HTTP Access Key模块

功能上分为:

  • Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。
  • Filters (过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。 Proxies(代理类模块)。此类模块是Nginx的HTTP
  • Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。

为什么Nginx具有高并发性

Nginx 的高并发得益于其采用了epoll模型,与传统的服务器程序架构不同,epoll 是linux 内核2.6以后才出现的。Nginx采用epoll模型,异步非阻塞,而Apache采用的是select模型。

Select特点:Select选择句柄的时候,是遍历所有句柄,也就是说句柄有事件响应时,Select需要遍历所有句柄才能获取到哪些句柄有事件通知,因此效率是非常低。

Epoll特点:Epoll对于句柄事件的选择不是遍历的,是事件响应的,就是句柄上事件来就马上选择出来,不需要遍历整个句柄链表,因此效率非常高。
Linux下I/O复用与Epoll详解:https://www.cnblogs.com/lojunren/p/3856290.html

Epoll的优点

  • 支持一个进程打开大数目的socket描述符(FD)
  • IO效率不随FD数目增加而线性下降
  • 使用mmap加速内核与用户空间的消息传递。
  • 内核微调

参考:
https://blog.csdn.net/qq_25934401/article/details/81561001

select/poll和epoll对比

Select/poll

1.select/poll每次都需要重复传递全部的监听fd进来,涉及用户空间和内核直接的数据拷贝。
2.fd事件回调函数是pollwake,只是将本进程唤醒,本进程需要重新遍历全部的fd检查事件,然后保存事件,拷贝到用户空间,函数返回。
3.每次循环都是对全部的监测的fd进行轮询检测,可能发生事件的fd很少,这样效率很低。
4.当有事件发生,需要返回时,也需要将全部fd的事件进行返回,而其中可能只有很少的fd有事件发生。
5.select/poll返回时,会将该进程从全部监听的fd的等待队列里移除掉,这样就需要select/poll每次都要重新传入全部监听的fd,然后重新将本进程挂载到全部的监测fd的等待队列,大量重复劳动,效率很低。

epoll

1.每次累加添加,不需要每次传入全部的监测fd。
2.每个fd只将本进程挂载到自己的等待队列一次,直到该fd被从epoll移除,不需要重复挂载。
3.fd事件回调函数是ep_epoll_callback,该函数将发生事件的fd加入到epoll专门的就绪队列rdllist中,同时唤醒本进程。
4.本进程不需要遍历每一个fd去监测事件是否发生,而只需要判断epoll中的就绪队列rdllist是否为空即可。
5.epoll返回时,只返回就绪队列rdllist中的项,避免了无关项的操作,应用层也就不需要再次重复遍历。
6.epoll内部使用红黑树存储监测fd,支持大量fd的快速查询、修改和删除操作。

对比

  1. select/poll把fd的监听列表放在用户空间,由用户空间管理,导致在用户空间和内核空间之间频繁重复拷贝大量fd;epoll在内核建立fd监听列表(实际是红黑树),每次通过epoll_ctl增删改即可。
  2. select/poll每当有fd内核事件时,都唤醒当前进程,然后遍历监听列表全部fd,检查所有就绪fd并返回;epoll在有fd内核事件时,通过回调把该fd放到就绪队列中,只需返回该就绪队列即可,不需要每次遍历全部监听fd。
  3. https://www.cnblogs.com/NerdWill/p/4996476.html
    https://blog.csdn.net/qq546770908/article/details/53082870

Nginx是如何实现高并发的?

许多web服务器和应用服务器使用简单的线程的(threaded)、或基于流程的(process-based)架构,NGINX则以一种复杂的事件驱动(event-driven)的架构脱颖而出,这种架构能支持现代硬件上成千上万的并发连接。

为什么架构很重要?任何Unix应用程序的根本基础都是线程或进程。进程和线程都消耗资源。它们都使用内存和其他OS资源,导致内核频繁切换(被称作上下文切换(context switch)的操作)。大多数现代服务器可以同时处理数百个小的、活跃的(active)线程或进程,但一旦内存耗尽,或高I/O负载导致大量的上下文切换时,服务器的性能就会严重下降。对于网络应用,通常会为每个连接(connection)分配一个线程或进程。这种架构易于实现,但是当应用程序需要处理成千上万的并发连接时,这种架构的扩展性就会出现问题。

Nginx的进程类型:

  • 主进程执行特权操作,如读取配置和绑定端口,还负责创建子进程(下面的三种类型)
  • 缓存加载进程(cache loader process)在启动时运行,把基于磁盘的缓存(disk-based cache)加载到内存中,然后退出。对它的调度很谨慎,所以其资源需求很低
  • 缓存管理进程(cache manager process)周期性运行,并削减磁盘缓存(prunes entries from the disk caches),以使其保持在配置范围内
  • 工作进程(worker processes)才是执行所有实际任务的进程:处理网络连接、读取和写入内容到磁盘,与上游服务器通信等

每个工作进程可以处理多个请求,每进来一个request,会有一个工作进程去处理。但不是全程的处理,处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的工作进程继续处理其他请求,而一旦上游服务器返回了,就会触发这个事件,工作进程才会来接手,这个request才会接着往下走。由于webserver的工作性质决定了每个request的大部份生命都是在网络传输中,实际上花费在server机器上的时间片不多。这是几个进程就解决高并发的秘密所在。即webserver刚好属于网络io密集型应用,不算是计算密集型。

如何理解Nginx的进程模型?

参考:https://blog.csdn.net/qq_25934401/article/details/81561001

Nginx反向代理与正向代理

正向代理:是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。

正向代理的用途:

  • 访问原来无法访问的资源,如google
  • 可以做缓存,加速访问资源
  • 对客户端访问授权,上网进行认证
  • 代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息

反向代理:实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。

反向代理的用途:

  • 保证内网的安全,可以使用反向代理提供WAF功能,阻止web攻击大型网站,通常将反向代理作为公网访问地址,Web服务器是内网。
  • 负载均衡,通过反向代理服务器来优化网站的负载。

Nginx时间驱动框架

所谓事件驱动架构,简单来说,就是由一些事件发生源来产生事件,由一个或多个事件收集器(epolld等)来收集、分发事件,然后许多事件处理器会注册自己感兴趣的事件,同时会“消费”这些事件。nginx不会使用进程或线程作为事件消费者,只能是某个模块,当前进程调用模块。

传统web服务器(如Apache),所谓事件局限在TCP连接建立、关闭上,其他读写都不在是事件驱动,这时会退化成按序执行每个操作的批处理模式,这样每个请求在连接建立后都将始终占用系统资源,直到连接关闭才会释放资源。大大浪费了内存、cpu等资源。并且把一个进程或线程作为事件消费者。

统web服务器与Nginx间重要差别:前者每个事件消费者独占一个进程资源,后者只是被事件分发者进程短期调用而已。

Nginx+KeepAlived双机热备

双机热备是指两台机器都在运行,但并非两台机器同时在提供服务。 当提供服务的一台出现故障的时候,另外一台会马上自动接管并且提供服务,且切换的时间非常短。Keepalived的工作原理是VRRP——虚拟路由冗余协议。

为什么杀死KeepAlived进程后,可以实现vip的漂移,但是原机器的vip无法自动删除?

VRRP协议原理是:只有MASTER对外发送消息。各BACKUP接受消息,当接受不到消息时会在剩下的BACKUP机器中选出新的MASTER。之前用kill -9 pid 或killall pid杀死keepalived进程,导致安装keepalived不能发送信息,BACKUP收不到信息升级为MASTER,但是由于进程被杀死【非正常关闭】,导致keepalived没有能力自己删除vip。

解决方案:关闭keepalived时用命令service keepalived stop或kill -15 pid(注:只删除第一个进程号)

KeepAlived的选举算法

keepalived中优先级高的节点为MASTER。MASTER其中一个职责就是响应VIP的arp包,将VIP和mac地址映射关系告诉局域网内其 他主机,同时,它还会以多播的形式(目的地址224.0.0.18)向局域网中发送VRRP通告,告知自己的优先级。网络中的所有BACKUP节点只负责 处理MASTER发出的多播包,当发现MASTER的优先级没自己高,或者没收到MASTER的VRRP通告时,BACKUP将自己切换到MASTER状 态,然后做MASTER该做的事:1.响应arp包,2.发送VRRP通告。

KeepAlived的Master和BackUp节点的优先级如何调整?

首先,每个节点有一个初始优先级,由配置文件中的priority配置项指定,MASTER节点的priority应比BAKCUP高。运行过程中keepalived根据vrrp_script的weight设定,增加或减小节点优先级。规则如下:

  • 当weight > 0时,vrrp_script的script脚本执行返回0(成功)时优先级为priority + weight,否则为priority。当BACKUP发现自己的优先级大于MASTER通告的优先级时,进行主从切换。
  • 当weight < 0时,vrrp_script的script脚本执行返回非0(失败)时优先级为priority + weight,否则为priority。当BACKUP发现自己的优先级大于MASTER通告的优先级时,进行主从切换。
  • 当两个节点的优先级相同时,以节点发送VRRP通告的IP作为比较对象,IP较大者为MASTER。

Nginx负载均衡策略

Nginx负载均衡策略主要分为两类:内置策略和扩展策略。内置策略包含加权轮询和ip hash,在默认情况下这两种策略会编译进nginx内核,只需在nginx配置中指明参数即可。扩展策略有很多,如fair、通用hash、consistent hash等,默认不编译进nginx内核。

  • 加权轮询
  • ip hash
    hash值既与ip有关又与后端机器的数量有关。经测试,上述算法可以连续产生1045个互异的value,这是此算法硬限制。nginx使用了保护机制,当经过20次hash仍然找不到可用的机器时,算法退化成轮询。因此,从本质上说,ip hash算法是一种变相的轮询算法,如果两个ip的初始hash值恰好相同,那么来自这两个ip的请求将永远落在同一台服务器上,这为均衡性埋下了较深隐患。
  • fair fair策略是扩展策略,默认不被编译进nginx内核。它根据后端服务器的响应时间判断负载情况,从中选出负载最轻的机器进行分流。这种策略具有很强的自适应性,但是实际的网络环境往往不是那么简单,因此须慎用。
  • 通用hash、一致性hash 通用hash和一致性hash也是种扩展策略。通用hash可以以nginx内置的变量为key进行hash,一致性hash采用了nginx内置的一致性hash环,可支持memcache。

图例:

负载均衡策略对比:

什么是C10K问题

指无法同时处理大量客户端(10,000)的网络套接字

Nginx异步非阻塞与Apache同步事件模型

Nginx采用多Worker的方式来处理请求,每个Worker里面只有一个主线程。nginx采用了异步非阻塞的方式来处理请求,也就是说,nginx是可以同时处理成千上万个请求的。一个worker进程可以同时处理的请求数只受限于内存大小,而且在架构设计上,不同的worker进程之间处理并发请求时几乎没有同步锁的限制,worker进程通常不会进入睡眠状态,因此,当Nginx上的进程数与CPU核心数相等时(最好每一个worker进程都绑定特定的CPU核心),进程间切换的代价是最小的。

Apache的常用工作方式(Apache也有异步非阻塞版本,但因其与自带某些模块冲突,所以不常用),每个进程在一个时刻只处理一个请求,因此,当并发数上到几千时,就同时有几千的进程在处理请求了。这对操作系统来说,是个不小的挑战,进程带来的内存占用非常大,进程的上下文切换带来的cpu开销很大,自然性能就上不去了,而这些开销完全是没有意义的。

Nginx为什么做动静资源分离

动态资源、静态资源分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,提高用户访问静态代码的速度,降低对后台应用的访问次数。

Nginx系统优化

  • 系统内核优化
  • 安全性优化
  • 性能参数优化

系统内核优化

Shell命令:vim /etc/sysctl.conf && /sbin/sysctl -p
常见参数:

net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1

较为完整的参数:

net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 16384 4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30
net.ipv4.ip_local_port_range = 1024 65000

安全性优化

  • 隐藏版本信息
    [root@db01 rpm]# curl -I 10.0.0.8
    HTTP/1.1 401 Unauthorized
    Server: nginx                   
    #隐藏版本号
    Date: Thu, 21 Jul 2016 03:23:38 GMT
    Content-Type: text/html
    Content-Length: 188
    Connection: keep-alive
    WWW-Authenticate: Basic realm="oldboy training"
    过程:
    vim /application/nginx/conf/nginx.conf
    在http模块下加入:
    server_tokens off;
    /application/nginx/sbin/nginx -t
    /application/nginx/sbin/nginx -s reload
    
  • 隐藏nginx要修改源代码
  • 更改nginx服务的默认用户(将默认的#user nobody;改为user nginx.nginx)
  • 降权启动Nginx

性能参数优化

# 使用的用户和组
user root root;
# 指定工作衍生进程数(一般等于CPU的总核数或总核数的两倍,例如两个四核CPU,则综合数为8.通过命令ps -ef|grep nginx可以看出来设置的是几个)
worker_processes  8;
#指定错误日志存放的路径,错误日志记录级别可选项为:[debug|info|notice|warn|error|crit],默认是crit,记录的日志数量从crit到debug,由少到多。
error_log  /usr/local/nginx/logs/nginx_error.log crit;

#指定pid存放的路径
pid       /usr/local/nginx/nginx.pid;

# 指定文件描述符数量??
worker_rlimit_nofile 51200;

#events settings
events {
    # 使用的网络I/O模型,Linux系统推荐采用epoll模型,FreeeBSD系统推荐采用kqueue模型
    use epoll;
    # 允许的连接数,该值不能大于操作系统支持打开的最大文件句柄数量
    worker_connections  51200;
}


#遵循http协议的服务器全局设置
http {
    # 引入定义网络资源媒体类型的文件,下面文件中就定义了(text/html, gif, js, 3gp等类型)
    include       mime.types;
    # 配置用于处理前端请求的MIME类型
    default_type  application/octet-stream;
    #设置使用的字符集,如果一个网站有多种字符集,请不要随便设置,应让程序员在HTML代码中通过Meta标签设置
    #charset utf-8;
    
    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;      # 允许的客户端请求头部的缓冲区大小
    large_client_header_buffers 4  32k;
    
    # 设置客户端能够上传的文件大小,注意要与应用程序中的文件大小限制兼容。
    client_max_body_size 300m;
    
    # 开启sendfile用于实现零拷贝,还可以设置sendfile_max_chunk 128k 用于限定最大传输量
    sendfile on;
    tcp_nopush on;
    # 会话保持时间
    keepalive_timeout 60;
    tcp_nodelay on;
    client_body_buffer_size 512k;
    proxy_connect_timeout 5;
    proxy_read_timeout 60;
    proxy_send_timeout 5;
    proxy_buffer_size 16k;
    proxy_buffers 4 64k;
    proxy_busy_buffers_size 128k;
    proxy_temp_file_write_size 128k;
    
    #关闭日志记录
    #access_log off;
    #log_format 自定义日志记录格式设置,main为名字,在access_log命令中引用
    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 访问日志文件设置
    # 指定日志存放路径,如果想使用默认的combined格式记录日志,可以使用access_log logs/access.log combined; 以下是使用log_format自定义的格式记录日志的。
    access_log  logs/access.log  main;

    
    gzip  on;   # 开启gzip压缩设置(只能在http模块中设置)
    gzip_min_length 1k;     # 待压缩数值大于此值时,才开启Gzip
    gzip_buffers  4 16k;    # Gzip使用想系统申请缓存空间的个数与每个缓存空间的大小
    gzip_http_version 1.1;  # 设置开启Gzip的最低HTTP协议版本
    gzip_comp_level 2;      # Gzip的压缩程度,级别为1-9,级别1表示压缩程度最低,效率最高
    # 根据响应页的MIME类型选择性地开启Gzip压缩功能
    gzip_types application/x-javascript text/css application/xml;
    gzip_vary on;           # 谨慎设置,可能有bug
    
    # 用于设置如果出现指定的HTTP错误状态码,则返回指定的url页面
    error_page  404              /404.html;
    error_page  500 502 503 504  /50x.html;
   
    #upstream设置,设置代理服务器(负载均衡池),默认的负载均衡方式是轮询,另外一种是ip_hash
    upstream tomcat_server {
        #ip_hash; # 一定程度上可以解决服务器组内的服务器间会话共享问题,不能与权重共用
        server 192.168.1.96:7070 weight=1;
        server 192.168.1.96:8081 weight=1;
    }

    #处理上传和下载的图片文件服务器,设置代理服务器(负载均衡池),默认的负载均衡方式是轮训,另外一种是ip_hash
    upstream image_server{
        server 192.168.1.96:9090 weight=1;
    }
 
    #server虚拟主机设置,可以设置多个:基于IP的虚拟主机,基于域名的虚拟主机
    # 第一个虚拟主机(基于域名的虚拟主机),反向代理tomcat_server和image_server这两组服务器
    server {
        # 监听所有IP连接的指定端口
        listen       8000;
        
        # 主机名称
        server_name  localhost;
        
        # 设置Nginx的默认首页(依次查询下述页面,找到就返回)
        index index.html index.htm index.jsp index.do;
        
        # root指定Nginx接收到请求以后查找资源的根目录路径
        #root /home/oracle/dev_tools/server/apache-tomcat-6.0.44/webapps/examples;
        
        # 配置该虚拟机的字符设置,如果不配置继承自http中的charset设置
        # charset koi8-r;

        # access_log 访问日志文件设置,如果server虚拟机中不设置,则继承http模块中的access_log的设置
        #access_log  logs/access.log  main;

        # rewrite settings -d表示目录 -f表示文件 -e表示文件或目录 -x表示文件是否可执行
        if (-d $request_filename)
        {
            rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent; # 目录自动添加/
        }

        # location模块说明
        # 使用环境:server模块

        # image 服务器location
        location ~*/NginxTest/image/ {
            proxy_pass http://image_server;
        }
        
        # =表示严格匹配; ~表示正则匹配,区分大小写; ~*表示正则匹配,不区分大小写
        location ~*/NginxTest/ {
            # root /home/oracle/dev_tools/server/apache-tomcat-6.0.44/webapps/;
            
            # HTTP代理模块 proxy,主要是用来转发请求到其他服务器
            # 如果后端服务器返回502,504,执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现failover。
            proxy_next_upstream http_502 http_504 error timeout invalid_header;
            # 变量$host等于客户端请求头中的Host值。
            proxy_set_header Host $host;
            #后端的web服务器可以通过X-Forwarded-For获取真实的IP地址,$remote_addr客户端的ip地址
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_pass http://tomcat_server;
        }

        #image expires settings
        # expires 属于http Header模块,主要用来Nginx返回给用户网页添加附件的header信息,可以在http,server,location中使用
        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires 30d;
        }

        #css&js expires settings
        # expires 属于http Header模块,主要用来Nginx返回给用户网页添加附件的header信息,可以在http,server,location中使用
        location ~ .*\.(js|css|html)?$
        {
            expires 2h;
        } 

        # 如果http模块设置了,则继承。此处设置了则覆盖。
        #error_page  404              /404.html;
        #error_page   500 502 503 504  /50x.html;
    }
}

上一篇 Shiro简介

下一篇 git常见操作

Comments

Content