乐趣区

关于后端:TARS-服务信息上报|全方位服务监控

作者 | Eaton

导语 | 服务上线经营后,出现异常是不免的事,通常状况下会通过服务日志排查问题。然而这种排查问题的形式有时候是低效的,特地是日志比拟多,还不晓得如何下手的时候,十分麻烦。那让服务被动报告呈现的谬误不就行了吗?本文将对 TARS 中的几种信息上报形式进行介绍。

目录

  • 简介
  • 状态统计上报
  • 异样上报
  • 属性统计上报
  • 总结

简介

TARS 框架中集成了服务信息上报的性能,蕴含了服务的状态统计上报、异样上报、属性统计上报等三个信息上报统计形式,实现对服务衰弱水平的多方面监控。这三种信息上报形式别离通过 Stat、Notify、Property 这三个节点实现。如下图

服务通过向这三个节点报告本身不同维度的信息,实现对服务状态的监控。那么接下来咱们来理解这三种信息上报形式吧。

状态统计上报

所谓的状态统计上报,就是在 TARS 框架中,服务向 Stat 上报本身的调用耗时、超时率、异样率等状态信息并进行统计。

服务调用上报接口后,实际上是先暂存在内存中,当达到某个工夫点后才正式上报到 Stat 服务(默认是 1 分钟上报一次)。咱们称两个上报工夫点之间的工夫为一个统计区间,在一个统计区间雷同 key 进行累加、比照等操作。

状态统计上报个别不需用户额定开发,服务在 TARS 框架中正确配置并部署后,即可主动上报。

关上 TarsWeb 的服务治理页面,在具体服务的 服务监控 页面中能够看到对应服务相干的状态信息,包含流量、均匀耗时、超时率等,如下图。

异样上报

服务状态统计上报可能直观地理解服务的状态和衰弱度。不过理论应用场景中,仅统计一些服务的调用信息是不够的。为了更好监控,TARS 框架反对在服务中将异样间接上报到 Notify,并能够在 TarsWeb 治理页面上查看到,或联合别的告警软件或平台间接告诉用户。TARS 不同语言版本中都提供了异样上报形式。本局部将别离基于 TarsCpp 和 TarsGo 举例介绍,其余语言版本相似。

TarsCpp

TarsCpp 中提供了一种异样上报形式,即应用 RemoteNotify::report 来上报异样,用法如下

RemoteNotify::getInstance()->report(info);

参数 info 为须要上报的异样信息,类型为 string 字符串, 能够间接上报字符串到 Notify,页面能够看到上报的字符串。例如咱们创立一个服务名为 Demo.DemoServer.DemoObj 的 TarsCpp 服务,创立命令如下

/usr/local/tars/cpp/script/cmake_tars_server.sh TestDemo 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 接口定义文件 

接着在 DemoServer.cpp 的服务初始化函数 DemoServer::initialize 中上报一条信息,这样服务在启动时,就会上报一条 DemoServer Start 的信息,如下

void
DemoServer::initialize()
{addServant<DemoImp>(ServerConfig::Application + "." + ServerConfig::ServerName + ".DemoObj");
    // 上报信息
    RemoteNotify::getInstance()->report("DemoServer Start");
}

将服务编译部署后,能够在 TarsWeb 上服务的实时状态中看到服务上报的信息,如下图

TarsGo

TarsGo 中提供了如下函数来上报异样信息,用法和后面 TarsCpp 的类似

func ReportNotifyInfo(level int32, info string)

level 指的是异样等级,分为 NOTIFY_NORMAL, NOTIFY_WARN, NOTIFY_ERRORinfo 则为上报的信息。

咱们通过以下命令创立一个 TarsGo 服务 Demo.NotifyDemo.DemoObj

$GOPATH/src/github.com/TarsCloud/TarsGo/tars/tools/cmake_tars_server.sh Demo NotifyDemo Demo github.com/ETZhangSX/NotifyDemo

我的项目目录构造如下

NotifyDemo
├── build
├── client
│   ├── client.go
│   └── CMakeLists.txt
├── CMakeLists.txt
├── config.conf
├── debugtool
│   └── dumpstack.go
├── demo_imp.go
├── Demo.tars
├── go.mod
├── go.sum
├── main.go
├── start.sh
└── tars-protocol

同 TarsCpp 类似,咱们在 demo_imp.cppInit 中增加异样上报

func (imp *DemoImp) Init() (error) {tars.ReportNotifyInfo(tars.NOTIFY_ERROR, "ssart")
        return nil
}

构建部署该服务后,同样能够在服务实时状态中看到

可见,异样上报是一个被动上报的过程,开发者能够通过异样上报,被动上报服务谬误,比方在 try...catch 捕捉到谬误时,进行上报。

属性统计上报

除了状态统计上报和异样上报,TARS 中也提供了属性统计的性能,开发者可能上报业务相干属性并进行统计。为了不便业务应用,TARS 目前自带了以下几种统计类型:

  • 求和(sum)
  • 均匀(avg)
  • 散布(distr)
  • 最大值(max)
  • 最小值(min)
  • 计数(count)

