Nginx学习总结
Nginx概述及注意事项
nginx是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器
目前Nginx使用简单的轮巡(polling)算法来实现负载均衡,所以无法做基本链接计数的负载均衡。
目前官方 Nginx 并不支持 Windows,您只能在包括 Linux、UNIX、BSD 系统下安装和使用;
Nginx 本身只是一个 HTTP 和反向代理服务器,它无法像 Apache 一样通过安装各种模块来支持不同的页面脚本,例如 PHP、CGI 等;
Nginx 支持简单的负载均衡和容错;
支持作为基本 HTTP 服务器的功能,例如日志、压缩、Byte ranges、Chunked respons
es、SSL、虚拟主机等等,应有尽有。
Nginx优势
在高连接并发的情况下,Nginx是Apache服务器不错的替代品:Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一。能够支持高达 50,000 个并发连接数的响应,感谢Nginx为我们选择了 epoll and kqueue作为开发模型。
Nginx作为负载均衡服务器:Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务,也可以支持作为 HTTP代理服务器对外进行服务。Nginx采用C进行编写,不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多。
作为邮件代理服务器:Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器),Last. fm 描述了成功并且美妙的使用经验。
Nginx 是一个安装非常的简单,配置文件非常简洁(还能够支持perl语法),Bugs非常少的服务器:Nginx 启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。
Nginx等单线程服务器设计原理与性能优势 
Nginx是以单线程为基础的,nginx通过异步IO来解决主线程阻塞的问题。windows上有IOCP(完成端口,对于一部IO包装的比较多,内部实现时用cpu个数的线程进行事件处理,他会通知你你给定的异步读写已经完成了),linux上有epool(一个纯事件通知接口,他会通知你可以读或者可以写了),如果将所有的请求简化为阻塞操作和非阻塞操作问题就简单了,所有需要阻塞请求的部分全部由epool触发相应事件,非阻塞(处理耗时很短)部分用主线程一直执行,直到遇到阻塞部分就停止,交由阻塞部分监听异步完成事件,这样就构成了事件驱动模型。
    很多人认为函数的处理会阻塞主线程,事实是他的处理时间占用很短,做100万次for循环说不定比局域网经过一次网络访问的时间还要短,理解了这点就不难理解了,如果说你的服务器每秒钟能处理1万个请求,那么在处理功能函数上(比如解析协议,操作、输出等等)顶多也就占用0.1-0.3秒,剩下的时间都是耗时在了网络阻塞上,耗时在了事件发生上了,既然如此,把操作部分独立分出来用多线程执行又有什么意义呢?对于公网就更不用说了,网络等IO阻塞才是影响服务器的主要因素,是那块短了的板。
      对于网络的IO,IOCP 、epool等事件通知机制就解决了这个问题,性能上由于是阻塞的,所以还不如直接accept等快,但是对于网络延时很严重的情况下性能反而显得更好,因为他们可以处理大量的连接而不使性能下降很厉害,如果值直接阻塞能连接处理1000个的话,epool等就可以同时处理3-5万个,所以实际的应用价值要大得多。剩下的部分就是处理事件发生后的事情上面,我前面的文章已经作了说明,在此不再重复,Nginx 、lighttpd等都是基于这类模型开发的。
