网站可扩展架构设计

从公众号转载,关注微信公众号掌握更多技术动态

---------------------------------------------------------------

一、可扩展性架构简介

1.可扩展性是什么

可扩展性指系统为了应对将来需求变化而提供的一种扩展能力,当有新的需求出现时,系统不需要或者仅需要少量修改就可以支持,无须整个系统重构或者重建。由于软件系统固有的多变性,新的需求总会不断提出来,因此可扩展性显得尤其重要。面向对象思想的提出和设计模式的应用,就是为了解决可扩展性带来的问题。

扩展性应该来自真实需求而不是假设将来某天可能需要扩展,因为扩展性的反面就是带来设计的抽象和复杂性及代码量的增加.。极致扩展性的标志,就是需求的新增,不会在原有代码交付物上进行任何形式的修改。

架构设计 时,如果模块划分的不好,一个 N 个模块的系统,它的复杂度就是 N×N(这个在上一讲 介绍的支付宝一代架构中,体现得很明显)。如果再加一个新的模块,复杂度就变成(N+1)×(N+1),系统的复杂度随着功能的数量指数级地上升,这样一来,当系统的规模到 一定程度,复杂度就会失控,导致系统彻底无序。 所以,要支持系统的扩展,架构设计上必须能够控制系统的复杂度,面对新需求,要让系统 复杂度做加法而不是乘法,从而保证系统的调整是局部化和最小化的,所以,业务架构扩展 性的本质是:通过构建合理的模块体系,有效地控制系统复杂度,最小化业务变化引起的系 统调整。

2.良好可扩展性系统的基本条件

(1)正确预测变化

    软件系统在发布后有很大的可能性会发生不断地修改和演进,这就意味着不断有新的需求需要实现,因此如果一个系统在设计之初能够正确的预测到未来需求对系统架构的改变,则在实现需求的时候只需要改变少许代码即可。

    然后“预测”则意味着不可能每次预测都是准确的,如果预测的事情出错,我们期望中的需求迟迟不来,甚至被明确否定,那么基于预测做的架构设计就没什么作用,投入的工作量也就白费了。综合分析,预测变化的复杂性在于:

  • 不能每个设计点都考虑可扩展性。

  • 不能完全不考虑可扩展性。

  • 所有的预测都存在出错的可能性。

    所以说如何把握预测的程度和提升预测结果的准确性,是一件很复杂的事情,而且没有通用的标准可以简单套上去,更多是靠自己的经验、直觉以及对业务的熟悉程度。

    

(2)完美封装变化

    当成功预测变化之后,就需要合适的解决方案去应对变化。

方案一:封装“变化层”和“稳定层”

图片

    

该种方式产生的问题:

  • 如何正确拆分出变化层和稳定层:对于哪些属于变化层,哪些属于稳定层,不同的人有不同的理解

  • 需要设计变化层和稳定层之间的接口:对于稳定层来说,接口肯定是越稳定越好;但对于变化层来说,在有差异的多个实现方式中找出共同点,并且还要保证当加入新的功能时原有的接口设计不需要太大修改,这是一件很复杂的事情。例如,MySQL 的 REPLACE INTO 和 Oracle 的 MERGE INTO 语法和功能有一些差异,那存储层如何向稳定层提供数据访问接口呢?

    

    

    

方案二:提炼出“抽象层”和“实现层”。

    抽象层是稳定的,实现层可以根据具体业务需要定制开发,当加入新的功能时,只需要增加新的实现,无须修改抽象层。这种方案典型的实践就是设计模式和规则引擎。比如设计模式中的“装饰者”模式相比传统的继承来实现功能,确实灵活很多。例如,《设计模式》中装饰者模式的样例“TextView”类的实现,用了装饰者之后,能够灵活地给 TextView 增加额外更多功能,比如可以增加边框、滚动条、背景图片等,这些功能上的组合不影响规则,只需要按照规则实现即可。但装饰者模式相对普通的类实现模式,明显要复杂多了。本来一个函数或者一个类就能搞定的事情,现在要拆分成多个类,而且多个类之间必须按照装饰者模式来设计和调用。

3.扩展性的难点

    系统的流量是每秒 1000 次请求,对数据库的请求量也是每秒 1000 次。如果流 量增加 10 倍,虽然系统可以通过扩容正常服务,数据库却成了瓶颈。再比方说,单机网络 带宽是 50Mbps,那么如果扩容到 30 台机器,前端负载均衡的带宽就超过了千兆带宽的限 制,也会成为瓶颈点。那么系统中存在哪些服务会成为制约系统扩展的重要因素 呢? 

    其实,无状态的服务和组件更易于扩展,而像 MySQL 这种存储服务是有状态的,就比较难以扩展。因为向存储集群中增加或者减少机器时,会涉及大量数据的迁移,而一般传统的关系型数据库都不支持。这就是为什么提升系统扩展性会很复杂的主要原因。 除此之外,从例子中你可以看到,需要站在整体架构的角度,而不仅仅是业务服务器的 角度来考虑系统的扩展性 。所以说,数据库、缓存、依赖的第三方、负载均衡、交换机带 宽等等都是系统扩展时需要考虑的因素。我们要知道系统并发到了某一个量级之后,哪一个 因素会成为我们的瓶颈点,从而针对性地进行扩展

二、打造一个善变的柔性系统

