每周学点TARS——服务自定义命令

做者 Eatonhtml

导语git

平常开发中,除了基础的服务管理功能,有时咱们还须要进行一些特殊的业务相关的服务管理,好比清除服务缓存,改变服务的模式、停用服务某个接口等。因为这些需求和业务耦合性较高,框架层面通常不会提供这样的功能,开发者甚至须要本身开发额外接口来实现。为了解决这一问题,TARS 在框架层面提供了自定义命令的功能。github

目录

  • TARS 自定义命令简介
  • 添加自定义命令缓存

    • 实现自定义命令响应函数
    • 将响应函数与自定义命令绑定
    • 使用自定义命令
  • TARS 自定义命令的原理
  • 总结

TARS 自定义命令简介

TARS 自定义命令功能用于实现除框架对服务的基础管理之外的服务管理功能。开发者可以添加自定义命令并实现命令的逻辑,并经过 TarsWeb 管理页面来向服务发送命令,触发自定义命令的逻辑。框架

TARS 服务框架中也经过自定义命令的方式,内置了如下八种命令:分布式

tars.help           # 查看全部管理命令
tars.loadconfig     # 从配置中心, 拉取配置下来: tars.loadconfig filename
tars.setloglevel    # 设置滚动日志的等级: tars.setloglevel [NONE, ERROR, WARN, DEBUG]
tars.viewstatus     # 查看服务状态
tars.connection     # 查看当前连接状况
tars.loadproperty   # 使配置文件的 property 信息生效
tars.setdyeing      # 设置染色信息 tars.setdyeing key servant [interface]

tars.setloglevel 为例,咱们想要修改某个服务的日志等级为 ERROR,打开服务的管理页面,点击 更多命令,以下函数

DHJK4e.png

在弹出窗口中选中自定义命令,输入命令 tars.setloglevel ERROR,并点击 肯定微服务

DHJUUS.png

点击 肯定 后,会弹出提示框,提示命令执行结果,以下图,咱们成功设置了日志等级。性能

DHYgsI.png

接下来,咱们介绍用户添加全新自定义命令的方法。ui

添加自定义命令

本部分将以 TarsCpp 应用为例,介绍如何在服务中添加自定义命令。这里咱们经过如下命令建立一个服务名为 CommandDemo.DemoServer.DemoObj 的服务,后面将以该服务为例子介绍如何使用自定义命令。

/usr/local/tars/cpp/script/cmake_tars_server.sh CommandDemo DemoServer Demo

项目结构以下

DemoServer
├── build                   # 构建目录
├── CMakeLists.txt          # cmake 构建文件
└── src                     # 源文件目录
    ├── CMakeLists.txt
    ├── Demo.h              # Demo.tars 生成文件
    ├── DemoImp.cpp         # 接口实现文件
    ├── DemoImp.h           # 接口实现头文件
    ├── DemoServer.cpp      # 服务实现文件
    ├── DemoServer.h        # 服务实现头文件
    └── Demo.tars           # tars 接口定义文件
关于 TARS 服务的建立与部署,参考文档 TARS 服务开发入门,本文再也不赘述。

添加全新自定义命令的方法分两步:

  1. 实现自定义命令响应函数
  2. 将响应函数与自定义命令绑定

实现自定义命令响应函数

在这一部分中,咱们将尝试建立并实现一个自定义命令。

首先,咱们在服务实现头文件 DemoServer.h 中,添加自定义命令函数的声明

bool testCommand(string const &command, string const &params, string &result);

这里咱们声明了一个 testCommand 函数。按照自定义命令函数的要求,必须声明三个参数 command, params, resultcommand 为具体的指令内容,params 为自定义命令携带的参数,result 为命令执行的结果,用于返回给 TarsWeb。

而后,咱们在 DemoServer.cpp 中添加这个函数的定义

bool DemoServer::testCommand(string const &command, string const &params, string &result)
{
    RemoteNotify::getInstance()->report("Receive CMD: " + command + " Params: " + params);
    result = "successful";
    return true;
}

实现很是简单,使用了 RemoteNotify::getInstance()->report() 上报接收到的命令和参数,可以直接在 TarsWeb 接收到上报的信息;并将命令的执行结果信息传入参数 result,也会在 TarsWeb 中显示;最后 return true ,表明本次命令执行成功。

将响应函数与自定义命令绑定

最后,咱们在文件 DemoServer.cpp 中服务的初始化函数 DemoServer::initialize 里,使用 TarsCpp 中提供的宏 TARS_ADD_ADMIN_CMD_NORMAL 来添加自定义命令,以下

