脚本宝典收集整理的这篇文章主要介绍了服务端基本概念和指标,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
这里主要介绍服务端架构工作中的一些常见的概念和指标,在我们部署、上线等运维工作时,方便排查问题,以及交流时的语义一致。
一般在谈论服务和调用关系的时候,我们会使用上游和下游来表示服务间的相关依赖。但是对于上下游的定义,会视情况而定的。
Stack Overflow上有个相同的问题:definITion - Upstream / downstream terminoLOGy used backwards? (E.g. nginx) - Stack Overflow
以下是点赞最多的回答的节选:
Formal definition was added later, in Rfc 2616:
upstream/downstream
Upstream and downstream describe the flow of a message: all messages flow From upstream to downstream.
According to this definition:
中文意思是:
在本文中,我们强调的是服务之间的调用关系,因此是以“请求”的角度来看到,即按照客户端为上游,服务端为下游的说法。
另外,在讨论A服务将数据写入一个消息队列,B服务消费消息队列的信息的这种情况,我们是按照数据的流向来定义上下游,此时,A为上游,B为下游。
扇入/扇出,在百度百科中有比较好的定义:扇出能力_百度百科 (baidu.COM)
在软件设计中,扇入和扇出的概念是指应用程序模块之间的层次调用情况。
按照结构化设计方法,一个应用程序是由多个功能相对独立的模块所组成。
扇入:是指直接调用该模块的上级模块的个数。扇入大表示模块的复用程度高。
扇出:是指该模块直接调用的下级模块的个数。扇出大表示模块的复杂度高,需要控制和协调过多的下级模块;但扇出过小(例如总是1)也不好。扇出过大一般是因为缺乏中间层次,应该适当增加中间层次的模块。扇出太小时可以把下级模块进一步分解成若干个子功能模块,或者合并到它的上级模块中去。
设计良好的软件结构,通常顶层扇出比较大,中间扇出小,底层模块则有大扇入。
在观察一个服务时,我们可以从多种角度去判定。
如果服务的响应变慢,延时增高,我们优先需要查看机器的负载情况。
这两个比较简单,使用常用的top
命令就可以看到。另外使用top -H
可以看到线程级别的占用。以下是top
的结果。
@H_406_78@
这里红色的框表示这个进程的CPU的占用,这个数字表示占用了多少CPU核。在4核的机器上,单个进程的占用可以达到300%+。
蓝色的框表示内存占用,这里是该进程对整个机器的内存的占用情况。
顺便介绍一下每一列的含义:
PID
: 进程编号USER
: 启动该进程的用户名PR
: 进程优先级NI
: nice值,越低表示优先级越高VIRT
: virtual memory,进程使用的虚拟内存总量,单位:kb。VIRT=SWAP+RESRES
: 进程使用的、未被换出的物理内存大小,单位:kb。RES=CODE+DATAShr
: 共享内存大小,单位:kbS
进程状态
D
: 不可中断的睡眠状态R
: 运行S
: 睡眠T
: 跟踪 / 停止Z
: 僵尸进程%CPU
: 上次更新到现在的 CPU 时间占用百分比,100%表示用满单核的资源,4核机器理论上限400%%MEM
: 内存占用百分比TIME+
: 进程使用的 CPU 时间总计,精确到 1/100 秒COMMAND
: 命令名 / 命令行接下来介绍一下我遇见过的一些案例:
这种情况下,一般先对比上线前后的CPU占用,发现新版服务的CPU占用上涨(一般服务都有自己的状态看板)。之后查看服务更新的代码,确定是有新增的功能。
此时,需要评估新增功能对资源的消耗是否符合预期。不符合,则考虑回滚,符合则保持。
这种情况,一般是服务自身内存有Cache数据,服务重启之后所有的Cache情况,此时对于所有的请求,都必须重新请求一次下游。数据的获取和解析需要额外的时间和CPU,以及内存的申请,因此延时上涨。一段时间后,Cache的命中率和重启前一致,延时正常。
这里需要注意的是,服务的Cache清空,导致对下游的请求里一次性增大,有可能会造成下游的雪崩问题。因此一方面下游需要做好应对策略,另一方面,上游的服务也尽量保持小粒度的滚动升级,不要一次性全部升级。
这篇文章有比较详细的介绍:[656]linux查看服务器带宽_周小董-CSDN博客_linux 查看带宽
通过nload
工具(机器不存在的话,可以apt install
安装)可以比较方便的查看网卡的流入流出的流量。
一般对于存放数据的服务,流量大的时候会存在带宽打满的情况。此时服务的CPU可能负载并不高,但是上游的延时或者错误率上涨。这里的带宽包括了单机、交换机等的带宽。
这里我也见过几次带宽导致的问题。
主要的现象是,客户端的调用时间远大于服务端的内部时间。这基本上可以认为是网络传输的问题。有两种可能:
上面的概念是照搬的其他的博客的说法。我在日常工作中,基本上没有遇到过TPS的概念。
对于QPS,由于每个服务都是以集群的方式部署,所以QPS分为整体QPS和单机QPS。我们可以粗略的认为整体QPS=单机QPS x 机器数
。但实际上,由于一致性Hash等策略,每台机器的负载可能不均,这是一些问题排查的干扰项,我们在后续的一致性Hash和Shard的章节具体介绍。
并发数,系统同时能够处理的请求/事务数量。注意,这里只是处理,并不是处理完。
响应时间即完成一次事务所需要的时间。一般从AVG、PCT90、PCT95、PCT99(PCT99可以简称P99)等多个维度去看。有时候也叫Latency。
需要注意的是,时延有服务端和客户端两个视角。一般可以理解: 客户端时延 = 服务端时延 + 网络时延
。
一般其实我其实主要看AVG和PCT99两个指标。一般新上线功能的时候,AVG和P99不应该有大的变化。如果有,则需要分析是否符合预期。
在线上如果出现报警,也可以观察这两个指标。
网络传输需要时间,所以肯定有差异。如果差异较大,考虑是否是数据量太大、带宽不足或跨机房。
客户端设置了超时,提前结束的响应。而服务端继续执行。浪费算力。
正常状态。也可以和历史的时延对照来看。
这种情况,一般是单机/小集群的问题。1%的机器的延时上涨就会影响P99的变化,但对AVG影响较小。
因此可能是小流量的实验或者机器故障。
这种有点反直觉。 一种可能是本身服务超时严重,pct99就等于设置的超时时间。 或者服务端拒绝响应,被拒绝的请求的延时就基本上等于0。而观察的时候没有区分是成功或是失败的响应,就可能出现这种现象。
全量服务变更或者故障,建议高优排查。
顾名思义,表示请求错误的比例。这里的错误有两种: 框架错误和业务错误。
一般框架协议会提供一套错误码机制,比如http的状态码,200表示success等。 同时在框架状态码为success时,接口一般会返回业务状态码,表示业务的执行情况。比如“用户未登录”、“token无效”、“success”等。 通过精细化状态码的含义,可以有效的协助我们有区分性地排查架构和业务问题。
一般就是我们程序运行输出的文本信息。最简单的日志系统就是把日志文件存在在服务所在的机器上。需要排查问题的时候登录到对应的机器,查看日志文件。
常见的有很多日志库,spdlog
,log4cpp
等。在写本文的时候,刚好爆出了log4j
这个日志库的命令注入的bug。
一般一条日志就是一行文本。包含了日期,级别,日志所在文件和行号,具体信息等。可以通过配置来定制。日志级别常见的有Error, Warning, Info, Debug, Trace等。 也有公司会将日志写入ElasticSeArch等引擎,便于问题排查和回溯。
打点也是日志的一种,不同于常规日志的简单的记录功能。打点的数据会被汇总并做聚合分析,常见的打点类型有计数counter,记时timer和存值Store。以及tag,便于按条件过滤。
打点系统一般包括数据采集、聚合、查询、可视化等部分。 相关的开源工具有Prometheus,grafana等,这里我也了解不多。
埋点一般指网页或者客户端的打点日志。比如用户点击了一个视频,在某个新闻停留多长时间,下载了app,充值,点击购物车或者购买商品等。 客户端埋点数据会实时或者定时的上传。(部分数据可能需要广告主等回传) 一般一次完整的交互过程会有一个唯一的trace_id,每一个环节的日志都包含了trace_id。因此通过trace_id对服务端和客户端的日志进行关联,我们就可以还原出一次交互的完整生命周期。 公司可以利用这些数据做用户画像,训练模型,提供更个性化的服务。
更可怕的是,不同的公司会共享这部分数据。比如当在微信搜索某件商品后,打开京东,会给你推荐相关的产品。可见大数据无处不在。还好,相关的政策在不断的提出,相信信息滥用的情况会逐渐好转。
这里有一些服务相关的概念,我平时接触的也很少。仅记录一下。
关于降级,熔断,限流,知乎的这篇文章有比较好的介绍。降级-熔断-限流-傻傻分不清楚 - 知乎 (zhihu.com)
这个概念主要出现在数据流的任务中。比如A服务将数据写入消息队列,B服务消费消息队列。如果B服务处理的过慢,会导致A服务必须降速或停止写入,否则消息队列会挤压大量的任务。 一般情况下B的处理效率会比A高的,因此消息队列一直很空。但当B出现GC,或者依赖的下游抖动时,B的处理效率可能会短时变差,从而对A造成反压,处理不当的话,会反压更上游的服务。
我见到的反压一般都是短时的,通过重启就可以较好的缓解。这里需要保障重启之后的数据状态可以恢复,或者丢弃的任务不影响整体的效果。 如果重启无效,还可以考虑上游做流量降级。甚至直接丢弃当前队列的数据。 故障是随时都会发生的,我们能做的无非是未雨绸缪和择祸从轻。
eBPF是一种让内核可编程的技术。 https://zhuanlan.zhihu.com/p/182344856
比如实时监控主机的内存、CPU、带宽等功能均可以通过该技术来实现。
这里为什么专门记录一下呢,是因为之前有线上问题最终排查是主机上的一个eBPF程序里维护了一个低性能的map结构,占用大量CPU。因此有时候服务的性能并不完全由自己的硬件和程序决定。还存在不知道哪里来的第三方。
这个一般是指设置程序的CPU亲和度。
比如某些嵌入式设备存在不同规格的CPU,在测试性能时可能会出现多次测试的结果差异很大的情况,大概率是执行程序的核心差异导致的。一般使用 taskset
命令。
在服务部署也有类似的问题,目前使用k8s进行服务部署,单个物理机会同时部署多个实例。通过绑核的操作,可以使程序(尽量)在固定的CPU运行,这样在NUMA架构下会更加友好。
本文介绍了许多我们谈论架构时常见的名词,以及比较简单的案例和分析。
由于概念的归类难以统一,因此本文的组织结构也并不严谨。每种专业术语的定义虽然也在网上查了下,仍会存在不准确的情况。 在我的日常工作,暂时还没有因为术语的不对齐而导致的误解,相信本文的介绍总体上还算正确,有问题请及时指正。
至此,本文就结束了。如果想到新的有意思的概念,我会继续在这里补充。
期待早日完成下一篇博客。
以上是脚本宝典为你收集整理的服务端基本概念和指标全部内容,希望文章能够帮你解决服务端基本概念和指标所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。