1.系统的构成:模块 + 关系

    模块定义系统都有哪些基本的“玩家”,分别承担什么职责。从业务的角度 看,每个模块都代表了某个业务概念,或者说业务领域。 模块内部由数据和业务逻辑组成,其中数据是核心,业务逻辑围绕着数据,对数据做进一步 加工,方便外部使用。 

  • 从扩展性的角度出发,首先对模块的要求是:定位明确,概念完整。每个模块要有明确的定位,模块有了定位,说明已经想清楚了它的核心职责是什么,这样每个人对它的期望和理解就会一致。在实践中经常会争论一个功能应该放到 A 模块还是 B 模块,表面上看,各有各的道理,谁也说不服谁,但如果对照模块的定位,回 到模块设计的初心,往往很快就能有答案。 定位比较抽象,在具体划分模块职责的时候,要保证模块业务概念的完整性。数据上,模块 需要覆盖对应业务领域的全部数据,比如一个订单模块,它要覆盖所有渠道的订单,包括三 方平台的订单、自有商城的订单、线下门店的订单等,这些不同类型订单的数据模型和实际 数据,都由订单模块负责。 功能上,模块要包含业务领域的全部功能,比如订单模块包含所有订单相关的功能,包括订 单数据的增删改查、订单业务规则校验、订单的状态和生命周期管理等。

  • 其次,模块还要:自成体系,粒度适中。 模块的业务逻辑尽量围绕自身内部数据进行处理,对外部依赖越小,模块的封装性越好,稳定性也越强,不会随着外部模块的调整而调整。 模块的粒度要保持适中,不能为了追求定位清晰,把粒度划分得很小,导致系统的碎片化。 比如系统早期的时候,一般把积分功能放到用户模块里面,不单独构建积分模块,如果 后续积分的概念越来越突出,承载的业务越来越复杂,到时候可以把积分功能分离出来,单独成模块。

    依赖关系定义了模块如何协作,一起完成业务流程,依赖关系实质上体现的是模块的组织结构。如果不对模块的依赖关系做针对性设计的话,依赖关系就是一个多对多的网状结构,一个有 N 个模块的系统,理论上有 N×N 个依赖关系,如果考虑依赖具有方向性,这个数字还要 加倍。 所以,要简化模块的依赖关系,就要同时简化依赖的方向和减少依赖的数量。 

    首先希望模块之间的依赖是单向的,尽量避免相互调用,为什么单向更好呢?我们知 道业务流程是有顺序的,如果模块依赖关系越直观地体现业务流程的顺序,越能帮助人理解,否则会被双向的依赖箭头绕的晕头转向,很难通过模块之间的依赖关系还原实际 业务的处理过程。 

    接下来看下模块的组织结构。网状结构是一种松散的结构,节点之间的依 赖关系比较复杂,一般用于表示非正式的关系,比如人群的社交关系;而层次结构是一种更有序的结构,一般用于表示正式的关系,比如公司内部的人员关系。 在模块的组织结构设计上也是如此,要尽量把网状结构转化为层次结构,模块结构层次化是简化模块依赖关系的有力手段。 

    具体做法就是,按照模块定位的不同,把模块划分为不同层次,比如划分为上面的应用层和下面的资源层。这样,一个层通过把多个模块组织在一起,就形成了概念上更大粒度的模块。有了层以后理解业务时,因为模块定位相同,往往关注这个更大粒度的层就可以,依赖关系只要指向这个层,而不是层里面的各个模块。这样,从人理解业务的角度,依赖的数量大幅度地减少了。 另外层与层之间的依赖关系都是层与层之间自上而下的依赖,相对于多对多的 网状依赖,层次依赖的方向更清晰,特别符合人的理解习惯。 

    

2.打造可扩展的模块体系

(1)模块拆分

图片

(1)水平方向拆分 

    水平拆分是指从上到下把系统分为多层,按照系统处理的先后顺序,把业务拆分为几个步 骤。 比如,整个叫车过程,可以分为 UI 展现、地图搜索、运力调度和订单支付等几个环 节,这是根据系统的处理过程进行划分的。 这样一来就把一个复杂流程,分解为几个相对独立的环节,分别进行处理。 

    首先,UI 展现部分独立成为一个模块,实现了前后端的分离。前端的用户体验 和界面样式会经常变化,而后端的数据和业务逻辑相对稳定,通过水平拆分实现了稳 定部分和不稳定部分的分开,避免相互影响。

    这里的后端包含三个模块,其中地图搜索负责路径规划,运力调度负责人车匹配,订单支付 负责交易管理。 可以看到,通过水平拆分,可以使每一块职责都比较明确,功能内聚,每个模块管理自己内 部的复杂性。同时,模块之间相互松耦合,一个模块的修改不影响另一个模块,比如地图搜 索模块中改变了优先路径的推荐,不会影响运力调度模块中的人车匹配算法。 水平分层可以很好地满足现有业务做深度扩展,当业务有变化时,系统在特定层做调整,对其他层影响有限,这样把变化局限在一个小范围。

(2)垂直方向拆分

    垂直拆分指的是按照不同的业务线拆分,比如,将整个出行业务分为出租车业务、快车业务 和顺风车业务,按照不同的业务场景,自上而下进行竖切,让每个业务都自成体系,形成自 己的业务闭环。 通过垂直拆分,一个复杂的出行场景就拆分为几个具体的场景,可以根据各个业务线的 特点去设计系统,从而降低了整个系统的复杂性。

    垂直拆分可以很好地满足业务广度上的扩展,比如说增加一条新的业务线,可以按照这个思路落地系统。 一般做业务架构时,先考虑垂直拆分,从大方向上,把不同业务给区分清楚,然后再针对具体业务,按照业务处理流程进行水平拆分。

     如果同时进行垂直拆分和水平拆分,一个大系统被拆分为了一个二维的模块矩阵,每个模块既属于某个业务线,也属于业务流程的某个环节。这样一来,每个模块的职责都很清晰,当 业务变化了,可以清楚地知道,这个变化涉及哪些模块,然后,对这些模块进行相应的 调整就可以。

    

