微服务架构在二手交易平台(转转)中的实践

本文根据ArchSummit北京2016大会分享整理

下面由我跟大家分享微服务架构在二手交易平台(转转)中的实践。大家知道微服务架构现在是非常火热的一个话题,具体在交易平台里面它是怎么应用实践的,接下来的45分钟我会和大家深入的探讨一下这个问题。在进入这个问题之前首先允许我介绍一下自己,刚才在开场时我已经介绍了,我是58集团技术委员会主席。我加入58做IM相关的东西,后来做二手电商转转相关的东西,在58也算是老员工了,在58工作将近5年多的时间。这几年在58有一些积累,也代表58在一些大会上做了分享。这是我分享时的一些图片,今天有很多同学咱们也碰过面,也很熟悉。非常荣幸能代表58做分享。

接下来就进入今天的主题,会分为几个方面,分享要点:微服务架构特点;为什么使用微服务、它背后的逻辑是怎么样的。重点讲一下围绕这个逻辑、结合我们业务特点,我们的架构该如何演进发展。接下来我会讲一下微服务架构里面我们的通信协议怎么做设计。讲完这个,大家知道微服务里面有很多服务,这个时候服务注册怎么弄、服务发现怎么做。最后我会讲一下,大家知道当你的量比较大的时候,这个时候性能可能会扛不住,那么柔性可用实践怎么做。接下来会讲一下服务治理的问题。大家知道你的系统上线之后仅仅是完成了第一步,那么接下来的时间怎么做保证线上的稳定,我会从这几个方面讲。

图1 微服务架构描述

首先看一下微服务架构。图1是微服务的提出者马丁福勒给我们的解释。首先这是一堆小的服务的集合。每一个服务可以作为一个独立的进程来运行。第三点是什么呢?首先这个微服务是围绕你的业务逻辑来建模,不能说我做一个微服务逻辑划分不清晰。另外一方面,整个服务它可以独立部署。这点很重要。另外一方面就是我要去中心管理。做微服务一定要满足这几点。到底这几点是什么具体含义呢?

第一是服务粒度要比较细。到底我们的服务多细会比较合适呢?比如说代码行数比较少,这算粒度比较细吗?其实不是。代码行数多算吗?也不是。那要怎么定义呢?还是要围绕业务架构来做。我们的服务要追求高内聚,什么意思呢?你的架构、功能如果是因为同一个原因引起的变化就把它聚合在一起,如果是因不同原因引起变化东西就分开。另外就是独立进程,这个很好理解。不管是开发、测试、部署、运行都是要独立完成。还有就是围绕业务建模,到底我们整个微服务该怎么建模?比如说做二手电商,怎么做这个事呢?一定是围绕二手电商特有的业务逻辑来拆分,比如说按照商品、交易、搜索、推荐等垂直业务功能来划分微服务粒度。另外就是轻量级通信,微服务多个服务之间怎么通信就是一个非常重要的问题。我们讲究轻量级通信,微服务之间通信和语言、平台是没有关系的,比如RESTAPI。整个微服务架构的特点,我刚才讲到任何微服务架构一定结合业务来打造,首先我们可以看一下我们的业务。

图2 转转

我们的业务是什么?图2转转。这是我们的logo,今天非常荣幸穿了一个类似的T恤。也是一个熊头。它的需求场景是什么样呢?之前你在各种电商平台是买买买。买了新的东西以后老的东西怎么办呢?对我这种屌丝我就想把它卖出去。那么怎么办呢?你需要通过平台方卖出去,转转就是卖卖卖。这是场景。

图3 转转功能

