谈谈我对SOFA模块化的理解

今天咱们谈谈SOFA模块化,首先看一段SOFA的介绍:java

SOFABoot是蚂蚁金服开源的基于Spring Boot的研发框架,它在Spring Boot的基础上,提供了诸如 Readiness Check,类隔离,日志空间隔离等能力。在加强了Spring Boot的同时,SOFABoot提供了让用户能够在Spring Boot中很是方便地使用SOFA中间件的能力。git

在接触SOFA的模块化概念以前,我对服务端开发的模块化认知停留在“模块化”这个层面,我一般会按照下图所示的结构组织本身负责的应用的代码。 github

普通的分层结构

在Spring体系中的模块(Module),就是经过不一样的Spring上下文来管理各自模块中的bean,在开发和编译期实现模块化,可是在运行时整个应用仍是在一个Spring上下文中,这些代码还都是被一个类加载器加载的。面试

在图1中,我在manager模块中定义的bean,在service中能够随时引用,而不须要关注这个引用是否合理;这样的开发模式在应用还小的时候没什么问题,不过,随着业务的发展和应用的升级,这些模块之间的引用关系会愈来愈复杂而没法管理(这时候应用也就成为了一个“大泥球”),当某一天须要对应用进行服务化拆分的时候,就须要花很大的精力去理清不一样模块之间的耦合和引用关系。SOFA的模块化特性就是为了解决这个问题而出现的,这种特性能够强制开发者在增长两个模块之间的引用关系的时候进行仔细的设计和思考。spring

SOFA的模块化

SOFA的模块,是一种可运行的模块;普通的Spring项目中的模块,则是普通的Jar。一个完整的 SOFA模块和一个普通的Jar包有两点区别:编程

  • SOFA模块包含一份sofa-module.properties文件,这份文件里面定义了SOFA模块的名称以及模块之间的依赖关系。
  • SOFA模块的META-INF/spring目录下,能够放置任意多的Spring配置文件,SOFA会自动把它们做为本模块的Spring配置加载起来。

使用SOFA模块化特性后,两个模块之间的bean没法直接通讯,须要使用SOFA的通讯协议进行通讯,SOFA支持两种通讯协议:后端

  • jvm调用,两个模块是在同一个JVM虚拟机中运行,无需通过网络调用。
  • rpc调用,两个模块不是在同一个JVM虚拟机中运行,甚至不是在一台机器上,须要通过网络调用。

SOFA为开发人员提供了三种形式的发布和引用服务的方式:xml方式、注解方式、编程方式。我如今用的比较多的仍是xml方式,缘由在于SofaService和SofaReference都是只支持jvm服务的发布和引用,而xml方式则能够支持两种形式的调用。安全

SOFA模块化对开发模式的影响

SOFA提供的模块化解决方案,既实现了真正的、运行时的模块化,又没有过分引入OSGI的复杂度,是一种有效的折衷方案。接触SOFA到熟悉SOFA的过程对个人开发思路影响很大,可是在熟悉了SOFA的模块化思想以后,我发现这个特性对于我日常的开发工做有几个好处。网络

安全的近远端架构

为了下降服务端的压力,咱们须要提供一个SDK供业务方使用,在以前Spring体系下,这种架构也是能够执行的,可是有个弊端——SDK中应用的类和JAR包对于业务方的应用来讲也是可见的,在某些状况下会出现冲突或引入潜在的BUG。架构

使用SOFA的模块化特性,咱们提供的近端包虽然仍是跟业务方的应用共享一个JVM,可是在类加载器层面实现了隔离,对于业务方来讲,他们只须要知道是使用了咱们的哪些接口,而不须要关注咱们这个SDK引入了多少三方JAR包。

更好的代码共享

利用SOFA模块化,要实现代码共享,可没有Spring体系下那么简单——直接引用给一个模块就能够。在SOFA中,要进行代码共享,一般有两种状况:(1)近远端代码共享(2)管理时和运行时代码共享。

以第(1)种状况为例,某个组件近远端都是同样的,为了不代码重复,咱们如何实现代码共享呢?我如今的作法是:在一个公共的test-core模块中定义须要共享的接口和实现类;这个test-core模块不能定义为SOFA的模块,只能定义为一个普通的JAR包;而后在须要使用该接口的SOFA模块(近端模块和远端模块)中,分别声明和引用那个共享的bean,示例图以下所示。

模块引用示例

这里的重点在于:

  • javaadu-core模块中是一个普通的JAR模块,只有接口的定义和实现,在这个模块中没有对bean的声明
  • javaadu-remote模块中是一个SOFA模块,在这里引用了javaadu-core中的接口和实现,这里须要对bean进行声明(bean声明)和发布(sofa-service),当前应用的其余模块要想使用该接口,只须要引用javaadu-core和javaadu-remote,而后使用sofa-reference引用该接口就能够,这里通常是jvm调用;其余应用若是想使用该接口,而且没有近端需求的话,则须要引用javaadu-core和javaadu-remote,并使用sofa-reference引用。能够看出,SOFA模糊了跨应用调用和应用内调用的概念,模块化作得很完全
  • javaadu-client模块是一个SOFA模块,也是近端模块,在这里也须要本身定义和使用javaadu-core中的接口和实现。

总结

本文主要介绍了SOFA开发框架与Spring体系区别最明显的一个特性:SOFA模块化,经过每一个模块一个Spring上下文的形式,实现了真正的运行时隔离。

基于我我的的使用经验,SOFA模块化对服务端开发的影响优大于劣:在维护代码中的过程当中会仔细斟酌当前应用的模块依赖结构是否合理;能够更安全得提供SDK给业务方使用;在实现代码共享的时候,也须要仔细考虑哪些代码值得共享,哪些不须要。

参考资料

  1. Sofaboot-模块化开发概述
  2. 蚂蚁金服的业务系统模块化之模块化隔离方案
  3. 阿里巴巴Java开发手册(华山版).pdf
  4. JVM服务发布与引用

本号专一于后端技术、JVM问题排查和优化、Java面试题、我的成长和自我管理等主题,为读者提供一线开发者的工做和成长经验,期待你能在这里有所收获。

javaadu
相关文章
相关标签/搜索