dubbo源码实践-Exchange 信息交换层例子
创始人
2024-05-07 05:18:07
0

1 Exchange 层概述

官方定义:

exchange 信息交换层:封装请求响应模式,同步转异步,以 Request, Response 为中心,扩展接口为 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer。

其中Exchanger是SPI扩展点,是该层的入口。其中客户端通过ExchangeClient.request发送请求,服务端通过ExchangeHandler的reply方法处理请求并返回结果。

为了理解上面官方的定义,下面将使用该层的类创建一个客户端和服务器端的应用。

2 实践例子

2.1 项目结构

由于是TCP框架,所以有服务端和客户端,两端的代码。

服务端代码:ExchangeServerTest 启动类,AlfServerExchangeHandler服务端的业务逻辑处理类(类似Netty的Handler作用)。

客户端代码:ExchangeClientTest 启动类,AlfClientExchangeHandler 客户端的业务逻辑处理类。

2.2 服务端代码

ExchangeServerTest类,使用Exchanger接口绑定(bind)端口8888,启动服务器。

注意URL中添加的codec属性,如果不添加程序会走telnet的实现,程序会报错。可以参考:可以参考AbstractEndpoint的getChannelCodec函数。

package org.example.dubbo.exchange;import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.remoting.RemotingException;
import org.apache.dubbo.remoting.exchange.ExchangeServer;
import org.apache.dubbo.remoting.exchange.Exchanger;
import org.apache.dubbo.remoting.exchange.support.header.HeaderExchanger;import java.io.IOException;/** 服务端代码 */
public class ExchangeServerTest {public static void main(String[] args) throws RemotingException, IOException {//构建URL, dubbo中靠URL来传递参数URLBuilder urlBuilder = new URLBuilder();urlBuilder.setHost("localhost");urlBuilder.setPort(8888);//指定超时事件, 调试时防止超时urlBuilder.addParameter("codec", "exchange");URL url = urlBuilder.build();//Exchanger层入口类,可以通过SPI方式获取实现,这里为了简单直接new了HeaderExchangerExchanger exchanger = new HeaderExchanger();//服务端调用bind方法ExchangeServer exchangeServer = exchanger.bind(url, new AlfServerExchangeHandler());System.out.println("服务器启动完成");//等待,防止程序提前结束System.in.read();}
}

AlfServerExchangeHandler类,主要关注reply方法,该方法处理客户端发来的请求,然后通过CompletableFuture异步返回给客户端。还记得官方说的“同步转异步”吗?这里是一个体现。

package org.example.dubbo.exchange;import org.apache.dubbo.remoting.Channel;
import org.apache.dubbo.remoting.RemotingException;
import org.apache.dubbo.remoting.exchange.ExchangeChannel;
import org.apache.dubbo.remoting.exchange.ExchangeHandler;import java.util.concurrent.CompletableFuture;/** 服务端业务处理 */
public class AlfServerExchangeHandler implements ExchangeHandler {@Overridepublic CompletableFuture reply(ExchangeChannel channel, Object request) throws RemotingException {System.out.println("reply AAA, request=" + request);CompletableFuture stringCompletableFuture = CompletableFuture.supplyAsync(() -> "服务器8888为你服务");return stringCompletableFuture;}@Overridepublic void connected(Channel channel) throws RemotingException {System.out.println("connected AAA");}@Overridepublic void disconnected(Channel channel) throws RemotingException {System.out.println("disconnected AAA");}@Overridepublic void sent(Channel channel, Object message) throws RemotingException {System.out.println("sent AAA, message =" + message);}@Overridepublic void received(Channel channel, Object message) throws RemotingException {System.out.println("received AAA");}@Overridepublic void caught(Channel channel, Throwable exception) throws RemotingException {System.out.println("caught AAA");exception.printStackTrace();}@Overridepublic String telnet(Channel channel, String message) throws RemotingException {System.out.println("telnet AAA, message = " + message);return null;}
}

2.3 客户端代码

ExchangeClientTest客户端代码入口,使用Exchanger接口连接(connect)函数来连接本机的8888端口。

注意一下CompletableFuture completableFuture = exchangeClient.request("你是谁?", null); 这句代码,通过是哦也能够CompletableFuture,把获取相应结果异步了。

package org.example.dubbo.exchange;import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;import org.apache.dubbo.remoting.RemotingException;
import org.apache.dubbo.remoting.exchange.*;
import org.apache.dubbo.remoting.exchange.support.header.HeaderExchanger;import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;/** 客户端*/
public class ExchangeClientTest {public static void main(String[] args) throws RemotingException, IOException, ExecutionException, InterruptedException {//构建URL, dubbo中靠URL来传递参数URLBuilder urlBuilder = new URLBuilder();urlBuilder.setHost("localhost");urlBuilder.setPort(8888);//指定超时事件, 调试时防止超时urlBuilder.addParameter("timeout", 1000 * 200);//指定编码器,可以参考AbstractEndpoint的getChannelCodec函数urlBuilder.addParameter("codec", "exchange");URL url = urlBuilder.build();//Exchanger层入口类,可以通过SPI方式获取实现,这里为了简单直接new了HeaderExchangerExchanger exchanger = new HeaderExchanger();//客户端调用connect方法连接服务端ExchangeClient exchangeClient = exchanger.connect(url, new AlfClientExchangeHandler());//发送消息CompletableFuture completableFuture = exchangeClient.request("你是谁?", null);System.out.println("客户端发送消息----------");Object o = completableFuture.get();System.out.println("客户端接收到消息----------" + o);//等待,防止程序提前结束System.in.read();}
}

AlfClientExchangeHandler类,业务处理器。主要是展示一下发送消息和获取响应时被掉用的方法。

package org.example.dubbo.exchange;import org.apache.dubbo.remoting.Channel;
import org.apache.dubbo.remoting.RemotingException;
import org.apache.dubbo.remoting.exchange.ExchangeChannel;
import org.apache.dubbo.remoting.exchange.ExchangeHandler;import java.util.concurrent.CompletableFuture;/** 客户端处理器*/
public class AlfClientExchangeHandler implements ExchangeHandler {@Overridepublic CompletableFuture reply(ExchangeChannel channel, Object request) throws RemotingException {//本例中是客户端发送的请求,所以该方法不会被调用的System.out.println("reply BBB, request=" + request);CompletableFuture stringCompletableFuture = CompletableFuture.supplyAsync(() -> "客户端返回数据");return stringCompletableFuture;}@Overridepublic void connected(Channel channel) throws RemotingException {System.out.println("connected BBB");}@Overridepublic void disconnected(Channel channel) throws RemotingException {System.out.println("disconnected BBB");}@Overridepublic void sent(Channel channel, Object message) throws RemotingException {System.out.println("sent BBB, message =" + message);}@Overridepublic void received(Channel channel, Object message) throws RemotingException {System.out.println("received BBB");}@Overridepublic void caught(Channel channel, Throwable exception) throws RemotingException {System.out.println("caught BBB");}@Overridepublic String telnet(Channel channel, String message) throws RemotingException {System.out.println("telnet BBB, message = " + message);return null;}
}

2.4 运行结果

启动服务端,再启动客户端,然后查看日志。

2.4.1服务端日志

1处:服务器启动成功。

2处:AlfServerExchangeHandler中的connected方法别回调了,表明有客户端连接了服务器。

3 处:AlfServerExchangeHandler中的reply方法别回调了,表明服务器收到了客户端发送的Request请求,并在这个方法中进行逻辑处理。

4 处:AlfServerExchangeHandler中的sent方法别回调了,表明服务器发送了一个消息(这里的消息其实是我们收到request处理完毕后的返回结果Response对象)。

2.4.2 客户端日志

1 处:AlfClientExchangeHandler中的connected方法被回调了,表明客户端连接服务器成功了。

2 处:代码中打印的输出System.out.println("客户端发送消息----------")

3 处:AlfClientExchangeHandler中的sent方法被回调了,表明客户端发送了一个请求(Request对象)。

4 处:通过CompletableFuture对象获取服务器的返回内容(这里是字符串)

3 总结

看完上面的代码例子,应该能理解“exchange 信息交换层:封装请求响应模式,同步转异步。”的含义了吧。😁

顺便提一下,看到图中的request方法和reply方法了吗?Protocol层会调用,其实就是我们例子中调用的发送Request和响应Response的两个方法。

相关内容

热门资讯

安卓系统短消息提醒,安卓系统短... 你有没有发现,手机里的短消息提醒功能有时候就像一个贴心的管家,有时候又像个爱闹腾的小孩子?今天,咱们...
安卓系统如何跳过密码,安卓系统... 你是不是也和我一样,有时候手机锁屏密码设置得太复杂,每次解锁都要费好大一番力气?别急,今天就来教你怎...
鸿蒙系统功能与安卓,功能对比与... 你知道吗?最近手机圈里可是热闹非凡呢!华为的新操作系统鸿蒙系统(HarmonyOS)一经推出,就引发...
安卓系统卡苹果系统不卡,揭秘两... 你有没有发现,身边的朋友都在争论安卓系统和苹果系统哪个更好?其实,这个问题就像是在问谁家的孩子更聪明...
安卓系统卡解决了吗,安卓系统卡... 你有没有遇到过安卓手机卡顿的问题?是不是每次打开应用都感觉像蜗牛爬行?别急,今天就来聊聊这个让人头疼...
华为安卓系统下载软件,畅享海量... 你有没有想过,手机里的系统就像是我们的大脑,而下载的软件就像是大脑里的各种功能?今天,就让我带你一起...
平板安卓7系统好吗,体验流畅与... 你有没有想过,你的平板电脑的安卓7系统到底怎么样呢?是不是觉得它既熟悉又有点陌生?别急,今天咱们就来...
鸿蒙系统和安卓10,跨时代操作... 你知道吗?最近科技圈可是炸开了锅,因为华为的新操作系统鸿蒙系统横空出世,而且它竟然和安卓10杠上了!...
苹果安卓和鸿蒙系统,三大操作系... 你有没有发现,现在的手机市场就像是一场精彩纷呈的武林大会,各路英雄齐聚一堂,各显神通?没错,说的就是...
鸿蒙怎么还原安卓系统,系统还原... 你是不是也和我一样,对鸿蒙系统里的安卓应用情有独钟呢?最近,不少小伙伴都在问,鸿蒙怎么还原安卓系统?...
荣耀10改回安卓系统,重拾纯净... 你有没有想过,你的荣耀10手机,曾经那般风光无限,如今却想要改回安卓系统呢?这可不是一件小事,得好好...
华为安卓系统设置权限,深度解析... 亲爱的手机控们,你是否曾为手机里那些层出不穷的权限请求而头疼?别急,今天就来给你详细解析一下华为安卓...
安卓刷系统的软件,探索系统升级... 你有没有遇到过手机卡顿、系统老化的问题?别急,今天就来给你安利几款超好用的安卓刷系统软件,让你的手机...
安卓系统投影怎么升级,轻松实现... 你有没有发现,你的安卓系统投影最近有点儿慢吞吞的,是不是也想给它来个升级,让它焕发新生呢?别急,今天...
安卓手机系统怎样加速,享受流畅... 你有没有发现,你的安卓手机最近变得有点“慢吞吞”的?别急,别急,今天就来给你支几招,让你的安卓手机瞬...
安卓系统怎么安装的,安卓系统安... 你有没有想过,你的安卓手机里那些神奇的APP是怎么来的呢?是不是觉得安装个APP就像变魔术一样简单?...
安卓系统下儿童编程,开启编程启... 你有没有想过,在这个科技飞速发展的时代,连小朋友也开始学习编程了呢?没错,就是那个在安卓系统下,孩子...
微信安卓系统转苹果系统,轻松实... 你有没有想过,从微信安卓系统转到苹果系统,这中间的转换过程,就像是一场说走就走的旅行,充满了未知和惊...
如何刷安卓8.0系统,安卓8.... 你有没有想过,让你的安卓手机升级到最新的8.0系统,让它焕发出全新的活力呢?别急,今天我就来给你详细...
安卓系统里查看路由,安卓系统下... 你是不是也和我一样,对家里的无线网络充满了好奇?想知道安卓手机里怎么查看路由器信息?那就跟着我一起探...