前言
最近因为一些情况,需要帮忙部署一个nginx,并且让web集群,负载均衡,所以记录一下Nginx的快速使用

以前的部署如果是C#,就是直接部署到IIS上
在多站点的情况下,必然会出现他们之间的端口被占用,或需要单独一个项目作网关转发,这样感觉上比较费劲
而这时候就用Nginx,它已经非常傻瓜化,很轻量,配置起来也非常简单,有win和linux\docker的版本.也很成熟了
好多年来不少公司都是用它来做网关

一、安装

Nginx 下载
Win直接上取下载就行

Linux和Docker就比较简单
使用sudo apt-get nginxdocker pull nginx就行

二、运行

Win

image.png

解压官网下载的压缩包就能即用,双击nginx.exe就会运行
因为双击打开也只是闪一下,第一次使用会以为运行失败,是否运行可以打开任务管理器查看到两个nginx的进程

image.png

而我比较喜欢使用命令,因为执行是否成功会换行,感觉直观些
start ./nginx

有时候在使用重载命令的时候,可能会出现没效果,这就很有可能开了多个nginx,那样就会看到两个以上的nginx.exe进程,这就需要关掉多余的才能正常重载。

Linux \ Docker

这两个比较简单,基本不会有太多的坑,就不细说
分别是进入nginx的目录直接执行nginx
而docker 直接run就得了,或者可以看我另一篇文章 部署一个自己的halo博客

三、配置

配置文件在 conf\nginx.conf

对于改了配置,nginx需要更新加载配置文件才能加载到变更的内容
nginx -s reload

1.站点配置

打开后会发现一堆代码,但大部分都是注释,删掉后内容就比较少了,我们从少来看
image.png

稍微简单说明一下,对于我们添加站点,一般只需要考虑 http 里面的 server即可
http是指使用http,而https则是https,我这边就先说http。
然后就是server内部
其中listen的数字很熟悉了,是端口。需要注意,这个端口不能够被其他应用占用才能正常工作
server_name 则填外面访问我们服务器的地址或域名
location则是映射的路径,如果用过IIS就清楚网站必须有个自己的目录,比如你的html放在 D:\web中,则就填写改地址,在访问的时候,会按照这个目录作为根目录访问

比如,我现在有个html文件需要挂在到Nginx上,让其能在浏览器上访问,则server可以这样配置
image.png

    server {
        listen 8088;
        server_name localhost;

        location / {
            root D:\Web;
        }
    }

运行起来后,就能通过访问
http://localhost:8088/index2.htmlhttp://localhost:8088/index.html访问到两个html

一般我们都是说用nginx来反代,大致就是nginx会将请求,转发到我们内网的web上,比我我这里有个内网地址为172.17.0.3:8090的博客,就可以这样配

    server {
        listen 8088;
        server_name localhost;

        location / {
            proxy_pass http://172.17.0.3:8090;
        }
    }

proxy_pass 既是指向的反代目标地址,重启后,访问localhost:8088效果就跟直接访问172.17.0.3:8090一样
(这个说法是对内网来说的,因为外网是不能访问 到172.17.0.3)

2.负载均衡

nginx的负载均衡也非常好配置,nginx带了好几种负载均衡的模式

配置

配置方面,只是在server同层添加上 upstream,调整下反代的地址即可
upstreamName是反代块的名称,这个可以自定义
server *** ;则是负载的服务器,比如下面的例子,我设置了三台服务器(bushi其实是web,反正效果一样)
proxy_pass 调整到我要的反代的那个块
在刷新的时候,会能发现,页面出来的内容会按顺序出现,从5051~5053的web一直循环

    upstream upstreamName {
        server localhost:5051 max_fails=2 fail_timeout=300s;
        server localhost:5052 max_fails=2 fail_timeout=300s;
        server localhost:5053 max_fails=2 fail_timeout=300s;
    }

    server {
        listen 80;
        server_name localhost;

        location / {
            proxy_pass http://upstreamName;
        }
    }
宕机说明

nginx的负载宕机是通过请求刺探的方式判断的
对于负载的机子宕机连不上的情况下,nginx会将请求转发到下一台负载的机子上
这个时间默认是10s1次
意思是10s内,负载机子有一次连不上,则在下个10s周期内,认为该机子宕机,不再负载它,在10s后,到达了下一个周期,则在尝试转发一个请求,若依然无法链接,则继续标识宕机,等待下一周期......

Nginx的负载策略
a. 轮询

没有配置其他内容,只配置了负载机子,则是默认的轮询方式负载

    upstream upstreamName {
        server localhost:5051;
        server localhost:5052;
        server localhost:5053;
    }
b.权重

权重是以手动的方式去均衡请求量,一般情况下都是使用这种方式,因为认为设置和控制,则需要严格了解服务器的性能冗余情况,对服务器的健康情况有一点的约束能力

    upstream upstreamName {
        server localhost:5051 weight=2;
        server localhost:5052 weight=2;
    }
c.Ip哈希

与名字一样,他对请求方的ip进行哈希,然后求出应该映射到哪台负载机子上
因此他能解决一些ip造成的session问题
当然缺陷也明显,想把他临时排除到负载外,只能手动down,不能只让负载机子直接宕机的方式转移流量

    upstream upstreamName {
 	ip_hash;	
        server localhost:5051;
        server localhost:5052;
    }
d.连接量

如题,若负载机子1的请求都是耗时的长链接,则负载机子2就会分配到更多的流量,直至连接量多台负载自己都平衡

    upstream upstreamName {
 	least_conn;	
        server localhost:5051;
        server localhost:5052;
    }
其他

worker_processes 是指nginx的worker个数,他就像本体是一条线程,而worker是另一条真正工作的线程,所以如果访问量太大,则就可以改大些,更多的给nginx压榨cpu的性能

worker_connections是指单个worker处理请求的量,对于并发非常大的情况下才需要调整这个值,当然需要按照服务器的性能情况调整,这里不深入讨论

gzip on;这是打开请求压缩,因为对于网络IO,一般情况下Cpu的性能会有冗余,额外使用Cpu压缩请求内容,分担网络IO的量,很多时候都会快很多.就如同你100m的文件压缩到5m再上传是一个效果

listen 443 ssl http2;如果你使用了ssl,那非常推荐加上http2,这是起启用https2,大部分情况下,对于css、js、图片这类资源会因请求的方式与原先的http不同,速度会快不少。原理这里不细说,有兴趣可以额外查一查

四、关于Reload与平滑更新

对于流量较大的情况下,需要调整nginx的配置又要重载,这样会丢失这期间的请求.....吗? 然而并不会 !

image.png

官方已经说了,对于reload命令,nginx会开启新的worker,并且将流量都指向新的worker,在旧的worker链接全部关闭前,旧的worker是不会关闭的。
所以不需要担心请求丢失

我本地也测试了让Api挂起10s的情况下reload,请求不会丢失,而且也不是重发请求。

那这就好玩了,平滑更新我们能通过调整配置文件的负载,就能平滑更新站点。
当然,这也有一个问题,如果有一个请求非常长时间保持链接,那么oldworker就不会被关闭
这官方也考虑到了,给我们提供了worker_shutdown_timeout配置,若worker超过设置的时间,则会被强制关闭

Q.E.D.


随意游世