美图全链路监控实战

2023-11-16

一. 摘要

 

本文内容分为3部分,首先简单介绍了美图的业务背景和监控体系,然后是两个美图的监控实践----基于Grafana FlowCharting插件的「监控大盘」实战和基于基于GrafanaImageRender+企业微信机器人的「图文告警」实战。这两个监控实战都是非常容易落地的,基本是开箱即用,中间只涉及到非常少量的代码工作。本文除了介绍我们做相关技术选型时的一些考量,同时给出了两个实战完整的“step by step”的操作步骤,对于涉及到的少量代码工作,文中也给出了代码样例。希望这两个案例对于大家做监控大盘和富文本告警的工作可以有所参考。

 

二. 美图监控的整体架构

1. 业务背景

 

在展开技术实战部分的讲解之前,我们先简单了解下美图公司的业务场景和规模。美图公司的业务主要分为 ToC 和 ToB 两类,以「消费者社区」为核心,在「影像美化」、「美妆平台」、「皮肤管理」几个垂直领域均有面向终端用户和面向企业的产品或解决方案。

 

美图的产品线覆盖社区、美颜、美妆、短视频、直播等领域,比较知名的C端APP有美图秀秀、美颜相机、美妆相机、美拍等。此外,美图拥有大量的海外用户,知名的产品有 BeautyPlus、AirBrush 等。围绕这些 APP 同时建设有大量的支撑服务,比如基础架构、大数据、AI开放平台、商业化生态等。

 

美图的产品线众多、业务形态丰富、ToC和ToB的服务并存,如何保障众多线上服务的稳定性也就是众多技术同学尤其是SRE同学所面临的挑战。而要保障服务的稳定性,不可或缺的一点就是对服务质量的感知力,也就要求我们建设一套稳定、高效、契合业务的监控系统。美图的监控体系就是建立在前文的场景和规模之下的,下面让我们来深入了解一下。

 

2. 监控体系

 

美图的整个监控体系分为「用户端」和「服务端」两大块。

  • 「用户端」主要覆盖客户端和中间链路。目前主要基于美图自研的APM(内部代号哈勃)来做客户端的的质量监测,监控的指标有:网络质量、崩溃、卡顿、响应时间、错误率、慢请求等。除此之外,美图还建设有流媒体的监控体系,主要用来覆盖直播推流拉流、点播拉流、CDN质量等。

  • 「服务端」的部分涵盖的内容比较多,如果从业务的请求链路来看,服务端的监控会覆盖从「入口层负载均衡」到「业务服务」、到「周边依赖服务」的调用、到「后端资源类服务」等整个请求链路。此外,还有一些基础设施的监控。

因为目前美图的业务已经“全量上云”,我们对基础设施的监控就不再过多关注网络设备、服务器等物理硬件相关的内容了,更多地转向了对云上基础设施的监控,比如网络质量、ECS虚机、容器平台、DNS等基础服务等。

 

美图整体的监控体系可以参照上图,本图的绘制时间稍微有点早了,但是基本的信息都还是适用的。

美图是从2016年开始推进完善上述监控体系的,在这个过程中我们也调研、测试、引入了众多的技术工具和技术栈:

  • Zabbix、OpenFalcon、OpenTSDB 基础监控

  • ELKB 日志套件

  • InfluxDB 的 TICK 套件

  • Prometheus

  • Spark、Storm、Kafka、Flink 等大数据套件

  • Netdata、Sentry、EagleEye、SkyWalking 等

 

此外,美图也基于开源的组件做了大量的二次开发的工作,同时也建设了一些诸如通知系统 NoticeSystem、统一告警平台 MTAlert 等工具。

 

监控体系涉及的内容比较庞杂,无法在一篇文章中做到全面细致的讲解,下面会将更多的篇幅放在「全链路监控报表」的建设思路上,并且会附带一个监控大盘和告警的实战。

3. 监控大盘

a. 统一监控报表查看入口到Grafana

 

经过上述的建设,已有的监控工具已经可以较好的覆盖从客户端到服务端的各个环节了,这时却有了新的问题:监控系统太多、报表散落在各个系统,业务方排查一个问题可能需要在多个系统之间来回切换,体验非常不好。

 

