如何对 docker 容器里的 nginx 进行热更新
Nginx ("engine x") 是一个高性能的 HTTP 和 反向 服务器软件,也是一个 IMAP/POP3/SMTP 服务器。 Nginx 是由 Igor Sysoev 为访问量第二的 Rambler.ru 站点开发的,它已经在该站点运行超过两年半了。
nginx热更新原理 nginx升级版本
Nginx:基本原理篇
Nginx的IO通常使用epoll,epoll函数使用了I/O复用模型。与I/O阻塞模型比较,I/O复用模型的优势在于可以同时等待多个(而不只是一个)套接字描述符就绪。Nginx的epoll工作流程如下:
2 . 当一个client连接到来时,所有accept的work进程都会受到通知,但只有一个进程可以accept成功,其它的则会accept失败,Nginx提供了一把共享锁accept_mutex来保证同一时刻只有一个work进程在accept连接,从而解决惊群问题
惊群现象:惊群效应就是当一个fd的事件被触发时,所有等待这个fd的线程或进程都被唤醒。一般都是socket的accept()会导致惊群,很多个进程都block在server socket的accept(),一但有客户端进来,所有进程的accept()都会返回,但是只有一个进程会读到数据,就是惊群。
Nginx 采用accept-mutex来解决惊群问题:当一个请求到达的时候,只有竞争到锁的worker进程才会惊醒处理请求,其他进程会继续等待,结合 timer_solution 配置的的超时时间继续尝试获取accept-mutex
I/O 复用接口有select 和 epoll 两种模型,首先介绍一下这两种模型的执行方式:
由于网络响应时间的延迟使得大量TCP连接处于非活跃状态,但调用select()还是会对 所有的socket进行一次线性扫描 ,会
调用一次epoll_wait()获得就绪文件描述符时,返回的并不是实际的描述符,而是一个代表就绪描述符数量的值,拿到这些值去epoll指定的一个数组中依次取得相应数量的文件描述符即可,这里使用内存映射(mmap)技术, 避免了大量文件描述符带来的开销。
在select/poll时代,服务器进程每次都把这100万个连接告诉作系统(从用户态句柄数据结构到内核态),让作系统内核去查询这些套接字上是否有事件发生,轮询完后,再将句柄数据到用户态,让服务器应用程序轮询处理已发生的网络事件,这一过程资源消耗较大,因此,select/poll一般只能处理几千的并发连接。
epoll的设计和实现与select完全不同。epoll通过在Linux内核中申请一个简易的文件系统,把原先的select/poll调用分成了3个部分:
调用epoll_create()建立一个epoll对象(在epoll文件系统中为这个句柄对象分配资源)
调用epoll_ctl向epoll对象中添加这100万个连接的套接字
调用epoll_wait收集发生的事件的连接
只需要在进程启动时建立一个epoll对象,然后在需要的时候向这个epoll对象中添加或者删除连接。同时,epoll_wait的效率也非常高,因为调用epoll_wait时,并没有一股脑的向作系统这100万个连接的句柄数据,内核也不需要去遍历全部的连接。
apache 采用的select模型,nginx采用epoll模型,nginx 处理请求是异步非阻塞的,而apache则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能。在Apache+PHP(prefork)模式下,如果PHP处理慢或者前端压力很大的情况下,很容易出现Apache进程数飙升,从而拒绝服务的现象。
Nginx 常用功能
参考文章:
如何对 docker 容器里的 nginx 进行热更新
如何通过Docker进行容器编排Docker容器运行后,如何进入容器进行作呢?起初我是用SSH。如果只启动一个容器,用SSH还能应付,只需要将容器的22端口映射到本机的一个端口即可。当我启动了五个容器后,每个容器默认是没有配置SSHServer的,安装配置SSHD,映射容器SSH端口,
nginx重载原理
nginx重载原理是:向master进程发送HUP信号(reload命令)、master进程检查配置语法是否正确master进程打开监听端口(在修改配置文件的端口情况下,可能)。
master进程使用新的配置文件启动新的worker子进程,master进程向老的worker子进程发送QUIT信号,旧的worker进程关闭监听句柄,处理完当前连接后关闭进程。
左边绿色的状态是执行nginx -s reload命令之前的状态,按照我个人主机的配置时一个master进程和4个worker子进程。
为了模拟执行nginx -s reload命令后原来的worker进程会处理完请求后再被杀掉,我模拟一个需要很久才能处理完任务并响应的接口。
是的在代码里sleep 15秒,也就是说这个接口响应需要15秒,时间弄长点方便我们来观察中间态,注意,在执行reload命令前请求该接口。
nginx的模块是:
Nginx的模块从结构上分为核心模块、基础模块和第三方模块:
核心模块:HTTP模块、EVENT模块和MAIL模块。
基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块。
第三方模块:HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块。
nginx 缓存机制
Nginx缓存的基本思路
基本思想是利用客户访问的时间局部性原理,对客户已经访问过的内容在Nginx服务器本地建立副本,这样在一段时间内再次访问该数据,就不需要通过Nginx服务器再次向后端服务器发出请求,所以能够减少Nginx服务器与后端服务器之间的网络流量,减轻网络拥塞,同时还能减小数据传输延迟,提高用户访问速度。同时,当后端服务器宕机时,Nginx服务器上的副本资源还能够回应相关的用户请求,这样能够提高后端服务器的鲁棒性。
对于缓存,我们大概会有以下问题:
(1)缓存文件放在哪儿?
(2)缓存的空间大小是否可以限定?
(3)如何指定哪些请求被缓存?
(4)缓存的有效期是多久?
(5)对于某些请求,是否可以不走缓存?
解决这些问题后,nginx的缓存也就基本配置完成了,下面看详细配置过程
开启缓存
要使用缓存,首先要使用 proxy_cache_path 这个指令(必须放在 http 上下文的顶层位置),然后在目标上下文中使用 proxy_cache 指令
配置示例
proxy_cache_path 有两个必填参数,个参数为 缓存目录,第二个参数keys_zone指定缓存名称和占用内存空间的大小(注:示例中的10m是对内存中缓存内容元数据信息大小的限制,如果想限制缓存总量大小,需要用 max_size 参数)
proxy_cache 的参数为之前指定的缓存名称
缓存管理的相关进程
在缓存工作中有两个附加进程:
(1)缓存管理器
定期检查缓存状态,看缓存总量是否超出限制,如果超出,就移除其中少使用的部分
(2)缓存加载器
加载器只在nginx启动后运行一次,把缓存内容的元数据信息加载到内存空间,如果一次性加载全部缓存信息,会大量消耗资源,使nginx在启动后的几分钟里变慢,为避免此问题,有3种加载策略:
loader_threshold – 指定每次加载执行的时间
loader_files – 每次多加载的数量
loader_sleeps – 每次加载的延时
例如:
proxy_cache_path /data/nginx/cache keys_zone=one:10m loader_threshold=300 loader_files=200;
指定缓存哪些请求
nginx默认会缓存所有 get 和 head 方法的请求结果,缓存的key默认使用请求字符串
(1)自定义key
例如 proxy_cache_key " request_uri cookie_nocache arg_comment;
如果任何一个参数值不为空,或者不等于0,nginx就不会查找缓存,直接进行转发
综合示例
nginx 缓存机制
三分钟看懂Nginx服务器的缓存原理和机制
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至836084111@qq.com 举报,一经查实,本站将立刻删除。