3.打造可扩展的模块体系:模块整合

(1)通用化整合 

    通用化指的是通过抽象设计,让一个模块具备通用的能力,能够替代多个类似功能的模块。 回到刚才的出行平台, 3 条业务线都有地图搜索、运力调度、订单支付这些模 块,不同的业务线之间,这些同名的模块逻辑高度类似,只是细节方面有差别。 

    可以在模块接口中,通过输入参数标识调用来自哪个业务,是出租车、快车还是 顺风车,然后在模块内部,针对不同业务线的差异化部分做针对性处理。结果可能是这个通 用模块增加 5% 的逻辑,但避免了 95% 的重复逻辑,这样,经过通用化整合,新的模块以 很低的代价,就为多个业务线提供了复用。而且,当新的业务线进来,很可能这个通用化的 模块,就已经提供了现成的支持。

    通过模块通用化,模块的数量减少了,模块的定位更清晰,概念更完整,职责更聚焦。在实 践中,当不同业务线对某个功能需求比较类似时,我们经常会使用这个手段。

(2)平台化整合 

    平台化是把定位相同的模块组织在一起,以组团的方式对外提供服务。对于外部系统来说, 可以把这些模块看成是一个整体,一起对业务场景提供全面的支撑。 地图搜索、运力调度、订单支付,都是各个业务线都需要的基 础和通用的业务能力,当增加新的业务线时,还是离不开这些基础能力

图片

    所以可以把这些基础模块放在同一层,构成一个基础业务平台。通过打造业务平台,一方面,我们对多个业务模块进行包装,形成更大粒度的抽象,相当于 减少了模块的数量;另一方面,作为平台,它的定位更明确,系统依赖关系也更清晰;而 且,如果新的业务线进来,它可以基于业务平台快速落地。 业务平台化是模块依赖关系层次化的一个特例,只是它偏向于基础能力,在实践中,当业务 线很多,业务规则很复杂时,我们经常把底层业务能力抽取出来,进行平台化处理。

三、可扩展架构演进

    SOA和微服务都是以RPC为根本进行的丰富实现

图片

1.单体架构MVC

    当业务规模很小时,奖所有功能都部署在同一个进程中,通过双机或者前置负载均衡器实现负载分流,此时,用于分离前后台逻辑的MVC架构是关键。

    

(1)缺点

  • 部署效率低下:随着项目代码量越来越大部署时间越来越长

  • 团队协作开发成本高:修改一个位置需要重新部署整个项目

  • 系统高可用性差:一旦某一功能涉及的代码或者资源有问题,那就会影响整个WAR 包中部署的功能

  • 扩展性不够:无法满足高并发下的业务需求

    

(2)优点

  • 开发简单,集中式管理

  • 基本不会重复开发

  • 功能都在本地,没有分布式的管理和调用消耗

2.分布式RPC(远程过程调用)架构

    当垂直应用越来越多,应用之间交互不可避免,有些核心服务会被多次访问,而非核心服务访问次数很少,将所有服务打包部署在服务器上并不能充分利用计算机资源,所以将核心和公共业务抽取出来,作为独立的服务,实现服务之间的分离,通过网络通信调用不同的服务。此时,用于提高业务复用及拆分的RPC框架是关键。RPC框架屏蔽了底层的传输方式(tcp/udp)、序列化方式和通信细节,框架使用者只需要了解谁在什么位置提供了什么样的远程服务接口即可

图片

    但分布式架构也有局限性,作为应用的开发者,除了要满足自身业务的需求之外,同时还需 要考虑外部业务的需求,这两部分经常会打架。比如,由于自身业务的需求,引起底层的业 务逻辑修改,这时会同时影响 API 接口功能,导致其他业务受影响;同样的道理,外部业 务需求过来,需要 API 接口做调整,即使不影响底层业务逻辑,也会导致整个应用重新部 署,影响自身业务的稳定性。

    在分布式架构下,每个应用都是从头到尾,自搭一套完整的体系,导致业务之间重复 造轮子,造成资源浪费。举个例子,在 2008 年,淘宝还没有开始服务化改造之前,不同业 务线的用户、商品、订单逻辑非常类似,导致了整个系统有超过 1/3 的核心代码重复。

    

(1)客户端调用

    服务调用方在调用服务时,一般进行相关初始化,通过配置文件/配置中心 获取服务端地址用户调用,调用接口方法。

    

(2)动态代理

    通过动态代理,获取实际注册类的方法信息,例如方法名,方法参数类型,方法参数值,返回对象类型。

    同时这个环节会提供序列化功能,一般的RPC网络传输使用TCP(哪怕使用HTTP)传输,这里也要将这些参数进行封装成我们定义的数据接口进行传输。

(3)网络传输

    将方法参数进行处理后,就要发起网络请求,使用tcp传输的就利用socket通信进行传输。

    

(4)服务端数据接受

    服务端接收到数据,获取到客户端的请求。

