RPC框架簡單入門之spring-boot整合dubbo

前言
現(xiàn)階段,web后端開發(fā)主流的接口協(xié)議類型主要有兩種,一種就是我們傳統(tǒng)的rest接口,另一種比較流行的就是rpc,今天我們就來簡單說下rpc接口,同時我們會通過一個簡單示例,來分享dubbo框架的基本用法。
rpc全稱Remote Procedure Call,中文的意思是遠程程序調(diào)用。簡單來說,rpc就是一種基于socket的調(diào)用方式,一種有別于rest的調(diào)用協(xié)議。其核心技術就是動態(tài)代理,關于rpc動態(tài)代理的實現(xiàn),我們前面其實有寫過一個簡易版的rpc接口,有興趣的小伙伴可以去看下:
下面是rpc的調(diào)用原理,這里放上百度百科的一張圖片,供大家參考:

好了,關于rpc的理論介紹,我們先說這么多,下面我們通過一個實例來分享下dubbo的簡答用法。
dubbo
我相信很多小伙伴經(jīng)常在實際開發(fā)過程中有用到rpc,但是對于rpc的相關知識,很多小伙伴肯定沒有系統(tǒng)學習過(當然也包括我),因為我們在實際工作中,大部分的時間都花在了業(yè)務實現(xiàn)方面,很少有機會能真正參與系統(tǒng)架構的搭建,所以很多時候這些知識就顯得不那么重要了。
但是考慮到未來個人職業(yè)發(fā)展,同時也為了讓我們在日常工作中更快地解決各類rpc的相關問題,掌握一些rpc的基礎知識就尤為重要了,所以從今天開始,我們開始系統(tǒng)地探討下rpc的相關知識,下面我們先從一個簡單的dubbo實例開始。
關于dubbo我想大家應該都比較熟悉了,就算實際工作沒有用到,在面試的過程中也一定聽過。dubbo是alibaba開源的一款rpc服務框架,被各大公司廣泛應用,現(xiàn)在也算是java開發(fā)必學的web開發(fā)框架之一,目前最新版本是3.0。想要了解更多信息,可以去官方網(wǎng)站看下:
https://dubbo.apache.org/zh/

創(chuàng)建項目
首先我們要創(chuàng)建一個maven項目,然后分別創(chuàng)建三個模塊:common-facade、service-provider和service-consumer 。其中service-provider和service-consumer是spring-boot項目,他們分別是服務提供者和服務消費者;common-facade是普通maven項目,它主要用來存放我們的facade接口,創(chuàng)建完成后,項目結構如下:

facade接口
項目創(chuàng)建完成后,我們先來編寫facade接口。它就是一個簡單的interface接口,不需要添加任何配置文件,也不需要引入第三方包,通常情況下我們會盡可能保證接口的簡潔性。
它就相當于一個接口規(guī)范,服務提供者通過實現(xiàn)它的接口提供服務,服務消費者通過它消費服務,所以在服務提供者和消費者的項目中都要引用common-facade的包,我們通常還會把接口的出入?yún)⒎旁谠摪隆τ谛枰{(diào)用我們服務的項目,直接引入我們的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);
}
服務提供者
服務提供者相對內(nèi)容比較多,它不僅要引入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典型應用場景的實現(xiàn)。
這里我專門去查了一下Netflix公司,竟然就是大名鼎鼎的奈飛公司,該公司核心業(yè)務就是視頻點播,如果你有留意之前我們分享的spring-cloud的相關內(nèi)容的話,你會在發(fā)現(xiàn)spring-cloud的好多組件就是出自這家公司,比如eureka、hystrix、ribbon、zuul,從這一點上來說,這家公司還是很優(yōu)秀的。
項目配置
首先我們需要通過@DubboComponentScan指定facade服務提供者的包名,用于服務注冊,缺少這個注解服務無法正常注冊,這里可以不指定包名,默認情況下應該會取當前類的包名;
這里我們還需要指定ApplicationConfig,也就是服務提供者配置信息,如果缺少這個配置,啟動的時候會報錯:

另外還有服務注冊配置RegistryConfig需要指定,這里主要指定的是zk的地址、zk客戶端類型,zk客戶端類型在dubbo-2.1.1及以后的版本只能選curator,在dubbo-2.7.0及以前的版本應該有兩種,這也是我們?yōu)槭裁匆?code style="overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 100, 65);">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;
}
}
編寫服務實現(xiàn)
服務實現(xiàn)就比較簡單了,只需要繼承facade接口,然后實現(xiàn)對應方法即可,需要注意的是,我們需要在接口實現(xiàn)加上@DubboService和@Service注解,這兩個注解一個是把接口服務注冊成rpc接口,一個是把接口實例注冊成spring bean。
方法內(nèi)部,我還打印接口調(diào)用時的信息,方便我們后面查看。
@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中查到:

服務消費者
完成服務提供者之后,服務消費者就相對簡單了。
項目依賴
項目依賴和服務提供者一樣,沒有任何區(qū)別
<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接口即可,然后在需要的地方調(diào)用即可
@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看下:

消費者控制臺:

服務提供者控制臺:

可以看到服務已經(jīng)訪問成功了,數(shù)據(jù)也成功返回了。
踩坑
如果你在本地啟動過程中,有如下報錯,請檢查本地zookeeper依賴版本,根據(jù)提示信息,zookeeper的版本必須大于3.3.3。默認情況下,curator-recipes是會為我們引入zk的,所以我們一般不需要引用。


總結
今天我們主要分享了spring-boot整合dubbo的整個過程,過程中踩了好多坑,但是還好問題都解決了,由于過程斷斷續(xù)續(xù)搞了一天,所以好多報錯都沒來得及記錄,不過你如果參照我們今天的整合過程的話,應該是沒有問題的。好了,今天內(nèi)容就到這里吧!
