作用
1.负载均衡器
2.转发请求
3.缓存静态资源
什么是共享内存?
首先,共享内存,是所有进程都可以访问。是进程通信的一种方法。
其次,就是磁盘文件和内存的映射。
这里的内存是共享内存。
但是,在NGINX里,是没有用到磁盘文件,而只用到共享内存。
NGINX的共享内存,主要是被主进程和从进程共同使用。
主进程是master进程,从进程是work进程。
主进程,主要干几件事情:
1.管理所有/全局东西
2.创建从进程
fork方法
3.申请共享内存
Linux有专门的申请共享内存方法,其实就是磁盘文件和内存映射的方法。叫map什么的。
从进程,主要作用就是,处理请求。
线程
NGINX的进程都是单线程,不是多线程。
linux epoll 多路复用 基于注册事件机制 请求连接队列 异步非阻塞
消费队列和事件队列的区别?
不同点
一个是数据,一个是操作,都有写读。只不过一个是是写数据,一个是写操作。数据是写到集合里,比如队列。操作也是写到一个数据结构里,操作其实也只是一个对象,只不过概念有一点不一样而已。比如,消费队列是叫消费者需要订阅主题/消费队列,生产者向消息队列写数据。而事件是消费者需要先注册一个什么事件,比如TCP socket里的连接事件,写数据事件,,读数据事件。
相同点
都有生产者和消费者,都是一个生产者生产数据/操作,一个消费者消费数据/操作。
TCP连接细节
1.半连接
Syn
2.连接成功
Ack
3.关闭
Fin
4.窗口抖动?
这他妈什么破名字
5.backlog
队列最大数量,分别在各个不同的状态



具体来说,就是客户端实际上是和操作系统内核打交道,一直到最终内核创建连接,并且把连接放到连接集合,即accept队列里。
NGINX,包括其他的所有的服务器软件,都只是从操作系统内核的连接队列即accept队列里取一个已经创建好的连接对象而已。
操作系统内核有两个集合,一个是未完成的连接,即刚进来的连接,新的连接,所谓未完成,指的是握手的这个流程没有完成。
一个是已经完成的连接,即完成握手的连接。
握手其实也就是请求,响应。按理来说,应该只有两步。
但是,实际情况是,更复杂一点。多了一个确认的过程。
本来应该是
1.客户端请求
2.服务器确认收到请求,处理数据
3.服务器返回数据
实际是
1.客户端请求
发送请求
2.服务器确认收到请求
把确认发给客户端。
你收到了请求,要告诉别人即客户端,别人即客户端才知道你服务器收到了请求。
3.客户端确认服务器收到了请求
和2同理,客户端收到了服务器的确认收到客户端请求,但是客户端也需要把这个确认告诉服务器。
4.服务器,即内核,把新连接放到已完成握手的队列里面
实际上,就是多了一个互相确认的过程,这个确认是指,还有点不一样。
服务器的确认是,收到了客户端的请求。
客户端的确认是,服务器收到了可客户端的请求。
内存池
每个http请求,分配一个内存池。 统一申请,统一释放。
六、内存池的设计 为了减少避免出现内存碎片、减少向操作系统申请内存的次数、降低各个模块的开发复杂度,Nginx采用了简单的内存池(统一申请,统一释放)。比如为每个http请求分配一个内存池,请求结束时销毁整个内存池。
c本来是需要程序员自己分配内存,自己释放内存,这样有两个问题,麻烦,而且还容易忘。基于此,JVM的垃圾回收就是为了解决这个问题的,就是内存释放的问题,把这个工作自动化,而不需要程序员人为的处理这个跟具体业务没什么关系的操作。至于分配内存,这个肯定是需要程序员手动创建的,因为创建对象,是程序员要不要创建和创建什么对象。NGINX里的内存池,也是为了解决自动释放内存的问题,具体是每个请求和每个连接都有自己的独立的线程池。这样的目的是,当请求/连接销毁的时候,即生命周期结束的时候,那么内存池也立即释放,这样就不会出现线程池申请之后,就一直占着内存的情况。
linux单机进程之间通信的各种方式
信号是其中的一种方式。
回调函数
所有的回调函数,都是基于阻塞队列,而阻塞队列的调用者是操作系统,就是有数据来了,就给消费者。
web服务器
按时间顺序
1.Apache
C
2.Tomcat
Java
3.NGINX
C
高性能
现在市场占用率第二名,超过Tomcat
自旋锁
是什么
顾名思义,是旋转多次获取锁,就是循环多次获取锁。而不是,在那里等待别人释放。
代码
代码如何实现,来一段代码。
锁的使用时间长短
因为要循环多次获取锁,所以适合锁占用时间短的情况。否则,锁一直被别的线程占用,那么自旋锁线程一直在长时间空转,浪费CPU。
不是获取不到锁,就必须要等待吗?为什么还能继续循环执行获取锁。
自旋锁,适合核心业务处理代码,因为必须要尽快主动获取锁,不能只是光等待。

信号量
作用
同步。
代码
信号
作用
进程之间的通信。主要是短数据,比如01,就是一个数字,一个进程通知一个进程做什么事情。
代码
与apache区别
2.apache 每个请求一个线程 和tomcat一样
master和worker进程的区别?
1.接受请求
master
2.处理请求
worker //worker由master创建fork
为什么要分成一个master一个worker两个进程? 各司其职
好处? 提高处理速度
两个进程之间如何通信? master对work进程采用信号进行控制。
负载均衡算法
nginx 的 upstream目前支持 4 种方式的分配
1)、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
2)、weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
2)、ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。 //最佳实践推荐,因为可以解决session的问题 //支付系统,没有在程序层面处理session的问题,所以同一个用户每次请求的tomcat服务器是同一个tomcat。如果ip经常改变怎么办?那就只能重新登录,不过一般很少出现这种情况。//hashcode具体计算方式?ip——》hashcode——》hashcode/机器数量 取余数,因为除数和被除数的值固定,所以同一个用户ip的请求的tomcat是同一个。
3)、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
4)、url_hash(第三方)
nginx内置策略包含加权轮询和ip hash
加权轮询算法分为先深搜索和先广搜索,那么nginx采用的是先深搜索算法,即将首先将请求都分给高权重的机器,直到该机器的权值降到了比其他机器低,才开始将请求分给下一个高权重的机器;
L7 负载均衡器?
待补充
C10K
请解释什么是C10K问题? C10K问题是指无法同时处理大量客户端(10,000)的网络套接字。
惊群
8、如何解决惊群现象?
惊群是多个子进程在同一时刻监听同一个端口引起的;
Nginx解决方法:同一个时刻只能有唯一一个worker子进程监听web端口,此时新连接事件只能唤醒唯一正在监听端口的worker子进程。
采用锁,互斥量实现!!
有哪些核心模块?
1.核心
2.配置
3.http
4.socket
一、Nginx优秀模块 模块设计:
高度模块化设计,除了少量核心代码,其他一切接模块。官方Nginx共有五大类型模块:核心模块、配置模块、事件模块、HTTP模块、mail模块。
要注意的是:nginx的模块是静态的,添加和删除模块都要对nginx进行重新编译,这一点与Apache的动态模块完全不同。
参考
陶辉 nginx