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

作者 Eaton

导语

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

目录

  • 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

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

添加自定义命令

本部分将以 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

2020年3月10日,Linux基金会正式宣布旗下的TARS开源项目将成立TARS基金会。TARS基金会是一个专注于微服...

16 声望
7 粉丝
0 条评论
推荐阅读
DCache 分布式存储系统|Set, ZSet 缓存模块的创建与使用
导语 | 在之前的系列文章中,我们介绍了 DCache 及其 KV, K-K-Row 和 List 缓存模块的使用,本文将继续介绍如何使用 DCache 中的集合类型缓存模块 —— Set 和 ZSet 缓存模块。

TARS基金会1阅读 1.8k

终于卷完了!Redis 打怪升级进阶成神之路(2023 最新版)!
是一种非关系型数据库服务,它能解决常规数据库的并发能力,比如传统的数据库的IO与性能的瓶颈,同样它是关系型数据库的一个补充,有着比较好的高效率与高性能。专注于key-value查询的redis、memcached、ttserver。

民工哥11阅读 989

封面图
算法可视化:一文弄懂 10 大排序算法
在本文中,我们将通过动图可视化加文字的形式,循序渐进全面介绍不同类型的算法及其用途(包括原理、优缺点及使用场景)并提供 Python 和 JavaScript 两种语言的示例代码。除此之外,每个算法都会附有一些技术说...

破晓L7阅读 945

封面图
硬卷完了!MongoDB 打怪升级进阶成神之路( 2023 最新版 )!
前面我们学习:MySQL 打怪升级进阶成神之路、Redis 打怪升级进阶成神之路,然后我们还在继续 NoSQL 的卷王之路。从第一篇文章开始,我们逐步详细介绍了 MogoDB 基础概念、安装和最基本的CURD操作、索引和聚合、工...

民工哥6阅读 553

封面图
「刷起来」Go必看的进阶面试题详解
逃逸分析是Go语言中的一项重要优化技术,可以帮助程序减少内存分配和垃圾回收的开销,从而提高程序的性能。下面是一道涉及逃逸分析的面试题及其详解。

王中阳Go4阅读 1.9k评论 1

封面图
架构设计-高性能篇
大家好,我是易安!今天我们谈一谈架构设计中的高性能架构涉及到的底层思想。本文分为缓存架构,单服务器高性能模型,集群下的高性能模型三个部分,内容很干,希望你仔细阅读。

架构狂人4阅读 795

Nginx常用配置及和基本功能讲解 | 京东云技术团队
作者:京东物流 殷世杰Nginx已经广泛应用于J-one和Jdos的环境部署上,本文对Nginx的常用的配置和基本功能进行讲解,适合Nginx入门学习。1 核心配置找到Nginx安装目录下的conf目录下nginx.conf文件,Nginx的基本功...

京东云开发者6阅读 606

封面图

2020年3月10日,Linux基金会正式宣布旗下的TARS开源项目将成立TARS基金会。TARS基金会是一个专注于微服...

16 声望
7 粉丝
宣传栏