我们看一下平台功能[图3]。首先要发布商品。发布商品之后要进行分类搜索,然后要做关键词搜索。还要提供用户一些功能场景,就是要推荐商品,根据你个人的兴趣、短期长期行为,来做推荐。作为一个二手电商平台必不可少的就是社交部分,这就是消息中心,包括留言、评论。还有一点就是个人中心,你买了什么东西、卖了什么东西。有了这些功能以后再看一下在实现上该怎么做这个事情。这里有一个总结,首先我们的功能是比较多,包括商品、交易、推荐等等。另外整个业务也是非常复杂的,有搜索、推荐、交易、商品,而且大家知道做一个二手交易平台,用户产品最主要的特点是什么?发展速度非常快。在这种情况下让整个业务更快的支撑它的发展这也是我们为什么选择微服务的原因。另外一点就是用户体验好。如果用户体验不好,如果用户有选择的话他一定会去你的竞争对手那里去使用。

围绕整个微服务架构以及二手交易平台,大家可以看看,我们为了达到这个目的,我们首先要做到系统高可用、系统高扩展性。微服务有什么特点?非常小,这样的话快速迭代非常快,并且要支持持续交付。有了这样的要求和微服务的特点,其实转转使用微服务是比较合理的。这是我们的使用原因。

图4 微服务架构图

接下来看一下微服务架构到底该怎么做。[图4]是一个最理想的情况。第一是App层,它的后面是什么?首先是微服务的网关。网关做什么事情?包括安全检查、用户校验、服务注册/发现。这一层做完之后还需要做什么?就是微服务层1、2、3,这里根据业务建立一个一个微服务,下面就是DB。

大家可以看到,刚才也讲了因为微服务颗粒非常多,这种情况下怎么把微服务串联起来,所以微服务的发现、注册中心是非常重要的。所以右边我们提供了微服务注册中心。这是最理想的整个微服务的架构来去做。那么我们到底是不是采用这个来做的呢?或者说我们做的和这个有什么本质区别?继续往下看。首先我们从整体架构上,因为微服务颗粒非常小,这个时候它是没有水平分层的功能。我们为了让整个系统足够的高可用,引入了水平分层的功能,这是第一点的考虑。第二点,因为你要支持快速迭代,所以整个业务一定会按照业务进行垂直拆分。另外一点每层怎么去做呢,每一层就是一个微服务来去做,按照业务进行拆分,并且在设计时要做成每一个微服务都是无状态化的。因为有状态的话部署、扩展时问题还是非常严重的。再一点,要做微服务要独立进程、部署、运维。那么我们做任何服务都是要考虑的一点就是高可用。要做高可用,如果仅仅是一个单点的话怎么样做其实都不高可用。所以做高可用最主要的点就是冗余,这是一个主要的手段。冗余还不够,比如说要宕机的话,你怎么样保证整个服务自动恢复,这个也是要考虑的一点。所以结合微服务的理想情况以及我们整个架构特点,我们怎么来做呢?这是第一版的微服务整体架构[图5]。

图5 转转微服务系统架构

最上面是App层,就是整个App的一个客户端。接下来是分层。分为四层:微服务网关层、微服务聚合层、微服务原子层以及数据层。网关层做什么事情呢?就是做一个网关,包括安全的校验、业务逻辑的检查等等。还有就是微服务聚合层,聚合层做什么事情呢?我们先不讲这一点,我们先讲微服务原子层做什么。大家知道做二手交易平台业务是非常多的,涉及到商品、交易、推荐、运营,这个时候怎么做微服务?首先按业务单元做了拆分,比如说交易就是一个微服务、搜索就是一个微服务、推荐就是一个微服务。下面对应的是数据单元。这些数据单元,因为你的原子服务颗粒非常小,比如说首页,我要请求的功能非常多,不可能每个都请求一遍原子服务,所以我们在微服务原子层基础之上封装了一层集合层,这样你请求一个接口就好了,由聚合层再请求所需要的多个原子层并进行组装。比如说你需要商品、搜索、推荐,对App层执行一个接口就可以了,到聚合层帮你组织起来,可以认为是proxy代理层。这是多了一层聚合层。为什么要做这一层?就是让服务高可用、性能更高。接下来是轻量级通信,包括http和rpc两种方式。然后管理时要做去中心化管理,开发语言是java。在微服务架构上我们支持去中心化管理,但是最终实施是基于java做的。最后就是微服务注册与发现。后面我会讲到这两点。这是第一版架构。