(5)真实调用

    服务端获取客户端请求的数据后, 调用请求中的方法,方法参数值,通过反射调用真实的方法,获取其返回值,将其序列化封装,通过netty进行数据返回,客户端再接收数据并解析,这就完成了一次rpc请求调用的全过程。

3.SOA(面向服务的架构)架构

    随着业务发展,服务数量越来越多,服务生命周期管控和运行态URL的治理成为瓶颈,服务之间的依赖关系错综复杂,此时用于提升服务质量的SOA服务治理是关键。

    

  • 系统集成:把原先散乱、无规划的系统间的网状结构,梳理成 规整、可治理的系统间星形结构,这一步往往需要引入 一些产品,比如 ESB、技术规范、服务管理规范; 这一步解决的核心问题是【有序】

  • 系统的服务化:把原先固有的业务功能转变为通用 的业务服务,实现业务逻辑的快速复用;这一步解决 的核心问题是【复用】

  • 服务是松耦合的,服务被设计为功能相对独立,尽量不依赖其它服务,逻辑由服务内部所控制

    ESB 的全称是 Enterprise Service Bus,ESB 将企业中各个不同的服务连接在一起。因为各个独立的服务是异构的,如果没有统一的标准,则各个异构系统对外提供的接口是各式各样的。SOA 使用 ESB 来屏蔽异构系统对外提供各种不同的接口方式,以此来达到服务间高效的互联互通。

    ESB 虽然功能强大,但现实中的协议有很多种,如 JMS、WS、HTTP、RPC 等,数据格式也有很多种,如 XML、JSON、二进制、HTML 等。ESB 要完成这么多协议和数据格式的互相转换,工作量和复杂度都很大,而且这种转换是需要耗费大量计算性能的,当 ESB 承载的消息太多时,ESB 本身会成为整个系统的性能瓶颈。

    ESB集中化的管理带来了性能不佳,厚重等问题,也无法快速扩展。不适合互联网的业务特点。

4.微服务架构

    微服务 = 小应用 + 小服务。

    微服务是在 SOA 上做的升华,随着敏捷开发、持续交付、DevOps理论的发展和实践,以及基于Docker等轻量级容器(LXC)部署应用和服务的成熟,微服务架构开始流行,逐渐成为应用架构的未来演进方向。

    将单体应用划分成一组⼩小的服务,尽可能的保证一个服务只做一件事,尽可能少依赖其它功能,做到高内聚松耦合,每个微服务运行在自己的进程之中并且围绕业务能力只做特定的一件事比如订单管理、用户管理。

    

5.SOA架构和微服务架构的区别

    首先SOA和微服务架构一个层面的东西,而对于ESB和微服务网关是一个层面的东西,一个谈到是架构风格和方法,一个谈的是实现工具或组件。

(1)ESB和微服务API网关。

    ESB(企业服务总线),简单 来说 ESB 就是一根管道,用来连接各个服务节点。为了集 成不同系统,不同协议的服务,ESB 做了消息的转化解释和路由工作,让不同的服务互联互通。

图片

    API网关:API网关是一个服务器,是系统的唯一入口。从面向对象设计的角度看,它与外观模式类似。API网关封装了系统内部架构,为每个客户端提供一个定制的API。API网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。通常,网关也是提供REST/HTTP的访问API。服务端通过API-GW注册和管理服务。

图片

(2)区别概括

功能

SOA

微服务

组件大小

大块业务逻辑

单独任务或小块业务逻辑

耦合

通常松耦合

总是松耦合

公司架构

任何类型

小型、专注于功能交叉团队

管理

着重中央管理

着重分散管理

目标

确保应用能够交互操作

执行新功能、快速拓展开发团队

    微服务架构强调的第一个重点就是业务系统需要彻底的组件化和服务化,原有的单个业务系统会拆分为多个可以独立开发,设计,运行和运维的小应用。这些小应用之间通过服务完成交互和集成。每个小应用从前端web ui,到控制层,逻辑层,数据库访问,数据库都完全是独立的一套,各服务向外提供API供其它服务进行调用。

    微服务架构强调的第二个重点就是去ESB、去中心化。每个微服务有自己私有的数据库持久化业务数据且只能访问自己的数据库,而不能访问其它服务的数据库。而SOA则注重中心化,也就是说系统存在着一个主要服务,其它的小服务是为了主服务提供功能的。

    微服务不再强调传统SOA架构里面比较重的ESB企业服务总线,同时SOA的思想进入到单个业务系统内部实现真正的组件化。

    

6.集群和分布式服务区别

分布式:一个业务分拆多个子业务,部署在不同的服务器上

集群:同一个业务,部署在多个服务器上

    比如一个饭店里原来只有一个厨师,切菜备料炒菜都需要干。之后客人越来越多,客人下单后一个厨师不能很快的将菜做好,降低了用户体验,为了快速将菜做好,老板又请了个厨师,两个厨师都能炒一样的菜,这两个厨师的关系是集群。后来客人又多了,老板决定再请几个厨师,但是发现请厨师的成本太高,于是决定请了一个专门备料和一个专门切菜的厨师,此时切菜师、备料师、和炒菜的厨师的关系就是分布式。当饭店规模进一步增大,这是饭店内有多名切菜,多名备料,多名炒菜的厨师,它们整体之间的关系可以称为分布式集群。

四、前后台分离

