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

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

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

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

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

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服务发布与引用
    ***
    本号(javaadu)专注于后端技术、JVM问题排查和优化、Java面试题、个人成长和自我管理等主题,为读者提供一线开发者的工作和成长经验,期待你能在这里有所收获。

谈谈我对SOFA模块化的理解的更多相关文章

  1. 谈谈你对 Java 平台的理解

    声明 本篇所涉及的提问,正文的知识点,全都来自于杨晓峰的<Java核心技术36讲>,当然,我并不会全文照搬过来,毕竟这是付费的课程,应该会涉及到侵权之类的问题. 所以,本篇正文中的知识点, ...

  2. java面试题(杨晓峰)---第一讲谈谈你对java平台的理解

    本人总结: 面向对象(封装,继承,多态) 平台无关性(jvm运行,class文件) 语言(泛型,lambda) 类库(集合,并发,网络,io/nio) jre(java运行环境,JVM,类库) JDK ...

  3. 谈谈你对java平台的理解?

    问题:谈谈你对java平台的理解?java是解释执行,这句话对吗? 典型回答:java本身是一种面向对象的语言,具有很好的跨平台的能力,能够做到“write once ,run anywhere”.另 ...

  4. Java核心-01 谈谈你对Java平台的理解

    今天我要问你的问题是,谈谈你对 Java 平台的理解?“Java 是解释执行”,这句话正确吗? 典型回答 Java本身是一种面向对象的语言,最显著的特性有两个.一是所谓的“书写一次,到处运行”,能够非 ...

  5. 谈谈你对 Struts 2 的理解

    谈谈你对Struts的理解. struts是一个按MVC模式设计的Web层框架,其实它就是一个大大的servlet,这个Servlet名为ActionServlet,或是ActionServlet的子 ...

  6. seajs模块化作用理解(一句话)

    seajs是js模块化的工具,主要大文件js不方便其他人理解,加载也较慢,seajs把各个功能模块分开,方便平行化开发,同时易于修改和理解,不用重复写功能需要时就应用 (有什么错误,请指正,缺少多谢补 ...

  7. 谈谈我对C# 多态的理解

    面向对象三要素:封装.继承.多态. 封装和继承,这两个比较好理解,但要理解多态的话,可就稍微有点难度了.今天,我们就来讲讲多态的理解. 我们应该经常会看到面试题目:请谈谈对多态的理解. 其实呢,多态非 ...

  8. 谈谈对HTML语义化的理解

    什么是HTML语义化? HTML标签可以分为有语义的标签,和无语义的标签.比如table表示表格,form表示表单,a标签表示超链接,strong标签表强调.无语义标签典型的有<div>, ...

  9. 谈谈你对this对象的理解

    理解: 1.this是js 的一个关键字,随着函数的使用场合的不同,this 的值会发生变化. 2.一个总原则:即this指的是调用函数的那个对象. 3.一般情况下,this 是全局对象,可以作为方法 ...

随机推荐

  1. CentOS EPEL yum源

    CentOS EPEL yum源 用yum安装软件时,经常发现我们的yum源里面没有该软件,比如htop.网上查到的一个方案是需要自己去wget源码,然后configure,make,make ins ...

  2. Java编程思想,初学者推荐看看

    这是一本介绍Java编程思想,如何从面向过程的编程思想转换为面向对象的编程思想.我个人是比较建议新手看一下的,思想掌握了,学起来自然也就会方便很多的,我还有一些Java基础的数,有需要的可以找我要,都 ...

  3. vue中el-upload上传多图片且携带参数,批量而不是一张一张的解决方案

    现在前端基本不是vue技术栈就是react技术栈. vue技术栈最常用的就是element-ui的ui框架了. 在项目中,我们经常会碰到这种需求:批量上传文件 element-ui 确实也为我们提供了 ...

  4. .Net集合详解

    前言 前面几篇文章讲了泛型.讲了数组,都有提到集合,这一节重点对集合进行详细解说.本文主要使用各种集合类型.以至于评估其性能,针对不同的场景选择不同的集合使用. 集合分类详解 一.列表 列表的创建 v ...

  5. 释放你的硬盘空间!——Windows 磁盘清理技巧

    引言 用了Windows系统的各位都知道,作为系统盘的C盘的空间总是一天比一天少.就拿本人的例子来说,自从安装了Win10,就发现,C盘从一开始的10几G占用,到现在慢慢变成了20G.30G….占用只 ...

  6. linux杂货铺

    vmware虚拟机克隆后网卡不能使用 解决方法如下 cat /etc/udev/rules.d/70-persistent-net.rules1.将eth0这行注释掉或者删除,这里记载的还是克隆系统时 ...

  7. jenkins未授权访问漏洞

    jenkins未授权访问漏洞 一.漏洞描述 未授权访问管理控制台,可以通过脚本命令行执行系统命令.通过该漏洞,可以后台管理服务,通过脚本命令行功能执行系统命令,如反弹shell,wget写webshe ...

  8. 一文搞懂Python迭代器和生成器

    很多童鞋搞不懂python迭代器和生成器到底是什么?它们之间又有什么样的关系? 这篇文章就是要用最简单的方式让你理解Python迭代器和生成器! 1.迭代器和迭代过程 维基百科解释道: 在Python ...

  9. 一文搞懂 Prometheus 的直方图

    原文链接:一文搞懂 Prometheus 的直方图 Prometheus 中提供了四种指标类型(参考:Prometheus 的指标类型),其中直方图(Histogram)和摘要(Summary)是最复 ...

  10. springmvc原理详解(手写springmvc)

    最近在复习框架 在快看小说网搜了写资料 和原理 今天总结一下 希望能加深点映像  不足之处请大家指出 我就不画流程图了 直接通过代码来了解springmvc的运行机制和原理 回想用springmvc用 ...