LC3视角:Kubernetes下日志采集、存储与处理技术实践

摘要: 在Kubernetes服务化、日志处理实时化以及日志集中式存储趋势下,Kubernetes日志处理上也遇到的新挑战,包括:容器动态采集、大流量性能瓶颈、日志路由管理等问题。本文介绍了“Logtail + 日志服务 + 生态”架构,介绍了:Logtail客户端在Kubernetes日志采集场景下的优势;日志服务作为基础设施一站式解决实时读写、HTAP两大日志强需求;日志服务数据的开放性以及与云产品、开源社区相结合,在实时计算、可视化、采集上为用户提供的丰富选择。

Kubernetes日志处理的趋势与挑战

Kubernetes的serveless化

Kubernetes容器技术促进了技术栈的去耦合,通过引入栈的分层使得开发者可以更加关注自身的应用程序和业务场景。从Kubernetes本身来看,这个技术解耦也在更进一步发展,容器化的一个发展的趋势是:这些容器都将会在无服务器的基础设施上运行。

谈到基础设施,首先可以联想到云,目前在AWS、阿里云、Azure的云上都提供了无服务器化的Kubernetes服务。在serverless Kubernetes上,我们将不再关心集群与机器,只需要声明容器的镜像、CPU、内存、对外服务方式就可以启动应用。


如上图,左右两边分别是经典Kubernetes、serverless Kubernetes的形态。在从左向右发展的过程中,日志采集也变得复杂:

  • 在一个Kubernetes node上,可能会运行更大规模量级的pod,每个pod上都可能有日志或监控指标采集需求,意味着单node上的日志量会更大。
  • 一个Kubernetes node上可能会运行更多种类的pod,日志采集来源变得多样化,各类日志的管理、打标需求越来越迫切。

日志实时性需求越来越强

首先要强调的是,并非所有日志都需要实时处理,当前很多"T+1"时效的日志交付依然非常重要,比如:做BI可能天级别延迟足够,ctr预估可能1小时延迟的日志也可以。

但是,在有些场景下,秒级或更高时效性的日志是必备前提条件,下图横坐标从左到右的对比展示了数据实时性对于决策的重要性。


举两个场景来谈一下实时日志对于决策的重要性:

  • 告警处理。搞devops同学都深有体会,线上问题越早发现、越早处理我们就可以更淡定,处理时间拖得久了故障就可能跟着升级。实时日志帮助我们更快发现系统的异常指标,触发应急处理流程。
  • AIOps。目前已经有一些算法基于日志做异常点检测、趋势预测:根据日志的pattern变化态势发现正常和异常情况下各类型日志出现的分布;针对IT业务系统,给定参数因子、变量对诸如硬盘故障等问题进行建模,加以实时日志来实现故障事件预警。

日志的集中式存储

日志来源有很多,常见的有:文件,数据库audit log,网络数据包等等。并且,针对同一份数据,对于不同的使用者(例如:开发、运维、运营等)、不同的用途(例如:告警、数据清洗、实时检索、批量计算等),存在使用多种方式重复消费日志数据的情况。

在日志数据的系统集成上,从数据源到存储节点再到计算节点,可以定义为一个pipeline。如下图,从上到下的变化是:日志处理正在从O(N^2) pipelines向O(N) pipelines演进。


在过去,各类日志用特定的方式来存储,采集到计算链路不具被通用和复用条件,pipeline非常复杂,数据存储也可能重复冗余。当前日志数据集成上,通过依赖一个中枢(Hub)来简化日志架构的复杂度、优化存储利用率。这个基础设施级别的Hub非常重要,需要支持实时pub/sub,能够处理高并发的写入、读取请求,提供海量的存储空间。

Kubernetes日志采集方案的演进

前面一节总结了Kubernetes日志处理上的趋势,那么家下来会盘点一下Kubernetes上几种常见日志采集的做法。

命令行工具

Kubernetes集群上要看日志,最基础的做法就是登机器,运行kubectl logs就可以看到容器写出的stdout/stderr。


基础的方案没法满足更多需求:

  • 只支持标准输出
  • 数据不能持久化
  • 除了看做不了别的事

节点日志文件落盘

在Kubernetes node维度去处理日志,docker engine将容器的stdout/stderr重定向到logdriver,并且在logdriver上可以配置多种形式去持久化日志,比如以json格式保存文件到本地存储。

