架构演变之路

159 阅读11分钟

背景介绍

最近公司在对原有的系统进行全新升级,根据业务实际需求与日后产品能够在市场具有一定的竞争力,需要将原有系统进行重构,这里我想谈下项目参与中自己的感受,事实上这篇文章的着重点应该放在微内核的概念讲解与技术选型,但是我还是更愿意追根溯源一步步的深入阐述

单体应用

所谓单体应用就是一个war包包含了所有了功能,其优缺点很明显

优点

  • 便于共享:单个归档文件包含所有功能,便于在团队之间以及不同的部署阶段之间共享

  • 易于测试:单体应用一旦部署,所有的服务或特性就都可以使用了,这简化了测试过程,因为没有额外的依赖,每项测试都可以在部署完成后立刻开始

  • 易于部署:只需将单个归档文件复制到单个目录下

  • 模块依赖:模块之间依赖简单因为在一个包内,一旦类出现了方法更新(增加或者删除),调用者l立刻就能感知

缺点

  • 复杂性高:随着业务的不断迭代,项目的代码量会急剧的增多,项目模块也会随着而增加,模块与模块之间的关系就会变成的很复杂,整个项目就会变成的非常复杂,在新增和修改代码的时候都会做很多的测试,很容易会由于一处的变动影响之前业务的功能
  • 部署评率低:随便代码的增多,首先部署会越来越消耗时间,还有我们在修复一个很小很小的bug的时候整个项目都要重新部署,所以我们会集中一个时间点部署多个需求
  • 可靠性差:这个很容易理解,假如某个影响出现了死循环,导致内存溢出,会影响整个项目挂掉
  • 扩展性差:我们在新增业务的时候,代码层面会考虑在不影响现有的业务基础上编写代码,提高了代码的复杂性
  • 数据瓶颈:随着用户数量级增大,数据库IO将成为瓶颈(数据库IO瓶颈 QPS:每秒3000次IO查询操作)
  • 资源消耗:我们实际的业务中总会有那些需要消耗系统资源比例很重的模块,也会有消耗系统资源不多的模块,如果使用单体应用势必造成资源匹配为不均,横向扩展资源浪费
  • 团队管理:对于单体应用的人员管理不如分而治之,将专业的人才去做专业的事情,团队范围变小变精

面相服务

相比于单体应用面相服务实质就将业务进行拆分,将拆分的业务抽象成服务,围绕这个业务的核心进行编程,落地就是面相服务编程(SOA)

优点:

  • 业务边界明显:面相服务这个过程就是在明确业务边界,将整个流程划分成一个个合理的业务子域,完成解耦
  • 模块统一标准:开发者不在局限于使用什么语言,只要我们明确我们的模块之间调用协议(标准),无论使用C或者是Python实现,那么我遵从这个标准实现模块之间的调用
  • 可用性更好:该特点是在于服务提供者和服务使用者的松散耦合关系上得以发挥与体现。使用者无须了解提供者的具休实现细节
  • 伸缩性更好:依靠业务服务设计、开发和部署等所采用的架构模型实现伸缩性。使得服务提供者可以互相彼此独立地进行调整,以满足新的服务需求
  • 团队管理:将专业的人才去做专业的事情,团队范围变小变精