第一版架构之后我们肯定会演进。演进存在的问题,我们看一下二手交易的特点,业务发展快、业务越来越复杂、研发人员增多、开发瓶颈集中在微服务聚合层。比如说10个人同时对这个模块进行开发,虽然采取分支开发的策略,实际上成本还是非常高的。我们只有一个进程,所以很快你会遇到瓶颈。这个瓶颈怎么扩展呢?比如交易遇到瓶颈,你能对交易进行扩展么?不能。你没有办法对每一逻辑单元做拆分,所以扩展性是非常差的。针对这个情况怎么做呢?既然你是一个单个微服务聚合层,我们能不能把单微服务聚合层变成多个微服务聚合层呢?一定是可以的。这个时候就变成多个微服务聚合层。怎么拆分的呢?单个微服务聚合层变成多个微服务聚合层。做完这个转变之后,微服务聚合层变成了多个服务,多服务之间独立的开发、测试、部署、运行都是非常方便的,不会存在耦合性问题。既然是比较独立的,我刚才说得问题就不存在了,这个时候效率也是高效的。比如说要对商品开发,很简单的,直接开发商品聚合层就行,其他聚合层没有任何的耦合。这是第二版[图6]。

图6 转转微服务系统架构演进

现在我们在做第三版演进,整个方向是什么呢?还是这个方向,只不过把微服务粒度拆的更细。我们现在是做进一步的拆分。目前第三版架构演进在落地实施中。

接下来讲一下通信协议怎么做选择。这是业内用的比较多的一些通信协议。第一个就是REST API,是基于HTTP协议做的。另外一个就是HAL协议,这个协议是描述协议,是基于REST做这件事情,并且解决了REST资源标准化的问题,亚马逊用的比较多,国内用的不是非常多。另外一个就是RPC。还有一个就是消息队列。消息队列做什么事情呢?发送方和接受方中间加了一层,双方通信变成异步化。每协议都有自己的特点,那我们该怎么选择呢?结合自己的业务特点怎么打造呢?

首先我们整个微服务网关,这也是第一层,第一层我们要考虑到它的易用性、安全性、开发成本。所以在这一层采用了RESTAPI的通信协议。包括HTTPS、JSON。在聚合层、原子层采用了RPC协议,这里就包括SCF、私有协议。对微服务还有两个非常重要的概念就是注册和发现怎么做,对于我们来说我们是需要考虑这两方面的问题,下游怎么让上游发现这是很重要的问题,特别是微服务粒度比较多的情况尤其要考虑。这里就引入了注册中心。注册中心要做什么事情?下游的IP和Port要存储起来,便于上游发现。还有一些配置信息,一旦把你放到注册中心,这时候你的上游就可以发现你的下游,这时候我的微服务发现就变的非常简单了。微服务发现要做什么事情呢?第一有能力让你的上游发现你的下游。另外当你的下游挂了,你的上游要有能力把这个节点剔掉。

图7 微服务发现案例

微服务发现,这里举一个例子[图7],假设微服务1挂掉了,那么微服务网关怎么能把微服务1剔除掉,并且保证零丢失请求。首先我们有注册中心,当你的下游挂了以后,你的注册中心是能知道你的哪个节点挂了,挂了之后就把剔除掉,上游取的时候就可以把它剔除掉,但是这里存在一个问题,发现不是及时的。这时候就会造成你的请求还是会有丢失的。那么如何保证任何一条请求不丢失呢?这个也很简单,因为我的整个上游在去往下游发包时,第一请求失败了,不管是什么原因,失败了以后我的上游服务会做重试,这时候要制定一些规则,我们换台机器重试,从而保证任何请求都不丢失。

图8 柔性可用实际案例