和kubectl命令行相比,更进一步是把日志做到了本地化存储。可以用grep/awk这些Linux工具去分析日志文件内容。


这个方案相当于回到了物理机时代,但仍然存在很多问题没有解决:

  • 基于docker engine和logdriver,除了默认的标准输出,不支持应用程序的日志
  • 日志文件rotate多次或者Kubernetes node被驱逐后数据会丢失
  • 没法跟开源社区、云上的数据分析工具集成

基于这个方案的一个进化版本是在node上部署日志采集客户端,将日志上传到中心化日志存储的设施上去。目前这也是推荐的模式,会在下一节再做介绍。

sidecar模式日志客户端采集

一种伴生模式,在一个pod内,除了业务容器外,还有一个日志客户端容器。这个日志客户端容器负责采集pod内容器的标准输出、文件、metric数据上报服务端。


这个方案解决了日志持久化存储等基本的功能需求,但两个地方有待提升:

  • 一个节点上如果运行了N个pod,就意味着会同时运行着N个日志客户端,造成CPU、内存、端口等资源的浪费。
  • Kubernetes下需要为每个pod单独进行采集配置(采集日志目录,采集规则,存储目标等),不易维护。

日志直写

直写方案一般是通过修改应用程序本身来实现,在程序内部组织几条日志,然后调用类似HTTP API将数据发送到日志存储后端。


带来的好处是:日志格式可以按需DIY,日志源和目标的路由可以任意配置。

也可以看到使用上的限制:

  • 侵入代码会对业务改造有直接的依赖,推动业务改造一般比较漫长。
  • 应用程序在发数据到远端遇到异常(比如网络抖动,接收服务端内部错误)时,需要在有限内存中缓存数据做重试,最终还是有概率造成数据丢失。

Kubernetes日志处理架构

来自社区的架构

目前见到比较多的架构中,采集工作通过每个Kubernetes node上安装一个日志客户端完成:

  • Kubernetes官方推荐的是treasure data公司开源的fluentd,它的性能现、插件丰富度比较均衡。
  • 社区有也不少在使用elastic公司开源的beats系列,性能不错,插件支持略少一些。针对一种数据需要部署特定的客户端程序,比如文本文件通过filebeats来采集。
  • 也有些架构在使用logstash,ETL支持非常丰富,但是JRuby实现导致性能很差。


日志客户端把数据格式化好之后用指定协议上传到存储端,常见的选择有Kafka。Kafka支持实时订阅、重复消费,后期可以再根据业务需要把数据同步到其它系统去,比如:业务日志到Elastic Search做关键词查询,结合Kibana做日志可视化分析;金融场景日志要长期留存,可以选择投递Kafka数据到AWS S3这样的高性价比存储上。

这个架构看起来简洁有效,但在Kubernetes下距离完美还有些细节问题要解决:

  • 首先,这是一个标准的节点级采集方案,Kubernetes下fluentd等客户端的程序部署、采集配置管理是个难题,在日志采集路由、数据打标、客户端配置等问题没有针对性优化。
  • 其次,在日志的消费上,虽然Kafka的软件生态足够丰富,但是仍然需要专业人员来维护,要做业务规划、考虑机器水位、处理硬件损坏。如果要查询分析日志,还需要有对Elastic Search系统有足够了解。我们知道在PB级数据场景下,分布式系统的性能、运维问题开始凸显,而驾驭这些开源系统需要很强的专业能力。

日志服务的Kubernetes日志架构实践

我们提出基于阿里云日志服务的Kubernetes日志处理架构,用以补充社区的方案,来尝试解决Kubernetes场景下日志处理的一些细节体验问题。这个架构可以总结为:“Logtail + 日志服务 + 生态”。


首先,Logtail是日志服务的数据采集客户端,针对Kubernetes场景下的一些痛点做了针对性设计。也是按照Kubernetes官方建议的方式,在每个node上只部署一个Logtail客户端,负责这个node上所有的pod日志采集。

其次,针对关键词搜索和SQL统计这两个基本的日志需求:日志服务提供了基础的LogHub功能,支持数据的实时写入、订阅;在LogHub存储的基础上,可以选择开启数据的索引分析功能,开启索引后可以支持日志关键词查询以及SQL语法分析。

