python通过telnetlib请求dubbo接口(含枚举类,实体类请求格式)

dubbo官方文档中有提到:

从 2.0.5 版本开始,dubbo 开始支持通过 telnet 命令来进行服务治理。

也就是说我们可以通过telnet远程连接已经部署dubbo的服务器,执行shell命令, 可用来调用dubbo接口

代码中使用的server_host 一般是ip地址,像这种分布式的服务一般是通过docker部署,每次部署ip都会变化。这时可以通过zk的后台管理服务,将每次部署的ip动态获取出来,再调用以下的方法进行请求

import re
import telnetlib
import time
import requests


class TelnetClient(object):
    """通过telnet连接dubbo服务, 执行shell命令, 可用来调用dubbo接口
    """

    def __init__(self, server_host, server_post):
        self.tn = telnetlib.Telnet()
        self.server_host = server_host
        self.server_port = server_post

    # 此函数实现telnet登录主机
    def connect_dubbo(self):
        try:
            print("telent连接dubbo服务端: telnet {} {} ……".format(self.server_host, self.server_port))
            self.tn.open(self.server_host, port=self.server_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, server_host, server_post):
        try:
            self.telnet_client = TelnetClient(server_host, server_post)
            self.login_flag = self.telnet_client.connect_dubbo()
        except Exception as e:
            print("invokedubboapi init error" + 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, dubbo_service, dubbor_method, *args):
        api_name = dubbo_service + "." + dubbor_method + "{}"
        cmd = "invoke " + api_name.format(args)
        print("调用命令是:{}".format(cmd))
        resp0 = None
        try:
            if self.login_flag:
                resp0 = self.telnet_client.execute_some_command(cmd)
                print("接口响应是,resp={}".format(resp0))
                return resp0
            else:
                print("登陆失败!")
        except Exception as e:
            raise Exception("调用接口异常, 接口响应是resp={}, 异常信息为:{}".format(resp0, str(e)))

    def logout(self):
        self.telnet_client.logout_host()

通过invoke请求dubbo接口的时候,除了integer,string还会有枚举类,实体类等入参。

枚举类请求

枚举类的请求格式为:
枚举类sex 中,包含man和woman

{"name":"MAN","class":"com.zl.enums.sex"}

实体类请求

实体类需要先将实体类全名写出,然后再写实体类对应的值

{"class":"com.zl.entity.student","name":"zl","sex":"man","age":"18"}

map对象请求

public class UserMap {
    private Map<String, Integer> UserMap;
}

调用方式:

{"UserMap":{"age":18}}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值