2014年6月11日星期三

闲谈高可用与负载均衡

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
闲谈高可用与负载均衡  阅读原文»

每日博报 精彩不止一点关闭

用户名:双鱼座小龙
文章数:27
评论数:71
访问量:18979
无忧币:800
博客积分:692
博客等级:4
注册日期:2011-11-23

闲谈高可用与负载均衡

闲谈高可用和负载均衡

高可用集群和负载均衡集群想必大家或多或少都听说过,但是很多人往往把这两个搞混在一起,不加区分地使用这两个概念。虽然说很多负载均衡的设备有着高可用的特性,或者高可用的机器使用着负载均衡的方式分发流量,事实上,高可用和负载均衡是两个完全不同的概念,两者关注的地方是不同的,而且很多在很多场景下两者的需求是冲突的。

那,什么是高可用和负载均衡呢?两个概念各自关注的地方又是什么?

高可用性:顾名思义,尽可能采取措施减少系统服务中断时间,进而提高业务程序持续对外提供服务的能力。

负载均衡:将高并发的请求数据分发到不同的集群结点,尽量平衡系统所有资源的压力,从而提升整个集群对于请求的处理能力。

以上的定义非常科学地定义了高可用性和负载均衡,但是对于很多人他没接触过这两个概念一时还不好理解怎么办,那就用一个我们工作中通俗的例子来跟大家聊下高可用和负载均衡。

工作岗位有产品人员,程序员和运维人员之分,一般一个产品人员会带着一群程序员开发一个产品,一个开发人员背后又有着系统运维,网络运维,业务运维,平台运维的支持。这个时候,产品人员就相当于负载均衡中的分发器,程序员相当于负载均衡集群的结点,产品人员作为分发器将各种收集来的用户请求转发给不同的程序员,当然分发给不同程序员处理的事务可能相同也可能不相同。假如说不考虑产品人员担心程序员的可用性,那一般情况下,一项需求是不会交给两个人去做的,每个程序员做的都是不相同的事务。同样,每个开发人员也相当一个分发器,一个应用需要上线需要做的事情非常多,包含系统,网络和应用环境以及一些与业务相关的配置,这个时候也是一个非常典型的负载均衡模型,一个开发人员提一个需求单,然后处于不同角色的运维人员然后处理自己相关的事情。当一件比较复杂或者一大堆比较繁琐的事情需要处理的时候,如果由某个单一的系统来处理,需要的时间以及相应的资源可能比较多,使用负载均衡集群将不同的请求分发到不同的结点,从而提高整个集群对于事务的处理能力,负载均衡集群相对于单个结点有着更高的性能。

那什么时候我们会考虑高可用性呢?同样是产品人员和程序员,产品人员发现某个程序员请假了,那么他就有可能要求开发团队的领导给他再安排一个人继续处理相同的事务,从而保证产品如期开发完成。当集群中某一个结点无法提供预期的服务的时候就使用另一个结点替换当前结点来进行服务。

再通俗点讲就是,

美国的总统和副总统更像高可用集群,只有等到总统挂了副总统才派得上用场,这叫高可用;像我朝各个正职和副职(比如正校长和副校长,正校长可能姓付,副校长也可能姓郑)的关系,更像负载均衡的关系,各个正副职往往各司其职,没有说哪两个人干的事情是一模一样的,或者某个人平时不干事就等正职那位伙计挂掉然后顺利成章就接手正职的职责和权利的。

负载均衡一般不关注集群中各节点对于请求的处理能力,很多时候会根据节点处理能力的不同而使用不同的分发策略,比如轮询,最小连接,最快响应等。高可用比较关注集群中结点处理请求能力的对等性,因为一单主节点出现问题备用节点需要承受主节点所有的请求压力,一旦处理能力较弱有可能无法正常提供服务,从而失去高可用的作用。

高可用性集群中的节点一般是一主一备,或者一主多备,通过备份提高整个系统可用性。负载均衡集群一般是多主,每个节点都会分担部分流量。

为什么很多人会把高可用和负载均混淆起来,因为大家一般了解的都是某个软件或者设备,往往这些设备会同时应用负载均衡和高可用。比较典型的F5和HAProxy中,F5作为一个负载均衡设备对后端节点有着健康监测功能,而且当有多个节点的时候是不影响到整个服务的可用性的。假如没有这个健康监测功能,一个集群下放1个节点和多个节点在可用性方面是没有区别的。同时HAProxy作为被大多数人认为的高可用软件,其实根本就不是什么高可用集群软件,其对于用户请求有着分发处理的功能,同时有着反向代理功能,事实上Haproxy 是一个负载均衡器(The Reliable, High Performance TCP/HTTP Load Balancer,可靠的高性能TCP/HTTP负载均衡器),真正的高可用是有一个叫keepalived 软件来实现的。由于数据库数据要保证数据的一致性,一般都是单写,所以无法实现数据库服务的负载均衡,这也是目前碰到的一个难题,当然了如果数据库是只读的,还是可以实现负载均衡的。

负载均衡集群中,更多的关注可扩展性和性能,比较关注集群节点处理能力;高可用集群,更多的关注可用性,比较关注自动侦测,自动切换,自动恢复。

