架构师小组交流会是由国内知名公司技术专家參与的技术交流会,每期选择一个时下最热门的技术话题进行实践经验分享。
第一期:来自沪江、滴滴、蘑菇街、扇贝架构师的 Docker 实践分享
第二期:来自滴滴、微博、惟品会、魅族、点评关于高可用架构的实践分享
第三期:京东、宅急送的微服务实践分享(上)nginx
第三期小组交流会邀请到了国内电商领头羊京东、宅急送技术负责人。在上篇京东、宅急送的微服务实践分享(上)中他们介绍了各自产品的微服务实践。本次他们就 API 网关的设计、服务的 Docker 化、服务測试、持续集成等详细话题展开了讨论。redis
Q:API 网关是怎么设计的?算法
京东章耿:咱们有个 HTTP 的网关,但不是一个对外网服务的一个网关。对外的话业务本身都有一些网关,好比无线有本身的网关,站点有本身的网关。而另一个公共的开放的是一个叫京东开放平台的网关。spring
而后咱们的网关干吗用的?主要作的就是一个跨语言支持用的,协议转发和限流。这个网关存在的意义,主要是为了让有的调用端不用杰夫协议,或者不依赖服务端的状况下。来调服务端的服务。最主要就是刚才说那个 HTTP 转成内部协议的一个转发的功能,其次咱们在上面作了一个接口级隔离,不要一个接口就把网关搞挂。另外一个就是限流,每分钟调多少次。还有受权,曾经的网关转发的作法。一般是比方说类似于一个 VIP。而后前面挂个域名。数据库
而后那个虚 IP 后面挂的服务列表通常都是要手动维护上。而咱们的网购本身主动就挂到这个网关上面,就是一个服务发现,还有就是咱们的结果,统计方面,咱们会统一包装一下,咱们的网关主要是作这个功能,现在一天应该是几十亿的调用量。九十台,几乎相同这些。安全
服务发现是到数据库里面去读服务列表,从注冊中心读出来之后会推给咱们的网关。网关跟调用者是类似的。restful
它事实上也是一个调用者,仅仅只是它是一个代理的调用者。它的服务列表,也是从咱们的注冊中心订阅的,不直接连数据库。可以以为本身是调用者。网关第一次去注冊中心去读,后面的话咱们可以推变化的部分。markdown
比方说你原来 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 上。