TarsCpp 中,能够通过 createPropertyReport() 来创立并配置一个属性上报对象,并通过调用该对象的办法 report 来上报属性值。例如,咱们想监控一个数组大小的最大值,咱们创立一个属性名为 array_size 的属性上报对象,并配置上报办法为 max,即最大值,能够通过如下步骤实现。

PropertyReportPtr reportPtr = Application::getCommunicator()
                    ->getStatReport()
                    ->createPropertyReport("array_size", PropertyReport::max());
// vector<int> a;
reportPtr->report(a.size());

接下来咱们以一个 C++ 实现的简略队列服务为例,该服务蕴含两个队列操作接口

  • pop:用于弹出队列最前端的数字
  • push:用于增加一个数字到队列中

并对服务中队列的大小进行属性统计上报。

首先,咱们新建一个服务名为 Demo.PropertyDemo.TestObj 的服务,并新建文件 Queue.h,我的项目构造如下

PropertyDemo
├── build
├── CMakeLists.txt
└── src
    ├── CMakeLists.txt
    ├── PropertyDemo.cpp
    ├── PropertyDemo.h
    ├── Queue.h
    ├── Test.h
    ├── TestImp.cpp
    ├── TestImp.h
    └── Test.tars

Queue.h 中实现一个简略的线程平安队列类,实现如下

#ifndef _QUEUE_H_
#define _QUEUE_H_

#include "util/tc_singleton.h"
#include "util/tc_thread_rwlock.h"

class Queue : public tars::TC_Singleton<Queue>
{
public:
    void Push(int value)
    {TC_ThreadWLock wlock(rw_locker_);
        q_.push(value);
    }
    void Pop()
    {TC_ThreadWLock wlock(rw_locker_);
        if (!q_.empty()) q_.pop();}
    int GetSize()
    {TC_ThreadRLock rlock(rw_locker_);
        return q_.size();}
private:
    std::queue<int> q_;
    tars::TC_ThreadRWLocker rw_locker_; // 读写锁
};
#endif

能够看到 Queue 继承自 TC_SingletonTC_Singleton 是 TarsCpp 中提供的一个单件类组件,通过继承该类,使 Queue 成为单件类。

批改 Test.tars,咱们新增两个接口 pop, push 用于操作服务的队列。如下

module Demo
{

interface Test
{int test();
    int push(int value);
    int pop();};

};

而后在 TestImp.h 中增加接口的申明,如下

virtual int push(int value, tars::TarsCurrentPtr current);
virtual int pop(tars::TarsCurrentPtr current);

并在 TestImp.cpp 中实现这两个接口,如下

#include "Queue.h"

    ...

int TestImp::push(int value, tars::TarsCurrentPtr current)
{Queue::getInstance()->Push(value);
    return 0;
}

int TestImp::pop(tars::TarsCurrentPtr current)
{Queue::getInstance()->Pop();
    return 0;
}

最初,在 PropertyDemo.cpp 中,增加对队列大小的上报,如下

#include "Queue.h"

    ...

void *reportFunc(void *pArg)
{
    static PropertyReportPtr reportPtr = NULL;

    // 初始化散布数据范畴
    vector<int> v;
    v.push_back(10);
    v.push_back(30);
    v.push_back(50);
    v.push_back(80);
    v.push_back(100);

    // 创立 queuelength 属性,该属性用到了所有的集中统计形式,留神 distrv 的初始化
    reportPtr = Application::getCommunicator()
                    ->getStatReport()
                    ->createPropertyReport("queuelength",
                        PropertyReport::sum(),
                        PropertyReport::avg(),
                        PropertyReport::count(),
                        PropertyReport::max(),
                        PropertyReport::min(),
                        PropertyReport::distr(v));
    // 定时上报
    while (1)
    {
        // 上报的属性仅反对整型
        reportPtr->report(Queue::getInstance()->GetSize());
        sleep(1);
    }
    return NULL;
}

int
main(int argc, char* argv[])
{
    try
    {
        pthread_t hThread;

        g_app.main(argc, argv);
        // 创立一个线程运行 reportFunc,上报属性信息
        pthread_create(&hThread, NULL, reportFunc, NULL);

        g_app.waitForShutdown();}

    ...
}

reportFunc 中,咱们创立了一个属性 queuelength 的上报对象 reportPtr,增加上述的六种统计策略,并定时上报;而后在 main 函数中创立一个线程来运行 reportFunc

构建并部署服务后,咱们就能够在 TarsWeb 页面服务的个性监控中看到属性的统计值了,如下图

如果看不到统计信息能够距离 5 分钟,监控信息每 5 分钟同步一次。

从上图中,能够看到六种统计策略的值,别离是 Queue 中队列大小的求和、最小值、最大值、散布、计数、平均值。通过调用服务的接口 poppush,即向 Queue 队列中增加或弹出对象,扭转队列大小,这些值也会相应的变动。

咱们能够依据本身业务需要抉择策略,比方在流量统计方面能够应用求和的形式。

总结

本文对 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/…

或扫码获取:

退出移动版