您的位置:首页 > 运维架构 > 网站架构

京东、宅急送的微服务实践分享(下)| 架构师小组交流会

2017-08-07 09:32 344 查看
架构师小组交流会是由国内知名公司技术专家參与的技术交流会,每期选择一个时下最热门的技术话题进行实践经验分享。

第一期:来自沪江、滴滴、蘑菇街、扇贝架构师的 Docker 实践分享

第二期:来自滴滴、微博、唯品会、魅族、点评关于高可用架构的实践分享

第三期:京东、宅急送的微服务实践分享(上)

第三期小组交流会邀请到了国内电商领头羊京东、宅急送技术负责人。在上篇京东、宅急送的微服务实践分享(上)中他们介绍了各自产品的微服务实践。本次他们就 API 网关的设计、服务的 Docker 化、服务測试、持续集成等详细话题展开了讨论。

话题交流

Q:API 网关是怎么设计的?

京东章耿:我们有个 HTTP 的网关,但不是一个对外网服务的一个网关。对外的话业务自己都有一些网关,比如无线有自己的网关,站点有自己的网关。而另外一个公共的开放的是一个叫京东开放平台的网关。

然后我们的网关干嘛用的?主要做的就是一个跨语言支持用的,协议转发和限流。这个网关存在的意义,主要是为了让有的调用端不用杰夫协议,或者不依赖服务端的情况下。来调服务端的服务。最主要就是刚才说那个 HTTP 转成内部协议的一个转发的功能,其次我们在上面做了一个接口级隔离,不要一个接口就把网关搞挂。另一个就是限流,每分钟调多少次。还有授权,曾经的网关转发的做法。通常是比方说相似于一个 VIP。然后前面挂个域名。

然后那个虚 IP 后面挂的服务列表一般都是要手动维护上。而我们的网购自己主动就挂到这个网关上面,就是一个服务发现,还有就是我们的结果,统计方面,我们会统一包装一下,我们的网关主要是做这个功能,如今一天应该是几十亿的调用量。九十台,几乎相同这些。

服务发现是到数据库里面去读服务列表,从注冊中心读出来以后会推给我们的网关。网关跟调用者是相似的。

它事实上也是一个调用者,仅仅只是它是一个代理的调用者。它的服务列表,也是从我们的注冊中心订阅的,不直接连数据库。能够觉得自己是调用者。网关第一次去注冊中心去读,后面的话我们能够推变化的部分。

比方说你原来 1000 台,你要是加了一台,按曾经拉的思路你会拉 1001 台。然后你自己比較一下。多了哪一台。但我们如今不是。我们如今是反向给他推加一台。

这样的话。大量的降低那个。还有网络 IO 的推送。京东章耿:我们想用 nginx+luaw 做一个 HTTP 转我们内部 JSF 协议的,但不是 worker 就是一个进程。会产生非常多长链接。所以我们后来就放弃了。我们如今是基于 nitty 做了一个转发,就是对外是 HTTP,对内就 JSF 协议。也做了一些授权,限流,还有服务之间的线程隔离,服务发现,另一个是结果的包装,包装成标准的 HTTP 的响应。由于像对外网的那些事实上都是有自己的系统,无论你是无线,还是 PC 他都有自己的系统,那个不须要我们做。对第三方的话。它也有当中京东一个开发平台,还有更严格的那个验证,我们这个主要还是做协议转换的 API 网关。

Q:你们怎么验证请求的合法性的。你们採用什么方法?就是就那种效率与安全性的这样的平衡你们怎么做的?

京东章耿:我们是有个授权。就是有个应用 ID,京东是每一个启动的都有个应用 ID,带着那个应用 ID 过来。我们也能够支持头上带 token。京东开放的那种是对外比較严格,我们这个不须要那么严格,反正就看你对象,就看你的网关给谁用了。

Q:你们如今有两种类型。一种是内部之间调用的,另外一部分是外部调用内部的调用你们系统。

京东章耿:那个是开放服务,有些供应商内部的系统,想要调京东的系统,那种就是京东开放服务,是须要 Oauth 认证。

**京东章耿:**HTTP+keepalive 也挺快的,由于它无非就是头上大一点,HTTP 的头大了一点。但假设后台是调 redis 那就比較明显的感觉,那假设后台是一个有个几百毫秒的,那你感觉不到那么明显。假设后台,你这就是读不取一下。读一下 redis,你感觉比較明显。我们这边是用 netty 做的 HTTP 跟二进制都是在同一个port支持的。

Q:你怎么划分,哪些用二进制的。那些用 restful 协议的呢?

京东章耿:那个我们没有强制要求,业务它自己想用什么用什么。

京东章耿:对我们来说,它一启动端线口它就支持这两种协议。启动同一个port。两种协议都支撑的。

Q:你们是怎么区分一种port种协议的呢?

