个人博客地址 https://studyidea.cn/dubbo-telnet-invoke , 点击查看更多原创文章
0x00. 前言
想象这样一个场景, 线上某个服务突发异常, 导致上游服务调用异常, 数据处于中间状态. 服务恢复之后, 我们需要修复这笔数据至正常状态, 怎么办?
如果仅是简单的服务, 涉及少量数据变更, 我们可以直接使用 SQL, 变更数据状态. 但是有些情况下, 服务需要联动调用其他系统, 变更其他系统数据. 这种情况下, 变更数据非常麻烦, 需要与其他系统开发沟通, 整理数据, 一起变更. 如果涉及还涉及外部系统, 数据变更几乎玩不下去了.
如果服务接口能重试, 重新调用, 那么数据变更就交给服务自动去调用即可. 这个过程我们需要组装参数, 然后调用服务接口. 如果你的服务采用 Http 接口, 可以使用 Curl 等命令重试. 如果你的服务使用 Dubbo , 这就需要使用到 Telnet 命令.
0x01. telnet 进入 Dubbo 调试
通过以下指令, 连接 Dubbo 服务.
- telnet IP PORT
- # 例如:
- telnet localhost 20880
Dubbo 版本需要大于 2.0.5, 远程调用需要注意网络是否可用
连上之后, 按下回车键将会进入以下页面:
这个界面与 Shell 类似, 需要我们输入相关命令. 例如:
命令参考手册:.
0x02. invoke 执行 Dubbo 方法
这里我们重点介绍 invoke 命令, 该命令可以用来执行 Dubbo 服务, 调用方式如下:
- # 需要提前调用 cd XxxService, 使这个服务成为缺省服务
- invoke xxxMethod(1234, "abcd", {
- "prop" : "value"
- })
- # 调用该服务的方法
- invoke XxxService.xxxMethod(1234, "abcd", {
- "prop" : "value"
- })
- # 调用全路径服务的方法, 推荐使用这种方式, 精确执行服务方法.
- invoke com.xxx.XxxService.xxxMethod(1234, "abcd", {
- "prop" : "value"
- })
运行结果如下:
槽点: Mac 平台 iTerm2 使用 telnet 命令进入 Dubbo 调试, 中文输入将会乱码, 使用 SecureCRT telnet 就不会乱码. 感觉是 Mac 平台终端问题, 不知道各位小伙伴有没有碰到过? 有解决办法的小伙伴, 欢迎留个言.
注意点
Invoke 命令内部使用 FastJson, 将字符串转化为 JSON 对象.
tips: 如果参数为 数组, List,Map, 小黑哥有时候想不到怎么转成 JSON 字符串. 现在知道底层原理了, 就好办了.
可以先将数组, List,Map 对象参数组装好, 然后调用 FastJson JSONObject.toJSONString(array) 得到 JSON 字符串.
不同版本解码方式不一样
2.5.3 解码方式:
list = (List) JSON.parse("[" + args + "]", List.class);
2.7.0 解码方式:
list = JSON.parseArray("[" + args + "]", Object.class);
某些 Dubbo 版本 POJO 参数对象需要在 JSON 字符串中需要指定 class, 明确参数类型, 例如:
- {
- "name": "11",
- "age": 12,
- "class":"xx.xx.Pojo"
- }
如果没有传入, 将会调用失败, 相关问题可以参见这个 Issue:https://github.com/apache/dubbo/issues/3105 https://github.com/apache/dubbo/issues/3105 . 所以如果方法参数为 POJO 对象, 最好在 JSON 中传入 class.
0x03. select 命令与意外之喜
Dubbo 最新版本, 如果服务存在多个相同参数的重载方法, 且没有使用 class 来明确参数类型, 提示用户使用新增的 select 命令来选择要调用的方法.
小黑哥在测试 select 命令的过程中发现了一个 Bug,select 执行未选中的方法. 如上, 我使用 select 1 希望执行 1. hello(HelloRequest), 但是实际上执行的是 2. hello(HelloRequestV2). 当输入 select 2 时, 执行结果如下:
这个 Bug 详情参考小黑哥提的这个 issue https://github.com/apache/dubbo/issues/5707 . 这个修复很简单, 小黑哥已提交 PR 修复该 Bug.
没想到, 写这篇文章过程中, 还能发现一个 Bug, 然后成为 Dubbo Committer, 哈哈哈哈.
0x04. 总结
使用 Dubbo Telnet 命令, 使用 invoke 命令, 可以调用 Dubbo 服务, 解决一些生产应急事件.
但是玩归玩, 闹归闹, 别把生产开玩笑.
随意使用 invoke 命令还是存在一定危险性, 只要知道方法类, 服务参数组装规则, 就可以远程执行方法, 所以生产系统建议按需申请 invoke 权限.
来源: https://www.cnblogs.com/goodAndyxublog/p/12262902.html