LB Cluster:
提升系统容量的方式:
scale up:向上扩展
scale out:向外扩展
LVS工作在内核中,本身的数量不受套接字数量限制,利用LVS做调度器,优化得当的话,并发数量可以到达300万,但是LVS是工作在传输层,所以LVS对应用层的报文处理是无能为力。
LVS根据用户请求的IP:PORT来进行调度的,所以并不能区别请求内容到底是动态还是静态的,因为LVS不具有对应用层操作的能力,
要判断请求内容是静态还是动态,可以根据请求内容的后缀名来判断,因此使用LVS负载均衡调度就无效了。
就需要某种服务工作在应用层,实现负载均衡,将用户请求调度至后端多个RS,这种服务器架构就可以实现动态内容和静态内容的分离。但必须工作在应用层。
http协议的反向代理为例,反向代理是一个可以工作在用户空间的应用程序。当用户请求到达节点A时,程序B负责接收用户请求,程序B自己要监听在80端口上,因此程序B要相当于一个正常的web服务器。当用户请求到达节点A,经由PREROUTING链而后经由路由送往INPUT链,最终送往用户空间。因为程序B时监听在80端口的,所以用户请求就由内核送到了用户空间中的程序B,程序B本来就是http协议的服务器,所以程序B可以工作在http协议,能分析每一个请求,能解码http协议的请求报文的首部,能封装响应首部,所以从本质上来讲程序B是一个web服务器,但响应报文的内容并不在本地(即节点A)提供。当用户请求报文到达程序B后,程序B分析完用户请求后,程序B知道用户请求的是什么,也知道到哪里去找请求的内容,所以由程序B扮演为web服务的客户端把请求发送至后端某一个主机,后端主机的响应报文经过层层拆封(各种首部都会被拆掉,包括http首部,得到报文里面的内容),最终程序B会得到想i也能够报文的内容,并由程序B再把内容封装成响应报文,响应给客户端。所以在客户端看来就是由节点A响应的。
后端节点通常被称为upstream server即上游服务器,当后端节点有多个,代理模块(程序B)向后端多个upstream server发请求时,会从中抽取一个节点来响应,到底抽取哪一个,也可以根据反向代理模块中所指定的调度方法来实现。
由于节点A的web服务器(即程序B)是工作在应用层的,所以可以清楚的取到用户所请求的URL,URL所标识的都是互联网上每一个特定资源的请求,而每一个资源也通过后缀名来判断内容类型的。内容类型分动态内容(.php、.jsp、.do等)和静态内容(.txt、.jpg等),所以就可以实现动态和静态内容的分离。
假如后端服务器分为两组,静态内容服务器和动态内容服务器。所以节点A中的程序B在实现反向代理时,可以通过判断文件的后缀名,再决定将请求调度至哪个类型的集群。由于无论静态内容服务器和动态内容服务器都不止一个主机,所以程序B还可以基于负载均衡的方式对后端不同类型的服务器组进行调度。
对静态内容做负载均衡时就不必考虑会话保持的问题,因为静态内容是不会处理会话的(当浏览一个电商网站时,往购物车添加商品时,一些列的处理操作都是由程序处理的),所以把用户的请求调度至静态内容服务器集群时,直接做轮询调度或者加权轮询就可以。对于动态内容的调度需要考虑session保持。
缓存之所以比较快是因为缓存是键值存储,key是URL,value是URL对应的资源
反向代理服务器为了提高效率,通常都会加一个缓存服务器
网站的小规模站点架构的实现方案
前端负载均衡器,专门负责调度,这里动态内容服务器和静态服务器实现分离了。动态内容直接调度至动态服务器组,静态内容要调度至后端缓存服务器组,实际上这些缓存服务器是静态内容服务器的反向代理,当nginx(前端负载均衡器)到对应的缓存服务器组(是varnish或squid)请求内容时,如果缓存服务器本地有就直接返回,如果没有的话,缓存服务器就当作反向代理,把请求发送至后端的静态内容服务器组。静态内容服务器不止一个,所以缓存服务器组向后反向代理时依然要做负载均衡,即缓存服务器组中的每台服务器都是通过负载均衡的方式向后端静态服务器组实现负载均衡的功能。
负载均衡器要能检查动态服务器组和缓存服务器组中每个服务器的健康状态,同时缓存服务器组要能检查后端静态内容服务器组的主机的健康状态。
如果利用LVS做调度器的话,那么所有的用户请求都是从客户端与服务器端建立的。如果利用nginx做代理服务器的话,那么客户端的请求到达代理服务器就终止了,有代理服务器重新启动一个本机的客户端进程去后端的主机取内容。代理服务器取得结果后,把此结果当作本地的结果,封装成响应报文响应给客户端,实现了一手托两家。反向代理是工作在应用层的,所以无论是接收前端的请求还是向后端的服务器请求内容都要用到套接字,因为代理服务器要基于内核中的套接字的方式进行通信,就必须向内核注册一个套接字文件(即向内核申请占用一个端口)。
所以nginx对前端的并发能力不是65535个,因为其他服务要占用一些,另外代理服务器除了响应客户端的请求外还要去请求后端服务器,所以并发能力还要除以2。
鉴于上述情况,可以对代理服务器做负载均衡(互为备份又互为高可用),然后利用DNS做域名解析轮询。如果并发量更大,即可在代理服务器集群前加LVS调度器(LVS做高可用)做负载均衡即可解决。
nginx反向代理、haproxy、使用keepalived负载均衡haproxy/nginx反向代理的模式或者ipvs
master进程(即主进程)负责装载配置文件(Load configuration),启动worker进程(Launch workers)、支持非宕机(平滑)的升级模式(Non-stop upgrade)
各worker进程内部装载ht_core、ht_upstream、ht_proxy、ht_fastcgi实现各种工作
ht_core: http协议的核心模块
ht_upstream: 负载均衡模块
ht_proxy: 代理模块
ht_fastcgi: fastcgi的代理模块,能够基于fastcgi协议将用户的动态内容请求转交至后台的动态内容服务器(Application server)
一个线程响应N个请求,就要实现复用 -->复用器(Multiplexing via kevent/epoll/selsect),基于复用器或事件驱动的方式实现单进程/线程响应多个请求。
nginx的核心特点:时间驱动、异步、非阻塞 所有进程仅含有一个线程(单线程模式)
master是以root用户运行,其他都是以普通用户运行
主进程master主要负责的工作:
1、读取并验证配置文件中的配置信息;
2、创建、绑定和关闭套接字;
3、启动、终止以及维护各worker进程,保证一定数量的worker进程在工作;
4、平滑的更新nginx;
5、控制非宕机的版本更新;
(nginx在非宕机的模式下更新:比如worker进程是老版(1.4),但可以先让master从版本1.4升级为1.6,而后版本1.6负责维护版本1.4worker进程,当有新进程来时,版本1.6(master)会生成版本为1.6的worker进行进行响应。原来的版本为1.4的worker进程在用户请求全部退出后,这个1.4的worker进程就被杀死,而后在启动1.6的worker进程,这就是平滑的升级);
6、实现平滑日志滚动;
worker进程的主要功能:
1、响应用户请求;
2、从本地缓存检索内容,如果命中,则从本地缓存返回,否则后端服务器加载内容;
3、把用户请求代理至后端服务器;
Cache loader的功能:
1、检查缓存中存储的缓存对象;
2、使用缓存元数据建立内存数据库(比如KV存储也有元数据和数据,K放在内存中,K指向的V是放在磁盘上的);
Cache manager的功能:
缓存的失效即过期检验以及清理操作
Nginx的配置:
main:定义全局属性
event:定义IO模型的相关操作,
http:定义如何处理http请求
http {
directive
server {
listen
server_name
location {
if {
}
}
}
server {
}
}