上文介紹了 SOFARPC 的簡單使用。在生產環境中,一般會將 SOFARPC 整合到 SpringBoot 中。螞蟻金服提供了 SOFABoot 框架,SOFABoot 是螞蟻金服開源的基於 Spring Boot 的研發框架,它在 Spring Boot 的基礎上,提供了諸如 Readiness Check,類隔離,日誌空間隔離等等能力。php
在加強了 Spring Boot 的同時,SOFABoot 提供了讓用戶能夠在 Spring Boot 中很是方便地使用 SOFA 中間件的能力。當前 SOFABoot 的 2.3.1 版本是基於 Spring Boot 1.4.2.RELEASE 來構建的。java
螞蟻金服SOFA-Boot整合SOFA-RPC(上篇) github
螞蟻金服SOFA-Boot整合SOFA-RPC(下篇) spring
SOFABoot 在 Spring Boot 的基礎上,提供瞭如下能力:docker
在 Spring Boot 健康檢查能力的基礎上,提供了 Readiness Check 的能力,保證應用實例安全上線。apache
中間件框架自動發現應用的日誌實現依賴並獨立打印日誌,避免中間件和應用日誌實現綁定,經過 sofa-common-tools 實現。編程
基於 SOFAArk 框架提供類隔離能力,方便使用者解決各類類衝突問題。json
統一管控、提供中間件統一易用的編程接口、每個 SOFA 中間件都是獨立可插拔的組件。
SOFABoot 基於 Spring Boot 的基礎上進行構建,而且徹底兼容 Spring Boot。
要使用 SOFABoot,須要先準備好基礎環境,SOFABoot 依賴如下環境:
SOFABoot 是直接構建在 Spring Boot 之上,所以能夠使用 Spring Boot 的工程生成工具來生成。添加一個 Web 的依賴,以便最後在瀏覽器中查看效果。
在建立好一個 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>
複製代碼
添加 SOFABoot 健康檢查擴展能力的依賴:
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>healthcheck-sofa-boot-starter</artifactId>
</dependency>
複製代碼
最後,在工程的 application.properties 文件下添加一個 SOFABoot 必需要使用的參數。
# 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
複製代碼
[
{
"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"
}
]
複製代碼
{
"status": "UP",
"sofaBootComponentHealthCheckInfo": {
"status": "UP"
},
"springContextHealthCheckInfo": {
"status": "UP"
},
"DiskSpaceHealthIndicator": {
"status": "UP",
"total": 250790436864,
"free": 208612020224,
"threshold": 10485760
}
}
複製代碼
status: "UP"
表示應用 Readiness Check
的就緒狀態是健康的。
{
"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 日誌。
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 重複的依賴排除在外,以避免引發衝突。
在 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
逐一查看。這裏加以不累述!
在要使用的 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">
複製代碼
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 屬性表示該服務的接口。
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 更豐富、強大的功能介紹,下篇敬請期待!
歡迎關注技術公衆號: 零壹技術棧
本賬號將持續分享後端技術乾貨,包括虛擬機基礎,多線程編程,高性能框架,異步、緩存和消息中間件,分佈式和微服務,架構學習和進階等學習資料和文章。