工程实践: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 于苏州