当单台服务器的负载达到一定程度时,服务器资源就无法满足用户的需求,此时可以通过多种方法来处理。比如说通过DNS解析多台服务器,或者是通过四层根据内容请求进行分发(如LVS),或是通过七层负载技术(nginx、haproxy)等方式来实现。Nginx的反向代理负载均衡能够更好的支持虚拟主机,可配置性强,可以根据服务器的硬件配置按比重进行轮询、权重负载,也可以根据IP哈希、URL哈希对后端服务器做负载,并且还支持对后端服务器的健康检查。
完整的Nginx代理配置如下:
user nginx nginx; #程序所使用的用户
worker_processes 8; #根据CPU决定进程数
error_log /data/logs/nginx-error.log cirt; #错误日志
pid /data/proc/nginx.pid; #进程位置
work_rlimit_nofile 51200; #单进程最大打开文件数
events{
use epoll; #设置用于复用客户端线程的轮询方法,在linux2.6版本之后,都建议使用epoll
worker_connections 51200; #单进程最大连接数
}
http
{
#包含一个文件描述了:不同文件后缀对应的MIME
include mime.types;
#制定默认MIME类型为二进制字节流
default_type application/octet-stream;
#默认字符集
charset utf-8;
#####保存服务器名字的hash表是由指令 server_names_hash_max_size 和 server_names_hash_bucket_size所控制的。参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。如果 hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。第一次是确定存储单元的地址,第二次是在存储单元中查找键 值。因此,如果Nginx给出需要增大 hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小#####以上内容摘自某中文wiki网站#####
server_name_hash_bucket_size 128k;
client_header_buffer_size 32k;
large_client_header_buffer_size 4 32k;
#日志格式
log_format main ‘$remote_addr - $remote_user [$time_local] "$request" ‘ ‘$status $body_bytes_sent "$http_referer"‘ ‘"$http_user_agent" "$http_x_forwarded_for"‘;
#首要访问日志
access_log /data/logs/access.log main;
#开启调用Linux的sendfile,提供文件传输效率
sendfile on;
#是否允许使用socket的TCP_NOPUSH或TCP_CORK选项
tcp_nopush on;
#keepalive不适宜设置过高,过高会影响nginx性能
keepalive_timeout 85;
#客户端最大上传文件大小
client_max_body_size 100m;
#客户端缓存大小
client_body_buffer_size 128k;
#代理连接超时
proxy_connect_timeout 240;
#代理读数据超时
proxy_read_timeout 360;
#代理传输数据超时
proxy_send_timeout 600;
#代理缓存
proxy_buffer_size 16k;
proxy_buffers 4 32k;
proxy_busy_buffer_size 64k;
proxy_temp_file_write_size 64k;
#webapp 代理上行服务器地址池
upstream tomcats {
ip_hash; #ip_hash技术能够将某个ip的请求定向到同一台后端,这样一来这个ip下的某个客户端和某个后端就能建立起稳固的session
server 10.0.1.102:9000 max_fails=1 fail_timeout=5s;
server 10.0.1.108:9000 max_fails=1 fail_timeout=5s;
}
#notify 代理上行服务器地址池
upstream notify_pool {
server 10.0.1.107:10010 max_fails=1 fail_timeout=6s;
server 10.0.1.127:10010 max_fails=1 fail_timeout=6s;
}
}
#fileserver 代理上行服务器地址池
upstream fileserver_pool {
server 10.0.1.104:80 weight=1 max_fails=1 fail_timeout=30s;
}
#将80端口的请求跳转至443端口
server {
listen 80;
server_name www.xxx.com;
rewrite ^(.*) https://www.xxx.com$1 permanent;
}
server {
listen 443 ssl;
server_name www.xxx.com;
### SSL log files ###
access_log /data/logs/ssl-access.log;
#ssl证书文件以及key#
ssl_certificate server.crt;
ssl_certificate_key server.key;
#ssl缓存和超时时间#
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
#ssl 连接加密
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
#webapp 代理配置#
location / {
proxy_next_upstream http_502 http_504 error timeout invalid_header; #当后端服务器出现502或是504错误时,转向另一台可用服务器
proxy_pass http://tomcats; #引用upstream参数tomcats
######Host的含义是表明请求的主机名,因为nginx作为反向代理使用,而如果后端真是的服务器设置有类似防盗链或者根据http请求头中的host字段来进行路由或判断功能的话,如果反向代理层的nginx不重写请求头中的host字段,将会导致请求失败(默认反向代理服务器会向后端真实服务器发送请求,并且请求头中的host字段应为proxy_pass指令设置的服务器)。同理,X_Forward_For字段表示该条http请求是有谁发起的?如果反向代理服务器不重写该请求头的话,那么后端真实服务器在处理时会认为所有的请求都来在反向代理服务器,如果后端有防攻击策略的话,那么机器就被封掉了。因此,在配置用作反向代理的nginx中一般会增加以下两条配置,这里的$host和$remote_addr都是nginx的导出变量,可以再配置文件中直接使用。如果Host请求头部没有出现在请求头中,则$http_host值为空,但是$host值为主域名。因此,一般而言,会用$host代替$http_host变量,从而避免http请求中丢失Host头部的情况下Host不被重写的失误。#######
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
#动静分离#
location ~ .*\.(jsp|do)?$ { #处于jsp或是do的动态请求时,只做代理,不做缓存服务
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_pass http://tomcats;
proxy_next_upstream http_502 http_504 error timeout invalid_header;
}
location ~ .*\.(html|jpg|gif|jpeg|png|bmp|swf|js|css|mp3|mp4|avi|flv)?$ { #将所有的静态资源缓存至本地,强制缓存时间为12小时,过期时间为30m
proxy_next_upstream http_502 http_504 error timeout invalid_header;
proxy_pass http://tomcats;
proxy_cache cache_one;
proxy_cache_valid 200 304 12h;
expires 30m;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
#错误页
location = /50x.html {
root html;
}
}
#fileserver 代理配置#
server {
listen 10000;
server_name www.xxx.com;
location / {
proxy_pass http://fileserver_pool;
proxy_set_header Host $host;
proxy_set_header X-Forward-For $remote_addr;
}
access_log /data/logs/fileserver.access.log;
}
#notify 代理配置#
server {
listen 10010;
server_name www.xxx.com;
location / {
proxy_pass http://notify_pool;
proxy_set_header Host $host;
proxy_set_header X-Forward-For $remote_addr;
}
access_log /data/logs/notify.access.log;
}
}