最后,日志服务的数据是开放的。索引数据可以通过JDBC协议与第三方系统对接,SQL查询结果与诸如阿里云DataV、开源社区的Grafana系统很方便地集成;日志服务的高吞吐的实时读写能力支撑了与流计算系统的对接,spark streaming、blink、jstorm等流计算系统上都有connector支持;用户还可以通过全托管的投递功能把数据写入到阿里云的对象存储OSS,投递支持行存(csv、json)、列存(parquet)格式,这些数据可以用作长期低成本备份,或者是通过“OSS存储+E-MapReduce计算”架构来实现数据仓库。

日志服务的优势

从四个点上来描述日志服务的特点:

  • 在可靠性和稳定性上,它支撑了阿里集团和蚂蚁金服多次双十一和双十二的大促。
  • 在功能上一站式覆盖了Kafka + ElasticSearch大部分场景。
  • 作为云上的基础设施可以方便地实现弹性伸缩,对于用户来说,大促时不需要操心买机器扩容、每天坏上数十个盘需要维修等问题。
  • 日志服务也同样具备云的0预付成本、按需付费的特点,并且目前每月有500MB的免费额度。


回顾第一节中提到的Kubernetes日志处理的趋势与挑战,这里总结了日志服务的三个优势:

  • 作为日志基础设施,解决了各种日志数据集中化存储问题。
  • 服务化的产品带给用户更多的易用性,与Kubernetes在serverless的目标上也是契合的。
  • 功能上同时满足实时读写、HTAP需求,简化了日志处理的流程与架构。

日志服务结合社区力量进行Kubernetes日志分析

Kubernetes源自社区,使用开源软件进行Kubernetes日志的处理也是一些场景下的正确选择。

日志服务保证数据的开放性,与开源社区在采集、计算、可视化等方面进行对接,帮助用户享受到社区技术成果。


如下图,举一个简单的例子:使用流计算引擎flink实时消费日志服务的日志库数据,源日志库的shard并发与flink task实现动态负载均衡,在完成与MySQL的meta完成数据join加工后,再通过connector流式写入另一个日志服务日志库做可视化查询。


Logtail在Kubernetes日志采集场景下的设计

在本文第二节我们回顾了Kubernetes日志采集方案演进过程中遇到的问题,第三节介绍了基于阿里云日志服务的功能、生态。在这一节会重点对Logtail采集端的设计和优化工作做一些介绍,细数Logtail如何解决Kubernetes日志采集上的痛点。

Kubernetes采集的难点

  • 采集目标多样化

    • 容器stdout/stderr
    • 容器应用日志
    • 宿主机日志
    • 开放协议:Syslog、HTTP等
  • 采集可靠性

    • 性能上需要满足单node上大流量日志场景,同时兼顾采集的实时性
    • 解决容器日志易失性问题
    • 在各种情况下尽量保证采集数据的完整性
  • 动态伸缩带来的挑战

    • 容器扩、缩容对自动发现的要求
    • 降低Kubernetes部署的复杂度
  • 采集配置易用性

    • 采集配置怎么部署、管理
    • 不同用途的pod日志需要分门别类存储,数据路由怎么去管理

Logtail高可靠采集

Logtail支持至少at-least-once采集的语义保证,通过文件和内存两种级别的checkpoint机制来保证在容器重启场景下的断点续传。

日志采集过程中可能遇到各种各样的来自系统或用户配置的错误,例如日志格式化解析出错时我们需要及时调整解析规则。Logtail提供了采集监控功能,可以将异常和统计信息上报日志库并支持查询、告警。

优化计算性能解决单节点大规模日志采集问题,Logtail在不做日志字段格式化的情况(singleline模式)下做到单cpu核100MB/s左右的处理性能。针对网络发送的慢IO操作,客户端将多条日志batch commit到服务端做持久化,兼顾了采集的实时性与高吞吐能力。

在阿里集团内部,Logtail目前有百万级规模的客户端部署,稳定性是不错的。

丰富的数据源支持

应对Kubernetes环境下复杂多样的采集需求,Logtail在采集源头上可以支持:stdout/stderr,容器、宿主机日志文件,syslog、lumberjack等开放协议数据采集。

将一条日志按照语义切分为多个字段就可以得到多个key-value对,由此将一条日志映射到table模型上,这个工作使得在接下来的日志分析过程中事半功倍。Logtail支持以下一些日志格式化方式:

  • 多行解析。比如Java stack trace日志是由多个自然行组成的,通过行首正则表达式的设置来实现日志按逻辑行切分。
  • 自描述解析。支持csv、json等格式,自动提取出日志字段。
  • 通过正则、自定义插件方式满足更多特定需求。
  • 对于一些典型的日志提供内置解析规则。比如,用户只需要在web控制台上选择日志类别是Nginx访问日志,Logtail就可以自动把一条访问日志按照Nginx的log format配置抽取出client_ip、uri等等字段。

