基于Nginx的负载均衡实验
Nginx介绍及安装:
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。
-
Mac下安装Nginx:
-
安装Homebrew
- 如何检测Homebrew安装?
- 终端输入
brew
输出各种brew命令说明安装成功 - 终端输入
brew list
查看已安装工具列表
- 终端输入
- 如何检测Homebrew安装?
-
检测软件Nginx是否可以brew:
brew search nginx
,返回==>Formulae nginx
-
安装Nignx,终端输入
brew install nginx
-
报错
-
lh@lihaoMac ~ % brew install nginx ==> Downloading https://mirrors.ustc.edu.cn/homebrew-bottles/bottles/bottles-portable-ruby/portable-ruby-2.6.8.yosemite.bottle.tar.gz ############################################################100.0% ==> Pouring portable-ruby-2.6.8.yosemite.bottle.tar.gz Error: The following directories are not writable by your user: #接下来的目录不可以写(权限不够?) /usr/local/lib/pkgconfig /usr/local/share/man/man8 You should change the ownership(所有权) of these directories to your user. sudo chown -R $(whoami) /usr/local/lib/pkgconfig /usr/local/share/man/man8 And make sure that your user has write permission. #(确保有权限) chmod u+w /usr/local/lib/pkgconfig /usr/local/share/man/man8
-
sudo
是给与暂时的root权限chown
是change owner改变文件的归属者-r
递归,将指定目录下的所有文件及子目录一并处理
-
sudo brew install nginx
会报错,因为直接给home-brew以root权限是极其危险的(系统判断) -
终端输入
sudo chown -R lh /usr/local/lib/pkgconfig /usr/local/share/man/man8
- 代表暂时给用户lh权限操作
/usr/local/lib/pkgconfig及 /usr/local/share/man/man8
目录以及该目录的子目录
- 代表暂时给用户lh权限操作
-
重新输入
brew install nginx
开始安装Nginx
-
-
-
-
安装时报错,输入
brew update
更新* 重新输入```brew install nginx```安装 * 输入```nginx```检测是否安装成功
-
-
验证安装:
- 终端输入
cd /usr/local/var/www/ //进入到www目录下 touch index.html //创建一个新的index.html文件 vim index.html //编辑该文件
修改index.html文件即可修改首页内容;
- 浏览器访问localhost:80验证安装
-
Nignx基本使用:
终端输入brew info nignx
查看安装nignx的目录信息;
目录信息:nginx will load all files in /usr/local/etc/nginx/servers/
打开目录,终端输入open /usr/local/etc/nginx/
,弹出目录
其中nignx.conf为nignx的配置文件:
# main全局块
# 配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
# 以nobody用户的身份运行
#user nobody;
# work进程的个数
# worker_processes 值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约。
worker_processes 1;
# 各种日志文件的存储位置?!
# .log是日志文件
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
# pid 进程控制符 , 指定nginx的pid文件
# events块
# 配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
events {
# 每个worker能够并发响应的最大请求数
worker_connections 1024;
}
# 可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
http {
# http全局块
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
# upstream负载均衡块
# upstream{}
# 配置虚拟主机的相关参数,一个http中可以有多个server,一个server就是一个虚拟主机
server {
# 监听8080端口,没设IP默认为本机IP
listen 8080;
# ngnix url,可以通过localhost访问页面
# 虚拟主机的域名,可以配置多个,用空格分隔,可以使用通配符和正则表达式
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
# 配置请求的路由,以及允许根据用户请求的URI来匹配指定的各location以进行访问配置;
# 匹配到时,将被location块中的配置所处理
location / {
# 设置web资源路径,用于指定请求的根文档目录,从根开始匹配。
root html;
# 定义默认页面,可以跟多个值。自左向右匹配。
index index.html index.htm;
}
#error_page 404 /404.html;
# 将服务器错误页重定向到静态页
# redirect server error pages to the static page /50x.html
# 当对于某个请求发回错误时,如果匹配上了error_page指令中设定的code,则从定向至新的URI中,错误重定向.
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
# 另一个虚拟主机使用基于IP、名称和端口的混合配置
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
include servers/*;
}
实现常用负载均衡策略:
服务端实现:
-
启用nginx实现反向代理的upstream负载均衡块,加入四个不同端口的web服务器;
-
在http块中加入:
-
upstream myservers { server 127.0.0.1:2321 weight = 10; server 127.0.0.1:2322 weight = 10; server 127.0.0.1:2323 weight = 10; server 127.0.0.1:2324 weight = 10; }
-
-
-
用js实现web服务;
-
终端创建四个js文件:
-
cd /Users/lh/分布式系统负载均衡实验/web vim webserver1.js vim webserver2.js vim webserver3.js vim webserver4.js
-
-
js文件内容:
-
webserver1.js
-
var http = require('http'); var server = http.createServer(function(req, res){ res.write("Hello world from Server One."); res.end(); }); server.listen(2321) console.log("running at http://127.0.0.1:2321")
-
-
webserver2.js
-
var http = require('http'); var server = http.createServer(function(req, res){ res.write("Hello world from Server Two."); res.end(); }); server.listen(2322) console.log("running at http://127.0.0.1:2322")
-
-
webserver3.js
-
var http = require('http'); var server = http.createServer(function(req, res){ res.write("Hello world from Server Three."); res.end(); }); server.listen(2323) console.log("running at http://127.0.0.1:2323")
-
-
webserver4.js
-
var http = require('http'); var server = http.createServer(function(req, res){ res.write("Hello world from Server Four."); res.end(); }); server.listen(2324) console.log("running at http://127.0.0.1:2324")
-
-
-
启动web服务器:
- 终端输入
node webserver1.js
运行第一个web服务,同理,运行其他三个web服务;
- 终端输入
-
访问验证:
- 浏览器地址栏输入http://127.0.0.1:2322访问webserver1提供的web服务;
- 浏览器地址栏输入http://127.0.0.1:2322访问webserver1提供的web服务;
-
几种常见的负载均衡策略:
只需要修改nginx实现反向代理的upstream负载均衡块即可以实现不同策略的负载均衡:
-
随机
-
实验现象:
- 终端输入
curl localhost:8080
,随机返回四个Web服务器中的一个的响应;
- 终端输入
-
upstream代码:
-
upstream myservers { random; server 127.0.0.1:2321; server 127.0.0.1:2322; server 127.0.0.1:2323; server 127.0.0.1:2324; }
-
-
-
轮询
-
实验现象:
- 终端输入
curl localhost:8080
,依次按顺序返回Web响应;
- 终端输入
-
upstream代码:
-
upstream myservers { server 127.0.0.1:2321; server 127.0.0.1:2322; server 127.0.0.1:2323; server 127.0.0.1:2324; }
-
-
-
固定权重值
-
实验现象:
- 终端输入
curl localhost:8080
,按照权重返回响应,权重大的响应次数多;
- 终端输入
-
upstream代码:
-
upstream myservers { server 127.0.0.1:2321 weight=1; server 127.0.0.1:2322 weight=2; server 127.0.0.1:2323 weight=3; server 127.0.0.1:2324 weight=4; }
-
-
-
IP哈希(可与固定权重值组合使用)
-
实验结果:
- 按照ip地址返回Web响应,本机访问多次都是同一个Web响应;
- 按照ip地址返回Web响应,本机访问多次都是同一个Web响应;
-
upstream代码:
-
upstream myservers { ip_hash; server 127.0.0.1:2321; server 127.0.0.1:2322; server 127.0.0.1:2323; server 127.0.0.1:2324; }
-
-
-
最小响应时间
-
实验结果:
- 按照最小响应时间返回Web响应;
-
upstream代码:
-
upstream myservers { least_conn; server 127.0.0.1:2321; server 127.0.0.1:2322; server 127.0.0.1:2323; server 127.0.0.1:2324; }
-
-