目录导航

  • 前言
  • 反向代理
  • 负载均衡
    • upstream
    • 其他配置信息
      • proxy_next_upstream
      • proxy_connect_timeout
      • proxy_send_timeout
      • proxy_read_timeout
      • proxy_upstream_fail_timeout
  • Nginx动静分离
    • 什么是动静分离
    • 静态资源的类型
    • 演示代码
    • 动静分离的好处
      • 缓存
      • 压缩
        • 配置信息
        • 演示效果
  • 防盗链
  • 跨域访问
  • 后记

前言

前面我们简单的介绍了Nginx的安装使用,配置文件以及模块的使用细则,这一节,主要讲一下Nginx的实际应用场景~

  • Nginx的初步认识及配置
  • Nginx的应用实战
  • Nginx的扩展
  • Nginx的扩展-OpenRestry-实现API网关限流及登录授权

反向代理

比较经典的Nginx服务器做反向代理/负载均衡的架构图:

  • 用户的请求首先通过浏览器请求到Nginx服务器
  • 由Nginx服务器做负载均衡,决定请求具体哪个Tomcat服务器
  • Nginx最终将结果返回给客户端

接下来,我们准备三台机器模拟一下这个场景:
linux1:192.168.200.111(Nginx服务器)
linux2:192.168.200.112 (Tomcat服务器)
linux3:192.168.200.113(Tomcat服务器)

首先启动两台Tomcat服务器:
linux2:

linux3同理,我就不截图了,至于Tomcat的安装过程基本也很简单

  1. 去官网下载Tomcat的jar包
  2. tar -zxvf 解压jar包
  3. 进入bin目录启动即可,同nginx一样,也存在配置文件,可以修改端口等操作

具体安装过程略,不懂着可自行百度,都是小白操作。

现在我们启动了linux2与Linux3的tomcat,默认是8080端口,我们在浏览器上看一下效果:


篇幅有限,不截图linux3的tomcat欢迎界面了

接下来,修改linux1上nginx安装目录下/conf/nginx.conf 配置文件

这里通过include指令可以引入额外的配置文件信息,而不用修改nginx.conf主配置文件了,这里采用通配符写法,好处就在于:

  • 便于管理多配置文件
  • 解耦:根据不同功能,不同模块进行划分,不同的域进行分离

因此就可以将.conf为结尾的文件都加载到当前主配置文件中。
接下来,我们自行创建.conf文件,实现反向代理

进入刚才在主配置文件里设定的目录,并添加proxy_demo.conf,名称不限,只要以.conf为后缀即可。


接下来,关键一步,配置代理:

server {listen 80;server_name localhost;location / {# 用户访问当前机器localhost:80,会跳转此地址proxy_pass http://192.168.200.112:8080;# 将当前nginx机器地址暴露,放置在请求头proxy_set_header Host $host;# 将实际请求的用户ip地址暴露,放置在请求头proxy_set_header X-Real-IP $remote_addr;# 获取到所有代理服务器的地址proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}
}

然后重新加载配置文件,到linux/sbin

我们发现,在linux1上启动nginx后,由nginx代理到linux2的ip:8080 ,也就是刚才我们启动的Tomcat,达到了反向代理的效果

负载均衡

网络负载均衡的大致原理是利用一定的分配策略将网络负载平衡地分摊到网络集群的各个操作单元上,使得单个重负载任务能够分担到多个单元上并行处理,使得大量并发访问或数据流量分担到多个单元上分别处理,从而减少用户的等待响应时间

upstream

upstream是Nginx的HTTP Upstream模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡

  1. Upstream

语法: server address [paramters]

  1. 负载均衡策略或者算法
  • 轮询算法(默认):如果后端服务器宕机以后,会自动踢出

  • ip_hash :根据请求的ip地址进行hash

  • 权重轮询

    这里我们通过配置weight设置权重,如上图所示,此时落在linux3的概率就比较大了,通常生产环境,将性能好的机器配置权重更高~

演示效果

接着刚才的配置,我们在linux1上nginx的配置文件,引入两台tomcat服务器地址:
为了区分跳转不同的Tomcat上的效果,我们在linux2的tomcat首页index.jsp加入不同的元素:

编辑index.jsp

接下来,重启linux1上的nginx(因为修改了nginx的配置文件),打开浏览器,访问linux1:,我们发现,会轮询访问linux2与Linux3的tomcat地址:

这个明显是linux2的地址,因为刚才我们在页面上加入了获取ip地址的标签

剩下这个明显是linux3的tomcat,linux默认轮询算法:

除了upstream外,还有很多参数值得注意:

其他配置信息

upstream tomcat {server 192.168.200.112:8080 max_fails=2 fail_timeout=60s;server 192.168.200.113:8080;
}server {listen 80;server_name localhost;location / {proxy_pass http://tomcat;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_next_upstream error timeout http_500 http_503;proxy_connect_timeout 60s;proxy_send_timeout 60s;proxy_read_timeout 60s;add_header 'Access-Control-Allow-Origin' '*';add_header 'Access-Control-Allow-Methods' 'GET,POST,DELETE'; add_header 'Aceess-Control-Allow-Header' 'Content-Type,*';
}location ~ .*\.(js|css|png|svg|ico|jpg)$ {valid_referers none blocked 192.168.200.111 www.baidu.com; if ($invalid_referer) {return 404;}root static-resource;expires 1d;}
}

proxy_next_upstream

语法:proxy_next_upstream [error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_404 | off ];

默认:proxy_next_upstream error timeout;

配置块:http、server、location

这个配置表示当向一台上有服务器转发请求出现错误的时候,继续换一台上后服务器来处理这个请求。

默认情况下,上游服务器一旦开始发送响应数据,Nginx反向代理服务器会立刻把应答包转发给客户端。因此,一旦Nginx开始向客户端发送响应包,如果中途出现错误也不允许切换到下一个上有服务器继续处理的。这样做的目的是保证客户端只收到来自同一个上游服务器的应答。

proxy_connect_timeout

语法: proxy_connect_timeout time;

默认: proxy_connect_timeout 60s;

范围: http, server, location

用于设置nginx与upstream server的连接超时时间,比如我们直接在location中设置proxy_connect_timeout 1ms, 1ms很短,如果无法在指定时间建立连接,就会报错。

proxy_send_timeout

向后端写数据的超时时间,两次写操作的时间间隔如果大于这个值,也就是过了指定时间后端还没有收到数据,连接会被关闭

proxy_read_timeout

从后端读取数据的超时时间,两次读取操作的时间间隔如果大于这个值,那么nginx和后端的链接会被关闭,如果一个请求的处理时间比较长,可以把这个值设置得大一些

proxy_upstream_fail_timeout

设置了某一个upstream后端失败了指定次数(max_fails)后,在fail_timeout时间内不再去请求它,默认为10秒语法 server address [fail_timeout=30s]

#服务器集群名字
upstream backend {#server 192.168.200.112:8080 weight=1 max_fails=2 fail_timeout=600s;
#server 192.168.200.113:8080 weight=1 max_fails=2 fail_timeout=600s;}

Nginx动静分离

什么是动静分离

必须依赖服务器生存的我们称为动。不需要依赖容器的比如css/js或者图片等,这类就叫静。

静态资源的类型

在Nginx的conf目录下,有一个mime.types文件
mime.types

types {
text/html   html htm shtml;
text/css    css;
text/xml    xml;
image/gif   gif;
image/jpeg  jpeg jpg;
application/javascript  js;
application/atom+xml   atom;
application/rss+xml    rss;
text/mathml mml;
text/plain  txt;
text/vnd.sun.j2me.app-descriptor    jad;
text/vnd.wap.wml    wml;
text/x-component    htc;
image/png   png;
image/svg+xml  svg svgz;
image/tiff  tif tiff;
image/vnd.wap.wbmp  wbmp;
image/webp  webp;
image/x-icon    ico;
image/x-jng
image/x-ms-bmp
jng;
bmp;application/font-woff woff; application/java-archive jar war ear; application/json json; application/mac-binhex40 hqx; application/msword doc; application/pdf pdf; application/postscript ps eps ai; application/rtf rtf; application/vnd.apple.mpegurl m3u8; application/vnd.google-earth.kml+xml kml; application/vnd.google-earth.kmz kmz; application/vnd.ms-excel xls; application/vnd.ms-fontobject eot; application/vnd.ms-powerpoint ppt; application/vnd.oasis.opendocument.graphics odg; application/vnd.oasis.opendocument.presentation odp; application/vnd.oasis.opendocument.spreadsheet ods; application/vnd.oasis.opendocument.text odt;application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;application/vnd.wap.wmlc   wmlc;application/x-7z-compressed    7z;application/x-cocoa  cco;application/x-java-archive-diff jardiff;application/x-java-jnlp-file    jnlp;application/x-makeself run;application/x-perl  pl pm;application/x-pilot   prc pdb;application/x-rar-compressed    rar;application/x-redhat-package-manager    rpm;application/x-sea   sea;application/x-shockwave-flash   swf;application/x-stuffit   sit;application/x-tcl   tcl tk;application/x-x509-ca-cert   der pem crt;application/x-xpinstall xpi;application/xhtml+xml  xhtml;application/xspf+xml xspf;application/zip    zip;application/octet-streamapplication/octet-streamapplication/octet-streamapplication/octet-streamapplication/octet-streambin exe dll;deb;dmg;iso img;msi msp msm;audio/midi  mid midi kar;audio/mpeg mp3;audio/ogg   ogg;audio/x-m4a m4a;audio/x-realaudio   ra;video/3gpp   3gpp 3gp;video/mp2t ts;video/mp4    mp4;video/mpeg  mpeg mpg;video/quicktime    mov;video/webm  webm;video/x-flv    flv;video/x-m4v m4v;video/x-mng mng;video/x-ms-asf  asx asf;video/x-ms-wmv  wmv;video/x-msvideo avi;}

用户访问一个网站,然后从服务器端获取相应的资源通过浏览器进行解析渲染最后展示给用户,而服务端可以返回各种类型的内容,比如xml、jpg、png、gif、flash、MP4、html、css等等,那么浏览器就是根据mime-type来决定用什么形式来展示的

服务器返回的资源给到浏览器时,会把媒体类型告知浏览器,这个告知的标识就是Content-Type,比如Content-Type:text/html。

演示代码

接下来,我们对于tomcat首页的静态资源进行拦截:
首先在linux1上nginx的配置文件加入:

location ~ .*\.(js|css|png|svg|ico|jpg)$ {# 将拦截的资源加载到这个自定义目录下/static-resourceroot static-resource;
}

然后在根据配置文件,在当前Linux1的nginx上创建一个静态资源目录:

此时为空,现在将linux2/linux3上tomcat的静态资源全部剪切到linux1刚才设置的静态资源目录下:

  • 删除tomcat的静态资源

  • 将静态资源转移到/static-resource

    去服务器看一下静态资源的完整性,并重启Nginx:

    看看效果:

    说明静态资源已经成功转移至Nginx的静态资源目录,实现了动静分离

以上静态资源的分离,是将两台tomcat服务器的静态资源拿到nginx上实现的,同样的我们可以基于nginx搭建一个静态资源服务器:

将拦截的静态资源加载到一台服务器上

location ~ .*\.(js|css|png|svg|ico|jpg)$ {valid_referers none blocked 192.168.200.111 www.baidu.com;if ($invalid_referer) {return 404;}root static-resource;expires 1d;}

动静分离的好处

  • Nginx本身就是一个高性能的静态web服务器;

  • 其实静态文件有一个特点就是基本上变化不大,所以动静分离以后我们可以对静态文件进行缓存、或者压缩提高网站性能

缓存

当一个客户端请求web服务器, 请求的内容可以从以下几个地方获取:服务器、浏览器缓存中或缓存服务器中。这取决于服务器端输出的页面信息

浏览器缓存将文件保存在客户端,好的缓存策略可以减少对网络带宽的占用,可以提高访问速度,提高用户的体验,还可以减轻服务器的负担Nginx缓存配置

Nginx缓存配置

Nginx可以通过expires设置缓存,比如我们可以针对图片做缓存,因为图片这类信息基本上不会改变。

在location中设置expires

格式: expires 30s|m|h|d

location ~ .*.(jpg|jpeg|gif|bmp|png|js|css|ico)$ {root static;expires 1d;}

压缩

Gzip

我们一个网站一定会包含很多的静态文件,比如图片、脚本、样式等等,而这些css/js可能本身会比较大,那么在网络传输的时候就会比较慢,从而导致网站的渲染速度。因此Nginx中提供了一种Gzip的压缩优化手段,可以对后端的文件进行压缩传输,压缩以后的好处在于能够降低文件的大小来提高传输效率 "

配置信息

Gzip on|off 是否开启gzip压缩

Gzip_buffers 4 16k #设置gzip申请内存的大小,作用是按指定大小的倍数申请内存空间。4 16k代表按照原始数据大小以16k为单位的4倍申请内存。

Gzip_comp_level[1-9] 压缩级别, 级别越高,压缩越小,但是会占用CPU资源

Gzip_disable #正则匹配UA 表示什么样的浏览器不进行gzip

Gzip_min_length #开始压缩的最小长度(小于多少就不做压缩),可以指定单位,比如 1k

Gzip_http_version 1.0|1.1 表示开始压缩的http协议版本

Gzip_proxied (nginx 做前端代理时启用该选项,表示无论后端服务器的headers头返回什么信息,都无条件启用压缩)

Gzip_type text/pliain,application/xml 对那些类型的文件做压缩 (conf/mime.conf)

Gzip_vary on|off 是否传输gzip压缩标识; 启用应答头"Vary: Accept-Encoding";给代理服务器用的,有的浏览器支持压缩,有的不支持,所以避免浪费不支持的也压缩,所以根据客户端的HTTP头来判断,是否需要压缩

演示效果
http {include    mime.types;default_type application/octet-stream;sendfile   on;keepalive_timeout    60;include extra/*.conf;gzip    on;gzip_min_length 5k;gzip_comp_level 3;gzip_types application/javascript image/jpeg image/svg+xml;gzip_buffers 4 32k;gzip_vary on;}

在nginx主配置文件加入压缩配置,我们试验一下效果:
原来的请求:.svg的文件大小为26.9kb

重新加载nginx的配置文件:文件大小变为9.2kb

防盗链

一个网站上会有很多的图片,如果你不希望其他网站直接用你的图片地址访问自己的图片,或者希望对图片有版权保护。再或者不希望被第三方调用造成服务器的负载以及消耗比较多的流量问题,那么防盗链就是你必须要做的

防盗链配置

在Nginx中配置防盗链其实很简单,

语法: valid_referers none | blocked | server_names | string …;

默认值: —

上下文: server, location

“Referer”请求头为指定值时,内嵌变量$invalid_referer被设置为空字符串,否则这个变量会被置成“1”。查找匹配时不区分大小写,其中none表示缺少referer请求头、blocked表示请求头存在,但是它的值被防火墙或者代理服务器删除、server_names表示referer请求头包含指定的虚拟主机名

  1. 配置如下
location ~ .*.(gif|jpg|ico|png|css|svg|js)$ {valid_referers none blocked 192.168.200.112 www.baidu.com;if ($invalid_referer) {return 404;}root static;}


通过这样配置后,相当于设置了一个白名单,只有linux2和百度的ip是可以访问静态资源的,而linux3是不能访问到的~

需要注意的是伪造一个有效的“Referer”请求头是相当容易的,因此这个模块的预期目的不在于彻底地阻止这些非法请求,而是为了阻止由正常浏览器发出的大规模此类请求。还有一点需要注意,即使正常浏览器发送的合法请求,也可能没有“Referer”请求头。

跨域访问

什么叫跨域呢?如果两个节点的协议、域名、端口、子域名不同,那么进行的操作都是跨域的,浏览器为了安全问题都是限制跨域访问,所以跨域其实是浏览器本身的限制。

解决办法

修改proxy_demo.conf配置

server{listen 80;server_name localhost;location / {proxy_pass http://192.168.200.111:8080;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_send_timeout 60s;proxy_read_timeout 60s;proxy_connect_timeout 60s;add_header 'Access-Control-Allow-Origin' '*';  // 允许来自所有的访问地址add_header 'Access-Control-Allow-Methods' 'GET,PUT,POST,DELETE,OPTIONS'; //支持的请求方式add_header 'Access-Control-Allow-Header' 'Content-Type,*'; //支持的媒体类型}location ~ .*\.(gif|jpg|ico|png|css|svg|js)$ {root static;}}

后记

更多架构知识,欢迎关注本套Java系列文章:Java架构师成长之路

分布式专题-高性能的Web容器之Nginx02-Nginx的应用实战相关推荐

  1. [置顶] 自己动手写Web容器之TomJetty之六:动态页面引入

    传送门 ☞ Android兵器谱 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 传送门 ☞ 1.Web服务内功经脉 传送门 ☞ 2.让服务动起来 传送门 ☞ ...

  2. [置顶] “非主流”Web容器之TomJetty之让服务动起来

    传送门 ☞ 1.Web服务内功经脉 传送门 ☞ 3.掀起请求盖头来 传送门 ☞ 4.静态页面启程 上一节我们对于实现TomJetty服务器做了一些与Web有关的知识铺垫和回顾.那么从本节正式开始实现T ...

  3. 分布式专题(2)- 分布式 Java通信

    本篇一句话总结:Java实现分布式通信,可以基于Java API.开源框架和远程通信技术三种方式实现. 正文开始: 通过上一篇文章<分布式专题(1)- 计算机网络>我们知道了计算机之间之所 ...

  4. 分布式专题-NIO框架之Netty01-Java IO 演进之路

    目录导航 前言 Java IO 阻塞(Block)和非阻塞(Non-Block) 同步(Synchronization)和异步(Asynchronous) Java BIO 与 Java NIO Ja ...

  5. Tomcat结合Apache、Nginx实现高性能的web服务器

    一.Tomcat为什么需要与apache.nginx一起结合使用? Tomcat虽然是一个servlet和jsp容器,但是它也是一个轻量级的web服务器.它既可以处理动态内容,也可以处理静态内容.不过 ...

  6. Docker容器之compose容器集群的快速编排

    Docker容器之compose容器集群的快速编排 前言 一.Docker-compose简介 二.YAML文件格式及编写注意事项 (1)YAML文件格式 (2)YAML格式的注意事项 (3)YAML ...

  7. 企业运维容器之 docker仓库

    企业运维容器之 docker 仓库 1. 什么是仓库? 2. Docker hub 3. Registry 工作原理 4. 配置镜像加速器 5. 搭建私有仓库 5. 总结 1. 什么是仓库? Dock ...

  8. Docker容器之macvlan网络

    Docker容器之macvlan网络 一.查看当前dokcer的版本 二.创建macvlan网络 三.查看现有网络类型 四.运行macvlan网络类型的容器 一.查看当前dokcer的版本 [root ...

  9. Java并发编程:并发容器之CopyOnWriteArrayList(转载)

    Java并发编程:并发容器之CopyOnWriteArrayList(转载) 原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW ...

最新文章

  1. 毕业论文答辩老师最想听到什么?最关注的问题是什么?
  2. 区块链是一种用一种不可变的形式存储数字信息
  3. 能打开java文件_用java打开一个本地文件
  4. php include和require
  5. QT的QPen类的使用
  6. 个推的appid是指什么_推箱子软件介绍→安卓下最专业的推箱子软件(推箱快手)...
  7. 使用双指针可能只需要遍历一趟哦(洛谷P1147题题解,Java语言描述)
  8. 计算机的的打印服务,win7电脑打印机服务被强行关闭怎么办
  9. mysql报错 Row size too large ( 8126)
  10. C# 中base和this关键字
  11. 约束最优化方法 (三) 外部罚函数法
  12. 中国移动----5G简介
  13. mysql io瓶颈_服务器IO瓶颈对MySQL性能的影响
  14. 逃脱者2服务器不稳定,逃脱者2EPIC版新手常见问题解决方法汇总
  15. 航班信息的查询与检索Java,航班信息的查询与检索
  16. 唯品会的订单分库分表实践总结以及关键步骤
  17. error: invalid application of 'sizeof' to an incomplete type 'JNINativeMethod []'
  18. 这一天,我们读了千页往事,和一页叫做“百度大脑”的未来
  19. Echarts中treemap实现知识地图的逐层展开
  20. 程序员开发必备英语基础–狂神版

热门文章

  1. 为什么目前的串行比并行传输快
  2. un7.2:IDEA中实现登录功能
  3. ZOJ - 3713 In 7-bit 进制转换
  4. 一种高效、安全的Dota全图新思路
  5. 头腾大战再升级 字节跳动做游戏的胜算有多少?
  6. OpenOCD failed tor read memory at $addr 错误
  7. 数据采集程序-----直播间
  8. 思科路由器的密码重置
  9. 通过图片像素计算图片大小的方法
  10. 最新vue实战视屏 vue2.x thinkPHP5.0后台 nodejs+mong0DB