今天继续说说nginx,之前只是介绍了nginx的配置,这次主要说说nginx的生产环境的配置,我们在生产中是如何配置的。源码:https://github.com/limingios/netFuture/tree/master/nginx
系统类型 | IP地址 | 节点角色 | CPU | Memory | Hostname |
---|---|---|---|---|---|
Centos7 | 192.168.66.110 | nginx | 1 | 2G | nginx |
Centos7 | 192.168.66.111 | tomcat | 1 | 2G | tomcat1 |
Centos7 | 192.168.66.112 | tomcat | 1 | 2G | tomcat2 |
假设在做一个大型项目,面向全国的,公司对架构师的要求是做到700+的QPS,如何去处理。
了解下一个网站一般的实际html大小
>打开一个技术博客:idig8.com
查看源代码
保存在文件大小:45kb,700QPS/s = 700*45/1024 = 30MB,单个页面如果700QPS的话需要吐出来30MB/s的量,毕竟是个人博客肯定承受不了。
咱们在拿某东为例,保存在文件大小:186kb,700QPS/s = 700*186/1024 = 100MB+,单个页面如果700QPS的话需要吐出来100MB/s的量,某东好牛逼。
如果让咱们来设计京东这么大的体谅如何设计。
* 对于商品详情 页涉及了如下主要服务:
1. 商品详情页HTML页面渲染
2. 价格服务
3. 促销服务 库存状态/配送至服务 广告词服务
4. 预售/秒杀服务
5. 评价服务
6. 试用服务
7. 推荐服务
8. 商品介绍服务 各品类相关的一些特殊服务
上边的全部搞成微服务。
1. 采用Ajax 动态加载 价格、广告、库存等服务
2. 采用key value 缓存详情页主体html。
很多比较大型的内部系统都是这样来设计的。
微服务和微服务之前都是内网都是千兆带宽,第一次从微服务中取。之后都是通过redis直接过去。特殊的数据通过ajax的方式。从redis来获取肯定会有大大的提升。如果用这种情况500qps还是可以的,如果想往上走,基本很难得。但是我们的要求走到700qps。
当达到500QPS 的时候很难继续压测上去。
分析原因:一个详情页html 主体达平均150 kb 那么在500QPS 已接近局域网宽带极限。75MB+,内网一般都是千兆带宽,千年带宽128MB/s,其实这个也是在往内网IO的一个瓶颈上边走。在上边图的架构,其实内网走了2次,一个是通过nginx访问商品的详情服务,一个是详情服务访问redis。
如果想解决上边的2次内网的通信最理想的方式,上图中的2个节点都不要就可以了。
> 不走redis缓存,也不通过nginx来请求商品详情页服务,直接从nginx本地的硬盘缓存来走。内网通信的瓶颈是不是就解决了。
解决方式
>减少内网的通信,nginx本身也可以通过配置将数据缓存到本地硬盘上,下次请求直接请求nginx内部的硬盘缓存数据,这样也减少了内网的通信。
正常情况下是这样的流程,有缓存的情况。
正常情况下没有缓存的情况,nginx自动添加缓存
商品变更怎么办,思路是通过MQ消息服务,通过详情页服务,由详情页服务统一的来请求直接的地址的,来清空nginx下的缓存。
nginx如何配置缓存
>proxy_cache 是用于 proxy 模式(一般也可称为反代)的缓存功能
events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; #配置缓存 proxy_cache_path /data/nginx/cache_item levels=1:2 keys_zone=cache_item:200m inactive=30d max_size=10g; upstream idig8 { server 192.168.66.111:8080 weight=5; server 192.168.66.112:8080 weight=5; } 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; } #配置缓存 location ~*/.(html|htm)$ { proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_pass http://idig8; proxy_cache cache_item; proxy_cache_key $host$uri$is_args$args; proxy_cache_valid 200 304 12h; expires 7d; } } }
在tomcat目录下新建立一个index.html
>tomcat1
idig8.com 192.168.66.111
tomcat2
idig8.com 192.168.66.112
./sbin/nginx -s stop mkdir -p /data/nginx/cache_item ./sbin/nginx
pwd cd /data/nginx/cache_item/3/cf ls
清空缓存
>看看效果
修改了index.html
请求还是缓存里面的数据
回顾如何配置,该方案Nginx 配置实现
1、在http元素下添加缓存区声明。 proxy_cache_path /data/nginx/cache_item levels=1:1:2 keys_zone=cache_item:500m inactive=30d max_size=10g; 2、为指定location 设定缓存策略。 proxy_cache cache_item; proxy_cache_key $host $uri$is_args$args;#以全路径md5值做做为Key proxy_cache_valid 200 304 12h; #对不同的HTTP状态码设置不同的缓存时间 expires 7d; #总体缓存时间
演示缓存生效过程
1. 配置声明缓存路径
2. 为location 配置缓存策略
3. 重启nginx(修改了)
4. 查看缓存目录生成
父元素 | 名称 | 描述 |
---|---|---|
http | proxy_cache_path | 指定缓存区的根路径 |
levels | 缓存目录层级最高三层,每层1~2个字符表示。如1:1:2 表示三层。 | |
keys_zone | 缓存块名称 及内存块大小。如cache_item:500m 。表示声明一个名为cache_item 大小为500m。超出大小后最早的数据将会被清除。 | |
inactive | 最长闲置时间 如:10d 如果一个数据被闲置10天将会被清除 | |
max_size | 缓存区硬盘最大值。超出闲置数据将会被清除 | |
location | proxy_cache | 指定缓存区,对应keys_zone 中设置的值 |
proxy_cache_key | 通过参数拼装缓存key 如:host uri is_args args 则会以全路径md5值做做为Key | |
proxy_cache_valid | 为不同的状态码设置缓存有效期 |
该功能可以采用第三方模块 ngx_cache_purge 实现。将ngx_cache_purge编译到到Nginx中,用来清除指定URL的缓存。
cd ~ wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz #查看已安装模块 ~/nginx/sbin/nginx -V #进⼊nginx安装包⽬录 重新安装 --add-module为模块解压的全路径 cd ~/nginx-1.13.10 ./configure --prefix=/root/nginx --with-http_stub_status_module --with-http_ssl_module --add-module=/root/ngx_cache_purge-2.3 #重新编译 make cp /root/nginx-1.13.10/sbin/nginx ~/nginx/sbin/nginx #查看是否安装成功 ./nginx/sbin/nginx -t
清除配置
location ~ /purge(/.*) { #允许访问的IP allow 127.0.0.1; allow 192.168.0.193; #禁⽌访问的IP deny all; #配置清除指定缓存区和路径(与proxy_cache_key⼀⾄) proxy_cache_purge cache_item $host$1$is_args$args; }
提问:
什么是图片防盗链?意思是指本站内图片、CSS等资源只有本站点可以访问,不允许其它站点打开!
该功能如果用JAVA如何实现?很单简单,只要判断一下 请求头当中的referer 属性是否为 指定域名即可。
Nginx原理类似。
location ~* /.(gif|png|jpg|swf|flv)$ { root html; valid_referers none *.tl.com; if ($invalid_referer) { rewrite ^/ http://www.tl.com/image/403.png; #return 404; } }
说明:如果 valid_referers 条件判断未通过,nginx 则会赋值 invalid_referer 为true
语法: valid_referers none | blocked | server_names | string …;
参数说明:
none
不允许 “Referer” 来源头部为空的情况
blocked
不允许“Referer”值为空情况,有可能Referer被的值被代理或者防火墙删除
server_names
“Referer”来源头部包必须含当前的server_names (当前域名)可以多个
有时会有这样的需求,每个子域名对应一个静态站点(类似58到家、有赞商城等)。如果每天增加一个域名
的会相当麻烦。在nginx 当中可直接基于$host 连接到对应目录。具体配置实现如下:
server { listen 80; server_name *.tl.com; root /data/www/$host; access_log logs/$host.access.log; location / { index index.html; } }
一定要修改下,主机的host文件,它依靠host文件的。
PS:一般用nginx比较多就是反向代理,其实很多特殊的配置也是在大型互联网电商经常使用的。所以这个高速缓存和防盗链也是一个不错的功能。
百度未收录
>>原创文章,欢迎转载。转载请注明:转载自IT人故事会,谢谢!
>>原文链接地址:上一篇:已是最新文章