应对节点级容器动态伸缩


容器天生会做常态化扩容、缩容,新扩容的容器日志需要及时被采集否则就会丢失,这要求客户端有能力动态感知到采集源,且部署、配置需要做到足够的易用性。Logtail从以下两个维度来解决数据采集的完整性问题:

  • 部署

    • 通过DaemonSet方式来快速部署Logtail到一个Kubernetes node上,一条指令就可以完成,与K8S应用发布集成也很方便。
    • Logtail客户端部署到node上以后,通过domain socket与docker engine通信来处理该节点上的容器动态采集。增量扫描可以及时地发现node上的容器变化,再加上定期全量扫面机制来保证不会丢失掉任何一个容器更改事件,这个双重保障的设计使得在客户端上可以及时、完整发现候选的监控目标。
  • 采集配置管理

    • Logtail从设计之初就选择了服务端集中式采集配置管理,保证采集指令可以从服务端更高效地传达给客户端。这个配置管理可以抽象为"机器组+采集配置"模型,对于一个采集配置,在机器组内的Logtail实例可以即时获取到机器组上所关联的采集配置,去开启采集任务。
    • 针对Kubernetes场景,Logtail设计了自定义标识方式来管理机器。一类pod可以声明一个固定的机器标识,Logtail使用这个机器标识向服务端汇报心跳,同时机器组使用这个自定义标识来管理Logtail实例。当Kubernetes节点扩容时,Logtail上报pod对应的自定义机器标识到服务端,服务端就会把这个机器组上的挂载的采集配置下发给Logtail。目前在开源采集客户端上,常见的做法是使用机器ip或hostname来标识客户端,这样在容器伸缩时,需要及时去增删机器组内的机器ip或hostname,否则就会导致数据采集的缺失,需要复杂的扩容流程保证。

解决采集配置管理难题

Logtail提供两种采集配置的管理方式,用户根据自己的喜好任选来操作:

  • CRD。与Kubernetes生态深度集成,通过在客户端上事件监听可以联动创建日志服务上的日志库、采集配置、机器组等资源。
  • WEB控制台。上手快,可视化方式来配置日志格式化解析规则,通过wizard完成采集配置与机器组的关联。用户只需要按照习惯来设置一个容器的日志目录,Logtail在上开启采集时会自动渲染成宿主机上的实际日志目录。

我们将日志从源到目标(日志库)定义为一个采集路由。使用传统方案实现个性化采集路由功能非常麻烦,需要在客户端本地配置,每个pod容器写死这个采集路由,对于容器部署、管理会有强依赖。Logtail解决这个问题的突破点是对环境变量的应用,Kubernetes的env是由多个key-value组成,在部署容器时可以进行env设置。Logtail的采集配置中设计了IncludeEnv和ExcludeEnv配置项,用于加入或排除采集源。在下面的图中,pod业务容器启动时设置log_type环境变量,同时Logtail采集配置中定义了IncludeEnv: log_type=nginx_access_log,来指定收集nginx类用途的pod日志到特定日志库。


所有在Kubernetes上采集到的数据,Logtail都自动进行了pod/namesapce/contanier/image维度的打标,方便后续的数据分析。

日志上下文查询的设计

上下文查询是指:给定一条日志,查看该日志在原机器、文件位置的上一条或下一条日志,类似于Linux上的grep -A -B

在devops等一些场景下,逻辑性异常需要这个时序来辅助定位,有了上下文查看功能会事半功倍。然后在分布式系统下,在源和目标上都很难保证原先的日志顺序:

  • 在采集客户端层面,Kubernetes可能产生大量日志,日志采集软件需要利用机器的多个cpu核心解析、预处理日志,并通过多线程并发或者单线程异步回调的方式处理网络发送的慢IO问题。这使得日志数据不能按照机器上的事件产生顺序依次到达服务端。
  • 在分布式系统的服务端层面,由于水平扩展的多机负载均衡架构,使得同一客户端机器的日志会分散在多台存储节点上。在分散存储的日志基础上再恢复最初的顺序是困难的。