这时候我们希望有一个统一的用户界面来展示不同监控系统的数据,我们也做了一些简单的调研。当时我们调研的方案有:自建前端、用iframe简易嵌套组合、Grafana。

自建前端和iframe嵌套的优点都是可以接入更多的监控系统,但是缺点也都比较明显。自建前端是可定制化程度最高的方案,但是需要比较多的适配工作,随着各个监控系统的迭代,平台维护的工作量也是比较可观的;iframe嵌套的方式倒是简单粗暴,但是并没有从本质上解决数据割裂的问题,并且还需要解决不同监控平台之间的用户权限打通的问题。

 

最终我们选择了Grafana作为统一的监控Dashboard工具,当时考量的点主要有:

  • Grafana对我们当时在用的大部分监控系统(数据源)都有支持,比如Zabbix、OpenTSDB、Prometheus、InfluxDB、Elasticsearch

  • Grafana是Prometheus官方推荐的展示组件,当时我们已经在大量推进业务侧的Prometheus监控,这个点对我们的决策比较重要

  • Grafana的发展很迅猛,社区活跃,有“大一统”之势

 

于是把原先没有接入到 Grafana 的数据源做了统一的接入,用 Grafana 来提供统一的监控用户界面。

当然,Grafana也有一些问题,比如对一些数据源没有提供支持或者支持不够完美,日志、告警的能力比较弱(现在已经有非常大的改观)等。对于这些问题,我们选择容忍或使用其他方案来配合和覆盖,比如:

  • ELK技术栈中的日志细节查看还是需要借助Kibana,Grafana则更合适去呈现Elasticsearch的汇总数据或变化趋势

  • Prometheus的PromQL的调试、AlertManager的管理,可能还是原生的UI会更友好

  • 监控告警的需求,我们则更多的依赖我们的告警平台MTAlert来做覆盖

 

考虑到我们的原始需求(统一的监控UI),目前Grafana是可以满足我们绝大多数日常的监控可视化需求的。

b. 在一张报表(Dashboard)中展示业务链路

 

在用 Grafana 解决了数据源散落在多个系统的问题之后,业务方可以不用频繁的在多个监控系统之间做切换了。但是由于请求链路中不同阶段的监控图表还是存放在不同位置的,业务方在实际的使用中还是需要在多个Org、Dashboard 或 Panel 中切换。

比如上文提到的典型的请求链路:

 

业务方期望能有一个全局的视角,可以在一个页面或者图表中体现出这些环节的监控数据,这时候我们可以怎么做呢?

 

通常的思路就是我们在一张 Dashboard 中,以业务的维度建立不同层次的 Panel,把这个业务相关的各个环节的监控图放到一起,这样业务方在一个页面里去做点击和滚动就可以了,相比前面的方式我们又往前迈了一步。

比如下面的两个样例:

Tips:在监控数据、业务线、用户数量比较多的时候,建立一套Grafana的使用规范(共识)是非常有必要的,这套规范可能需要涵盖:

  • Grafana中各种资源的申请和使用约束

  • 数据源的管理规范

  • 权限管理规范

  • Org、报表命名规范

c. 我们还可以更进一步吗?

 

回顾一下上面两个阶段中监控报表的发展:

  1. 从监控数据散落在多个系统中,到把汇总数据到同一个平台(Grafana)

  2. 再到把不同Org、不同 Dashboard 中的数据汇总到一张 Dashboard 中展示

 

这个发展路径中,我们都是在试图把(相关联的)监控数据汇总到一个地方,整体的方向是越来越集中的。因为我们的一个诉求是期望可以在更少的页面中去看到更多的信息,以此来辅助我们更好地掌控服务、更快地排查问题。

 

但其实,上面的这些方式都只是解决了“监控数据集中展示”的问题,我们还有一个更核心的诉求之前是一直没有得到满足的:我们希望看到各个监控数据之间的关联关系。我们希望可以通过各层次、各依赖服务、各资源的监控状态,以及它们之间的关联关系,来辅助业务方构建一个更立体的全局视角。比如现在服务SLA告警了,我希望一眼看到整个系统中所有关联模块的状态,希望能够知道这个SLA问题(告警)可能是由什么导致的。如果监控系统可以达到这个目标的话,它就可以辅助业务方打造一个全方位的服务感知能力,也可以让问题排查和定位变得更高效。

 

