實操 | 基於 SOFABoot 進行模塊化開發

SOFA 中間件是螞蟻金服自主研發的金融級分佈式中間件,包含了構建金融級雲原生架構所需的各個組件,包括微服務研發框架,RPC 框架,服務註冊中心,分佈式定時任務,限流/熔斷框架,動態配置推送,分佈式鏈路追蹤,Metrics監控度量,分佈式高可用消息隊列,分佈式事務框架,分佈式數據庫代理層等組件,是在金融場景裏錘鍊出來的最佳實踐。git


SOFABoot 是螞蟻金服中間件團隊開源的基於 Spring Boot 的一個開發框架,SOFABoot 從 2.4.0 版本開始支持基於 Spring 上下文隔離的模塊化開發能力,SOFABoot 模塊除了包括 Java 代碼外,還會包含 Spring 配置文件,每一個 SOFABoot 模塊都是獨立的 Spring 上下文。github


SOFABoot 的 Github 的地址是:web

https://github.com/alipay/sofa-boot spring


背景

爲了更好的理解 SOFABoot 模塊化開發的概念,咱們來區分幾個常見的模塊化形式:數據庫

  • 基於代碼組織上的模塊化:這是最多見的形式,在開發期,將不一樣功能的代碼放在不一樣 Java 工程下,在編譯期被打進不一樣 jar 包,在運行期,全部 Java 類都在一個 classpath 下且使用同一個 Spring 上下文,沒作任何隔離;bash

  • 基於 Spring 上下文隔離的模塊化:使用 Spring 上下文來作不一樣功能模塊的隔離,在開發期和編譯期,代碼和配置也會分在不一樣 Java 工程中,但在運行期,不一樣的 Spring Bean 相互不可見,IoC 只在同一個上下文內部發生,可是全部的 Java 類仍是在一個 ClassLoader 下;架構

  • 基於 ClassLoader 隔離的模塊化:借用 ClassLoader 來作隔離,每一個模塊都有獨立的 ClassLoader,模塊與模塊之間的 classpath 不一樣,SOFAArk 就是這種模塊化的實踐方式。併發

以上三種模塊化形式的隔離化程度逐次遞進,但模塊化就像一把雙刃劍,在下降模塊間耦合的同時也給模塊間交互增長了成本,本文介紹第二種模塊化形式 — 基於 Spring 上下文隔離的模塊化。app

與基於代碼組織上的模塊化相比,每一個 SOFABoot 模塊不單單包括 Java 代碼,還會包含 Spring 配置文件,這種全新的包組織方式大大下降了用戶接入成本,用戶只須要簡單的引入 Jar 包便可,由 SOFABoot 框架負責刷新模塊上下文,無需在原來 Spring 配置文件中新增任何 Bean 定義,簡化了接入流程,下降了出錯概率。框架

每一個 SOFABoot 模塊的 Spring 上下文都是隔離的。在 Spring 開發中,保證 Spring BeanId 不衝突是 Spring 運行的基礎,這個限制在應用規模較小時很容易解決,只需用戶在定義 BeanId 時稍加註意便可。

可是隨着系統規模愈來愈大,一個系統的開發每每涉及多個團隊,保證每一個業務定義 BeanId 不重複的成本也愈來愈高。在 SOFABoot 中,每一個 SOFABoot 模塊使用獨立的 Spring 上下文,避免了不一樣 SOFABoot 模塊間 BeanId 衝突,有效下降企業級多模塊開發時團隊間的溝通成本。

基本原理

在介紹 SOFABoot 模塊化開發使用以前,咱們簡單瞭解下其背後的實現原理。下圖是應用運行時的邏輯視圖:

SOFABoot 模塊是模塊化開發的最小單元,每一個 SOFABoot 模塊是一個獨立的 Spring 上下文,在 SOFABoot 模塊中咱們能夠定義Bean、發佈 RPC 服務、鏈接數據庫等等。

因爲上下文隔離,模塊與模塊之間的 Bean 沒法經過@Autowired 依賴注入,咱們提供了 JVM Service/Reference 的方式進行模塊間通訊。

SOFABoot 提供了兩種形式的服務發佈和引用,用於解決不一樣級別的模塊間調用問題:

  • JVM 服務發佈和引用:解決一個 SOFABoot 應用內部各個 SOFABoot 模塊之間的調用問題

  • RPC 服務發佈和引用:解決多個 SOFABoot 應用之間的遠程調用問題

Spring Boot 應用在調用 SpringApplication.run 時會建立一個 Spring Context,咱們把它叫作 Root Application Context,它是每一個 SOFABoot 模塊建立的 Spring Context 的 Parent。這樣設計的目的是爲了保證每一個 SOFABoot 模塊的 Spring Context 都能發現 Root Application Context 中建立的 Bean,這樣當應用新增 Starter 時,不只 Root Application Context 可以使用 Starter 中新增的 Bean,每一個 SOFABoot 模塊的 Spring Context 也能使用這些 Bean。

下面咱們來演示如何開發一個簡單的 SOFABoot 模塊

1. 新建工程

DEMO 工程地址:

https://github.com/caojie09/sofaboot-module-demo

運行須要 JDK 6 及以上、 Maven 3.2.5 以上。

