1、Nginx负载均衡(服务端的负载均衡)
1.1、轮询
轮询是最基本的配置方法,上面的例子就是轮询的方法,它是upstream模块默认的负载均衡策略,每个请求会按时间顺序逐一分配到不同的后端服务器。
注意:
- 在轮询中,如果服务器down掉了,会自动剔除该服务器
- 缺省配置就是轮询策略
- 此策略适合服务器配置相当,无状态且短平快的服务使用
1.2、weight
加权重的方式,在轮询策略的基础上指定轮询的几率。例子如下:
权重方式,在轮询的策略的基础上指定轮询的几率。例子如下:
在该例子中,weight参数用于指定轮询几率,weight的默认值为1;weight的数值与访问比率成正比
注意:
- 权重越高分配到的需要处理的请求越多
- 此策略可以与least_conn合ip_hash结合使用
- 此策略比较适合服务器的硬件配置差别比较大的情况
upstream tomcatservers {
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8081 weight=2;
server 127.0.0.1:8082 weight=3;
}
1.3、upStream
upstream指令存在一些参数:
- max_conns: 可以限制一台服务器的最大访问连接数。默认值是0,代表不限制
upstream tomcatservers {
server 127.0.0.1:8080 max_conns=1;
server 127.0.0.1:8081 max_conns=2;
server 127.0.0.1:8082 max_conns=3;
}
- slow_start: 当设置了这个以后,权重weight会从0慢慢的升级到一个正常的value,可以把一个不健康的服务器变成一个健康的服务器,它是在一段时间以后再去启动。默认值是0,默认情况下是关闭的。它可以让一个服务器慢慢的加入到集群中,这个参数不能使用到hash和random的负载均衡策略中,如果在upstream中只有一台server,则该参数有效。
比如下面的服务器中,8080不会直接参与到这个服务器集群中去,他在60秒内,慢慢的从0升级到10,8080服务器默认是关闭的,所以是0
upstream tomcatservers {
server 127.0.0.1:8080 weight=10 slow_start=60s;
server 127.0.0.1:8081 weight=2;
server 127.0.0.1:8082 weight=2;
}
- down: 用于标识服务器当前的状态,标识当前服务器不可用,比如下面的8080服务器是不可用的
upstream tomcatservers {
server 127.0.0.1:8080 weight=10 down;
server 127.0.0.1:8081 weight=2;
server 127.0.0.1:8082 weight=2;
}
- backup: 备机,标识当前服务器是备用机,只有在其他的服务器都宕机以后,自己才会加入到集群中,被用户访问到。当其他服务器再次启动时,这个服务器又被挂起当作备用机。可以用于灰度部署时候的一种更替效果。
upstream tomcatservers {
server 127.0.0.1:8080 weight=10 backup;
server 127.0.0.1:8081 weight=2;
server 127.0.0.1:8082 weight=2;
}
- fail_timeout和max_fails: 如果配置fail_timeout=10s, max_fails=5次,代表的含义是在10s之内如果出现的错误次数大于等于5次的时候,就会认为这个服务器是一个挂掉的服务,nginx会剔除该服务。max_fails的默认值是1,fail_timeout的默认值是10。
upstream tomcatservers {
server 127.0.0.1:8080 max_fails=2 fail_timeout=10;
server 127.0.0.1:8081 weight=1;
server 127.0.0.1:8082 weight=1;
}
上面的配置代表在10秒内请求8080服务器失败达到2次后,则认为该服务器已经挂了或者宕机了,随后再过10秒,这10秒内不会有新的请求达到刚刚挂掉的节点上。10秒后会再有新请求尝试连接挂掉的服务器,如果还是失败,则重复上一过程,知道恢复。
1.4、ip_hash
指定负载均衡按照基于客户端IP的分配方式,这个方法确保了相同的客户端的请求一直发送到相同的服务器,以保证session会话。这样每个访客都固定访问一个后端服务器,可以解决session不能跨服务器的问题。
注意:
- 在nginx版本1.3.1之前,不能在ip_hash中使用权重(weight)
- ip_hash不能与backup同时使用
- 此策略适合有状态服务,比如session
- 当有服务器要剔除,必须手动down掉
注意上图,ip_hash机制取得是IP地址的前三位去做运算,找到对应的服务器,具体逻辑看源码,不用做过多了解,这样就能判断是不是在同一个网段内。
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;
server backend4.example.com;
}
如果是在同一局域网内,算出hash是一致的,这样他们就会出现相同的hash。
1.5、url_hash
- 第三方的负载均衡策略的实现需要安装第三方插件
- 按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,要配合缓存命中来使用。同一个资源多次请求,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时间的浪费,而是用url_hash,可以使得同一个url(也就是同一个资源请求)会到达同一台服务器,一旦缓存住了资源,再次收到请求,就可以从缓存中读取。
upstream tomcatservers {
hash $request_uri;
server localhost:8080;
server localhost:8081;
server localhost:8082;
}
1.6、least_conn
把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使他们的负载大致相同:但是有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果。此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况。
配置如下:
upstream tomcatservers {
least_conn;
server 127.0.0.1:8080;
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}
1.7、fair
按照服务器端的相应时间来分配请求,响应时间短的优先分配。
比如有三个服务器分别是1M带宽,2M带宽,5M带宽,那么他们的响应速度肯定是不一样的。
注意:fair不是服务器内部机制,不是根据内部情况自动适应,而是我给8080加了fair,那么就更倾向于把更多的请求发给它。
upstream tomcatservers {
server 127.0.0.1:8080 fair;
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}
1.8、总结
以上说到了6种负载均衡策略的实现方式,其中除了轮询和权重外,都是nginx根据不同的算法实现的,在实际运用种,需要根据不同的场景选择性运用,大都是多种策略结合使用以达到实际需求。
1.9、一致性hash
这个东西单独领出来讲,因为它比较有意思,也比较独特,为什么会出现一致性hash呢?先来看看ip_hash存在的一些问题。
ip_hash存在的问题如下:
- 上面的hash负载均衡存在一个问题,就是如果一个服务器挂掉了,hash的计算就需要全部重新计算,如果是在并发非常大的情况下,用这种算法来实现的话,可能会造成大量的请求在某一刻失败。
- 节点增加也会发生上述问题
- hash算法还会造成数据的服务的倾斜
一致性hash的出现解决了上述的问题,一致性hash算法在很多场景下都有应用,尤其是在分布式缓存系统中,经常用其来进行缓存的访问的负载均衡,比如redis集群部署,nginx插件,es内部集群节点等。
2、https的配置基础
2.1、http与https的区别
http是一种用于分布式、协作式和超媒体信息系统的应用层协议。简单来说就是一种发布和接收HTML页面的方法,被用于Web浏览器和网站服务器之间传递信息。
但是,http协议是以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息。因此,http不适合传输一些敏感信息,比如:信用卡、密码等支付信息。
https是一种通过计算机网络进行安全通信的传输协议,https经由http进行通信,但利用SSL/TLS来加密数据包,https开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。
2.2、https的应用场景
基于前后端分离开发方式,比如微信小程序,APP开发,比如ios开发等这些移动端应用开发。例如ios苹果软件开发,如果说你的软件要上架到苹果应用市场,那么你的服务器接口必须是https。再例如微信小程序在真实的项目发布中如果不是https接口也是通不过的。
2.3、https的配置准备工作
- 要购买一个ssl安全证书或者免费领取一个ssl安全证书。
- 必须要有一个域名和一个服务器,域名要和服务器要进行DNS解析,这个域名访问的是哪个服务器
- 域名和ssl安全证书进行绑定授权
- 授权成功以后,把证书安装到nginx中
3、购买域名、服务器并且绑定服务器公网ip和域名
3.1、阿里云买个域名:wujunjie.fun
3.2、阿里云买个云服务器:远程登录名:root 账号密码:!Wujunjie916(注意一定要点分配公网ip)
3.3、下载终端模拟器工具FinalShell,网址:http://www.hostbuf.com/t/988.html
3.4、利用FinalShell连接到服务器
3.5、域名绑定服务器ip
3.6、域名备案
注意备案很麻烦,而且备案需要你购买的服务器至少三个月以上,并且要上传身份证
如果不通过多问阿里云客服即可,或者官网上提工单,一直回复人工服务,就会有人工回答问题
3.7、开放服务端口
正常以上就可以通过域名访问服务器了,但是一般在访问之前还要做一件事,就是开放端口。如果是单机部署多应用的话,应该开放的端口有:80、443、22;如果是多机部署多应用的话,那么必须开放对应服务器安装的服务端口,比如服务器安装了redis、mysql、kafka、zk,那就要开放他们需要的端口:6379、3306、2181、80、443、22(后面这三个是必须开的)…….
那什么是单机部署多应用?只有一个服务器场景如下
那么在哪里开放呢???
注意:开放端口的原则就是:如果你的服务(tomcat、nginx、mysql、kafka等)要对外访问的话,你就必须在安全组中把这些服务器的端口进行配置开放即可。
同时需要注意的是,单机多应用在实际场景中是不允许开放tomcat、mysql等的端口的,不安全,这样别人用IP地址加端口号就能访问你的服务了,因为单机多应用没必要对外开放端口,外部的访问只需要通过nginx转发就行了。
那什么是多机部署多应用?此时有多个服务器:
4、安全证书的获取
4.1、安全证书的申请和购买
在阿里云里主页,在搜索框里搜索SSL即可,点击弹窗来的选项:数字这个数管理服务。
选择20,这个是免费的,点击购买、点击支付即可。
回到证书管理页,点击创建证书,把该填的填完,有默认值的不用动,点击提交审核即可。
审核需要时间,审核通过之后,点击验证即可
审核通过之后如下,点击下载
点击nginx那一行的下载,下载nginx的证书,拿到压缩包里的两个文件
5、nginx的安装
5.1、回到FinalShell,安装nginx
nginx的官方网址为:https://nginx.org/en/download.html
- 在服务器种创建目录: mkdir jjwu/nginx
- 进入nginx文件夹:cd jjwu/nginx
- 安装编译工具及库文件:yum -y install make zlib zlib-devel gcc-c++ libtool openssl openss1-devel
- 下载安装nginx: wget http://nginx.org/download/nginx-1.20.1.tar.gz
- 解压nginx:tar -zxvf nginx-1.20.1.tar.gz
- 创建一个临时目录:mkdir -p /var/temp/nginx
- 进入安装包目录:cd nginx-1.20.1
- 安装编译文件:在当前目录下
// 1、先装一下这个
yum install pcre pcre-devel
// 2、再装这个
yum -y install openssl openssl-devel
// 2、然后复制下面这个直接回车
./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-http_stub_status_module
// 3、当出现如下列表说明成功了
nginx path prefix: "/usr/local/nginx"
nginx binary file: "/usr/local/nginx/sbin/nginx"
nginx modules path: "/usr/local/nginx/modules"
nginx configuration prefix: "/usr/local/nginx/conf"
nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
nginx pid file: "/var/run/nginx.pid"
nginx error log file: "/var/log/nginx/error.log"
nginx http access log file: "/var/log/nginx/access.log"
nginx http client request body temporary files: "/var/temp/nginx/client"
nginx http proxy temporary files: "/var/temp/nginx/proxy"
nginx http fastcgi temporary files: "/var/temp/nginx/fastgi"
nginx http uwsgi temporary files: "/var/temp/nginx/uwsgi"
nginx http scgi temporary files: "/var/temp/nginx/scgi"
相关解释如下
- make编译:在当前目录下执行 make
- 安装:make install
- 退到根目录
- 进入目录usr/local/nginx启动nginx
- 我这里装错了,装进了usr/ocal/nginx一样用
// 启动
./nginx
// 重新启动
./nginx -s reload
// 停止
./nginx -s stop
- 打开网址输入公网ip:http://120.55.182.61/ 即可看到nginx的主页面
- 进入到usr/ocal/nginx/conf文件夹将nginx.conf文件内容修改为
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
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;
include yykk.conf; #意思就是包含yykk.conf的内容
}
创建一个新的文件和nginx.conf平级:yykk.conf
// 创建文件
vi yykk.conf
// 文件内容修改为
server {
listen 80; # 监听端口
server_name wujunjie.fun; #或者可以域名或者ip
location / {
root html;
}
}
// 确认是否修改完成
nginx -t
// 出现如下说明完成了
nginx: the configuration file /usr/ocal/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/ocal/nginx/conf/nginx.conf test is successful
安装环境变量,不然每次启动都得进入到那个sbin目录下,然后启动nginx,很烦的
vim /etc/profile
// 滚动到在文件的低端,输入i,这个时候就可以插入文本了,在unset -f pathmunge后面换行写如下
unset -f pathmunge
export NGINX_HOME=/usr/local/nginx
export PATH=$NGINX_HOME/sbin:$PATH
// 重启一下配置文件
source /etc/profile
// 这样就可以在任意文件夹输入nginx命令了
6、上传证书
在nginx的conf目录下新建一个cert目录,并将两个ssl文件上传,直接拖拽到FinalShell里面就行了
将yykk.conf内容修改为
server {
listen 80; # 监听端口
server_name localhost; #或者可以域名或者ip
location / {
root html;
}
}
server {
#HTTPS的默认访问端口443。
#如果未在此处配置HTTPS的默认访问端口,可能会造成Nginx无法启动。
listen 443 ssl;
#填写证书绑定的域名
server_name wujunjie.fun;
#填写证书文件绝对路径
ssl_certificate cert/jnawujunjie.fun.pem;
#填写证书私钥文件绝对路径
ssl_certificate_key cert/jnawujunjie.fun.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
#自定义设置使用的TLS协议的类型以及加密套件(以下为配置示例,请您自行评估是否需要配置)
#TLS协议版本越高,HTTPS通信的安全性越高,但是相较于低版本TLS协议,高版本TLS协议对浏览器的兼容性较差。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
#表示优先使用服务端加密套件。默认开启
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
这个时候我们就可以用https访问了:https://www.wujunjie.fun
仔细看一下可以知道有两个server,上面是支持访问http的,下面是支持访问https的
现在我不想别人访问http的了,怎么办呢,重定向这样写,把上面的server改成
server {
listen 80;
server_name wujunjie.fun;
#将所有HTTP请求通过rewrite指令重定向到HTTPS。
rewrite ^(.*)$ https://$host$1;
location / {
index index.html index.htm;
}
}
7、总结一下
一般我们nginx就配置负载均衡、反向代理、https配置就行了,外加一个重定向!!!!