- 高性能
- 可扩展性好
- 高可靠
- 热部署
- bsd许可证
反向代理和负载均衡
NGINX的 3个主要应用场景
- 静态资源服务(缓存加速)
- 反向代理(因为又容灾的需求,一定要有负载均衡的功能)
- api服务
传统的 CGI程序,每个请求都要启动一个新的进程,如果 CGI程序执行时间很短,启动进程的开销时间很可能会超过实际执行时间,而在java 的 servlet 中一个请求由一个 java 线程来处理。http请求会和servlet api中的一条线程绑定到一起,以'一对一'的服务方式处理浏览器发来的请求。传统的 java web服务器的线程池容量通常在几十个到两百个之间,在大量请求的情况下,就要使用新的处理方案了。可以搭建集群,由nginx 作反向代理
早期,主要的 CGI 编程语言是使用 perl ,web服务器是通过启动独立进程的方式调用 CGI程序,消耗许多不必要的系统资源,java servlet 则是以线程的方式在 java web容器中调用 servlet,较CGI方式消耗资源更少
以前一般是 CGI程序解析http 请求,处理逻辑业务,并在输出流中构造响应的HTML,这样业务代码和页面语法耦合在一起,难以维护
PHP,asp, 以及jsp的出现就是为了改善这一局面,与 CGI程序输出 HTML页面相反,是开发人员在HTML上嵌入 程序代码,这种模式叫做 服务器页面模式,像PHP,jsp等等。
CGI擅长处理请求信息,而服务器页面擅长构造响应页面,于是发展出来了 mvc模式,
(model+ view+ controller), 控制器接收 http请求,决定调用哪个业务,将业务的数据绑定到哪个视图上。mvc将很好的分离模型与视图,给前后端进行了解耦。
分层的模式 ,隔离上层和下层的直接依赖,上层设计无需考虑下层设计的实现,各层之间只是保持较少的耦合,只要定义好接口,保持接口规范不变,各个层之间的实现可以随意替换和复用。
MVC 模式通常分为 3层, 表现层,业务逻辑层(service),数据源层(DAO), 表现层完成视图展示和用户交互,业务逻辑实现核心逻辑,并且调用 数据源层。 数据源层则是负责数据存储,交换和通信
下面是对称加密算法的一种基本实现
采用异或运算
下面是非对称加密:
可以使用 goAcces 实现一个可视化监控 access 日志,和免费制作一个 ssl证书
Nginx多进程模型(为了保证其高可用性和 高可靠性)
如果使用多线程的话(线程之间是共享同一块地址空间),某一块地址空间导致段错误时,会导致nginx 挂掉
如果 多进程的话 就不会有这样的问题
nginx 进程的结构:
1.maser进程 (负责监控每一个 worker 进程,是否正常工作,是否热部署,是否缓存,由worker进程处理请求)
2.worker 进程 处理请求
3.cache Manager 缓存管理
4. cache loader 缓存载入
进程间的通讯都是 使用共享内存解决的
nginx 具有 CPU亲和性,最好 把 worker 进程的数量和 CPU数量调一致,把 一个 worker 进程和一个 CPU进行绑定,
充分使用CPU核上的缓存,降低缓存失效的命中率
绿色这条线是 select, 随着连接数(句柄数)增加,消耗的时间急速上升,而 epoll并没有随着连接数的变化受到过多的影响,因此 epoll适合这种高并发的场景
select的话比较耗费资源,因为是轮询所有的连接请求来进行处理,而活跃的连接请求就那几个
使用 epoll 性能提高的原因:
高并发连接中,每次处理活跃连接数量占比很小
nginx 的 epoll 用来两种数据类型,链表和红黑树
每次会遍历一个链表,去处理活跃连接和请求
每次 读取或写入的请求操作 会添加到红黑树 的节点(维持着一颗平衡二叉树),因此操作效率(添加修改、删除)是 o(logN) ,十分高效。
每次系统受到(从内核态到用户态只是读一下活跃的请求到一个链表)
redis,nginx 都是 epoll
linux 下 java 的 nio 也是用 的 epoll这一块
多线程来做 服务器会出现 cpu的上下文切换,耗费性能
select不足
1.select需要从用户态将监听的集合拷贝给内核,
2.内核通过轮询的方式查找有事件的文件描述符并返回
3.且文件描述符有上限
4.没有直接告诉我们具体哪个fd有数据,导致需要遍历
https://baijiahao.baidu.com/s?id=1641172494287388070&wfr=spider&for=pc
NGINX 目前是使用的 自旋锁,所有 worker进程协同工作,操作同一块内存
这就是 nginx直接的通讯方式