前言

打算要跳槽啦,所以这几天的文章多半是理论性的,针对于面试的一些东西,实验性的文章等过几天再说吧。等拿到一个好的offer之后,也可以正好休整休整。


Nginx是网页服务器运维人员不可能绕开的一个弯,剩下几个比较高危的面试范围是:linux基础、网络知识基础、python,或许还会有zabbix等监控工具。这里先说nginx,后面几个肯定也会写。


试题

【试题1】缺省安装的 nginx + php-fpm 环境,假设用户浏览一个耗时的网页,但是却在服务端渲染页面的中途关闭了浏览器,那么请问服务端的 php 脚本是继续执行还是退出执行?

【解答】正常情况下,如果客户端client异常退出了,服务端的程序还是会继续执行,直到与IO进行了两次交互操作。服务端发现客户端已经断开连接,这个时候会触发一个user_abort,如果这个没有设置ignore_user_abort,那么这个php-fpm的程序才会被中断。

拓展阅读:http://www.cnblogs.com/yjf512/p/5362025.html?foxhandler=R***eadRenderProcessHandler


【试题2】首先,Nginx 日志格式中的 $time_local 表示的是什么时间?请求开始的时间?请求结束的时间?其次,当我们从前到后观察日志中的 $time_local 时间时,有时候会发现时间顺序前后错乱的现象,请说明原因。

【解答】$time_local:在服务器里请求开始写入本地的时间,因为请求发生时间有前有后,所以会时间顺序前后错乱。


【试题3】在Nginx+PHP环境中,Web错误日志里偶尔会出现如下错误信息:「recv() failed (104: Connection reset by peer) while reading response header from upstream」,请分析可能的原因是什么。

【解答】遇到这种情况,第一解决方法是重启php服务,service php5-fpm restart,但是这个治标不治本,相对治本的方法是把php的pm.max_requests值改大一点,比如500;第二个方法,修改php-fpm的request_terminate_timeout,把值改成=0。


这个情况要看后端的php,要么是链接不上,要么是php服务挂了,要么就是链接超时。

worker数不够挂掉就会504,worker处理超时就会502。

拓展阅读:http://serverfault.com/questions/543999/nginx-errors-recv-failed-104-connection-reset-by-peer-while-reading-respon


【试题4】已知Nginx和PHP-FPM安装在同一台服务器上,Nginx连接PHP-FPM有两种方式:一种是类似127.0.0.1:9000的TCP socket;另一种是类似/tmp/php-fpm.sock的Unix domain socket。请问如何选择,需要注意什么。

【解答】Unix domain socket的流程不会走到TCP 那层,直接以文件形式,以stream socket通讯。如果是TCP socket,则需要走到IP层。说的通俗一点,追求可靠性就是tcp(需要占用一个端口,更稳),追求高性能就是Unix Socket(不需要占用端口,更快)。有图有真相:

wKioL1c9NsLhLRbtAAE59HPkdgE280.jpg

上面的是tcp/ip模式,每秒钟解决不到140个请求。

wKiom1c9NfahNG8FAAF97ZfiiUI422.jpg

这个是socket模式,一秒钟解决5700+个请求,高下立判!

拓展阅读:https://blog.linuxeye.com/364.html

http://www.cnxct.com/default-configuration-and-performance-of-nginx-phpfpm-and-tcp-socket-or-unix-domain-socket/ (这篇文章强烈推荐,写得特别好!)


【试题5】在Nginx中,请说明Rewrite模块里break和last的区别。

解答】官方文档的定义如下:

last:停止执行当前这一轮的ngx_http_rewrite_module指令集,然后查找匹配改变后URI的新location;
break:停止执行当前这一轮的ngx_http_rewrite_module指令集;

千言万语举个例子:

location /test1.txt/ {

        rewrite /test1.txt/  /test2.txt break;

}

        location ~ test2.txt {
        return 508;
}


使用break会匹配两次URL,如果没有满足项,就会停止匹配下面的location,直接发起请求www.xxx.com/test2.txt,由于不存在文件test2.txt,则会直接显示404。
使用last的话,会继续搜索下面是否有符合条件(符合重写后的/test2.txt请求)的location,匹配十次,如果十次没有得到的结果,那么就跟break一样了。返回上面的例子,/test2.txt刚好与面location的条件对应上了,进入花括号{}里面的代码执行,这里会返回508。(这里的508是我自己随便设定的)


拓展阅读:http://nigelzeng.iteye.com/blog/1731317


【试题6】有时候nginx运行很正常,但是会发现错误日志中依旧有报错connect() failed (111: Connection refused) while connecting to upstream.请问肿么办?

【解答】一般情况下我们的upstream都是fastcgi://127.0.0.1:9000. 造成这个问题的原因大致有两个1)php-fpm没有运行:执行#netstat -ant | grep 9000命令查看是否启动了php-fpm,如果没有则启动你的php-fpm即可,2)php-fpm队列满了:php-fpm.conf配置文件pm.max_children修改大一点,重启php-fpm并观察日志情况。


【试题7】简单描述一下nginx里root和alias的区别。

【解答】root与alias主要区别在于nginx如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上。root是全路径定位,alias是当前路径定位。

举个例子

location ~ ^/weblogs/
{
 root /data/nginx/html;
 autoindex on;
}

这里匹配是分大小以/weblogs的路径,当在浏览器地址栏申请/weblogs/a/b/c/123.txt的时候,服务器查找的是/data/nginx/html/weblogs/a/b/c/123.txt文件,并把它重现给web服务器,这就是全路径定位,即完整的URI映射。

location ^~ /binapp/ {  
 internal;  
 alias /data/nginx/conf/html/;
}

这时候浏览器地址栏申请/binapp/a/456.jpg的时候,服务器查找的是/data/nginx/conf/html/a/456.jpg,看到了吗!没有location后面的直连的/binapp/了,也就是说alias会把location后面配置的路径丢弃掉,把当前匹配到的目录指向到指定的目录。


注意!使用alias时,目录名后面一定要加"/",否则会找不到文件,而root不一定。