首先咱們在 IDE 裏新建一個普通 Maven 工程,並建立兩個普通的 Maven 模塊:

  • service-facade: 定義服務接口

  • service-provide: 演示新建 SOFABoot 模塊併發布 JVM 服務

2. 定義服務接口

service-facade 模塊包含用於演示 SOFABoot 模塊發佈與引用服務接口:

public interface SampleService {
    String message();
}複製代碼

3. 定義 SOFABoot 模塊

service-provider 是一個 SOFABoot 模塊,它會發佈一個 JVM 服務供其餘模塊使用。首先須要爲 service-provider 模塊增長 sofa-module.properties 文件,將其定義爲 SOFABoot 模塊,sofa-module.properties 文件放置在 resources 目錄:

Module-Name=com.alipay.sofa.service-provider複製代碼

4. 發佈服務

SOFABoot 支持三種形式的服務發佈,分別是: XML 方式、Annotation 方式以及 API 編碼方式,這裏演示的是 XML 方式發佈服務。

首先增長 SampleServiceImpl 類,實現 SampleService 接口:

public class SampleServiceImpl implements SampleService {
    private String message;

    public String message() {
        return message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}複製代碼

增長 META-INF/spring/service-provide.xml 文件,將 SampleServiceImpl 發佈爲 JVM 服務:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:sofa="http://sofastack.io/schema/sofaboot"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd"
       default-autowire="byName">
    <bean id="sampleService" class="com.alipay.sofa.isle.sample.SampleServiceImpl">
        <property name="message" value="Hello, SOFABoot module."/>
    </bean>

    <sofa:service ref="sampleService" interface="com.alipay.sofa.isle.sample.SampleService">
        <sofa:binding.jvm/>
    </sofa:service>
</beans>複製代碼

到此爲止,咱們就成功新建了一個 SOFABoot 模塊,並在模塊中發佈了一個 JVM 服務,能夠看到,一個 SOFABoot 模塊不單單包括代碼,還包括 Spring 配置文件。

接下來,在 Spring Boot 工程中,快速集成 SOFABoot 的模塊化開發能力,並使用剛剛新建的模塊發佈的服務

Spring Boot 工程集成模塊化開發組件

1. 新建工程

Demo 工程地址:

https://github.com/caojie09/sofaboot-module-run

在 Spring Boot 官網 https://start.spring.io 新建一個 web 工程,請選擇 Spring Boot 版本號爲 1.X,目前不支持 Spring Boot 2。修改 maven 項目的配置文件 pom.xml,將

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.14.RELEASE</version>
    <relativePath/>
</parent>複製代碼

替換爲:

<parent>
    <groupId>com.alipay.sofa</groupId>
    <artifactId>sofaboot-dependencies</artifactId>
    <version>2.4.2</version>
</parent>複製代碼

並添加以下依賴:

<dependency>
    <groupId>com.alipay.sofa</groupId>
    <artifactId>isle-sofa-boot-starter</artifactId>
</dependency>複製代碼

這樣,一個 Spring Boot 工程便集成了 SOFABoot 模塊化開發能力。

2. 添加 SOFABoot 模塊

添加 SOFABoot 模塊很簡單,只須要把 SOFABoot 模塊的座標加在當前 maven 工程便可,對於這個例子,只須要在啓動類模塊添加上面建立的 service-provider 模塊:

<dependency>
    <groupId>com.alipay.sofa</groupId>
    <artifactId>service-provide</artifactId>
    <version>1.0.0</version>
</dependency>複製代碼

與傳統的 JAR 包代碼分發方式相比,SOFABoot 模塊不單單包括代碼,還包括 Spring 配置文件,用戶在使用 SOFABoot 模塊時,只需增長依賴便可。

3. 引用服務

爲了直觀演示,咱們在演示工程增長了一個 Rest 接口,在 Rest 接口中引用上文 SOFABoot 模塊發佈的 JVM 服務。這裏演示的是 Annotation 方式引用服務,只需在類的字段上增長

@
SofaReference 註解便可:

@RestController
public class HelloController {
    @SofaReference
    private SampleService sampleService;

    @RequestMapping("/hello-sofamodule")
    public String hello() throws IOException {
        return sampleService.message();
    }
}複製代碼

訪問 http://localhost:8080/hello-sofamodule,能夠看到 HelloController 成功調用到了 service-provider 發佈的服務。

總結

本文主要介紹了使用 SOFABoot 進行上下文隔離的模塊化開發,經過兩個簡單的用例工程,分別介紹瞭如何開發一個 SOFABoot 模塊以及如何在 Spring Boot 快速集成模塊化開發能力。每一個 SOFABoot 模塊都是獨立的 Spring 上下文,SOFABoot 模塊不單單包括代碼,還包括 Spring 配置文件,用戶在引用 SOFABoot 模塊時,只需簡單增長依賴便可,由框架負責刷新模塊上下文,無需在 Spring 中新增任何 Bean 定義,簡化了接入流程,下降了出錯概率。


你也許感興趣:

開源 | 在 Spring Boot 中集成 SOFABoot 類隔離能力

開源 | SOFABoot 類隔離原理剖析


長按關注,獲取最新分佈式架構乾貨

歡迎你們共同打造 SOFAStack https://github.com/alipay

相關文章
相關標籤/搜索