RPC框架簡單入門之spring-boot整合dubbo
前言
現階段,web
後端開發主流的介面協議型別主要有兩種,一種就是我們傳統的rest
介面,另一種比較流行的就是rpc
,今天我們就來簡單說下rpc
介面,同時我們會通過一個簡單示例,來分享dubbo
框架的基本用法。
rpc
全稱Remote Procedure Call
,中文的意思是遠端程式呼叫。簡單來說,rpc
就是一種基於socket
的呼叫方式,一種有別於rest
的呼叫協議。其核心技術就是動態代理,關於rpc
動態代理的實現,我們前面其實有寫過一個簡易版的rpc
介面,有興趣的小夥伴可以去看下:
下面是rpc
的呼叫原理,這裡放上百度百科的一張圖片,供大家參考:
好了,關於rpc
的理論介紹,我們先說這麼多,下面我們通過一個例項來分享下dubbo
dubbo
我相信很多小夥伴經常在實際開發過程中有用到rpc
,但是對於rpc
的相關知識,很多小夥伴肯定沒有系統學習過(當然也包括我),因為我們在實際工作中,大部分的時間都花在了業務實現方面,很少有機會能真正參與系統架構的搭建,所以很多時候這些知識就顯得不那麼重要了。
但是考慮到未來個人職業發展,同時也為了讓我們在日常工作中更快地解決各類rpc
的相關問題,掌握一些rpc
的基礎知識就尤為重要了,所以從今天開始,我們開始系統地探討下rpc
的相關知識,下面我們先從一個簡單的dubbo
例項開始。
關於dubbo
我想大家應該都比較熟悉了,就算實際工作沒有用到,在面試的過程中也一定聽過。dubbo
alibaba
開源的一款rpc
服務框架,被各大公司廣泛應用,現在也算是java
開發必學的web
開發框架之一,目前最新版本是3.0
。想要了解更多資訊,可以去官方網站看下:
https://dubbo.apache.org/zh/
建立專案
首先我們要建立一個maven
專案,然後分別建立三個模組:common-facade
、service-provider
和service-consumer
。其中service-provider
和service-consumer
是spring-boot
專案,他們分別是服務提供者和服務消費者;common-facade
是普通maven
專案,它主要用來存放我們的facade
facade介面
專案建立完成後,我們先來編寫facade
介面。它就是一個簡單的interface
介面,不需要新增任何配置檔案,也不需要引入第三方包,通常情況下我們會盡可能保證介面的簡潔性。
它就相當於一個介面規範,服務提供者通過實現它的介面提供服務,服務消費者通過它消費服務,所以在服務提供者和消費者的專案中都要引用common-facade
的包,我們通常還會把介面的出入參放在該包下。對於需要呼叫我們服務的專案,直接引入我們的facade
介面包即可。
package io.github.syske.common.facade;
/**
* 示例服務
*
* @author syske
* @version 1.0
* @date 2021-08-11 8:34
*/
public interface DemoService {
String sayHello(String name);
}
服務提供者
服務提供者相對內容比較多,它不僅要引入dubbo
的相關依賴,還需要引入zookeeper
的相關依賴,同時還需要對服務註冊做一些設定。
專案依賴
首先我們看下服務提供者的依賴:
<!-- facade介面 -->
<dependency>
<groupId>io.github.syske</groupId>
<artifactId>common-facade</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- dubbo核心依賴 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.7</version>
</dependency>
<!-- zookeeper客戶端依賴 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>3.3.0</version>
</dependency>
這裡解釋下最後一個依賴。Curator
是Netflix
公司開源的一套Zookeeper
客戶端框架,而Recipes
是Zookeeper
典型應用場景的實現。
這裡我專門去查了一下Netflix
公司,竟然就是大名鼎鼎的奈飛公司,該公司核心業務就是視訊點播,如果你有留意之前我們分享的spring-cloud
的相關內容的話,你會在發現spring-cloud
的好多元件就是出自這家公司,比如eureka
、hystrix
、ribbon
、zuul
,從這一點上來說,這家公司還是很優秀的。
專案配置
首先我們需要通過@DubboComponentScan
指定facade
服務提供者的包名,用於服務註冊,缺少這個註解服務無法正常註冊,這裡可以不指定包名,預設情況下應該會取當前類的包名;
這裡我們還需要指定ApplicationConfig
,也就是服務提供者配置資訊,如果缺少這個配置,啟動的時候會報錯:
另外還有服務註冊配置RegistryConfig
需要指定,這裡主要指定的是zk
的地址、zk
客戶端型別,zk
客戶端型別在dubbo-2.1.1
及以後的版本只能選curator
,在dubbo-2.7.0
及以前的版本應該有兩種,這也是我們為什麼要引入curator-recipes
客戶端的原因。
如果你這裡設定的是zkclient
,啟動的時候是會報錯的:
下面是完整配置:
@SpringBootApplication
@DubboComponentScan(value = "io.github.syske.demo.service.facade")
public class DemoProviderApplication {
public static void main(String[] args) {
SpringApplication.run(DemoProviderApplication.class, args);
}
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("dubbo-server");
return applicationConfig;
}
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress("zookeeper://127.0.0.1:2181");
registryConfig.setClient("curator");
return registryConfig;
}
}
編寫服務實現
服務實現就比較簡單了,只需要繼承facade
介面,然後實現對應方法即可,需要注意的是,我們需要在介面實現加上@DubboService
和@Service
註解,這兩個註解一個是把介面服務註冊成rpc
介面,一個是把介面例項註冊成spring bean
。
方法內部,我還列印介面呼叫時的資訊,方便我們後面檢視。
@Service
@DubboService
public class DemoServiceImpl implements DemoService {
@Override
public String sayHello(String name) {
System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] Hello " + name +
", request from consumer: " + RpcContext.getContext().getRemoteAddress());
return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress();
}
}
其實這裡的@Service
和@DubboService
就等同於下面的xml
<bean id="demoService" class="io.github.syske.demo.service.facade.DemoServiceImpl"/>
<dubbo:service interface="io.github.syske.common.facade.DemoService" ref="demoService"/>
測試
完成以上工作,我們的服務提供者就配置完成了,這時候只需要先啟動zk
元件,然後再執行我們的服務提供者即可,正常情況下,服務啟動成功後,會在zk
中查到:
服務消費者
完成服務提供者之後,服務消費者就相對簡單了。
專案依賴
專案依賴和服務提供者一樣,沒有任何區別
<dependency>
<groupId>io.github.syske</groupId>
<artifactId>common-facade</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>3.3.0</version>
</dependency>
專案配置
專案配置也是一致的
@SpringBootApplication
@DubboComponentScan
public class DemoConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(DemoConsumerApplication.class, args);
}
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("dubbo-server");
return applicationConfig;
}
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress("zookeeper://127.0.0.1:2181");
registryConfig.setClient("curator");
return registryConfig;
}
}
服務消費者
消費這裡也比較簡單,只需要通過@DubboReference
引入facade
介面即可,然後在需要的地方呼叫即可
@RestController
@RequestMapping("/dubbo")
public class DemoController {
@DubboReference
private DemoService demoService;
@RequestMapping("/test")
public Object demo() {
String hello = demoService.sayHello("world");
System.out.println(hello);
return hello;
}
}
消費者@RequestMapping
註解等同於下面的配置
<dubbo:reference id="demoService" check="true" interface="io.github.syske.common.facade.DemoService.DemoService"/>
測試
完成相關配置後,啟動服務消費者,然後去zk
看下注冊資訊:
測試
下面我們直接訪問消費者的介面/dubbo/test
看下:
消費者控制檯:
服務提供者控制檯:
可以看到服務已經訪問成功了,資料也成功返回了。
踩坑
如果你在本地啟動過程中,有如下報錯,請檢查本地zookeeper
依賴版本,根據提示資訊,zookeeper
的版本必須大於3.3.3
。預設情況下,curator-recipes
是會為我們引入zk
的,所以我們一般不需要引用。
總結
今天我們主要分享了spring-boot
整合dubbo
的整個過程,過程中踩了好多坑,但是還好問題都解決了,由於過程斷斷續續搞了一天,所以好多報錯都沒來得及記錄,不過你如果參照我們今天的整合過程的話,應該是沒有問題的。好了,今天內容就到這裡吧!