Nginx是一款可用于静态资源服务器、反向代理服务器的工具,由于它具备高并发、可扩展性好、高可靠、支持热部署等特性,在互联网项目中广泛应用。此篇博客将介绍Nginx基础知识以及一些基本实验操作,例如:源码编译安装、静态服务器配置、反向代理配置、热部署、goaccess使用、配置https访问

Nginx主要由四部分组成:Nginx可执行的二进制文件,即由个模块源码编译出的一个可执行文件;Nginx.conf配置文件,用于控制nginx的行为;access.log访问日志,用于记录每一条http请求信息;error.log错误日志,用于错误定位。安装Nginx有两种方式,第一种方式是通过操作系统系统的安装工具例如ubuntu使用apt install nginx,mac使用brew install nginx命令nginx。第二种方式是下载后通过源码进行编译安装,推荐采用第二种安装方式,因为第二种安装方式可以自定义需要enable和disable的module,灵活性更强。从官网下载Nginx的源代码解压后的目录如下所示:

CHANGES中主要记录每次版本发布的更新信息

conf目录中是配置文件相关信息

html目录中是存放默认的静态文件

src目录中是源代码

auto目录里面又有四个目录,例如cc目录是用于编译的

configure命令用于编译,通过configure命令可以查看configure的命令参数,例如可以通过--with-xx_module和--without-xx_module参数控制是否将某些模块编译到nginx中。

安卓里安装nginx android nginx_配置文件

安卓里安装nginx android nginx_html_02

通过源码安装步骤:

1:解压压缩包,执行./configure命令,执行命令过程中如果遇到某些包不存在的情况,那么可以通过apt install命令(ubuntu系统)安装需要的包。例如下面的错误就需要安装这些包:apt install libpcre3 libpcre3-dev zlib1g-dev

安卓里安装nginx android nginx_nginx_03

./configure命令执行完成后会生成Makefile文件,所以执行make&&make install即可完成nginx的安装操作。./configure命令执行完成后,会生成相关文件目录信息,如下图所示:nginx path prefix是/usr/local/nginx,进入该目录的sbin目录,执行./nginx即可启动安装的nginx服务。

安卓里安装nginx android nginx_nginx_04

安卓里安装nginx android nginx_html_05

上面介绍了nginx的安装,接下来看看如何完成重载配置文件、热部署、日志切割操作。先认识下nginx配置文件的基本规则。配置文件由指令和指令块构成,每条指令以;分号结尾,指令和参数间用空格分开。指令块用{}将多条指令组织在一起。使用$符号来使用变量,部分指令支持正则表达式,include语句允许组合多个配置文件以提示可维护性。如下是一个nginx.conf文件,对于http的配置主要由server、location、http、upstream组成。

安卓里安装nginx android nginx_安卓里安装nginx_06

重载配置文件操作,非常简单,当修改nginx.conf命令后,cd sbin,执行./nginx -s reload即可。切割日志也非常简单,先备份原有的日志信息,mv access.log back.log,再执行./nginx -s reopen即能生产新的日志文件,实际项目中可以编写一个shell脚本存放到crontab下定时执行切割日志的操作。如下图所示是一个切割日志的shell脚本,通过mv命令对日志进行备份,然后通过发送kill - USR1 nginx.pid的方式切割日志,发送命令和上面执行./nginx -s reopen的效果一致。

安卓里安装nginx android nginx_配置文件_07

除了reload和reopen命令还支持./nginx -s stop(立刻停止服务),./nginx -s quit(优雅的停止服务,即正在执行的任务完成后,再停止服务)。上面介绍了重载配置文件和日志切割,接下来看看如何完成热部署,即在不影响已经允许的任务下,完成nginx的版本变更。对nginx进行版本变更的过程实际就是要替换/usr/local/nginx/sbin目录下的二进制可执行文件。