这个需求类似于「服务链路跟踪」或者「根因定位」,但是这两个领域都是需要大量基础建设和业务适配的,工作量大,推行成本比较高。那我们有没有什么折中的方案,是可以“以较小的代价”来实现(或者部分实现)这个需求呢?接下来,让我们看一下目前在美图推广的一个基于 Grafana FlowCharting插件的监控大盘实践,看下这个是否可以给你带来一些参考。

三. 基于FlowCharting的监控大盘实战

1. FlowChating介绍

 

FlowCharting是一款Grafana的插件从名字应该就可以大概了解这款插件的用途。flow,流、数据流;charting,图表。这个插件是基于draw.io在线绘图库的,用draw.io可以完成非常复杂的图表的绘制,比如网络拓扑图、数据流量图、技术架构图等,然后我们可以用FlowCharting为图表中的各个元素绑定动态的数据,从而完成一张动态的图表。

 

我们借助这个插件完成了“把服务整个请求链路的监控数据汇总到一张图表”的需求,通过这样的图表我们可以一眼看到服务当前状态的全貌。如下图所示,我们把一个服务从「客户端」到「服务端」以及「依赖服务」和「资源服务」的监控数据都汇总到了一起。通过为不同的监控数据设置不同的阀值、配置不同的颜色,可以更直观的看到整个系统的健康状态。

这个方案里各个监控数据之间的逻辑关联性可能不像trace系统中那么紧密,需要人工去梳理服务的监控项、绘制可以体现数据链路及逻辑关系的图标,但是它切实解决了之前我们监控数据逻辑性不够直观的问题。当系统出现问题的时候,我们可以快速的从这张图表中看到各层、各组件及组件之间的链路状态,它切实提高了我们在问题排查中的效率。

 

对于这个方案的另一点说明:这个插件只是提供了一种数据可视化的方法,前提还是需要先建设有相关的监控数据。如果你面临的场景跟我们是类似的----已经有各类监控数据,但是苦于如何更直观地把监控数据展示出来,那么这款插件一定值得尝试。

2. 监控大盘实践Step by Step

a. 第一步:绘制图形

 

首先,我们需要借助 draw.io 来绘制我们的业务架构图(如图-业务架构图)。

 

业务架构图

 

流程图绘制工具可采用以下两种方式:

  • Web在线绘制:draw.io

  • 本地客户端绘制:客户端下载地址

 

业务架构图绘制完毕后,我们通过点击【其他】-【编辑绘图】可以看到图形的代码。

 

 

b. 第二步:将图导入Grafana

 

我们先将 draw.io 中的流程图代码粘贴在 Source Centent 中,粘贴完毕后,我们就可以从 Grafana 看板中看到绘制好的图形了。

 

 

  • Edit Draw:在线编辑当前图形。

  • Prettify:格式化图形代码。

  • Minify:合并图形代码。

  • Compress/Encode:加密图形代码。

  • Extract/Decode:解码图形代码。

 

生成好绘制的图形后,我们就可以开始调整看板的基础配置。

 

  • Bg Color: 可以调整 grafana 看板背景色。

  • Enable animation:开启动画效果。

前提条件:Grafana需要安装并开启FlowCharting插件。详见:https://grafana.com/grafana/plugins/agenty-flowcharting-panel/installation

 

 

c. 第三步:为图形元素绑定监控数据源

 

我们需要为关键图形元素添加监控数据源。根据需求可以在报表中添加相应的 Query 语句。

此处各个查询语句的"名称",会用于下文中关联图形使用。

 

 

d. 第四步:配置图形展示规则

 

在报表中可以通过添加 Rule ,来设置我们图形的展示效果。

 

 

如上图所示,Options 是用来关联上一步中添加的监控数据源。

  • Rule name: 规则名称。

  • Apply to metrics:与哪个查询语句关联 (支持正则)。

  • Aggregation: 为数据源选择一个聚合。

 

Type 是用来设置数据源展示的指定单位和类型。

  • Type:类型。

  • Unit:单位。

  • Decimals:保留几位小数。

 

Thresholds 用来设置图形展示的颜色变化规则。

  • Invert:倒序排列。

  • Gradient:使用渐变颜色。

  • Icon state:图标状态。

 

Tooltips 开启后,将鼠标移动到具体图形上,会自动展示对应监控值一个周期状态,

 

