【修真院java小课堂】nginx是什么?

大家好,我是来自郑州分院的第10期java学员王耀琪,今天我要讲nginx服务器有什么作用?什么叫反向代理?为什么要使用反向代理?

例行公事先来背景介绍


背景介绍
Nginx("engine x") 是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点开发的
Nginx 是一个高性能的 HTTP和反向代理服务器,也是一个 IMAP/POP3/SMTP(都是关于电子邮件的协议) 服务器。


知识剖析
反向代理(Reverse Proxy)实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。
反向代理的作用:
       保证内网安全,使用反向代理提供WAF(Web应用防护系统)功能,阻止web攻击大型网站,通常将反向代理作为公网访问地址,Web服务器是内网。


互联网早期,业务流量比较小并且业务逻辑比较简单,单台服务器便可以满足基本的需求;但随着互联网的发展,业务流量越来越大并且业务逻辑也越来越复杂,单台机器的性能问题以及单点问题凸显了出来,因此需要多台机器来进行性能的水平扩展以及避免单点故障。但是要如何将不同的用户的流量分发到不同的服务器上面呢?
早期的方法是使用DNS做负载,通过给客户端解析不同的IP地址,让客户端的流量直接到达各个服务器。但是这种方法有一个很大的缺点就是延时性问题,在做出调度策略改变以后,由于DNS各级节点的缓存并不会及时的在客户端生效,而且DNS负载的调度策略比较简单,无法满足业务需求,因此就出现了负载均衡。
客户端的流量首先会到达负载均衡服务器,由负载均衡服务器通过一定的调度算法将流量分发到不同的应用服务器上面,同时负载均衡服务器也会对应用服务器做周期性的健康检查,当发现故障节点时便动态的将节点从应用服务器集群中剔除,以此来保证应用的高可用。
客户端的流量首先会到达负载均衡服务器,由负载均衡服务器通过一定的调度算法将流量分发到不同的应用服务器上面,同时负载均衡服务器也会对应用服务器做周期性的健康检查,当发现故障节点时便动态的将节点从应用服务器集群中剔除,以此来保证应用的高可用。


nginx的内部结构是由核心部分和一系列的功能模块所组成。这样划分是为了使得每个模块的功能相对简单,便于开发,同时也便于对系统进行功能扩展。
nginx将各功能模块组织成一条链,当有请求到达的时候,请求依次经过这条链上的部分或者全部模块,进行处理。每个模块实现特定的功能。


Nginx模块分类
event module: 搭建了独立于操作系统的事件处理机制的框架,及提供了各具体事件的处理。包括ngx_events_module, ngx_event_core_module和ngx_epoll_module等。nginx具体使用何种事件处理模块,这依赖于具体的操作系统和编译选项。
phase handler: 此类型的模块也被直接称为handler模块。主要负责处理客户端请求并产生待响应内容,比如ngx_http_static_module模块,负责客户端的静态页面请求处理并将对应的磁盘文件准备为响应内容输出。
output filter: 也称为filter模块,主要是负责对输出的内容进行处理,可以对输出进行修改。例如,可以实现对输出的所有html页面增加预定义的footbar一类的工作,或者对输出的图片的URL进行替换之类的工作。
upstream: upstream模块实现反向代理的功能,将真正的请求转发到后端服务器上,并从后端服务器上读取响应,发回客户端。upstream模块是一种特殊的handler,只不过响应内容不是真正由自己产生的,而是从后端服务器上读取的。
load-balancer: 负载均衡模块,实现特定的算法,在众多的后端服务器中,选择一个服务器出来作为某个请求的转发服务器。


Nginx处理请求过程:
(1)首先,nginx在启动时,会解析配置文件,得到需要监听的端口与ip地址
然后,nginx的master进程里面,先初始化好这个监控的socket(创建socket--设置addrreuse等选项--绑定到指定的ip地址端口--在listen),然后再fork出多个子进程出来,然后子进程会竞争accept新的连接。
此时,客户端就可以向nginx发起连接了。
(2)客户端向Nginx发起连接
首先:当客户端与nginx进行三次握手,与nginx建立好一个连接后,此时,某一个子进程会accept成功,得到这个建立好的socket,然后创建nginx对连接的封装,即ngx_connection_t结构体。
其次:设置读写事件处理函数并添加读写事件来与客户端进行数据的交互。
最后,nginx或客户端来主动关掉连接。至此,一个连接寿终正寝。



常见问题

Nginx的权重分配方式有哪些?


解决方案

主要有5种:

1、轮询

每个请求按时间顺序逐一分配到不同的后端服务器
2、Weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
3、Ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
4、Fair
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
Nginx本身不支持fair,如果需要这种调度算法,则必须安装upstream_fair模块。
5、Url_hash
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效

Nginx本身不支持url_hash,如果需要这种调度算法,则必须安装Nginx的hash软件包。



扩展思考
Nginx怎么解决惊群问题?
首先说什么是惊群问题,nginx是一个master进程,fork出多个子进程,这些子进程会开始同时监听同一个Web端口。假如在没有用户连入服务器,某一时刻恰好所有的worker子进程都休眠且等待新连接的系统调用;这时有一个用户向服务器发起了连接,内核在收到TCP的SYN包时,会激活所有的休眠worker子进程。最先开始执行accept的子进程可以成功建立新连接,而其他worker子进程都会accept失败,转而继续休眠。这些accept失败的子进程被内核唤醒是不必要的,这一时刻它们占用了本不需要的系统资源,引发了不必要的进程上下文切换,增加了系统开销。


不让多个进程在同一时间监听接受连接的socket,而是让每个进程轮流监听,这样当有连接过来的时候,就只有一个进程在监听那肯定就没有惊群的问题。具体做法是:利用一把进程间锁,每个进程中都尝试获得这把锁,如果获取成功将监听socket加入wait集合中,并设置超时等待连接到来,没有获得所的进程则将监听socket从wait集合去除。


参考文献
http://tengine.taobao.org/book/chapter_02.html
https://blog.csdn.net/russell_tao/article/details/7204260

https://www.cnblogs.com/lvgg/p/6140584.html


更多讨论

Q1:nginx优点有哪些?

A1:1.高并发连接 :官方测试能够支撑5W并发连接,在实际生产中可跑到2~3W并发连接数。
    2.内存消耗少:在3万并发连接下,开启的10个Nginx 进程才消耗150M内存 (15M*10=150M)。
    3.配置文件非常简单 :风格跟程序一样通俗易懂。
    4.成本廉价 :Nginx为开源软件,可以免费使用。
    5.支持Rwrite重写:能够根据域名、URL的不同, 将HTTP请求分发到不同的后端服务器群
    6.内置健康检查功能 :在3万并发连接下,如果Nginx Proxy后端的某台Web服务器宕机了,       不会影响前端的访问。
    7.节省带宽:支持GZIP压缩,可以添加浏览器本地缓存的Header头
    8.稳定性高 :用于反向代理,宕机的概率微乎其微。


Q2:反向代理的好处?

A2:保证内网安全,使用反向代理提供WAF(Web应用防护系统)功能,阻止web攻击大型网站。


Q3:nginx如何做日志统计?

A3:nginx.conf可以根据字段配置需要打印的信息。然后通过脚本整理信息进行统计。

猜你喜欢

转载自blog.csdn.net/UWillNeverWalkAlone/article/details/80992219
今日推荐