故第一步:先下载需要升级的nginx的包,进行解压编译生成新的nginx二进制文件,备份原来的二进制文件为nginx.old名称,将新的二进制文件nginx拷贝过来。

第二步:执行kill -USR2 old-nginx-master-pid,此时会启动新的master和worker进程,master和work间是父子进程关系,后续的请求会发送到新的worker进程上进行处理。老的master和worker仍然存活,所以老的任务执行不受影响。

第三步:执行kill -WINCH old-nginx-master-pid.关闭老的work进程,老的master进程还不会关闭,这样有利于回滚,如果一段时间后确定新版本无问题,那么可以向老的nginx master进程发送QUIT信号杀死老的进程,这样就完成了nginx的热部署。如果要进行回滚,那么对老的master进程发送HUB命令,向新的master进程发送QUIT进程即可。为了防止在优雅关闭worker进程中发现长时间无法停止worker进程的情况,会设置worker_shutdown_timeout时间。

安卓里安装nginx android nginx_安卓里安装nginx_08

上面提到了nginx的信号量,接下来看看都有哪些信号量。kill命令是在linux系统中,通过进程pid向进程发送信号作用的。可以通过kill向nginx的master进程发送特定的信号来进行对nginx的控制。nginx主进程支持的信号:
TERM, INT 作用和nginx -s stop一致,快速停止服务。
QUIT 作用和nginx -s quit一致,优雅停止服务。
HUP 作用和nginx -s reload一致,重载配置文件。
USR1 作用和nginx -s reopen一致,重新开启新的日志文件。
USR2 平滑升级nginx,用新的nginx二进制文件,启动新的master和worker进程
WINCH平滑关闭工作进程,关闭老的worker进程。

前面介绍了热部署过程,接下来看看如何通过nginx搭建简单静态资源服务器反向代理服务器。要搭建静态资源服务器很简单,即配置好http模块下location即可。如下图所示:server下面配置静态服务器的监听接口,location下面配置指向的静态文件目录,这里采用的是alias配置方式,右图是配置监听在8070端口,并指向dlib文件后的访问结果,因为开启了autoindex,所以访问localhost:8070时,显示了在nginx/dlib目录下的内容。

安卓里安装nginx android nginx_安卓里安装nginx_09

安卓里安装nginx android nginx_html_10

实际在配置location时还可以用root配置,那么两种方式有什么区别呢?下面是root和alias的配置

location /blog/ {
         root /usr/local/nginx/html;
         index index.html index.htm;
 }
 location /blog/ {
         alias /usr/local/nginx/html/;
         index index.html index.htm;
 }


root配置时,请求http://127.0.0.1:80/blog/root.html 这个地址时,那么在服务器里面对应的真正的资源是 /usr/local/nginx/html/blog/root.html文件。可以发现真实的路径是root指定的值加上location指定的值。alias配置时,同样请求http://127.0.0.1:80/blog/alias.html时,在服务器查找的资源路径是:/usr/local/nginx/html/alias.html。正如其名,alias指定的路径是location的别名,不管location的值怎么写,资源的真实路径都是alias指定的路径。总结而言,location和root组合相当于在root指定目录下进行location匹配,location所匹配内容必须保证在root指定目录的子目录,否则配置无效。location与alias组合,需要保证location匹配目录与alias指定目录级别相同,否则配置无效。

前面介绍了静态服务器的配置,接下来看看如何配置反向代理,反向代理的配置也非常简单,即在location中添加proxy_pass即可,proxy_pass后面可以直接放跳转的地址,也可以通过配置upstream server{}来配置。如下图所示:配置了upstream和proxy_pass,server.name指定为taoli.test,监听的端口是80,当用http://taoli.test访问时,实际请求转发到了127.0.0.1的8070端口上。为了模拟这个实验,可以启动两个nginx服务,一个是静态服务器,监听在8070端口,一个是反向代理服务器监听在80端口上。

安卓里安装nginx android nginx_配置文件_11