京东章耿:每一个数据包含头上前两位不是模数位吗?它们都有自己的模数位。

然后我们自己协议有自己的模数位,你 HTTP 就是那几个打头的 H。然后我们的 decode 是自己主动装载的,它不是说你能够一開始装载一个什么那是适配器 decode。

当你请求来的时候。你再自己主动装载量,由于我们是超链接,无论你是 HTTP,我们一般都默认开启 keepalive 也是个超链接。

事实上,你能够知道这个长链接相应的是什么协议。

Q:它一般保持稳定的一个超链接,肯定是一种协议持续下去,不可能说动态的变质。

京东章耿:是,看效率要求,事实上 HTTP keepalive 也还能够,性能也还能够,假设不是那种调量特别特别大的话,它效率也还是能够的。然后 debug 的时候可能可读性会好一点。

二进制最大问题还是比較麻烦,特别是,我们如今用 message pack。然后会生成一堆的代理类。模板类,反正问题也比較麻烦。

宅急送石廷鑫:我们都用 Spring cloud 的那一套。然后自个改了一部分东西。像 Consul 好像也和 Zookeeper 一样的问题,所以说后边都改造数据库了。

我如今用的是开源的 eureka。仅仅是后边从属变了。

眼下来说还没发现问题,由于我没有跨机房的问题。假设是跨机房的话。基本上都是数据库同步,两个数据之间同步的问题。

京东章耿:一般我们是有一个功能服务降级,事实上最主要还是业务部门自己的代码实现,那我们事实上有提供一个 mok 功能,就是那在我们配置这边直接配上一个,假设这个接口不可用返回的什么东西有没有开关,这也是能够。可是这个用起来比較少,一般他们自己在业务代码上也是容错的,就是没有说从平台这样的角度去搞,一般都是自己考虑。然后假设是有一个目视跟踪系统的话,就一般的也能够跟踪整个调用链,就会看出来这个。

比方说这个接口它依赖其它的接口,然后京东事实上是没有投资这么细。由于眼下我们分公司跟踪还没有上。我们如今主要是依赖我们内部的一个应用管理系统,我们叫 JOne,有点像自己主动部署。我们每一个进程启动的时候都会带上这个应用 ID,在我们管理端是能看到这个接口是属于哪个应用的,我们仅仅能看到应用级别的。这个应用调了哪些接口?哪些接口依赖?调的那些接口还被谁调用了?到这个级别。

宅急送石廷鑫:我们用 Springcloud。熔断机制的降级处理的话,它有一个统计的接口,基本上按那个规则来做。调用关系的话,一个是我们做了一个 trace ID,就是 google zipkin,它本身有自带的工具。

另一部分就是服务的排层。我们如今就是用 camel 来做的,把这个业务整个来排层次做,大体是这样。

眼下来说,大的情况就是监控时会有一些出常常会出现一些抖动。

就比方说 trace ID 那部分。不能用它自带的 stream 的模式。

我们如今还是用 elk 来做,然后把 trace ID 打出来。然后做了一套简单的监控,相似于模仿它整个 trace 的路径。当然不要用 google 自带的监控,我们发现机器多了自带的监控不太可靠。我们都是做到日志里面。然后用 elk 收集起来。说起来自个做一个监控的调用量,这个就是略微有点延迟。

京东章耿:我们这边近期正在做,然后我们的思路是这样的。有个包放在应用里面,它会输出日志,然后我们有一个日志收集,原来就有日志收集的我们仅仅是扩展了一下。在每台机子上把它收到一个 kafka 里面。然后后面是用一个 storm 去把它读出来,写到 H base 里做分析,然后我们是有个採样率的一个概念,比方说一千次。才写一次,或者是一万次才写一次,做个採样率。

然后终于我们如今是分两部分,刚才说写 H base 是一个离线数据。事实上我们另一些简单样例。就是直接做一些统计,实时的,大概延迟在一分钟左右。

Q:关于服务的 Docker 化有什么进展?

京东章耿:我们主要还是应用级别的 Docker。如今仅仅是说,可能这样的公布模式会改一下。如今是基于一个 Docker VM。比方说你起来以后。事实上整个镜像文件都在那里。然后你弹的时候事实上还是比較慢的。比方我要扩的话,得先创建一个 Docker 的 VM。再把那些东西复制进去,才干有个装机的过程。

就是比較慢一点。可能得分钟级别才干把它给提起来。可是未来我们希望把它改用镜像的那种形式,就你上线完毕以后。生成一个镜像。每次上线。你仅仅须要布一台机器。后面全是复制的一个过程。未来会改成这样。预计今年开发,明年推。如今相当于要布 20 个节点,那相当于是给你 20 个 Docker VM,你上线公布 20 次,未来是希望给你一个,然后你公布一次以后。系统自己主动给你复制 19 个。

并且反正后面服务发现什么这些都是原生的,都是无所谓的。

