对于lvs集群,是一个四层路由的集群,Director无需启用对端口的监控,直接将报文转发给后端业务服务器RealServer。
使用Nginx也可以实现集群功能,Nginx实现反向代理,实现的是七层上的转发,要求Nginx本身就是一个WEB服务器,监听在80端口,然后按照不同的请求,对后端业务服务器,这里叫做upstream server,上游服务器,再发起请求,获得结果后返回给客户端。
Nginx反向代理配置 ,主要是模块ngx_http_proxy_module :官网:http://nginx.org/en/docs/http/ngx_http_proxy_module.html
Module ngx_http_proxy_module
Nginx安装,可以下载.rpm包直接安装,而不必源码编译安装
http://nginx.org/packages/centos/7Server/x86_64/RPMS/
rpm -ivh nginx-1.26.0-1.el7.ngx.x86_64.rpm
配置:
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
在192.168.61.129上配置nginx
在192.168.61.130上部署httpd
配置/etc/nginx/conf.d/default.conf:
未重新启动nginx,访问192.168.61.129:
重新启动nginx后,再次访问192.168.61.129:
请求转发到后端的upstream server上了。查看upstream server上的httpd日志:
发现最后请求的客户端地址是192.168.61.129,而不是真正的客户端192.168.61.1
也可以对不同的请求进行不同的映射处理
访问192.168.61.129时,访问的是nginx的/usr/share/nginx/html/下的index.html,访问192.168.61.129/form/时,会访问192.168.61.130/bbs/下的index.html
使用模式匹配时,proxy_pass的http://192.168.61.130后不能加任何url,否则语法错误。
proxy_pass http://192.168.147.140/bbs/;
访问http://192.168.61.129/1.jpg --> http://192.168.61.130/1.jpg
http://192.168.61.129/bbs/1.jpg --> http://192.168.61.130/bbs/1.jpg
将匹配到的整个路径添加到proxy_pass后。
这种配置下,后端服务器的日志记录中客户端地址都是nginx代理服务器地址,hostname也都是后端服务器,可以使用nginx核心模块的内嵌变量进行信息传递。
ngx_http_core_module中:
Embedded Variables
$arg_name
$args
$binary_remote_addr
$body_bytes_sent
$bytes_sent
$connection
$connection_requests
$connection_time
$content_length
$content_type
$cookie_name
$document_root
$document_uri
$host
$hostname
$http_name
$https
$is_args
$limit_rate
$msec
$nginx_version
$pid
$pipe
$proxy_protocol_addr
$proxy_protocol_port
$proxy_protocol_server_addr
$proxy_protocol_server_port
$proxy_protocol_tlv_name
$proxy_protocol_tlv_alpn
$proxy_protocol_tlv_0x01
$proxy_protocol_tlv_ssl_version
$proxy_protocol_tlv_ssl_0x21
$query_string
$realpath_root
$remote_addr
$remote_port
$remote_user
$request
$request_body
$request_body_file
$request_completion
$request_filename
$request_id
$request_length
$request_method
$request_time
$request_uri
$scheme
$sent_http_name
$sent_trailer_name
$server_addr
$server_name
$server_port
$server_protocol
$status
$tcpinfo_rtt, $tcpinfo_rttvar, $tcpinfo_snd_cwnd, $tcpinfo_rcv_space
$time_iso8601
$time_local
$uri
在upstreamserver上,对httpd的日志进行配置:
此时再次访问后,查看httpd的日志:
客户端地址已经是实际的客户端地址了。
Nginx代理具有内置的缓存:
proxy_cache zone | off;
proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size
proxy_cache_methods GET | HEAD | POST ...;
proxy_cache_min_uses number;
proxy_cache_purge string ...;
proxy_cache_revalidate on | off;
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | off ...;
proxy_cache_valid [code ...] time;
修改/etc/nginx/nginx.conf:
修改/etc/nginx/conf.d/default.conf,对服务器中的location添加缓存:
重新启动nginx后,再次访问时,在/cache/nginx下就有缓存内容了,客户端再次访问时,内容就从缓存中取。
proxy_connect_timeout:连接超时时间。
proxy_hide_header:upstream响应的头部内容,不打算反馈给客户端。
proxy_read_timeout time:
upstream模块 :Module ngx_http_upstream_module
在使用proxy_pass指令时,指定的是单个主机,可以使用upstream模块指定一组主机,实现负载均衡。
定义服务器组:proxy_pass、fastcgi_pass、uwsgi_pass
upstream只能定义在http中。
在http中定义好upstream后,在server的location中使用:
此时访问http://192.168.61.129/,不断刷新,就会交替访问128和130两个upstreamserver。
还可以对定义的server加权重:
此时,128权重为2,130权重默认1,访问时128出现2次130出现1次。
也可以指定调度方法,如ip_hash:
此时再访问,就固定在一个upstream server上了。
server参数除了weight外,还有:
max_fails=#,失败次数
fail_timeout=#,失败的时间,秒数
此时停止128的httpd,访问就固定到130上了。如果128启动httpd,又可以负载均衡了。
down参数,手工标记某服务器下线;
backup参数,标记某服务器为备用服务器;
此时访问,只有130响应,如果130故障,128才会上线,只要服务器组中有一个可用的server,backup服务器都不会上线。
proxy_cache_bypass string:设置在何种情形下nginx将不从cache取数据;
个人私有内容或设置某些标记的内容不会从缓存中获取
$cookie_nocache $arg_nocache $http_authorization
根据IP绑定,会造成使用SNAT访问的众多客户端被绑定到同一台upstream server,而根据cookie进行绑定,即使是同一个客户端,使用不同的浏览器,在http看来也是两个不同的客户端,所以使用基于cookie的绑定,可以很好的解决SNAT的问题。(lvs无法实现,因为无法识别应用层的cookie)
基于sticky实现session绑定:
三种方法:cookie、route、learn
sticky cookie name [expires=time] [domain=domain] [httponly] [samesite=strict|lax|none|$variable] [secure] [path=path];
sticky route $variable ...;
sticky learn create=variable lookup=variable zone=name:size [timeout=time] [header] [sync];
least_conn:调度方法,最少连接;
keepalive connections:保持连接,一般是非http协议时使用;
health_check:在location上下文中使用,对proxy_pass的upstream server做健康检查;建议,关闭该location中的访问日志;可以带的参数:interval=time,fails=number,passes=number,uri=uri,match=name
upstream模块自带的内嵌变量:
$upstream_addr
$upstream_bytes_received
$upstream_bytes_sent
$upstream_cache_status
$upstream_connect_time
$upstream_cookie_name
$upstream_header_time
$upstream_http_name
$upstream_last_server_name
$upstream_queue_time
$upstream_response_length
$upstream_response_time
$upstream_status
$upstream_trailer_name
在server上下文中可以使用add_header给响应头增加自定义头部信息。如增加信息
add_header X-Cache $upstream_cache_status;
向客户端提供本次请求是否缓存命中。
**Module ngx_http_fastcgi_module :**allows passing requests to a FastCGI server.
客户端向nginx发起.php(或其他动态资源如jsp)的访问.
安装php-fpm:yum install php-fpm
修改nginx配置文件/etc/nginx/conf.d/default.conf:
运行php-fpm:
查看配置文件:/etc/php-fpm.conf、/etc/php-fpm.d/www.conf,其中配置了监听地址和端口,以及其他一些配置项。
启动:systemctl start php-fpm.service
修改nginx配置文件/etc/nginx/conf.d/default.conf
修改/etc/nginx/fastcgi_params:
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME document_rootfastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
访问:http://192.168.61.129/index.php,显示
index.php :<?php phpinfo(); ?>
测试数据库连接:test.php
<?php
$conn=mysql_connect('127.0.0.1','root','');
if ($conn)
echo succ;
else
echo fail;
?>
这里实际上实现了动静分离的功能。静态资源请求转发到upstream server,动态资源转发到php-fpm服务器。
此时的架构:
一般的,会使用LNAMP架构:
对于动态资源,使用fastcgi,也可以使用缓存,跟proxy_cache类似:
在http上下文中定义fastcgi缓存:
fastcgi_cache_path /cache/fastcgi/ levels=1:2 keys_zone=fastcache:10m inactive=3m max_size=1g;
在location中使用:
fastcgi_cache fastcache
再次访问index.php:
可以看到,相应报头中缓存是HIT,缓存命中,使用了缓存。
后续就是对相关模块的各个指令进行深入研究,进行精细化定制。
对于缓存,可以使用ab工具进行压力测试,可以感受到使用缓存后响应速度大增。
ab -n 100 -c 200 http://192.168.61.129/index.php
概念:一致性hash
一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。 在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题 。
致性哈希算法将整个哈希值空间映射成一个虚拟的圆环,整个哈希空间的取值范围为0~2^32-1。整个空间按顺时针方向组织。0~2^32-1在零点中方向重合。接下来使用如下算法对服务请求进行映射,将服务请求使用哈希算法算出对应的hash值,然后根据hash值的位置沿圆环顺时针查找,第一台遇到的服务器就是所对应的处理请求服务器。当增加一台新的服务器,受影响的数据仅仅是新添加的服务器到其环空间中前一台的服务器(也就是顺着逆时针方向遇到的第一台服务器)之间的数据,其他都不会受到影响。