工程实践:Nginx了解与入门
Nginx是一个Http服务器,常常被用在高并发,反向代理和负载均衡的场景下。这块内容一直没时间研究,刚好周末刷一下,恶补一下知识。
我用Docker启动了Nginx容器,以下内容均在容器内实现。
在启动了容器后,首先使用nginx -v查看版本。并用service nginx status来检查运行状态:
1 | |
如果已经正确运行,这时候访问localhost,就能看到Welcome to nginx的页面。这意味着人们已经可以通过网址来访问我们的Web服务器了。
Nginx配置文件
Nginx的配置文件在Linux系统下位于/etc/nginx,名为nginx.conf。我们进去看一下,这是默认的配置:
1 | |
看着云里雾里,为了学习配置文件,我们备份一下,再写个新的配置。
1 | |
通常修改配置文件后,需要使用nginx -t来进行检查,查看是否能正确执行。不过现在是空的配置文件,会报错。
报错信息提示:no "events" section in configuration。events字段代表nginx如何处理连接。
我们可以修改一下内容:
1 | |
这时候nginx -t不报错了。
检查完文件后,就需要重新加载,指令是nginx -s reload。启动完之后,发现之前的localhost无法访问了,意料之中。
好吧,并不是意料之中。我在Windows上依然访问到了
localhost。很神奇,哪怕我把nginx容器关闭,依然能访问。这说明Windows上有其他进程调用了nginx,最后发现是Docker Desktop。应该是WSL里有配置nginx。
解决了这个小插曲,后面我就不用Docker启动了。我在官网下了nginx的压缩包,解压后在路径下执行命令行:start nginx,即可启动服务。
Web服务器
同样备份清空,现在无法访问了。这就是http字段需要配置的内容:我们需要在这个字段内配置server,也就是http服务。例如如果服务器需要监听80端口,就这么写:
1 | |
完成这一步,reload一下发现又可以访问localhost了,因为这次我们准确提供了IP和端口,用户可以直接访问了。Perfecto!
这里其实还有一点问题。配置文件里是需要配置资源的,正常来说未配置资源时,会报错403 Forbidden。这就是
nginx未找到资源。而它在未设置字段时默认读取html路径下的index.html。因此,当我修改了它的名字时,页面成功报错。
在server字段,我们不一定需要设置资源地址,还可以返回状态码和对应字段。例如:
1 | |
这时候访问localhost,就会返回这句话。也可以通过curl localhost从命令行访问到这句话。
配置文件中还可以设置资源根目录,我们进行如下修改,此时nginx就会从指定路径访问默认的index.html,而如果路径下没有这个文件,则会报错:
1 | |
如果要指定文件,则需要给index字段进行赋值。这里我新建了一个自己页面,路径为C:\nginx-1.26.0\html,页面名为test.html。那么,配置文件这边需要改为:
1 | |
这时访问localhost,就可以正确显示了。

有的时候,需要在页面文件内引入各种其他文件。在配置文件的相同路径下,有一个mime.types的文件,这是对于各种文件类型的解析。我们需要对它进行引入,才能让web服务器正确解析文件。因此,我们需要在配置文件中加上include字段:
1 | |
这里的配置是全局配置,所以被放在了单个的server块外部。
除了这个配置,nginx自身的配置在conf.d中的default.conf中定义,如果需要修改就要在那里进行改动,例如一开始默认的index.html就在那里设置。
同样的,我们也可以把上面写的这些配置也通过一个文件进行导入。我们在conf.d路径下新建default.conf,并把内容复制其中:
1 | |
然后我们回到nginx.conf文件,导入这个配置:
1 | |
reload一下,就实现了将配置文件分开执行的效果,有点像编程语言的导入库。这让config文件更加简洁。
现在,我想在default.conf中设定在访问localhost的时候,能够直接访问根目录。那么我需要在default.conf如下设置:
1 | |
用这种方式可以更方便的定义路径。
现在,我想在访问localhost/app的时候能够访问到这个路径下的index文件,因此我们需要在location字段加上app路径,即:
1 | |
这里需要注意,location后面的字段需要在root里找到一样的字段,否则nginx会找不到。现在,通过访问localhost/app/或localhost/app/index.html都可以访问到index页面。
当我们输入
location /app时,它就会在root路径寻找app为前缀的文件或URI(例如文件夹:localhost/apple/)。如果找不到就会报错。
为了安全隐患,防止用户可以访问到路径下其他文件,我们可以指定location:
1 | |
这时,URI和文件路径必须完全匹配才能访问,即只有访问localhost/app/index.html才能访问资源。
此外,还可以使用正则来进行模糊匹配,例如我们的路径下有视频文件0-9.avi共九个文件,我们只想开放6-9这三个文件,就需要在location中设置正则表达式,只有访问指定名字的文件,才能访问到路径下的视频文件。
1 | |
有时候,我们想要隐藏真实地址,来避免用户直接访问资源,这时可以用rewrite的字段来进行重定向。
1 | |
此时访问localhost/temp即可访问到资源,而且用户也不会察觉到文件在服务器的真实路径。
反向代理
反向代理区别于正向代理,是为服务器上的资源和服务代理出去,访客通过访问服务器代理的多台子服务器,就能访问到网站,这样做能够进行负载均衡,减少主服务器的负担。
什么是正向代理,简单来说就是VPN,我们通过访问一个代理服务器,这个服务器代表我们去访问我们无法直连的服务器。正反代理代表的角色正好相反。
下面就用nginx来实现一下反向代理。假如我们创建了两个服务app/app1,分别监听3000和3001端口。此时我们需要修改配置文件:
1 | |
这样,访问指定的路径,就可以访问到对应端口运行的项目的资源。例如,访问localhost/app1就能访问到3000端口。实战中,可以通过修改server_name来设置不同后端。例如改为zerolovesea.com
负载均衡
使用nginx来设置负载均衡,需要在http块内设置upstream块,即上游服务器。我们修改配置文件:
1 | |
这样访问localhost时,通过不断刷新,可以看到我们在3000和3001的服务中来回变化,这时因为服务器默认使用轮询的方式来进行负载均衡。我们可以使用weight字段来分配不同服务的权重占比,例如:
1 | |
2024/4/27 于苏州