前言
上文介紹了 SOFARPC 的簡單使用。在生產環境中,通常會將 SOFARPC 整合到 SpringBoot 中。螞蟻金服提供了 SOFABoot 框架,SOFABoot 是螞蟻金服開源的基於 Spring Boot 的研發框架,它在 Spring Boot 的基礎上,提供了諸如 Readiness Check,類隔離,日誌空間隔離等等能力。
在增強了 Spring Boot 的同時,SOFABoot 提供了讓使用者可以在 Spring Boot 中非常方便地使用 SOFA 中介軟體的能力。當前 SOFABoot 的 2.3.1 版本是基於 Spring Boot 1.4.2.RELEASE 來構建的。
其他文章
正文
1. 功能描述
SOFABoot 在 Spring Boot 的基礎上,提供了以下能力:
1.1. 擴充套件 Spring Boot 的健康檢查
在 Spring Boot 健康檢查能力的基礎上,提供了 Readiness Check 的能力,保證應用例項安全上線。
1.2. 日誌空間隔離能力
中介軟體框架自動發現應用的日誌實現依賴並獨立列印日誌,避免中介軟體和應用日誌實現繫結,通過 sofa-common-tools 實現。
1.3. 提供類隔離的能力
基於 SOFAArk 框架提供類隔離能力,方便使用者解決各種類衝突問題。
1.4. 中介軟體的整合管理
統一管控、提供中介軟體統一易用的程式設計介面、每一個 SOFA 中介軟體都是獨立可插拔的元件。
1.5. 完全相容 Spring Boot
SOFABoot 基於 Spring Boot 的基礎上進行構建,並且完全相容 Spring Boot。
2. 快速開始
2.1. 環境準備
要使用 SOFABoot,需要先準備好基礎環境,SOFABoot 依賴以下環境:
- JDK7 或 JDK8
- 需要採用 Apache Maven 3.2.5 或者以上的版本來編譯
2.2. 建立工程
SOFABoot 是直接構建在 Spring Boot 之上,因此可以使用 Spring Boot 的工程生成工具來生成。新增一個 Web 的依賴,以便最後在瀏覽器中檢視效果。
2.3. 引入 SOFABoot
在建立好一個 Spring Boot 的工程之後,接下來就需要引入 SOFABoot 的依賴。首先,需要將上文中生成的 Spring Boot 工程的 zip 包解壓後,修改 maven 專案的配置檔案 pom.xml。
替換 spring-boot-starter-parent 為相應版本的 sofaboot-dependencies,例如:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/>
</parent>
複製程式碼
替換為:
<parent>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofaboot-dependencies</artifactId>
<version>2.3.1</version>
</parent>
複製程式碼
2.4. SOFABoot 健康檢查
引入相關依賴
新增 SOFABoot 健康檢查擴充套件能力的依賴:
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>healthcheck-sofa-boot-starter</artifactId>
</dependency>
複製程式碼
最後,在工程的 application.properties 檔案下新增一個 SOFABoot 必須要使用的引數。
- spring.application.name:用於標示當前應用的名稱
- logging path:用於指定日誌的輸出目錄
# Application Name
spring.application.name=SOFABoot Example
# logging path
logging.path=./logs
複製程式碼
執行 main() 方法,專案啟動以後,控制檯的日誌輸出如下:
2018-05-09 09:56:48.305 INFO 15097 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2018-05-09 09:56:48.309 INFO 15097 --- [ main] c.o.s.r.e.SofaBootExampleApplication : Started SofaBootExampleApplication in 2.551 seconds (JVM running for 3.046)
2018-05-09 09:57:46.005 INFO 15097 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-05-09 09:57:46.005 INFO 15097 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2018-05-09 09:57:46.021 INFO 15097 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 16 ms
複製程式碼
檢視健康狀態
- 在瀏覽器中輸入 http://localhost:8080/sofaboot/versions 來檢視當前 SOFABoot 中使用 Maven 外掛生成的版本資訊彙總,結果類似如下:
[
{
"GroupId": "com.alipay.sofa",
"Doc-Url": "https://github.com/alipay/sofa-boot",
"ArtifactId": "infra-sofa-boot-starter",
"Bulit-Time": "2018-04-18T22:19:09+0800",
"Commit-Time": "2018-04-18T22:07:52+0800",
"Commit-Id": "466f0e039b250ff7b201dc693eec7fa07eb21ad7",
"Version": "2.3.1"
}
]
複製程式碼
- 在瀏覽器中輸入 http://localhost:8080/health/readiness 檢視應用 Readiness Check 的狀況,類似如下:
{
"status": "UP",
"sofaBootComponentHealthCheckInfo": {
"status": "UP"
},
"springContextHealthCheckInfo": {
"status": "UP"
},
"DiskSpaceHealthIndicator": {
"status": "UP",
"total": 250790436864,
"free": 208612020224,
"threshold": 10485760
}
}
複製程式碼
status: "UP"
表示應用 Readiness Check
的就緒狀態是健康的。
- 在瀏覽器中輸入 http://localhost:8080/health 來檢視應用的執行時健康狀態(可能會隨著時間發生變化,Spring Boot原生自帶功能)。
{
"status": "UP",
"sofaBootComponentHealthCheckInfo": {
"status": "UP",
"Middleware": {
}
},
"springContextHealthCheckInfo": {
"status": "UP"
},
"diskSpace": {
"status": "UP",
"total": 250790436864,
"free": 208612528128,
"threshold": 10485760
}
}
複製程式碼
檢視日誌
在上面的 application.properties 裡面,我們配置的日誌列印目錄是 ./logs 即當前應用的根目錄(我們可以根據自己的實踐需要配置),在當前工程的根目錄下可以看到類似如下結構的日誌檔案:
./logs
├── health-check
│ ├── sofaboot-common-default.log
│ └── sofaboot-common-error.log
├── infra
│ ├── common-default.log
│ └── common-error.log
└── spring.log
複製程式碼
如果應用啟動失敗或者健康檢查返回失敗,可以通過相應的日誌檔案找到錯誤的原因,有些需要關注 common-error.log 日誌。
2.5. SOFA-RPC 環境準備
引入相關依賴
SOFABoot 使用一系列字尾為 -sofa-boot-starter 來標示一箇中介軟體服務,如果想要使用某個中介軟體,直接新增對應的依賴即可。進一步引入 SOFA-RPC 的 starter 依賴:
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>rpc-sofa-boot-starter</artifactId>
</dependency>
複製程式碼
選擇 Zookeeper 作為服務註冊列表,在 pom.xml 檔案中引入相關依賴:
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
<version>0.10</version>
</dependency>
複製程式碼
注意將 zkclient 重複的依賴排除在外,以免引起衝突。
配置 zookeeper 叢集
在 application.properties 中進一步配置 zookeeper 的地址資訊。
# zookeeper address list
com.alipay.sofa.rpc.registry.address=zookeeper://127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183?file=/home/admin/registry
複製程式碼
為了方便起見,本地使用 docker 環境對 zookeeper 叢集進行容器編排。多個 zookeeper 節點通過逗號分隔,file 引數指定當 zookeeper 不可用時,可以利用本地快取檔案進行服務發現。
編寫 docker-compose.yml 檔案如下:
version: '2'
services:
zoo1:
image: zookeeper:latest
restart: always
hostname: zoo1
ports:
- 2181:2181
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=0.0.0.0:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
zoo2:
image: zookeeper:latest
restart: always
hostname: zoo2
ports:
- 2182:2181
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=0.0.0.0:2888:3888 server.3=zoo3:2888:3888
zoo3:
image: zookeeper:latest
restart: always
hostname: zoo3
ports:
- 2183:2181
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=0.0.0.0:2888:3888
複製程式碼
進入 docker-compose.yml 所在檔案目錄, 執行 docker-compose up -d
啟動3臺 zookeeper 容器。啟動完成後,執行 docker-compose ps
檢視程式狀態如下:
$ docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------------------------------
zookeeper_zoo1_1 /docker-entrypoint.sh zkSe ... Up 0.0.0.0:2181->2181/tcp, 2888/tcp, 3888/tcp
zookeeper_zoo2_1 /docker-entrypoint.sh zkSe ... Up 0.0.0.0:2182->2181/tcp, 2888/tcp, 3888/tcp
zookeeper_zoo3_1 /docker-entrypoint.sh zkSe ... Up 0.0.0.0:2183->2181/tcp, 2888/tcp, 3888/tcp
複製程式碼
zookeeper 容器叢集啟動完成,如果想要檢視叢集 leader,可以執行 docker exec -it [container-id] /bin/bash
進入容器執行 zkServer.sh status
逐一檢視。這裡加以不累述!
XSD管理
在要使用的 XML 配置檔案中將頭部 xsd 檔案的宣告設定為如下,這樣就能夠使用 SOFABoot 定義的 XML 元素進行開發。
<?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"
xmlns:context="http://www.springframework.org/schema/context"
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">
複製程式碼
2.6. SOFA-Boot 整合 SOFA-RPC
編寫服務介面和實現類
HelloSyncService.java
public interface HelloSyncService {
String saySync(String string);
}
複製程式碼
HelloSyncServiceImpl.java
public class HelloSyncServiceImpl implements HelloSyncService {
@Override
public String saySync(String sync) {
return sync;
}
}
複製程式碼
編寫服務提供方配置檔案
simple-server-example.xml
<?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="helloSyncServiceImpl" class="com.ostenant.sofa.rpc.example.simple.HelloSyncServiceImpl"/>
<!-- 以多種通訊協議釋出服務 -->
<sofa:service ref="helloSyncServiceImpl" interface="com.ostenant.sofa.rpc.example.simple.HelloSyncService">
<sofa:binding.bolt/>
<sofa:binding.rest/>
<sofa:binding.dubbo/>
</sofa:service>
</beans>
複製程式碼
通過 sofa:service
元素將該服務釋出,其中 ref
屬性表示釋出的服務例項,interface 屬性表示該服務的介面。
- sofa:binding.bolt: 服務通過 bolt 協協議通道釋出,底層基於 Netty 實現。
- sofa:binding.rest: 服務通過 http 協議釋出。
- sofa:binding.dubbo: 服務基於 dubbo 的協議通道釋出。
編寫服務提供方啟動程式
SimpleServerApplication.java
@ImportResource({ "classpath:simple-server-example.xml" })
@SpringBootApplication
public class SimpleServerApplication {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(SimpleServerApplication.class);
ApplicationContext applicationContext = springApplication.run(args);
}
}
複製程式碼
編寫服務消費方配置檔案
simple-client-example.xml
<?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">
<!-- bolt引用 -->
<sofa:reference id="boltHelloSyncServiceReference" interface="com.ostenant.sofa.rpc.example.simple.HelloSyncService">
<sofa:binding.bolt/>
</sofa:reference>
<!-- rest引用 -->
<sofa:reference id="restHelloSyncServiceReference" interface="com.ostenant.sofa.rpc.example.simple.HelloSyncService">
<sofa:binding.rest/>
</sofa:reference>
<!-- dubbo引用 -->
<sofa:reference id="dubboHelloSyncServiceReference" interface="com.ostenant.sofa.rpc.example.simple.HelloSyncService">
<sofa:binding.dubbo/>
</sofa:reference>
</beans>
複製程式碼
編寫服務提供方啟動程式
SimpleClientApplication.java
@ImportResource({ "classpath:simple-client-example.xml" })
@SpringBootApplication
public class SimpleClientApplication {
public static void main(String[] args) {
System.setProperty("server.port", "8081");
SpringApplication springApplication = new SpringApplication(SimpleClientApplication.class);
ApplicationContext applicationContext = springApplication.run(args);
HelloSyncService boltHelloSyncService = (HelloSyncService) applicationContext.getBean("boltHelloSyncServiceReference");
HelloSyncService restHelloSyncService = (HelloSyncService) applicationContext.getBean("restHelloSyncServiceReference");
HelloSyncService dubboHelloSyncService = (HelloSyncService) applicationContext.getBean("dubboHelloSyncServiceReference");
System.out.println("Bolt result:" + boltHelloSyncService.saySync("bolt"));
System.out.println("Rest result:" + restHelloSyncService.saySync("rest"));
System.out.println("Dubbo result:" + dubboHelloSyncService.saySync("dubbo"));
}
}
複製程式碼
分別啟動服務端和客戶端
客戶端控制檯輸出日誌如下:
Bolt result: bolt
Rest result: rest
Dubbo result: dubbo
複製程式碼
對於同一個服務,在服務釋出方配置時,可在以 sofa:service
中通過 sofa:binding.xxx
提供多種協議通道配置;在服務消費方配置時,可以在 sofa:reference
中通過 sofa:binding.xxx
提供對不同通道服務的引用。
小結
本文引入了 SOFA-Boot 框架,對 SOFA-Boot 的將康檢查功能和日誌管理的使用進行了簡單說明,然後在 SOFA-Boot 環境中引入了 SOFA-RPC 框架,並提供了一個完整的服務釋出和註冊的示例程式。
關於 SOFA-RPC 更豐富、強大的功能介紹,下篇敬請期待!
歡迎關注技術公眾號: 零壹技術棧
本帳號將持續分享後端技術乾貨,包括虛擬機器基礎,多執行緒程式設計,高效能框架,非同步、快取和訊息中介軟體,分散式和微服務,架構學習和進階等學習資料和文章。