二、Nginx的https配置解决方案


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_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内部集群节点等。

此处B站讲解链接:https://www.bilibili.com/video/BV1yM4y137iz/?spm_id_from=333.1007.top_right_bar_window_custom_collection.content.click&vd_source=bc93e908334fea5384c4d1d3b8e66bbc

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

域名绑定ip流程图

3.6、域名备案

网址:https://beian.aliyun.com/

注意备案很麻烦,而且备案需要你购买的服务器至少三个月以上,并且要上传身份证

如果不通过多问阿里云客服即可,或者官网上提工单,一直回复人工服务,就会有人工回答问题

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配置就行了,外加一个重定向!!!!


文章作者: 吴俊杰
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 吴俊杰 !
  目录