王作敬
作者王作敬2018-01-02 11:21
管理信息系统总监, 银河证券

容器云之弹性伸缩

字数 4008阅读 4717评论 1赞 3

本文作者:汪照辉 王作敬 中国银河证券股份有限公司 信息技术部IT研发中心


一、综述

弹性伸缩是容器云的一个重要特性,也是实施容器云的一个重要业务场景,更是容器云产品的重要卖点。这也是我们非常关注的功能。所以我们一直也在考虑服务弹性伸缩的问题。目前Kubernetes支持CPU、Memory伸缩策略,但CPU和Memory很多场景并不适合。CPU和Memory的使用情况有时并不能真实反映实际业务的运行情况,而且用他们来扩展、收缩容器也显得武断,很可能导致没有完成的业务请求的容器被回收,象我们证券涉及的都是钱、资金,如果在资金处理上出错将是对客户的极端不负责任,很容易失去客户的信任。所以我们在考虑弹性收缩时就考虑的更多。

不过遗憾的是,目前我们接触的厂商基本上都没有实现对其他弹性伸缩策略的支持,比如系统吞吐量tps、响应时间response time、并发数量等,有厂商反馈是要跟随Kubernetes版本的功能,不想维护多套产品,因为社区版本以后会支持更多策略。唉,很让我无语。在Kubernetes社区版本的基础上实现扩展支持,才能够与众不同,才能够引领设计引领潮流,才能够赢得客户,才能有钱赚。总跟在人家屁股后面亦步亦趋,怎么可能超越别人?

即便是Kubernetes社区版本不支持,扩展实现一些策略并不困难,或者至少提供对客户自定义弹性伸缩策略的支持。只要整个容器云平台架构定义合理,并不影响后期Kubernetes新版本的新特性和功能,平台升级也不会带来什么问题,况且,对客户来说,关心的是应用服务,容器云只是个工具、基础载体,工具好用,在运营应用服务时才能得心应手。

我们说服务伸展时相对容易,收缩时就涉及业务,这就要求我们不仅仅考虑容器的回收就行了,也需要考虑在容器回收时是不是会影响到业务?会不会有容器在未处理完业务请求时就会被强制回收?如果出现这种情况该如何处理?是否有更好的方法可以避免这种情况?等等。我们需要一个整体的考虑,不只是容器云的弹性收缩策略的支持,也包括在业务实现时支持弹性伸缩的架构等考虑。在此也是抛砖引玉,与大家共同探讨。

二、弹性伸缩策略扩展

服务在实现弹性伸缩时,该选择什么样的伸缩策略,很多时候是需要根据服务的架构和能力来选择的,基于CPU和内存的伸缩策略是最简单的策略,就象Hello World QuickStart演示程序一样,基于很多假定,但现实往往这些假定都不成立,这些简单的演示是不能满足我们的需求的。

现实的需求复杂,那么容器云平台能不能支持?能是肯定的,实现方式有很多种,但是否有简单的方法来实现?这就是我们讨论的问题。

比如并发数,如果我们有了并发数,那么就可以使用它作为伸缩的策略,并发数大于某个临界值,就可以扩展容器数量,从而扩展服务实例数量;如果低于某个临界值,就可以按照一定的方式来回收容器,回收资源。这也是我们充分利用资源选择容器化的初衷。

但并发数从哪里能够获取?怎么获取?这也是很多人茫然的问题。我们觉得不能仅仅从容器云平台考虑,容器云平台最终是要支撑业务服务的,要支撑业务服务,就需要有相应的机制和组件,这就是我们强调的生态,不能割裂开来。所在需要在容器云平台搭建支撑业务服务,业务应用的服务化生态能力,比如服务注册发现、服务日志管理、服务监控告警、服务API Gateway等。从服务API Gateway是不是可以获取到并发数、响应时间等?其实在我们看来,在容器云平台上对服务化或微服务的生态支持,并不和容器云的调度管理框架后期对新的弹性策略的支持相悖,可以是并行的。同时也和服务化或微服务的整个设计架构有关系,我们强调不要割裂来看,我们不是玩过家家,我们需要全面考虑适用且实用的完整方案。微服务、容器化、分布式技术等相辅相成,从整体上考虑才能真正便捷的满足我们的业务实际需求。

容器云平台也可以支持用户自定义弹性伸缩策略,想清楚从哪里取策略值、怎么取策略值,实现就相对简单了。

三、通过API Gateway

API Gateway是服务治理的一个重要组件,我们以后也会详细讨论。这里我们尝试通过API Gateway来获取到我们实现弹性策略需要的并发数、响应时间、吞吐量等数据。另外也基于我们的服务化实施架构,对于涉及的编排的服务、组合服务中不同层次中的服务的伸缩及伸缩策略,做个讨论。

图片1.png

图片1.png

我们实施服务化,特别微服务化,通常需要实现一个API Gateway来负责服务请求的认证授权、路由、协议转换、统计等功能。客户端的所有请求都首先要经过API Gateway,然后由它将请求路由到合适的服务或微服务。

有了API Gateway,并且所有的请求都会通过API Gateway,那么我们就有可能获取到请求数、请求时间、请求处理结果返回时间等,从而计算出系统吞吐量等。有了这些数据,就可以用于服务的弹性伸缩场景。不过很遗憾的是,目前基本上容器云厂商都没有考虑到对这点的支持,都不提供API Gateway组件。容器云只是一个简单的基础平台,并没有在其之上提供完整的服务或微服务生态支撑。

