螞蟻金服SOFA-Boot整合SOFA-RPC(上篇)

前言

上文介紹了 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

其餘文章

正文

1. 功能描述

SOFABoot 在 Spring Boot 的基礎上,提供瞭如下能力:docker

1.1. 擴展 Spring Boot 的健康檢查

在 Spring Boot 健康檢查能力的基礎上,提供了 Readiness Check 的能力,保證應用實例安全上線。apache

1.2. 日誌空間隔離能力

中間件框架自動發現應用的日誌實現依賴並獨立打印日誌,避免中間件和應用日誌實現綁定,經過 sofa-common-tools 實現。編程

1.3. 提供類隔離的能力

基於 SOFAArk 框架提供類隔離能力,方便使用者解決各類類衝突問題。json

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 必需要使用的參數。

# 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 的就緒狀態是健康的。

  • 在瀏覽器中輸入 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 更豐富、強大的功能介紹,下篇敬請期待!


歡迎關注技術公衆號: 零壹技術棧

image

本賬號將持續分享後端技術乾貨,包括虛擬機基礎,多線程編程,高性能框架,異步、緩存和消息中間件,分佈式和微服務,架構學習和進階等學習資料和文章。

相關文章
相關標籤/搜索