目录
一:nginx可以替代tomcat吗?
二:nginx配置的各项参数指标
三:浏览器request header中provisional headers are shown
四:nginx服务访问出现403问题
五:nginx的反向代理及负载均衡原理及实现(高级教程)
微信前端核心500人群:群内不定期会有赞助商送书活动,BAT大厂资深大牛定期推送面经与源码分析,各平台大牛优秀文章推荐,更有内推跳槽咨询、视频资源共享、学习资料文章pdf面经网盘资源等等福利。加入我们一起进步。
为了解决知乎活码识别问题,下方的二维码做了持久化处理。扫描二维码添加小柠即可加入我们。
公众号:中台架构之家
群内分享每日一题:题目传送门
前端电子书大全:电子书
每日7点贝壳网P7大牛免费基础公开课开讲中
指南一:nginx可以替代tomcat吗?
严格的来说,Apache/Nginx 应该叫做「HTTP Server」;而 Tomcat 则是一个「Application Server」,或者更准确的来说,是一个「Servlet/JSP」应用的容器(Ruby/Python 等其他语言开发的应用也无法直接运行在 Tomcat 上)。这里从区别与相同点展开剖析
nginx
一个 HTTP Server 关心的是 HTTP 协议层面的传输和访问控制,所以在 Apache/Nginx 上你可以看到代理、负载均衡等功能。客户端通过 HTTP Server 访问服务器上存储的资源(HTML 文件、图片文件等等)。通过 CGI 技术,也可以将处理过的内容通过 HTTP Server 分发,但是一个 HTTP Server 始终只是把服务器上的文件如实的通过 HTTP 协议传输给客户端。
优点:轻量级,同样起web 服务,比apache占用更少的内存及资源 抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能高度模块化的设计,编写模块相对简单提供负载均衡
Tomcat
而应用服务器,则是一个应用执行的容器。它首先需要支持开发语言的 Runtime(对于 Tomcat 来说,就是 Java),保证应用能够在应用服务器上正常运行。其次,需要支持应用相关的规范,例如类库、安全方面的特性。对于 Tomcat 来说,就是需要提供 JSP/Sevlet 运行需要的标准类库、Interface 等。为了方便,应用服务器往往也会集成 HTTP Server 的功能,但是不如专业的 HTTP Server 那么强大,所以应用服务器往往是运行在 HTTP Server 的背后,执行应用,将动态的内容转化为静态的内容之后,通过 HTTP Server 分发到客户端。
Tomcat运行在JVM之上,它和HTTP服务器一样,绑定IP地址并监听TCP端口,同时还包含以下内容:
虽然Tomcat也可以认为是HTTP服务器,但通常它仍然会和Nginx配合在一起使用:
Nginx与Apache比较
1) nginx相对于apache的优点
轻量级,同样起web 服务,比apache占用更少的内存及资源 抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能高度模块化的设计,编写模块相对简单提供负载均衡
社区活跃,各种高性能模块出品迅速
2) apache 相对于nginx 的优点
apache的 rewrite 比nginx 的强大 ;
支持动态页面;
支持的模块多,基本涵盖所有应用;
性能稳定,而nginx相对bug较多。
3) 两者优缺点比较
Nginx 配置简洁, Apache 复杂 ;
Nginx 静态处理性能比 Apache 高 3倍以上 ;
Apache 对 PHP 支持比较简单,Nginx 需要配合其他后端用;Apache 的组件比 Nginx 多 ;
apache是同步多进程模型,一个连接对应一个进程;nginx是异步的,多个连接(万级别)可以对应一个进程;
nginx处理静态文件好,耗费内存少;
动态请求由apache去做,nginx只适合静态和反向;
Nginx适合做前端服务器,负载性能很好;
Nginx本身就是一个反向代理服务器 ,且支持负载均衡
所以第一个坑:nginx完全可以替代tomcat(错)
正确理解:nginx处理静态数据优势,tomcat处理动态数据优势,tomcat依赖nginx以实现更多的功能。Nginx并发性比较好,CPU内存占用低,如果rewrite频繁,那还是Apache较适合。
指南二:nginx配置的各项参数指标
worker_processes
一般一个进程足够了,你可以把连接数设得很大。
如果有SSL、gzip这些比较消耗CPU的工作,而且是多核CPU的话,可以设为和CPU的数量一样。
或者要处理很多很多的小文件,而且文件总大小比内存大很多的时候,也可以把进程数增加
服务器是“多个CPU+gzip+网站总文件大小大于内存”的环境,worker_processes设置为CPU个数的两倍比较好
nginx作为http服务器的时候:
max_clients = worker_processes * worker_connections/2
nginx作为反向代理服务器的时候:
max_clients = worker_processes * worker_connections/4
server_name
注意nginx只有一个端口为80,部署在其上的服务都通过都通过servername进行分配,listen相应的端口号,注意不可重复
server_name _; #servername这么写表示不启用域名,直接ip访问
然后server_name 为虚拟服务器的识别路径。因此不同的域名会转发到对应的应用服务器中去,
在修改nginx.conf文件后使用 热启动指令
nginx -s reload #重新读取nginx配置文件内容
gzip
nginx自带压缩功能,但对视频图片效果不好,建议只对css,js等进行压缩
gzip on; #默认为off
location
http>server>location这项参数
语法规则: location [=|~|~*|^~] /uri/ { … }
=
开头表示精确匹配^~
开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。以xx开头~
开头表示区分大小写的正则匹配 以xx结尾~*
开头表示不区分大小写的正则匹配 以xx结尾!~
和!~*
分别为区分大小写不匹配及不区分大小写不匹配 的正则/
通用匹配,任何请求都会匹配到。多个location配置的情况下匹配顺序为
location = / {
#规则A
}
location = /login {
#规则B
}
location ^~ /static/ {
#规则C
}
location ~ .(gif|jpg|png|js|css)$ {
#规则D,注意:是根据括号内的大小写进行匹配。括号内全是小写,只匹配小写
}
location ~* .png$ {
#规则E
}
location !~ .xhtml$ {
#规则F
}
location !~* .xhtml$ {
#规则G
}
location / {
#规则H
}
那么产生的效果如下:
访问根目录/, 比如http://localhost/ 将匹配规则A
http://localhost/login 将匹配规则B,http://localhost/register 则匹配规则H
http://localhost/static/a.html 将匹配规则C
http://localhost/a.gif, http://localhost/b.jpg 将匹配规则D和规则E,但是规则D顺序优先,规则E不起作用, 而 http://localhost/static/c.png 则优先匹配到 规则C
http://localhost/a.PNG 则匹配规则E, 而不会匹配规则D,因为规则E不区分大小写。
http://localhost/a.xhtml 不会匹配规则F和规则G,
http://localhost/a.XHTML不会匹配规则G,(因为!)。规则F,规则G属于排除法,符合匹配规则也不会匹配到,所以想想看实际应用中哪里会用到。
http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为方向代理服务器存在。
#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
proxy_pass http://tomcat:8080/index
}
# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ { //以xx开头
root /webroot/static/;
}
location ~* .(gif|jpg|jpeg|png|css|js|ico)$ { //以xx结尾
root /webroot/res/;
}
#第三个规则就是通用规则,用来转发动态请求到后端应用服务器
#非静态文件请求就默认是动态请求,自己根据实际把握
location / {
proxy_pass http://tomcat:8080/
}
静态http服务器配置
server {
listen 80;
server_name localhost;
client_max_body_size 1024M;
location / {
root /usr/...; //通过/将所有的请求,转发给root的路径处理
index index.html;
}
}
反向代理配置
server {
listen 80;
server_name localhost; #访问localhost的时候相当于访问 http://localhost:8080
client_max_body_size 1024M;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host 192.168.11.139:80 //通过/,将所有的请求,转发给第3方处理
}
}
#为了将不同的请求分达到多个服务器,反向代理存在的意义
重定向配置
server {
listen 80;
server_name start.igrow.cn;
index index.html index.php;
root html;
if ($http_host !~ "^star.igrow.cn$" {
rewrite ^(.*) http://star.igrow.cn$1 redirect;
}
}
防盗链配置
location ~* .(gif|jpg|png|bmp)$ {
# 来源是自己的网站或者是百度和谷歌的搜索结果才不回被block
valid_referers none blocked *.***.com server_names ~.google. ~.baidu.;
if ($invalid_referer) {
return 403; #假如不是自己的网站返回403页面
#rewrite ^/ http://www.ttlsa.com/403.jpg;
}
}
根据图片文件类型设置过期时间
location ~* .(js|css|jpg|jpeg|gif|png|swf)$ {
if (-f $request_filename) { //只能是写了扩展名的文件,因为这用-f判断了
expires 1h;
break;
}
}
设置禁止访问某个目录
location ~* .(txt|doc)${
root /data/www/wwwroot/linuxtone/test; #所有用户都禁止访问这个目录
deny all;
}
隐藏版本号
#通过你所用的版本,找其漏洞,进行攻击你
在http中添加该配置:server_tokens off;
动静分离
# 所有静态请求都由nginx处理,存放目录为html
location ~ .(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
root /usr/local/nginx/...;
}
# 所有动态请求都转发给tomcat处理
location ~ .(jsp|do)$ {
proxy_pass http://test;
}
指南三:provisional headers are shown
在部署后出现请求一直发不到服务器的问题,在request header中出现provisional headers are shown的问题
现在网站的静态资源都会存在专门的静态域名下面,和实际访问的域名可能不一致。
这种情况基本发生在ajax请求,都是基于CORS来解决这个问题。
服务器上无法访问相应的文件夹,或者服务器异常均会导致此问题产生。
chrome插件会导致此问题的产生
只从缓存中获得的通信显示为“显示临时标题”(或“执行”),因为该文件是从缓存中获取的,并且未进行通信,所以并不会显示详细标头。
如果上一个资源加载失败,可能导致从缓存加载的资源失败,即缓存资源请求之前的请求不能失败。强缓存from disk cache或者from memory cache,此时也不会显示。
前面提到的那么多情况,其实都是与服务器没有进行或者完成正确的通信,所以只展示临时信息。
指南四:nginx文件访问403问题
访问相应的IP与端口出现403页面。最终通过修改scp后的文件夹权限解决此问题。
出现403是因为服务器拒绝了你的地址请求,很有可能是你根本就没权限访问网站,就算你提供了身份验证也没用。
1.权限配置不正确
这个是nginx出现403 forbidden最常见的原因。
为了保证文件能正确执行,nginx既需要文件的读权限,又需要文件所有父目录的可执行权限。
例如,当访问/usr/local/nginx/html/image.jpg时,nginx既需要image.jpg文件的可读权限,也需要/, /usr,/usr/local,/usr/local/nginx,/usr/local/nginx/html的可以执行权限。
解决办法: 设置所有父目录为755权限,设置文件为644权限可以避免权限不正确。
2.目录索引设置错误(index指令配置)
网站根目录不包含index指令设置的文件。
例如,运行PHP的网站,通常像这样配置index
index index.html index.htm index.php;
当访问该网站的时,nginx 会按照 index.html,index.htm ,index.php 的先后顺序在根目录中查找文件。如果这三个文件都不存在,那么nginx就会返回403 Forbidden。
如果index中不定义 index.php ,nginx直接返回403 Forbidden而不会去检查index.php是否存在。
同样对于如果运行jsp, py时也需要添加index.jsp,index.py到目录索引指令index中。
解决办法: 添加首页文件到index指令,常见的是index.php,index.jsp,index.jsp或者自定义首页文件。
系统中不同文件
红色文件为压缩文件
蓝色文件为目录
绿色文件表示文件有执行权限,只有具备相应权限的用户才可访问
白色文件表示任何用户均可访问该文件
-rwx------:等于数字表示700。
-rwxr—r--:等于数字表示744。
-rw-rw-r-x:等于数字表示665。
drwx—x—x:等于数字表示711。
drwx------:等于数字表示700。
通过以下命令修改权限(绿转白)
chmod 755 file/filename
或者
chmod -x file/filename
可以参考:
centos修改文件及文件夹权限 - 山高我为峰 - 博客园www.cnblogs.com将相应非755文件夹及文件转换为755
软件负载均衡 lvs nginx haproxy
硬件负载均衡 f5 netscalar
总结:1台就是反向代理,多台就是负载均衡
反向代理:就是后端服务不直接对外暴露,请求首先发送到nginx,然后nginx将请求转发到后端服务器,比如tomcat php等.如果后端服务只有一台服务器,nginx在这里只有一个作用就是起到了代理后端服务接收请求的作用.称之为反向代理.
负载均衡:在现实的应用场景中,一台后端服务器出现单点故障的概率很大或者单台机器的吞吐量有限,无法承担过多请求.这时候就需要在nginx后端配置多台服务器,利用nginx内置的规则讲请求转发到后端不同的机器上.这时候就起到了负载均衡的作用.
配置方法:
//写在 http中,upstream backend和server是平级
//这种是普通的轮训方式
upstream backend {
server ip:81;
server ip:82;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://backend; //这的backend是upstream后面的
}
}
配置完使用热启动命令
nginx -s reload
重启nginx
四种upstream的配置方式
1)、轮询(也叫RR,是默认的策略)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。 参照上面最简单的配置方法即可
2)、weight 权重
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
upstream test {
server localhost:8080 weight=9;
server localhost:8081 weight=1;
}
//10次一般只会有1次会访问到8081,而有9次会访问到8080
3)、ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。 PR 和权重 在有session
进行访问时,由于随机访问,导致session
无效,需要使用ip_hash
upstream test {
ip_hash;
server localhost:8080;
server localhost:8081;
}
4.1)、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream backend {
fair;
server localhost:8080; //基于多端口
server localhost:8081;
}
4.2)、url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。 在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法。
upstream backend {
hash $request_uri;
hash_method crc32;
server localhost:8080; //基于多端口
server localhost:8081;
}
Happy Hacking!!
持续更新中~~~