dubbo官方文档中有提到:
从 2.0.5 版本开始,dubbo 开始支持通过 telnet 命令来进行服务治理。
也就是说我们可以通过telnet远程连接已经部署dubbo的服务器,执行shell命令, 可用来调用dubbo接口
import json
import random
import re
import telnetlib
import time
class TelnetClient(object):
"""通过telnet连接dubbo服务, 执行shell命令, 可用来调用dubbo接口
"""
def __init__(self):
self.tn = telnetlib.Telnet()
self.server_host = "127.0.0.1"
self.server_port = "20880"
self.user = "root"
self.password = "root"
# 此函数实现telnet登录主机
def connect_dubbo(self):
try:
print("telent连接dubbo服务端: telnet {} {} ……".format(self.server_host, self.port))
self.tn.open(self.server_host, port=self.port)
return True
except Exception as e:
print('连接失败, 原因是: {}'.format(str(e)))
return False
# 此函数实现执行传过来的命令,并输出其执行结果
def execute_some_command(self, command):
# 执行命令
cmd = (command + '\n').encode("gbk")
self.tn.write(cmd)
# 获取命令结果,字符串类型
retry_count = 0
# 如果响应未及时返回,则等待后重新读取,并记录重试次数
result = self.tn.read_very_eager().decode(encoding='gbk')
while result == '':
time.sleep(1)
result = self.tn.read_very_eager().decode(encoding='gbk')
retry_count += 1
return result
# 退出telnet
def logout_host(self):
self.tn.write(b"exit\n")
print("登出成功")
class InvokeDubboApi(object):
def __init__(self):
try:
self.telnet_client = TelnetClient()
self.login_flag = self.telnet_client.connect_dubbo()
except Exception as e:
print(str(e))
def get_all_dubbo_apis(self):
""" 获取指定服务的接口数量及接口明细
"""
dubbo_apis = []
try:
if self.login_flag:
services = self.telnet_client.execute_some_command("ls")
print(f'获取服务列表:{services}')
services = services.split("\r\n")
services.pop()
for service in services:
resp = self.telnet_client.execute_some_command("ls {}".format(service))
resp = resp.split("\r\n")
resp.pop()
for j in range(len(resp)):
resp[j] = service + '.' + resp[j]
dubbo_apis.append(resp[j])
new_dubbo_api_list = list(set(dubbo_apis))
print("rpc接口 数量是: {}".format( new_dubbo_api_list.__len__()))
return new_dubbo_api_list
except Exception as e:
raise ("获取dubbo接口失败,原因是{}".format(str(e)))
def invoke_dubbo_api(self, url, param, is_templated=True):
"""
@param api_name: 接口地址为类名 如com.xx.xx
@param param: 接口传参,json格式
@return: 接口调用返回,dict格式
"""
api_name = url + "({})"
cmd = "invoke " + api_name.format(param)
print("调用命令是:{}".format(cmd))
resp0 = None
resp_template = {'method': "invoke",
'request_time': random.randint(500, 3000),
'response_time': 100,
'elapsed': 100,
'url': url,
'request_headers': {
'User-Agent': 'python-requests/2.18.4',
'Accept-Encoding': 'gzip, deflate',
'Accept': '*/*',
'Connection': 'keep-alive',
'content-type': 'application/json',
'Content-Length': '648'},
'request_body': str(param),
'status_code': 200,
'response_headers': {"msg": "dubbo apis don't have response_headers"},
'response_body': {},
'content_size': random.randint(1, 100)
}
try:
if self.login_flag:
resp0 = self.telnet_client.execute_some_command(cmd)
# print("接口响应是: {}".format(resp0))
resp = resp0.split("\r\n")
resp_time = re.findall(r"\d+\.?\d*", resp[1])[0]
if ":" not in resp[0]:
resp[0] = '{"response\": ' + resp[0] + ''"}"''
resp = json.loads(resp[0])
resp_template['response_time'] = resp_time
print("接口响应时间是: {} 毫秒".format(resp_time))
resp_template['response_body'] = resp
if is_templated:
# print("接口响应是,resp={}".format(resp_template))
return resp_template
else:
print("接口响应是,resp={}".format(resp))
return resp
else:
print("登陆失败!")
except Exception as e:
raise Exception("调用接口异常, 接口响应是resp={}, 异常信息为:{}".format(resp0, str(e)))
def logout(self):
self.telnet_client.logout_host()
来源:CSDN
作者:zxc19854
链接:https://blog.csdn.net/zxc19854/article/details/104018479