1.前后台分离场景

    一个业务一般对应两种使用者

  • 普通用户,浏览与发布数据,俗称“前台用户”

  • 后台用户,运营与管理数据,俗称“后台用户”

    一般后台抓取数据源很多,数据结构变化快,用户数据相对结构化,变化少,如果两者数据都在一起进行处理则会导致经常被动修改前台用户展现逻辑,配合后台抓取升级  ,其根本是数据层的耦合

2.优化方案

优化思路:前台展现数据,后台抓取数据分离,解耦。

图片

  • 前台展现的稳定数据,库独立

  • 后台抓取的多变数据,库独立

  • 任务层新增一个异步转换的任务

3.微服务架构优化

用户侧,前台访问的特点是:

  • 访问量较大

  • 对访问时延敏感

  • 对服务可用性要求高

  • 对数据一致性的要求高

运营侧,后台访问的特点是:

  • 访问模式多种多样,运营销售各种奇形怪状的需求,大批量分页的,模糊搜索的

  • 用户量小,访问量小

  • 访问延时不这么敏感,大批量分页,几十秒能出结果,也能接受

  • 对可用性能容忍,系统挂了,10分钟之内重启能回复,也能接受

  • 对一致性的要求始终,晚个30秒的数据,也能接受

    前台和后台的模式与访问需求都不一样,但是,如果前台与后台混用同一套服务和结构化数据,会导致:

  • 后台的低性能访问,对前台用户产生巨大的影响,本质还是耦合

  • 随着数据量变大,为了保证前台用户的时延,质量,做一些类似与分库分表的升级,数据库一旦变化,可能很多后台的需求难以满足

优化思路:冗余数据,前台与后台服务与数据分离,解耦。

图片

五、可扩展架构案例

1.V1.0 架构

    App 前端的 iOS 和 Android 开发团队是外 包出去的,而 App 的服务端是由 1 号店内部一个小型的移动团队负责的,这个团队主要负 责提供 App 前端需要的各个接口,接口使用的通信协议是 HTTP+JSON。

图片

    这个架构比较简单,App 的服务端整体上就一个应用,由移动团队来维护所有对外接口, 服务端内部有很多 Jar 包,比如商品搜索、商品详情、购物车等等,这些 Jar 包包含了各个 业务线的业务逻辑及数据库访问,它们由各个业务线的开发者负责提供。 

    可以看到这个 1.0 版本的服务端,实际上就是一个单体应用,只是对外的接口和内部 Jar 包分别由不同的团队来提供,这个架构的优点和缺点同样都非常明显。 它的优点是简单方便。App 前端的外包团队只需要对接后端的一个移动团队就可以了,然 后移动团队通过现成的 Jar 包,封装各个业务线的功能。至于这些 Jar 包,业务线团队也无需额外去开发。 为什么呢?我们知道,早期的电商平台都是先有 PC 端应用,再推 App,App 最开始的功 能,大多是从已有的 PC 端平移过来的。因此,这些 Jar 包直接从 PC 端应用里拿过来就可 以了,如果 Jar 包版本有更新,由业务线团队直接同步给移动团队即可。 

  • 第一个问题:移动服务端对 Jar 包的紧密依赖 移动团队负责对外接口,但他们非常依赖业务团队提供的 Jar 包来实现业务逻辑,这是一种 物理上的紧耦合依赖关系。 如果业务团队根据 PC 端的需求,修改了应用代码后,Jar 包也会随之修改。那么在实践 中,经常会出现这样的情况:业务团队很多时候,要么忘了同步新的 Jar 包给移动团队,要 么是新的 Jar 包调整了类的接口,导致了 App 服务端的功能有问题,或者直接不可用。 

  • 第二个问题:移动团队的职责过分复杂 服务端为 App 提供的是粗粒度接口,而业务团队的 Jar 包提供的是细粒度的接口。 因此,移动团队在 Jar 包的基础上,还需要做很多的业务逻辑聚合,很多时候,这些逻辑还 跨多个业务线,导致移动团队对所有业务逻辑都要深入了解。相信你也知道,这是很难做到 的。 

  • 第三个问题:团队并行开发困难 由于移动团队和业务团队是通过物理 Jar 包进行集成的,移动团队直接受业务团队的代码影 响,就导致了团队之间并行开发困难,一次大的 App 升级经常需要 2~3 个月的时间。

2.V2.0 架构

    在这个时候,1 号店自己接手了 App 前端的开发工作,同时,服务端接口也由各个业务线团队直接负责,这样,App 前端 直接对接多个后端应用提供的 HTTP 接口。