京东章耿:京东的 Docker 主要解决资源调度的问题。就相当于如今部物理机。你可能自己要须要部署机器 。但 Docker 能够把资源分配均匀一点。用算法给算出来。在分配时不会分到同一个机架上,不会分到同一个主机上,还有不会分到非常繁忙的机器上。这些都会帮你考虑一下。

京东章耿:京东这边是自己有一套部署系统,尽管他没有像你说就镜像这样公布,尽管没这么快。但对于我们开发者上线来说。事实上是一样的,他仅仅须要配一下,然后一点,他 24 台自己主动就上去了,就是有一套工具,也非常快。仅仅只是,他须要提前创建好,比方说你刚才说 20 个,你要提前创建 20 个 VM。

就比镜像的话肯定是要慢在这一步。你镜像的话。你直接拉下来一起,然后能够调度到哪台机子上到个 Docker API 一调,他直接就提起来了。那也是我们未来的改变方向。

七牛陈爱珍:我们的数据处理系统系统上执行的都是 CPU 密集型的计算。获取一个原文件,进行数据处理算法的执行,比方对一个视频进行转码,而在转码的过程中须要大量的 CPU 资源来进行处理。处理完后就能够获得预设的文件样式。不同的数据处理对资源的需求是不一样的,比方获取一个文件的 hash 值,这个处理逻辑非常easy,也没有大量的运算,配置的资源就相对小一些,而视频转码则非常的复杂,配置的资源就会相对多一些。如今在我们的平台上执行了数千种数据处理应用,每种处理的的请求量不一样,比方有些图片处理每秒能够达到数十万的请求量。而有一些则可能是每秒几万的请求量,几千种数据处理应用的高峰期也不一样。有些可能在早上。有些可能在晚上,并且每种处理都会存在突发流量的情况。比方一些电商型的客户,在做大促销时。就会导致图片处理的请求量突增,而一些音视频的客户在会在一些活动时会突然增长对音视频的处理。

这个系统的核心问题是怎样把硬件资源对每一种应用不同高峰期的请求量和突发流量做合理的资源分配。不合理的资源分配就可能会造成资源的浪费,或导致负载过重的机器会宕机,不能及时响应用户的需求。原有的系统架构的资源是静态规划的,也就是把指定的资源给指定的应用使用,而这样的资源的分配往往是依照每一个应用的业务高峰进行规划的,为了应对突发的流量并会预设一定的冗余,那么这样就会须要准备非常多的资源。后来我们使用容器,由于容器能够封装环境,动态迁移,底层使用 Mesos 做资源的调度,这就能够对整个环境按需动态分配。非常好的攻克了资源利用率的问题。

Q:关于服务測试、持续集成,大家分享一下实践经验吧。



京东章耿:持续集成我们这边事实上在编译环节就做了。上线我们这边是有一个灰度上线功能。

我们有一个预公布环节,它能够直接把它标记为预发,然后有个測试平台能够对它进行一个服务的測试。那假设是正式环境的话。那就他就得自己想办法,由于我们如今这个环节是不能随便測试的。由于我无法推断你这个是读还是写,我不能让你随便測。

Q:由于你们是把一个业务系统拆成了非常多这样的服务化的服务去跑。那肯定是要涉及到这样的单元測试、集成測试和业务流的这样的測试,那这样的測试的话你们都是怎么做的呢?

京东章耿:这边都是提前測的。就是你測都没測。那你根本就提不到上线这一步。

你上线的时候必须有一个測试审批通过,事实上他事实上就是已经在线下就測过了。

七牛陈爱珍:我们是基于 Jenkins 做的持续集成。把代码上传到 Github 后,会做自己主动的代码静态检查和单元測试,再做自己主动的集成測试。这样的优点是开发仅仅须要开发代码,不须要构建环境,都是自己主动完毕的,并且反馈的速度也会非常高速。

宅急送石廷鑫:測试环境是由开发者去部署,线上正式环节,是从这个測试环境把报測试通过去的,直接拷贝过去。我觉得 Docker 是解决整个配置的问题,由于生产环境測试环境和开发环境不一样。

配置环境这个东西非常难非常麻烦做的。尽可能就是 UAT 的环境和測试环境,就是用户測试的环境和线上的环境尽量是一样。如今不是有配置管理吗?这三个环境能来回切换。比方说 spring boot 这样的,实际上就是一个 Jar 包命令。Jar 包命令唯一不同的就是它的配置问题。你仅仅要一上线。那边一监控就能够看到。由于你启动时候他有注冊。注冊基本上他要调哪些东西就能看到他注冊的配置。

京东章耿:京东測试环境,预发。线上都是从源代码库里编译为准。主干编译为准,所以说代码应该是一样的。线上配置我们是管理在配置中心。可是眼下我们測试环境就没有这个东西。

预发,线上有配置中心,这个配置中心也集成到我们那个公布平台 JOne 上。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