前言
目前接触的一个服务,它的7层负载均衡使用Nginx,4层使用的是我司自研的弹性负载均衡ELB。
而本文介绍和实战的是工作在4层负载均衡之一的LVS(Linux Virtual Server),权当抛砖引玉,实战是从工作中简化而来。
概念
章文嵩博士在 1998 年 5 月成立了 Linux Virtual Server 的自由软件项目,进行Linux服务器集群的开发工作,并且在 Linux2.4 以后的版本中,直接将 LVS 加入内核中,不用在重新自行编译进内核。
看到这里很汗颜,这是人家98年,也就是20年前就捣鼓的技术……
因为单台服务器并不能满足大部分的线上需求,而高端服务器又太贵,效果也不咋地,由此大部分线上服务都会使用多台服务器同时提供服务,而这样的多台服务器就是大家俗称的(服务器)集群。而LVS是一个开源软件,它是专门进行Linux服务器集群开发的。
为什么要实现服务器集群?
实现服务器集群主要就是为了负载均衡(Load Balance)——有两台或者以上的服务器或者站点提供服务,服务将来自客户端的请求,靠某种算法,去尽量平分请求到集群的机器中,从而避免一台服务器因为负载太高而出现故障,而即使其中某个机器出现故障,负载均衡会自动规避选择,使得用户也能正常访问服务。
web服务端架构的发展史
当然不会说全面,也可能会有谬误,抛砖引玉!
单机部署
这是web服务最初的状态,一台机器同时部署了服务器和数据库。
我记得我之前搭建个人网站,还有我们在学校里捣鼓的一些教学项目,一般就是用的这种模式。
程序&数据库服务器分离
后来,随着业务量变大,类型增多,原始方案愈来愈成为了项目开发阶段进行自测的一个选择。等自测完毕,域名备案后,真正上线的往往是采用了数据库和服务器单独部署的模式。
好处是:服务器的压力变小,而且当程序服务器被攻击的时候 ,数据库不会被连累。
坏处是:数据远程传输性能无法保证,除非是将两者放在同一机房节点下,或者同一台交换机下。
动&静资源分离
网站有很多资源。其中有静态资源和动态资源之分。
静态资源,比如HTML,JavaScript,CSS,img等文件,也就是可以直接呈现给用户的页面资源;
动态资源,是不能直接在页面呈现,而是需要在后台进行某种转换的资源,即动态资源要转换为静态资源。
对于Java 的 Web程序,JSP/Servlet 容器的基本功能是把动态资源转换成静态资源,当然JSP/Servlet容器不只这些功能。
动静分离就是把静态资源与后台应用分开部署,提高用户访问静态代码的速度,降低对后台应用的访问速度。
好处
比如,在目前我接手的这个网络服务中,采用动静分离之后,后端只需要提供restful API 即可,其他模块或者前端只需要访问我的API接口即可。也就是说,如此一来,我的服务,可以同时被多个外部模块甚至是多平台去调用,逻辑清晰,便于维护。
另外,提到了前端调用后端的restful API,这样可以使得前端和后端的开发&测试进度互不影响,它们之间只需要关注接口的协议即可。
这样搞的最终目的,无非就是为了减轻后端服务器的压力,提高静态资源访问速度,因为后端程序不需要在使用模板去渲染页面。
坏处
首先要明白什么是SEO,以国内的百度为例,百度的爬虫会根据网站的URL去抓取页面进行分析,一份分析的都是文本内容,也就是说会过滤掉js代码,而动静分离后,前端一般需要实时同后端进行异步请求和响应,这个异步请求的实现一般都是js来做。而常规的爬虫一般不能抓取异步加载的内容,也就是说爬虫抓取下来的前端的页面里,包含了大量异步加载的操作,但是爬虫无法执行也无法获得其内容,这样会导致网站的SEO受影响。
目前我听说的解决方案,是可以采用前端缓存技术来解决,把不经常变的数据缓存起来。
负载均衡+服务水平扩展
负载均衡不再多说,谈下下服务扩展。
服务的垂直扩展
垂直扩展意思就是努力提高后端服务的服务能力,如何优化业务逻辑?如何提高代码质量?使用多线程(进程)?能否从单机硬件着手,比如增加服务器内存,磁盘容量,购买更好的CPU……以期能提高服务的负载能力。
但是这样搞,明显成本是很高的,死活薅一个羊的毛,其实意义不是很大。于是,就有了水平扩展。
服务的水平扩展
在水平扩展中,不追求增加单个服务器的负载能力,而是简单的通过部署更多的廉价服务器,去分摊负载。
数据库性能瓶颈
搞了那么多的服务器,在结合LB,虽然负载被分摊,但是数据库的性能又跟不上了。主要还是I/O瓶颈,那么这时候就出现了NoSQL缓存。
NoSQL缓存
主流的有memcached以及Redis。
当然,数据库方面也有水平扩展,同时还有库表水平和垂直拆分。
库表水平和垂直拆分
垂直拆分:当网络服务不断壮大的时候,数据库也会变成多个子系统来支撑,这时就有按业务把表划分出来的需求,即就是把业务联系紧密的数据表划分到同一个数据库中,这样整个服务的多张表会分配到不同的数据库,原则是不破坏第三范式。
但是垂直拆分依然存在问题,如果拆分之后的单表数据小,数据增速缓慢,一般会维持现状。否则进行水平拆分。
水平拆分:把一个表按照约定的规则,将数据划分到不同表或者数据库。
大白话解释就是:库表的水平拆分对应的行,把行数据拆分到不同表中, 而垂直拆分对应的列,把表数据拆分到不同表中。
因为后续还涉及到了筛选合并。
总之,比较复杂……
引入SOA架构
SOA,即面向服务的体系结构(Service-Oriented Architecture,SOA),它是一个组件模型,官方的解释是:
它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。
接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以使用一种统一和通用的方式进行交互。
SOA,本质上是一种业务和技术完全分离,业务和技术又能自由组合的思想。
SOA架构,达到了目前软件设计思想的最高境界。
引入CDN镜像
大数据平台
防火墙——防DDos
当然接下来的东西还有很多
容器部署
……
多机房容灾机制
……
虚拟化云计算
一切都在云上,云存储,云主机等等。
四层负载均衡
本图的7层负载均衡使用了Nginx,4层使用了LVS,缓存服务使用Memcached,队列服务使用Redis,文件服务器使用NFS,数据库是MySQL主从集群。
可以看到,用户的请求先经过防火墙,然后到LVS负载均衡主服务器,然后按照静态和动态内容,分发到Nginx的负载均衡服务器,如果是静态内容,那么直接从静态web节点集群读取数据返回给用户,如果是动态内容,那么Nginx会把请求分发到Tomcat集群,也就是动态web节点。
Tomcat集群获得请求后,会做一系列业务判断,比如是否有缓存,如果缓存没有,要去直接访问MySQL主从集群。如果对于一些memcached应付不了的,需要持久化的资源,就会被送到Redis队列服务器。
对于Nginx和Tomcat,都会共享文件,这里就可以用NFS文件服务器解决。
额外的,海量数据的处理,比如日志分析,目前都是使用的Hadoop。
……
其中,本篇文章重点说的是4层负载均衡 LVS。
负载均衡的发展史
硬件时代
硬件负载均衡解决方案是直接在服务器和外部网络间,安装负载均衡设备,由专门的设备完成专门的任务,独立于操作系统,再加上多样化的负载均衡算法,智能化的流量管理,使得服务的整体性能得到大量提高。但是相对来说硬件的成本较高。
软件时代
因为硬件的成本贵,互联网公司肯定不会首选的,那么软件负载均衡就应运而生。也是目前使用的最为广泛的。一是它的效果很牛B,二是不需要很大的成本,甚至可以近乎0成本!
其中常用的软件实现方式有:
- LVS
- Nginx
- HAProxy
LVS 主要工作在第四层,Nginx 主要工作在第七层,HAProxy 是一款提供高可用性、负载均衡以及基于TCP和HTTP应用的代理软件,也支持虚拟主机。