大牛带你深入Dubbo-Telnet调用原理:指令解析原理+实现健康监测

Telnet调用原理

有了编解码器实现的基础,再理解Telnet处理就容易多了。

编解码器处理有三种场景:请求、响应和Telent调用。理解Telnet调用并不难,编解码器主要把Telnet当作明文字符串处理,按照Dubbo的调用规范,解析成调用命令格式,然后查找对应的Invoker,发起方法调用即可。

Telnet指令解析原理

为了支持未来更多的Telnet命令和扩展性,Telnet指令解析被设置成了扩展点TelnetHandler,每个Telnet指令都会实现这个扩展点。我们首先查看这个扩展点的定义,如代码清单6-9所示。

代码清单6-9 TelnetHandler定义

@SPI
public interface TelnetHandler {
String telnet(Channel channel. String message) throws RemotingException;
}

通过这个扩展点的定义,能够解决扩展更多命令的诉求。message包含处理命令之外的所有字符串参数,具体如何使用这些参数及这些参数的定义全部交给命令实现者决定。

完成Telnet指令转发的核心实现类是TelnetHandlerAdapter,它的实现非常简单,首先将用户输入的指令识别成commandC比如invoke>Is和status),然后将剩余的内容解析成message,message会交给命令实现者去处理。实现代码类在TelnetHandlerAdapter#telnet中,如代码清单6-10所示。
代码清单6-10 Telnet转发解析
^Override
public String telnet(Channel channel. String message) throws RemotingException {
String prompt = channel.getllrl().getParameterAndDecoded(Constants.PROMPT^EY,
Constants.DEFAULT_PROMPT);
boolean noprompt = message.contains("-- no-prompt");
message = message.replace("--no-prompt","");
StringBuilder buf = new StringBuilder();
message = message.trim();
String command;
if (message.length() > 0) (
int i = message.indexOf('');
if (i > 0) {
command = message.substring(0, i).trim(); ① 提取执行命令
message = message.substring(i + 1).trim();②提取命令后的所有字符串
} else {
command = message;
message ="
}
) else {
command ="
}
if (command.length() > 0) (
if (extensionLoader.hasExtension(command)) {  ③检查系统是否有命令对应的扩展点
try {
String result = extensionLoader.getExtension(command).telnet(channel^
message);<—④交给具体扩展点执行
if (result == null) {
return null;
)
buf.append(result);
} catch (Throwable t) (
buf append(t.getMessage());
}
} else (
buf.append("Unsupported command:");
buf.append(command);
}
}
if (buf.length() > 0) {
buf .appendC'XrXn"); <— ⑤ 在Telnet消息结尾追加回车和换行
}
if (prompt != null && prompt.length() > 0 && !noprompt) {
buf.append(prompt);
)
return buf.toString();
}

理解编解码后,可以更好地理解上层的实现和原理,在①中提取Telnet一行消息的首个字符串作为命令,如果命令行有空格,则将后面的内容作为字符串,再通过②提取并存储到message中。在③中判断并加载是否有对应的扩展点,如果存在对应的Telnet扩展点,则会通过④加载具体的扩展点并调用其telnet方法,最后连同返回结果并追加消息结束符(在⑤中处理)返回给调用方。

在讲解完Telnet调用转发后,我们对常用命令Invoke调用进行探讨,在InvokeTelnetHandler中本地实现Telnet类调用,如代码清单6-11所示。

当本地没有客户端,想测试服务端提供的方法时,可以使用Telnet登录到远程服务器(Telnet IP port),根据invoke指令执行方法调用来获得结果。当用户输入invoke指令时,会被转发到代码清单6-11对应的Handlero在①中提取方法调用信息(去除参数信息),在②中会提取调用括号内的信息作为参数值。在③中提取方法调用的接口信息,在④中提取接口调用的方法名称。在⑤中会将传递的JSON参数值转换成fastjson对象,然后在⑥中根据接口名称、方法和参数值查找对应的方法和Invoker对象。在真正方法调用前,需要通过⑦把fastjson对象转换成Java对象,在⑧中触发方法调用并返回结果值。

Telnet实现健康监测

Telnet提供了健康检查的命令,可以在Telnet连接成功后执行status -1查看线程池、内存和注册中心等状态信息。为了完成线程池监控、内存和注册中心监控等诉求,Telnet提供了新的扩展点Statuschecker,如代码清单6-12所示。

代码清单6・12健康检查扩展点

@SPI
public interface Statuschecker (
Status check();
)

当执行status命令时会触发StatusTelnetHandler#telnet调用,这个方法的实现也比较简单,它会加载所有实现Statuschecker扩展点的类,然后调用所有扩展点的check方法。因为这类扩展点的具体实现并不复杂,所以不会一一讲解,表6.4列出了健康监测对应的实现和作用。

  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值