链家网房源平台微服务架构实践

Posted InfoQ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链家网房源平台微服务架构实践相关的知识,希望对你有一定的参考价值。

作者|于洋

编辑|小智


链家网从线下化到线上化,从线上化到规模化,背后有一套庞大而复杂的服务系统支持。随着公司的转型升级,业务变化更加的快速而多样化,系统的访问量也随之增加。如何快速的推进业务的发展,保障系统的稳定性?链家网通过实践微服务架构,降低系统复杂度,提高交付效率,并结合自研监控系统保障系统高可用。

永恒的诉求

与其说是诉求,不如说是我们要解决的问题。永恒的诉求,就是解决所有已有的问题。

问题
  1. 影响业务的变化的要素有很多,不同的城市,不同的交易类型,不同的房屋属性,价格的变化等等,都可能影响我们的运营策略。同事,公司自身的业务模式也在不停的转变,例如我们支持直营,加盟,第二品牌等多种模式。

  2. 稳定性的要求,每天早上 8 点 15 万经纪人同时登录的流量挑战以及每天来自内网,外网的数十亿次访问量 Hits。而这是只开通了 28 个城市的情况,目标是面向全国,服务全国 150 万的经纪人,如何以后会同时上线多个城市的流量激增。

  3. 而我们并不是构建一套微服务,而是转型微服务架构,如果使用微服务的架构,对原有业务的影响,重构系统的代价也是一个要考虑的问题.


实践之路

那么下面就带着我们的痛点,开启我们今天的实践之路。

实践之路我们大致概括为四个部分,首先,是选择一个合适的开发利器,符合微服务的需求,使用起来简单,扩展性好,最好学习成本也不高。然后,我重新审视我们现有的架构,分析一下在技术上需要做的取舍,它相对微服务还差什么,需要补充的是什么。接下来,介绍一下我们下功夫最大的,也是最有特色的部分,利用这个平台如何完成可用性的保障的。最后,回到微服务最贴近业务的一个核心“拆”,我们微服务拆分的过程是有分有合的。

实践之基础框架


链家网房源平台微服务架构实践

对比之下,spring boot 有明显优势,它不仅功能强大,易于扩展,而且对于我们现有的架构十分契合,几乎没有迁移成本。相比之下,Jersey 偏向于接口开发,功能性稍差,而 DropWizard 功能齐全,但是内置容器单一,而且有一定的迁移成本。

实践之 spring boot

选定 spring boot 我们就按照 spring boot 的玩法。如果用过 spring cloud 的话就应该知道,基于 spring boot 引入 spring cloud 的话是十分容易的,只需要引入依赖,代码中一行注释就能实现功能的引入。那我们也想在开发中享受这种便利,于是,我们基于 spring boot 扩展了我们大部分中间件产品的接入 starter,从而简化开发过程。

除此之外,我们还利用 spring boot 的 endpoint 扩展了服务的监控能力(监控检查,服务下线等)。这个功能在后面有很多应用。


链家网房源平台微服务架构实践

在开发启动器的时候会让你重新深入地了解一遍这些技术,如何自动接入,怎么简化配置,如何定义 metrics,设计 endpoint 执行 actuator 等等。

个性框架

除此之外,我们还在 boot 的基础上,开了适应于特殊业务场景的开发框架。

以录入一套房子为例,同样的录入流程,租赁还需要关注家具状况。以往的开发过程,需要对录入房子的逻辑做一部分特殊处理,如果是租赁类型,则处理家具相关逻辑。这是一种普遍场景,内部很多业务都有这种需求,针对这个情况,我们开发了我们的个性化框架。该框架的目的是简化开发过程,让开发只关注业务场景,而何种情况下执行何种业务场景,都交给配置中心。


链家网房源平台微服务架构实践

业务请求被控制层拦截,控制器会去配置中心加载对应的类型的数据,然后根据类型定位个性化服务的处理类,执行个性化业务。而个性化业务是否执行依赖于配置的数据,数据变化则业务执行也会切换。例如配置中配置了买卖和租赁两种类型,则买卖和租赁业务都会执行处理家具的逻辑。

当特殊业务依赖城市配置时,可以实现灰度上线;当特殊业务依赖异常配置时,可以实现服务降级。

求同存异

通过对 spring cloud 的调研,全面衡量成本和上下游影响;以及对现有的技术体系功能性评估,我们决定还是在现有的 dubbo+zk 的基础上构建我们的微服务体系。

网关代理

选择了现有的技术,就要面对技术中可能有的缺陷,首先是异构系统的服务发现。我们的实现方案是在网关层做了 dubbo 的代理,通过代理将 dubbo 转换成 http 服务。


链家网房源平台微服务架构实践

