螞蟻 RPC 框架 SOFA-RPC 初體驗

莫那·魯道發表於2018-04-30

image.png

前言

最近螞蟻金服開源了分散式框架 SOFA,樓主寫了一個 demo,體驗了一下 SOFA 的功能,SOFA 完全相容 SpringBoot(當然 Dubbo 也是可以相容的)。

專案地址:Alipay ,該主頁有 5 個專案,都是阿里開源的。 sofa-bootsofa-rpcsofa-boltsofa-arksofa-rpc-boot-projects

快速開始

實際上,SOFA-RPC 的官方文件已經詳細介紹瞭如何使用這個 RPC 框架,基於 Netty 的長連線。類似 Dubbo。樓主看這個框架主要是為了學習分散式 RPC 框架的設計。

由於測試例子需要兩個專案,我們建一個目錄,目錄下建立兩個 maven module(SpringBoot 專案即可):

螞蟻 RPC 框架 SOFA-RPC 初體驗

一個生產者,一個消費者。

將這兩個專案的 pom.xml 中 springBoot 的 parent 標籤換成如下:

  <parent>
    <groupId>com.alipay.sofa</groupId>
    <artifactId>sofaboot-dependencies</artifactId>
    <version>2.3.1</version>
  </parent>
複製程式碼

再增加一個依賴:

<dependency>
  <groupId>com.alipay.sofa</groupId>
  <artifactId>rpc-sofa-boot-starter</artifactId>
</dependency>
複製程式碼

到這裡,關於 RPC 框架的依賴和搭建就好了,是不是很簡單?

介面建立

既然是 RPC 服務,那就需要一個介面,再有一個實現類。我們在提供方這裡建立。

public interface HelloSyncService {
  String saySync(String string);
}

// 實現類
public class HelloSyncServiceImpl implements HelloSyncService {

  @Override
  public String saySync(String string) {
    return "provider tell you : this is your say: " +  string;
  }
}
複製程式碼

然後在消費方的 pom.xml 新增對這個介面的依賴。

<dependency>
  <groupId>cn.think.in.java</groupId>
  <artifactId>provider</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <scope>compile</scope>
</dependency>
複製程式碼

有了介面,就需要配置一下。

介面配置

首先在提供方這裡釋出介面。建立一個 xml 檔案,名為:rpc-sofa-boot-starter-samples.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">

  <bean id="helloSyncServiceImpl" class="cn.think.in.java.provider.HelloSyncServiceImpl"/>
  <sofa:service ref="helloSyncServiceImpl" interface="cn.think.in.java.provider.HelloSyncService">
    <sofa:binding.bolt/>
  </sofa:service>
</beans>
複製程式碼

很簡單,釋出了一個介面,類似 Spring 的一個 bean。

同時這個介面的協議是 bolt,也就是阿里的 RPC 網路通訊框架 solt(基於 Netty 的最佳實踐)。

同樣的,在消費者的 resource 檔案下,也建立一個同名檔案。內容稍有不同。

<?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">

  <sofa:reference id="helloSyncServiceReference" interface="cn.think.in.java.provider.HelloSyncService">
    <sofa:binding.bolt/>
  </sofa:reference>
</beans>
複製程式碼

通過介面得到一個 bean。

好,介面的配置好了,那麼就可以啟動測試了。

準備測試

測試之前還要做點點工作。

在提供者配置檔案 appcation.perproties 中,配置一下埠和程式名稱。

# server.port=8080 # 預設
spring.application.name=provider
複製程式碼

預設 8080 埠,就不必配置了。

然後,在消費者那裡同樣配置這個檔案。內容如下:

spring.application.name=consumer
server.port=8081
複製程式碼

消費者和提供者埠不能衝突。

還剩最後一步。

將檔案引入到 Spring 容器中。

在提供者啟動類上加入以下內容(引入配置檔案):

@ImportResource({ "classpath*:rpc-sofa-boot-starter-samples.xml" })
@SpringBootApplication
public class ProviderApplication {

  public static void main(String[] args) {
    SpringApplication.run(ProviderApplication.class, args);
  }
}
複製程式碼

在消費者啟動類中引入以下內容:

@ImportResource({ "classpath*:rpc-sofa-boot-starter-samples.xml" })
@SpringBootApplication
public class ConsumerApplication {

  public static void main(String[] args) {
    SpringApplication springApplication = new SpringApplication(ConsumerApplication.class);
    ApplicationContext applicationContext = springApplication.run(args);

    HelloSyncService helloSyncServiceReference = (HelloSyncService) applicationContext
        .getBean("helloSyncServiceReference");

    System.out.println(helloSyncServiceReference.saySync("sync"));
  }
}
複製程式碼

稍微多點東西,但也還是挺簡單的。

首先建立一個 Spring 啟動類。然後執行,從 Spirng 容器中獲取到 bean(被動態代理封裝的遠端呼叫)。然後呼叫代理方法。

執行

先執行提供者:

2018-04-23 23:18:24.776  INFO 26654 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)
2018-04-23 23:18:24.776  INFO 26654 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env || /env.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-04-23 23:18:24.886  INFO 26654 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-04-23 23:18:24.893  INFO 26654 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Logback ]
2018-04-23 23:18:24.966  INFO 26654 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Logback ]
2018-04-23 23:18:25.174  INFO 26654 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2018-04-23 23:18:25.179  INFO 26654 --- [           main] c.t.i.java.provider.ProviderApplication  : Started ProviderApplication in 3.352 seconds (JVM running for 3.978)
複製程式碼

再執行消費者:

2018-04-23 23:19:21.940  INFO 26673 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env || /env.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-04-23 23:19:22.055  INFO 26673 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-04-23 23:19:22.063  INFO 26673 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
2018-04-23 23:19:22.319  INFO 26673 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8081 (http)
2018-04-23 23:19:22.324  INFO 26673 --- [           main] c.t.i.java.consumer.ConsumerApplication  : Started ConsumerApplication in 3.898 seconds (JVM running for 4.524)
provider tell you : this is your say: sync
複製程式碼

成功列印結果。

總結

首先第一感覺是,這個框架還是挺好用,挺簡單的,基於當前的 SpringBoot 。快速啟動。而且不是 SpringCloud 的 Http 呼叫,使用 Netty 作為網路通訊框架,效能當然是沒有問題的。

當然,我們這裡的 demo 使用的註冊中心沒有使用 ZK,畢竟初體驗嘛,使用的本地的檔案。

然而,樓主對這個框架有很大的興趣。接下來的空閒時間裡,樓主將好好研究 SOFA 相關的程式碼。

相關文章