nginx介绍
是什么:nginx是开源的轻量级web服务器、方向代理服务器、负载均衡器以及http缓存器,其特点是高并发、高性能和低内存
一般提到反向代理,说的都是http反向代理,但是也有tcp反向代理,以下都讨论http反向代理
正向代理:正向代理也叫做代理,所作的事只是将浏览器的请求转发给服务器,再将服务器的响应转发给浏览器而已;正向代理可以方便进行一些安全审计及控制、可以加速或节省带宽(有些代理服务器还能对资源进行缓存)
反向代理:若以浏览器为主体,可以这样理解,正向代理是浏览器主动走代理服务器,需要在浏览器客户端进行一些代理服务器的配置,而反向代理是浏览器“被代理”,反向代理也叫“透明代理”,也即浏览器以为与其交互的服务器是真实的服务器,而实际上就是一个代理服务器,即浏览器都不知道自己被代理,因此也不需要在客户端进行配置
作用:反向代理可以作为内部负载均衡的手段,从这里可以理解到,虽然反向代理在浏览器上没有进行配置,但是是需要在服务器上进行配置的,相当于原本服务器开放80端口对外服务,浏览器只认识这个端口的服务,访问的时候都是访问这个端口,现在在服务器上将该端口让给nginx,让nginx接收浏览器发送过来的请求,再转交给服务器,负载均衡的原理是可以在服务器上多开放端口对外服务,nginx会合理分配访问请求,分流给两个端口服务;虽然大量的访问都去到nginx,但是nginx只是负责转发,因此能够处理得过来
nginx反向代理实战
配置tomcat,官网下载tomcat包,解压并移动到/usr/local
下,在/usr/local/tomcat/bin
下./startup.sh
启动,启动之前需要在/etc/profile
配置文件中添加以下内容
# tomcat
CATALINA_BASE=/usr/local/tomcat
CATALINA_HOME=/usr/local/tomcat
TOMCAT_HOME=/usr/local/tomcat
export CATALINA_BASE CATALINA_HOME TOMCAT_HOME
执行source /etc/profile
使环境变量生效,访问ip+8080端口可以访问到tomcat的首页
配置防火墙出战规则,firewall-cmd --zone=public --add-port=80/tcp --permanent
开放80端口,firewall-cmd --reload
刷新防火墙配置规则
至此宿主机也能够成功访问虚拟机的tomcat首页
在C:\Windows\System32\drivers\etc
下的hosts
文件中加入域名www.test.com
到虚拟机192.168.80.8
的映射关系(访问192.168.80.8
默认访问80
端口),注意需要提升宿主机对hosts
文件的权限等级才能进行修改和写入操作
在/usr/local/nginx/conf/nginx.conf
中修改域名server_name
为www.test.com
,在location
添加proxy_pass
模块配置对应的服务器为192.168.80.8:8080
,这样一来,对于所有访问域名www.test.com
(主机访问会域名解析到192.168.80.8:80
端口)的请求,都会先经过nginx,nginx监听80端口,收到请求后会将请求转发到proxy_pass
模块配置的192.168.80.8:8080
端口上实现反向代理(起初还会访问不到,是nginx修改配置之后需要刷新一下),nginx的配置和启动,在/usr/local/nginx/sbin
下./nginx
启动,此外还可以./nginx -h
查看nginx的命令行帮助
整一个流程就是,浏览器先访问www.test.com
,本地域名解析到192.168.80.8:80
端口,访问192.168.80.8:80
,这是nginx的开放端口,nginx监听着该端口,当收到该端口的访问请求后会将请求转发到192.168.80.8:8080
端口的服务,从而浏览器访问到tomcat首页
若没有设置nginx和tomcat开机自启,则重新开机之后需要启动nginx和tomcat服务才能正常访问
至此,在宿主机访问虚拟机的80端口会访问到tomcat首页
nginx负载均衡实战
在/usr/local/tomcat/webapps
目录下新建一个test
目录,在test
目录下新建一个html文件为以下内容,浏览器访问www.test.com/test/test.html
显示welcome to service 8080
<!--apache8080-->
<html>
<head></head>
<body>
welcome to service 8080
</body>
</html>
重新解压一个tomcat压缩包重命名为tomcat-8081,移动到/usr/local/
目录,进入tomcat-8081/webapps
目录,新建一个test
目录,在该目录中新建一个test.html
文件为以下内容
<!--apache8081-->
<html>
<head></head>
<body>
welcome to service 8081
</body>
</html>
修改/usr/local/tomcat-8081/conf/server.xml
,修改服务端口server port
为8015防止8005端口占用,修改连接端口connector port
为8081,修改/etc/profile
配置文件,为第二个tomcat添加环境变量
# tomcat-8081
CATALINA_BASE_8081=/usr/local/tomcat_8081
CATALINA_HOME_8081=/usr/local/tomcat_8081
TOMCAT_HOME_8081=/usr/local/tomcat_8081
export CATALINA_BASE_8081 CATALINA_HOME_8081 TOMCAT_HOME_8081
执行source /etc/profile
使环境变量生效,将/usr/local/tomcat-8081/bin
目录下的catalina.sh
文件(由于启动tomcat的startup.sh
和关闭tomcat的shutdown.sh
都调用了catalina.sh
来完成启动和关闭tomcat的功能)中的CATALINA_BASE
、CATALINA_HOME
、TOMCAT_HOME
三个环境变量修改成CATALINA_BASE_8081
、CATALINA_HOME_8081
、TOMCAT_HOME_8081
,从而可以调用对应的环境变量实现tomcat的启动和关闭
本地访问8080端口和8081端口都返回了tomcat首页,访问对应test
目录下的test.html
文件,显示了对应的文件内容
接着再修改nginx下的配置(ifconfig
是动态获取,有时候ip变了需要重新修改一下nginx的反向代理ip,还要修改本地hosts端口映射),在http全局块添加以下代码
upstream myserver{
server 192.168.80.9:8080;
server 192.168.80.9:8081;
}
在server
中的location
块添加proxy_pass
为http://myserver
location / {
proxy_pass http://myserver;
index index.html index.htm;
}
实现了负载均衡,在宿主机访问www.test.com/test/test.html
,不断刷新可以发现页面返回内容在8080和8081之间跳转,即nginx实现了负载均衡的功能,将请求平均分配给两个tomcat服务进行处理(当然还能设置某个服务的权重,即将请求更多的分配给权重更多的服务进行处理)
nginx进程模型
存在一个master进程和多个worker进程,master进程用于管理worker进程,包括接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态;主要干活的是worker进程(主要体现为worker进程中存在一个函数执行无限循环,不断处理收到的来自客户端的请求并进行处理);
nginx时间模型与异步非阻塞处理方式
nginx不同于传统web服务器的事件驱动局限于TCP连接建立、关闭事件,每个请求在连接建立后都始终占用着系统资源知道关闭才会释放资源;而nginx不使用进程或线程来作为事件消费者,所谓的事件消费者只能是某个模块,只有事件收集、分发器才有资格占用进程资源,它们会在分发某个事件时调用事件消费者模块使用当前占用的进程资源。多个worker进程会通过共同竞争来处理客户端请求,各个worker进程之间相互独立且平等,最终一个请求只会被一个worker进程接收并处理,由worker进程通过upstream
或FastCGI
实现与上游服务器或应用服务器的信息交换;而一个worker进程可以监听多个套接字,又基于nginx异步非阻塞的处理方式,可以实现高并发的请求处理;
nginx模块化结构设计
每个模块就是一个功能模块,只负责自身的功能,模块之间遵循“高内聚,低耦合”的原则,便于对nginx进行开发和增加功能;其中
(1)nginx core
实现了底层的通讯协议,为其他模块和nginx进程构建了基本的运行时环境,并且构建了其他各模块的协作基础;
(2)event module
搭建了独立于操作系统的事件处理机制的框架,并提供了各具体事件的处理。源码理解参见
(3)phase handler
模块也被直接称为handler
模块。主要负责处理客户端请求并产生待响应内容,nginx在接收并解析完请求行,请求头之后,就会一次调用各个phase handler
,共有11个handler
,其是完毕nginx主要功能的阶段;相当于是对请求处理的一种抽象,便于定制处理过程。源码理解参见
(4)output filter
也称为filter
模块,主要是负责对输出的内容进行处理,可以对输出进行修改。nginx在生成响应内容之后实际上还需要做加工处理
(5)upstream
是实现反向代理功能的模块,将真正的请求转发到后端服务器上,并从后端服务器上读取响应,发回客户端。upstream
模块是一种特殊的handler
,只不过响应内容不是真正由自己产生的,而是从后端服务器上读取的。该模块也能实现nginx的负载均衡功能,其支持的代理方式有:uwsgi_pass
、fastcgi_pass
、proxy_pass
、memcached_pass
;由于该模块实际上不需要自己产生响应,因此upstream模块通过一些回调函数来实现请求的构造以及响应的解析:
create_request
:生成发送到后端服务器的请求缓存,在初始化upstream
时使用
reinit_request
:在某台后端服务器出错的情况,nginx会尝试另一台后端服务器,nginx选定新的服务器之后,会先调用此函数,以重新初始化upstream
模块的工作态部分,然后再次进行upstream
连接
process_header
:处理后端服务器返回的信息头部,比如http协议的header
部分,或者memcached协议的响应状态部分
abort_request
:在客户端放弃请求时被调用,不需要在函数中实现关闭后端服务器连接的功能,系统会自动完成关闭连接的步骤,所以一般此函数不会进行任何具体工作
finalize_request
:正常完成与后端服务器的请求后调用该函数,一般不会进行任何具体工作
input_filter
:处理后端服务器返回的响应正文,nginx默认的input_filter
会将收到的内容封装成缓冲区链ngx_chain
,该链由upstream
的out_bufs
指针域定位,所以开发人员可以在模块以外通过该指针得到后端服务器返回的正文数据
input_filter_init
:初始化input_filter
的上下文
(6)load balancer
是一个负载均衡器,可以实现集群
(7)extend module
是一个继承模块,当需要用到第三方模块时会使用到
nginx将各功能模块组织成一条链,当有请求到达时,请求依次经过这条链上的部分或者全部模块进行处理;
nginx请求处理流程
nginx配置文件
nginx的配置文件的默认位置是/usr/local/nginx/conf/nginx.conf
若需要使用自定义的配置文件,则需要在运行前指定所使用的配置文件的路径,比如./sbin/nginx -c my_conf/my_conf.conf
./sbin/nginx -h
可以查看nginx命令行支持的参数
nginx的配置文件主要分为四部分,main全局模块、events模块、http模块以及server模块
... #main全局块
events { #events块
...
}
http #http块
{
... #http全局块
server #server块
{
... #server全局块
location [PATTERN] #location块
{
...
}
location [PATTERN]
{
...
}
}
server
{
...
}
... #http全局块
}
main全局模块用于配置与具体业务无关的参数,即一些影响nginx服务器整体运行的配置指令,如worker_processes
用来配置线程数,值越大,可以支持的并发处理量就越多;
events模块用于配置影响nginx服务与用户之间连接的属性,即主要涉及影响nginx服务器与用户的网络连接的指令,如worker_connections
用来配置每个线程的最大连接数;
http模块用于配置nginx的业务功能,是服务器配置中最频繁的部分,又包括了http全局块和server块,包括了配置代理、缓存、日志定义等绝大多数功能;
server模块必须位于http内部,用于配置nginx的一个主机,其中listen指定监听的端口,server_name
指定主机名,location
用于指定主机上的资源位置
worker_processes、events、http、server、worker_connections,这些配置项的名称,在nginx源码中都是写死的字符串
参考文章
- 深入理解 http 反向代理(nginx). 知乎. Available at here. Accessed: 22 August 2023.
- 深入理解HTTP协议. 知乎. Available at here. Accessed: 22 August 2023.
- Centos 7防火墙添加端口及管理命令(Centos 7 及以上版本). CSDN. Available at here. Accessed: 26 August 2023.
- CentOS7安装tomcat. CSDN. Available at here. Accessed: 26 August 2023.
- linux部署多个tomcat. CSDN. Available at here. Accessed: 27 August 2023.
- vim几个小技巧(批量替换,列编辑). CSDN. Available at here. Accessed: 27 August 2023.
- Nginx的模块化体系详解. CSDN. Availavle at here. Accessed: 4 September 2023.
- 深入 Nginx 之事件驱动核心架构篇. 知乎. Available at here. Accessed: 4 September 2023.
- Nginx 架构——【核心流程+模块介绍】. 腾讯云. Available at here. Accessed: 5 September 2023.
- Nginx开发从入门到精通. Tengine. Available at here. Accessed: 5 September 2023.