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

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

2、nginx是如何实现高并发的?

答:nginx之所以可以实现高并发,与它采用的epoll模型有很大的关系。epoll模型采用异步非阻塞的事件处理机制。这种机制可让nginx进程同时监控多个事件。

简单来说,就是异步非阻塞,使用了epoll模型和大量的底层代码优化。如果深入一点的话,就是nginx的特殊进程模型和事件模型的设计,才使其可以实现高并发。

进程模型

它是采用一个master进程和多个worker进程的工作模式。
1、master进程主要负责收集、分发请求。当一个请求过来时,master拉起一个worker进程负责处理这个请求。;
2、master进程也要负责监控worker的状态,保证高可靠性;
3、worker进程议案设置为和CPU核心数一致或者其二倍。nginx的worker进程和Apache的不一样。apache的进程在同一时间只能处理一个请求,所以它会开启很多个进程,几百甚至几千个。而nginx的worker进程在同一时间可以处理的请求数只受内存限制,因此可以处理更多请求。

事件模型

nginx是异步非阻塞的。

一个master进程,多个worker进程,每个worker进程可以处理多个请求。每进来一个request,都会有worker进程去处理。但不是全程的处理,那么处理到的程度就是可能发生阻塞的地方,比如向后端服务器转发request,并等待请求返回。那么,在等待期间,这个处理的worker不会这么傻等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是它就去休息了,此时,如果再有request进来,它就可以很快再按这种方式处理。而一旦后端服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。
由于nginx的的这个工作性质决定了每个请求大部分的生命都是在网络传输中,所以实际上花费在nginx 服务器上的时间并不多,这就是它几进程就能解决高并发的秘密所在。

3、已知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(需要占用一个端口,更稳定,如:127.0.0.1:9000),追求高性能就是Unix Socket(不需要占用端口,更快,但可靠性不如TCP的方式)。

4、nginx和Apache的区别?

两者最核心的区别在于apache是同步多进程模型,一个request对应一个进程,而nginx是异步的,多个连接(万级别)可以对应一个进程。

一般来说,需要性能的web服务,用nginx,如果不需要性能只求稳定,更考虑Apache,后者的各种模块实现的比前者好很多,epoll网络IO模型是nginx处理性能高的根本,但并不是所有情况下epoll大获全胜的,如果本身提供静态服务的只有几个文件,apache的select模型或许比epoll更高性能。当然,这只是一个假设,真正还需要实测了再说。

更通用的方案是,前端nginx抗并发,后端apache集群,配合起来会更好。

5、nginx的调度算法有哪些?

  • sticky:通过nginx-sticky模块,来实现cookie黏贴的方式将来自同一个客户端的请求发送到同一个后端服务器上处理,这样一定程度上可以解决多个后端服务器的session会话同步的问题;
  • round-robin(RR):轮询,每个请求按时间顺序依次分配到不同的后端服务器,如果后端某台服务器死机,自动剔除故障系统,使用户访问不受影响;
  • weight:轮询权重,weight的值越大分配到的访问概率就越高,主要用于后端每台服务器性能不均衡的情况下,或者仅仅为在主从的情况下设置不同的权重,达到合理有效的利用主机资源。
  • least_conn:请求被发送到当前活跃连接最少的realserver上,会考虑到weight的值;
  • ip_hash:每个请求按照IP的哈希结果分配,使来自同一个IP的访客固定访问后端服务器,可以有效的解决动态网页存在的session共享问题。
  • fair:比weight、ip_hash更加智能的负载均衡算法,fair算法可以根据页面的大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,相应时间短的优先分配。nginx本身不支持fair,如果需要使用这种调度算法,则必须安装upstream_fair模块。
  • url_hash:按访问的URL的哈希结果来分配请求,使每个URL定向到后端服务器,可以进一步提高后端缓存服务器的效率。同样,nginx本身不支持url_hash,如果需要这种调度算法,则必须安装nginx的hash软件包。

6、nginx负载均衡调度状态

在nginx upstream模块中,可以设定每台后端服务器在负载均衡调度中的状态。

常用的状态有:

  • down:表示当前的server暂时不参与负载均衡;
  • backup:预留的备份机器。当其他所有的非backup机器出现故障或者繁忙的时候,才会请求backup机器,因此这台机器的访问压力最低;
  • max_fails:允许请求失败的次数,默认为1,当超过最大次数时,返回proxy_next_upstraem模块定义的错误;
  • fail_timeout:请求失败超时时间,在经历了max_fails次失败后,暂停服务的时间。max_fails和fail_timeout可以一起使用。

7、如何查看nginx已添加的模块?如果需要添加某个模块,应该如何实现?

查看已添加的模块:nginx -V;
如果需要添加某个模块,需要将工作目录切换至nginx的源码包中,执行“nginx -V”命令查看之前配置时的选项进行复制,然后增加需要添加的模块配置项,进行配置并编译,将新生成的nginx命令覆盖掉原有的nginx命令,然后重载nginx服务,即可实现在线添加模块。

8、可以从哪些方面来优化nginx服务?

  • 配置nginx的proxy缓存;
  • 对静态页面开启压缩功能,如br压缩或者gzip压缩;
  • 调整nginx运行工作进程个数,最多开启8个,8个以上话性能就不会再提升了,而且稳定性变得更低,所以8个足够用了;
  • 调整nginx运行CPU的亲和力;
  • 修改nginx最多可打开的文件数,若超过系统限制的最多打开文件数(ulimit -n命令查看系统的最多打开文件数),还需要修改系统默认的文件数;
  • 修改单个worker的最大连接数;
  • 开启高效传输;
  • 设置连接超时时间,以便保护服务器资源,因为建立连接也是需要消耗资源的;
  • 优化fastCGI的一个超时时间,也可以根据实际情况对其配置缓存动态页面;
  • expires缓存调优,主要针对图片、css、js等元素更改较少的情况下使用。
  • 配置防盗链;
  • 优化内核参数,如进程可以同时打开的最大句柄数;开启tcp重用机制,以便允许TIME_WAIT sockets重新用于新的TCP连接....还有好多,记不住。