图片

    对于各个业务团队来说现在走向了前台,每个团队负责各个业务线的 App 接口。他 们一般采取这样的做法,一方面以 Web 应用的方式,为 PC 端浏览器提供访问;另 一方面,针对移动端的访问需求,在 Web 应用里面,增加了一些 REST 接口,直接供App 访问。

    在这里,移动接口和 Web 应用在同一个工程里开发,作为同一个应用进行部 署和运行。 这里你可以看到,这实际上就是一种分布式的系统架构,每块业务由不同的团队负责,可以很好地支持团队之间的并行开发;同时,移动接口和 PC 端共享底层业务逻辑,有助于快速 把 PC 端的功能完整地复制到 App 端。 这样,通过 V2.0 架构的升级,业务线团队的生产力就被完全释放了,App 的功能也就快 速丰富起来了。但这种方式也带来了一系列的问题。

  • 首先是移动端和 PC 端互相干扰的问题。 在同一个业务线内部,移动接口和 Web 应用,物理上是绑定在一起的。很多 时候,PC 端的代码修改会影响到移动接口,而 Web 应用的发布,也会导致移动接口被动 地被发布,如果 PC 端出现功能问题,也会影响到移动接口的可用性。反过来也是一样的, 移动接口的需求变化,会影响到 PC 端的功能。当移动端发展到了一定程度,它需要和 PC 端有不同的功能和用户体验,但这种 紧耦合的方式,导致了相互之间产生很多不必要的干扰,对系统的功能和稳定性都带来了负 面影响。 

  • 其次是重复开发的问题。 移动接口除了要给 App 端提供业务数据,还需要考虑一系列系统级的功能,比如说,安全 验证、日志记录、性能监控等等,每个移动接口都需要这些通用功能。 那现在,由于 App 前端是和后端直连的,这就意味着,每个后端系统都需要独自去支持这 些系统级的功能,导致了各个后端系统重复开发。一旦这些通用需求发生了变化,比如说要对传输数据进行压缩,那么,所有的后端系统都需要同步调整,这样不但工作量很 大,而且也给项目管理也带来了很大的挑战。

  • 最后是稳定性的问题。在这里,基于这种直连方式,只要一个后端系统出问题,就会直接影响到 App 的可用性, 使得 App 整体上非常的脆弱。 之所以会出现以上这些问题,它的根本原因在于,我们在 App 端,直接照搬了 PC 端的做 法,没有针对移动端自身的特点,去做架构设计。 我们知道,当 App 发展到一个成熟阶段时,无论是业务功能,还是非业务性功能,和 PC 端都是不同的。

3.V3.0 架构

    对每个业务线的服务端进行拆分,让 App 接口和 PC 端接口各自在物理上独 立,但它们共享核心的业务逻辑。

图片

    这样拆分的结果是,原来大的服务端变成了 3 个应用,包括一个 App 端接口应用,一个 PC 端 Web 应用,还有一个核心业务逻辑服务,3 个部分都是独立维护和部署的。 除此之外,架构改造还考虑了移动端自身的特点。一方面,每个移动端接口需要调用对应的后台服务,进行业务逻辑处理,这个是个性化的, 每个接口的处理逻辑都不一样;另一方面,每个移动端接口都需要进行系统级的功能处理, 比如前面所说的安全验证、接口监控等,这个是共性的,每个接口的处理方式都是一样的。 那么,在架构上,我们就需要把共性的系统级功能进行集中处理,把个性化的业务功能进行 分散处理。 最后,我们结合服务端的应用拆分,以及对移动接口本身的改造,落地了服务端 V3.0 架 构。

图片

    

4.最终结果

  • 首先,App 端和 PC 端彻底独立了。App 前端和 PC 端浏 览器是完全对等的,PC 端浏览器有自己的服务端,App 前端也有自己的服务端,在这里, 移动网关就充当 App 服务端的角色。 在这个架构下,两个服务端都可以针对自身的特点,独立开发,独立部署,无论在逻辑层面 还是物理层面都实现了彻底解耦。

  •  其次,通过架构改造,实现了核心业务的复用。把核心的业务逻辑从 Web 应用 中剥离出来,变成了共享的服务。在服务设计时,不再区分 PC 端还是移动端,而是从 业务本身出发,提供一套通用的接口,同时供 PC 端和移动端调用,从而实现了底层业务逻 辑的复用。 

  • 还有,这个架构强化了系统级功能。原来通用的系统级功能,由各个团队各自去提供,很多 团队要么不提供,要么实现的方式不一样;现在的系统级功能,是由集中式的移动网关统一 来提供,就可以很方便地强化这些系统级功能。 举个例子可以把通信协议由 HTTP 升级为更安全的 HTTPS,当后端服务有问题时, 也可以通过网关进行事先的数据缓存,直接返回给 App 前端。比如说商品的详情数据,就 很适合这样的处理。 所以,有了移动网关,整个 App 的可用性、稳定性和安全性都得到了大幅度的提升。 最

  • 最后,团队分工也更明确了。在这里,移动团队主要负责移动网关,包括网关本身和各种过 滤器的维护,他们可以针对移动端的特点,做各种系统级功能的优化;而业务团队,主要负 责各自的业务逻辑,包括适配器和底层服务。移动团队和业务团队通过明确的适配接口进行 协作,相互不影响。V3.0 在 V2.0 分布式架构的基础上,通过服务化改造,实现了基础业务的 复用;同时,通过移动网关落地系统级功能,实现了系统的平台化改造。 总的改造结果就是,解放了业务线,提升了系统的稳定性,使得移动端可以做大做强。

五、云计算

1.为什么上云

  • 数字化转型的结果是:云会吞噬一切;

  • 云不仅仅是技术,更是最好的商业模式

(1)从业务发展的角度出发,倒推上云规划 上云是为了帮助业务降本提效,做任何事都要从目标出发。云产品带来的价值,不仅是资源节省,还有人力节省、加速研发等,这些都可以换算成财务价值。如果你上了云,IT 开销反而更大了,那说明整个规划和管理一定存在问题,先不要上云。

(2)坚持“拿来主义”,不要在企业层面重复造轮子 当下,许多的 IT 研发工作都是重复造轮子,美其名曰为“沉淀企业 IT 基因”,实际就是浪费 IT 资源,对业务发展施加反作用。企业经营要务实,对于非核心业务,坚持“拿来主义”,不要过于理想主义;对于核心业务,坚持长期投入,建立团队推进自研工作。