缺点:

  • 可靠性:SOA还没有完全为事务的最高可靠性——不可否认性(nonrepudiation)、消息一定会被传送且仅传送一次(once-and-only-once delivery)以及事务撤回(rollback)——做好准备,不过等标准和实施技术成熟到可以满足这一需求的程度并不遥远。

  • 安全性:访问控制只需要登录和验证;而在SOA环境中,由于一个应用软件的组件很容易去与属于不同域的其他组件进行对话,所以确保迥然不同又相互连接的系统之间的安全性就复杂得多了

  • 编排:统一协调分布式软件组件以便构建有意义的业务流程是最复杂的,但它同时也最适合面向服务类型的集成,原因很显然,建立在SOA上面的应用软件被设计成可以按需要拆散、重新组装的服务。作为目前业务流程管理(BPM)解决方案的核心,编排功能使IT管理人员能够通过已经部署的套装或自己开发的应用软件的功能,把新的元应用软件 (meta-application)连接起来。 事实上,最大的难题不是建立模块化的应用软件,而是改变这些系统表示所处理数据的方法

  • 遗留系统处理:SOA中提供集成遗留系统的适配器, 遗留应用适配器屏蔽了许多专用性API的复杂性和晦涩性。一个设计良好的适配器的作用好比是一个设计良好的SOA服务:它提供了一个抽象层,把应用基础设施的其余部分与各种棘手问题隔离开来。一些厂商就专门把遗留应用软件“语义集成”到基于XML的集成构架中。 但是集成遗留系统的工作始终是一种挑战

微服务

SOA(Service-Oriented Architecture)面向服务的体系架构。SOA只是一个架构模型的方法论,并不是一个明确而严谨的架构标准。只是后面很多人将SOA与The Open Group的SOA参考模型等同了,认为严格按照TOG-SOA标准的才算真正的SOA架构。SOA就已经提出的面向服务的架构思想,所以微服务应该算是SOA的一种演进吧

优点:

  • 单一职责:每个微服务都需要满足单一职责原则,微服务本身是内聚的,因此微服务通常比较小。比如示例中每个微服务按业务逻辑划分,每个微服务仅负责自己归属于自己业务领域的功能。

  • 自治:一个微服务就是一个独立的实体,它可以独立部署、升级,服务与服务之间通过REST等形式的标准接口进行通信,并且一个微服务实例可以被替换成另一种实现,而对其它的微服务不产生影响

  • 可扩展:应对系统业务增长的方法通常采用横向(Scale out)或纵向(Scale up)的方向进行扩展。分布式系统中通常要采用Scale out的方式进行扩展。因为不同的功能会面对不同的负荷变化,因此采用微服务的系统相对单块系统具备更好的可扩展性

  • 灵活组合:在微服务架构中,可以通过组合已有的微服务以达到功能重用的目的

缺点:

  • 复杂度高:微服务间通过REST、RPC等形式交互,相对于Monolithic模式下的API形式,需要考虑被调用方故障、过载、消息丢失等各种异常情况,代码逻辑更加复杂;对于微服务间的事务性操作,因为不同的微服务采用了不同的数据库,将无法利用数据库本身的事务机制保证一致性,需要引入二阶段提交等技术;同时,在微服务间存在少部分共用功能但又无法提取成微服务时,各个微服务对于这部分功能通常需要重复开发,或至少要做代码复制,以避免微服务间的耦合,增加了开发成本
  • 运维复杂:在采用微服务架构时,系统由多个独立运行的微服务构成,需要一个设计良好的监控系统对各个微服务的运行状态进行监控。运维人员需要对系统有细致的了解才对够更好的运维系统
  • 影响性能:相对于单体架构,微服务的间通过REST、RPC等形式进行交互,通信的时延会受到较大的影响

微内核

微内核是内核的一种精简形式。通常系统服务层是和内核集成在一起的,而微内核将系统服务层被分离出来,变成可以根据需求加入的选件(增除模块实现动态管理),这样就可以提供更好的可扩展性和更加有效的应用环境,以下着重介绍OSGI

OSGI概念

OSGi(Open Service Gateway Initiative,直译为“开放服务网关”)实际上是一个由OSGi联盟(OSGi Alliance)发起的以Java为技术平台的动态模块化规范

