服务熔断降级是在易语言客户端服务端上还是服务端

4368人阅读
伴随着微服务架构被宣传得如火如荼,一些概念也被推到了我们面前(管你接受不接受),其实大多数概念以前就有,但很少被提的这么频繁(现在好像不提及都不好意思交流了)。想起有人总结的一句话,微服务架构的特点就是:“一解释就懂,一问就不知,一讨论就吵架”。
其实对老外的总结能力一直特别崇拜,Kevin Kelly、Martin Fowler、Werner Vogels……,都是著名的“演讲家”。正好这段时间看了些微服务、容器的相关资料,也在我们新一代产品中进行了部分实践,回过头来,再来谈谈对一些概念的理解。
今天先来说说“服务熔断”和“服务降级”。为什么要说这个呢,因为我很长时间里都把这两个概念同质化了,不知道这两个词大家怎么理解,一个意思or有所不同?现在的我是这么来看的:
在股票市场,熔断这个词大家都不陌生,是指当股指波幅达到某个点后,交易所为控制风险采取的暂停交易措施。相应的,服务熔断一般是指软件系统中,由于某些原因使得服务出现了过载现象,为防止造成整个系统故障,从而采用的一种保护措施,所以很多地方把熔断亦称为过载保护。大家都见过女生旅行吧,大号的旅行箱是必备物,平常走走近处绰绰有余,但一旦出个远门,再大的箱子都白搭了,怎么办呢?常见的情景就是把物品拿出来分分堆,比了又比,最后一些非必需品的就忍痛放下了,等到下次箱子够用了,再带上用一用。而服务降级,就是这么回事,整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来。
所以从上述分析来看,两者其实从有些角度看是有一定的类似性的:
目的很一致,都是从可用性可靠性着想,为防止系统的整体缓慢甚至崩溃,采用的技术手段;最终表现类似,对于两者来说,最终让用户体验到的是某些功能暂时不可达或不可用;粒度一般都是服务级别,当然,业界也有不少更细粒度的做法,比如做到数据持久层(允许查询,不允许增删改);自治性要求很高,熔断模式一般都是服务基于策略的自动触发,降级虽说可人工干预,但在微服务架构下,完全靠人显然不可能,开关预置、配置中心都是必要手段;
而两者的区别也是明显的:
触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分(比如降级一般是从最外围服务开始)实现方式不太一样,这个区别后面会单独来说;
当然这只是我个人对两者的理解,外面把两者归为完全一致的也不在少数,或者把熔断机制理解为应对降级目标的一种实现也说的过去,可能“一讨论就吵架”也正是这个原因吧!
概念算是说完了,避免空谈,我再总结下对常用的实现方法的理解。对于这两个概念,号称支持的框架可不少,Hystrix当属其中的佼佼者。
先说说最裸的熔断器的设计思路,下面这张图大家应该不陌生(我只是参考着又画了画),简明扼要的给出了好的熔断器实现的三个状态机:
Closed:熔断器关闭状态,调用失败次数积累,到了阈值(或一定比例)则启动熔断机制;Open:熔断器打开状态,此时对下游的调用都内部直接返回错误,不走网络,但设计了一个时钟选项,默认的时钟达到了一定时间(这个时间一般设置成平均故障处理时间,也就是MTTR),到了这个时间,进入半熔断状态;Half-Open:半熔断状态,允许定量的服务请求,如果调用都成功(或一定比例)则认为恢复了,关闭熔断器,否则认为还没好,又回到熔断器打开状态;
那Hystrix,作为Netflix开源框架中的最受喜爱组件之一,是怎么处理依赖隔离,实现熔断机制的呢,他的处理远比我上面说个实现机制复杂的多,一起来看看核心代码吧,我只保留了代码片段的关键部分:
public abstract class HystrixCommand&R& extends AbstractCommand&R& implements HystrixExecutable&R&, HystrixInvokableInfo&R&, HystrixObservable&R& {
protected abstract R run() throws E
protected R getFallback() {
throw new UnsupportedOperationException(&No fallback available.&);
final protected Observable&R& getExecutionObservable() {
return Observable.defer(new Func0&Observable&R&&() {
public Observable&R& call() {
return Observable.just(run());
} catch (Throwable ex) {
return Observable.error(ex);
final protected Observable&R& getFallbackObservable() {
return Observable.defer(new Func0&Observable&R&&() {
public Observable&R& call() {
return Observable.just(getFallback());
} catch (Throwable ex) {
return Observable.error(ex);
public R execute() {
return queue().get();
} catch (Exception e) {
throw decomposeException(e);
HystrixCommand是重重之重,在Hystrix的整个机制中,涉及到依赖边界的地方,都是通过这个Command模式进行调用的,显然,这个Command负责了核心的服务熔断和降级的处理,子类要实现的方法主要有两个:
run方法:实现依赖的逻辑,或者说是实现微服务之间的调用;getFallBack方法:实现服务降级处理逻辑,只做熔断处理的则可不实现;
使用时,可参考如下方式:
public class TestCommand extends HystrixCommand&String& {
protected TestCommand(HystrixCommandGroupKey group) {
super(group);
protected String run() throws Exception {
//这里需要做实际调用逻辑
return &Hello&;
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
TestCommand command = new TestCommand(HystrixCommandGroupKey.Factory.asKey(&TestGroup&));
//1.这个是同步调用
command.execute();
//2.这个是异步调用
command.queue().get(500, TimeUnit.MILLISECONDS);
//3.异步回调
command.observe().subscribe(new Action1&String&() {
public void call(String arg0) {
细心的同学肯定发现Command机制里大量使用了Observable相关的API,这个是什么呢?原来其隶属于RxJava,这个框架就不多介绍了 --- 响应式开发,也是Netflix的作品之一,具体大家可参考这系列博客,我觉得作者写的很通俗:
接着呢,大家一定会问,那之前说的熔断阈值设置等,都在哪块做的呢?再来看看另一块核心代码:
public abstract class HystrixPropertiesStrategy {
public HystrixCommandProperties getCommandProperties(HystrixCommandKey commandKey, HystrixCommandProperties.Setter builder) {
return new HystrixPropertiesCommandDefault(commandKey, builder);
这个类作为策略类,返回相关的属性配置,大家可重新实现。而在具体的策略中,主要包括以下几种策略属性配置:
circuitBreakerEnabled:是否允许熔断,默认允许;circuitBreakerRequestVolumeThreshold:熔断器是否开启的阀值,也就是说单位时间超过了阀值请求数,熔断器才开;circuitBreakerSleepWindowInMilliseconds:熔断器默认工作时间,超过此时间会进入半开状态,即允许流量做尝试;circuitBreakerErrorThresholdPercentage:错误比例触发熔断;......
属性很多,这里就不一一说明了,大家可参考HystrixCommandProperties类里的详细定义。还有一点要着重说明的,在熔断器的设计里,隔离采用了线程的方式(据说还有信号的方式,这两个区别我还没搞太明白),处理依赖并发和阻塞扩展,示意图如下:
如上图,好处也很明显,对于每个依赖都有独立可控的线程池,当然高并发时,CPU切换较多,有一定的影响。
啰嗦了一堆,最后总结一下,我认为服务熔断和服务降级两者是有区别的,同时通过对Hystrix的简单学习,了解了其实现机制,会逐步引入到我们的产品研发中。当然还有好多概念:服务限流、分流,请求与依赖分离等,后面有时间一一与大家分享。&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:7402次
排名:千里之外devops 漫谈微服务与DevOps:如何在实践中快速落地?[ 01:13:22]
专题分类:>>>
“ 本文围绕作者这些年在OpenStack、Kubernetes、Microservice、DevOps、Cloudfoundry、ELK等云计算相关领域及技术的实践,从微服务和DevOps两方面着手,旨在为两者的落地提供一个快速可行路径。针对这“说说还可以,一深入讨论就吵架”的热点概念,详解了在产品研发过程中的思考与实践,通过多维度的架构与技术剖析,与大家深入沟通云计算的企业级落地思路。本文不局限于微服务与DevOps,更多的从自己这些年的经历与实践来和大家交流,更希望本次分享之后能和各位长期保持沟通与学习。老司机简介顾伟,毕业于东南大学,现任普元公司主任架构师;先后参与和带领了华为BME、中信银行CBJUP、工商银行CTP、中航信RI、阿里云ACE、普元云计算平台、普元The Platform等大型项目的交付;长期致力于IT技术研究、产品设计、架构咨询等工作,擅长Web、OSGI、CI/CD、服务治理、云计算等领域技术;对DevOps、自动化运维、微服务架构有着浓厚的兴趣。分享包括以下四部分:我经历的云计算历程:简单介绍下自己参与的一些产品研发,然后从现在市场格局的角度,提出一些自己作为云计算产品线负责人的想法;微服务与DevOps的认识:围绕今天的主题,从微服务与DevOps角度,阐述自己的理解;平台级的实践与支撑:基于当前正在研发的“基于微服务架构的DevOps平台”,详解我们的设计与技术,当然也会有些坑里面会提到;参考与总结:整个过程中我们也参考了很多优秀的架构与理念,希望对大家也有用,最后给今天的分享做个总结;我经历的云计算历程严格来算,我是09年开始做和云计算有关的事情的,中间经历了很多方向、技术的变更,对个人确实有好处(接触更多的人和事嘛),但对于产品线来说,这往往是很不明智的:09年:如果放到现在大家会叫它为“传统的PaaS平台”,我们做了一款“云应用交付平台”,平台面向于运营商,帮助其更快速的部署轻量化的应用及服务,并提供了一定的快速伸缩能力,平台没有用到现在大家熟悉的技术栈,说实话,就是个土生土长的有点土的家伙;11年:正值OpenStack与CloudStack兴起,我们也看到了云计算的“美好前景”,从IaaS层着手,旨在从所谓的“千亿”市场分一杯羹,“理想很美好,现实很残酷”;13年:混合云模式逐步被接受,大家是否记得前段时间刚刚正式下线的ACE平台,当时我们就参与了这款平台的企业级落地,虽有成功案例,但混合云目前的形式,大家都是清楚的;15年:我们走到了现在的阶段,以容器为默认承载,微服务架构为支撑,打造企业级DevOps数字化平台,事实证明这个13年就想到过的点子是很成功的,成功在于两面:市场上的客户反馈(包括收入)和内部的能力驱动(团队使能)。那我们再来看看现在的云计算格局:我不太喜欢用标准的IaaS、PaaS、SaaS来区分,我认为这个界限越来越模糊(比如我们甭管好不好,三者都做),我更倾向于UCOBP的模式来看待领域:就目前来说在运营商和软硬件提供商来看,市场趋于稳定,大家都还把住了自己的核心优势(体量、门槛…)但从集成商和应用或者服务提供商来看,这些市场还是面临着竞争,比如现在的很多创业公司,都是瞄准这两块开始的我觉得像现在的云计算、大数据、移动互联、物联网、人工智能等大领域(其实我觉得泛领域更合适),进去很容易,想做好(至少赚到钱,借马云名言:“能赚到钱的不一定有价值,对社会有价值一定能赚到钱”)是要有几个前提的:定位要明确,你在这些泛领域中有没有找到市场地位,不求找到的都是蓝海,但不能使劲往红海挤方式要合理,我们一直遵循一个很简单的方法,我们自己叫“厚+薄”,这个面向企业市场很有用。所谓“厚”是说企业流程都是复杂的,无论用什么,需要基于企业级流程串接;所谓“薄”是说现在开源技术多如满天星,如何去其糟粕,取其精华,是我们要总结的基因很重要,下一个红帽也许永远不会再出现了,不仅仅IT市场,大家的朋友如果做生意一样能感受到,以前只要愿意努力去做,加上一点点聪明,基本上不会失败;现在如果你要去拓新一个完全未知或不相干领域,基本上会有两条死路,做不起来或者做起来点儿被巨头给cut了。微服务与DevOps的认识现在见客户就会聊微服务、聊DevOps、聊容器,但这种热点概念,真的是“简单聊聊可以,一深入就吵架”,比如以前谁问我传统应用该怎么拆分,我还会说一堆,现在基本上对于这种开放型问题都不敢回答了,怕“没朋友”。我简单说说我对微服务和DevOps的认知吧:第一个就不说了,第二个垂直架构,典型的比如SSH框架,帮大家考虑了模块化、MVC等,但并没有考虑服务化。第三个是分布式架构,以SOA为代表的这类技术已经热了很多年,也很成熟,也是目前很多企业架构的主体支撑。而第四个以微服务架构为支撑的技术虽然在一些先进企业或互联网公司已经运用,但从生态上来看,还有很长一段时间要走,其更强调在DDD下的业务服务自治性及原子性。“DevOps”通常指的是新兴的专业化运动,这种运动提倡开发和IT运维之间的高度协同,从而在完成高频率部署的同时,提高生产环境的可靠性、稳定性、弹性和安全性。其概念也特别多,简单浏览下就可以了:DevOps运动的起源通常被放在2009年前后,伴随着许多运动的相辅相成和相互促进——效率研讨会运动,特别是由JohnAllspaw和Paul Hammond展示的开创性的“一天10次部署”,基础设施即代码”运动(Mark Burgess和LukeKanies),“敏捷基础设施运动”(Andrew Shafer),“敏捷系系统管理(PatrickDeBois),“精益创业”运动(EricRies),JezHumble的持续集成和发布运动,以及Amazon的“平台即服务运动”等这些运动的相辅相成和相互促进而发展起来的。云计算、微服务、容器这些概念或能力之间到底是什么关系呢?其实这个主要看大家的方向了,结合我所面临的客户以及IT现状,我的理解是这样的:云基础平台作为底层支撑,既可以是Docker、Unikernel这样的容器技术,也可以像vmware或OpenStack这样以VM为管理单元的方式,旨在为上层提供有SLA能力的资源池管理与调度;DevOps作为一层可选平台,以流程自动化、工具自动化为主要手段,通过长期的积累与优化,为最终业务交付提供更敏捷、更数字化的能力;历史系统与微服务在企业会长时间并存(BiModal),不要试图一步到位,我所经历的企业客户中,都是从部分外围应用开始试点,甚至是先拆应用、再拆数据这样循序渐进的。平台级的实践与支撑先和大家说说我们的平台具体在做什么:这个定位(非市场定位)讲起来比较拗口,“用微服务架构,做云计算DevOps平台,支撑上层微服务的全生命周期管理”。 这里有个鸡生蛋、蛋生鸡的问题,那我们还是通过制定微服务的规范以及一部分配套工具,基于这些开发了第一版DevOps云平台,将其作为后续版本的生产线使用。过程中对康威定律又有了进一步认识,尤其是运用在异地协作和技术选型上,团队能力、异地松耦合是必须考虑的维度。先将平台用到的一些技术栈列出来:图中标红的是目前我们已使用的,相信大家不难看出来:我们主要是走的容器云这条线(当然传统的也是支持的),以Kubernetes为容器管理与调度的框架,结合Flannel网络、Ceph存储形成底层基础支撑微服务方面使用SpringBoot作为载体,引入了Netflix的部分框架支撑微服务调用、配置在全生命周期中,还支持了文档、Mock、自动化测试的能力,以便微服务架构下的快速交付在监控方面采用Journald采集,Fluentd作为server、同时通过索引及时序库支撑数据分析及展现这里有三个想法与大家共勉:架构师的角色转变,从原来的技术货架的搭建(加法)到现在海量技术中选择最合适的(减法),对能力的要求更高个人全栈已经不再多见,而团队全栈却越来越重要,学习型组织将是未来衡量团队能力的一大标准框架能力的阳性与阴性,同样是结合现在海量技术来看,测试是必不可少的,但业务场景的多变往往会造成数据的片面性,比如Flannel的UDP和Vxlan模式(就像体育赛场上一样,阳性不好,但伪阴性就更糟糕了)接着分别从微服务和DevOps方面来看看我们的一些关键设计和想法,先说说微服务架构:当然微服务架构中重要的不仅仅是上述的5个能力:服务的隔离与互通伸缩与漂移升级与回退熔断与降级服务注册与发现上图亦可理解为是核心概念模型,面向的问题是这样的:有些企业会考虑生产上VM,开发测试上容器;有些企业需要开发测试预发上线四套环境,有些只要两套:有些企业环境间要求完全隔离,有些只要逻辑隔离;有些企业要求对接下层资源池,有些则完全没有资源池的概念;……那概念模型上我们怎么办?上图的核心是业务运行及namespace的设计,下层无论资源有没有池化,都需要加一层Namespace的管理,这个管理有很多目标,比如隔离,再比如池化。然后紧接着是pod,这个概念参考了Kubernetes,在微服务运行时,一直强调一个业务的独立性,比如一个业务,其应用及数据库是绑定的,且与其他业务隔离。那我们认为这种就是一个pod(豌豆荚),体现的是一个独立业务(微服务)。一个pod无论内部如何,一般是跑在一台宿主机的,业务内部尽量本地调用,pod可以包括多个进程,也可以包含多个容器,也就是上图的pod与process的关系。从可靠性及性能考虑,pod必须是集群的,所以一个pod可以有多个副本,也就是上图的pod与replication的关系。最终业务要能对外提供能力,类似一个集群对外的统一发布地址,也就是上图的service的概念,service是外部的访问入口,并拥有一定的负载均衡能力。下图是运行时的调用过程示意:互通要求的是“可达、快速可达、安全并快速可达”。一个微服务内部可采用本地方式,而微服务之间采用service地址(无论内部怎么漂移伸缩,对外地址不变),对于公网上的调用,采用宿主机端口映射出去是个可选方式,当然要结合底层硬件基础设施本身的外网能力,比如阿里还有EIP之类微服务的伸缩与漂移,需要与监控能力结合,监控结果判断则运用的是万年不变公式:Result = function1*weight1 + function2*weight2 + …… + functionN*weightN。以漂移为例子,漂移有很多触发器,有因为故障的,有基于优化考虑的,比如像优化漂移这种,就要求定义很多维度,包括资源均衡维度、宿主机特性维度、标签配置变更维度等,需结合多维打分对微服务进行合理调度。那对于伸缩漂移所依赖的能力上,着重考虑下述两点:存储能力,存储可从服务状态特征考虑,一般来说,有状态服务采用共享存储,无状态服务采用非共享或者不适用存储。监控能力,点线面结合的监控,需注意对Metrics的正确使用,以及全局流水号等规范约束。微服务的升级与回退:发布要原子化,可编排,每个企业在流程上都会有所区别,只有在完全原子化的情况下,才能保证平台的快速实施标签设计,让每个动作、每个状态、每个资源都可以标识;标签设计不仅仅用于部署,我觉得在任何产品中都有借鉴意义状态设计,部署是原子化的操作,而内部的状态设计同样重要,比如可结合状态做挂起、唤醒等诸多操作版本规范,这个不仅仅是版本号的规范,还包括版本升级规范、配置规范等,不过微服务架构下,建议全量升级与回退路由能力,微服务这种快速迭代发布,伴随试错试对,快速变更,灰度等,对流量的出入动态性要求很高而对于我们来说,使用了rollingupdate机制来进行升级和回退(包括灰度),大家可参考Kubernetes的机制,一种基于标签和Replication的实现方法。对于升级回退、灰度中,最复杂的莫过于数据库以及前端负载的处理问题:1、数据库简单的做法就是类似传统行业,尤其像银行等,只增不减的方式 2、前端负载问题要结合业务来实现,很多企业会在Apigateway中考虑,当然不同行业稍有区别,比如在电力行业,IBM给规划的API基线也有这个能力微服务的熔断与降级,当然熔断与降级并不是一个概念,只是很多时候会一起实现了:熔断是指上游服务在调用下游服务时,因下游服务的种种问题,对调用链智能处理的手段降级是指整体资源瓶颈时,一般业务暂停(优先保证核心业务)的一种处理手段举例:熔断器实现方式,设计参考了一般都使用的三态设计,默认关闭态,调用出错率到一定程度半开,半开时,允许一部分流量继续调用下游微服务,如果一定时间还是出错(这个时间可结合MTTR设置),就将熔断器置为全开态,同样设置一定的时间后再尝试调用;现在在熔断和降级这块实现的比较好的包括netflix的Hystrix,还有motan,大家都可尝试,我们Hystrix测试过,目前使用了motan,仅从能力上对比,Hystrix无疑更强大。前段时间乐视受攻击,差不多每秒200G流量,最终能撑下来据说主要功劳和这个有关系。微服务的注册与发现,解决微服务之间的调用、以及一定的客户端和服务端集群的问题。采用etcd作为分布式注册中心,在服务启动和停止时实现注册和注销,运行过程中,会定时同步服务的元信息(比如流量、健康性等),以便实现智能路由。接着,我们来看看在DevOps实践中的一些关键点:四要素的提法和友商大同小异,包括组织、流程、技术、文化,下图会将四要素进行更细粒度的要素分解。组织:包括全栈团队、自治团队等流程:包括开发、测试、集成、交付、度量等技术:包括监控、chatops等文化:包括协作、学习等实现企业级DevOps,有很多方式和着手点,比如最常用的就是从持续发布开始。而我们更聚焦企业的全生命周期,所以在目前版本中(与上图有少许不对应),实现了基于微服务架构的以下15个DevOps领域系统:IAM:身份识别与访问管理,通过OAuth能力,一次登录,全网通行SPM:软件产品管理,DevOps平台的核心管理对象:产品。以产品维度为入口,管理包括产品的多版本,每个版本拥有多个组件,组件之间、组件与第三方产品之间的依赖关系等SCM:软件配置管理,主要是应用配置的管理,在编译打包时通过autoconfig技术,注入到最终部署包SRM:软件资源管理,资源,即上述产品的运行实例,所以持续发布等都是有SRM发起SEM:软件环境管理,企业环境千差万别,SEM屏蔽了异构环境的差异性,让上游系统及业务能够松耦合的运行QAF:质量保证反馈,这个系统负责收集全生命周期的数据反馈,为后续优化演进提供重要依据UMC:统一监控中心,主要收集日志及资源运行信息,通过计算分析,形成相关报表,同时与告警中心对接,风险异常准实时提示VCS:版本控制系统,默认集成GITCI:持续集成系统,默认集成JenkinsBPR:二进制仓库DPR:可部署包(镜像)仓库PM:项目管理系统,可集成redmine或wiki,目前平台是自己实现的IM:团队间即时通讯系统TM:租户管理系统MKT:云市场,平台最终期望作为中间平台,通过市场打通内容提供者与最终用户这里对一些DevOps的关键系统协作方式做了一定描述,就不赘述了。最终这个平台同时支撑了公有云与私有云两条线(8月发布第二版),其中公有云目前运行于阿里云上,使用了阿里云的ECS、VPC、EIP等很少的服务种类;而私有云,目前也在一些企业开始试点。当然,过程中,尤其是公有云上遇到了不少问题,举两个例子:我们采用coreos系统作为宿主系统,阿里云的版本很低,只能自建升级服务器,但升级后网卡默认没有启动,且因为一些service未启动问题,导致无法快照。再比如安全组问题,同一安全组的ECS完全不控制的方式,让我们也忙活了很久。参考与总结最后分享下我觉得比较好的一些可参考材料,并对分享做下总结:这个不确定最初是不是Gartner提出的,旨在给DevOps从运营效率、服务、组织、客户价值、业绩维度评估,让企业发现其需要改进的一些点。平台品质属性,很多时候翻译成质量属性,一种属性分类的方法是把在运行时可识别的特性与那些不可识别的特性区分开),另一种方法是把对用户很重要的可见特性与对开发者和维护者很重要的不可见特性区分开,和CAP类似,这些特性有些可叠加,有些则会相互制约,在产品设计时需清楚哪些是您最迫切的。Heroku的12Factor,这些因素为系统的CloudNative目标考虑,让云上云下得到同样的体验,这12因素不能简单的字面理解,要结合您现在的实际运行来看,则会发现其独到的地方,也不要想一蹴而就,只要时刻有这么根弦,在很多选择前面看看这12因素是否有类似的可参考,比如当时我们纠结了很久的,VCS是否使用TBD模式,其实这里面都可以找到相关答案。谷歌的Borg,作为谷歌内部的管理调度核心,支撑着谷歌上万台机器及业务的运行,这个虽然是不开源的,但其设计思路和架构是很容易被找到学习的。参考这个的原因是谷歌本身内部就是容器与微服务架构的生产运用,是一个真正大规模的实践参考。扫描作者二维码加入由作者顾伟主持的“普元云计算研发开放群”,与大牛讨论更多云计算、微服务、DevOps、容器相关内容,加群备注为“云计算”。▽延展阅读(点击标题):喜欢我们的会点赞,爱我们的会分享!今晚8:30,InfoQ大咖说最新直播,等你来看!专题导读:>>>
"devops"相关文章
无相关信息知识杂谈(31)
首先本文不讨论为什么要服务化,包括服务化的优点缺点。
其次本文也不讨论什么是微服务,也不讨论微服务和SOA的区别。
最后本文也不讨论哪个技术最优。
服务框架构成
最基本的服务框架
基本的服务化框架包括如下模块:统一的RPC框架,服务注册中心,管理平台。
有了这三个模块,就能实现基本的服务化。下面对三个模块进行具体分析。
RPC框架选型
为什么一定要是统一的RPC框架,而不是随便啥框架,这里主要是为了技术对齐,减少开发人员的学习成本,减少团队间沟通成本。
好,那么选择一个RPC框架,我们都需要考量什么东西呢?这里我总结下:
代码规范:例如是对已有代码透明,还是代码生成。通讯协议:例如是TCP还是HTTP序列化协议:例如是二进制还是文本,是否需要跨语言,性能IO模型:异步/同步,阻塞/非阻塞负载均衡:客户端软负载,代理模式,服务端负载
另外如果是从开源里面选择,那么我们还需要考量:
成熟度:包括学习成本,社区热度,文档数,是否有团队维护,稳定性(盲目追求的不一定是最适合)可扩展性:是否有SPI支持扩展,是否支持上下兼容跨语言:是否支持跨语言性能:要想作为RPC框架,性能一般都不会太差 [滑稽脸]
下面是常见的一些开源框架的比较,大家可以看一下。
Ps:SOAP,RMI,Hessian,ICE就不列举了。
选型小结:
如果需要与前端交互的,适合短链接、跨语言的RPC框架,例如RESTful、gRPC等如果纯粹后台交互的,适合长链接、序列化为二进制的RPC框架,例如thrift、dubbo等更高效如果是小公司,新公司从头开始推广服务化框架的,可以选择规范化的RPC框架,例如thrift、RESTful、gRPC如果是已有大量业务代码的再推广服务框架的,那么最好选择无代码入侵的RPC框架,例如dubbo、RESTful
注册中心选型
注册中心相当于是服务提供者和服务调用者之间的引路人,在服务治理中的作用极为重要。
选择注册中心基本要考量:
服务注册:接收注册信息的方式服务订阅:返回订阅信息的方式,推还是拉状态检测:检测服务端存活状态
重点提一下这个状态检测,因为这个要是检测不准确会误判,导致严重后果,
例如Zookeeper根据服务端注册的临时节点进行状态检测,如果服务端和Zookeeper之间的网络闪断,导致Zookeeper认为服务端已经死了,从而摘掉这个节点。
但是其实客户端和服务端直接的网络是好的,这样就有可能把节点全部摘掉,导致无可用节点。
如果是从开源里面选择,那么还需要考量:
成熟度:包括学习成本,社区热度,文档数(盲目追求的不一定是最适合)维护成本:注册中心维护数据解构:是否能快速定位结果,是否能遍历性能和稳定性:CAP原则:CP(关注一致性)还是AP(关注可用性)
下面是常见的一些使用开源项目做注册中心的比较,大家可以看一下。
Ps:Redis和MySQL没有列举。
选型小结:
规模小选择CP,RPC框架可以直接接入数据源规模大选择AP, RPC框架不可以直接接入数据源存在跨机房,跨地域的尽量不要选有强一致性协议的注册中心RPC框架必须要有注册中心不可用的容灾策略服务状态检测十分重要
简易管理端
管理端没啥特殊要求,最起码能看到服务提供者和调用者即可。
完善的服务化框架
如果需要一个完善的服务化框架,那么必须增加外部模块,常见的模块如下图:
接口文档管理
提供一个接口文档管理以及接口查询的入口,可以是一个公共的WIKI,也可以是独立的系统,等等。
这里可以定义接口的文档,包括接口描述,方法定义,字段定义
可以定义接口的SLA,包括支持的并发数,tp99多少,建议配置是什么
还有就是接口的负责人等一些查询的入口。
提供一个配置管理的地方,这里说的配置主要指的是服务相关的一些配置。
配置包括分组配置、路由策略、黑白名单、降级开关、限流信息、超时时间、重试次数等等,任何可以动态变更的所有数据。
这样服务提供者和服务调用者可以不需要重启自己的应用,直接进行配置的变更。
配置中心可以独立于注册中心,也可以和注册中心合并。
监控服务关注接口维度,实例(例如所在JVM实例)维度的数据。
RPC框架可以定时上报调用次数,耗时,异常等信息。
监控中心可以统计出服务质量信息,也可以进行监控报警。
分布式跟踪
区别于监控中心,以调用链的模式对服务进行。
RPC框架作为分布式跟踪系统的一个天然埋点,可以很好的进行一个数据输出。
服务治理(重点)
我这边列了常见的服务治理功能,例如:
服务路由:
权重:例如机器配置高的权重高,机器配置低的权重低
IP路由:例如某几台机器只能调某几台机器分组路由:例如自动根据配置调某个分组参数路由:例如根据方法名进行读写分类,或者根据参数走不同的节点机房路由:例如只走同机房,或者同机房优先
调用授权:
应用授权:只有授权后的应用才能调这组服务token:只有token对的调这组服务黑白名单:只有名单允许的才能调这组服务
动态分组:
服务端切分组:可以根据分组的情况,对服务提供者进行一个动态的分组调度客户端切分组:可以对调用者进行一个分组调度
调用限流:
服务端限流:服务端基于令牌桶或者漏桶模型进行限流客户端限流:根据客户端的标识,进行调用次数限流
灰度部署:
灰度上线:先启动,验证后在提供服务预发标识:表示该服务为预发布服务接口测试:方便的提供接口自动化功能测试功能
配置下发:
服务配置全局配置
服务降级:
Mock:出现异常或者测试情况下,返回Mock数据熔断:客户端超时或者服务端超时拒绝服务:服务端压力大时,自动拒绝服务,保护自己
RPC框架大部分场景都是自己调用的,什么时候会需要一个网关呢?
网关可以提供如下功能:
统一的鉴权服务限流服务协议转换:外部协议转统一内部协议Mock:服务测试,降级等
其它一些统一处理逻辑(例如请求解析,响应包装)
服务注册中心Plus
需要逻辑处理能力,例如对数据进行筛选过滤整合,计算服务路由等功能
同时还需要有与RPC框架交互的功能。
管理端Plus
管理端除了之前的简单服务管理功能外,还需要提供配置信息展示,监控信息展示,各种维度的数据展示。
也就是下面提到的服务治理功能,都可以在管理端进行管理。
另外,常见的服务治理功能,我们都可以作为开放服务供开发人员进行一个调用。
第一代SAF背景
2012年初,京东从.NET转Java。各个部门,各个业务线都没有一个统一的服务化框架,有的是dubbo,有的是WebService,有的是Hessian等等。
同时各个业务系统自己有非常多的业务代码。通过统计接口规模在1K左右,服务节点在50K左右,机器规模在8K左右,机房比较少拓扑简单。
所以当时的愿景和目标比较明确:
京东系统服务化、API化的从无到有统一京东的RPC调用框架稳定可靠提供简单的服务治理功能
第一代SAF选择
OK,结合我们的情况和上面的一些选型小结,我们当时的选择如下:
RPC框架:基于dubbo2.3.2做配置扩展,以及功能扩展包括rest(resteasy)、webservice(cxf)、kryo/thrift序列化、调用压缩等注册中心:Zookeeper,RPC框架直接接入数据源监控中心:监控服务+HBase管理平台:读取Zookeeper做管理平台,提供基本的上下线、黑白名单等功能
于2012年4月上线,最大规模时,接口数3K,接入最大IP数20K。
第二代JSF背景
随着京东业务的不断快速增长,接口、机器数也呈数量级增长。
同时京东成立子公司,在全国各地新建机房,部署结构也变得比较复杂。
加上SAF遗留的一些问题,大概面临如下几点:
RPC框架较重,性能有提高的空间注册中心无业务逻辑,直接对外暴露京东复杂的部署架构需要更强大灵活的服务治理功能监控数据不完整,维度不够无应用依赖关系跨语言调用需求
第二代JSF选择
所以在2014年初,我们进行了第二代JSF的一个全部自研过程。
我们主要做了如下技术选型:(全部自研)
RPC框架:轻量级,更佳的性能,兼容旧版本协议注册中心:基于DB作为数据源,前置Index服务;支持十倍接入量;部分逻辑放在注册中心减少客户端负担监控中心:监控Proxy服务+InfluxDB(2015后改为ElasticSearch)管理端:基于DB,功能更强大,提供完善的服务治理管理功能;打通京东应用管理平台,提供应用依赖关系梳理;HTTP网关:基于Netty,支持跨语言调用
开发周期:7人/年(5.1)。包括开发、测试、预发、上线、推广。
JSF架构简图
JSF注册中心
京东的注册中心是自研的,基于DB做的数据最终一致,也就是上面说的AP系统。
注册中心主要实现的就是服务列表的注册订阅推送,服务配置的获取下发,服务状态的实时查看等功能。
注册中心节点是无状态的,可水平扩展的。整个注册中心集群下的所有注册中心几点都是等价的。
每个机房部署多个注册中心节点。同机房的RPC框架会优先连本机房的注册中心节点。
主要亮点如下:
引入Index服务概念
该服务就是一个最简单HTTP的服务,用于找注册中心节点(同机房或者压力最小或者其它特定场景),可以认为是不会挂的服务,RPC框架会优先连该服务拿注册中心地址,这样子的好处是注册中心地址变化后,RPC框架不用修改任何设置。
注册中心内存有服务列表全量缓存,连不上数据库也保证可读
数据库的数据结构更适合各种维度展示、过滤、分析等
例如根据分组,IP,应用,机房等不同维度
注册中心就是个JSF服务,监控到压力大即可进行动态水平扩展
dogfooding,注册中心其实是第一个JSF接口
服务列表推送逻辑改进
例如原来100个Provider,现在加1个节点,之前的SAF是需要下发101个节点,自己判断加了哪个节点,进行长链接建立;现在的改进是:修改为下发一个add事件,告知RPC框架加了1个节点,RPC框架进行长链接建立;这样做大大减少了推送的数据量。
注册中心与RPC框架可各种交互
注册中心和RPC框架是长链接,而且JSF是支持Callback的,注册中心可以调用RPC框架进行服务列表变化之外的操作;例如查看状态,查看配置,配置下发等。
JSF RPC框架
RPC框架作为服务化里面的最基本的组件,其实都大同小异,因为RPC调用都绕不开代理、网络、序列化这些操作。
JSF的RPC框架也类似,主要分为图中的几个模块,
下面大概列下一些功能特性:
Config:Spring/API/AnnotationProxy: Javassist/JDKInvoker/Filter:内置+自定义,Filter可扩展Client:Failover(默认)/FailFast/TransportPinpoint/MultiClientProxy调用方式:同步(默认)/异步并行/异步回调/Callback/泛化Loadbalance:Random(默认)/Roundrobin/ConsistentHash/ LocalPreference/LeastActiveCall路由:参数路由,分组路由,(IP级别路由逻辑在注册中心做)长连接维护:可用/死亡/亚健康协议:JSF(默认)/SAF(dubbo)/HTTP/Telnet/HTTP2第三方:REST/Webservice序列化:MsgPack(默认)/Hessian/Json/Java/protobuf(c++)压缩:Snappy/LZMA网络:基于Netty4.0,长连接复用线程模型:BOSS+WORKER+BIZ容灾:本地文件请求上下文:IP,参数,隐式传参事件监听:响应事件,连接事件,状态事件分布式跟踪支持:进行数据埋点
JSF管理平台
提供强大管理功能,包括服务管理,监控管理,注册中心管理等功能。
我们针对服务治理的功能,提供了很多API,可以授权给开发人员或者外部系统使用。
例如单元测试调用,限流配置/开关,动态分组,上下线等都提供了开放API。
JSF HTTP网关
网关是为了方便跨语言通过HTTP+JSON调用JSF服务,而不需要使用JSF的RPC框架。
特性如下:
基于Netty4.0实现HTTP网关,没有使用Servlet容器,轻量高效。
支持服务自动发现
一般的HTTP服务,外面为了解决单点问题,都会用域名+VIP等实现高可用,故障转移等;现在网关同时原生接入了JSF的注册中心,知道了服务的提供者信息(JSF协议支持HTTP调用)。服务提供者也不用关系扩容缩容导致服务的IP端口发生变化,网关会自动维护服务列表。
针对方法级+应用进行授权,固定时间只能调用指定次数。同一个方法也只能占用网关内的部分线程
结果统一包装
对异常等响应进行包装
JSF遇到京东弹性云
京东的JSF服务开发在京东弹性云的研发推广之前完成,自从京东弹性云落地以来,也遇到不少问题。
硬件指标:例如使用JDK获取的Docker的指标有些是物理机的,我们需要特殊处理网络:结合京东的“胖”容器,每个容器其实有实际IP,对外提供服务轻量:提高启动速度开放服务:在容器销毁或者非优雅停机的情况下,提供API进行服务治理
接口数:万级服务节点数:百万级接入实例数:十万级框架调用量:每天千亿级别监控数据:每天120亿条数据,1.2T数据量HTTP网关:每天百亿级别
没有最好,只有最适合!
意思就是不要人云亦云,盲目看大公司用什么,现在什么最新,或者什么性能最好。因为架构不是让你一下子设计出来使用一辈子,好的架构都是慢慢演化而来的。不同的架构会做出不同的技术选型。所以无论什么时候都要结合自己的现状以及未来几年的规划,来进行技术选型。
It’s just the beginning!
服务化框架的选择只是开始,真正的变革是选择后,公司整体业务和开发的变革。这个大家有空可以看看康威定律。
编辑推荐:架构技术实践系列文章(部分):
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:26705次
积分:1706
积分:1706
排名:第19678名
原创:28篇
转载:562篇

我要回帖

更多关于 客户端和服务端的区别 的文章

 

随机推荐