一、Telnet 命令参考手册
Dubbo 服务发布之后,我们可以利用telnet命令进行调试、管理。
Dubbo 2.0.5 以上版本服务提供端口支持 telnet 命令,使用方式:telnet localhost 20880
ls 命令ls:显示服务列表
ls -l:显示服务详细信息列表
ls XxxService:显示服务的方法列表
ls -l XxxService:显示服务的方法详细信息列表
ps 命令ps:显示服务端口列表
ps -l:显示服务地址列表
ps 20880:显示端口上的连接信息
ps -l 20880:显示端口上的连接详细信息
cd 命令 (change default service)cd XxxService:改变缺省服务,当设置了缺省服务,凡是需要输入服务名作为参数的命令,都可以省略服务参数。
cd /:取消缺省服务。
pwd 命令 (print working default service)pwd:显示当前缺省服务。
trace 命令trace XxxService:跟踪 1 次服务任意方法的调用情况
trace XxxService 10:跟踪 10 次服务任意方法的调用情况
trace XxxService xxxMethod:跟踪 1 次服务方法的调用情况
trace XxxService xxxMethod 10:跟踪 10 次服务方法的调用情况
count 命令count XxxService:统计1次服务任意方法的调用情况。
count XxxService 10:统计10次服务任意方法的调用情况。
count XxxService xxxMethod:统计1次服务方法的调用情况。
count XxxService xxxMethod 10:统计10次服务方法的调用情况。
invoke 命令invoke XxxService.xxxMethod({"prop": "value"}):调用服务的方法。
invoke xxxMethod({"prop": "value"}):调用服务的方法(自动查找包含此方法的服务)。
invoke XxxService.xxxMethod(["xxx","xxx"]):调用list,array参数方法
invoke ArtisanService.queryArtisans({"class":"com.xxx.user.api.model.ArtisanQuery", "status": "1", "type": "1", "city": "5306", "offset": 0, "rows": 3}):调用对象
比如StudentService.save这种方法。则需要将入参转换成json串,然后在json串中补上“class”一项,用于InvokeTelnetHandler类进行转换。
status 命令status:显示汇总状态,该状态将汇总所有资源的状态,当全部OK时则显示OK,只要有一个ERROR则显示ERROR,只要有一个WARN则显示WARN。
status -l:显示状态列表。
log 命令
2.0.6以上版本支持log debug:修改dubbo logger的日志级别
log 100:查看file logger的最后100字符的日志
help 命令help:显示telnet命帮助信息。
help xxx:显示xxx命令的详细帮助信息。
clear 命令clear:清除屏幕上的内容。
clear 100:清除屏幕上的指定行数的内容。
exit 命令
exit:退出当前telnet命令行。
二、利用python3调用dubbo服务接口
1、telnet 查看 dubbo 服务dubbo>ls -l ArtisanService
com.xxx.user.api.model.ArtisanModel getArtisanById(java.lang.String)
java.util.List getArtisansByIds(java.util.List)
java.util.List queryArtisans(com.xxx.user.api.model.ArtisanQuery)
接下来使用python方式分别调用上面的三个方法
2、python 调用 dubbo 服务# -*- coding: utf-8 -*-
import json
import telnetlib
class Dubbo(telnetlib.Telnet):
prompt = 'dubbo>'
coding = 'utf-8'
def __init__(self, host=None, port=0):
super().__init__(host, port)
# 触发dubbo提示符
self.write(b'\n')
def command(self, flag, str_=""):
data = self.read_until(flag.encode())
self.write(str_.encode() + b"\n")
return data
def invoke(self, service_name, method_name, arg):
self.command(Dubbo.prompt, "invoke {0}.{1}({2})".format(service_name, method_name, json.dumps(arg)))
data = self.command(Dubbo.prompt, "")
data = data.decode(Dubbo.coding, errors='ignore').split('\n')[0].strip()
# 终止Telnet连接
self.close()
return data
def do(self, arg):
self.command(Dubbo.prompt, arg)
data = self.command(Dubbo.prompt, arg)
data = data.decode(Dubbo.coding, errors='ignore').split('\n')[0].strip()
# 终止Telnet连接
self.close()
return data
if __name__ == '__main__':
conn = Dubbo('172.0.0.1', 20880)
# 调用方式1:格式invoke 接口全名字.方法名(参数1,参数2,参数3...参数n)
# invoke_str = 'invoke com.xxx.user.api.service.ArtisanService.getArtisanById("7b988f3ba005466eba12f5852b15ad0e")'
# invoke_str = 'invoke ArtisanService.getArtisanById("7b988f3ba005466eba12f5852b15ad0e")'
invoke_str = 'invoke getArtisanById("7b988f3ba005466eba12f5852b15ad0e")'
result = conn.do(invoke_str)
# print(result)
# eval 把 str 转换 dict,indent 缩进空格数量,ensure_ascii 显示中文
print(json.dumps(eval(result), indent=4, ensure_ascii=False))
# 调用方式2:
# service_name = 'com.xxx.user.api.service.ArtisanService'
# service_name = 'ArtisanService'
# method_name = 'getArtisanById'
# arg = '7b988f3ba005466eba12f5852b15ad0e'
# result = conn.invoke(service_name, method_name, arg)
# 调用list参数
# invoke_str = 'invoke ArtisanService.getArtisansByIds(["7b988f3ba005466eba12f5852b15ad0e", "000e67027e9b44fa978800e8e7f7ea98"])'
# result = conn.do(invoke_str)
# 调用object对象
# param = {
# "class": "com.helijia.user.api.model.ArtisanQuery",
# "status": "1",
# "type": "1",
# "city": "5306",
# "offset": 0,
# "rows": 3
# }
# invoke_str = 'invoke ArtisanService.queryArtisans(' + str(param) + ')'
# invoke_str = 'invoke ArtisanService.queryArtisans({"class":"com.xxx.user.api.model.ArtisanQuery", "status": "1", "type": "1", "city": "5306", "offset": 0, "rows": 3})'
# print(invoke_str)
# result = conn.do(invoke_str)
说明
1、调用方式# 以下三种方式调用结果相同
invoke_str = 'invoke com.xxx.user.api.service.ArtisanService.getArtisanById("7b988f3ba005466eba12f5852b15ad0e")'
invoke_str = 'invoke ArtisanService.getArtisanById("7b988f3ba005466eba12f5852b15ad0e")'
invoke_str = 'invoke getArtisanById("7b988f3ba005466eba12f5852b15ad0e")'
2、json结果缩进# eval 把 str 转换 dict,indent 缩进空格数量,ensure_ascii 显示中文
print(json.dumps(eval(result), indent=4, ensure_ascii=False))
结果{
"artisanCode": "18aar10196",
"artisanGlory": 0,
"artisanId": "xxx",
"artisanLevel": 10,
"averagePrice": 170.0,
"bankCardno": "xxx",
"bankCity": "北京市",
"bankDeposit": "xx美甲",
"bankType": "95588",
"cardholder": "白鲸",
"certificationFlag": 0,
"checkBankStatus": 2,
"city": 2,
"commentCount": 0,
"constellation": "巨蟹座",
"createDate": xxx,
"dataIsNew": 0,
"description": "老娘的美甲,天下第一!无敌!",
"email": "sjsjjsjsjsh@163.com",
"fastEnterFlag": 2,
"favCount": 8,
"gender": 1,
...
}
3、请求参数是集合,数组invoke_str = 'invoke ArtisanService.getArtisansByIds(["7b988f3ba005466eba12f5852b15ad0e", "000e67027e9b44fa978800e8e7f7ea98"])'
4、请求参数是对象invoke_str = 'invoke ArtisanService.queryArtisans({"class":"com.xxx.user.api.model.ArtisanQuery", "status": "1", "type": "1", "city": "5306", "offset": 0, "rows": 3})'
# 等同于
param = {
"class": "com.xxx.user.api.model.ArtisanQuery",
"status": "1",
"type": "1",
"city": "5306",
"offset": 0,
"rows": 3
}
invoke_str = 'invoke ArtisanService.queryArtisans(' + str(param) + ')'
补充
有了telnet终端,为什么我们还需要python方式来调用呢?
优势1:终端不允许左右键盘控制指定输入某一个字符,会变成乱码符号,而python就像编辑文本文件一样方便
优势2:终端不支持输入中文参数,会变成乱码符号,如下代码,而python却可以。dubbo>invoke ArtisanService.queryArtisans({"class":"com.xxx.user.api.model.ArtisanQuery", "status": "1", "type": "1", "city": "5306", "offset": 0, "rows": 3, "nick": "QAi^G
e:^Fg>^Ng2"})Unsupported command: ��invoke
dubbo>
Unsupported command: e:g>g2"})
dubbo>
python方式param = {
"class": "com.xxx.user.api.model.ArtisanQuery",
"status": "1",
"type": "1",
"city": "5306",
"nick": "重庆美甲",
"offset": 0,
"rows": 3
}