架构师小组交流会:每期选一个时下最热门的技术话题进行实践经验分享。java
第三期:微服务。微服务架构以其高度的弹性、灵活性和效率的巨大提高,快速受到各领域架构师和技术决策者的关注。它的基本理念是将一个肥大的系统拆分红若干小的服务组件,组件之间的通信采用轻量的协议完成。咱们本期小组交流会来探讨一下,如今互联网公司的微服务实践状况。python
嘉宾:京东章耿、原惟品会石廷鑫、七牛陈爱珍数据库
本文是对这次交流的整理,分了上下两篇文章。json
第一轮:自由交流后端
京东章耿:你们好,我是京东基础架构部平台中间件的章耿,主要负责京东的服务框架,配置中心等项目。京东11年末进行.NET转Java的技术变革,当时就提出了接口的SOA化的概念。那时京东业务发展很是快,项目愈来愈多,服务化是必然的趋势。京东的服务化框架是一共有两代。第一代是12年开始,咱们使用开源的一个实现,用Dubbo做为RPC框架,Zookeeper 做为注册中心,那时应该算一个主流的技术选型。咱们在开源的基础上作了一些易用性和功能扩展,好比说支持REST、支持kryo/thrift等序列化,服务监控等,这个框架在那时的业务规模和节点数量下面仍是比较稳定的。14年初咱们开始自研服务框架。为何这么作呢?一个是以前的服务框架仍是有不少能够提高的地方,无论是性能仍是服务治理的一些功能,由于京东的机器数,机房也在不停的建,网络拓扑的复杂直接须要高级的服务治理功能;还有一个就是接口节点等数量级的增长,当时咱们的接口规模慢慢的已经好几千了,接口的实例也几十万;另外就是用开源的有些内部系统打通比较麻烦,因此咱们要作升级换代。当时也是考量了用开源的改改,仍是所有本身从新作的抉择。后来以为一个是有时间,二是以为本身有能力作一个符合京东本身的定制化的服务框架,因此14年咱们就开始自研框架,作了整整一年。15年初咱们上线新版的服务框架。服务器
咱们新的注册中心,是无状态的一些节点,基于数据库作最终一致性。为何选数据库,替换之前的Zookeeper?由于Zookeeper是树状结构,从某些维度查询它要遍历整棵数,用数据库的好处就是能够从多维度的查询分析过滤,无论是机房、 IP,均可以去查询,分析,过滤比较结果。而后Zookeeper在跨机房的时候有一个问题,它是半数节点存活才能够用,因此若是跨机房部署的话,最起码得3个机房,才能保证集群总体可用。还有Zookeeper它是强一致性的的,比较依赖网络。若是网络很差,若是跨机房断网的时候,它实际上是不可用的,读都不能读,因此会带来必定的问题。之前用zookeeper注册服务端,就是写一个临时节点,等服务端死了节点自动消失的。可是你在网络一抖的时候,或者是服务端和Zookeeper之间有网络故障的时候,它其实会不当心把它摘掉,由于Zookeeper认为它死了,但其实它不必定真的死了,因此这个时候就须要有一些辅助的去判断它是否是真的死了。第一次遇到的状况是那个临时节点,后来咱们是把它改为永久节点,而后定时的去telnet 它的端口,像Dubbo是直执行ls 命令,咱们也是直接执行一个命令,看它有没有响应,那是第一代的时候。在JSF的框架里有一个哨兵的组件,咱们的Provider会定时的发心跳,对于注册中心来讲,它知道最后的心跳时间,而后定时刷到数据库里面,看哨兵的状况,若是没有哨兵,数据库里面保存一个最后心跳时间,这时候你能够用定时任务去找它,这是咱们最先的一个版本。后来咱们改进了,由于有时断网了,这个心跳时间就不许了。因此在每一个机房还布了一套独立的程序,没心跳的同时再由它来判断是否可用,若是这个同机房的程序都连不上,咱们再把它置成一个不可用的状态,双重保证。另外之前Zookeeper的时候服务列表是下发的全量列表,例如1000台加一台,下发的是1001台,而新版注册中心咱们是推变化的部分,只推加1台,大大节省了数据的推送量。网络
RPC框架,咱们内部叫杰夫,JSF,京东服务框架的简称。咱们是用基于Netty本身研发的。为了兼容上一代版本,兼容以前的dubbo协议,因此咱们也是用的无代码入侵的;咱们在同一个端口支持多协议,包括自定义的JSF协议,http协议,dubbo协议等。目前咱们只有C++和Java的客户端,而后若是是其它语言例如Golang,python,PHP的话,咱们都会让他向咱们的一个HTTP的网关发请求,这个网关主要就是转发。把前面的http请求转换到后面一个JSF请求,也是基于Netty作的。序列化默认是Message Pack,是个跨语言的协议,也支持hessian,json,Java,Protobuf等。注册中心和RPC框架直接是长链接,能够进行一个通信。架构
惟品会石廷鑫:你们好,我是石廷鑫,原来在京东、惟品会,如今在宅急送。我基本上都是在仓储物流这方面。之前在亚洲一号是按照仓库的整个操做细节分红各个模块来作的服务拆分,每一个模块是单独部署的。仓储的每一个仓,根据种品类不同,整个的操做流程是不同的。可是核心的东西,如库存、订单管理,都是同样的,只是一些组合不同。举个例子,小件商品上下架都要作的,可是对于大件商品,好比说你们电,基本上都不须要放架。打订单也不须要,完成配送才须要订单,其实是到了最后才绑定订单。因此每一个流程不同,须要的组合也不同。那时咱们就想到了,把每一个模块先拆出来,主要是用KVM运行整个节点,业务部分就用这些节点来整个串联起来。核心的东西好比说库存、订单、商品资料,基本上都是用这个简单的模块。并发
惟品会的仓储也是按这种思路来作的。当时惟品会用的是Dropwizard,其实是咱们用了它的一个壳,后面仍是用的Spring,也作了一个模块,把Spring集成到一块。后来Springboot作了出来,基本上就把Dropwizard抛弃掉了。由于Dropwizard版本升级变化比较大。但它有一个好处,就是Bundle比较好,服务化拆分的时候能够根据它的大小进行可分可合,若是不须要拆分的时候,咱们就把Bundle合到一块,若是须要拆分的话,就把Bundle再拆出来,单独这个应用是很是容易的。负载均衡
我去年到的宅急送,咱们的服务注册、服务发现、网关都使用的Spring Cloud的这一套。目前来讲仍是不错的,基本没发现大的毛病。惟一的问题是若是前期没有作好的整个数据抽取,整个报表可能会比较麻烦一些。
七牛陈爱珍:你们好,我是七牛的陈爱珍。微服务架构的设计理念很是适合七牛的业务特色,每一个服务只负责单一的职责。好比音视频的处理服务:音视频转码 , 音视频拼接 , 视频帧缩略图,点播流式转码,都是以微服务的方式构建,这样每一个服务都拥有独立的运行环境,而且能够根据自身的业务压力状况进行独立扩展,动态的弹性扩展还能够提升资源的利用率。一个可落地的微服务架构应该为微服务提供独立的运行环境,调度框架,注册中心,配置管理中心和监控平台。 七牛采用的是Mesos+Docker+自研调度系统的架构。Docker作环境封将,Mesos作资源调度,自研的调度系统负责对Docker进行弹性的调度。
咱们使用Consul作注册中心,实现服务的注册与发现。Consul自带key/value存储,可经过DNS接口作服务发现,且具体健康检查的功能,并支持跨数据中心的服务发现。API Gateway 能够经过 Consul提供的DNS接口查询到服务全部的可用实例的列表信息,并将请求进行转发。流量转发具备负载均衡的功能,采用的是轮询的方式,服务发现则是基于Consul作的。用户请求进来后经过Consul查询到全部可用节点的访问地址,再经过轮询的方式将请求发给后端的服务进行处理,对于返回的结果仅做转发,由请求方解释和使用。而且在API网关中带有监控的组件,对请求数,失败数等进行监控,传送到Prometheus服务器上。经过监控数据对请求进行流量控制及服务降级等相应的处理。
当须要调用多个微服务时,根据七牛云的数据处理的业务特色咱们使用管道(pipeline)来进行串行的处理。每个微服务的输出都是下一个微服务的输入,直到最后一个微服务执行结束才是最终数据处理的内容。好比上传一个视频资源后,须要作两个数据处理操做: 转成mp4资源和进行HLS切片,这种场景下不能对原资源同时执行两个数据处理的操做,必须按序执行。
第二轮:话题交流
主持人:服务与服务之间的依赖关系怎么管理?服务编排怎么作?把这些服务节点串起来。
惟品会石廷鑫:比方说不是业务的,基础服务,如图片服务器这些,都是独立的。惟一相关的是下面的业务层和底下的基础服务有之间调用,还有是业务模块之间有服务的调用,在系统里是没作体现的,可是咱们在服务和服务之间,就加了相似于熔断的那个默认的东西。系统之间的依赖关系,咱们本身作了一个简单的系统进行维护。Spring cloud eureka是都是存在内存里,咱们改良过,我都改到一个数据库。咱们交互所有都是Rest ,咱们后边还写过一套,Google protobuf。咱们仓储的内部的业务模块之间是用Google protobuf来作的。咱们自个作了一套虚拟化的在里边的。
惟品会石廷鑫:我如今用的是Apache camel作编排,能够用DSL描述把服务串起来。其实更多的是业务的流程怎么组织,怎么去把基础服务让串起来,造成一个真正大的业务场景。
京东章耿:目前京东大部分一个接口一个方法就已是操做多张表了,通常认为是一个比较原子性的操做了,若是再在外面有一个东西把它包一下,例如把3个方法包成一个方法,其实意义不大,因此咱们如今是没有作这方面的工做。另外京东有弹性云,用的Docker,不过不是大家想象中那种微服的那个Docker用法,京东如今用叫“胖容器”,更像一个虚拟机同样的一个东西。Docker里面运行的是一个应用,而后这个应用,它可能包含多个接口多个方法。可能你们理解微服务的Docker用法应该是一个容器里面,他只跑一个独立的逻辑,对数据的一个操做,或者对一个资源的操做。好比说下订单、扣库存,这两步操做,他可能跑了两个容器。把它编排成一个service的这种,咱们好像没有这种。
主持人:服务拆分是怎么作的?
京东章耿:京东如今的服务其实也是没拆太细,主要仍是业务部门本身控制服务粒度。京东的业务仍是比较复杂的,各个应用之间互相依赖,互相调用,每一个操做基本都会涉及到不少资源的变动,像微服务推崇的那种对单一资源的操做,基本上没有。说实话,这种大型互联网公司里面的服务根本就微不起来的,不可能像RESTful同样,对一个资源的一个put post 操做基本不可能,咱们如今都是力度仍是由使用咱们框架的研发人员本身定的,而后通常他们都是根据这种方法之间的一些关联性或者原子性,或者是扩展性来进行组合或者拆分。因此咱们通常叫本身服务化框架,不叫微服务框架。另外他们可能还会考虑一些服务是否能够独立部署,拆的时候可能会考虑一下这些。
主持人:其实不少大型电商互联网也拆不开,也不能称之微服务,是那种服务力度很粗,而后每一个服务号有若干个接口,其实耦合性很高的合在一块儿,相关度很高,数据都在一块儿。
京东章耿:都差很少,都是业务开发本身来折分服务粒度的。就像刚才说的下单。确定是一次要操做好多表的。业务开发认为这是几回表操做实际上是一个下单的原子操做,那么他就拆到这么细了。
惟品会石廷鑫:咱们服务不是说一个部一个,实际上它是和数据域相关的,都搁到一块。
惟品会石廷鑫:按功能分的,功能跟功能之间调用,若是不是同一个数据域里边的,仍是用RPC来调用的。
京东章耿:那个听起来很美好,你想咱们如今这样拆,都已经上万了接口,方法基本都上十万了。你这样拆的话,起码乘以10的接口,并且这样搞的话就得整个公司都要动用很是很是大的能力去搞好这个事情。
主持人:单体他若是拆成像市场上去提倡的那种微服务,其实他对内部的消耗是很是大的,由于咱们不少的服务内部的调用,实际上是很是频繁,若是都把它拆开了去独立部署的话,它其实对网络的消耗是要求很是高的。
惟品会石廷鑫:就是最难的点,一开始你是拆不开这个数据。
主持人:数据只要能拆开,你什么都好干。你只要能把数据粒度拆的很细的话,那就没问题了,那也能作的很细,但就是拆不开。其实好多数据都是陈年老表,都是很都是从原来系统继承下来的,就很难拆。
惟品会石廷鑫:因此新作一个系统还能够。要作这个老系统计划很难的,拆个表就要拆数日。
京东章耿:并且是数据量比较少,而后逻辑比较简单的,例如那种创业型公司,使用开源的方案,这种能够很方便。
主持人:在双11时各个电商确定会有大型的促销,这时服务的压力确定会有很大的增加,怎么解决服务的伸缩的问题?
惟品会石廷鑫:就像咱们这边的话,就看哪一个基点的压力比较大一些,而后你多布几个基点就能够了。如今基本上都是中泰的那个,就是Spring cloud那套。扩展都是提早先作一步。自动扩的话,就是至关于咱们租了一个相似于简单的监控。就是根据他的实例,而后由于微服务,咱们如今是Spring cloud ,基本上都是java -jar,而后本身启就得了,反正那个jar,你能够放到一个公用的地,远程java -jar要干架就起来了,监控的时候根据他的量,而后随时能够启就好了。
京东章耿:京东的服务发布都是挂在应用下面的,而应用发布的平台其实会和各个系统打通,好比说数据库受权的系统,而后自动挂VIP的一些系统,挂监控平台,日志系统等。而后咱们还有个监控平台,监控一些指标,例如机器状况,应用状况,还有本身业务埋点的性能等数据。至于服务是否有压力,都是本身评估,本身提早扩展。 通常大促前会进行大规模的压测,他们本身压测,而后根据结果本身扩就能够了。京东是没有开自动弹性扩展的,基本都是大促前提早申请容器,而后提早扩完。
惟品会石廷鑫:并发量大的业务都是放在公有云,双十一比日常多了两倍的机器,咱们只买 了一个月的云主机。临时用几天,结束就不用了。