【詳解】后端研發(fā)常用的服務(wù)端之間通信的五種方式
五種方式總結(jié)
HTTP/HTTPS | 基于網(wǎng)絡(luò)請(qǐng)求,調(diào)用方直接與服務(wù)端通信。 | RESTful API、跨平臺(tái)調(diào)用 |
RPC【使用多】 | 基于二進(jìn)制協(xié)議,調(diào)用方通過(guò)框架(如 Dubbo、gRPC)與服務(wù)端通信。 | 微服務(wù)架構(gòu) |
SDK(Maven)【使用多】 | 提供封裝好的庫(kù),調(diào)用方通過(guò)依賴管理工具引入并直接調(diào)用。 | 第三方服務(wù)集成、工具類(lèi)封裝 |
WebSocket | 全雙工通信,適合實(shí)時(shí)性要求高的場(chǎng)景。 | 實(shí)時(shí)通信(如聊天、推送) |
MQ【使用多】 | 基于異步通信,適合解耦和高并發(fā)場(chǎng)景。 | 分布式系統(tǒng)、異步任務(wù)處理 |
下面依次介紹常用的三種方式:SDK(maven)、RPC(Dubbo)、MQ(RocketMQ)。
一、以 Maven 包形式提供給對(duì)方的方式
概述
以 Maven 包的形式提供給對(duì)方是一種常見(jiàn)的 SDK 接入方式。這種方式將功能封裝成一個(gè)可復(fù)用的庫(kù)(Library),并通過(guò) Maven 等依賴管理工具分發(fā)給調(diào)用方。調(diào)用方只需在項(xiàng)目中引入該包即可使用其中的功能。
特點(diǎn)
- 封裝性好: 調(diào)用方無(wú)需關(guān)心底層實(shí)現(xiàn)細(xì)節(jié),只需調(diào)用提供的 API。
- 易于分發(fā): 通過(guò) Maven 中央倉(cāng)庫(kù)或私有倉(cāng)庫(kù)發(fā)布,方便調(diào)用方引入。
- 版本管理: 支持語(yǔ)義化版本控制(如 1.0.0、1.1.0),便于升級(jí)和維護(hù)。
- 開(kāi)發(fā)效率高: 調(diào)用方只需引入依賴即可使用,減少了重復(fù)開(kāi)發(fā)的工作量。
適用場(chǎng)景
- 需要為第三方開(kāi)發(fā)者提供一組功能接口。
- 希望簡(jiǎn)化調(diào)用方的集成過(guò)程。
- 功能相對(duì)獨(dú)立且通用,適合封裝成庫(kù)。
優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 封裝性好:調(diào)用方無(wú)需關(guān)心底層實(shí)現(xiàn)細(xì)節(jié)。
- 易于分發(fā):通過(guò) Maven 中央倉(cāng)庫(kù)或私有倉(cāng)庫(kù)發(fā)布。
- 版本管理:支持語(yǔ)義化版本控制。
- 開(kāi)發(fā)效率高:減少重復(fù)開(kāi)發(fā)工作量。
缺點(diǎn)
- 耦合性:調(diào)用方需要依賴提供方的包,可能會(huì)受到版本更新的影響。
- 安全性:如果 SDK 包含敏感邏輯或數(shù)據(jù),可能存在泄露風(fēng)險(xiǎn)。
- 靈活性不足:調(diào)用方無(wú)法輕易修改 SDK 的內(nèi)部實(shí)現(xiàn)。
實(shí)現(xiàn)步驟
1. 提供方:創(chuàng)建 Maven 項(xiàng)目并打包
1.1 創(chuàng)建 Maven 項(xiàng)目
- 使用 IDE(如 IntelliJ IDEA)創(chuàng)建一個(gè) Maven 項(xiàng)目。
- 編寫(xiě)核心功能代碼。
1.2 配置 pom.xml
在 pom.xml
中定義項(xiàng)目的元信息(如 groupId
、artifactId
、version
)。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>example-sdk</artifactId> <version>1.0.0</version> <packaging>jar</packaging> </project>
1.3 打包
使用 Maven 打包工具生成 JAR 文件:
mvn clean package
1.4 發(fā)布到 Maven 倉(cāng)庫(kù)
- 中央倉(cāng)庫(kù):遵循 Maven Central Repository 的發(fā)布流程。
- 私有倉(cāng)庫(kù):上傳到公司內(nèi)部的 Nexus 或 Artifactory 私有倉(cāng)庫(kù)。
2. 調(diào)用方:引入 Maven 依賴
2.1 在 pom.xml
中引入依賴
調(diào)用方在自己的項(xiàng)目中通過(guò) pom.xml
引入該依賴:
<dependency> <groupId>com.example</groupId> <artifactId>example-sdk</artifactId> <version>1.0.0</version> </dependency>
2.2 配置私有倉(cāng)庫(kù)(如果需要)
如果是私有倉(cāng)庫(kù),還需要配置倉(cāng)庫(kù)地址:
<repositories> <repository> <id>private-repo</id> <url>https://repo.example.com/repository/maven-releases/</url> </repository> </repositories>
3. 調(diào)用方:使用 SDK 功能
調(diào)用方可以直接使用 SDK 提供的類(lèi)和方法。例如:
import com.example.sdk.ExampleService; public class Main { public static void main(String[] args) { ExampleService service = new ExampleService(); String result = service.doSomething("input"); System.out.println(result); } }
分類(lèi)
根據(jù) SDK 的實(shí)現(xiàn)內(nèi)容,可以進(jìn)一步細(xì)分為以下幾種:
- 功能型 SDK:提供一組功能接口,調(diào)用方可以直接調(diào)用這些接口完成特定任務(wù)。示例:支付 SDK(如支付寶、微信支付)、云服務(wù) SDK(如阿里云、AWS)。
- 協(xié)議型 SDK:封裝了與外部系統(tǒng)的通信協(xié)議(如 HTTP 請(qǐng)求、RPC 調(diào)用)。調(diào)用方通過(guò) SDK 間接與外部系統(tǒng)交互,而無(wú)需關(guān)心底層通信細(xì)節(jié)。示例:Dubbo 客戶端 SDK、gRPC 客戶端 SDK。
- 工具型 SDK:提供一組工具類(lèi)或工具方法,幫助調(diào)用方完成某些通用任務(wù)。示例:日志工具、加密工具、文件處理工具。
總結(jié)
以 Maven 包的形式提供給對(duì)方屬于 SDK 方式,是一種常見(jiàn)的接入方式。它通過(guò)封裝功能為庫(kù)的形式,簡(jiǎn)化了調(diào)用方的集成過(guò)程,同時(shí)提供了良好的版本管理和分發(fā)能力。
二、以 RPC 方式(如 Dubbo)提供給對(duì)方的方式
概述
Dubbo 是阿里巴巴開(kāi)源的一款高性能 Java RPC 框架,廣泛應(yīng)用于微服務(wù)架構(gòu)中。通過(guò) Dubbo 提供服務(wù)的方式,通常是基于服務(wù)注冊(cè)與發(fā)現(xiàn)的機(jī)制。調(diào)用方和提供方通過(guò) Dubbo 框架進(jìn)行遠(yuǎn)程服務(wù)調(diào)用,而無(wú)需關(guān)心底層通信細(xì)節(jié)。
特點(diǎn)
- 透明性: 調(diào)用方像調(diào)用本地方法一樣調(diào)用遠(yuǎn)程服務(wù),無(wú)需關(guān)心底層通信細(xì)節(jié)。
- 高性能: 使用高效的二進(jìn)制協(xié)議(默認(rèn)為 Dubbo 協(xié)議),支持高吞吐量的服務(wù)調(diào)用。
- 服務(wù)治理: 支持負(fù)載均衡、熔斷、限流等高級(jí)功能。
- 分布式支持: 適合微服務(wù)架構(gòu),能夠輕松實(shí)現(xiàn)服務(wù)間的解耦。
適用場(chǎng)景
- 微服務(wù)架構(gòu)中的服務(wù)間通信。
- 需要高性能、低延遲的服務(wù)調(diào)用。
- 分布式系統(tǒng)中需要服務(wù)注冊(cè)與發(fā)現(xiàn)的場(chǎng)景。
- 內(nèi)部系統(tǒng)之間的交互。
優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 透明調(diào)用:調(diào)用方像調(diào)用本地方法一樣調(diào)用遠(yuǎn)程服務(wù)。
- 高性能:使用高效的二進(jìn)制協(xié)議,減少網(wǎng)絡(luò)開(kāi)銷(xiāo)。
- 服務(wù)治理:支持負(fù)載均衡、熔斷、限流等功能。
- 分布式支持:適合微服務(wù)架構(gòu),能夠輕松實(shí)現(xiàn)服務(wù)間的解耦。
缺點(diǎn)
- 復(fù)雜性增加:需要引入服務(wù)注冊(cè)中心(如 ZooKeeper、Nacos)和 Dubbo 框架。
- 運(yùn)維成本:需要維護(hù)服務(wù)注冊(cè)中心和 Dubbo 框架。
- 學(xué)習(xí)曲線:需要熟悉 Dubbo 的使用。
實(shí)現(xiàn)步驟
1. 提供方:發(fā)布服務(wù)
1.1 引入 Dubbo 依賴
在 pom.xml
中引入 Dubbo 和注冊(cè)中心(如 Nacos 或 ZooKeeper)的 Maven 依賴。
<dependencies> <!-- Dubbo 核心依賴 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>3.2.0</version> </dependency> <!-- 注冊(cè)中心依賴(以 Nacos 為例) --> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>2.2.3</version> </dependency> </dependencies>
1.2 定義服務(wù)接口
定義一個(gè)服務(wù)接口,供調(diào)用方使用。
public interface HelloService { String sayHello(String name); }
1.3 實(shí)現(xiàn)服務(wù)接口
提供方實(shí)現(xiàn)服務(wù)接口,并將其發(fā)布為 Dubbo 服務(wù)。
import org.apache.dubbo.config.annotation.DubboService; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; @DubboService(version = "1.0.0") public class HelloServiceImpl implements HelloService { @Override public String sayHello(String name) { return "Hello, " + name; } }
1.4 配置 Dubbo
在 application.properties
或 application.yml
中配置 Dubbo 和注冊(cè)中心。
# Dubbo 配置 dubbo.application.name=dubbo-provider dubbo.protocol.name=dubbo dubbo.protocol.port=20880 # 注冊(cè)中心配置(以 Nacos 為例) dubbo.registry.address=nacos://127.0.0.1:8848
1.5 啟動(dòng)服務(wù)
啟動(dòng) Spring Boot 應(yīng)用程序,服務(wù)將自動(dòng)注冊(cè)到注冊(cè)中心。
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableDubbo // 啟用 Dubbo public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); } }
2. 調(diào)用方:調(diào)用服務(wù)
2.1 引入 Dubbo 依賴
調(diào)用方同樣需要引入 Dubbo 和注冊(cè)中心的 Maven 依賴。
<dependencies> <!-- Dubbo 核心依賴 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>3.2.0</version> </dependency> <!-- 注冊(cè)中心依賴(以 Nacos 為例) --> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>2.2.3</version> </dependency> </dependencies>
2.2 引用遠(yuǎn)程服務(wù)
調(diào)用方通過(guò) Dubbo 框架獲取遠(yuǎn)程服務(wù)的代理對(duì)象,并調(diào)用其方法。
import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.stereotype.Component; @Component public class HelloServiceConsumer { @DubboReference(version = "1.0.0") private HelloService helloService; public void callRemoteService() { String result = helloService.sayHello("World"); System.out.println(result); } }
2.3 配置 Dubbo
在 application.properties
或 application.yml
中配置 Dubbo 和注冊(cè)中心。
# Dubbo 配置 dubbo.application.name=dubbo-consumer # 注冊(cè)中心配置(以 Nacos 為例) dubbo.registry.address=nacos://127.0.0.1:8848
2.4 啟動(dòng)調(diào)用方
啟動(dòng) Spring Boot 應(yīng)用程序,調(diào)用方將從注冊(cè)中心獲取服務(wù)并調(diào)用。
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ConsumerApplication implements CommandLineRunner { @Autowired private HelloServiceConsumer consumer; public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } @Override public void run(String... args) throws Exception { consumer.callRemoteService(); } }
3. 配置服務(wù)注冊(cè)中心
3.1 使用 Nacos 或 ZooKeeper
Dubbo 通常依賴服務(wù)注冊(cè)中心(如 Nacos 或 ZooKeeper)來(lái)實(shí)現(xiàn)服務(wù)注冊(cè)與發(fā)現(xiàn)。
- Nacos:輕量級(jí)服務(wù)注冊(cè)中心,功能更加強(qiáng)大。
- ZooKeeper:經(jīng)典的服務(wù)注冊(cè)中心,比較老了。
3.2 配置服務(wù)地址
在 application.properties
或代碼中配置服務(wù)注冊(cè)中心的地址。
# 配置 Nacos 地址 dubbo.registry.address=nacos://127.0.0.1:8848 # 或配置 ZooKeeper 地址 dubbo.registry.address=zookeeper://127.0.0.1:2181
總結(jié)
通過(guò) Dubbo 提供服務(wù)的方式屬于 RPC 接入方式,它本質(zhì)上是一種同步通信機(jī)制。這種方式適合微服務(wù)架構(gòu)中的服務(wù)間通信,同時(shí)提供了高性能和服務(wù)治理能力。
三、以 MQ 方式(如 RocketMQ)提供給對(duì)方的方式
概述
RocketMQ 是阿里巴巴開(kāi)源的一款分布式消息中間件,廣泛應(yīng)用于高并發(fā)、分布式系統(tǒng)中。通過(guò) RocketMQ 提供服務(wù)的方式,通常是基于消息隊(duì)列的異步通信機(jī)制。調(diào)用方和提供方通過(guò)消息隊(duì)列進(jìn)行解耦,實(shí)現(xiàn)高效、可靠的消息傳遞。
特點(diǎn)
- 異步通信: 調(diào)用方和提供方之間通過(guò)消息隊(duì)列進(jìn)行解耦。適合高并發(fā)、分布式系統(tǒng)的場(chǎng)景。
- 高性能: RocketMQ 提供了高效的二進(jìn)制協(xié)議,支持高吞吐量的消息傳遞。
- 可靠性: 支持消息持久化、重試機(jī)制,確保消息不會(huì)丟失。
- 靈活性: 支持多種消息模式(如點(diǎn)對(duì)點(diǎn)、發(fā)布/訂閱)。
適用場(chǎng)景
- 需要實(shí)現(xiàn)異步通信的系統(tǒng)。
- 高并發(fā)、分布式架構(gòu)中的服務(wù)解耦。
- 數(shù)據(jù)流處理(如日志收集、事件驅(qū)動(dòng)架構(gòu))。
- 不需要實(shí)時(shí)響應(yīng)的場(chǎng)景。
優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 異步解耦:調(diào)用方和提供方無(wú)需直接交互,降低了耦合度。
- 高并發(fā)支持:RocketMQ 能夠處理大量消息,適合高并發(fā)場(chǎng)景。
- 可靠性高:支持消息持久化、重試機(jī)制,確保消息不丟失。
- 靈活的消息模式:支持點(diǎn)對(duì)點(diǎn)、發(fā)布/訂閱等多種模式。
缺點(diǎn)
- 延遲較高:由于是異步通信,不適合實(shí)時(shí)性要求高的場(chǎng)景。
- 復(fù)雜性增加:需要引入消息隊(duì)列組件,增加了系統(tǒng)復(fù)雜性。
- 運(yùn)維成本:需要維護(hù) RocketMQ 集群。
實(shí)現(xiàn)步驟
1. 提供方:生產(chǎn)消息
1.1 引入 RocketMQ 依賴
在 pom.xml
中引入 RocketMQ 的 Maven 依賴:
<dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>4.9.3</version> </dependency>
1.2 編寫(xiě)生產(chǎn)者代碼
提供方通過(guò) RocketMQ 生產(chǎn)消息,并將消息發(fā)送到指定的 Topic。
import org.apache.rocketmq.client.producer.DefaultMQProducer; import org.apache.rocketmq.common.message.Message; public class RocketMQProducer { public static void main(String[] args) throws Exception { // 創(chuàng)建生產(chǎn)者實(shí)例 DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName"); producer.setNamesrvAddr("localhost:9876"); // 設(shè)置 NameServer 地址 producer.start(); // 創(chuàng)建消息 Message message = new Message("TopicTest", "TagA", "Hello RocketMQ".getBytes()); // 發(fā)送消息 producer.send(message); // 關(guān)閉生產(chǎn)者 producer.shutdown(); } }
2. 調(diào)用方:消費(fèi)消息
2.1 編寫(xiě)消費(fèi)者代碼
調(diào)用方通過(guò) RocketMQ 消費(fèi)消息,并根據(jù)業(yè)務(wù)邏輯處理消息內(nèi)容。
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; import org.apache.rocketmq.common.message.MessageExt; import java.util.List; public class RocketMQConsumer { public static void main(String[] args) throws Exception { // 創(chuàng)建消費(fèi)者實(shí)例 DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName"); consumer.setNamesrvAddr("localhost:9876"); // 設(shè)置 NameServer 地址 // 訂閱 Topic consumer.subscribe("TopicTest", "*"); // 注冊(cè)消息監(jiān)聽(tīng)器 consumer.registerMessageListener(new MessageListenerConcurrently() { @Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) { for (MessageExt msg : msgs) { System.out.printf("Receive Message: %s%n", new String(msg.getBody())); } return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; // 返回消費(fèi)成功狀態(tài) } }); // 啟動(dòng)消費(fèi)者 consumer.start(); System.out.println("Consumer Started."); } }
3. 配置 RocketMQ 環(huán)境
3.1 安裝 RocketMQ
- 下載 RocketMQ 并解壓。
- 啟動(dòng) NameServer 和 Broker:
3.2 驗(yàn)證 RocketMQ
- 使用 RocketMQ 自帶的工具驗(yàn)證是否正常運(yùn)行:
4. 消息模式
4.1 點(diǎn)對(duì)點(diǎn)模式
- 每條消息只能被一個(gè)消費(fèi)者消費(fèi)。
- 適用于任務(wù)分配、訂單處理等場(chǎng)景。
4.2 發(fā)布/訂閱模式
- 每條消息可以被多個(gè)消費(fèi)者消費(fèi)。
- 適用于廣播通知、日志收集等場(chǎng)景。
總結(jié)
通過(guò) RocketMQ 提供服務(wù)的方式屬于 消息隊(duì)列接入方式,它本質(zhì)上是一種異步通信機(jī)制。這種方式適合高并發(fā)、分布式系統(tǒng)中的服務(wù)解耦,同時(shí)提供了高可靠性和靈活性。
關(guān)注【碼間煙火錄】,獲取更多技術(shù)干貨呀!??
#Java##后端#