反向代理
1,准备两台nginx真实服务器
a、nginx-1 启动网站(内容)(作为网站服务器)
b、nginx-2 启动代理程序
一、编辑nginx-2的配置文件[root@nginx-server ~]# vim /etc/nginx/conf.d/default.conf
server {
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://ngnix-1的IP地址:80; #ip地址加端口
proxy_redirect default;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
proxy_busy_buffers_size 256k;
proxy_max_temp_file_size 256k;
}
}
重新加载nginx配置文件[root@nginx-server ~]# systemclt restart nginx
nginx proxy 具体配置详解
proxy_pass :真实服务器的地址,可以是ip也可以是域名和url地址
proxy_redirect :如果真实服务器使用的是的真实IP:非默认端口。则改成IP:默认端口。
proxy_set_header:重新定义或者添加发往后端服务器的请求头
proxy_set_header X-Real-IP :启用客户端真实地址(否则日志中显示的是代理在访问网站)
proxy_set_header X-Forwarded-For:记录代理地址
proxy_connect_timeout::后端服务器连接的超时时间发起三次握手等候响应超时时间
proxy_send_timeout:后端服务器数据回传时间就是在规定时间之内后端服务器必须传完所有的数据
proxy_read_timeout :nginx接收upstream(上游/真实) server数据超时, 默认60s, 如果连续的60s内没有收到1个字节, 连接关闭。像长连接
proxy_buffering on;开启缓存
proxy_buffer_size:proxy_buffer_size只是响应头的缓冲区
proxy_buffers 4 128k; 内容缓冲区域大小
proxy_busy_buffers_size 256k; 从proxy_buffers划出一部分缓冲区来专门向客户端传送数据的地方
proxy_max_temp_file_size 256k;超大的响应头存储成文件。
负载均衡
一、负载均衡使用的是upstream这个模块upstream 这个配置的,是写一组被代理的服务器地址,然后转向upstream进行负载均衡的算法。这里的被代理服务器地址是testapp
编辑nginx的配置文件[root@nginx-server ~]# vim /etc/nginx/conf.d/default.conf
upstream testapp {
server 10.0.105.199:8081; #要负载的二个IP地址
server 10.0.105.202:8081;
}
server {
....
location / {
proxy_pass http://testapp; #请求转向 testapp 定义的服务器列表
}
2、配置实例1、热备:如果你有2台服务器,当一台服务器发生事故时,才启用第二台服务器给提供服务。服务器处理请求的顺序:AAAAAA突然A挂啦,BBBBBBBBBBBBBB.....
upstream myweb {
server 172.17.14.2:8080;
server 172.17.14.3:8080 backup; #热备
}
2、轮询:nginx默认就是轮询其权重都默认为1,服务器处理请求的顺序:ABABABABAB....
upstream myweb {
server 172.17.14.2:8080;
server 172.17.14.3:8080;
}
3、加权轮询:跟据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置,则默认为1。下面服务器的请求顺序为:ABBABBABBABBABB....
upstream myweb {
server 172.17.14.2:8080 weight=1;
server 172.17.14.3:8080 weight=2;
}
4、ip_hash:nginx会让相同的客户端ip请求相同的服务器。
upstream myweb {
server 172.17.14.2:8080;
server 172.17.14.3:8080;
ip_hash;
}
5、nginx负载均衡配置状态参数
- down,表示当前的server暂时不参与负载均衡。
- backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。
- max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
- fail_timeout,在经历了max_fails次失败后,暂停服务的时间单位秒。max_fails可以和fail_timeout一起使用。
upstream myweb {
server 172.17.14.2:8080 weight=2 max_fails=2 fail_timeout=2;
server 172.17.14.3:8080 weight=1 max_fails=2 fail_timeout=1;
}
nginx 会话保持的几种方法
一、ip_haship_hash使用源地址哈希算法,将同一客户端的请求总是发往同一个后端服务器,除非该服务器不可用。
upstream backend {
ip_hash;
server ip地址;
server ip地址;
server IP地址 down;
}
p_hash简单易用,但有如下问题:
当后端服务器宕机后,session会丢失;
来自同一局域网的客户端会被转发到同一个后端服务器,可能导致负载失衡;
不适用于CDN网络,不适用于前段还有代理的情况。
二、sticky_cookie_insert使用sticky_cookie_insert启用会话亲缘关系,这会导致来自同一客户端的请求被传递到一组服务器的同一台服务器。与ip_hash不同之处在于,它不是基于IP来判断客户端的,而是基于cookie来判断。因此可以避免上述ip_hash中来自同一局域网的客户端和前段代理导致负载失衡的情况。(需要引入第三方模块才能实现)
upstream backend {
server backend1.example.com;
server backend2.example.com;
sticky_cookie_insert srv_id expires=1h domain=3evip.cn path=/;
}
expires:设置浏览器中保持cookie的时间
domain:定义cookie的域
path:为cookie定义路径
三、jvm_route方式
jvm_route是通过session_cookie这种方式来实现session粘性。将特定会话附属到特定tomcat上,从而解决session不同步问题,但是无法解决宕机后会话转移问题。如果在cookie和url中并没有session,则这只是个简单的round-robin负载均衡。
jvm_route的原理
- 一开始请求过来,没有带session的信息,jvm_route就根据round robin的方法,发到一台Tomcat上面
- Tomcat添加上session信息,并返回给客户
- 用户再次请求,jvm_route看到session中有后端服务器的名称,他就把请求转到对应的服务器上
暂时jvm_route模块还不支持fair的模式。jvm_route的工作模式和fair是冲突的。对于某个特定用户,当一直为他服务的Tomcat宕机后,默认情况下它会重试max_fails的次数,如果还是失败,就重新启用round robin的方式,而这种情况下就会导致用户的session丢失。
4、使用后端服务器自身通过相关机制保持session同步,如:使用数据库、redis、memcached 等做session复制
网站转接 Rewrite 相关指令
Nginx Rewrite 相关指令有 if、rewrite、set、return
if 语句
- 应用环境
server,location
语法:
if (condition) { … }
if 可以支持如下条件判断匹配符号
~ 正则匹配 (区分大小写)
~* 正则匹配 (不区分大小写)
!~ 正则不匹配 (区分大小写)
!~* 正则不匹配 (不区分大小写)
-f 和!-f 用来判断是否存在文件
-d 和!-d 用来判断是否存在目录
-e 和!-e 用来判断是否存在文件或目录
-x 和!-x 用来判断文件是否可执行
在匹配过程中可以引用一些Nginx的全局变量
$args 请求中的参数;
$document_root 针对当前请求的根路径设置值;
$host 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
$limit_rate 对连接速率的限制;
$request_method 请求的方法,比如"GET"、"POST"等;
$remote_addr 客户端地址;
$remote_port 客户端端口号;
$remote_user 客户端用户名,认证用;
$request_filename 当前请求的文件路径名(带网站的主目录/usr/local/nginx/html/images /a.jpg)
$request_uri 当前请求的文件路径名(不带网站的主目录/images/a.jpg)
$query_string 与$args相同;
$scheme 用的协议,比如http或者是https
$server_protocol 请求的协议版本,"HTTP/1.0"或"HTTP/1.1";
$server_addr 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
$server_name 请求到达的服务器名;
$document_uri 与$uri一样,URI地址;
$server_port 请求到达的服务器端口号;
Rewrite flag
**rewrite** 指令根据表达式来重定向URI,或者修改字符串。可以应用于**server,location, if**环境下每行rewrite指令最后跟一个flag标记,支持的flag标记有:
last 相当于Apache里的[L]标记,表示完成rewrite。默认为last。
break 本条规则匹配完成后,终止匹配,不再匹配后面的规则
redirect 返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent 返回301永久重定向,浏览器地址会显示跳转后URL地址
redirect 和 permanent区别则是返回的不同方式的重定向,对于客户端来说一般状态下是没有区别的。而对于搜索引擎,相对来说301的重定向更加友好,如果我们把一个地址采用301跳转方式跳转的话,搜索引擎会把老地址的相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的老地址。使用302重定向时,搜索引擎(特别是google)有时会查看跳转前后哪个网址更直观,然后决定显示哪个,如果它觉的跳转前的URL更好的话,也许地址栏不会更改,那么很有可能出现URL劫持的现像。在做URI重写时,有时会发现URI中含有相关参数,如果需要将这些参数保存下来,并且在重写过程中重新引用,可以用到 () 和 $N 的方式来解决。
2.3、Rewrite匹配参考示例
本地解析host文件
# http://www.testpm.com/a/1.html ==> http://www.testpm.com/b/2.html
location /a {
root /html;
index 1.html index.htm;
rewrite .* /b/2.html permanent;
}
location /b {
root /html;
index 2.html index.htm;
}
例2:
# http://www.testpm.com/2019/a/1.html ==> http://www.testpm.com/2018/a/1.html
location /2019/a {
root /var/www/html;
index 1.html index.hml;
rewrite ^/2019/(.*)$ /2018/$1 permanent;
}
location /2018/a {
root /var/www/html;
index 1.html index.htl;
}
例3:
# http://www.qf.com/a/1.html ==> http://jd.com
location /a {
root /html;
if ($host ~* testpm.com ) {
rewrite .* http://jd.com permanent;
}
}
例4:
# http://www.qf.com/a/1.html ==> http://jd.com/a/1.html
location /a {
root /html;
if ( $host ~* testpm.com ){
rewrite .* http://jd.com$request_uri permanent;
}
}
例5: 在访问目录后添加/ (如果目录后已有/,则不加/)
# http://www.tianyun.com/a/b/c
# $1: /a/b
# $2: c
# http://$host$1$2/
location /a/b/c {
root /usr/share/nginx/html;
index index.html index.hml;
if (-d $request_filename) {
rewrite ^(.*)([^/])$ http://$host$1$2/ permanent;
}
}
例6:
# http://www.tianyun.com/login/tianyun.html ==> http://www.tianyun.com/reg/login.html?user=tianyun
location /login {
root /usr/share/nginx/html;
rewrite ^/login/(.*)\.html$ http://$host/reg/login.html?user=$1;
}
location /reg {
root /usr/share/nginx/html;
index login.html;
}
例7:
#http://www.tianyun.com/qf/11-22-33/1.html ==> http://www.tianyun.com/qf/11/22/33/1.html
location /qf {
rewrite ^/qf/([0-9]+)-([0-9]+)-([0-9]+)(.*)$ /qf/$1/$2/$3$4 permanent;
}
location /qf/11/22/33 {
root /html;
index 1.html;
}