在柔性可用实践上怎么做?作为二手电商平台,虽然我们是去年11月推的,现在只有一年,但实际上流量已经很大了。那么瞬间流量上来以后有可能造成请求崩溃的情况,因为你的服务能力是有限的。我们看几个例子[图8],你们“双十一”都购物吗?都不购物啊。看来都没女朋友。这是一个例子,这是“双十一”时某个电商网站出现的一个情况。各种电商网站都会出现这样的例子,这个怎么办呢?我的服务没能力处理全部,就要做柔性可用。我们的目标是要保证核心服务可用,非核心服务弱可用甚至不可用。什么是核心服务?比如说“双十一”期间什么最重要?一定是交易、下单最重要,那么社交、个人主页这些不重要,这个时候要保证核心服务可用。采用什么手段来做呢?系统层、数据层都要做相应的柔性可用的策略。方式有两种,第一种要达到这个目标,可以拒绝部分请求。第二点更狠,直接把一些边缘的服务关闭掉。但是这种方式不好意思我们没有采用。因为觉得比较low。你要做一个推广、运营,你居然要关闭服务,是不是很low?我们采用的是拒绝部分请求。第一是拒绝部分老请求。请求过来以后首先进行队列,这个时候一旦拥挤了,那么请求出队时时间一定非常长,怎么办?超过1秒直接丢掉,这样保证新的请求可以响应。这个OK吗?不OK。我刚才讲了要保证核心服务可用。这个时候你有可能把核心服务给丢弃掉了。那怎么办呢?我们根据优先级请求方式。非核心请求直接丢弃。那么怎么样保证优先级队列方式呢?比如说这个时候队列已经很长了,我知道需要开启了,那么我们根据预先配置的请求优先级进行开启。最后就是随机拒绝方式。我原来在大学毕业时有一家公司去我们学校招聘,他号称比BAT高两倍的工资。大家都是屌丝嘛,工资高大家都会去投简历。他们说你们投简历可以,但是我们只招10个人。要进行笔试,当时大概去了500多人,但是我们只选择100人面试。他说运气差的不要。500人的简历随机丢弃400份。我当时比较幸运,成为100人中的一人去面试。他告诉我面试要从早上八点到晚上八点,我当时面试到下午4点就体力不支了。我问他,为什么要面试这么久,他说我给你这么高的薪水,你的体力到底行不行!这是一家国外公司,不知道现在怎么样了。这是随机拒绝的方式。

只有系统层面还不够,数据层面往往是更重要的。如果数据层压力比较大怎么办?第一是更新请求。有更新请求不再更新数据库,仅仅Append持久到消息队列和更新缓存。读请求,读要配合着做,仅仅读缓存。问题来了,当整个高峰期过了,怎么样把数据补齐呢?这种情况下还需要把消息队列积累的数据回放到数据库做数据补齐。

虽然说柔性策略设计的很好,但是最终上线时能否自动打开。这个时候就需要系统能够自动打开。怎么自动打开?很重要的一点就是测试。时间原因我就不展开测试了,包括单元测试、接口测试等等。另外一点要保证线上系统可用,所以一定要在线下多演练,甚至有可能的话在线上演练。目前我们没有在线上做演练,更多的是在线下做演练。一定要保证线上可以打开,否则不就是瞎了嘛。

另外讲一下服务治理的问题。服务上线仅仅是万里长征的第一步,服务治理也很重要。为什么需要监控?很简单,要了解进程状态、及时发现问题、掌握主动权。到底要监控什么?两方面:机器资源和进程状态。针对这些问题我们怎么去做?这是我们的一些做法。第一我们要对进程做监控。要保证进程是活着的,否则的话肯定是有问题的。怎么做这个事情?在Linux下面父进程开启一个子进程,如果子进程退出,父进程会收到一个信号子进程挂了。大家知道Linux下supervise工具可以帮你干这个事。当然进程活着并不代表着你的进程还能干活。这种情况下要引入语义监控。还有一点,你的语义监控,你要监控它,假设接口一定是幂等的。你的语义监控不可能所有接口都加上,不加上的话怎么办?要引入错误日志监控。系统的错误正常情况下是一定的(选择高峰期一分钟的错误量作为Base)。我们要监控一分钟日志量条数。还有一个就是数据波动监测,比如说流量上升或者下降10%,通过刚才的方式是发现不了。所以要通过实时监控,同期流量做对比。如果你的流量下降了10%,如果你不监控是很被动的。最后是机器资源方面,监控硬盘、CPU、内存、磁盘资源等。除此之外,我们还采用了一个微服务实时监控手段[图9]。通过实时的方式发现一些异常。比如说黄色是昨天的曲线,红色是代表今天的曲线。大家可以看看平均耗时情况以及请求异常条数。这里可以看到最大的两个毛刺,这就是有问题了。如果我们有可视化的监控手段便于会更及时发现问题,至少没有那么被动。