OSGi规范并不是单一的规范文档,而是由一系列子规范构成,这些子规范主要可分为两大部分,其中一部分用于描述OSGi的核心框架(OSGi Framework)。OSGi核心框架是一个可运行OSGi系统的最小集合,它由以下内容组成:

  • 执行环境(Execution Environment):由于OSGi所适用的目标范围非常广泛,为了更好地处理不同硬件、软件环境对OSGi造成的兼容性问题,在建立其他约定之前,必须先定义好系统的执行环境
  • 安全层(Security Layer):描述了基于Java 2安全架构实现的代码验证、JAR文件数字签名、数字证书服务,安全层贯穿了OSGi框架的其他各个层次
  • 模块层(Module Layer):模块层从“静态”的角度描述了一个模块的元数据信息、执行环境定义、模块约束和解析过程、类加载顺序等内容。模块层是整个OSGi中最基础、最底层的层次
  • 生命周期层(Life Cycle Layer):生命周期层从“动态”的角度描述了一个模块从安装到被解析、启动、停止、更新、卸载的过程,以及在这些过程中的事件监听和上下文支持环境
  • 服务层(Service Layer):描述了如何定义、注册、导出、查找、监听和使用OSGi中的服务。服务层是所有OSGi标准服务的基础
  • 框架API(Framework API):由一系列通过Java语言实现的接口和常量类构成,为上面各层提供面向Java语言的编程接口

OSGi的入门门槛相对较高,如果没有足够的指导材料,开发人员从零开始学习并探索OSGI的最佳实践需要很高的成本

Equinox框架

Equinox是目前使用最为广泛的OSGI R4.x规范的实现,它是一个松散的程序集,由一系列Bundle共同组成,这些Bundle有的用于实现OSGi运行的基础架构,有的用于提供众多OSGi标准服务,还有一些Bundle提供了在OSGi标准之外的Equinox的专有功能

step1:安装

官网下载:https://download.eclipse.org/equinox/
文件名称:Equinox.zip
本机环境:macOS
开发工具:idea
核心目录:解压Equinox.zip,Equinox目录下plugins是Equinox(微内核)核心库		

step2:配置

目录结构:Equinox -> plugins-> configuration-> config.ini

进入plugins目录创建configuration文件夹
检查是否存在config.ini 若不存在
在configuration文件夹内新建config.ini
编写config.ini内容,其中osgi.bundles配置的内容时启动命令行必备的否则,不能启动,或者启动不能输入命令
	org.eclipse.equinox.console_1.4.400.v20210602-1312.jar
	org.eclipse.equinox.common_3.15.100.v20210909-1439.jar
	org.apache.felix.gogo.runtime_1.1.4.v20210111-1007.jar
	org.apache.felix.gogo.shell_1.1.4.v20210111-1007.jar
	org.eclipse.osgi.services_3.10.200.v20210723-0643.jar
	org.eclipse.osgi.util_3.6.100.v20210723-1119.jar

config.ini内容如下(参考):

osgi.framework=file\:plugins\org.eclipse.osgi_3.17.100.v20210920-2103.jar
eclipse.ignoreApp=true  
osgi.noShutdown=true  
osgi.console=  
osgi.clean=true
osgi.bundles=reference\:file\:org.eclipse.equinox.console_1.4.400.v20210602-1312.jar@start,reference\:file\:org.apache.felix.gogo.runtime_1.1.4.v20210111-1007.jar@start,reference\:file\:org.eclipse.osgi.services_3.10.200.v20210723-0643.jar@start,reference\:file\:org.apache.felix.gogo.shell_1.1.4.v20210111-1007.jar@start,reference\:file\:org.eclipse.equinox.common_3.15.100.v20210909-1439.jar@start,reference\:file\:org.eclipse.osgi.util_3.6.100.v20210723-1119.jar@start

step3:启动

启动:
java -jar org.eclipse.osgi_3.17.100.v20210920-2103.jar -configuration configuration -console -Xms40m -Xmx512m

创建项目参考

blog.csdn.net/qq_34248376… (IDEA中osgi的开发应用指南)

如何动态加载、启停

step1:

若开发完成请在idea build->build project
若将生产的jar包拷贝到 Equinox->plugins

step2:

osgi> install reference\:file\:plugin-test.jar
osgi> ss
osgi> start [id]  id:是当前模块在内核中的ID
osgi> stop [id]