随着网站业务的发展,网站用户访问量不断激增,单台服务器将无法满足访问压力,需要部署多台服务器来集群分发服务,然后通过 Nginx 把服务反向代理到多台服务器,统一请求入口。
根据不同的场景来反向代理分发到不同服务器,如根据来访区域、搜索引擎爬虫、浏览器等
1、根据来访区域分发
基于来访的 IP 地址,通过 Nginx 的 ngx_http_geo_module 模块,分发到不同的服务器
# 默认服务器
upstream default.server {
server server_default;
}
# 北京服务器
upstream beijing.server {
server server_beijing;
}
# 广州服务器
upstream guangzhou.server {
server server_guangzhou;
}
# IP 库
geo $geo {
server_default default;
server_beijing beijing;
server_guangzhou guangzhou;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://$geo.server$request_uri;
}
}
2、根据来访搜索引擎爬虫分发
基于来访的 user agent,根据 Nginx 的 $http_user_agent ,分发到不同的服务器
# 默认服务器
upstream default.server {
server server_default;
}
# 百度蜘蛛服务器
upstream baidu.server {
server server_baidu;
}
# 谷歌蜘蛛服务器
upstream google.server {
server server_google;
}
server {
listen 80;
server_name www.example.com;
location / {
set $spider 0;
if ($http_user_agent ~ "Baiduspider|^$" ) {
set $spider 1;
}
if ($http_user_agent ~ "Googlebot|^$" ) {
set $spider 2;
}
if ($spider ~* 1) {
proxy_pass http://baidu.server;
}
if ($spider ~* 2) {
proxy_pass http://google.server;
}
if ($spider ~* 0) {
proxy_pass http://default.server;
}
}
}
3、根据来访客户端的浏览器分发
基于来访的 user agent,根据 Nginx 的 $http_user_agent ,分发到不同的服务器
# 默认服务器
upstream default.server {
server server_default;
}
# 移动端服务器
upstream mobile.server {
server server_mobile;
}
server {
listen 80;
server_name www.example.com;
location / {
set $useragent 0;
if ($http_user_agent ~ "Mobile|iPhone|Android|iPad|^$" ) {
set $useragent 1;
}
if ($useragent ~* 1) {
proxy_pass http://mobile.server;
}
if ($useragent ~* 0) {
proxy_pass http://default.server;
}
}
}
4、根据开发语言分发
适用于混合开发的网站,某些大型网站既有 aspx,php 也有 jsp,分发到不同的服务器
# 默认服务器
upstream default.server {
server server_default;
}
# php 服务器
upstream php.server {
server server_php;
}
# asp 服务器
upstream asp.server {
server server_asp;
}
server {
listen 80;
server_name www.example.com;
location ~* \.php$ {
proxy_pass http://php.server;
}
location ~* \.asp$ {
proxy_pass http://asp.server;
}
}
5、根据业务分发
适用于一个公司有多个网站,一个网站设置为一个集群
# 默认服务器
upstream default.server {
server server_default;
}
# oa 服务器
upstream oa.server {
server server_oa;
}
# mail 服务器
upstream mail.server {
server server_mail;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://default.server;
}
}
server {
listen 80;
server_name oa.example.com;
location / {
proxy_pass http://oa.server;
}
}
server {
listen 80;
server_name mail.example.com;
location / {
proxy_pass http://mail.server;
}
}
6、根据 http Header 分发
基于请求 Header ,分发到不同的服务器
http {
map $http_custom_header $backend_name {
default backend1;
"version2.0" backend2;
}
upstream backend1 {
server backend1.example.com;
}
upstream backend2 {
server backend2.example.com;
}
server {
listen 80;
location / {
proxy_pass http://$backend_name;
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_set_header X-Forwarded-Proto $scheme;
}
}
}
在这个配置中,$http_custom_header 是一个变量,代表 HTTP 请求 header 中的自定义字段。map 指令根据这个变量的值来设置一个变量 $backend_name。如果请求 header 中的自定义字段值为 “version2.0″,则会将请求转发到 backend2.example.com;否则,会转发到 backend1.example.com。
也可以如下配置
map $http_accept $version {
default "";
"application/vnd.demo.v2.0+json" "v2.0";
}
upstream backend1 {
server backend1.example.com;
}
upstream backend2 {
server backend2.example.com;
}
server {
listen 80;
server_name olive.com;
charset utf-8;
autoindex off;
location / {
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_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Ssl on;
if ($version="v2.0"){
proxy_pass http://backend2;
break;
}
proxy_pass http://backend1;
}
}
在这个配置中,$http_accept 是一个变量,代表 HTTP 请求 header 中的 http_accept 字段。map 指令根据这个变量的值来设置一个变量 $version。如果请求 header 中的自定义字段值为 “application/vnd.demo.v2.0+json”,则$version 的值为 v2.0;否则$version 的值为空字符串。然后 if 条件判断根据$version 的值进行转发。