用于给请求提供服务的分配
短请求可以反向代理
Nginx负载均衡
#upstream是和server同级的
upstream tomcat1{
server localhost:8083;
server localhost:8084;
}
#负载均衡
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://tomcat1;
}
}
分配策略
轮询
权重设置
用于设置负载访问量的比重
默认是1:1的比例,当其中一台服务器挂了,这时候检测到的已挂服务器恢复正常访问前不会再继续访问
upstream tomcat1{
server localhost:8083 weight = 3; #默认是1
server localhost:8084;
}
这样tomcat在访问8083和8084分别是3:1的访问比
ip_hash
根据ip地址获得一个hash值,该hash分配到某一特定服务上
在于同一ip每次访问的是同一台服务器,没有数据共享的问题
upstream tomcat1{
server localhost:8083;
server localhost:8084;
ip_hash;
}
Nginx读写分离
场景还原:
需求分析,前端一台nginx做负载均衡反向代理,后面两台httpd服务器。整个架构是提供BBS(论坛)服务,有一需求得实现读写分离,就是上传附件的功能,我们上传的附件只能上传到Web1,然后在Web1上利用rsync+inotify实现附件同步,大家都知道rsync+inotify只能是主向从同步,不能双向同步。所以Web1可进行写操作,而Web2只能进行读操作,这就带来读写分离的需求,下面我们就来说一下,读写分离怎么实现。
**原理:**根据发送的请求类型,进行相应的动态分发
if ($request_method = "PUT"){}
实现步骤
配置nginx.conf文件
location / {
if ($request_method = "PUT"){
proxy_pass http://172.16.1.251:8099;
}
proxy_pass http://localhost:8080;
}
重启服务
nginx -s reload
发送请求查看效果
我这里只有一台服务器,proxy_pass http://172.16.1.251:8099;
这个地址是错的,指向不到任何地方,这里就拿来测试
正常情况:
错误情况:
至此:所谓读取操作全部在服务A进行,写操作全部在服务B进行,以达到读写分离的效果.
Nginx地址重写
语法
rewrite <regex> <replacement> [flag];
关键字 正则 替代内容 flag标记
关键字:其中关键字error_log不能改变
-
正则:perl兼容正则表达式语句进行规则匹配
-
替代内容:将正则匹配的内容替换成replacement
-
flag标记:rewrite支持的flag标记
flag标记说明:
- rewrite break - url重写后,直接使用当前资源,不再执行location里余下的语句,完成本次请求,地址栏url不变
- rewrite last - url重写后,马上发起一个新的请求,再次进入server块,重试location匹配,超过10次匹配不到报500错误,地址栏url不变
- rewrite redirect – 302临时重定向,地址栏显示重定向后的url,爬虫不会更新url
- rewrite permanent – 301永久重定向, 地址栏显示重定向后的url,爬虫更新url
Nginx内置的全局变量
$args :这个变量等于请求行中的参数,同$query_string
$content_length : 请求头中的Content-length字段。
$content_type : 请求头中的Content-Type字段。
$document_root : 当前请求在root指令中指定的值。
$host : 请求主机头字段,否则为服务器名称。
$http_user_agent : 客户端agent信息
$http_cookie : 客户端cookie信息
$limit_rate : 这个变量可以限制连接速率。
$request_method : 客户端请求的动作,通常为GET或POST。
$remote_addr : 客户端的IP地址。
$remote_port : 客户端的端口。
$remote_user : 已经经过Auth Basic Module验证的用户名。
$request_filename : 当前请求的文件路径,由root或alias指令与URI请求生成。
$scheme : HTTP方法(如http,https)。
$server_protocol : 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。
$server_name : 服务器名称。
$server_port : 请求到达服务器的端口号。
$request_uri : 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
$uri : 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
$document_uri : 与$uri相同。
举例1
location /linayi/images/ {
rewrite "^/linayi/images/2018/([0-10])" http://www.laykj.com$uri break ;
}
假设我访问
http:/localhost/linayi/images/2018/10/02/17/b25fd304-1d16-4e0b-b303-b614e57be499.jpg
,根据/linayi/images的匹配规则,可以进入继续进行重写规则^/linayi/images/2018/([0-10])
是一个正则,代表除去ip+端口后,是以/linayi/images/2018/
开头,并紧接着是从0到10的数字,所以以上条件将会进入http://www.laykj.com$uri结果的地址,$uri代表的是不带请求参数的当前URI,所以最后进入的是
http://www.laykj.com/linayi/images/2018/10/02/17/b25fd304-1d16-4e0b-b303-b614e57be499.jpg
举例2
假设要将地址从:http://blog.tuine.me/article/show?id=1&type=php&cat_id=2
修改为:http://blog.tuine.me/article/show/1?type=php&cat_id=2
方法一
if ( $uri ~ ^/article/show$) {
#注意此处带问号和不带问号的区别,带问号不会携带请求参数
#rewrite ^/ $uri/$arg_id?type=$arg_type&cat_id=$arg_cat_id? redirect;#1
#rewrite ^/ $uri/$arg_id redirect; #2
}
方法二
if($request_uri ~* "/article/show\?id=([0-9]+)&(.*)") {
set $myid $1;#注意$1不能直接使用
set $myque $2;
rewrite ^/ /article/show/$myid?$myque? redirect;
}
$1表示第一个正则表达式匹配的那部分内容,比如 ^([1-10]) 就会把匹配的数组当做变量$1
$2表示第二个,以此类推