1. 概述
很多人可能或多或少了解过nginx,即使没有使用过nginx,但是可能用Apache搭建过简单的web服务器,用tomcat写过一些简单的动态页面,其实这些功能nginx都可以实现。
nginx最重要的三个使用场景个人认为是静态资源服务、反向代理服务和api服务。
web请求走进服务以后会先经过nginx再到应用服务,然后再去访问redis或者mysql提供基本的数据功能。
这就有个问题,应用服务因为要求开发效率高,所以他的运行效率是很低的,他的qbs,tps并发都是受限的,所以就需要把很多的应用服务组成集群,向用户提供高可用性。
很多服务构成集群的时候,需要nginx具有反向代理的功能,可以把动态请求传导给对应的应用服务。服务集群一定会带来两个需求,动态的扩容和容灾。
反向代理必须具备负载均衡的功能,其次在链路中,nginx是处在企业内网的边缘节点,随着网络链路的增长,用户体验到的时延会增加。
把一些所有用户看起来不变的,或者在一段时间内看起来不变的动态内容缓存在nginx部分,由nginx直接向用户提供访问,用户的时延就会减少很多。
反向代理衍生出另外的功能叫缓存,他能够加速访问,而很多时候在访问像css或js文件又或者一些小图片是没有必要由应用服务来访问的,他只需要直接由nginx提供访问就可以了这就是nginx的静态资源功能。
应用服务它本身的性能有很大的问题,数据库服务要比应用服务好的多,原因是数据库他的业务场景比较简单,并发性能和tps都要远高于应用服务。由nginx直接去访问数据库或者redis也是不错的选择。
还可以利用nginx强大的并发性能,实现如web防火墙的一些业务功能,这就要求nginx服务有非常强大的业务处理功能,openResty和nginx集成了一些工具库来实现此功能。
2. 历史背景
全球化和物联网的快速发展,导致接入互联网中的人与设备的数量都在快速的上升,数据的快速爆炸,对硬件性能提出很高的要求。
摩尔定律表明之前服务跑在1GHZ的CPU上的服务更新到2GHZ的CPU时服务会有两倍的性能提升。
但是到了本世纪初,摩尔定律在单颗CPU的频率上已经失效了,CPU开始向着多核方向发展,当服务器现在是跑在8核CPU上时,一年半以后换到了16核的CPU,服务的性能通常是不会有一倍的提升的。
这些性能主要损耗在操作系统和大量的软件没有做好服务于多核架构的准备,比如说像Apache是低效的,因为他的架构模型里一个进程同一时间,只会处理一个连接,一个请求。只有在这个请求处理完以后才会去处理下一个请求。
它实际上在使用操作系统的进程间切换的特性,因为操作系统微观上是有限的CPU,但是操作系统被设计为同时服务于数百甚至上千的进程。
Apache一个进程只能服务于一个连接,这种模式会导致当Apache需要面对几十万,几百万连接的时候,他没有办法去开几百万的进程,而进程间切换的代价成本又太高啦。
当并发的连接数越多,这种无谓的进程间切换引发的性能消耗又会越大。
nginx是专门为了这种应用场景而生的,可以处理数百万甚至上千万的并发连接,nginx目前在web市场份额中排行第二,在过去几年他增长极度迅速,在不久的将来nginx在web端的应用将远远超过其他服务器。
3. nginx的优点
大部分的程序和服务器随着并发连接数的上升他的RPS数会急剧的下降,这里的原理就像之前所说过的,他的设计架构是有问题的。
nginx的第一个优点就是高并发和高性能同时具备的,往往高并发只需要对每一个连接所使用的内存尽量的少就可以达到。
而具有高并发的同时达到高性能,往往需要非常好的设计,那nginx可以达到什么样的标准呢?
比如说现在主流的一些服务器32核64G的内存可以轻松达到数千万的并发链接,如果是处理一些简单的静态资源请求,可以达到一百万的RPS这种级别。
其次nginx的可扩展性非常好,主要在于他的模块化设计非常的稳定,而且nginx的第三方模块的生态圈非常的丰富。甚至于有像TNG,openRestry这种第三方插件。丰富的生态圈为nginx丰富的功能提供了保证。
第三个优点是它的高可靠性,所谓的高可靠性是指nginx可以在服务器上持续不间断的运行数年,而很多web服务器往往运行几周或者几个月就需要做一次重启。
对于nginx这种高并发高性能的反向代理服务器而言,他往往运行在企业内网的边缘节点上,如果企业想提供4个9,5个9,甚至更高的高可用性时,对于nginx持续运行能够down机的时间一年可能只能以秒来计。所以在这种角色中,nginx的高可靠性给提供了非常好的保证。
第四个优点热部署,是指可以在不停止服务的情况下升级nginx,这对于nginx来说非常的重要,因为在nginx可能跑了数百万的并发连接。
如果是普通的服务可能只需kill掉进程再重启的方式就可以处理好,但是对于nginx而言,因为kill掉nginx进程,会导致操作系统为所有的已经建立连接的客户端发送一个tcp中的reset报文。而很多客户端是没有办法很好的处理请求的。
在大并发场景下,一些偶然事件就会导致必然的恶性结果,所以热部署是非常有必要的。
第五个优点是BSD许可证,BSD Listens是指nginx不仅是开源的免费的,而且可以在有定制需要的场景下,去修改nginx源代码,再运行在商业场景下,这是合法的。
以上的优点是nginx最核心的特性。
4. 主要组成部分
首先是nginx的可执行文件,它是由nginx自身的框架、官方模块以及各种第三方模块共同构建的文件。他有完整的系统,所有的功能都由他提供。
第二个部分是nginx.conf配置文件,类似于骑车的驾驶员,虽然可执行文件已经提供了许多功能,但这些功能有没有开启,或者开启了以后定义了怎样的行为处理请求,都是由nginx.conf配置文件决定的。
nginx的第三个组成部分叫做access.log访问日志,access.log会记录下每一条nginx处理过的http请求信息与响应信息。
第四个组成部分是error.log错误日志,当出现了一些不可预期的问题时,可以通过error.log去把问题定位出来。
这四个部分是相辅相成的。
nginx的可执行文件和nginx.conf定义了处理请求的方式。如果想对web服务,做一些运营或者运维的分析,需要对access.log做进一步的分析。如果出现了任何未知的错误,或者与预期的行为不一致时,应该通过error.log去定位根本性的问题。
5. 版本规则
nginx每发布一个版本的时候会有三个特性,一个是feature,就是他新增了哪些功能,bugfix表示他修复了哪些bug,change表示做了哪些重构。
每一个版本都有mainline主干版本和stable稳定版本。
在nginx的官网点击右下角的download,就可以看到版本号列表,单数版本表示主干版本,会新增很多功能,但不一定稳定。双数版本是稳定版本。
CHANGES文件中可以看到每一个版本含有的新增功能,修复的bug,以及做了哪些小的重构。
大概在2009年以后nginx的bugfix数量已经大幅度减少,所以nginx相对已经很稳定了。
nginx的开发时间是在2002年,但是他在2004年10月4日推出了第一个版本,在2005年曾经做过一次大的重构。
因为nginx优秀的设计,使得他的生态圈极为丰富,模块的设计,架构的设计都没有再做过大的变动。
在2009年nginx开始支持windows操作系统,2011年1.0正式版本发布,同时nginx的商业公司nginx Plus也成立了,在2015年nginx发布了几个重要的功能。
其中提供stream,四层反向代理,他在功能上完全可以替代传统使用的LVS, 并且具有更丰富的功能。
6. 版本选择
免费开源: nginx.org
商业版本: nginx.com
开源免费的nginx在2002年开始开发,到2004年发布第一个版本,2011年开源版的nginx发布了1.0稳定版,同年nginx的作者成立了一家商业公司,开始推出nginx Plus商业版的nginx。
商业版的nginx在整合第三方模块上还有运营监控以及技术支持上有很多优点,但他有个最大的缺点就是不开源,所以通常在国内会使用nginx.org开源版的。
阿里巴巴也推出了Tengine版本,Tengine的优点就是在阿里巴巴生态下他经历了非常严苛的考验,Tengine之所以会存在也是因为他的很多特性领先于nginx的官方版本。
所以Tengine实际上是修改了nginx官网版本的主干代码,当然框架被修改以后Tengine就遇到了一个明显的问题,没有办法跟着nginx的官方版本同步的升级。Tengine也可以使用nginx的第三方模块。
OpenResty的作者章亦春在阿里巴巴的时候开发了Lua语言版本的openResty,因为nginx的第三方模块开发的难度相当大,章亦春把nginx非阻塞事件的一种框架以Lua语言的方式提供给了广大开发者。
OenRestry兼具了高性能,以及开发效率高的特点,OpenResty同样有开源版和商业版,目前多使用openresty.org站点下的开源版本。商业版OpenRestry的主要特点是技术支持相对比较好很多。
如果你没有太多的业务诉求,那么使用开源版的nginx就足够了,如果你需要开发Api服务器,或者需要开发web防火墙,openrestry是一个很好的选择。
7. 编译配置
安装nginx有两种方法,除了编译外,还可以直接用操作系统上自带的一些工具,比如说yum,apt-get,直接去安装nginx。
但是直接安装nginx有个问题,就是nginx的二进制文件不会把模块直接编译进来,毕竟nginx的官方模块,并不是每一个默认都会开启的。
如果想添加第三方的nginx模块,就必须通过编译nginx的方式。
编译nginx主要分为六个部分,首先需要下载nginx,从nginx.org网站上直接下载就可以。
打开nginx.org在页面中找到右下角donwload,选择Stable版本的下来链接,右键复制链接地址即可,进入到Linux中使用wget进行下载
cd /home/nginx wget http://nginx.org/download/nginx-1.18.0.tar.gz 复制代码
下载完nginx压缩包以后首先解压压缩包。
tar -xzf nginx-1.18.0.tar.gz 复制代码
接着进入解压后的目录通过ll命令查看所有文件。
cd nginx-1.18.0 ll 复制代码
第一个目录叫auto目录。
cd auto 复制代码
auto目录里面有四个子目录,cc是用于编译的,lib库和对操作系统的判断在os里面,其他所有的文件都是为了辅助config脚本执行的时候判定nginx支持哪些模块以及当前的操作系统有什么样的特性可以供给nginx使用。
CHANGES文件标记了nginx每一个版本中提供了哪些特性和bugfix。
cat ../CHANGES 复制代码
其中会有feature,bugfix,change三种特性在里面。
CHANGES.ru文件是俄罗斯语言的CHANGES文件,可能因为作者是个俄罗斯人。
conf文件是一个示例文件,就是把nginx安装好以后,为了方便运维配置,会把config里面的示例文件copy到安装目录。
configure脚本用来生成中间文件,执行编译前的一个一些配置,也就是记录编译前的设定信息,编译时使用。
contrib目录提供了两个脚本和vim工具,也就是让vim打开config配置文件时支持代码高亮。
把contrib目录下vim的所有文件copy到自己的目录中
cp -r contrib/vim/* ~/.vim/ 复制代码
就可以把nginx语言的语法高亮显示在vim中了。
html目录里面提供了两个标准的HTML文件,一个是发现500错误的时候可以重定向到的文件,另一个是默认的nginx的欢迎界面index.html。
man文件里则是Linux对nginx的帮助文件,里面标识了最基本的nginx帮助和配置。
src目录是nginx的核心源码。