如下图所示。

  • Label:弹出窗口中展示的标签(默认和查询语句命名的"名称"相同)。

  • Direction:垂直显示还是水平显示。

  • Color with state:弹出的图形颜色是否和服务状态颜色保持一致。

 

 

Graph Tooltips 用来设置弹出图形展示的效果。

  • Graph type:使用线性或者柱状图。

  • Graph Size:弹出的图形大小。

  • Scale type:颜色填充部分选择。

 

e.  第五步:关联具体的图形

 

我们将具体的图形关联到配置好的 Rule 中,这样就可以在 Grafana 看板中看到具体图形的状态颜色了。

 

 

Color/Tooltip Mappings 颜色映射,图表颜色填充/边框填充等。

  • Identify by:选择一种图形的关联类型,有 id 和 Label 两种。

    • id:即每个图形的 id。例如流程图代码中的 UD0VAbfAxGPwaQMbtyaW-13

    • Label:即每个图形的"标题"。例如流程图代码中的 value 值 MTXX

  • Regular exression:是否使用正则。如果下方 What 中的值未使用正则,请关闭这个开关以提高性能。

  • Buttons:选项的添加和删除。

  • What:与哪个图形关联,添加图形关联的方式有两种:

    • 手动填写"图形id"或"图形标题"。

    • 先点击 Buttons 中的链接标志,再点击图形,会自动读取 Pannel 中的"图形id"或"标题"。

  • When:颜色填充触发条件。

  • How:填充类型。

 

Label/Text Mappings: 数值映射, 图表与查询结果的数值填充。

  • When:数值显示条件。

  • How:数值显示位置。

 

Link Mappings: 链接映射,点击图形可跳转至指定 URL(比如具体监控项的详情页面)。

 

Event/Animation Mappings: 事件映射。

 

f. 第六步:完善流程图中其他图形

 

最后,为所有需要监控的图形创建对应的 Rule ,整个业务流程监控大盘就制作完毕了。至此,你将收获一张包含动态监控数据的监控大盘。

 

 

四. 基于GrafanaImageRender+企业微信的「图文告警」实战

1. 思路介绍

 

这个部分可以算作是上一个实战的延展,经过上面的建设我们已经有了服务级整体的请求流向图后。如果我们可以在服务发生「告警」的时候,同时把「监控大盘」的信息发出来,让我们在收到服务告警的同时可以快速感知服务的整体状态,这将大大提升我们问题排查的效率。

 

结合目前我们在用的企业IM的群机器人告警通道和Grafana的ImageRender,告警和监控大盘的联动也就水到渠成了。目前美图选用的企业IM是企业微信,我们只需要在服务告警发生的时候,同时将监控大盘的「状态截图」通过企业微信的IM机器人发到各个群组即可。

 

钉钉、飞书等企业IM也都有提供群机器人的功能。

 

结合美图已有的监控告警组件,我们选择的告警发送请求链路为 Grafana-Image <-> MTAlert -> 企业微信机器人。 

 

 

组件说明

 

  • MTAlert为美图自研告警平台,支持配置监控告警。同时支持在触发指定监控告警时,将告警的内容发送给扩展脚本做定制处理。

  • GrafanaImageRender是Grafana的一个后端插件,用这个插件可以把Panel或者Dashboard渲染为PNG图片,官方建议独立部署。

 

告警流程 我们的告警规则是维护在MTAlert中的,当告警发生的时候我们将告警消息发给一个指定的脚本。这个脚本负责根据约定好的规则做过滤和处理,去GrafanaImageRender渲染图片并获取图片的链接,然后将组合后的图文消息发送给指定的企业微信群机器人。

 

用这样的方式,我们就可以在一条告警消息中获取到服务本身及上下游的即时状态,从而让我们对问题的原因和影响范围有一个快速的大致判断,进而缩短问题排查时间,降低MTTR(故障平均修复时间),提升服务的稳定性。

 

2.「图文告警」实战Step by Step

