// 命令行终端运行
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
// 安装 nginx
brew install nginx
// 运行 nginx
nginx
默认是在 /usr/local/etc/nginx 下, 有两个配置文件 nginx.conf 和 nginx.conf.default ,这两个文件内容是一样的。
文件最后一行 include servers/*; 引入了当前路径 servers 目录下的所有配置,我们只需要在当前路径下创建 servers 文件夹,把我们的配置写在 这个文件夹下就行。
当我们浏览器想上 google ,但是本地网络不支持的时候,我们可以配一个代理,通过代理来访问 google。
当我们在国内,想买一些国外的产品,然后通过朋友或者一些其他渠道进行购买,这也可以叫做代理。
总之,代理就是你要做一些事情,但是没有直接去做,而是通过中间商完成了这件事情,这就属于代理。
红框中的内容, client 是客户端,proxy 是代理服务器,google 是目标服务器。这就是一个正向代理的过程,客户端通过代理服务器访问目标服务器,此时对于客户端来说,客户端知道自己访问的是 google ,对于 google 来说,google 不知道是哪个客户端访问的,只知道代理服务器的信息。
正向代理对于服务器来说是透明的。
举例:大家平时买海外的东西可能会找一些代购,把找代购购买海外物品的这一流程看作客户端服务器正向代理的流程。我们是客户,代购是中间商是代理,海外卖家相当于服务器,比如说我要买韩国XX店的某一件物品,这时候我会告诉代购,代购会去这家店帮我购买,此时我知道我买的是哪家物品,但是店家不知道真正卖给了谁,店家只知道是代购过来买的。
大家都知道百度,百度每天有上亿的访问量,目前一台服务器一定是承受不了这么大的流量,所以当我们直接访问百度的时候,百度服务器会根据一定的策略做一个转发,根据内部负载均衡算法将流量分发给各个服务器。
这是一个反向代理的过程,反向代理对客户端是透明的,客户端访问百度服务器,百度服务器将流量分发到各个服务器,从而减少主服务器的压力,这时客户端不知道访问的具体是哪台服务器。客户端只会得知反向代理的IP地址,而不知道在代理服务器后面的服务器集群的存在。
负载均衡一般被用来优化资源利用率、最大化吞吐量、降低延迟和容错配置。
nginx 默认负载均衡算法就是轮询,代理服务器会按照配置顺序将请求发往各个服务器,使它们的负载量大致相同。
# 轮询 none (默认)
upstream polling {
server 127.0.0.1:3000;
server 127.0.0.1:4000;
server 127.0.0.1:5000;
}
server {
listen 80;
server_name 127.0.0.1;
location / { #location1
proxy_pass http://polling;
}
}
Web请求会被转发到当前连接数最少的服务器上。
# least_conn 最少连接
upstream least_conn {
least_conn;
server 127.0.0.1:3000;
server 127.0.0.1:4000;
server 127.0.0.1:5000;
}
server {
listen 80;
server_name 127.0.0.1;
location / { #location1
proxy_pass http://least_conn;
}
}
根据真实服务器的不同处理能力来调度访问请求,这样可以保证处理能力强的服务器处理更多的访问流量。
# 权重 weight
upstream weight {
server 127.0.0.1:3000 weight=11;
server 127.0.0.1:4000 weight=1;
server 127.0.0.1:5000 weight=1;
}
server {
listen 80;
server_name 127.0.0.1;
location / { #location1
proxy_pass http://weight;
}
}
每个请求按访问ip的hash结果分配,这样每个 ip 固定访问一个后端服务器。
# 哈希 ip_hash
upstream ip_hash {
ip_hash;
server 127.0.0.1:3000;
server 127.0.0.1:4000;
server 127.0.0.1:5000;
}
server {
listen 80;
server_name 127.0.0.1;
location / { #location1
proxy_pass http://ip_hash;
}
}
基于 node http 模块开了三个端口 3000 4000 5000
// server1.js
const http = require('http')
const port = 3000
http.createServer(function(req,res){
res.end(`${port}`)
}).listen(port)
console.log(`port: ${port}`)
// server2.js
const http = require('http')
const port = 4000
http.createServer(function(req,res){
res.end(`${port}`)
}).listen(port)
console.log(`port: ${port}`)
//server3.js
const http = require('http')
const port = 5000
http.createServer(function(req,res){
res.end(`${port}`)
}).listen(port)
console.log(`port: ${port}`)
使用 pm2 来管理这些端口
pm2 start server1.js
pm2 start server2.js
pm2 start server3.js
启动后可以先访问 127.0.0.1:3000 127.0.0.1:4000 127.0.0.1:5000 看有没有问题。
然后终端进入 /usr/local/etc/nginx/ 下,新建文件夹 servers ,在 servers 下面创建配置文件 test.conf。
# 轮询 none (默认)
upstream none {
server 127.0.0.1:3000;
server 127.0.0.1:4000;
server 127.0.0.1:5000;
}
# 权重 weight
upstream weight {
server 127.0.0.1:3000 weight=11;
server 127.0.0.1:4000 weight=1;
server 127.0.0.1:5000 weight=10\;
}
# 哈希 ip_hash
upstream hash {
ip_hash;
server 127.0.0.1:3000;
server 127.0.0.1:4000;
server 127.0.0.1:5000;
}
# least_conn 最少连接
upstream least_conn {
least_conn;
server 127.0.0.1:3000;
server 127.0.0.1:4000;
server 127.0.0.1:5000;
}
server {
listen 80;
server_name 127.0.0.1;
location / { #location1
# 可以每次打开一个 proxy_pass 尝试
proxy_pass http://none;
# proxy_pass http://weight;
# proxy_pass http://hash;
# proxy_pass http://least_conn;
# proxy_redirect default;
# proxy_set_header X-real-ip $remote_addr;
# proxy_set_header Host $http_host;
}
# error_page 500 502 503 504 /50x.html;
# location = /index.html { #location2
# root html;
# }
}
重启 nginx
nginx -s reload