传统上下文查询方案,一般是根据日志到达服务端时间、日志业务时间字段做两次排序。这在大数据场景下存在:排序性能问题、时间精度不足问题,无法真实还原事件的真实时序。

Logtail与日志服务(关键词查询功能)相结合来解决这个问题:

一个容器文件的日志在采集上传时,其数据包是由一批的多条日志组成,多条日志对应特定文件的一个block,比如512KB。在这一个数据包的多条日志是按照源文件的日志序排列,也就意味着某日志的下一条可能是在同一个数据包里也可能在下一个数据包里。

Logtail在采集时会给这个数据包设置唯一的日志来源sourceId,并在上传的数据包里设置包自增Id,叫做packageID。每个package内,任意一条日志拥有包内的位移offset。

虽然数据包在服务端后存储可能是无序状态,但日志服务有索引可以去精确seek指定sourceId和packageId的数据包。

当我们指定容器A的序号2日志(source_id:A,package_id:N,offset:M)查看其下文时,先判断日志在当前数据包的offset是否为数据包的末尾(包的日志条数定义为L,末尾的offset为L-1):如果offset M小于(L-1),则说明它的下一条日志位置是:source_id:A,package_id:N,offset:M+1;而如果当前日志是数据包的最后一条,则其下一条日志的位置是:source_id:A,package_id:N+1,offset:0。


在大部分场景下,利用关键词随机查询获取到的一个package,可以支持当前包长度L次数的上下文翻页,在提升查询性能同时也大大降低的后台服务随机IO的次数。

原文链接

本文为云栖社区原创内容,未经允许不得转载。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/521508.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ 添加用户(入门试炼_第2篇)