(3)别害怕上云,和乙方一起搞定障碍 很多技术管理者一提上云就如临大敌:顶层规划怎么做呀?云上架构怎么设计呀?应用怎么迁移呢?怎么把云用好呀?怎么选择云厂商啊?还没正式见过服务商们,就先把自己吓了个半死 —— 这么多问题都不懂,我们团队可能支持不了上云改造,要不计划先搁置吧。依据我在企业上云方面的经验,上云规划涉及的内容会非常多,包括:上云方案、现有系统评估、云平台成本优化建议、迁移方案、云主机的功能和指标、网络带宽指标、跨国专线带宽指标,等等。在当时,团队也是第一次做上云迁移,很多内容都不懂。这份文档的内容,部分是我们根据自身需求提出的,部分来自于云厂商对自己亮点的介绍。最终,文档在不断地沟通和商业谈判中丰富起来了。

(4)开放心态看待数据隐私。

很多人对公有云比较抗拒,担心数据隐私泄露,担心竞争对手派系的企业盗用自己数据。其实我认为,大可不必担心。我个人的观点是,云厂商不会在公司层级盗取你的数据,但有可能因为管理不善而导致数据泄露。可我们也要多问问自己,自己管理的数据就安全吗?比头部云厂商的管理更加安全吗?(5)正确看待云计算的“负面影响”。 如果企业奉行的不是以业务为中心,以产品为核心的组织文化,不具备我们前面所讲的、优秀的组织架构,就很可能在上云问题上陷入多方扯皮。因为,这触动了部分人的“蛋糕”,打扰了部分人的浑水摸鱼。所以上云,依然是个一把手工程。 我们要明确地意识到,未来,专业分工一定会越来越明确,技术基座一定会不断上移,每家企业都可以忘掉底层技术细节,聚焦自己的核心业务逻辑。因此,这条思考脉络最终也会回到出发点,形成闭环:对于大部分商业公司(非技术产品或云计算公司)而言,技术只有在成就业务时,才具备真正的价值。

2.云机房和普通机房区别

云机房是一种基于互联网的计算方式,通过这种方式,共享的软硬件资源和信息可以按需提供给计算机和其他设备。典型的云计算提供商往往提供通用的网络业务应用,可以通过浏览器等软件或者其他Web服务来访问,而软件和数据都存储在服务器上。

云机房和普通机房的区别  

(1)工作原理不一样

云机房,也就是云服务器,是云计算的新一代产品,它是通过虚拟化、集群技术进行资源整合,通过云端控制平台按需生成相关主机资源。而物理机房,也就是服务器租用托管,可以理解为买了一台电脑放在机房。

(2)使用成本不一样

  一间45人的云机房只需要配备一台服务器和45个云终端即可,服务器+禹龙云终端平均功耗一台不会超过30W,而传统机房采用的台式机平均功耗是200W,也就是说传统机房平均一台就会比使用云终端的云机房多出170W耗电量的,据统计云机房和传统机房相比每年可以节省95%用电成本的。

(3)维护难度不一样

使用云终端建设的云机房维护是这样的,如果是系统问题老师只需要在服务器上就可以进行维护的,而如果是云终端硬件问题更是简单的,只需要拿一个好的换上去就可以。而传统机房的维护则是这样的,不管是系统问题还是主机硬件问题都需要本地进行维护的。系统问题还好重新安装就好了,如果是硬件问题则需要每一个硬件进行排查的看是哪里出现的。

(4)使用区别

云服务器是一种可弹性伸缩的计算、网络、存储服务,其管理方式比物理服务器更加高效简单。与此同时,云服务器可以做到即买即用,无需像物理机那样,还需要服务器采购、上架、系统安装......

(5)收费区别

拿腾讯云4核8G5M50G云服务器和物理机来对比,腾讯云服务器最新的2折特惠秒杀活动价格只要2899元/3年,平均一年只要900多块,而物理机则需要9000元左右/1年,3年差不多27000多块,价格是云主机的10倍。

(6)物理好处

当然物理机也是有好处的。服务器租用托管的话稳定性和安全性有保障,不会因为共享主机,而引起的主机负载过重,导致服务器性能下降或瘫痪。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/775830.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】链表习题之反转链表和删除链表中等于给定值 val 的所有节点

👑个人主页:啊Q闻 🎇收录专栏:《数据结构》 🎉道阻且长,行则将至 前言 今天的博客是关于链表的题目,力扣上的题目之反转链表和删除链表中等于给定值 val 的所有节点 一.反转…

基于SpringBoot的“篮球竞赛预约平台”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“篮球竞赛预约平台”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体结构图 平台首页界面图 用户注册界面…

使用Qt生成图片

Qt之生成png/jpg/bmp格式图片_qt生成图片-CSDN博客 (1)使用QPainter 示例关键代码: QImage image(QSize(this->width(),this->height()),QImage::Format_ARGB32);image.fill("white");QPainter *painter new QPainter(&image);painter->…

QT程序打包

将exe文件单独拿出来放入一个单独的文件夹 保存qt安装路径下有如下这个文件 windeployqt.exe 在TCPFile.exe文件夹中使用以下cmd命令运行 即可打包 windeployqt 文件名.exe 成功打包!

功能强大的国外商业PHP在线教育系统LMS源码/直播课程系统

功能强大的国外商业PHP在线教育系统LMS/在线教育市场源码/直播课程系统 Proacademy是在线教育一体化的解决方案,用于创建类似于Udemy、Skillshare、Coursera这种在线教育市场。 这个平台提供在线课程,现场课程,测验等等,并有一个…