这里再补充说明下正向代理和反向代理的区别,正向代理即客户端发送请求时,直接给出了目标服务的地址,而反向代理指客户端访问时步知道目标服务地址,只知道代理服务器地址,由代理服务器把请求转发到目标地址。实际项目中为了安全真实服务一般情况下不会直接暴露到外网供所有用于通过浏览器或者postman等工具访问,暴露的是nginx服务的地址,nginx上配置请求与转发的目标服务关系,即upstream{}和proxy_pass配合完成请求的转发。上面的配置就是反向代理,因为浏览器在访问的时候,是访问nginx服务的地址,而不是后端真实服务地址,即监听8070端口的服务地址。

反向代理有广泛的应用,那么正向代理用于哪些场景呢?正向代理主要用于某些国外网站在国内无法访问,那么可以通过正向代理完成访问。例如国内客户通过浏览器访问某国外网站,直接访问不允许,但是在hongkong的服务运行访问,那么当我们在浏览器中访问目标网站时,请求先转发到hongkong的正向代理服务器上,代理服务器把请求转发到目标网站,目标网站返回response后,代理再把请求返回给客户端。在整个访问过程中,客户端在浏览器中输入的地址就是目标网站地址,故这里是正向代理。

上面介绍了反向代理接下来介绍如何通过goaccess工具查看nginx的日志信息。首先是安装goaccess工具,接着执行下面的命令即可生成html格式的日志信息文件。这里--real-time-html指实时显示日志信息内容,-o指生成的html格式的日志信息内容存放位置

LANG="en_US.UTF-8" bash -c 'goaccess host.access.log -o ../html/report.html --real-time-html --time-format='%H:%M:%S' --date-format='%d/%b/%Y' --log-format=COMBINED'

report.html文件生成后,可以在nginx.conf文件的location中配置访问该文件的路径,或者直接打开查看。下图是日志相关信息。

安卓里安装nginx android nginx_nginx_12

最后介绍下如何将服务配置成https访问,首先需要了解的是证书的类型分为三类,该demo中申请的是DV域名型证书,如下图所示:

安卓里安装nginx android nginx_nginx_13

部署成https访问,需要有一张被信任的CA( Certificate Authority )也就是证书授权中心颁发的SSL安全证书,并且将它部署到你的网站服务器上。一旦部署成功后,当用户访问你的网站时,浏览器会在显示的网址前加一把小绿锁,表明这个网站是安全的。理论上,我们自己也可以签发SSL安全证书,但是我们自己签发的安全证书不会被主流的浏览器信任,所以我们需要被信任的证书授权中心( CA )签发的安全证书。而一般的SSL安全证书签发服务都比较贵,比如Godaddy、GlobalSign等机构签发的证书。为了加快推广 HTTPS的普及, EEF电子前哨基金会、 Mozilla 基金会和美国密歇根大学成立了一个公益组织叫ISRG( Internet Security Research Group ),这个组织从2015年开始推出了 Let’s Encrypt免费证书。所以可以利用Let’s Encrypt提供的免费证书部署HTTPS服务了。Let’s Encrypt项目发布了一个官方的客户端Certbot ,利用它可以完全自动化的获取、部署和更新安全证书。可以通过yum或者apt在linux服务器上安装certbot(yum install python2-certbot-nginx),安装完成后执行如下命令,即可生成证书以及完成nginx的配置文件修改。

certbot --nginx --nginx-server-root=/usr/local/nginx/conf/ -d taoli.test

注意:执行该命令时需要保证-d后面是真实的域名,因为生成证书的过程中会检查域名是否可以访问。执行完命令后,查看nginx.conf文件,一般会有如下修改,此时再访问nginx就会变成https方式访问。

安卓里安装nginx android nginx_html_14

另外,需要注意,Certbot的证书有效期是3个月,可以通过cerbot renew命令续订。以上就是nginx基础知识介绍。