a. 第一步:创建群机器人并获取 Webhook

 

 > [企业微信 - 如何使用群机器人](https://work.weixin.qq.com/help?doc_id=13376)

 

因告警会包含图片和标题, 使用图文类型消息, 需要发送给 Webhook 的格式如下: 

 

PS: 机器人的频率限制为每个机器人发送的消息不能超过20条/分钟。

 

b. 第二步:获取 Grafana-Panel 图形链接

 

  • 获取流向图所在 Grafana-org 的 API Keys。 

 

可指定 Keys 的有效时长, 如果不指定, 则 key 永久有效。

  • 获取指定 Panel 的渲染图形链接。点击指定 Panel 的 Share 后, 可以看到 Direct link rendered image。

 

  • 使用 Grafana-Image 根据渲染图形链接获取该 Panel 的 png 格式的图形链接。

  •  
  •  
  •  
  •  
curl -H "Accept: application/json"    -H "Authorization: grafana_api_key"    -d '{"imageUrl":"http://grafana-panel-url/render/d-solo/panelxxxxx"}'    "http://grafana-images-server/grafana-images"

 

调用成功可得到如下的返回值

  •  
{"pubImg":"http://grafana-images-server/f6cdd1xxxxxxxb01b.png"}

我们的GrafanaImageRender为独立部署的模式,通过HTTP方式提供服务。传入一个GrafanaPanel的URL(还有Grafana的API Key)将得到一个可以直接访问(公网下或者受信网络下)的图形的URL。

 

c. 第三步:配置监控告警策略

 

  • 自研 MTAlert 添加监控策略。此处的 Grafana 链接为 渲染图形链接(非 png 格式图形链接),且该内容会在触发告警时作告警内容的一部分被发送给下游。

 

为提升扩展脚本的可扩展性, 我们对告警配置中的grafana链接约定了一个固定的格式:grafana链接&&&&&&微信机器人webhook地址&&&&&&报警名称&&&&&&报警描述&&&&&&

  • 添加告警扩展, 与监控策略联动。如果使用了告警扩展, 在触发告警后, 告警平台会将告警内容传送对应的扩展脚本。告警扩展对于过滤类型,需要脚本返回 ture OR false。告警平台如果收到 true 的返回,将认为告警需要发出,如果收到 false,则不会发出该告警。

     

 

d. 第四步:告警扩展脚本

 

告警扩展脚本我们使用了Python,告警扩展会固定调用脚本中的 getExtendData(data) 这个函数,其中 data 为告警平台传送的告警内容。扩展脚本部分代码如下:

# 3. 发送告警
def SendPanelMsg(token, new_panel_url, webhook_url, title, description):
    public_url = GeneratePanelPngurl(token, new_panel_url)
    data = {
        "msgtype": "news",
        "news": {
            "articles": [
                {
                    "title": title,
                    "description": description,
                    "url": public_url,
                    "picurl": public_url
                }
            ]
        }
    }

    # post
    url = webhook_url
    postdata = json.dumps(data)
    request = urllib2.Request(url, postdata)
    request.add_header('Content-Type','application/json')
    try:
        response = urllib2.urlopen(request)
        return 'post Success'
    except Exception as ex:
        return 'post Exception'

def getExtendData(data):
    # 1. 从告警内容中获取该条告警策略对应的信息: 渲染图形链接, 机器人 webhook, 告警策略名称, 告警策略描述;
    msg_info = json.loads(data)
    msg_data = msg_info['data']
    msg = msg_data['报表地址'.decode('utf-8')]
    msgArr = re.split('&&&&&&', msg)
    if len(msgArr) != 5 :
        print 'mtalert->业务预警配置->grafana链接 配置有误!格式应为: grafana_panel_url&&&&&&webhook_addr&&&&&&alert_title&&&&&&alert_description&&&&&&'
        return 'true'

    panel_url = msgArr[0]
    webhook_url = msgArr[1]
    title = msgArr[2]
    description = msgArr[3]

    # 2. 获取对应 org 的 Token, 修改渲染图形链接时间范围为当前时间, 生成新的渲染图形链接.
    org_id = GetOrgId(panel_url)
    token = GetOrgToken(org_id)
    panel_time_range = 30
    new_panel_url = GenerateNewPanelUrl(panel_url, panel_time_range)
    

    # 3. 由渲染图形链接请求 Grafana-Image, 获取 png 格式图形链接, 并通过群机器人 webhook 发送带图形的告警.
    SendPanelMsg(token, new_panel_url, webhook_url, title, description)
    return 'false'

e. 告警实例

 

以上就是这个实战的全部内容了,其实整个实践的思路还是比较简单和清晰的,大家可以根据自己的环境做些灵活的适配。

 

五. 未来展望

 

基于FlowCharting的大盘实践和信息更丰富的图文告警,相比于传统的监控和告警方式来讲,虽然略新颖,但是基本都还是围绕“工具应用”的层面开展的。这远不是终点,我们还有非常多的事情需要继续去推进,下面是两个较为“清晰”的思路或方向,大家或许可以参考:

 

一、我们需要有一个认识 ---- “监控只是帮助我们达成某些目标的工具或手段,而不是最终的目的”。因此我们还可以继续往前迈进,做更多的横向连接和扩展。比如:

  1. 如果我们的目标是「服务的稳定性」,我们可以跟服务的弹性策略、异常处理、故障自愈做联动,更好地做服务质量保障。

  2. 如果我们的目标是「降低成本」,我们的监控数据也可以提供强有力的支撑,配合对监控数据的挖掘,指导我们更好的做容量规划。

 

二、再有一个较为前沿,也正在如火如荼开展的方向则是「基于DataOps/AIOps的(监控)实践」。通过大数据、机器学习等新兴技术手段,更好的挖掘监控数据的价值,打造更智能的工具体系,用更科学、更智能的方法来辅助运营和生产。

 

当然,未来在监控上可以做的事情也远不止这些,我们可以一同努力、共同期待。

 

六. 全文总结

 

本文先介绍了美图的监控体系,然后着重讲解了监控大盘的发展:按照将监控数据尽可能集中汇总的思路,我们逐步把监控数据从多个系统收敛到一个系统,然后我们把多个监控报表整合到一个页面中进行呈现,最后我们用FlowCharting这个插件把监控数据的集中展示做到了“极致”,在一张图表中展示。同时巧用FlowCharting插件来体现监控数据之间的关联关系,由此我们就可以用它以较低的成本构建出一个「端到端的全链路监控」了。

 

最后,我们分享的一个基于GrafanaImageRender组件和企业微信群机器人的“图文告警”实战。

 

PS:目前这套监控大盘和图文告警在美图的应用效果非常不错,感兴趣的同学也可以做一些尝试。

 


文章作者介绍: 石鹏、朱起飞、王苑卜,三人均为美图产品SRE团队的同学。

鸣谢:感谢公司所有参与基础设施、监控平台建设的同学,感谢各兄弟部门在上述建设中提供的协助和支持。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

美图全链路监控实战 的相关文章

  • anaconda安装所有库代码集总

    1 安装jupyter conda install jupyter
  • 接口请求合并的3种技巧,性能直接爆表!

    将相似或重复请求在上游系统中合并后发往下游系统 可以大大降低下游系统的负载 提升系统整体吞吐率 文章介绍了 hystrix collapser ConcurrentHashMultiset 自实现BatchCollapser 三种请求合并技
  • 5.3.6 复合主键@IdClass

    有时一个实体的主键可能同时为多个 例如同样是之前使用的 CustomerEO 实体 需要通过name和email来查找指定实体 当且仅当name和email的值完全相同时 才认为是相同的实体对象 要配置这样的复合主键 步骤如以下所示 1 编
  • 快速排序(Java实现) 单边循环、多边循环

    package com xiaoxin sort import java util Arrays public class quickSort me public static void main String args int arr 9
  • 关于CSS及JS的使用技巧浅谈

    使用CSS预处理器 例如Sass和Less 可以帮助开发者更快速 更有效地编写CSS代码 模块化 将CSS和JS代码分解为模块 可以帮助开发者更好地组织和管理代码 压缩和合并 使用压缩工具可以帮助减少CSS和JS文件的大小 使网站更容易加载
  • minikube单机安装nfs服务

    1 安装 nfs server sudo apt get update sudo apt get install y nfs kernel server 2 创建目录 配置 IP 共享目录绑定 vim etc exports 新增 data
  • Shiro权限框架-实现分布式会话SessionManager(7)

    1 会话的问题 2 分布式会话实现思路 1 原理分析 所有服务器的session信息都存储到了同一个Redis集群中 即所有的服务都将 Session 的信息存储到 Redis 集群中 无论是对 Session 的注销 更新都会同步到集群中
  • vue+elementUI图片预览,<el-image> 的使用

    vue elementUI图片预览 el image 的使用 本文转载自 https www cnblogs com allanlau p 13397625 html 首页定义data data return imgs imgsVisibl
  • 手把手教你使用transciver-ip核的配置

    目前很多行业都会用到transceiver 甚至像pcie srio等高速接口都调用了transceiver 所以了解并学会其使用方法还是很重要的 本文结合作者的使用经验 让你快速的了解并上手使用 Xilinx提供了Transceivers
  • (Scikit-Learn)朴素贝叶斯使用方法:高斯朴素贝叶斯 多项式朴素贝叶斯(文本分类)

    在贝叶斯分类中 我们希望确定一个具有某些特征的样本属于某类标签的概率 通常记为 P L 特征 贝叶斯定理告诉我们 可以直接用下面的公式计算这个概率 假如需要确定两种标签 定义为 L1 和 L2 一种方法就是计算这两个标签的后验概率的比值 其
  • Python自学之路第九步——用户输入和while循环

    主要用到的是input 函数 他可以接受用户的输入 这样便可以编写交互式的程序了 还介绍了while循环 这个和C中一样 包括if判断都可以尝试测试一下 很有意思 函数input pr 我们将统计您的基本信息 pr n请输入您的名字 nam
  • Mybatis - NoSuchMethodError: net.sf.jsqlparser.statement.select.SetOperationList.getSelects()Ljava/

    昨天在修改一个接口功能时 需要在原来的接口上提供分页和模糊查询 就使用了分页 PageHelper来做 但是在mybatis的xml文件中又使用了UNION来合并查询结果 导致项目启动直接报错 Handler processing fail
  • MySQL 中读写分离可能遇到的问题

    前言 MySQL 中读写分离是经常用到了的架构了 通过读写分离实现横向扩展的能力 写入和更新操作在源服务器上进行 从服务器中进行数据的读取操作 通过增大从服务器的个数 能够极大的增强数据库的读取能力 MySQL 中的高可用架构越已经呈现出越
  • ubuntu 光盘读取

    把光盘放入光驱后 要挂载光驱 将光驱设备挂在到 mnt 下 sudo mount dev sr0 mnt mount dev sr0 is write protected mounting read only 到 mnt目录下就可以看到光盘
  • 一条SQL语句求前面记录的平均值

    有算法要求如下 For i 1 i lt 10 i ta i t 1 t 2 t i i 用一条SQL语句实现它 分别用表变量 ta 和 t 来对应 ta 和 t declare t table id int d decimal 18 4
  • 第一课 认识Python

    相比大家都听说过Python是一门容易学习的语言 那么实际是怎么样呢 我们从以下几点看看 1 首先 Python是最容易学习和最好用的语言 Python容易阅读和编写 比较清晰 格式非常简洁 表达能力强 这样同样写一个程序 Python比其
  • uniApp条件编译以及跳转方法

    1 使用Uniapp的方法获取系统环境 仅在JS中可以使用 uni getSystemInfoSync platform 获取应用所在的平台 if uni getSystemInfoSync platform ios if uni getS

随机推荐

  • pickle与.pkl文件

    经常遇到在Python程序运行中得到了一些字符串 列表 字典等数据 想要保存下来 长长久久的 方便以后使用 这个时候Pickle模块就派上用场了 pickle 模块及其同类模块 cPickle 向 Python 提供了 pickle 支持
  • mipi介绍

    文章目录 1 MIPI简介 1 1 DSI layer 2 D PHY 2 1 D PHY介绍 2 2 电平状态 2 3 lane结构 2 4 data lane操作模式 2 4 1 escape mode和space one hot co
  • kylin启动netstat: n: unknown or uninstrumented protocol

    检查hadoop配置的时候出现问题 报错如下 lcc lcc apache kylin 2 6 0 hbase1x bin check env sh Retrieving hadoop conf dir KYLIN HOME is set
  • 史上最快的实例分割SparseInst Int8量化实录

    近期 YOLOv7里面借鉴 复 制 粘 贴 了一个新的模型 SparseInst 我借助YOLOv7的基建能力 将其导出到了ONNX 获得了一个非常不错的可以直接用OnnxRuntime 或者TensorRT跑的实例分割 后续也可能把lin
  • 数据挖掘十大算法

    参考 ICDM 数据挖掘十大算法
  • flutter 去除超出警报

    给超出内容套上SingleChildScrollView组件即可 SingleChildScrollView child
  • wpf datagrid自动生成列时特殊字符转换

    DataGrid控件可以根据DataTable自动生成行和列 但是如果列名包括一些特殊字符 的时候 会出现无法显示出数据或者显示DataRowView的情况 原因是这些字符是Xaml里用来标识绑定path和xpath的符号 例如我们会这么用
  • C语言补漏:字符串指针与字符数组传参

    字符串指针与字符数组传参 深信服的笔试上被吊打 其中对一道用指针做形参的题目印象十分深刻 借此恶补了一晚上指针 今天总结 以作警示 试想有如下情形 将一个字符串指针做形参赋值函数修改其字符串 函数结束后字符串被改变了吗 include
  • 快速上手Gobject

    转自 http blog csdn net acs713 article details 7778051 What is G object 很多人被灌输了这样一种概念 要写面向对象程序 那么就需要学习一种面向对象编程语言 例如C Java
  • chrome扩展开发调试

    chrome扩展由content scripts browser actions background等多个部分组成 其中 content scripts属于注入web页面 所以在contentscripts中的console log会被正
  • Uncaught TypeError: AMap.MarkerClusterer is not a constructor

    实验点聚合时报错 cluster new AMap MarkerClusterer map markers styles sts gridSize 80 改为 map plugin AMap MarkerClusterer function
  • SQL语法基础

    SQL语法基础 SQL语法基础 SQL 是用于访问和处理数据库的标准的计算机语言 SQL 语句 需要在数据库上执行的大部分工作都由 SQL 语句完成 tips SQL 对大小写不敏感 SELECT 与 select 是相同的 一些最重要的
  • 【每周一个编程技巧 - Java笔记】玩转SSM:SpringBoot+Mybatis多条件筛选

    SpringBoot Mybatis多条件筛选 在实际的业务开发系统中 做的最多的工作就是增 删 改 查操作 而这部分增 删 改 查的操作中又有80 的都是查询操作 本文记录的主要内容是 基于SpringBoot和Mybatis来实现条件查
  • tesseract-orc编译及使用(WINDOWS VS 2019)

    1 准备资源 Vs2010或者更高版本 本教程使用vs2019 1 1Tesseract源码 分支切换到3 04 看到vs2010 git地址https github com tesseract ocr tesseract下载源码 文件夹并
  • 关于 Demo_Ocean 例子的分析

    关于 Demo Ocean 例子的分析 重要总结 1 该例主要类不再继承自ExampleApplication和ExampleFrameListener 重写驱动类和监听类 2 如何创建OIS的输入系统 1 创建OIS ParamList
  • Arduino与人体感应模块

    工具 1 Arduino 开发板 1 2 人体感应模块传感器 1 这个人体感应传感器有三个引脚 分别是VCC OUT GND 同之前的红外线传感器一样输出的是数字信号 所以要将OUT接入digital pwm引脚 这里我接入3号引脚 下面是
  • sql排序,数据库字段设置为varchar导致排序失效

    一般情况下 我们在表设置排序字段都是int 对应的sql查询 也就只需要order by xx desc 但是总有一些老项目 由于会因为各种原因 导致出现此字段为varchar情况 这种情况我们应该怎么排序呢 ex g Ex state 0
  • 1、shell 基础进阶系列文章

    shell 基础进阶系列文章 目录 第一章 shell本质 第二章 shell2 第三章 shell3 第一章 shell认知 shell 基础进阶系列文章 前言 一 shell基础 1 shell脚本的本质 2 shell编译的基本步骤
  • zabbix监控数据转存与处理

    zabbix是一个基于WEB页面的分布式系统监控方案 能够监控各类资产并提供灵活的通知功能 同时能够运行在各种流行系统中 zabbix分为zabbix server和zabbix agent端 zabbix server可以单独远程监控服务
  • 美图全链路监控实战

    一 摘要 本文内容分为3部分 首先简单介绍了美图的业务背景和监控体系 然后是两个美图的监控实践 基于Grafana FlowCharting插件的 监控大盘 实战和基于基于GrafanaImageRender 企业微信机器人的 图文告警 实