zoukankan      html  css  js  c++  java
  • Archi

    总结

    1.分布式组件的优先级

    • 1、服务发现、服务路由、服务容错:这是最基本的微服务基础设施。
    • 2、接口框架、API 网关:主要是为了提升开发效率,接口框架是提升内部服务的开发效率,API 网关是为了提升与外部服务对接的效率。
    • 3、自动化部署、自动化测试、配置中心:主要是为了提升测试和运维效率。
    • 4、服务监控、服务跟踪、服务安全:主要是为了进一步提升运维效率。

    根据优先级分析来看3和4两种是随着微服务节点数量的增加而越来越重要,前期拆分的服务较少并且团队对于微服务架构也在逐渐掌握中,可以暂时采用人工的方式,虽然效率低了点,但是不会因为某个环节熟悉程度不够而导致整体崩盘的情况。

    2.三个改造策略

    策略1:新老分离

    当你的单体应用已经变得无法管理的时候,就不要再继续扩大它的规模了。比如你想添加新功能,不要在单体应用中添加代码,而要将新的代码放在另一个单独的微服务中。下图展示了使用这种方法后的系统架构:

    除了新服务和旧的单体应用,还有两个组件。一个是请求路由(request router),用来处理过来的(比如HTTP)请求,类似于API网关。这个路由发送与新功能相应的请求到新的服务上,将旧服务相关的请求路由到单体应用上。

    另一个组件是胶水代码(glue code),用来将服务与单体应用集成起来。一个服务很少是隔离存在的,需要访问单体应用的数据。胶水代码就负责这些数据集成。微服务组件可以通过它来读写单体应用中的数据。

    一个服务可以通过三种方式访问单体应用中的数据:

    • 通过调用单体应用提供的远程API
    • 直接访问单体的数据库
    • 保存一份数据的副本,和单体数据库保持同步

    胶水代码有时被称为防腐层(anti-corruption layer),可以防止拥有自己原始领域模型的服务,被来自单体领域模型的概念所影响。

    胶水代码可以在两个不同的模型间充当翻译官,防腐层这个词最初出现在Eric Evans写的《Domain DrivenDesign》一书中。开发一个防腐层不是一个小工程,但如果你想从单体地狱中走出来,这是很重要的。

    用轻量级的服务实现一个新功能,有很多好处。首先,可以防止单体应用变得更难以管理;其次,这个应用可以被独立地开发,部署和扩展。

    然而,这个方法并不能解决在旧有的单体部分遇到的问题,你还需要破坏原有的单体部分。

    策略2:前后端分离

    缩减单体应用的一个策略是将表现层从业务逻辑和数据访问层中分离出来,一个典型的企业应用至少包括三种组件:

    • 表现层:这层组件用来处理HTTP请求,实现(REST)API或者基于HTML的Web
    • UI。在一个有着复杂的用户接口的应用中,表现层通常有大量的代码;
    • 业务逻辑层:应用的核心代码,用来实现业务规则;
    • 数据访问层:访问数据库或信息中介的组件。

    在表现逻辑与业务和数据访问逻辑之间通常有着明显的区分。业务层有一个粗粒度的API,包含一个或多个外立面组成,外立面封装了业务逻辑组件。这个API是自然的『缝合』,所以可以将单体分割为更小的应用,一个应用包含了表现层,另一个应用包含了业务和数据访问层。分隔后,表现逻辑层应用可以远程调用业务逻辑层应用,下图展示了改造前后的架构:

    这样分隔单体应用有两个主要好处。首先你可以独立地开发,部署和扩展两个应用,比如对于表现层开发者来说,他们可以实现用户界面的快速迭代,A/B测试也很容易实现;其次,这样做会向外开放一个微服务也可以调用的远程API。

    但是这个策略只是部分解决方案,很有可能会变成两个混乱的单体应用。需要用下面第三个策略去减少单体部分的比重。

    策略3:提取服务

    第三个策略的目的是将单体中的模块,转变为单独的微服务。每次提取一个模块,就改造为微服务,单体部分就缩减了。一旦你转化了足够的模块,最后不管单体部分是完全消失了,还是变小成了另一个微服务,都不是问题了。

    优先改造哪个模块?

    三种思路:

    • 可以从容易被提取的开始,积累微服务的经验,然后提取那些能给你带来最大好处的模块。
    • 提取那些频繁变化的模块很有用,一旦你将这个模块提取出来,就可以独立开发和部署它了,可以加速开发。
    • 提取那些资源需求和其它部分有很大不同的模块。比如将一个有内存数据库的模块转变为服务,就可以把它部署在内存很大的主机上;同样的,提取那些实现复杂算法的模块,就可以把它部署在CPU多的主机上。总之这样做有助于你扩展应用。

    如何提取一个模块?

    第一步是在模块和单体之间定义一个粗粒度的接口。由于单体和微服务的数据互相都有需求,所以它很像一个双向的API。但是在这个模块和应用的剩余部分之间,有着混乱的依赖关系和细粒度的交互模式,所以实现这个API还是很有挑战的。通过域模型实现的业务逻辑,改造起来尤其困难,因为各个域模型间的关系复杂。通常需要进行大量的代码修改,去打破这些依赖。

    一旦你实现了细粒度的接口,就可以将模块改造为一个独立的服务。要写代码实现单体和微服务间的通信,通过使用了IPC机制的API。下图展现了一个架构在改造前,改造中和改造后的样子:

    在这个例子中,模块Z是待提取的模块。模块X使用了Z的组件,Z又使用了模块Y。

    改造的第一步是定义一对粗粒度的API,第一个接口是模块X调用模块Z的入站接口,第二个是模块Z调用模块Y的出站接口;
    第二步是将这个模块改造为独立的服务。入站接口和出站接口都通过IPC机制的代码实现。可能你需要通过结合模块Z到微服务底盘框架(用来处理横切关注点,比如服务发现)上,来构建这个服务。

    一旦你提取了这个模块,就可以独立地开发,部署和扩展它了。你甚至可以从头重写这个服务,将这个服务和单体结合起来的API代码就成了防腐层,相当于两个域模型之间的翻译官。每次提取一个服务,都是向着微服务又进了一步,单体的比重会逐步缩减。

    参考文献

    https://blog.csdn.net/rickiyeat/article/details/62043588

    https://blog.csdn.net/zhenghhgz/article/details/89380714

  • 相关阅读:
    .NetCore Grpc 客服端 工厂模式配置授权
    DOCKER 拉取 dotnet 镜像太慢 docker pull mcr.microsoft.com too slow
    Introducing .NET 5
    VSCode 出现错误 System.IO.IOException: The configured user limit (128) on the number of inotify instances has been reached.
    Omnisharp VsCode Attaching to remote processes
    zookeeper3.5.5 centos7 完全分布式 搭建随记
    Hadoop2.7.7 centos7 完全分布式 配置与问题随记
    MySQL索引 索引分类 最左前缀原则 覆盖索引 索引下推 联合索引顺序
    SQL基础随记3 范式 键
    MySQL调优 优化需要考虑哪些方面
  • 原文地址:https://www.cnblogs.com/frankcui/p/15393374.html
Copyright © 2011-2022 走看看