在高可用性集群内,每种服务的用户数据只有一份,在任一时刻只有一个节点能读写这份数据。

在负载均衡集群内,对于数据一般不会只有一份,往往基本上都是有差异的。

高可用性集群对一种服务而言不具有负载均衡功能,它可以提高整个系统的可靠性,但不能增加系统的负载能力。负载均衡集群的各节点间通常没有共用的存储介质,用户数据被复制成多份,存放于每一个提供该项服务的节点上。

对于同一种服务,是不能同时获得高可用性与负载均衡能力的,大家看看数据库服务就很清楚了。

source:http://liuqunying.blog.51cto.com/

本文出自 "从菜鸟到老鸟" 博客,请务必保留此出处http://liuqunying.blog.51cto.com/3984207/1424811

分享至 一键收藏,随时查看,分享好友!
昵称:
登录快速注册
内容:
返回顶部

ASP.NET MVC控制器(一)  阅读原文»

用户名:jinyuan0829
文章数:29 评论数:1
访问量:2469无忧币:404博客积分:298:2 注册日期:2014-04-26

ASP.NET MVC控制器(一)

ASP.NET MVC 控制器(一)

前言

在路由的篇章中讲解了路由的作用,讲着讲着就到了控制器部分了,从本篇开始来讲解MVC中的控制器,控制器是怎么来的?MVC框架对它做了什么?以及前面有的篇幅所留的疑问将会在这部分里解决掉。

对于控制器激活的总结

总的来说控制器的激活过程有这么几个步骤(部分):

1.根据当前路由信息获取控制器名称

2.获取当前系统的控制器工厂(用来生成控制器)

2.1 据控制器名称生成和当前系统的请求上下文参数生成控制器类型(Type

2.1.1 根据当前的路由信息判断选择控制器所在命名空间

2.1.2 返回控制器类型(Type)

2.2根据控制器类型(Type)请求上下文参数生成控制器类型(IController)

2.3 返回控制器类型(IController)

3.获取由控制器工厂生成的控制器(IController)

4.执行IController.Execute()

控制器的由来

前面都有讲到MVC的入口在Module中,具体是在注册路由的时候,默认的注册MvcHandler作为请求处理类型,而控制器的就是在这里生产出来的,为什么说是生产?因为系统预先实现了一个控制器工厂类DefaultControllerFactory(如下的代码结构),在控制器生成到执行的这个过程里涉及到众多的类型和控制器的对象模型,这些内容在后面篇幅会一一讲解。

DefaultControllerFactory类型的结构:

1publicclassDefaultControllerFactory:IControllerFactory
3publicDefaultControllerFactory();
DefaultControllerFactory(IControllerActivatorcontrollerActivator);
6publicvirtualIControllerCreateController(RequestContextrequestContext,stringcontrollerName);
7protectedinternalvirtualIControllerGetControllerInstance(RequestContextrequestContext,TypecontrollerType);
8protectedinternalvirtualSessionStateBehaviorGetControllerSessionBehavior(RequestContextrequestContext,TypecontrollerType);
9protectedinternalvirtualTypeGetControllerType(RequestContextrequestContext,stringcontrollerName);
10publicvirtualvoidReleaseController(IControllercontroller);

本篇先将上面总结中的2.1.2之前的部分粗略的讲解一下,请先看如下图:

如上图,这里先要说的是控制器类型缓存对象ControllerTypeCache,ControllerTypeCache加载所有实现了IController接口的公共类并缓存在MVC-ControllerTypeCache.xml文件里。当然了这些都是框架所做的,我们只需了解一下,学习其中的思想就行了。

在请求到达默认请求处理程序的时候,由默认的控制器工厂DefaultControllerFactory来根据RouteData的DataToken【NameSpaces】里的定义的命名空间和Values【controller】的控制器名称来进行判断,具体怎么判断的是由ControllerTypeCache对象来查询匹配的。

先根据控制器名称查询缓存中是否有对应此名称的控制器,如果有则存放在 ILookup<string, Type>类型对象中,然后根据RouteData的DataToken【NameSpaces】里的定义的命名空间来和ILookup<string, Type>对象中的控制器类型所在命名空间进行比对,如果是相同的则添加此类型到返回集合,如果不相同则继续用RouteData的DataToken【NameSpaces】剩下的命名空间值挨个的进行比对。

根据返回的类型集合,如果总数为0返回空,总数为1返回此集合中的类型,如果大于1则会引发CreateAmbiguousControllerException类型的异常。

在此时DefaultControllerFactory中已经获取到了控制器类型(Type)。

在总结中2.2所指部分为IControllerActivator接口类型的实现。

2//对使用依赖项注入实例化控制器的方式进行精细控制。
3publicinterfaceIControllerActivator
5//摘要:
6//在类中实现时创建控制器。
//参数:
9//requestContext:
10//请求上下文。
12//controllerType:
13//控制器类型。
15//返回结果:
16//创建的控制器。
17IControllerCreate(RequestContextrequestContext,TypecontrollerType);

这部分的实现,可以注入到控制器工厂,而?p>阅读更多内容

没有评论:

发表评论