Nginx 简介
Nginx(发音同engine x)是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD协议下发行,可以在UNIX、GNU/Linux、BSD、Mac OS X、Solaris,以及 Microsoft Windows等操作系统中运行。
Nginx由俄罗斯的程序设计师Igor Sysoev所开发,最初供俄国大型的入口网站及搜寻引擎Rambler(俄文:PaM6nep)使用。其特点是占有内存少,并发能力强(用于解决C10K问题),事实上Nginx的并发能力确实在同类型的网页服务器中表现较好。
Nginx做为一个强大的Web服务器软件,具有高性能、高并发性和低内存占用的特点。此外,其也能够提供强大的反向代理功能。俄罗斯大约有超过20%的虚拟主机采用Nginx作为反向代理服务器,在国内也有腾讯、新浪、网易等多家网站在使用Nginx作为反向代理服务器。据Netcraft统计,世界上最繁忙的网站中有11.48%使用Nginx作为其服务器或者代理服务器。
- 基于反向代理的功能,Nginx作为负载均衡主要有以下几点理由:
- 高并发连接
- 内存消耗少
- 配置文件非常简单
- 成本低廉
- 支持Rewrite重写规则
- 内置的健康检查功能
- 节省带宽
- 稳定性高
正向代理和反向代理
-
正向代理
正向代理类似一个跳板机,代理访问外部资源。即假设客户端无法访问某个网站,此时可以将访问请求发送到正向代理服务器,然后由正向代理服务器将该请求转发给某个网站,然后将响应内容返回给客户端。
-
反向代理
实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。
即正向代理服务器是将请求转发向外,而反向代理则是将请求转发向内,此时反向代理中具体的web服务器是不能使用外网IP进行访问的。
- 反向代理的作用
反向代理实现负载均衡的例子
- 保证内网的安全,可以使用反向代理提供WAF功能,组织web攻击。大型网站,通常将反向代理作为公网访问地址,Web服务器则是内网的。
- 负载均衡,通过反向代理服务器来优化网站的负载。
负载均衡原理
负载均衡,单从字面上的意思来理解就可以解释N台服务器平均分担负载,不会因为某台服务器负载高宕机和某台服务器闲置的情况。那么负载均衡的前提就是要2台以上服务器才能实现。
Nginx 负载均衡有4种方案配置
-
轮询
轮询即Round Robin,根据Nginx配置文件中的顺序,依次把客户端的Web请求分发到不同的后端服务器上。 -
最少连接 least_conn;
Web请求会被转发到连接数最少的服务器上。 -
IP地址哈希 ip_hash;
前述的两种负载均衡方案中,同一客户端连续的Web请求可能会被分发到不同的后端服务器进行处理,因此如果涉及到会话Session,那么会话会比较复杂。常见的是基于数据库的会话持久化。要克服上面的难题,可以使用基于IP地址哈希的负载均衡方案。这样的话,同一客户端连续的Web请求都会被分发到同一服务器进行处理。 -
基于权重weight
基于权重的负载均衡即Weighted Load Balancing,这种方式下,我们可以配置Nginx把请求更多地分发到高配置的后端服务器上,把相对较少的请求分发到低配服务器。
负载均衡配置
1. 配置基于Round Robin轮询的负载均衡
- 需要注意以下几点:
- 缺省配置就是轮询策略
- nginx负载均衡支持http和https协议,只需要修改proxy_pass后协议即可
- nginx支持FastCGl, uwsgi, sCGl,memcached的负载均衡,只需将proxy_pass改为fastcgi_pass,uwsgi_pass,scgi_pass,memcached_pass即可。
- 此策略适合服务器配置相当,无状态且短平快的服务使用。
- 例子
user www-data;
worker_processes auto; #表示服务器有几个内核就起几个work
pid /run/nginx.pid; #进程编号
events {
use epoll; #指定多路复用的形式
worker_connections 65535;
}
http {
upstream test.lazyfennec.cn {
server 127.0.0.1:8081; # 第一台服务器
server 127.0.0.1:8082; # 第二台服务器
server 127.0.0.1:8083; # 第三台服务器
}
server {
listen 80; # 监听80端口
server_name test.lazyfennec.cn; # 自己的域名或者IP
location / {
proxy_pass http://test.lazyfennec.cn;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
2. 配置基于ip_hash的负载均衡
- 需要注意以下几点:
- ip哈希负载均衡使用ip_hash指令定义;
- nginx使用请求客户端的ip地址进行哈希计算,确保使用同一个服务器响应请求;
- 此策略适合有状态的服务,比如session;
- 例子
user www-data;
worker_processes auto; #表示服务器有几个内核就起几个work
pid /run/nginx.pid; #进程编号
events {
use epoll; #指定多路复用的形式
worker_connections 65535;
}
http {
upstream test.lazyfennec.cn {
ip_hash; # 表示使用ip_hash的负载均衡
server 127.0.0.1:8081; # 第一台服务器
server 127.0.0.1:8082; # 第二台服务器
server 127.0.0.1:8083; # 第三台服务器
}
server {
listen 80; # 监听80端口
server_name test.lazyfennec.cn; # 自己的域名或者IP
location / {
proxy_pass http://test.lazyfennec.cn;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
3. 配置基于least_conn的负载均衡
- 需要注意以下几点:
- 最少链接负载均衡通过least_conn指令定义;
- 此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况;
- 例子
user www-data;
worker_processes auto; #表示服务器有几个内核就起几个work
pid /run/nginx.pid; #进程编号
events {
use epoll; #指定多路复用的形式
worker_connections 65535;
}
http {
upstream test.lazyfennec.cn {
least_conn; # 表示使用least_conn的负载均衡
server 127.0.0.1:8081; # 第一台服务器
server 127.0.0.1:8082; # 第二台服务器
server 127.0.0.1:8083; # 第三台服务器
}
server {
listen 80; # 监听80端口
server_name test.lazyfennec.cn; # 自己的域名或者IP
location / {
proxy_pass http://test.lazyfennec.cn;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
4. 配置基于权重的负载均衡
- 需要注意以下几点:
- 权重负载均衡需要使用weight指令定义;
- 权重越高分配到需要处理的请求越多;
- 此策略可以与最少链接负载和ip哈希策略结合使用;
- 此策略比较适合服务器的硬件配置差别比较大的情况;
- 例子
user www-data;
worker_processes auto; #表示服务器有几个内核就起几个work
pid /run/nginx.pid; #进程编号
events {
use epoll; #指定多路复用的形式
worker_connections 65535;
}
http {
upstream test.lazyfennec.cn {
least_conn; # 表示使用least_conn的负载均衡
server 127.0.0.1:8081 weight=3; # 第一台服务器,权重为3
server 127.0.0.1:8082 weight=2; # 第二台服务器,权重为2
server 127.0.0.1:8083 weight=1; # 第三台服务器,权重为1
}
server {
listen 80; # 监听80端口
server_name test.lazyfennec.cn; # 自己的域名或者IP
location / {
proxy_pass http://test.lazyfennec.cn;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
模拟一下使用轮询的负载均衡方式
1. 首先这里写三个node的服务端脚本
const http = require('http')
const hostname = '127.0.0.1'
const port = 8881
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('Hello World from 8881\n')
})
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`)
})
这里只写一个就好了,剩下的两个分别把其中的8881 改成 8882 和 8883 即可
具体node的语法,可以查看网站,不用纠结这个(http://nodejs.cn/learn)
2. 修改电脑的host文件
添加下面一行
127.0.0.1 test.lazyfennec.cn
3. 修改nginx的config.conf文件
在http下添加以下内容即可
####################### 轮询方式Demo #################################
upstream test.lazyfennec.cn {
server 127.0.0.1:8881; # 第一台服务器
server 127.0.0.1:8882; # 第二台服务器
server 127.0.0.1:8883; # 第三台服务器
}
server {
listen 80;
server_name test.lazyfennec.cn;
location / {
proxy_pass http://test.lazyfennec.cn;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
4. 启动三个js
启动三个js5. 启动nginx
6. 尝试多次访问
尝试多次访问可以看见虽然并不是按照顺序8881->8882->8883 访问的,但是的确是按照轮询的方式访问着不同的服务。
如果觉得有收获就点个赞吧,更多知识,请点击关注查看我的主页信息哦~
网友评论