四、使用JMS Queue

JMS Queue提供了消息中间件层的负载均衡能力。在服务化实现过程中带给我们很多便利。在内部服务调用中,可以采用JMS 接口,基于JMS Queue本身的特性,可以部署多实例来实现服务实例间的负载均衡。同时,JMS Transaction机制和JMS message Acknowledge机制也可以保证事务处理的完整性和满足消息处理的性能和可靠性之间达到需求平衡。目前我们在ESB系统中就采用这种方式,通过监控JMS Queue上pending的messages数量,在请求并发数持续增长时,可以部署(自动或手动方式扩展,监控可以实现即时告警)更多的服务实例,来均衡和保证服务的处理能力及响应时间。在请求并发数恢复正常,消息被正常处理之后,可以回收资源,停止部分服务实例。当然这需要业务服务设计中一些机制的协同支持,很难仅靠一种方法满足这么多要求。

图片2.png

图片2.png

JMS Queue上待处理的消息数量可以使用JMS API或者JMS消息中间件工具来取得。通过监控JMS Queue上的待处理消息数量和大小,来作为是否扩展服务实例的一个策略。

图片3.png

图片3.png

我们这里只是讨论弹性伸缩的一种实现方式,JMS Queue上消息的持续增长,并不一定非要通过扩展服务实例来解决。

另外我们需要说明的一点是:服务的整个处理流程各层服务要都具有可扩展性,不能有瓶颈,否则无法实现整个服务链路的能力扩展。比如如果数据库服务处理能力有限,无论怎么扩展其他服务的处理能力,瓶颈会始终存在于数据库,整个服务链路性能无法提升。

五、自定义策略支持

作为一个平台产品,很难罗列用户潜在需要支持的各种弹性扩展策略,一个好的方式是提供一种机制,可以让用户自定义弹性伸缩策略,就象我们开发软件时习惯提供几种通用的模板之外,用户可以按照自己的实际需求去定义自己的业务流程。那么怎么能够兼容用户的自定义弹性伸缩策略?有了上面的思考,我们知道,首先要明确策略值从哪里来,然后明确如何和容器云平台集成,我们才能使用这些策略值来定义弹性伸缩的条件。

策略值从哪里来?源应该是多种多样。象我们提到的资源CPU、Memory使用率、请求数、响应时间、吞吐量;还有累积的待处理消息量(Pending MSG Count)等其他可能选项。容器云平台要想用这些值,它得能够采集得到,这就是和容器云集成问题。CPU、Memory最容易采集,所以目前Kubernetes等只支持CPU、Memory策略,其他的怎么办?这是我们考虑容器云产品也关心的问题。

1、容器云是不是可以提供一个定时回调机制,具体的弹性伸缩策略在回调机制中由用户实现?比如回调函数。如同对JMS Queue Pending Msg Count,我们可以通过Java 代码来连接检查JMS Queue上的消息数,这样就可以在回调函数中实现,容器云平台调用此回调函数,就采集到了JMS Queue上的消息数。使用此值,就可以在容器云平台定义自己的弹性伸缩策略了。

2、或者是否可以实现一种通知接收机制,容器云平台接收通知,然后根据定义执行相应的操作(伸展或收缩)。这是一种被动机制。容器云平台不需要主动去采集策略值,只是在某项策略值达到临界值时,能够接收到此策略值即可。

六、弹性伸缩之收缩

我们谈弹性伸缩,往往只是“伸”没有“缩”。在我们接触的厂商中,很少考虑到收缩时的问题。我们不能率性的、武断的把容器停掉就行了,那会影响到实际的业务的。理想很丰满,现实很骨感。所以我们需要考虑收缩时怎么做才能保证被收缩的容器不会影响到实际的业务的。

有厂商是按照容器编号来管理的,先创建的容器先回收。这往往是不合适的。容器回收时需要保证容器已经不再接收新的服务请求,并且已经处理完了接收到的所有服务请求。这种情况下容器才可以被回收,实现服务实例收缩。

交流过程中也有厂商提到通过监控来实现,监控容器中服务满足上面条件,但我们感觉复杂化了。其实也不好操作。

我们的想法是,结合Load Balancer的Load Balance策略,比如权重,来实现。在服务实例伸展时,可以根据实际情况设置不同的权重值。或者提供服务实例权重值实时更改能力,这样会更好。这样,在并发量大的情况下,权重低的服务实例也会处理请求;并发量小时,权重低的服务实例就空闲了,可以做回收收缩处理。

还有一种方式是操作Load Balancer,收缩时,先把服务实例从Load Balancer上移除,不让它接收新的服务处理请求。等它把它所有的请求都处理完之后,空闲情况下,通知容器云平台可以回收了。
不同的Load Balancer有不同的策略支持,我们在选择时可能需要考虑和验证下。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

3

添加新评论1 条评论

wuwenpinwuwenpin软件开发工程师, 南京
2018-01-02 16:49
学习了
Ctrl+Enter 发表

本文隶属于专栏

最佳实践
不同的领域,都有先行者,实践者,用他们的最佳实践来加速更多企业的建设项目落地。

作者其他文章

相关文章

相关问题

相关资料

X社区推广