Nginx 连接处理
Ngnix使用hash表来协助完成请求的快速处理。考虑到保存键及其值的hash表存储单元的大小不至于超出设定参数(hash bucket size),在启动和每次重新配置时,Nginx为hash表选择尽可能小的尺寸。直到hash表超过参数(hash max size)的大小才重新进行选择. 对于大多数hash表都有指令来修改这些参数。例如,保存服务器名字的hash表是由指令server_names_hash_max_size 和server_names_hash_bucket_size所控制的。参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查hash表键值成为可能。如果hash bucket size等于
一路处理器缓存的大小,那么在查键的时候,最坏的情况下在内存中查的次数为2。第一次是确定存储单元的地址,第二次是在存储单元中查键值。因此,如果Nginx给出需要增大hash max size 或hash bucket size的提示,那么首要的是增大前一个参数的大小.
Nginx支持如下处理连接的方法(I/O复用方法),这些方法可以通过use指令指定。
select- 标准方法。如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数--with-select_module 和--without-select_module 来启用或禁用这个模块。         
poll- 标准方法。如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数--with-poll_module 和--without-poll_module 来启用或禁用这个模块。
kqueue- 高效的方法,使用于FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和MacOS X. 使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。
epoll- 高效的方法,使用于Linux内核2.6版本及以后的系统。在某些发行版本中,如SuSE 8.2, 有让2.4版本的内核支持epoll的补丁。
rtsig- 可执行的实时信号,使用于Linux内核版本2.2.19以后的系统。默认情况下整个系统中不能出现大于1024个POSIX实时(排队)信号。这种情况对于高负载的服务器来说是低效的;所以有必要通过调节内核参数/proc/sys/kernel/rtsig-max 来增加队列的大小。可是从Linux内核版本2.6.6-mm2开始,这个参数就不再使用了,并且对于每个进程有一个独立的信号队列,这个队列的大小可以用RLIMIT_SIGPENDING 参数调节。当这个队列过于拥塞,Nginx就放弃它并且开始使用poll 方法来处理连接直到恢复正常。
/dev/poll- 高效的方法,使用于Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ 和Tru64 UNIX 5.1A+.
eventport- 高效的方法,使用于Solaris 10. 为了防止出现内核崩溃的问题,有必要安装这个安全补丁。
Nginx的内存池管理分析
    Nginx的内存管理,主要是用来实现防止内存泄露,和内存碎片,而并没有真正的预先分配获得大量内存。因此实际上和普通意义上的内存池有一定的区别。预先分配的内存通常
也就是1块16K大小的内存快,大内存直接使用malloc分配,16k*n小内存块中,用来处理各种小的内存资源需求,并且不是放,对一个连接来说,连接完成后统一释放,既防止了小内存碎片,也防止了泄露。由于系统操作中,分配小块内存的频率远远高于分配大块内存的频率,因此实际大大较小了malloc的系统调用,同时实现也比较简练,也不用向通常的内存池管理一样,多任务环境下,还需要考虑加锁的问题。而锁将大大降低程序的性能。
      1)内存池就是一个单链表
      2)拥有独立的多个内存池,而不是全局唯一的内存池,比如针对每个新建立的连接,创建一个新的内存池,并在连接结束后,一次性释放资源
      3)内存池本身分配小内存,防止碎片,大内存直接使用malloc,多个大内存构成单链表,并挂到pool的large成员
      4)每个连接处理,针对一些需要在连接关闭的时候需要做清理的工作,可以在pool中注册回调处理函数,比如unlink文件,关闭文件等操作,防止系统资源,如文件句柄的泄漏!   
      5)小内存一旦分配使用,直到整个池释放,才被回收,这样管理简单,最重要的是效率高,没有碎片,不用来回的在小内存中管理,而且小内存块可以被完整使用!(16k,应该可以应付很多次调用了!通常一个连接处理,能用到多少个16K的内存块呢?比如复杂的邮件应用?)
      6)大内存,可以通过调用释放函数,在摧毁池之前,提前回收!
      Nginx管理内存的宗旨,就是:
      1)高效,不在小内存上花费太多时间
      2)没有碎片
      3)简单,只用到单链表,不引入复杂的操作
      4)隔离设计,每个连接单独一个池,方便回收,防止泄露,针对单连接,调用destroy可以完全放心没有内存的泄漏,很适合网络应用程序的开发。
Nginx中常用的函数
内存分配函数
        ngx_palloc(ngx_pool_t *pool, size_t size)
        ngx_memalign,该函数没有使用,而用宏实现了内存对齐
        #define ngx_align_ptr(p, a) \
            (u_char *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))
内存结构体:
        struct ngx_pool_s {
              u_char *last;记录上次的位置(在内存块中,上次的位置) nginx和apache区别
              u_char *end;(记录内存块最后的位置)
              ngx_pool_t          *current;
              ngx_chain_t        *chain;//buf结构体的单链表组成,该buf可以使mmap内存(ngx_write_chain_to_temp_file,可以实现多块内存同时写文件操作)
              ngx_pool_t          *next;
              ngx_pool_large_t        *large;//大内存的分配,一个单链表
              ngx_pool_cleanup_t        *cleanup;//针对有需要清理的数据,如删除文件等等,将之
              ngx_log_t                        *log;

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。