图9 微服务实时监控

讲完监控手段就看到底怎么做这个事。目前我们在做一些尝试。第一是监控框架采用open-falcon,在此基础上做了定制开发。

今天我讲的内容我这里回顾一下。第一个就是微服务的特点,第二个就是结合微服务的特点以及我们的业务讲到使用原因,第三个就是架构设计及演进,重点分享了通信协议、服务注册/发现,最终我们讲了柔性可用的实践以及微服务治理。

原文发布于微信公众号 - 架构之美(beautyArch)

原文发表时间:2016-12-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏SEO

搜索新规则下,移动端如何优化?

2766
来自专栏腾讯技术工程官方号的专栏

微信朋友圈:应对春节千亿访问量背后的故事

微信朋友圈包括图片和视频两套业务架构组成,朋友圈图片的特点是请求量大、消耗计算资源较多,视频则主要消耗带宽。朋友圈的数据是永远存储的,而且随着业务的快速发展,存...

7233
来自专栏phodal

后台即服务演进史

节选自《Growh:深入浅出全栈工程师》 BaaS(Backend as a Service)是一种新型的云服务,旨在为移动和Web应用提供后端云服务,包括云...

17610
来自专栏CSDN技术头条

如何运用微服务来创建资产管理集成系统

在酒店行业,由于各类系统太过分散,进行整合势在必行。公司系统要与来自不同提供商的各类系统进行交互,这些系统的应用程序接口(API)也各不相同。此外,随着系统中录...

18310
来自专栏DT乱“码”

不错的大数据课程体系(感谢某机构,希望不属于侵权)

阶段一、大数据、云计算 - Hadoop大数据开发技术 课程一、大数据运维之Linux基础 本部分是基础课程,帮大家进入大数据领域打好Linux基础,以便更好地...

3099
来自专栏飞雪无情的博客

Go语言经典库使用分析(一)| 开篇

《Go语言实战》的笔记系列写完了,大概近30篇,15W字。完结后,开始在想下个系列写什么,或者不再是系列,而是零零散散的技巧或者案例等,不过最终还是选择了这个G...

862
来自专栏北京马哥教育

大数据怎样帮助运维工程师实现无死角监控?

今天一大早就看到了一篇文章,叫【大数据对于运维的意义】。该文章基本上是从三个层面阐述的: 工程数据,譬如工单数量,SLA可用性,基础资源,故障率,报警统计 业务...

38611
来自专栏腾讯技术工程官方号的专栏

从蓝光到4K,腾讯视频高码率下载背后的技术

本文讲述架构平台部 TVideo平台从资源,链路、缓存、接入进行调优,有效解决4k高码率视频的二次缓冲问题。

88012
来自专栏Java架构

前阿里P8架构师:精准定制Java架构师学习计划!

可以说,Java是现阶段中国互联网公司中,覆盖度最广的研发语言,掌握了Java技术体系,不管在成熟的大公司,快速发展的公司,还是创业阶段的公司,都能有立足之地。

1424
来自专栏小程序·云开发官方专栏

云开发初探 —— 更简便的小程序开发模式

小程序诞生以来,业界关注小程序前端的技术演进较多,因此众多小程序前端的框架、工具也应运而生,前端开发效率大大提高,而后台的开发技术则关注不多,痛点不少,具体痛在...

50718

扫码关注云+社区