一、nginx负载均衡
当我们的应用单例不能支撑用户请求时,此时就需要扩容,从一台服务器扩容到两台、几十台、几百台,我们需要一个入口,将客户端请求均衡分布在后台的多 个服务器上。
负载均衡在服务端开发中算是一个比较重要的特性, nginx 提供的负载均衡可以实现上游服务器的负载均衡、故障转移、失败重试、容错、健康检查,当某些 上游服务器出现问题时,可以将请求转到其它的上游服务器从而保障高可用。
第一步我们需要给 nginx 配置上游服务器,即负载均衡到真实的处理业务的服务器 通过在 http 指令下配置 upstream 即可。
指定一组上游服务器地址,其中,地址可以是域名、IP地址。可以在域名或者IP地址后加端口,如果不加端口,那么默认使用80端口。
语法: upstream name { ... }
默认值: —
上下文: http
例子:
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
}
server {
location / {
proxy_pass http://backend;
}
}
upstream 指令当中包含server指令
语法: server address [parameters];
默认值: —
上下文: upstream
可以定义下面的参数:
weight=number 设定服务器的权重,默认是1,权重越大被访问机会越大,要根据机器的配置情况来配置
max_fails=number 设定Nginx与服务器通信的尝试失败的次数。在fail_timeout参数定义的时间段内,如果失败的次数达到此值,Nginx就认为服务器不 可用。在下一个fail_timeout时间段,服务器不会再被尝试。 失败的尝试次数默认是1。
可以通过指令proxy_next_upstream 和memcached_next_upstream来配置什么是失败的尝试。 默认配置时,http_404状态不被认为是失败的尝试。
fail_timeout=time 统计失败尝试次数的时间段。在这段时间中,服务器失败次数达到指定的尝试次数,服务器就被认为不可用。默认情况下,该超时时间是10秒。
backup 标记为备用服务器。当主服务器不可用以后,请求会被传给这些服务器,配置这个指令可以实现故障转移。
down 标记服务器永久不可用,可以跟ip_hash指令一起使用。
当访问Nginx时,会将请求反向代理到backend配置的upstream server。
上游服务器实例代码如下:
<?php
$http = new Swoole\Http\Server("0.0.0.0",9501);
$http->on('request',function($request,$response){
$response->end("<h1>9501</h1>");
});
$http->start();
接下来启动服务
nginx配置如下:
user root;
#worker进程数量 grep processor /proc/cpuinfo|wc -l 查看进程 cpu小于等于核数
worker_processes 2;
worker_priority -15; #woker进程优先级-20~19
worker_cpu_affinity auto; #自动绑定cpu跟进程的关系
worker_rlimit_nofile 65535;#理论上这个值是最多打开文件数(ulimit -n)与nginx工作进程相除
error_log /var/log/nginx/error.log warn;
#pid /var/run/nginx.pid;
events {
worker_connections 20480;#单个进程允许的客户端最大连接数
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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 /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
#负载均衡配置
upstream swoole_server {
#ip_hash;
#least_conn;#最少连接数
#backup 和 ip_hash 无法同时使用
#hash $key;#商品id
server 110.67.104.69:9501 ;#weight=10;
server 110.67.104.69:9502 max_fails=1 fail_timeout=30s;#weight=8;
server 110.67.104.69:9503 backup;#weight=3;
}
#黑白名单限制 判断客户端的地址是否在白名单列表当中
geo $whiteIpList{
default 0;
139.159.141.107 1;
#include '/conf/whiteIpList';
}
#如果不在白名单中,返回客户端的二进制ip地址
map $whiteIpList $limit {
1 $binary_remote_addr;
0 "";
}
#如果返回空字符串那么速率限制会失效
limit_req_zone $limit zone=test:1m rate=1r/s;#限制请求数
server {
listen 80;
server_name 127.0.0.0.1;
root /var/www/html;
#负载均衡相关配置 参数设置
if ( $request_uri ~* ^\/.*id\/(\d+).* ) {
set $key $1;
}
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
limit_req zone=test burst=5 nodelay;
index index.php index.html index.htm;
}
#黑白名单限流测试
location /ip {
default_type text/html;
return 200 '$limit';
}
#禁止访问某些文件
location ~.*\.(sql|log|txt|jar|war|sh) {
deny all;
}
#防盗链
location ~ .*\.(jpg|png|flv|zip|jpeg|gif|bmp|rar|swf|wmv|mp3|mmf|asf)$ {
#alias /var/www/html/test;#指定文件夹路径
#第一种方法
#valid_referers none blocked 47.98.147.49 *.23673.com;
#if ( $invalid_referer ) {
#rewrite ^/ http://xxx.xxx.xxx/nolink.jpg break;
# return 403 "$request_filename";
#}
#嵌入lua脚本文件
#init_lua_file "index.lua";
#第二种方法
accesskey on; #模块开关
accesskey_hashmethod md5; #加密方式MD5或者SHA-1
accesskey_arg "sign"; #url中的关键字参数
accesskey_signature "jason$remote_addr"; #加密值,此处为mypass和访问IP构成的字符串
#accesskey_signature "jason$uri"; #加密值,此处为mypass和访问路径构成的字符串
#expires 30d;
}
#均衡代理
location /upstream {
#default_type text/html;
#return 200 '$key';
proxy_next_upstream error timeout;#超时
proxy_next_upstream_tries 2; #重试次数
proxy_next_upstream_timeout 1; #重试的超时时间
proxy_send_timeout 10;#后端服务器数据回传时间(代理发送超时时间)
proxy_read_timeout 10;#连接成功后,后端服务器响应时间(代理接收超时时间)
proxy_connect_timeout 10;#nginx连接后端的超时时间,一般不超过75s
proxy_pass http://swoole_server;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#php文件配置
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #加了这一项
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
}
简单配置如下:
浏览器访问结果如下:(默认位轮询方式 9501-9502-9503)
二、负载均衡的方法
nginx支持以下负载均衡机制:
1、轮询
默认轮训方式 每一个来自网络中的请求,轮流分配给内部的服务器,从1到N然后重新开始。此种负载均衡算法适合服务器组内部的服务器都具有相同的配置并且平均服务请求 相对均衡的情况。
2、加权轮询
通过 weight 参数控制权重
根据服务器的不同处理能力,给每个服务器分配不同的权值,使其能够接受相应权值数的服务请求。例如:服务器A的权值被设计成1,B的权值是3,C的权值是 6,则服务器A、B、C将分别接受到10%、30%、60%的服务请求。此种均衡算法能确保高性能的服务器得到更多的使用率,避免低性能的服务器负载过重。
3、IP Hash
在 upstream 当中配置 ip_hash ;
这种方式通过生成请求源IP的哈希值,并通过这个哈希值来找到正确的真实服务器。这意味着对于同一主机来说他对应的服务器总是相同。使用这种方式,你不 需要保存任何源IP。 将客户端会话"沾住"或者"持久化",以便总是能选择特定服务器,那么可以使用 ip-hash 负载均衡机制。
使用 ip-hash 时,客户端IP地址作为 hash key 使用,用来决策选择服务器集群中的哪个服务器来处理这个客户端的请求。这个方法保证从同一个客户端发起的 请求总是定向到同一台服务器,除非服务器不可用。
4、最少连接数
在 upstream 当中配置 least_conn 实现最少连接数
客户端的每一次请求服务在服务器停留的时间可能会有较大的差异,随着工作时间加长,如果采用简单的轮循或随机均衡算法,每一台服务器上的连接进程可能 会产生极大的不同,并没有达到真正的负载均衡。最少连接数均衡算法对内部中需负载的每一台服务器都有一个数据记录,记录当前该服务器正在处理的连接数 量,当有新的服务连接请求时,将把当前请求分配给连接数最少的服务器,使均衡更加符合实际情况,负载更加均衡。
三、失败重试
通过配置上游服务器 max_fails 和 fail_timeout,指定每个上游服务器,当 fail_timeout 时间内失败了 max_fails 次请求,则认为该上游服务器不可用/不存 活,然后这段时间将不会访问这台上游服务器, fail_timeout 时间后会再次进行重试。
max_fails=2 fail_timeout=30s 这2个一起搭配使用,表示:当失败2次的时候,就停止使30秒
proxy_next_upstream 指令
在nginx的配置文件中, proxy_next_upstream 项定义了什么情况下进行重试
语法: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 http_503 | http_504 |http_404 | off ...;
默认值: proxy_next_upstream error timeout;
上下文: http, server, location
其中:
error 表示和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现错误。
timeout 表示和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现超时。
invalid_header 表示后端服务器返回空响应或者非法响应头
http_500 表示后端服务器返回的响应状态码为500
.............
off 表示停止将请求发送给下一台后端服务器
重试不能无限制进行,因此,需要如下两个指令控制重试次数和重试超时时间。
proxy_next_upstream_tries number:设置重试次数,默认0表示不限制,注意此重试次数指的是所有请求次数(包括第一次和之后的重试次数之和)。
proxy_next_upstream_timeout time: 设置重试最大超时时间,默认0表示不限制。
即在 proxy_next_upstream_timeout 时间内允许 proxy_next_upstream_tries 次重试。如果超过了其中一个设置,则 Nginx 也会结束重试并返回客户 端响应(可能是错误码)。
proxy_send_timeout 后端服务器数据回传时间(代理发送超时时间)
proxy_read_timeout 连接成功后,后端服务器响应时间(代理接收超时时间)
proxy_connect_timeout nginx连接后端的超时时间,一般不超过75s
backup(故障转移)
标记为备用服务器。当主服务器不可用以后,请求会被传给这些服务器。
down 标记服务器永久不可用,可以跟ip_hash指令一起使用。