如果按照正常流程安装nginx,即:
1、解压 tar -zxf nginx.zip.gz; 2、安装 ./configure 3、make && make install那么nginx的conf、html、logs、sbin目录就会默认安装到/usr/local/nginx/sbin目录下。如果想把这些目录安装到nginx的根目录下,那么在执行configure的时候应该这样子:
./configure --prefix=/home/work/yournginx/安装好之后启动nginx,如果遇见这个错误
nginx:[emerg] the "ssl" parameter requires ngx_http_ssl_module in /home/openuser/nginx-1.16.0/conf/nginx.conf:96说明我们的nginx缺少http_ssl_module模块,需要在已安装的nginx中添加ssl模块。
查看nginx中已安装的模块:
/sbin/nginx -V进入nginx源码包目录,运行:
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module配置完成后,运行make命令。注意:如果我们继续执行make install就会把之前的配置给覆盖掉,我们这里是新增而不是覆盖。
替换之前先备份:
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak停止nginx服务;
将刚刚编译好的nginx覆盖掉原有的nginx:
cp ./objs/nginx /usr/local/nginx/sbin/然后启动nginx,仍可以通过命令查看是否已经加入成功。
在linux上删除nginx,步骤如下:
切换到root权限,进入根目录,执行命令 find / -name nginx*,把nginx相关的文件全部查出来把查出来的nginx文件删掉后再重新解压nginx的安装包然后安装在安装时执行命名./configure --prefix=/你要安装的nginx目录 --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-stream,后面这些都是要顺带安装的模块,由于不清楚这个规定,在linux上安装了nginx后发现始终启动不了,报这个错误:
nginx:[emerg] bind() to 0.0.0.0.80 failed(13:permission denied)把nginx.conf的监听端口改为大于1024的即可,因为1024以下的端口只有root用户有权限。谨记
在安装的时候,还发现如果同一台服务器已经安装了不同版本的nginx 了,那么再次安装会失败,我的linux版本为3.10.0-514.el7.x86_64。sbin目录都没有,应该需要先卸载旧的再安装新的,待测试。
我们在修改完nginx.conf之后,执行nginx -s reload就可以使修改的配置生效,这就是nginx的热部署,所谓热部署,就是修改配置文件后不需要stop Nginx,不需要中断请求,就能让配置文件生效。那么nginx是具体如何做到的,有以下两种方案:
方案一:修改配置文件nginx.conf之后,主进程负责推送给worker进程更新配置信息,worker进程收到信息后,更新进程内部的线程信息。
方案二:修改配置文件后,重新生成新的worker进程,这些新的worker进程会以新的配置进行请求的处理,而且新的请求必须给新的worker进程,至于老的worker进程,等把以前的请求处理完毕,kill即可。
而nginx就是采用的方案二来达到热部署的。
nginx的worker进程个数与CPU个数绑定,worker进程内部包含一个线程高效回环处理请求,这的确有助于效率,但是不够。要同时处理这么多请求,要知道有的请求需要发生IO,可能需要很长时间,如果等着会影响worker的效率。
nginx采用了Linux的epoll模型,epoll模型基于事件驱动机制。它可以监控多个事件是否准备完毕,如果ok,那么放入epoll队列中,这个过程是异步的,worker只需要从epoll队列循环处理即可。
简单的说,如果一个server采用一个进程(或者线程)负责一个request的方式,那么进程数就是并发数,显而易见,会有很多进程在处理request的时候处于等待状态,等待什么呢?等待网络传输,而Nginx正是利用了这段等待的时间,每进来一个请求,会有一个worker进程去处理,但不是全程不停歇地处理,在遇到可能发生阻塞的地方,比如服务器转发请求等,那么这个worker进程不会傻等着,会注册一个事件:如果upstream返回了告诉我一声,我接着干,于是这个worker就去休息了,此时如果有新的request进来,那么这个worker可以立马去处理,而一旦上游服务器返回了,这个worker才会来接手,这个request才会接着往下走。这就是Nginx基于事件模型,
nginx既然作为入口网关,如果出现单点问题,显然是不可接受的。
我们可以采用nginx+keepalived实现高可用。keepalived是一个高可用解决方案,主要用来防止服务器的单点发生故障,可以通过和nginx配合来实现web服务的高可用。
nginx+keepalived配合思路:请求先通过keepalived(虚拟ip),keepalived监控nginx的状态,可通过一个脚本定期检查nginx进程状态,进行权重变化,从而实现nginx故障切换。
Nginx真正处理请求业务的是Worker之下的线程。worker进程中有一个ngx_worker_process_cycle()函数,执行无限循环,不断处理收到的来自客户端的请求,并进行处理,直到整个Nginx服务被停止。
worker 进程中,ngx_worker_process_cycle()函数就是这个无限循环的处理函数。在这个函数中,一个请求的简单处理流程如下:
操作系统提供的机制(例如 epoll, kqueue 等)产生相关的事件。
接收和处理这些事件,如是接收到数据,则产生更高层的 request 对象。
处理 request 的 header 和 body。
产生响应,并发送回客户端。
完成 request 的处理。
重新初始化定时器及其他事件。
首先,master进程会根据nginx.conf配置来listen的ip和port,建立网络socket fd,然后fork出多个具有相同socket fd的worker进程,这时候有多个worker进程都在监听相同的socket fd,这意味着当有一个请求进来时,所有的worker进程都会感知到,会尝试去注册listen的fd事件,这就叫惊群效应,为了避免不必要的资源占用,nginx中实现了一个互斥锁,只有获取到这个锁才能去注册读事件。最后,监听成功的worker进程,读取请求,解析处理,响应数据返回给客户端,断开连接,结束,一个request请求就完成了。
进程模型的处理方式带来的一些好处就是,进程之间是独立的,一个进程挂了不会影响其他进程的处理,独立进程也不需要锁机制,这样子能提高效率,而且开发调试也容易。
但是多进程模型+异步非阻塞模型(IO多路复用模型epoll)才是最佳解决方案,单纯的多进程模型无法处理高并发的情况。
worker进程会竞争客户端的连接请求,这种方式可能会带来一个问题,就是所有的请求可能都会被一个或者少数worker进程给获取了,导致其他worker进程无事可做。这种状态可能还会导致无法及时响应连接而丢弃掉本有能力处理的请求。这种不公平的现象是需要避免的。
很对这种现象,nginx采用了一个是否打开accept_mutex选项的值,ngx_accept_disabled标志控制一个worker进程是否需要去竞争获取accept_mutex选项,进而获取accept事件。ngx_accept_disabled变量在ngx_event_accept函数中计算,如果ngx_accept_disabled大于0(连接数达到这个worker进程最大连接数的7/8时,ngx_accept_disabled就会大于0),就表示该进程接受的连接数过多,就会放弃一次争抢accept mutex的机会,同时将自己减1,然后继续处理已有连接。
Apache:创建多个线程或进程,每个进程或线程都会为其分配CPU和内存,如果并发过大会榨干服务器资源
Nginx:采用单线程来异步非阻塞处理请求,不会为每个请求分配cpu和内存资源,节省大量资源,同时也节省了大量的cpu上下文切换,才使得Nginx支持更高的并发。
Netty、Redis基本采用同样的思路。
动态资源、静态资源分离,是让动态网站里的动态网页根据一定规则把经常变的资源和不变的资源分开,动静资源拆分好了后我们就可以根据静态资源的特点做缓存操作,这就是网站静态化的核心思路。
在我们的软件开发中,有些请求是需要后台处理的,有些请求是不需要经过后台处理的,这些不需要后台处理的文件成为静态文件、否则动态文件。
因此我们后台处理可以忽略静态文件,减少后台的请求次数,提高资源的响应速度,将静态资源交给nginx,动态资源则交给tomcat。当然现在阿里云的CDN服务已经很成熟,主流的做法,是把静态资源缓存到CDN服务中,从而提升访问速度。
相比本地的 Nginx 来说,CDN 服务器由于在国内有更多的节点,可以实现用户的就近访问。并且,CDN 服务可以提供更大的带宽,不像我们自己的应用服务,提供的带宽是有限的。CDN,即内容分发网络。其目的是,通过在现有的Internet中,增加一层新的网络架构,将网站的内容发布到最接近用户的网络边缘,使用户可就近取得所需的内容,提高用户访问网站的速度。
一般来说,现在CDN服务比较大众,基本所有公司都会用CDN服务。https://blog.csdn.net/LJFPHP/article/details/81566992
1.轮询(默认)round——robin
2.IP哈希 ip_hash,每个请求按访问的ip的hash结果分配,这样每个访客固定去访问一个后端服务器,可以解决session共享问题,然后实际情况中不这样去解决session共享问题
3.最少连接,下一个请求将被分配到活动连接数量最少的服务器。
4.另外,我们还可以配置每一个后端节点在负载均衡时的其它配置:
weight=1; # (weight 默认为1.weight越大,负载的权重就越大) down; # (down 表示单前的server暂时不参与负载) backup; # (其它所有的非backup机器down或者忙的时候,请求backup机器) max_fails=1; # 允许请求失败的次数默认为 1 。当超过最大次数时,返回 proxy_next_upstream 模块定义的错误 fail_timeout=30; # max_fails 次失败后,暂停的时间