void
DemoServer::initialize()
{
    addServant<DemoImp>(ServerConfig::Application + "." + ServerConfig::ServerName + ".DemoObj");
    // 添加自定义命令 testCommand
    TARS_ADD_ADMIN_CMD_NORMAL("testCommand", DemoServer::testCommand);
}

TARS_ADD_ADMIN_CMD_NORMAL 第一个参数为具体命令字符串,即 TarsWeb 中输入的命令;第二个参数为命令的触发函数,即接收到这个命令后会执行的函数,这里咱们传入咱们刚刚定义的函数 testCommand

这样咱们就完成了自定义命令的添加,编译并在 TarsWeb 发布服务后,咱们就可以向服务发送自定义命令来管理了。

使用自定义命令

前面咱们已经完成了自定义命令的添加,接下来咱们就可以在 TarsWeb 上向服务发送自定义命令来执行相应的逻辑了。

咱们按照简介中介绍的方式,在 TarsWeb 的 DemoServer 服务管理页面中输入自定义命令。这里咱们输入 testCommand param1 param2,即咱们前面添加的命令 testCommand,并附带了参数,以下图

点击 肯定 后,会弹出提示框,提示命令执行结果,以下

[1]: 后面的 successful 即为前面咱们在自定义命令函数中返回的 result 的值,会显示在提示框中。而后咱们刷新服务的实时状态,会出现一条服务状态信息 ,以下图

这里的信息就是函数中调用 RemoteNotify::getInstance()->report() 上报的信息,咱们在函数中上报了命令字符串和传入的参数字符串,可见,和咱们传入的是一致的,说明咱们成功执行了自定义命令函数。

TARS 自定义命令的原理

前面咱们了解了如何添加并向服务发送自定义命令,总结一下流程大体以下:

  1. 声明并实现自定义命令响应函数;
  2. 将自定义命令与函数绑定。

实际上就是将命令和函数绑定,接收到该命令时执行相应函数。咱们前面提到,命令与函数的绑定经过 TARS_ADD_ADMIN_CMD_NORMAL 实现。它的定义以下

/**
 * 添加Normal命令处理方法
 * 在全部前置方法最后执行
 * 多个Normal方法之间顺序不肯定
 */
#define TARS_ADD_ADMIN_CMD_NORMAL(c,f) \
    do { addAdminCommandNormal(string(c), std::bind(&f, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); } while (0);

这个宏调用了函数 addAdminCommandNormal 来绑定,再来看看它的定义

void BaseNotify::addAdminCommandNormal(const string& command, TAdminFunc func)
{
    TC_LockT<TC_ThreadRecMutex> lock(*this);

    _procFunctors.insert(std::make_pair(command, func));

    _observer->registerNotify(command, this);
}

从上述代码中,能够看出原理很简单,其实是经过一个 map 类型的对象 _procFunctors 来存储自定义命令绑定的函数。当调用服务自定义命令入口函数 notify 时,经过这个对象来获取命令对应的函数,并执行。notify 定义以下

bool BaseNotify::notify(const string& cmd, const string& params, CurrentPtr current, string& result)
{
    TC_LockT<TC_ThreadRecMutex> lock(*this);

    map<string, TAdminFunc>::iterator it;

    it =  _procFunctors.find(cmd);

    if (it != _procFunctors.end())
    {
        return (it->second)(cmd, params, result);
    }
    return false;
}

可见,的确是经过 map 类型对象 _procFunctors 来获取自定义命令对应的函数的。

总结

本文介绍了 TARS 中的自定义命令功能的使用和原理,经过简单的使用示例介绍如何使用。开发者也可以根据业务需求,完成更加复杂的操做,实现对服务进行更多管理。

TARS 能够在考虑到易用性和高性能的同时快速构建系统并自动生成代码,帮助开发人员和企业以微服务的方式快速构建本身稳定可靠的分布式应用,从而令开发人员只关注业务逻辑,提升运营效率。多语言、敏捷研发、高可用和高效运营的特性使 TARS 成为企业级产品。

TARS微服务助您数字化转型,欢迎访问:

TARS官网:https://TarsCloud.org

TARS源码:https://github.com/TarsCloud

Linux基金会官方微服务免费课程:https://www.edx.org/course/bu...

获取《TARS官方培训电子书》:https://wj.qq.com/s2/6570357/...

或扫码获取:

QR

相关文章
相关标签/搜索