精华内容
下载资源
问答
  • 美团外卖Android平台化架构演进实践

    千次阅读 2018-03-16 19:23:00
    美团外卖自2013年创建以来,业务一直高速发展。目前美团外卖日完成订单量已突破1800万,成为美团点评最重要的业务之一。美团外卖的用户端入口,从单一的外卖独立App,拓展为外卖、美团、点评等...平台化背景 很早之...

    美团外卖自2013年创建以来,业务一直高速发展。目前美团外卖日完成订单量已突破1800万,成为美团点评最重要的业务之一。美团外卖的用户端入口,从单一的外卖独立App,拓展为外卖、美团、点评等多个App入口。美团外卖所承载的业务,也从单一的餐饮业务,发展到餐饮、超市、生鲜、果蔬、药品、鲜花、蛋糕、跑腿等十多个大品类业务。业务的快速发展对客户端架构不断提出新的挑战。

    平台化背景

    很早之前,外卖作为孵化中的项目只有美团外卖App(下文简称外卖App)一个入口,后来外卖作为一个子频道接入到美团App(下文简称外卖频道),两端业务并行迭代开发。早期为了快速上线,开发同学直接将外卖App的代码拷贝出一份到外卖频道,做了简单的适配就很快接入到美团App了。

    早期外卖App和外卖频道由两个团队分别维护,而在随后一段时间里,两端代码体系差异越来越来大。最后演变成了从网络、图片等基础库到UI控件、类的命名等都不尽相同的两套代码。尽管后来两个团队合并到一起,但历史的差异已经形成,为了优先满足业务需求,很长一段时间内,我们只能在两套代码的基础上不断堆积更多的功能。维护两套代码的成本可想而知,而业务的迅猛发展又使得这一问题越发不可忍受。

    wm_screenshot-w400

    在我们探索解决两端代码复用的同时,业务的发展又对我们提出新的挑战。随着团队成员扩充了数倍,商超生鲜等垂直品类的拆分,以及异地研发团队的建立,外卖客户端的平台化被提上日程。而在此之前,外卖App和外卖频道基本保持单工程开发,这样的模式显然是无法支持多团队协作开发的。因此,我们需要快速将代码重构为支持平台化的多工程模式,同时还要考虑业务模块的解耦,使得新业务可以拷贝现有的代码快速上线。此外,在实施平台化的过程中,两端代码复用的问题还没有解决,如果两端的代码没有统一而直接做平台化业务拆库,必然会导致问题的复杂化。

    在这样的背景下,可以看出我们面临的问题相较于其他平台型App更为特殊和复杂:既要解决外卖业务平台化的问题,又要解决外卖App和外卖频道两端代码复用的问题。

    屡次探索

    在实施平台化和两端代码复用的道路上并非一帆风顺,很多方案只有在尝试之后才知道问题所在。我们多次遇到这样的情况:设计方案完成后,团队已经全身心投入到开发之中,但是由于业务形态发生变化,原有的设计也被迫更改。在不断的探索和实践过程中,我们经历了多个中间阶段。虽然有不少失败的案例,但是也积累了很多架构设计上的宝贵经验,整个团队对业务和架构也有了更深的理解。

    搜索库拆分实践

    早期美团外卖App和美团外卖频道两个团队的合并,带来的最大痛点是代码复用,而非平台化,而在很长的一段时间内,我们也没有想过从平台化的角度去解决两端代码复用的问题。然而代码复用的一些失败尝试,给后续平台化的架构带来了不少宝贵的经验。当时是怎么解决代码复用问题的呢?我们通过和产品、设计同学的沟通,约定了未来的需求,会从需求内容、交互、样式上,两端尽可能的保持一致。经过多次讨论后,团队发起了两端代码复用的技术方案尝试,我们决定将搜索模块从主工程拆分出来,并实现两端代码复用。然而两端的搜索模块代码底层差异很大,BaseActivity和BaseFragment不统一,UI样式不统一,数据Model不统一,图片、网络、埋点不统一,并且两端发版周期也不一致。针对这些问题的解决方案是:

    1. 通过代理屏蔽Activity和Fragment基类不统一的问题;
    2. 两端主工程style覆盖搜索库的UI样式;
    3. 搜索库使用独立的数据Model,上层去做数据适配;
    4. 其他差异通通抛出接口让上层实现;
    5. 和PM沟通尽量使产品需求和发版周期一致。

    架构大致如图:
    wm_search_arch_ne-w716

    虽然搜索库在短期内拆分为独立的工程,并实现了绝大部分的两端代码复用,但是好景不长,仅仅更新过几个版本后,由于需求和版本发布周期的差异,搜索库开始变为两个分支,并且两个分支的差异越来越大,最后代码无法合并而不得不永久维护两个搜索库。搜索库事实上是一次失败的拆分,其中的问题总结起来有三个:

    1. 在两端底层差异巨大的情况下自上而下的强行拆分,导致大量实现和适配留在了两端主工程实现,这样的设计层级混乱,边界模糊,并且极大的增加了业务开发的复杂性;
    2. 寄希望于两端需求和发版周期完全一致这个想法不切实际,如果在架构上不为两端的差异性预留可伸缩的空间,复用最终是难以持续的;
    3. 约定或规范,受限于组织架构和具体执行的个人,不确定性太高。

    页面组件化实践

    在经历过搜索库的失败拆分后,大家认为目前还不具备实现模块整体拆分和复用的条件,因此我们走向了另一个方向,即实现页面的组件化以达成部分组件复用的目标。页面组件化的设计思路是:

    1. 将页面拆分为粒度更小的组件,组件内部除了包含UI实现,还包含数据层和逻辑层;
    2. 组件提供个性化配置满足两端差异需求,如果无法满足再通过代理抛到上层处理。

    页面组件化是一个良好的设计,但它主要适用于解决Activity巨大化的问题。由于底层差异巨大的情况,使得页面组件化很难实现大规模的复用,复用效率低。另一方面,页面组件化也没有为2端差异性预留可伸缩的空间。

    MVP分层复用实践

    我们还尝试过运用设计模式解决两端代码复用的问题。想法是将代码分为易变的和稳定的两部分,易变部分在两端上层实现差异化处理,稳定部分可以在下层实现复用。方案的主要设计思路是:

    1. 借鉴Clean MVP架构,根据职责将代码拆分为Presenter,Data Repository,Use Case,View,Model等角色;
    2. UI、动画、数据请求等逻辑在下层仅保留接口,在上层实现并注入到下层;
    3. 对于两端不一致的数据Model,通过转换器适配为下层统一的模型。

    架构大致如图:
    wm_mvp_arch-w614

    这是一种灵活、优雅的设计,能够实现部分代码的复用,并能解决两端基础库和UI等差异。这个方案在首页和二级频道页的部分模块使用了一段时间,但是因为学习成本较高等原因推广比较缓慢。另外,这个时期平台化已被提上日程,业务痛点决定了我们必须快速实施模块整体的拆分和复用,而优雅的设计模式并不适合解决这一类问题。即使从复用性的角度来看,这样的设计也会使得业务开发变得更为复杂、调试困难,对于新人来说难以胜任,最终推广落地困难。

    中间层实践

    通过多次实践,我们认识到要实现两端代码复用,基础库的统一是必然的工作,是其他一切工作的基础。否则必然导致复杂和难以维护的设计,最终导致两端复用无法快速推进下去。

    计算机界有一句名言:“计算机科学领域的任何问题都可以通过增加一个中间层来解决。”(原始版本出自计算机科学家David Wheeler)我们当然有想过通过中间层设计屏蔽两端的基础库差异。例如网络库,外卖App基于Volley实现,外卖频道基于Retrofit实现。我们曾经在Volley和Retrofit之上封装了一层网络框架,对外暴露统一的接口,上层可以切换底层依赖Volley或是Retrofit。但这个中间层并没有上线,最终我们将两端的网络库统一成了Retrofit。这里面有多个原因:首先Retrofit本身就是较高层次的封装,并且拥有优雅的设计模式,理论上我们很难封装一套扩展性更强的接口;其次长期来看底层网络框架变更的风险极低,并且适配网络层的各种插件也是一件费时费力的事情,因此保持网络中间层的性价比极低;此外将两端的网络请求都替换为中间层接口,显然工作量远大于只保留一端的依赖。

    通过实践我们认识到,中间层设计是一把双刃剑。如果基础框架本身的扩展性足够强,中间层设计就显得多此一举,甚至丧失了原有框架的良好特性。

    平台化实践

    好的架构源于不停地衍变,而非设计。对于外卖Android客户端的平台化架构构建也是经历了同样的过程。我们从考虑如何解决代码复用的问题,逐渐的衍变成如何去解决代码复用和平台化的两个问题。而实际上外卖平台化正是解决两端代码复用的一剂良药。我们通过建立外卖平台,将现有的外卖业务降级为一个频道,将外卖业务以aar的形式分别接入到外卖平台和美团平台,这样在解决外卖平台化的同时,代码复用的问题也将得到完美的解决。

    平台化架构

    经过了整整一年的艰苦奋斗,形成了如图所示的美团外卖Android客户端平台化架构:
    wm_architecture_ne-w692

    从底层到高层依次为平台层、业务层和宿主层。

    1. 平台层的内容包括,承载上层的数据通信和页面跳转;提供外卖核心服务,例如商品管理、订单管理、购物车管理等;提供配置管理服务;提供统一的基础设施能力,例如网络、图片、监控、报警、定位、分享、热修、埋点、Crash上报等;提供其他管理能力,例如生命周期管理、组件化等。
    2. 业务层的内容包括,外卖业务和垂直业务。
    3. 宿主层的内容包括,Waimai App壳和美团外卖频道Waimai-channel壳,这一层用于Application的初始化、dex加载和其他各种必要的组件或基础库的初始化。

    在构建平台化架构的过程中,我们遇到这样一个问题,如何长久的维持我们平台化架构的层级边界。试想,如果所有的代码都在一个工程里面开发,通过包名、约定去规范层级边界,任何一个紧急的需求都可能破坏层级边界。维持层级边界的最好办法是什么?我们的经验是工程隔离。平台化的每一层都去做工程隔离,业务层的每个业务都建立自己的工程库,实现工程隔离。同时,配套编译脚本,检查业务库之间是否存在相互依赖关系。工程隔离的好处是显而易见的:

    1. 每个工程都可以独立编译、独立打包;
    2. 每个工程内部的修改,不会影响其他工程;
    3. 业务库工程可以快速拆分出来,集成到其他App中。

    但工程隔离带来的另一个问题是,同层间的业务库需要通信怎么办?这时候就需要提供业务库通信框架来解决这个问题。

    业务库通信框架

    在拆分外卖商家业务库的时候,我们就发这样一个案例:在商家页有一个业务,当发现当前商家是打烊的,就会弹出一个浮层,推荐相似的商家列表,而在我们之前划分的外卖子业务库里面,相似商家列表应该是属于页面库里面的内容。那怎么让商家业务库访问到页面库里面的代码呢。如果我们将商家库去依赖页面库,那我们的层级边界就会被打破,我们的依赖关系也会变得复杂。因此我们需要在架构中提供同层间的通信框架,它去解决不打破层级边界的情况下,完成同层间的通信。

    汇总同层间通信的场景,大致上可以划分为:页面的跳转、基本数据类型的传递(包括可序列化的共有类对象的传递)、模块内部自定义方法和类的调用。针对上述情况,在我们的架构里面提供了二种平级间的通信方式:scheme路由和美团自建的ServiceLoaders sdk。scheme路由本质上是利用Android的scheme原理进行通信,ServiceLoader本质上是利用的Java反射机制进行通信。

    scheme路由的调用如图所示:


    wm_uri_router.png

    最终效果:所有业务页面的跳转,都需要通过平台层的scheme路由去分发。通过scheme路由,所有业务都得到解耦,不再需要相互依赖而可以实现页面的跳转和基本数据类型的传递。

    serviceloader的调用如图所示:


    wm_serviceloader_impl.png

    提供方和使用方通过平台层的一个接口作为双方交互的约束。使用方通过平台层的ServiceLoader完成提供方的实现对象获取。这种方式可以解决模块内部自定义方法和类的调用,例如我们之前提到了商家库需要调用页面库代码的问题就可以通过ServiceLoader解决。

    外卖内核模块设计

    在实践的过程中,我们也遇到业务本身上就不好划分层级边界的业务。大家可以从美团外卖三层架构图上,看出外卖业务库,像商家、订单等,是和外卖的垂类业务库是同级的。而实际上外卖业务的子业务是否应该和垂类业务保持同层是一个目前无法确定的事情。

    目前,外卖接入的垂类业务商超业务,是隶属于外卖业务的子频道,它依然依赖着外卖的核心model、核心服务,包括商品管理、订单管理、购物车管理等,因此目前它和外卖业务的商家、订单这样的子业务库同层是没有问题的。但随着商超业务的发展,商超业务未来可能会建设自己的商品管理、订单管理、购物车管理的服务,那么到时商超业务就会上升到和外卖业务一样同层的业务。这时候,外卖核心管理服务,处在平台层,就会导致架构的层级边界变得不再清晰。

    我们的解决办法是通过设计一个属于外卖业务的内核模块来适应未来的变化,内核模块的设计如图:


    wm_business_core.png
    1. 内圈为基础模型类,这些模型类构成了外卖核心业务(从门店→点菜→购物车→订单)的基础;
    2. 中间圈为依赖基础模型类构建的基础服务(CRUD);
    3. 最外圈为外卖的各维度业务,向内依赖基础模型圈和外卖基础服务圈。

    如果未来确定外卖平台需要接入更多和外卖平级的业务,且最内圈都完全不一样,我们将把外卖内核模块上移,在外卖业务子库下建立对内核模块的依赖;如果未来只是有更多的外卖子业务的接入,那就继续保留我们现在的架构;如果未来接入的业务基础模型类一样,但自己的业务服务需要分化,那么我们将对保留内核模块最核心的内圈,并抽象出服务层由外卖和商超上层自己实现真正的服务。

    业务库拆分

    在拆分业务库的时候,我们面临着这样的问题:业务之间的关系是较为复杂的,如何去拆分业务库,才是较为合理的呢?一开始我们准备根据外卖业务核心流程:页面→商家→下单,去拆分外卖业务。但是随着外卖子频道业务的快速发展,子频道业务也建立了自己的研发团队,在页面、商家、下单等环节,也开始建立自己的页面。如果我们仍然按照外卖下单的流程去拆分库,那在同一个库之间,就会有外卖团队和外卖子频道团队共同开发的情况,这样职责边界很不清晰,在实际的开发过程中,肯定会出现理不清的情况。

    我们都知道软件工程领域有所谓的康威定律

    Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations. - Melvin Conway(1967)

    翻译成中文的大概意思是:设计系统的组织,其产生的设计等同于组织之内、组织之间的沟通结构。

    在康威定理的指导下:我们认为技术架构应该反映出团队的组织结构,同时,组织结构的变迁,也应该导致技术架构的演进。美团外卖平台下包含外卖业务和垂直品类业务,对于在我们团队中已经有了组织结构,优先组织结构,去拆出独立的业务库,方便子业务库的同学内部沟通协作,减少他们跨组织沟通的成本。同时,我们将负责外卖业务的大团队,再进一步细化成页面小组、商家小组和订单小组,由这些小组的同学去在外卖业务下完成更细维度的外卖子业务库拆分。根据组织结构划分的业务库,天然的存在业务边界,每个同学都会按照自己业务的目标去继续完善自己的业务库。这样的拆库对内是高内聚,对外是低耦合的,有效的降低了内外沟通协作的成本。

    工程内代码隔离

    在实现工程隔离之后,我们发现工程内部的代码还是可以相互引用的。工程内部如果也不能实现代码的隔离,那么工程内部的边界就是模糊的。我们希望工程内至少能够实现页面级别的代码隔离,因为Activity是组成一个App的页面单元,围绕这个Activity,通常会有大量的代码及资源文件,我们希望这些代码和资源文件是被集中管理的。

    通常我们想到的做法是以module工程为单位的相互隔离,但在module是相对比较重的一个约束,难道每个Activity都要建一个module吗?这样代码结构会变得很复杂,而且针对一些大的业务体,又会形成巨大化的module。

    那我们又想到规范代码,用包名去人为约定,但靠包名约束的代码,边界模糊,时不时的紧急需求,就把包名约定打破了,而且资源文件的摆放也是任意的,迁移成本高。

    那怎么去解决工程内部的边界问题呢?《微信的模块化架构重构实践》一文中提到了一个重要的概念p(pins)工程,p工程可谓是工程内约束代码边界的重要法宝。通过在Gradle里面配置sourceSets,就可以改变工程内的代码结构目录,完成代码的隔离,配置示例:

    sourceSets {
        main {
            def dirs = ['p_widget', 'p_theme',
                        'p_shop', 'p_shopcart',
                        'p_submit_order','p_multperson','p_again_order',
                        'p_location', 'p_log','p_ugc','p_im','p_share']
            dirs.each { dir ->
                java.srcDir("src/$dir/java")
                res.srcDir("src/$dir/res")
            }
        }
    }
    

    效果如图所示:


    wm_p_project.png

    从图上可以可以看出,这个业务库被以页面为单元拆分成了多个p工程,每个p工程的边界都是清楚的,实现了工程内的代码隔离。工程内代码隔离带来的好处显而易见:

    1. p工程实现了最小粒度的代码边界约束;
    2. 工程内模块职责清晰;
    3. 业务模块可以被快速的拆分出来。

    代码复用

    p工程满足了工程内代码隔离的需求,但是别忘了,我们每个模块在外卖两个终端上(外卖App&美团App)上可能存在差异,如果能在模块内部实现两端差异,我们的目标才算达成。基于上述考虑,我们想到了使用Gradle提供的productFlavors来实现两端的差异化。为此,我们需要定义两个flavor:wm和mt。

    productFlavors {
         wm {}
         mt {}
    }
    

    但是,这样生成的p工程是并列的,也就是说,各个p工程中所有的差异化代码都需要被存放在这两个flavor对应的SourceSet下,这岂不是跟模块间代码隔离的理念相违背?理想的结构是在p工程内部进行flavor划分,由p工程内部包容差异化,继续改成Gradle脚本如下:

    productFlavors {
        wm {}
        mt {}
    }
    sourceSets {
        def dirs = ['p_restaurant', 'p_goods_detail', 'p_comment', 'p_compose_order',
                    'p_shopping_cart', 'p_base', 'p_product_set']
        main {
            manifest.srcFile 'src/p_restaurant/main/AndroidManifest.xml'
     dirs.each { dir ->
                java.srcDir("src/${dir}/main/java")
                res.srcDir("src/${dir}/main/res")
            }
        }
        wm {
            dirs.each { dir ->
                java.srcDir("src/${dir}/wm/java")
                res.srcDir("src/${dir}/wm/res")
            }
        }
        mt {
            dirs.each { dir ->
                java.srcDir("src/${dir}/mt/java")
                res.srcDir("src/${dir}/mt/res")
            }
        }
    }
    

    最终工程结构变成如下:


    wm_rsetaurant.png

    通过p工程和flavor的灵活应用,我们最终将业务库配置成以p工程为维度的模块单元,并在p工程内部兼容两端的共性及差异,代码复用被很好的解决了。同时,两端差异的问题是归属在p工程内部自己处理的,并没有建立中间层,或将差异抛给上层壳工程去完成,这样的设计遵守了边界清晰,向下依赖的原则。
    但是,工程内隔离也存在与工程隔离一样的问题:同层级p工程需要通信怎么办?我们在拆分商家库的时候,就面临这这样的问题,商品活动页和商品详情页,可以根据页面维度,去拆分成2个p工程,这两个页面都会用到同一个商品样式的item。如何让同层间商品活动页p工程和商品详情页p工程访问到商品样式item呢?在实际拆库的实践中,我们逐渐的探索出三级工程结构。三级工程结构不仅可以解决工程内p工程通信的问题,而且可以保持架构的灵活性。

    三级工程结构

    三级工程结构,指的是工程→module→p工程的三级结构。我们可以将任何一个非常复杂的业务工程内部划分成若干个独立单元的module工程,同时独立单元的module工程,我们可以继续去划分它内部的独立p工程。因为module是具备编译时的代码隔离的,边界是不容易被打破的,它可以随时升级为一个工程。需要通信的p工程依赖module的主目录,base目录,通过base目录实现通信。工程和module具有编译上隔离代码的能力,p工程具有最小约束代码边界的能力,这样的设计可以使得工程内边界清晰,向下依赖。设计如图所示:
    wm_submodule-w653

    三级工程结构的最大好处就是,每级都可按照需要灵活的升级或降级,这样灵活的升降级,可以随时适应团队组织结构的变化,保持架构拆分合并的灵活性,从而动态的满足了康威定理。

    工程化建设

    平台化一个直观的结果就是产生了很多子库,如何对这些子库进行有效的工程化管理将是一个影响团队研发效率的问题。目前为止,我们从以下两个方面做了改进。

    一键切源码

    主工程集成业务库时,有两种依赖模式:aar依赖和源码依赖。默认是aar依赖,但是在平时开发时,经常需要从aar依赖切换到源码依赖,比如新需求开发、bugfix及排查问题等。正常情况我们需要在各个工程的build.
    中将compile aar手动改为compile project,如果业务库也需要依赖平台库源码,也要做类似的操作。如下图所示:
    wm_sourcecode_denpency-w567

    这样手动操作会带来两个问题:

    1. build.gradle改动频繁,如果开发人员不小心push上去了,将会造成各种冲突。
    2. 当业务库越来越多时,这种改动的成本就越来越大了。

    鉴于这种需求具备通用性,我们开发了一个Gradle插件,通过主工程的一个配置文件(被git ignore),可一键切换至源码依赖。例如需要源码依赖商家库,那么只需要在主工程中将该库的源码依赖开关打开即可。商家库还依赖平台库,默认也是aar依赖,如果想改成源码依赖,也只需把开关打开即可。

    一键打包

    业务库增多以后,构建流程也变得复杂起来,我们交付的产物有两种:外卖App的apk和外卖频道的aar。外卖App的情况会简单一些,在Jenkins上关联各个业务库指定分支的源码,直接打包即可。而外卖频道的情况则比较复杂,因为受到美团平台的一些限制,频道打包不能直接关联各个业务库的源码,只能依赖aar。按照传统做法,需要逐个打业务库的aar,然后统一在频道工程中集成,最后再打频道aar,这样效率实在太低。为此,我们改进了频道的打包流程。如下图所示:
    wm_packaging-w471

    先打平台库aar,打完后自动提PR到各个业务库去修改平台库的版本号,接着再逐个触发业务库去打aar,业务库打完aar之后再自动提PR到频道主库去修改业务库的版本号,等全部业务库aar打完后最后再自动触发打频道主库的aar,至此一键打包完毕。

    平台化总结

    从搜索库拆分的第一次尝试算起,外卖Android客户端在架构上的持续探索和实践已经经历了2年多的时间。起初为了解决两端代码复用的问题,我们尝试过自上而下的强行拆分和复用,但很快就暴露出层次混乱、边界模糊带来的问题,并且认识到如果不能提供两端差异化的解决方案,代码复用是很难持续的。后来我们又尝试过运用设计模式约束边界,先实现解耦再进行复用,但在推广落地过程中认识到复杂的设计很难快速推进下去。

    在平台化开始的时候,团队已经形成了设计简单、边界清晰的架构理念。我们将整体结构划分为宿主层、业务层、平台层,并严格约束层次间的依赖关系。在业务模块拆分的过程中,我们借鉴微信的工程结构方案,按照三级工程结构划分业务边界,实现灵活的代码隔离,并降低了后续模块迁出和迁入成本,使得架构动态满足康威定律。

    在两端代码复用的问题上,我们认识到要实现可持续的代码复用,必须自下向上的逐步统一两端底层的基础依赖,同时又能容易的支持两端上层业务的差异化处理。使用Flavor管理两端的差异代码,尽量减少向上依赖,在具体实施时应用之前积累的解耦设计的经验,从而满足了架构的可伸缩性。

    没有一个方案能获得每个人的赞同。在平台化的实施过程中,团队成员多次对方案选型发生过针锋相对的讨论。这时我们会抛开技术方案,回到问题本身,去重新审视业务的痛点,列出要解决的问题,再回过头来看哪一个方案能够解决问题。虽然我们并不常常这么做,但某些时刻也会强制决策和实施,遇到问题再复盘和调整。

    任何一种设计理念都有其适用场景。我们在不断关注业内一些优秀的架构和设计理念,以及公司内部美团App、点评App团队的平台化实践经验,学习和借鉴了许多优秀的设计思想,但也由于盲目滥用踩过不少坑。我们认识到架构的选择正如其他技术问题一样,应该是面向问题的,而不是面向技术本身。架构的演进必须在理论和实践中交替前行,脱离了其中一个谈论架构,都将是个悲剧。

    展望

    平台化之后,各业务团队的协作关系和开发流程都发生了很大转变。在如何提升平台支持能力,如何保持架构的稳定性,如何使得各业务进一步解耦等问题上,我们又将面对新的问题和挑战。其中有三个问题是亟待我们解决的:

    1. 要确保在长期的业务迭代中架构不被破坏,除了流程规范之外,还需要在本地编译、远程提交、代码合并、打包提测等各个阶段建立更健全的检查工具来约束,而目前这些工具链还并不完善。
    2. 插件化架构是平台型App集成的最好方式,不仅使得子业务具备动态发布的能力,还可以解决令人头疼的编译速度问题。目前美团平台已经在部分业务上较好的实现了插件化集成,外卖正在跟进。
    3. 统一页面级开发的标准化框架,可以解决代码的可维护性、可测试性,和更细粒度的可复用性,并且有利于各种自动化方案的实施。目前我们正在部分业务尝试,后续会持续推进。

    参考资料

    1. MVP + Clean Architecture
    2. 58同城沈剑:好的架构源于不停地衍变,而非设计
    3. 每个架构师都应该研究下康威定理
    4. 微服务架构的理论基础 - 康威定律
    5. 架构的本质是管理复杂性,微服务本身也是架构演化的结果
    6. 微信Android模块化架构重构实践
    7. 配置构建变体
    8. 美团App 插件化实践

    作者简介

    吴凯,美团点评技术专家。2016年加入美团点评,目前负责外卖用户端Android团队,主要致力于外卖Android平台化业务支持和技术建设。

    晓飞,美团点评资深工程师。2015年加入原美团,是外卖Android的早期开发者之一,目前作为外卖Android App负责人,主要负责平台和业务架构。

    海冰,美团点评高级工程师。2015年加入原美团,曾支持开店宝等B端业务,目前作为外卖Android App主力开发,负责商家容器模块,及平台化相关推进工作。

    招聘

    美团外卖长期招聘Android、iOS、FE 高级/资深工程师和技术专家,base 北京、上海、成都,欢迎有兴趣的同学投递简历到wukai05#meituan.com。




    发现文章有错误、对内容有疑问,都可以关注美团点评技术团队微信公众号(meituantech),在后台给我们留言。我们每周会挑选出一位热心小伙伴,送上一份精美的小礼品。快来扫码关注我们吧!

    展开全文
  • P2P平台架构基于组件化架构设计

    千次阅读 2015-01-26 15:04:50
    P2P平台架构基于组件化架构设计

     

    の

     

    首先对上图做一个解释:

     

     

    在组件化架构设计中,需要遵循如下一些原则,这些原则有些属于传统分层架构设计中的原则:

    web层调用服务器代理进入逻辑层,逻辑层调用持久层,不应该出现逆向调用。

    业务组件间的调用,或说跨模块的调用需要通过服务组件暴露的服务接口进行,跨模块调用建议尽量是同层调用为主,即A模块的逻辑层只能调用B模块的逻辑层,而不能调用B模块的数据层。如果存在对B模块数据层的调用应该转化为B模块的业务服务后暴露到逻辑层。

    对于数据库也需要考虑隔离和解耦,为了达到这点,尽量减少对数据库存储过程和关联视图的使用,数据库基本不承载任何的业务规则和逻辑。对数据库中的公用基础数据剥离到公用业务组件中。

    对于系统管理,组织,权限,流程等转化为独立的平台层基础组件,为各个业务组件都需要依赖的组件。基础平台层能力如权限,安全,流程,日志等一定要抽取为公用的独立基础组件,业务组件不在承担这部分内容。

    不一定要引入复杂的ESB,但是系统内部基于IOC或OSGI模式来实现总线式集成和组件热插拔。

    各层提供的服务存在分级,数据层提供数据服务,逻辑层提供业务服务,UI层提供UI组件服务。平台层提供基础的技术服务和流程服务等。

    如果在DDD领域驱动架构设计下,数据层转化为基础架构层,业务层转化为领域层,整体思路仍然不变。而领域驱动设计中的应用层转化为组件集成和整合层。

    将跨系统的流程整合的概念引入到系统内部,各个业务组件即可以理解为独立的子系统,可以考虑这些子系统间如何通过服务组装和集成解决流程整合的问题,但是并不一定要用到BPEL。

    在这种原则下,业务组件之间本身也不存在交叉依赖,业务组件之间的依赖关系是一种多层传递关系,如A组件依赖B组件,B组件依赖C组件。对于整个组件依赖关系建议是一种倒金字塔的结构,这样可以实现最大化的组件独立部署。

     

    组件化技术架构

    前面已经对组件化技术架构做了一定的描述,在此再进行一些关键点的说明。首先对于企业级的应用系统开发建议还是采用标准的MVC模式。对于SSH框架在做一点说明是,对于ORM数据持久化,可以考虑使用Hibernate还是轻量灵活一点的iBatis来做。对于struts和spring没有过多的说明,struts考虑尽量多使用标签库或对标签库进行模板化定义。对于Web展现层框架,可以考虑使用jQuery来或其它来做。

    传统Web展现层,不管是jsp页面还是html较难以实现Web展现层的独立打包和组件化管理。这也是Web展现层引入sitemesh框架的一个重要意义。

    对于软总线这块,其实Spring和IOC机制已经实现了内部的一种软总线,软总线重点是负责组件,接口的注册,寻找,装载,调用等机制。在内部软总线这块,需要考虑是否引入OSGI软总线,类总线重点解决是内部类接口的反射调用问题,偏白盒层面。而OSGI软总线解决的是组件的独立建设,部署,管理和升级的问题,偏黑盒层面。OSGI软总线将更容易从物理逻辑层面来体现组件化架构和组件热插拔的概念。

     

     

    对于SOA架构,其核心还是在于组件化和服务化,然后才是服务管控和治理,基于服务化思想对传统软件开发生命周期过程的改进。SOA架构大家刚接触时候很容易将其理解为一种单纯的技术架构,或者更多的人仅仅是将SOA理解为service服务接口,这些都是对SOA方法论很大的误解。

    SOA技术架构不要考虑的太复杂,其本质仍然是组件化和领域服务设计思想下,可复用组件设计,服务接口的设计这些传统软件架构设计的内容。目的就是首先要解耦,其次才是解耦后的组件能够快速的装配。这些思想没有理解而一下进入到单个服务识别或接口的设计,那就很难从全局来掌握整个SOA架构的合理性。

     

     

    通信框架如下:

     

    展开全文
  • 淘宝的电商系统是业内标杆、TOP1,十多年前浩浩荡荡做平台化、商品系统首当其冲。这样的经验足可以史为鉴。 1.现状背景 Detail当前的问题可参见《Detail2.0介绍》(2014年7月),本文不赘述。而Detail新平台的目标...

    本文来自阿里巴巴技术协会(ATA)精选集。淘宝的电商系统是业内标杆、TOP1,十多年前浩浩荡荡做平台化、商品系统首当其冲。这样的经验足可以史为鉴。

     

    1.    现状背景

    Detail当前的问题可参见《Detail2.0介绍》(2014年7月),本文不赘述。而Detail新平台的目标是提升协作效率/稳定性/扩展性,倡导商品详情业务归一,能横向复用在其它Detail也能运用在非Detail场景。从产品到研发等各维度均展开梳理和重构,采取模块化、SDK/API等方式来定义协作和扩展机制,并提供合成和分组两种部署模式,以应对创新业务快速多变的需求。并在稳定性和性能方面进行统一封装管理和工具的插件式注入,使之常态化和标准化。

     

    2.    名词定义

    什么是模块

    模块是具备可部署、可管理、可重用、可组合、无状态等特性,遵循统一规范且提供对外接口的软件单元。

     

    什么是平台

    平台是一套完整的技术体系和架构,具备可重用、可维护、可扩展、可协作等特性,能规范研发阶段的各项工作,最终支撑物种多样化、个性化等业务目标。

     

    模块与平台

    可以发现模块的特性与平台所追求的特性是一致的。模块是微观的具体实现单位,而平台则是宏观上的体系架构。模块化是构建平台的基本元素和方法,故两者并不冲突。以模块化理念解决当前面临的各项问题,对系统进行模块改造,再对模块库进行组织、调度,并提升除研发外其它各维度的能力以实现最终平台化。

     

    3.    设计理念

    (仅针对当前场景,普适原则不赘述)

    分而治之

    是解决复杂问题的有效方式,模块化便是具体的实现方法。模块更具可重用性、可维护性,控制复杂度、易于理解等,特别是共建(多团队协作)和需求多变的场景下。而当今Java平台,无论OSGi或Jigsaw等都还在发展中(细节不赘述) ,但模块化理念和模式是通用的,只要对系统进行良好的设计和拆分,无论采用何种模块化方法都能受益。所以,自主设计一套轻量级模块规范是本次平台化的切入点。

     

    框架治理

    事实证明,以口述或文档等方式制定的技术规范都是弱规范,会被日积月累的无序行为致使架构积重难返。所以推崇通过框架定义标准,使研发过程和实现得以规范化。但框架除了按规范去约束,也要允许在同样规范下开放。对无序行为的治理,就如同大禹治水,并不能完全的堵也要疏。所以,模块框架是规范的具体体现,框架会很轻很薄的对基础部份规范,但框架更多的是支撑开放和扩展。

     

    模块粒度

    在本方案的模块认定中,一个模块是无关逻辑封装粒度、表现形式的,而是只要可被重用、接受模块框架管理的便是模块。不关心内部逻辑、代码分层等,只关心真正对外暴露的部份是否遵循模块规范。

     

    平台定位

    相对IC/TC/UIC等,商品详情绝非一个同类型的基础平台,因其并非位于淘宝架构的底层,且没有直接属于自身的数据,而是基于后端服务通过“逻辑再封装(注)”及“编排各服务“实现的上层业务系统。从更优雅长远的角度,就只应承担后端逻辑服务的“编排者”一职,不能有具体的业务逻辑实现。

    注:商品详情的业务逻辑主要靠后端服务化接口提供,但因后端接口封装度较低等历史原因,仍有约10%以上(比率视各后端接口而不同)的逻辑“残留”在Detail上。虽然Detail系统内部也可分出业务逻辑层、数据访问层等,但从淘宝大架构视图分析,Detail仅是各业务系统和基础平台的表现层之一。

     

    4.    平台化

    4.1.前后端分离

    Detail因历史问题,有大量业务逻辑散落在包括JS代码和VM模板在内的前端层。使得前端层复杂而又臃肿,可维护性差;也使得后端对逻辑的控制能力减弱,可重用性低;同时前后端在协作时因边界模糊和过程依赖,使得研发效率降低。为解决这些问题,商品详情平台化项目首先便进行了前后端分离(或称解耦)。

     

    针对浏览型系统,可将逻辑划分为:后端的业务逻辑、前端的展现和交互逻辑(统称体验逻辑)。业务逻辑产出业务数据,展现逻辑负责模板渲染、交互逻辑响应用户行为。前后端分离就是要将业务和体验逻辑解耦,将业务逻辑完全下沉由后端控制,提升可重用性,将展现和交互的表达交给前端层负责,各司其职。

     

     

    前后端分离只将逻辑解耦,但前后端并没有因此而失去互动,后端的业务数据接口便成为前后端的通信管道。所以平台化项目接着便对接口进行了规范性定义,包括:模型定义(入参和结果模型等)、安全机制(授权与鉴权等)、调用协议(HTTP/RPC)、返回格式(JSON/JSONP等),并支持且推荐Java本地的原生方式。

     

    商品详情前后端分离之后,后端在业务规则和功能领域便更具操控性,而前端也能专注于用户体验,且前后端在协作时只需遵循统一规范,即可并行展开各自的逻辑实现,如下图,职责边界清晰,有助效率提升。

     

    前后端分离也请关注Midway

     

    4.2.模块改造

    平台化项目中设计实现的模块规范和框架,用于将整块架构的应用(monolithic)拆解为模块服务级应用。模块框架是通过对源类的轻量级再封装以实现统一管理,包括管理类的生命周期/输入/输出/调用模式/稳定性等。不侵入逻辑不关心类的分层和设计模式等,事实上不依赖模块框架,如将框架废弃源类仍能运行。

     

    核心构成

    • AbstractModule 是所有模块的基类,每个模块加载到独立的Classloader以避免冲突

    • 通过LifecycleListener 可以监听模块生命周期

    • ExtensionPoint 是可扩展入口,以注解(@annotation)方式声明

    • Extension 是扩展实现的基类

     

    代码实现

    • 模块基本定义

    public final class ExampleModule extends AbstractModule  /*implements LifecycleListener*/ {

    @Override

    protected ExampleResult execute(RunData data, ModuleContext context) throws ModuleException {

        //...

    }

    }

     

    • 模块最少描述

    #module.properties 需与模块同层

    Module-Class=ExampleModule@1.0.0

    Module-Requires=XxxModule@1.0.1,YyyModule,ZzzModule

    #or Module-Local=XxxModule@1.0.1,YyyModule,ZzzModule

    Module-Description=anything

     

    生命周期定义

     

    生命周期监听(optional)

    public interface LifecycleListener extends EventListener {

    public void changed(Event event);

    }

     

    模块容器

    模块容器主要将原本已通过模块框架暴露的本地接口,发布为服务化接口,提供了丰富的远程调用协议,并对服务化后的接口进行安全包装,支持服务化后的批量处理等功能,即未采用模块容器的模块只支持本地调用。除服务化一系列的支持外,模块容器也提供了模块管理的钩子,但模块管理这部份暂时尚未实现。

     

    配套工具

    针对模块的生命周期和版本进行管理,以及开发阶段的IDE插件等工具。还在开发中。

     

    插件体系

    将日志工具(如slf4j)、稳定性工具(如Switch)、参数校验、模块流程编排等常用的类库,以插件形式融入模块框架,保持各模块在开发时能使用一致,以降低开发成本和提高可维护性。类库在统一定义的接口下适配成插件,目的是保障如果需要替换或升级一款类库后,模块内的代码不用任何改动。现日志、开关框架已完成插件化。

    (近期针对模块化进行部份改造优化,后续会针对模块规范和框架实现再单独详细介绍)

     

    4.3.代码重构

    详情项目基于上述模块规范,再对业务逻辑重新梳理、对原有代码彻底重构,并按共建型、模块化、可扩展的设计思路重新分层。在新的层次中,每一层内的每一点在逻辑实现后,凡向上暴露接口时均以模块方式表达,上层通过模块描述发现下层能力。整个平台运行在模块容器上,模块容器运行在应用服务器之上。

     

     

    4.4.稳定性

    淘宝商品详情前辈们在多年稳定性实践中积累了丰富的经验,并沉淀了包括静态化/异步化/单元化等全局架构,平台化项目在继续受益延用的同时也在代码层做了统一性和标准性的优化,目标稳定性治理常态化。

    • 模块的安装卸载,保障模块级稳定性,使得最少有一层保护

    • 模块被手工或自动卸载后,可降级其它许可版本或触发容灾

    • 模块内有否实现容灾会在模块安装前被校验,使之成为必然

    • 在批量执行模块时(常见场景),模块框架可并发执行并为每个模块设定不同的超时时长以提升性能

    • 因各层通过模块框架组织,而模块框架支持稳定性框架以插件的形式嵌入,使得各模块能统一使用

    • 新的平台分层里,上层调用二方服务必需通过Adapter层(此层不开放共建,主要是将外部服务进行符合模块规范的适配并未有多余的逻辑)。在适配层进行对外部服务的统一稳定性治理,包括开关降级/容灾/超时控制等。使之前但凡要调用外部服务就直接使用就造成需多次稳定性治理的情况得以改善,降低维护成本。Adpater层内各模块或其它各层的模块,也能针对来源设定不同的限流阀值

     

    4.5.测试体系

    Detail受历史原因也碍于代码的分层结构和代码的不规范性,未能实现行之有效的测试方案,所以测试工作回归量大、重复劳动、枯燥无味、效率低下。而平台化项目针对现状重新整理了Detail的技术质量体系。

     

    分层测试

    根据代码分层,技术质量维度也进行了对等的分层单元测试。各层主要包括:基础服务层(如DAO/Util等)、业务逻辑层(如Service/Manager等)、对外接口层(此层进行接口级测试)、页面展现层等。而Detail场景大都是依赖更后端的服务化接口,所以在Detail新平台的单元测试中为提升效率引入了PowerMock框架。

     

    自动方式

    除页面展现层外,其它各层均实施自动化测试方式,而页面展现层更多的还是需要通过手工介入方式来进行功能测试。能够代替手工测试、找出重复测试工作是进行自动化方式的思路。而在衡量自动化测试目标时,也应从追求自动化覆盖率,到追求正确率、关注运行时间、测试脚本可重用性等,进行全方位的提升。

     

    持续集成

    基于分层单元测试、自动化测试,才能实现最终的持续集成。持续集成平台通过跟踪代码库的变更而自动执行测试用例、静态扫描等,这样便能快速发现问题,当然也要在环境部署之前触发,同时持续集成平台还应支持执行对应的用例,比如,只修改了AbcUtil.java那么则只执行AbcUtilTest.java。将持续集成定义为常态化,设进标准流程,融入日常工作,不断有所追求,最终高效保障淘宝商品详情平台的技术质量。

     

    4.6.研发模式

    没有规矩,不成方圆。商品详情平台作为一个设计完整的平台,还针对各维度定义出一套规范(或称标准)、针对各阶段设计出一套流程,以指导平台化后的研发模式。包括:模块开发规范、提测标准、质量标准(包括业务逻辑质量标准、性能标准、稳定性标准、安全标准、可维护标准也包括运维)、发布流程(含紧急发布流程)、线上问题处理规范,这些规范和流程面向参与平台建设的所有前后端开发、测试、运维等各角色。

     

    规范是必需要建立起来的指导原则,在通过商品详情平台化的实践后,针对规范的落地也更有理由相信:

    1、设计再良好的架构,也是需要依靠合适的组织结构去保障的;

    2、架构的认同、执行、维护,最终需转变团队成员的思想,这是一个过程;

    3、尽量将规范和流程用以工具、示例等更形象更直接方式表达。

     

    另一方面,在共享共建大背景下,平台在搭建之初也针对共建进行设计,无论是共建理念定位、模块逻辑结构、物理部署方式,再到各维度能力的协同。以下便是经过模块化改造后商品详情平台的共建研发模式:

     

    商品详情新平台提供两种协作模式:

    1、 独立模块级共建

    默认共建方式。各方基于Aone二方库进行共建,一个二方库即一个模块,二方Jar包即模块单元,二方库内代码实现需符合模块规范才可被识别和部署。该方式在研发过程和部署方式上更灵活,更可管理,共建方的可控性更强,但对于Detail主维护团队所提供的平台底层扩展能力(即SDK)要求较高。

     

    2、 源码分支级共建

    多人基于同一个源码工程,通过开多个分支的方式,在各分支上实现业务逻辑,最终各个分支在整体合并后进行部署。优势是允许从底层能力至上层业务更大范围内进行编码,更具连贯和顺畅性,但缺点是分支和流程冲突大难以协调、业务理解能力和编码实现习惯各有不同,容易逐渐造成架构被腐蚀。

     

    商品详情新平台更加关注“共建方体验”,在新架构和新研发模式的基础上,共建方将得到如下体验和权力:

     

    4.7.部署结构

    平台逻辑架构和部署物理结构,因所面临的问题领域和解决方式各不相同,所以不能互相限制对方的最终形态,即不能因为平台逻辑架构而绑死最后部署结构,这是平台化项目的架构设计基本原则之一。更何况在业务高速发展,需求多变,团队协作的特定场景,更是要求部署模式也一样的灵活,按需定制,可组合。

     

     

    5.    Use Cases

    成功案例

    农业Detail全部承载

    挑食Detail全部承载

    虾米Detail全部承载,暂未上线

    旅行Detail部份后端接口

    等等……

     

    其它业务场景

    高速业务场景:针对大型的垂直业务或快速发展的业务,在除主站Detail集群即主平台外,只需采购所需的业务模块(也可远程调用),就可以在独立集群再进行部署,业务方只需关注自身模块的开发迭代,其余的模块包括基础框架均由Detail团队负责推送更新,便可自行掌控所有权限和节奏,还能共享同一套CDN静态化体系。如当业务成熟、需求逐渐减少,认为有必要时,只需向Detail团队提供模块即可回归主平台。

     

    无线终端场景:某APP或HTML 5端需要部份接口,Detail直接提供远程服务或将所需要的模块接入MTOP

     

    非详情的场景:某页面需展现SKU,可将Detail前后端的SKU模块拿走,从后端数据到前端渲染及SKU选择计算就统统包括;某页面非商品详情但需展现卖家档案可结构略不同,则复用卖家档案模块,前端部份自行实现。复用时可直接拿走卖家档案模块包自行部署提,也可找Detail团队先沟通后直接调远程服务

    等等……

     


    =>更多文章请参考《中国互联网业务研发体系架构指南》

    https://blog.csdn.net/Ture010Love/article/details/104381157

    =>更多行业权威架构案例、领域标准及技术趋势请关注微信公众号 '软件真理与光':

    公众号:关注更多实时动态
    更多权威内容关注公众号:软件真理与光
    展开全文
  • 该主题介绍交易平台化的背景,要解决的问题,解决方案上的思考以及整个架构的蓝图。后面会介绍一下在平台化建设过程中的一个技术实践,引入CPS理念,通过自动化分析及处理,提高系统的吞吐能力并降低请求的响应时间...

    天猫交易平台的架构演变及并行化实践


    淘宝的交易系统,经过服务化改造之后,在一定程度上解决了原来大而全型架构的诟病。该主题介绍交易平台化的背景,要解决的问题,解决方案上的思考以及整个架构的蓝图。后面会介绍一下在平台化建设过程中的一个技术实践,引入CPS理念,通过自动化分析及处理,提高系统的吞吐能力并降低请求的响应时间。


    详细解读 和小伙伴们一起来吐槽

    展开全文
  • 接口自动测试平台架构

    千次阅读 2018-11-14 04:17:28
    接口自动测试平台架构
  • 小米大数据平台OLAP架构 演进 一、数据仓库 1、离线数据仓库的架构 数据仓库一般架构 分析型系统进行联机数据分析,一般的数据来源是数据仓库,而数据仓库的数据来源为可操作型系统,可操作型 系统的数据来源...
  • 直播平台整体架构

    千次阅读 2016-12-08 11:31:58
    直播平台整体架构
  • 服务标准,流程个性,交互人性
  • 组件化架构剖析

    千次阅读 2016-10-10 18:03:55
    组件化架构的由来 随着移动互联网的不断发展,很多程序代码量和业务越来越多,现有架构已经不适合公司业务的发展速度了,很多都面临着重构的问题。 在公司项目开发中,如果项目比较小,普通的单工程+MVC架构就可以...
  • KVM 虚拟化架构和实现原理

    万次阅读 2016-07-07 18:42:50
    KVM虚拟化架构 devkvm QEMU KVM的虚拟化实现KVM虚拟化架构KVM是嵌入在Linux操作系统标准内核中的一个虚拟化模块,它能够将一个Linux标准内核转换成为一个VMM,嵌有KVM模块的Linux标准内核可以支持通过kvm tools来...
  • 物联网平台架构设计

    万次阅读 多人点赞 2017-09-11 14:13:28
    用户如何管理,数据包如何解析,大数据如何展示等也是物联网模块中非常重要的部分,所以作者就根据自身工作中总结出来的建构在云端的物联网平台基本架构分享给大家,并基于此架构如何一步一步来开发
  • 共享平台逻辑架构设计

    千次阅读 2017-05-02 09:08:19
    共享平台逻辑架构设计   如上图所示为本次共享资源...整体应用系统通过SOA面向服务管理架构模式实现应用组件的有效整合,完成应用系统的统一管理与维护。 2 应用资源采集 整体应用系统资源统一分为两类,具
  • 虚拟化架构图解

    千次阅读 2020-02-25 14:56:10
    虚拟化架构 全虚拟化架构 客户机操作系统不宿主机操作系统的限制 操作系统层的虚拟化 客户机操作系统必须要和宿主机操作系统保持一致 平台虚拟化(硬件虚拟化) 无需安装宿主机操作系统,客户机操作系统可以随意进行...
  • 大数据平台基础架构指南

    万次阅读 2018-07-07 13:03:39
    之前的文章,整理了一下,补充了一些内容,做了一些更新,现已出版上市了。...目录列表:第1章 大数据平台整体建设思想 11.1 什么是大数据平台 11.2 大数据平台的建设目标 31.2.1 别人的大数据平台是怎样的 31.2....
  • SAP云平台架构概述

    千次阅读 2018-08-29 12:09:39
    在我们开始SAP云平台架构之旅之前,让我们先看看SAP已经发布的一些其他云产品。这些云产品方案可以分为公有云和私有云两种。 SAP公有云解决方案见下图最右侧,比较著名的有SAP SuccessFactors和SAP Cloud for ...
  • 针对开放平台架构理解

    千次阅读 2020-05-13 23:30:21
    背景 随着阿理,拼多多,微信…等...平台架构 对外接口层 主要用于与外面业务平台的一个对接(包括收集平台认证及用户信息) 服务层 根据开放平台的每一个接口和收集的用户进行针对性的配置,包括缓存策略,限流策略
  • 物联网平台架构

    千次阅读 2018-03-05 09:12:45
    物联网很久之前就提出了这个概念,现在也是在继续加速发展的过程中,物联网名叫IOT(Internet of Things),学术点来说是一个基于互联网、传统电信...现从学习中总结出来的建构在云端的物联网平台基本架构进行分享。...
  • 互联网金融平台微服务架构设计

    千次阅读 2017-09-29 18:06:11
    互联网金融平台微服务架构设计  按照孢子框架要义对互联网金融理财平台进行微服务架构设计。假设我们设计的目标是5年后的陆金所(https://www.lu.com/)。陆金所简介,平安集团旗下理财平台,是中国最大的网络...
  • UGC平台架构

    千次阅读 2017-12-26 20:26:59
    端到端的视频UGC核心路径技术方案梳理 一、目标 以UC账号为基础,从视频上传、视频存储、视频...二、架构思考 1、客户端架构 2、服务端架构 三、概要技术方案 1、架构大图 2、核
  • 外卖客户端容器化架构的演进

    千次阅读 2020-09-30 20:01:48
    总第413篇2020年 第37篇好的架构要不断演变,进而去适应业务的发展。美团在移动端上的架构,也经历了组件化、平台化、RN混合化,到现在开始向容器化变迁。容器化架构充分地利用了现在的跨...
  • 运维平台基本架构

    千次阅读 2018-06-26 09:20:15
    什么是思通运维企业级自动运维监控平台?思通运维企业级自动运维监控平台,是一个以Zabbix为底层核心进行二次开发的开源企业级运维监控平台。主要为金融行业、跨国企业及政府机构提供全面的IT运维服务,根据客户...
  • 平台架构

    千次阅读 2016-10-31 09:49:27
    整理自云架构分享:罗立树 【云起源和云技术】 亚马逊经过多年的深耕积累,发展成为了云行业的标杆企业,甚至是建立了云解决方案的标准。 在云领域,也存在相应的开源解决方案,在开源的云解决方案里...
  • 平台的层次架构

    万次阅读 2019-03-19 15:03:04
    云计算平台 ​ 云计算是一种资源的服务模式,该模式可以实现随时随地、便捷按需地从...​ 经典云计算架构包括IaaS ( Infrastructure as a Service,基础设施即服务)、PaaS ( Platform as a Service,平台即服务)、S...
  • 平台架构概述

    万次阅读 2018-01-11 10:23:03
    平台架构概述:  首先应明白建立云平台的目的,与传统的服务器相比,云平台可以将物理资源虚拟化为虚拟机资源池,灵活调用软硬件资源,实现对用户的按需访问。而且在运行过程中根据用户并发量不同,实时迁移...
  • 对于建设平台架构,首先应注重对它的工程设计和管理,而且要用比产品和项目更加严谨的工程思想,来进行平台构架的规划、设计、落实和演进。 1、工程 在度娘搜索了一下,关于工程,没有找到更合适的、权威...
  • 消息推送作为移动 APP 运营中的一项关键技术,已经被越来越广泛的运用。...实践中,借助于该平台,不仅能提能显著提高消息到达率,还能提高研发效率,并道出了移动开发基础设施的平台化架构思路。 推送基础...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 518,813
精华内容 207,525
关键字:

平台化架构