1、反代的模型
反代服务器实现反代功能的是 nginx-proxy 模块
虚拟服务器组实现是由 upstream 模块实现的
大概流程是:客户端发起资源请求,反代服务器上接收后(首部和body全部接收后再发,若报文小于4k内存中缓存,大于4k先缓存在硬盘上),nginx开始解析报文(此时报文源地址是客户的地址),先查看请求的资源知否在反代缓存中命中,若未命中,则自己作为客户端向服务器发起请求(此时报文源地址是反代服务器地址)
那么如何让后端服务器记录真实的客户地址呢,反代中可配置x-forward-to 让反代发给服务器的首部报文中带着源客户的地址
一个大文件如视频文件,会切成好多个报文再逐个发出(首部和body全部接收后再发,若报文小于4k内存中缓存,大于4k先缓存在硬盘上)
2、应用程序发布:
灰度模型:(一部分一部分的更新,先将一个服务器的权重调为0,则10秒后它将不会再接到任何请求了,此时可以将它下线,更新后恢复,如果没问题,再继续别个服务器)
(1) 如果存在用户会话;(一般 会有独立的存放session 的 session 服务器)
从服务器上拆除会话;
(2) 新版本应用程序存在bug;(每一个版本存放一个目录,然后建立一个软链接,让客户访问软链接,而不是直接访问目录,方便升级或者回滚)
回滚;
实操配置
Centos7(1)客户端
Centos7(2)NGINX反向代理服务器
添加另一个网卡,使之工作在局域网中(同后端服务器一个网段),往往是双网卡,但也不是必须双网卡
Centos7(3)后端服务器(装httpd、php、php-mysql、mariadb-server提供静态动态资源)
安装服务:
yuminstall httpd
yum-y install php php-mysql mariadb-server
ss-tnl
systemctlstart httpd.service
查看日志:
tail/var/log/httpd/access_log
3、NGINX反向代理服务器相关模块配置
ngx_http_proxy_module
(1) proxy_pass URL;
location,if in location, limit_except
注意:proxy_pass后面的路径不带uri时,其会将location的uri传递给后端主机;
location/uri/ {
proxy_passhttp://HOST;
}
proxy_pass后面的路径是一个uri时,其会将location的uri替换为proxy_pass的uri;
location/uri/ {
proxy_passhttp://HOST/new_uri/;
}
如果location定义其uri时使用正则表达式的模式,则proxy_pass之后必须不能使用uri;
location~|~* PATTERN {
proxy_pass http://HOST;
}
(2)proxy_set_header field value;
设定发往后端主机的请求报文的请求首部的值;(首部里的源地址可以加上实际客户的ip,而不是反代服务器自己的ip,通过查询日志可以看出结果)
示例:
反代服务器上在虚拟服务器配置文件/etc/nginx/conf.d/default.conf中
server上下文中加
proxy_set_headerX-Real-IP $remote_addr;(客户地址)
proxy_set_headerX-Forwarded-For $proxy_add_x_forwarded_for;(客户地址以及所有的反代地址)
后端服务器主配置文件/etc/httpd/conf/httpd.conf里配置logfrt格式
LogFormat "%h %l %u %t \"%r\"%>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined改为下面:
LogFormat "%{X-Forwarded-For}i %l %u %t\"%r\" %>s %b \"%{Referer}i\"\"%{User-Agent}i\"" combined
配置后:
httpd -t
systemctl restart httpd.service
查看日志:
tail/var/log/httpd/access_log
(3)proxy_cache_path
配置缓存之前,ab压力测试(ab的生成包是yum install apr-util)
proxy_cache_path path [levels=levels][use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size][loader_files=number] [loader_sleep=time] [loader_threshold=time][purger=on|off] [purger_files=number] [purger_sleep=time][purger_threshold=time];
使用示例:
定义在http{}中:
proxy_cache_path/var/cache/nginx/proxy_cache levels=1:2:1 keys_zone=pcache:10m max_size=1g;(缓存路径以后要放在固态硬盘中,做raid0,缓存读取速率固然重要,数据也很重要,现在的网络很依赖缓存,可能有80%的资源由缓存直接提供,缓存一挂,直接都去访问服务器,服务器承受不住,所有系统很依赖缓存,设计缓存要做负载均衡)
定义在server{}及其内部的组件中:(放在所有location之外,则所有location多生效)
proxy_cachepcache;
proxy_cache_key$request_uri;
proxy_cache_valid200 302 10m;
proxy_cache_valid301 1h;
proxy_cache_validany 1m;
此时,再做ab压力测试,ab -c100 -n 5000 http://192.168.58.131/phpinfo.php (800个平均)
(7)proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 |http_502 | http_503 | http_504 | http_403 | http_404 | off ...;
ngx_http_headers_module
Thengx_http_headers_module module allows adding the “Expires” and “Cache-Control”header fields, and arbitrary fields, to a response header.
上面说过了,从反代到后端服务器的报文首部,可以修改,那从反代到客户的响应报文首部,怎么修改呢(就是这个模块的作用ngx_http_headers_module)
(1)add_header name value [always];
向响应报文中添加自定义首部;
可用上下文:http,server, location, if in location
add_headerX-Via $server_addr;(经由谁来帮忙转发的)
add_headerX-Accel $server_name;
(2)expires [modified] time;
expiresepoch | max | off;
用于定义Expire或Cache-Control首部的值,或添加其它自定义首部;
ngx_http_upstream_module
后端服务器不止一个的话,就需要将后端服务器定义成组的专用工具,还可以定义各服务器负载均衡,调度算法等
示例:
只能用在http{}中
upstreambackend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
server{
location / {
proxy_pass http://backend;
}
}
在http 中定义{ (/etc/nginx/nginx.conf)
upstreamwebsrvs {
server 192.168.58.131;
server 192.168.58.132;
}
}
在server中调用 (/etc/nginx/conf.d/default.conf)
location/ {
root /usr/share/nginx/html;
index index.html index.htm;
proxy_pass http://192.168.58.131;(改为)
proxy_pass http://websrvs;
}
默认调度法则是轮循,如果写成这样
server192.168.58.131 weight=2;(权重默认等于1),那它的承载量将增加一倍左右,如果写成
server192.168.58.131 backup;那就只有等另一个server down机这台才会启用
(1)upstream name { ... }
定义后端服务器组;引入一个新的上下文;只能用于http{}上下文中;
(2)server address [parameters];
定义服务器地址和相关的参数;
地址格式:
IP[:PORT]
HOSTNAME[:PORT]
unix:/PATH/TO/SOME_SOCK_FILE
参数:
weight=number
权重,默认为1;(常用)
max_fails=number
失败尝试的最大次数;
fail_timeout=time
设置服务器为不可用状态的超时时长;
backup
把服务器标记为“备用”状态;(常用)
down
手动标记其为不可用;
(5)ip_hash;
源地址hash算法;能够将来自同一个源IP地址的请求始终发往同一个upstreamserver;
upstreamwebsrvs {
server 192.168.58.131;
server 192.168.58.132;
ip_hash;
}
加一条ip_hash在upstream里面,来自同一个源地址的请求始终发往同一个server
hash算法
根据ip做hash,要对它的key做哈希计算,得出一个16进制的数,比如四台server都是默认权重1,那就用这个数除4取膜,0|1|2|3,如果权重是1,1,1,2,那就除5取膜,0|1|2|34,3和4都落在一台server上,但缺点是增删服务器影响范围太大,会引起雪崩效应
一致性hash算法
增删服务器影响范围小,具体实现过程是省略,不表了
在缓存服务器上调度,经常使用的是一致性hash算法
(6)hash key [consistent];
基于指定的key的hash表实现请求调度,此处的key可以文本、变量或二者的组合;
consistent:参数,指定使用一致性hash算法;
为了使同一个用户每次访问都能发往同一个server主机,,
当用户第二次来访问时,怎么定位到同一台服务器上,
示例:
hash$request_uri consistent;(根据用户请求的uri做hash)
hash$remote_addr;(根据源地址做hash)
hash$cookie_name;根据cookie做hash)
ip_hash;
(7)keepalive connections;在upstream上下文中设置,(了解即可)
memcached:(静态、动态、及session)
为什么会出现memcached
反向代理自己当然有缓存功能,可以配置文件开启,然而做负载均衡时,即会有多个反向代理,如果每一个都自己缓存静态资源,那如果有一个down了,这个上的缓存也就没有了,解决方案是设立共享缓存服务器,此处缓存的是后端服务器上的静态、动态、及session资源。有时还可用于后端服务器与数据库之间,用于缓存数据库资源
memcached 的 API 特点
然而memcached 是一个API,与php链接要用到适配器,类似php服务器和mysql服务器连接所用的适配器php-mysql,此处用的是php-pecl-memcache.x86_64(通过yum listall *memcache* 查到的)
缓存服务器:
缓存:cache,无持久存储功能;重启就没有了,存在内存中的
配置过程:
1、nginx作为反代,接受用户请求,并做调度工作,准备工作:配置双网卡,安装nginx包启动服务,做简单相关配置
2、在memcached 服务器上安装memcached和 php-pecl-memcache.x86_64
3、在后端服务器上安装有 httpd、php、mariadb-server、php-mysql
配置php的配置文件php.ini来连接memcached
vim/etc/php.ini
session.save_handler= memcache
session.save_path="tcp:192.168.58.132:11211?persistent=1&weight=1&timeout=1&retry_interval=15"