第十篇【传奇开心果系列】Python自动化办公库技术点案例示例:深度解读Python自动化操作Excel

传奇开心果博文系列 系列博文目录Python自动化办公库技术点案例示例系列博文目录 前言一、重要作用解说二、Python操作Excel的常用库介绍三、数据处理和分析示例代码四、自动化报表生成示例代码五、数据导入和导出示例代码六、数据可视化示例代码八、数据校验和清洗示例代码九、…

go面向对象

继承 封装 多态 定义结构体 //定义老师的结构体 type Teacher struct {Name stringAge intSchool string }func main() {var t1 Teacherfmt.Println(t1)t1.Name "tom"t1.Age 20t1.School "school"fmt.Println(t1) } 结构体实例的创建 package ma…

uniApp使用XR-Frame创建3D场景(4)金属度和粗糙度

上一篇讲解了如何在uniApp中创建xr-frame子组件并创建简单的3D场景。 这一篇我们讲解xr-frame中关于mesh网格材质的金属度和粗糙度的设置。 1.先看源码 <xr-scene render-system"alpha:true" bind:ready"handleReady"> <xr-node visible"{…

springboot使用com.github.binarywang 包实现微信网页上的支付和退款

前提 微信小程序中实现微信支付是从小程序中调去微信支付的界面直接进行支付&#xff0c;那么在pc端需要实现微信的支付呢&#xff0c;是需要出现一个二维码让用户使用扫码支付的。 注意&#xff1a; 需要实现pc端的微信支付&#xff0c;需要在微信商户平台开通native支付&…

如何使用VS统计自己的代码量?

历经漫漫编程之路&#xff0c;此刻我们不妨回首细数&#xff0c;那已累积的无数行代码&#xff0c;它们如同一串串无声的脚印&#xff0c;记载着我们默默耕耘的点滴时光。每一行代码都是平凡努力的印记&#xff0c;见证了我们的执着与付出&#xff0c;也塑造了今天的我们。让这…

uniApp使用XR-Frame创建3D场景(3)光源投影的运用。

上一篇讲解了如何在uniApp中创建xr-frame子组件并创建简单的3D场景。 这篇我们讲解光源在场景中的运用以及相关属性。 在子组件 xr-start的index.wxml文件中我们加入如下代码 <xr-scene render-system"alpha:true" bind:ready"handleReady"><xr…

操作系统系列学习——内存分区与分页

文章目录 前言内存分区与分页 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招&#xff0c;计划学习操作系统并完成6.0S81&#xff0c;加油&#xff01; 本文总结自B站【哈工大】操作系统 李治军&#xff08;全32讲&#xff09; 老师课程讲的非常好&#xff0c;感谢 【哈工…

MATLAB机器学习工具箱——傻瓜式操作

一、使用回归学习器预测北京二手房房价 软件&#xff1a;MATLAB R2023 a 数据&#xff1a; 第一步&#xff1a;导入原始数据和待预测数据 第二步 &#xff1a;打开工具箱中的回归学习器导入学习数据 1.新建会话 2.寻找导入learning data 3.自动锁定前7列为自变量&#xff…

共射极放大电路理论计算

目录&#xff1a; 1、概述 2、理论计算 3、Multisim仿真验证 1&#xff09;静态工作点与放大倍数 2&#xff09;输入阻抗仿真 1、概述 如下图所示的共射极放大电路&#xff0c;本内容主要计算静态工作点电压、电压放大倍数与输入输出阻抗。 2、理论计算 列出方程如下&am…

AndroidStudio中一些实用插件

1.RainbowBrackets插件为圆括号、方括号和花括号内的代码添加了漂亮的彩虹色 2.CodeGlance类似于Sublime或Xcode&#xff0c;CodeGlance插件在编辑器中嵌入了代码迷你图。滚动条也有所增大。在CodeGlance预览文件的代码模式下&#xff0c;用户可以快速导航到目标处。 3.ADBWifi…

java数据结构与算法刷题-----LeetCode540. 有序数组中的单一元素

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 1. 异或运算2. 全数组二分查找异或奇偶3. 偶数下标二分查找 1. 异…

前端如何判断元素是否到达可视区域

以图片显示为例&#xff1a; window.innerHeight 是浏览器可视区的高度&#xff1b;document.body.scrollTop || document.documentElement.scrollTop 是浏览器滚动的过的距离&#xff1b;imgs.offsetTop 是元素顶部距离文档顶部的高度&#xff08;包括滚动条的距离&#xff0…

快速上手Spring Cloud 十一:微服务架构下的安全与权限管理

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

机器学习——聚类算法-层次聚类算法

机器学习——聚类算法-层次聚类算法 在机器学习中&#xff0c;聚类是一种将数据集划分为具有相似特征的组或簇的无监督学习方法。聚类算法有许多种&#xff0c;其中一种常用的算法是层次聚类算法。本文将介绍聚类问题、层次聚类算法的原理、算法流程以及用Python实现层次聚类算…

蓝桥杯练习题——博弈论

1.必胜态后继至少存在一个必败态 2.必败态后继均为必胜态 Nim游戏 思路 2 3&#xff0c;先手必赢&#xff0c;先拿 1&#xff0c;然后变成 2 2&#xff0c;不管后手怎么拿&#xff0c;先手同样操作&#xff0c;后手一定先遇到 0 0 a1 ^ a2 ^ a3 … ^ an 0&#xff0c;先…