为什么做在了网关层而没有让 dubbo 直接有提供 http 的能力,这里要考虑一个负载均衡的问题,我们知道 dubbo 的负载均衡做在了 consumer 端,如果直接让 dubbo 提供服务,那消费者要自己实现负载均衡,这肯定是不现实的。负载由我们做,而做在网关层也符合网关的定义,同时,也给了我们一个机会,实现对外的负载均衡和对内的负载均衡的差异化配置。

服务自治与降级

通过 dubbo 的 echo service 做服务的监控检查。同时提供了服务线下的功能。通过自研框架实现服务的降级。


链家网房源平台微服务架构实践

优雅下线

以前每次上线,都会接到下游系统的大量报警,Dubbo 本身是有优雅停机的功能的,为什么还是有异常报出呢,原因是运维平台不能判断服务的状态,当它使用 stop 脚本没有终止进程的时候,只能强制杀死进程,保证项目能重启成功,导致 hook 根本没有机会执行。我们的方案是重启操作分两步,先下线服务,在重启机器,保证整个服务安全线下并没有流量进入。


链家网房源平台微服务架构实践

监控结合

大多数监控平台只重视“监”不重视“控”。我们研发了一套业务接口级的监控系统。很多时候业务的指标也能反映出系统潜在的问题。并提供了灵活可配置的监控规则和报警规则。除此之外利用服务自治的能力时间监控平台对服务控制的能力。当服务出现异常报警(cpu 过高或响应时间过长),监控平台会根据异常情况选择下线服务,并对下线的服务开始监控检查,一旦监控检查状态恢复,则重新上线服务。从而实现服务的自动恢复功能。


分合有道

在拆分方面,我们遵循以下几个原则:

  • 首先,微不是小,并不是简单的把项目拆小部署就解决问题的。按代码量,按业务数都不能用来划分一个微服务的边界。还是要从项目职责,维护成本,交付周期等多个方面均衡考虑在做拆分整合。

  • 再一个就是要业务完整,一方面不希望同一个业务模型的处理在几个项目中来回转,另一方面,不需要有一个独立部署的服务,没有任何独立的功能。

  • 必要的时候需要做重新的整合,这个过程可能不是拆,而主要是合并。毕竟太多离散的服务既不利于维护,又浪费资源。

跨库查询

拆分之后必然要面临很多问题,首先就是跨库查询问题。单纯的多次接口查询不能解决分页和聚合的问题。我们采用的是迂回的战术,将数据重新聚合,利用搜索完成跨库查询的操作。

分布式事务

不保证分布式事务会有出现数据不一致的情况,单纯的通过后期对账来实现数据一致性,不仅实时性差,而且处理起来也十分复杂。业界也有基于 XA 的两阶段提交的方案,进一步保证分布式事务。但是这种方案效率不是很理想,而且比较好的实现一般都是在商业数据库中。我们采用可靠消息 + 回溯 + 数据对账的模式。通过发送可靠消息,消息发送成功即认为事务成功。消息中间件保证消息到达。如果消费端消费失败则重试。后期还可以通过消息回溯的机制保证重试依然失败的消息。

写在最后
  1. 对于技术选型方面,我们需要根据自己实际情况,因地制宜。能在现有的架构上平滑过渡;

  2. 我们不希望重复造轮子,但是如果觉得所有的轮子都不适合我们,那不妨就造一个适合自己的;

  3. 拆分并不是最终目的,综合考虑项目边界,维护成本,交付周期等再做决定;

  4. 面对拆分后资源离散的问题,有时让他们重新聚合也是一种很好的选择。

最后,我们目前的微服务体系还有很多不足之处,后续还有很大的改进空间。智能化运维,更好的安全体系也都是很重要的方向。

技术的路程没有尽头,我们还在路上。

作者介绍

于洋,链家网高级工程师。负责链家网房源系统的开发设计工作,主导推动微服务架构设计落地。多年传统软件和互联网系统开发设计经验。先后就职于用友,Oracle,阿里。

今日荐文

那个逃离北京的程序员说:我想工作到 70 岁


技术浪潮不断来袭,在技术层出不穷的今天,如何洞悉技术前景显得尤为重要,左耳朵耗子等业内资深专家在极客时间开设针对前沿技术、职业发展、商业思维的付费专栏,现正感恩回馈,199 元专栏现 1 元即可阅读,请识别文末二维码。


以上是关于链家网房源平台微服务架构实践的主要内容,如果未能解决你的问题,请参考以下文章

Go语言在微服务架构上的优势,专访亚信数据平台部工程师——刘旭

58转转孙玄|微服务架构在二手交易平台中的实践

微服务架构的4大设计原则和1个平台实践

从标准到实践,权威解读微服务架构设计

云平台的微服务架构实践

微服务架构可视化平台实践