文章目录一、登录二、添加用户和角色2.1. 用户角色介绍2.2. 用户和角色分配2.3. 创建Virtual Hosts一、登录 二、添加用户和角色 2.1. 用户角色介绍 1、超级管理员(administrator) 可登陆管理控制台,可查看所有的信息,并且可以对用户,策略(…

如何查看一个组件的 classid是多少_如何查看iphone电池使用次数?6s电池容量多少需要更换?...

手机用久了之后,总感觉电池特别不耐用,特别是到了冬天,我相信很多人都会有种感觉,就是手机电池也越来越不耐用,待机时间变短,一天甚至需要三充。手机的电池确实和温度有关,但在使用一段时间后&a…

SLB访问日志分析:基于客户端来源和HTTP状态码的实践

摘要: 阿里云负载均衡SLB可以对多台云服务器(ECS)进行流量分发,支持TCP的四层负载均衡和基于HTTP/HTTPS的七层负载均衡。使用SLB可以降低单台ECS异常时对业务的冲击,提升系统可用性。同时,结合弹性伸缩服务…

android选择多个文件_一分钟合并多个Excel、PDF文件,3种方法任你选择,好用到没朋友...

一分钟合并多个Excel、PDF文件,3种方法任你选择,好用到没朋友前情提要:Excel、PDF多个文件怎样合并成一个文件?需求场景:PDF文件合并当一份完成的PDF资料分为很多份的时候,我们怎样将他们合并起来呢&#x…

Spring 常犯的十大错误,打死都不要犯!

戳蓝字“CSDN云计算”关注我们哦! 作者 | Toni Kukurin责编 | 刘丹错误一:太过关注底层我们正在解决这个常见错误,是因为 “非我所创” 综合症在软件开发领域很是常见。症状包括经常重写一些常见的代码,很多开发人员都有这种症状…

confluence启动不起来_汽车“一键启动”只用来点火?太浪费!你不知道的还有这3个功能...

说到“一键启动”,相信大多车主都不陌生。在早些年,这个配置只有B级以上的车才会有,而现在普遍都具备了。那这个“一键启动”到底有什么作用呢?只能用来点火和无钥匙启动?不,还有这几点,我们一起…

数据可视化揭晓NBA球星顶薪背后的真相

戳蓝字“CSDN云计算”关注我们哦!作者 | pk哥责编 | 刘丹7月1日凌晨6点,2019年NBA自由市场正式拉开大幕。之后的故事,我们都知道了,很多球员都签了顶薪合同,在我们看来,这是一堆的天文数字。美媒统计了一个…

RabbitMQ的5种队列_简单队列_入门试炼_第4篇

Statement 文章目录一、队列总览1.1. 图示1.2. 说明二、简单队列2.1. 图示2.2. 导入RabbitMQ的客户端依赖2.3. 获取MQ的连接2.4. 生产者发送消息到队列2.5. 管理工具中查看消息2.6. 消费者从队列中获取消息一、队列总览 1.1. 图示 1.2. 说明 说明模式①简单队列②work模式 多…

阿里云操作审计 - 日志安全分析(一)

摘要: 阿里云操作审计ActionTrail审计日志已经与日志服务打通,提供准实时的审计分析、开箱机用的报表功能。本文介绍背景、配置和功能概览。背景安全形式与日志审计伴随着越来越多的企业采用信息化、云计算技术来提高效率与服务质量。针对企业组织的网络…

spark中local模式与cluster模式使用场景_不可不知的Spark调优点

不可不知的Spark调优点​mp.weixin.qq.com在利用Spark处理数据时,如果数据量不大,那么Spark的默认配置基本就能满足实际的业务场景。但是当数据量大的时候,就需要做一定的参数配置调整和优化,以保证业务的安全、稳定的运行。并且在…

命令逐行显示_Linux命令和Shell脚本学习随笔3

一、处理目录创建目录:mkdir Test创建多级目录: mkdir -p Test1/testsub删除目录:rmdir 该命令只允许删除空目录,删除非空命令提示:Directory not empty,如果文件夹下有文件可以配合命令rm进行删除二、查看文件内容命令…

【图解分布式架构】看不懂直接面壁

戳蓝字“CSDN云计算”关注我们哦!作者 | 佚名责编 | 阿秃初始阶段架构初始阶段的小型系统、应用程序、数据库、文件等所有的资源都在一台服务器上。通俗称为LAMP。特征:应用程序、数据库、文件等所有的资源都在一台服务器上。描述:通常服务器…

RabbitMQ的5种队列_Work模式_入门试炼_第5篇

文章目录一、work模式1.1. 图示1.2. 消费者11.3. 消费者21.4. 生产者1.5. 测试二、Work模式的“能者多劳”2.1. 关键配置2.2. 测试:一、work模式 1.1. 图示 一个生产者、2个消费者。 一个消息只能被一个消费者获取。 1.2. 消费者1 package com.gblfy.rabbitmq.w…

阿里云云数据库RDS秒级监控功能解锁,通宵加班找故障将成为过去式

摘要: 每一个奋斗在前线的数据库管理员和运维人员似乎运气都不太好,这些人都绝对经历过的诡异事件就是:逢年过节必出故障,明明眼看着要休假了,又接到故障通知,只好通宵加班找问题。没问题的时候可能大家都不…

阿里云DDoS高防 - 访问与攻击日志实时分析(三)

摘要: 本文介绍了DDoS日志分析功能的日志报表的使用方法。概述本文介绍DDoS日志分析功能的日志报表的使用方法。前提配置刚进入DDoS高防控制台的全量日志下,在界面引导下开通日志服务并授权操作后。就可以给特定的网站启用日志分析功能了。报表界面介绍在…

vue获取输入框得内容_React入坑(四):获取输入框内的内容

方法一:通过event对象信息获取import React from react;class Show extends React.Component {//state 相当于是Vue里面的data state {text: "",//默认初始值 }; hanChange ev > {//onChange 为Change事件,ev是传递的参数 …

学计算机的用surface,11个高效利用Surface处理工作学习任务的方法 - Surface 使用教程...

在 Surface 上捕获屏幕截图同时按下“电源”按钮 “调高音量”按钮来捕获全屏幕的截图,然后即可将其粘贴到文档、电子邮件或应用中。 屏幕截图同时也会保存在“屏幕截图”文件夹中。在网页上做笔记在 Microsoft Edge 中,选择“设置及更多” >“更多工…

RabbitMQ的5种队列_消息确认模式_入门试炼_第6篇

消费者从队列中获取消息,服务端如何知道消息已经被消费呢? 模式1:自动确认 只要消息从队列中获取,无论消费者获取到消息后是否成功消息,都认为是消息已经成功消费。 模式2:手动确认 消费者从队列中获取消息…

5分钟了解什么是真正的深度学习

人工智能(AI)和机器学习(ML)在当下的火热程度我就不多说了,但是真正懂这方面的人又有多少呢?本文将带你了解人工智能和机器学习的基本知识。同时,你也会了解到机器学习中最火的方法——深度学习…