反向代理服务器
通常一个大型项目会部署在一组或者多组的后端服务器上,反向代理即就是做这些后端服务器的代理人,只把代理人的IP/域名暴露给客户端,当客户端请求到达时,代理人根据客户端的请求,从其后端的服务器上获取资源,再返回给客户端,从客户端角度来看,只能感知到代理人的存在,而不会感知到后台服务器的存在。
Nginx的特点
- 反向代理加速(无缓存)
- 简单的负载均衡和容错
- 基于IP和名称的虚拟主机服务
- 支持keep-alive和管道连接
- 支持热重启
- …
Nginx内置负载均衡相关策略
-
基于轮询的均衡策略
轮询策略时Nginx的默认负载均衡策略,就是对于到达Nginx服务器的请求按照遍历的方式进行发放
-
基于最少连接数的均衡策略
在该策略下,Nginx会判断当前后端集群服务器中哪个server的Active Connection的数量是最少的,对于新到达Nginx服务器的请求,Nginx将转发给对应的后端服务器
-
基于IP-hash的均衡策略
使用请求的IP地址建立IP-Server之间的映射关系,将对应的IP转发给对应的Server
-
基于加权轮询的衡策略
根据Server的各项信息组织Server的权重,按照优先级进行排序,将请求发给当前优先级最高的Server
Nginx安装
yum install nginx
Nginx结构
Nginx master进程
主要用来管理worker进程,同时接收来自外界的信号,像各个worker进程发送信号,监控worker进程的运行状态(当worker异常退出时,会重启worker进程)
- 读取和验证配置
- 创建,绑定,关闭socket
- 启动,终止,维护worker进程的配置数量
- 热重启
- 控制非停止的二进制更新
- 重新打开日志文件
- 编译嵌入的Perl脚本
worker进程
处理网络事件请求,多个worker进程之间同等竞争来自客户端的请求,相互独立;一个请求只可能在一个worker进程中被处理,当请求到达时,所有的worker进程争抢锁accept_mutex,抢到锁的进程处理当前请求
- 接收,处理来自客户端的连接
- 提供反向代理和过滤功能
配置文件
配置文件位于/etc/nginx/nginx.conf
,nginx -t
检测当前配置文件是否有语法错误,nginx -s reload
不影响nginx服务器并且令当前配置文件生效。
#全局模块
events {
#events模块
}
http {
#http全局模块
server {
#server全局模块
location [svr] {
#location模块
}
}
}
全局模块
该模块配置影响Nginx的全局指令,通常有运行nginx的用户,允许生成worker的进程数,日志存放路径,nginx进程pid存放路径等信息,配置文件引入
events模块
该模块配置影响nginx服务器与用户的网络连接,通常有每个进程的最大连接数
http模块
可以嵌套多个server,配置代理、缓存、日志定义等绝大多数功能和第三方模块配置
server模块
配置虚拟主机的相关参数,一个http中可以有多个server
location模块
配置请求的路由,以及各种页面的处理情况
配置语法
location后面的url使用正则匹配,并遵循一定的优先级
location = [请求内容] {
# 只有当请求内容完全匹配时,才能进入这里
}
location ~ [请求内容] {
# 不忽略大小写匹配请求内容,匹配成功时进入这里
}
location ~* [请求内容] {
# 忽略大小写匹配请求内容,匹配成功时进入这里
}
location ^~ [请求内容] {
# # 匹配任何以 [请求内容] 开头的请求,匹配符合之后,停止向下搜索正则
}
location ~* \.([请求内容1]|[请求内容2])$ {
# 匹配所有以[请求内容1]或[请求内容2]结尾的请求
}
location / {
# 匹配所有以/开始的请求,如果以上规则都未匹配,则匹配该规则,类似与default
}
# 优先级:= > [完整路径] > ^~ > ~* > 部分起始地址 > /
location [请求内容] {
root /home/ahao/nginx/; # 当匹配到这里时,将文件的根目录改变为/home/ahao/nginx/
}
location [请求内容] {
try_files $uri [服务器内容路径]; # 当匹配到这里时,检测[请求内容]是否存在,使用第一个被找到的文件返回,如果没有文件被找到,那么将会重定向到[服务器内容路径]
#$uri代表不带请求参数的当前url
}
location [请求内容] {
rewrite [规则] [定向路径] [重写类型];#需要结合正则表达式,重定向至当前服务器其他目录
#TODO
}
#规则:字符串或正则表达式
#定向路径
#重写类型
# last:表示完成rewrite,浏览器里的url地址不变,last不终止重定向后的url匹配
# break:表示本条规则匹配完成后,终止匹配,不再匹配后面的规则,浏览器里的url变,break终止url匹配
# redirect:返回302临时重定向,浏览器地址会显示跳转后的url地址
# permanent:返回301永久重定向,浏览器地址栏会显示跳转后的url地址
if表达式
# 内置的条件判断
-f !-f用来判断是否存在文件
-d !-d用来判断是否存在目录
-e !-e用来判断是否存在文件或目录
-x !-x用来判断文件是否可执行
内置的全局变量
变量 | 意义 |
---|---|
$args | 表示url请求行中的参数,同$query_string |
$content_length | 表示请求头中的Content-length字段 |
$content_type | 表示请求头中的Content-Type字段 |
$document_root | 表示当前请求在root指令中指定的值 |
$host | 表示请求主机头字段,否则则为服务器名称 |
$http_user_agent | 表示客户端agent的信息 |
$http_cookie | 表示客户端的cookie信息 |
$limit_rate | 该变量可以限制连接速率 |
$request_method | 表示客户端的请求方法 |
$remote_addr | 表示客户端的IP地址 |
$remote_port | 表示客户端的端口 |
$remote_user | 表示已经经过Auth Basic Module验证的用户名 |
$request_filename | 表示当前请求的文件路径,由root或alias指令与url生成 |
$scheme | HTTP方法(HTTP/HTTPS) |
$server_protocol | 表示请求所使用的协议(HTTP/1.0、HTTP/1.1) |
$server_addr | 表示服务器地址,在完成一次系统调用后可以确定这个值 |
$server_name | 表示服务器名称 |
$server_port | 请求到达服务器的端口号 |
$request_uri | 包含请求参数的原始url,不包含主机名(IP地址) |
$uri | 表示不带请求参数和主机名的当前url |
$document_uri | 与uri相同 |
内置的负载均衡策略
轮询
轮询策略即就时按照后台server的顺序,当请求到达时,依次发放请求让server去处理请求使得后台服务器之间的负载相对均衡,但是这种方式在后台服务器的状态基本一致时是最有效的,但是机器的状态是随着服务时间而发生变化的,所以会出现机器负载不均衡的情况,当某一台机器出现问题时,也无法将出现问题的机器边缘化。
# 配置方法
http {
upstream mySevers {
server [DNS/IP]+[PORT];
server [DNS/IP]+[PORT];
...
}
...
server {
...
location / {
proxy_pass http://mySevers;
}
}
}
加权轮询
为后台server的每一台机器根据其状态添加权重,按照权重的优先级来分配到达的请求。
# 配置方法
http {
upstream mySevers {
least_conn;
server [DNS/IP]+[PORT];
server [DNS/IP]+[PORT];
...
}
...
server {
...
location / {
proxy_pass http://myServers;
}
}
}
IP-hash映射
IP-hash映射的方法可以解决session在后台服务器之间不共享的问题,来自同一个IP的请求会一直被分配到同一台后台服务器上。根据客户端IP计算得到一个数值,对应的后端机器处理某一个特定的值。
# 配置方法
http {
upstream mySevers {
ip_hash;
server [DNS/IP]+[PORT];
server [DNS/IP]+[PORT];
...
}
...
server {
...
location / {
proxy_pass http://myServers;
}
}
}
最少连接
根据各个服务器当前连接状况分配请求。least_conn算法首先会遍历后端集群,比较每个后端的连接数,选取值最小的机器,如果多个后端的连接数同为最小的,则对它们采用加权轮询算法。
# 配置方法
http {
upstream mySevers {
server [DNS/IP]+[PORT] weight=2;
server [DNS/IP]+[PORT] weight=1;
...
}
...
server {
...
location / {
proxy_pass http://myServers;
}
}
}