精华内容
下载资源
问答
  • 度量空间
    千次阅读
    2019-09-20 18:33:35

    度量空间的数学意义

    在数学中,度量空间是个具有距离函数的集合,该距离函数定义集合内所有元素间之距离。此一距离函数被称为集合上的度量。

    度量空间中最符合人们对于现实直观理解的为三维欧几里得空间。事实上,“度量”的概念即是欧几里得距离四个周知的性质之推广。 欧几里得度量定义了两点间之距离为连接这两点的直线段之长度。此外,亦存在其他的度量空间,如椭圆几何与双曲几何,而在球体上以角度量测之距离亦为一度量。 狭义相对论使用双曲几何的双曲面模型,作为速度之度量空间。

    度量空间还能导出开集与闭集之类的拓扑性质,这导致了对更抽象的拓扑空间之研究。

    定义

    度量空间是个有序对 (M,d),这里的 M 是集合而 d 是在 M 上的度量(metric),即为函数 d:M x M -> R ,使得对于任何在M 内的 x、y、z,下列条件均成立:

    1.d(x, y) ≥ 0 (非负性)
    2.d(x, y) = 0 当且仅当 x = y (不可区分者的同一性)
    3.d(x, y) = d(y, x) (对称性)
    4.d(x, z) ≤ d(x, y) + d(y, z) (三角不等式)。
    

    函数 d 亦称为“距离函数”或简称“距离”。 两个位置间之距离可被定义为连接这些位置的最短路径之长度。

    例子

    • 具有由绝对值给出的距离函数 d ( x , y ) = ∣ y − x ∣ {\displaystyle d(x,y)=\vert y-x\vert } d(x,y)=yx 之实数集合,以及更一般性地,具有欧几里得距离之n 维欧氏空间,这些空间均为完备度量空间。具有相关度量的有理数集合也会形成一个度量空间,但不完备。
    • 具有距离函数 d ( x , y ) = ∣ log ⁡ ( y / x ) ∣ {\displaystyle d(x,y)=\vert \log(y/x)\vert } d(x,y)=log(y/x) 的正实数集合为完备度量空间。
    • 双曲平面是个度量空间。
    • 每个赋范向量空间都是度量空间,其度量可定义为 d ( x , y ) = ∥ y − x ∥ {\displaystyle d(x,y)=\lVert y-x\rVert } d(x,y)=yx若此类空间为完备的,则称之为巴拿赫空间。
      • 曼哈顿范数会形成曼哈顿距离。其中,任何两点或向量之间的距离为对应坐标间差距之和。
      • 极大范数会形成切比雪夫距离(或称为棋盘距离), 为国王在棋盘上从x移动到 y 的所需最小步数。
    • 赋范向量空间上的英国铁路度量(亦称为邮局度量或法国铁路度量) 定义为 d ( x , y ) = ∥ x ∥ + ∥ y ∥ , {\displaystyle d(x,y)=\lVert x\rVert +\lVert y\rVert }, d(x,y)=x+y 其中 x 与 y 为不同的点,且 d ( x , x ) = 0 。 {\displaystyle d(x,x)=0}。 d(x,x)=0更一般性地, ∥ . ∥ {\displaystyle \lVert .\rVert } .可用由任意集合 S 映射至非负实数,且 0 至多出现一次的函数f 替代:则集合 S 上的度量可定义为 d ( x , y ) = f ( x ) + f ( y ) {\displaystyle d(x,y)=f(x)+f(y)} d(x,y)=f(x)+f(y),其中 x 与 y 为不同的点,且 d ( x , x ) = 0 {\displaystyle d(x,x)=0} d(x,x)=0 此一度量的名称系用来影射不论旅途(或信件)的终点为何,都会经过伦敦(或巴黎)的情形。

    维基百科有较为全面介绍,本文是作者为了系统地了解度量空间,对具体应用不作详细说明,仅以上述为例。

    开集、闭集、拓扑与收敛性

    **每个度量空间都自然地会是个拓扑空间,因此与一般拓扑空间有关的所有定义及定理也一样适用于所有的度量空间。 **

    对于度量空间M 内的任一点x,可定义中心为 x,半径为r > 0(其中,r 为一实数)的开球

    B ( x ; r ) = { y ∈ M : d ( x , y ) < r } {\displaystyle B(x;r)=\{y\in M:d(x,y)<r\}} B(x;r)={yM:d(x,y)<r} 这些开球会形成M 上拓扑的基,使之成为一个拓扑空间。
    具体来说,M 的子集 U 称之为开放的,若对于每个U 内的 x,存在一个 r > 0,使得 B(x;r) 包含于U。开集的补集为闭集。点 x 的邻域是指M 内包含中心为 x 的某一开球之任何子集。

    开集是指不包含任何自己边界点的集合。或者说,开集包含的任意一点的充分小的邻域都包含在其自身中。

    在拓扑空间中,闭集是指其补集为开集的集合。在一个拓扑空间内,闭集可以定义为一个包含所有其极限点的集合。在完备度量空间中,一个闭集的极限运算是闭合的。

    拓扑空间若可由某个度量空间形成,则称之为可度量化空间。

    度量空间M 内之序列 ( x n ) (x_n) (xn) 称之为可收敛至极限 x ∈ M x\in M xM,当且仅当对于每个 ε > 0 \varepsilon>0 ε>0,均存在一个自然数 N,使得 d ( x n , x ) < ε {\displaystyle d(x_{n},x)<\varepsilon } d(xn,x)<ε,对于所有 n > N。在拓扑空间内也有相对应的收敛之一般定义。

    度量空间M 内的子集 A 是封闭的,当且仅当每个在A 内的序列若可收敛至 M 内的一极限,则该极限在 A 内。

    度量空间的类型

    1. 完备空间

    • 度量空间 M 称之为完备的,若每个柯西序列均收敛于 M 内,亦即:若 d ( x n , x m ) → 0 {\displaystyle d(x_{n},x_{m})\to 0} d(xn,xm)0,其中 n 与 m 各自趋近于无限大,则存在某个 y ∈ M {\displaystyle y\in M} yM,使得 d ( x n , y ) → 0 d(x_{n},y)\to 0 d(xn,y)0
    • 每个欧氏空间都是完备的,而且该空间的每个闭子集也都是完备空间。使用绝对值度量 d ( x , y ) = ∣ x − y ∣ d(x,y) = \vert x - y \vert d(x,y)=xy 的有理数集合则不是完备的。
    • 每个度量空间都有个在同构意义下唯一的完备化空间。该完备化空间是个完备空间,给定之度量空间为其稠密子集。例如,实数是有理数的完备化空间。
    • 若 X 是空间空间 M 内的完备子集,则 X 在 M 内是封闭的。而实际上,一个空间是完备的,当且仅当该空间在任何包含该空间的度量空间内都是封闭的。
    • 每个完备度量空间都是个贝尔空间。

    同构:在抽象代数中,同构指的是一个保持结构的双射。在更一般的范畴论语言中,同构指的是一个态射,且存在另一个态射,使得两者的复合是一个恒等态射。

    2. 有界与完全有界空间

    度量空间 M 被称为有界的,如果存在某个数 r,使得对于所有 M 中的 x 和 y 有 d(x,y) ≤ r。r 最小可能的值称之为 M 的直径。空间 M 称之为预紧致的或完全有界的,如果对于所有 r > 0 存在有限多个半径为 r 的开球,其并集覆盖 M。因为这些球为有限个,所以该空间的直径亦为有限值,从而得出(使用三角不等式)所有完全有界空间都是有界的。但逆命题不成立,因为任何无限集合均可给定其离散度量(上面第一个例子),使得该空间是有界的,但不是完全有界的。

    注意,在讨论实数空间的区间及欧氏空间的区域时,有时会将有界集合指为“有限区间”或“有限区域”。不过,有界性与“有限”之间一般并无关连;有限通常意含着有界,但反之不一定成立。

    3. 紧致空间

    度量空间 M 是紧致的,若每个 M 内的序列均有个子序列,会收敛于 M 内的一点。 这称为序列紧致性,且在度量空间(但不是一般拓扑空间)里,这等价于可数紧致与以开覆盖定义之紧致性等拓扑性质。

    紧致度量空间的例子包括具绝对值度量的闭区间 [0,1]、所有具有限多个点的度量空间,以及康托尔集。每个紧致集合的闭子集也是紧致的。

    一度量空间为紧致的,当且仅当该空间是完备的,且为完全有界的。这即是所谓的海涅-博雷尔定理。须注意,紧致性仅决取于拓扑,而有界性则决取于度量。

    勒贝格数引理表示,对于紧致度量空间 M 内的每个开覆盖,均存在一个“勒贝格数δ,使得每个 M 内直径 < δ 的子集均会被包含于某些覆盖内。

    每个紧致度量空间均为第二可数,且是康托尔集的连续像。(后者由帕维尔·亚历山德罗夫与帕维尔·萨穆伊洛维奇·乌雷松所证得。)

    4. 局部紧致与常态空间

    度量空间M称为局部紧致的,如果每一点都有一个紧致邻域。 欧氏空间为局部紧致的,但无限维巴拿赫空间则不是。

    度量空间M称为常态(proper)的,如果每个闭球都是紧致的。 常态空间是完备且局部紧致的,但局部紧致空间未必是常态的。

    5. 连通性

    度量空间 M 是连通的,若唯一同时开放或封闭的子集只有空集与 M 本身。

    度量空间 M 是路径连通的,若对于 M 内的任两点 x、y,均存在一个连续映射 f  ⁣ : [ 0 , 1 ] → M f\colon [0,1] \to M f:[0,1]M,其中 f(0)=x 且 f(1)=y。每个路径连通空间都是连通的,但反之通常不成立。

    上述性质均有相对的局部定义:局部连通空间与局部路径连通空间。

    单连通空间在某一层面上来说,可说是个没有“洞”的空间。

    6. 可分空间

    一度量空间称之为可分空间,若该空间有可数稠密子集。 典型的例子为实数或任何一个欧氏空间。对于度量空间(但不包括一般拓扑空间)可分性等价于第二可数,亦等价于林德勒夫性质。

    更多相关内容
  • 质量度量

    2021-02-21 20:56:49
    随着技术的进步和软件应用领域的拓展,用户需要更规模、更可靠的软件,此时,软件度量工作显得更为重要了。如果一个组织能够对其生产的产品做出预测和承诺,那么就可以说这个组织是成功的。有效度量的作用在于能够...
  • 度量驱动开发

    2021-03-02 09:47:20
    在这篇文章里,我将分享我的想法和来自于我和DEV(开发)团队一起工作的经验——让度量变得有意义。本文描述的观点来自我在Adform公司任职IT架构师(联系开发团队和运维团队)的工作经验。Adform是一家数字广告公司...
  • 度量驱动的DevOps转型

    2021-02-25 10:00:43
    新的工具链和技术栈的采用进一步降低了DevOps的技术门槛,越来越多的企业纷纷开始自己的DevOps转型之路,然而……本次分享我们将会讨论到:DevOps以及企业DevOps转型的现状为什么我们需要在DevOps转型中强调度量如何...
  • 度量学习现实检查 请参阅 。 基准测试结果: 这个图书馆的好处 高度可配置: 用于有组织的配置 ,使您可以合并,覆盖,交换,应用和删除配置选项。 可定制的: 您自己的损失,矿工,数据集等进行基准测试。 轻松...
  • 基组(如论文中所述),但它很容易修改,因此用户可以根据需要输入自己的基组。 参考 如果您在科学工作中使用此代码,请引用: Y. Shi、A. Bellet 和 F. Sha。 稀疏组合度量学习。 AAAI 人工智能会议 (AAAI),2014 ...
  • 包括ArcFace,CosFace,insightface等各种人脸识别代码,部分都自己训练过,有效
  • 代码度量标准

    2021-05-22 17:40:11
    使用代码度量提高代码质量SourceMonitor1.总体介绍SourceMonitor是一款免费的软件,运行在Windows平台下。它可对多种语言写就的代码进行度量,包括C、C++、C#、Java、VB、Delphi和HTML,并且针对不同的语言,输出...

    使用代码度量提高代码质量

    SourceMonitor

    1.总体介绍

    SourceMonitor是一款免费的软件,运行在Windows平台下。它可对多种语言写就的代码进行度量,包括C、C++、C#、Java、VB、Delphi和HTML,并且针对不同的语言,输出不同的代码度量值。

    像其他代码度量工具一样,SourceMonitor只关注代码,并为编码人员提供及时的反馈,它不是一款项目管理工具,不关注项目实施中从功能分析到设计编码,再到测试这整个过程。

    2.C语言度量值(C Metrics)

    前面讲了那么多,还没提到代码度量的核心内容——度量值。下面以C语言度量值为例,看看SourceMonitor都给我们反馈了哪些信息。

    总行数(Lines):包括空行在内的代码行数;

    语句数目(Statements):在C语言中,语句是以分号结尾的。分支语句if,循环语句for、while,跳转语句goto都被计算在内,预处理语句#include、#define和#undef也被计算在内,对其他的预处理语句则不作计算,在#else和#endif、#elif和#endif之间的语句将被忽略;

    分支语句比例(Percent Branch Statements):该值表示分支语句占语句数目的比例,这里的“分支语句”指的是使程序不顺序执行的语句,包括if、else、for、while和switch;

    注释比例(Percent Lines with Comments):该值指示注释行(包括/*……*/和//……形式的注释)占总行数的比例;

    函数数目(Functions):指示函数的数量;

    平均每个函数包含的语句数目(Average Statements per Function):总的函数语句数目除以函数数目得到该值;

    函数圈复杂度(Function Complexity):圈复杂度指示一个函数可执行路径的数目,以下语句为圈复杂度的值贡献1:if/else/for/while语句,三元运算符语句,if/for/while判断条件中的"&&"或“||”,switch语句,后接break/goto/ return/throw/continue语句的case语句,catch/except语句;

    函数深度(Block Depth):函数深度指示函数中分支嵌套的层数。

    对其他语言,SourceMonitor输出不同的度量值,例如在C++度量值中包括类的数目(Classes),在HTML中包括各个标签的数目(HTML Tags)、超链接数目(Hyperlinks)等。

    3.度量值的呈现样式

    SourceMonitor从几个不同的视图层次,为我们展示以上列举的度量值,包括项目视图、检查点视图和函数视图。

    项目视图(project view)

    235f73ee8c532771126b02c45d72949c.png

    SourceMonitor下建立项目须在一个文件夹下进行,该文件夹下的源码文件可以被分成一个或几个检查点,项目视图下列出了各个检查点的度量值信息。

    检查点视图(checkpoint view)

    866de3c8b4c7ee1c13d50f51194d54ae.png

    检查点视图中列出了某个检查点中包含的各个源代码文件的度量值信息。

    函数视图(method view)

    e27b8b69179b962335c2db9664f4147d.png

    函数视图中展示了某个检查点下,某个源文件中所有函数的度量信息,双击某函数可以跳转到源文件中该函数的相应位置。

    小结

    本文介绍了代码度量工具SourceMonitor的使用以及圈复杂度等相关概念,SourceMonitor帮助编程人员更多地了解自己编写的代码。在我看来,使用代码度量工具的目的在于:了解我们的劳动成果,在代码层面上保证产品的质量;审视、改进自己的代码,提高自身的编程水平。

    标签:语句,函数,代码,视图,标准,SourceMonitor,度量

    来源: https://www.cnblogs.com/klb561/p/14124243.html

    展开全文
  • uom-度量单位-Rust开发

    2021-05-27 18:29:06
    您可以创建自己的系统,也可以使用基于国际数量系统(ISQ)的预先构建的国际单位系统(SI),其中包括许多数量(长度,质量,时间,...),以及用于转换的因子甚至更多的度量单位(米,公里,英尺,英里等)。...
  • RIP的度量

    千次阅读 2021-02-10 11:49:39
    rip的度量值 技术背景 对于动态路由而言,度量值是一个非常重要的概念。 度量值就是指到达目的网络所需的代价或成本。 每种路由协议都定义了路由的度量值,但是它们对度量值的规定可能不尽相同: (1)比如有的路由...

    rip的度量值

    技术背景

    • 对于动态路由而言,度量值是一个非常重要的概念。
    • 度量值就是指到达目的网络所需的代价或成本。
    • 每种路由协议都定义了路由的度量值,但是它们对度量值的规定可能不尽相同:
      (1)比如有的路由协议使用到达目的网络沿途需经过的路由器个数作为路由的度量值(距离矢量路由协议),
      (2)而有的协议则基于链路带宽计算路由度量值(链路状态路由协议)。
    • 度量值的大小将直接影响路由器对到达某个目的网段的路由(或者说路径)的优选:
      (1)比如当一台路由器发现两条路径可以到达同一个目的地(或者说路由器从两个不同的下一跳学习到去往同一个目的网络的路由),并且这两条路由都是通过同一种路由协议发现的,
      (2)那么通常情况下度量值更优的那条路由会被优选,而度量次优的路由则作为备份,只有当最优路由失效时,次优路由才会被使用。
      RIP以跳数(Hop Count)作为路由的度量值,所谓的跳数,就是到达目的网络所需经过的路由器个数,也就是说RIP的度量值需为非负整数,而且跳数越少,路由被认为越优。

    举个例子:
    如下图所示的网络拓扑
    在这里插入图片描述

    • R1到达直连网段1.0.0.0/8的度量值为0。
    • 当RIP更新周期的到来时,它将该条路由从部署了RIP协议的GE0/0/0接口通告出去,在R1所通告的路由更新中,1.0.0.0/8路由携带的度量值为1,也就是说,R1将该条路由的度量值加1后才通告给R2。
    • R2收到R1通告的路由更新后,将1.0.0.0/8路由学习过来,加载到路由表中,并将路由的度量值设置为1,也就是沿用R1所通告的度量值。
    • 然后R2将1.0.0.0/8路由从自己的GE0/0/1接口通告出去,而在R2所通告的路由更新中,该条路由的度量值被设置为2,R2将路由的度量值加1后通告给R3。
    • 最后,R3也能学习到1.0.0.0/8路由,度量值为2。
    度量值分为:接收度量值和发送度量值
       发送度量值仅当接口发送rip路由时才会添加到路由表中(默认为1)
       接收度量值会在接口接收到rip路由之前,把该度量值加入到该路由表上(默认为0)
       
    (可以简述为:路由器在发送路由时要加上度量值,在接收路由时不需要加上度量值。)
    

    RIP使用跳数作为度量值的设定使得路由器能够直观地知道自己距离目的网络的“远近”。在路由优选的过程中,通过比较度量值,RIP会从可选路径中选择一条到达目的网络的最优路径,最优意味这跳数最小。

    示例2

    如下图所示的网络拓扑
    在这里插入图片描述

    • 假设所有路由器都运行了RIP,则R5会将路由5.0.0.0/8通告给R2、R4,通告时路由的度量值设置为1跳。
    • R2在收到这条路由更新后,会把这条路由通告给R1并告知度量值为2跳,那么R1便发现了一条到达5.0.0.0/8的路由。
    • 另一方面,R4从R5学习到5.0.0.0/8路由后会进一步通告给R3,而R3又会将其通告给R1,这样R1又发现了另一条到达5.0.0.0/8的路由。
    • 此刻对于R1而言,有两条路由可以到达5.0.0.0/8,那么R1就会进行最优路由的选择:
      (1)优选规则:拥有更少跳数的路由将被优选并最终被加载到路由表中作为数据转发的依据。
      (2)因此在R1的路由表中,5.0.0.0/8路由的下一跳是R2。

    引入问题

    通过跳数来度量到达目的网络的远近非常简单和直观,但是也存在一个明显的问题。在上文所述的例子中,如果网络链路带宽不一致,RIP的这种度量值的设计就可能导致路径选择不合理。

    如下图所示的网络拓扑:
    在这里插入图片描述
    网络中的链路带宽是不一致的,但是RIP并不关心链路的带宽,它只关心到达目的地沿途需经过的路由器个数,因此即使R1-R3-R4-RS这条路径的沿途链路带宽要比另一条路径高得多,但由于这条路径的跳数更大,因此它将永远不会被Rl选择作为到达5.0.0.0/8的路径(除非另一条路径失效),这显然是不合理的。

    在这种场景中,网络管理员可以通过对RIP路由的度量值进行适当地调整,例如,将低带宽路径的RIP路由的度量值增加一个特定的量,使得其不被目标设备优选,进而影响数据流量的转发路径。

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,本文链接:https://blog.csdn.net/mn3321/article/details/107722158.

    展开全文
  • 文章目录PreActuator 中的度量指标Micrometer 度量库 Pre SpringBoot - 构建监控体系01_使用 Actuator 组件实现及扩展系统监控 我们引入了 Spring Boot Actuator 组件来满足 Spring Boot 应用程序的系统监控功能,...

    在这里插入图片描述


    Pre

    SpringBoot - 构建监控体系01_使用 Actuator 组件实现及扩展系统监控 我们引入了 Spring Boot Actuator 组件来满足 Spring Boot 应用程序的系统监控功能,并重点介绍了如何扩展常见的 Info 和 Health 监控端点的实现方法。

    这一讲我们继续讨论如何扩展 Actuator 端点,但更多关注与度量指标相关的内容。同时,我们还将给出如何创建自定义 Actuator 的实现方法,以便应对默认端点无法满足需求的应用场景。


    Actuator 中的度量指标

    对于系统监控而言,度量是一个很重要的维度。

    在 Spring Boot 2.X 版本中,Actuator 组件主要使用内置的 Micrometer 库实现度量指标的收集和分析。


    Micrometer 度量库

    Micrometer 是一款监控指标的度量类库,为 Java 平台上的性能数据收集提供了一套通用的 API。在应用程序中,我们只使用 Micrometer 提供的通用 API 即可收集度量指标。

    下面我们先来简要介绍 Micrometer 中包含的几个核心概念。

    Meter接口

    首先我们需要介绍的是计量器 Meter,它是一个接口,代表的是需要收集的性能指标数据。关于 Meter 的定义如下:

    public interface Meter extends AutoCloseable {
    
       
        //Meter 的唯一标识,是名称和标签的一种组合
        Id getId();
    
        //一组测量结果
    	Iterable<Measurement> measure();
    
    	//Meter 的类型枚举值
        enum Type {
            COUNTER,
            GAUGE,
            LONG_TASK_TIMER,
            TIMER,
            DISTRIBUTION_SUMMARY,
            OTHER
       }
    }
    
    

    通过上述代码,我们注意到 Meter 中存在一个 Id 对象,该对象的作用是定义 Meter 的名称和标签。从 Type 的枚举值中,我们不难看出 Micrometer 中包含的所有计量器类型。

    接下来我们先说明两个概念。

    • Meter 的名称:对于计量器来说,每个计量器都有自己的名称,而且在创建时它们都可以指定一系列标签。
    • Meter 的标签:标签的作用在于监控系统可以通过这些标签对度量进行分类过滤。

    计量器类型

    在日常开发过程中,常用的计量器类型主要分为计数器 Counter、计量仪 Gauge 和计时器 Timer 这三种。

    • Counter:这个计量器的作用和它的名称一样,就是一个不断递增的累加器,我们可以通过它的 increment 方法实现累加逻辑。

    • Gauge:与 Counter 不同,Gauge 所度量的值并不一定是累加的,我们可以通过它的 gauge 方法指定数值。

    • Timer:这个计量器比较简单,就是用来记录事件的持续时间。


    如何创建这些计量器

    既然我们已经明确了常用的计量器及其使用场景,那么如何创建这些计量器呢?

    在 Micrometer 中,我们提供了一个计量器注册表 MeterRegistry,它主要负责创建和维护各种计量器。关于 MeterRegistry 的创建方法如下代码所示:

    public abstract class MeterRegistry implements AutoCloseable {
    
        protected abstract <T> Gauge newGauge(Meter.Id id, @Nullable T obj, ToDoubleFunction<T> valueFunction);
    
        protected abstract Counter newCounter(Meter.Id id);
    
        protected abstract Timer newTimer(Meter.Id id, DistributionStatisticConfig distributionStatisticConfig, PauseDetector pauseDetector);}
    
    

    以上代码只是创建 Meter 的一种途径,从中我们可以看到 MeterRegistry 针对不同的 Meter 提供了对应的创建方法。

    而创建 Meter 的另一种途径是使用某个 Meter 的具体 builder 方法。以 Counter 为例,它的定义中包含了一个 builder 方法和一个 register 方法,如下代码所示:

    public interface Counter extends Meter {
    
        static Builder builder(String name) {
            return new Builder(name);
    	}
    
        default void increment() {
            increment(1.0);
    	}
    
    	void increment(double amount);
    
    	double count();
    
        @Override
        default Iterable<Measurement> measure() {
            return Collections.singletonList(new Measurement(this::count, Statistic.COUNT));
    
    	}public Counter register(MeterRegistry registry) {
            return registry.counter(new Meter.Id(name, tags, baseUnit, description, Type.COUNTER));
    
        }
    
    }
    
    

    注意到最后的 register 方法就是将当前的 Counter 注册到 MeterRegistry 中,因此我们需要创建一个 Counter。通常,我们会采用如下所示代码进行创建。

    Counter counter = Counter.builder("counter1")
            .tag("tag1", "value1")
            .register(registry);
    
    

    扩展 Metrics 端点

    了解了 Micrometer 框架的基本概念后,接下来我们回到 Spring Boot Actuator,一起来看看它提供的专门针对度量指标管理的 Metrics 端点。

    在 Spring Boot 中,它为我们提供了一个 Metrics 端点用于实现生产级的度量工具。访问 actuator/metrics 端点后,我们将得到如下所示的一系列度量指标。

    在这里插入图片描述
    以上代码中涉及的指标包括常规的系统内存总量、空闲内存数量、处理器数量、系统正常运行时间、堆信息等,如果引用了数据库,也也包含我们引入 JDBC 和 HikariCP 数据源组件之后的数据库连接信息等。

    此时,如果我们想了解某项指标的详细信息,在 actuator/metrics 端点后添加对应指标的名称即可。

    例如我们想了解当前内存的使用情况,就可以通过 actuator/metrics/jvm.memory.used 端点进行获取,如下代码所示。

    在这里插入图片描述


    自定义 Metrics 指标

    前面介绍 Micrometer 时,我们已经提到 Metrics 指标体系中包含支持 Counter 和 Gauge 这两种级别的度量指标。

    通过将 Counter 或 Gauge 注入业务代码中,我们就可以记录自己想要的度量指标。其中,Counter 用来暴露 increment() 方法,而 Gauge 用来提供一个 value() 方法。

    下面我们以 Counter 为例介绍在业务代码中嵌入自定义 Metrics 指标的方法,如下代码所示:

     package com.artisan.admin;
    
    import io.micrometer.core.instrument.Counter;
    import io.micrometer.core.instrument.Metrics;
    import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
    import org.springframework.stereotype.Component;
    
    /**
     * @author 小工匠
     * @version 1.0
     * @description: 
     * @date 2021/5/30 19:16
     * @mark: show me the code , change the world
     */
    @Component
    public class CounterService {
    
        public CounterService() {
            Metrics.addRegistry(new SimpleMeterRegistry());
        }
    
    
    
        public void counter(String name, String... tags) {
            Counter counter = Metrics.counter(name, tags);
            counter.increment();
        }
    }
        
    
    

    在这段代码中,我们构建了一个公共服务 CounterService,并开放了一个 Counter 方法供业务系统进行使用。当然,你也可以自己实现类似的工具类完成对各种计量器的封装。


    另外,Micrometer 还提供了一个 MeterRegistry 工具类供我们创建度量指标。因此,我们也十分推荐使用 MeterRegistry 对各种自定义度量指标的创建过程进行简化

    使用 MeterRegistry

    比如我们希望系统每创建一个客服工单,就对所创建的工单进行计数,并作为系统运行时的一项度量指标,该效果的实现方式如下代码所示:

    @Service
    public class CustomerTicketService {
    
    
        @Autowired
        private MeterRegistry meterRegistry;
    
    
    	public CustomerTicket generateCustomerTicket(Long accountId, String orderNumber) {
       		 CustomerTicket customerTicket = new CustomerTicket();
    
        …
    
            meterRegistry.summary("customerTickets.generated.count").record(1);
            return customerTicket;
    
        }   
    
    }
    
    

    在上述 generateCustomerTicket 方法中,通过 MeterRegistry 我们实现了每次创建 CustomerTicket 时自动添加一个计数的功能。

    而且,MeterRegistry 还提供了一些类工具方法用于创建自定义度量指标。这些类工具方法除了常规的 counter、gauge、timer 等对应具体 Meter 的工具方法之外,还包括上述代码中的 summary 方法,且 Summary 方法返回的是一个 DistributionSummary 对象,关于它的定义如下代码所示:

    public interface DistributionSummary extends Meter, HistogramSupport {
    
     
    
        static Builder builder(String name) {
            return new Builder(name);
        }
    
        //记录数据
        void record(double amount);
    
        //记录操作执行的次数
        long count();
    
        //记录数据的数量
        double totalAmount();
    
    
        //记录数据的平均值
        default double mean() {
            return count() == 0 ? 0 : totalAmount() / count();
        }
    
    
        //记录数据的最大值
    	double max();}
    
    

    因为 DistributionSummary 的作用是记录一系列的事件并对这些事件进行处理,所以在 CustomerTicketService 中添加的meterRegistry.summary("customertickets.generated.count").record(1) 这行代码相当于每次调用 generateCustomerTicket 方法时,我们都会对这次调用进行记录。

    现在访问 actuator/metrics/customertickets.generated.count 端点,我们就能看到如下所示的随着服务调用不断递增的度量信息。

    {
    
         "name":"customertickets.generated.count",
         "measurements":[
             {
                 "statistic":"Count",
                 "value":1
             },
             {
                 "statistic":"Total",
                 "value":19
             }
         ] 
     }
    

    显然,通过 MeterRegistry 实现自定义度量指标的使用方法更加简单。这里,你也可以结合业务需求尝试该类的不同功能。

    接下来我们再来看一个相对比较复杂的使用方式。在 customer-service 中,我们同样希望系统存在一个度量值,该度量值用于记录所有新增的 CustomerTicket 个数,这次的示例代码如下所示:

     @Component
    
    public class CustomerTicketMetrics extends  AbstractRepositoryEventListener<CustomerTicket> {
    
     
        private MeterRegistry meterRegistry;
    
        public CustomerTicketMetrics(MeterRegistry meterRegistry) {
            this.meterRegistry = meterRegistry;
        }
    
     
    
        @Override
        protected void onAfterCreate(CustomerTicket customerTicket) {                 		     meterRegistry.counter("customerTicket.created.count").increment();  
    	}
    
    }
    
    

    首先,这里我们使用了 MeterRegistry 的 Counter 方法初始化一个 counter,然后调用它的 increment 方法增加度量计数(这部分内容我们已经很熟悉了)。

    注意到这里,我们同时还引入了一个 AbstractRepositoryEventListener 抽象类,这个抽象类能够监控 Spring Data 中 Repository 层操作所触发的事件 RepositoryEvent,例如实体创建前后的 BeforeCreateEvent 和 AfterCreateEvent 事件、实体保存前后的 BeforeSaveEvent 和 AfterSaveEvent 事件等。

    针对这些事件,AbstractRepositoryEventListener 能捕捉并调用对应的回调函数。关于 AbstractRepositoryEventListener 类的部分实现如下代码所示:

    public abstract class AbstractRepositoryEventListener<T> implements ApplicationListener<RepositoryEvent> {
    
     
    
        public final void onApplicationEvent(RepositoryEvent event) {Class<?> srcType = event.getSource().getClass();
    
            if (event instanceof BeforeSaveEvent) {
                onBeforeSave((T) event.getSource());
            } else if (event instanceof BeforeCreateEvent) {
                onBeforeCreate((T) event.getSource());
            } else if (event instanceof AfterCreateEvent) {
                onAfterCreate((T) event.getSource());
            } else if (event instanceof AfterSaveEvent) {
                onAfterSave((T) event.getSource());
                  }}
    }
    
    

    在这段代码中,我们可以看到 AbstractRepositoryEventListener 直接实现了 Spring 容器中的 ApplicationListener 监听器接口,并在 onApplicationEvent 方法中根据所传入的事件类型触发了回调函数。

    以案例中的需求场景为例,我们可以在创建 Account 实体之后执行度量操作。也就是说,可以把度量操作的代码放在 onAfterCreate 回调函数中,正如案例代码中所展示那样。

    现在我们执行生成客户工单操作,并访问对应的 Actuator 端点,同样可以看到度量数据在不断上升。


    自定义 Actuator 端点

    在日常开发过程中,扩展现有端点有时并不一定能满足业务需求,而自定义 Spring Boot Actuator 监控端点算是一种更灵活的方法。

    假设我们需要提供一个监控端点以获取当前系统的用户信息和计算机名称,就可以通过一个独立的 MySystemEndPoint 进行实现,如下代码所示

    @Configuration
    @Endpoint(id = "mysystem", enableByDefault=true)
    public class MySystemEndpoint { 
    
     
        @ReadOperation
        public Map<String, Object> getMySystemInfo() {
            Map<String,Object> result= new HashMap<>();
            Map<String, String> map = System.getenv();
            result.put("username",map.get("USERNAME"));
            result.put("computername",map.get("COMPUTERNAME"));
            return result;
        }
    }
    
    

    在这段代码中我们可以看到,MySystemEndpoint 主要通过系统环境变量获取所需监控信息。

    注意,这里我们引入了一个新的注解 @Endpoint,该注解定义如下代码所示:

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Endpoint {
    
     
    
        //端点 id
        String id() default "";
    
        //是否默认启动标志位
        boolean enableByDefault() default true;
    
    }
    
    

    这段代码中的 @Endpoint 注解主要用于设置端点 id 及是否默认启动的标志位。且在案例中,我们指定了 id 为“mysystem”,enableByDefault 标志为 true。

    事实上,在 Actuator 中也存在一批类似 @Endpoint 的端点注解。其中被 @Endpoint 注解的端点可以通过 JMX 和 Web 访问应用程序,对应的被 @JmxEndpoint 注解的端点只能通过 JMX 访问,而被 @WebEndpoint 注解的端点只能通过 Web 访问。

    在示例代码中,我们还看到了一个 @ReadOperation 注解,该注解作用于方法,用于标识读取数据操作

    在 Actuator 中,除了提供 @ReadOperation 注解之外,还提供 @WriteOperation 和 @DeleteOperation 注解,它们分别对应写入操作和删除操作。

    现在,通过访问 http://localhost:8080/actuator/mysystem,我们就能获取如下所示监控信息。

    在这里插入图片描述

    有时为了获取特定的度量信息,我们需要对某个端点传递参数,而 Actuator 专门提供了一个 @Selector 注解标识输入参数,示例代码如下所示:

    @Configuration
    @Endpoint(id = "account", enableByDefault = true)
    public class AccountEndpoint {
    
        @Autowired
        private AccountRepository accountRepository;    
    
    
        @ReadOperation
        public Map<String, Object> getMySystemInfo(@Selector String arg0) {
            Map<String, Object> result = new HashMap<>();
            result.put(accountName, accountRepository.findAccountByAccountName(arg0));
            return result;
        }
    }
    
    

    这段代码的逻辑非常简单,就是根据传入的 accountName 获取用户账户信息。

    这里请注意,通过 @Selector 注解,我们就可以使用http://localhost:8080/actuator/ account/account1 这样的端口地址触发度量操作了。


    小结

    度量是我们观测一个应用程序运行时状态的核心手段。我们介绍了 Spring Boot 中新引入的 Micrometer 度量库,以及该库中提供的各种度量组件。

    同时还基于 Micrometer 中的核心工具类 MeterRegistry 完成了在业务系统中嵌入度量指标的实现过程。最后,我们还简要介绍了如何自定义一个 Actuator 端点的开发方法。

    在这里插入图片描述

    展开全文
  • 那篇论文中讨论了如何将样本投影到一个嵌入空间中,使得相似样本间的距离较近,他学习的是如何投影这个过程,而样本间的距离度量方法是人为设定的,这样的话那个投影过程也就是基于人为设定的度量方法来学习的了。...
  • Q1:度量体系建设的难点有哪些?后来是采取哪些策略解决的? A1:难点:采集哪些数据是有用的?有了数据如何抓结论出来。 Q2:故障解决闭环率,类似这种KPI考核指标,有什么好的方法可以高效推进闭环呢? A2: 分析...
  • 我说CMMI2.0之管理性能和度量数据

    千次阅读 2019-02-12 09:11:50
    它将组织级的、项目级的度量实践,以及统计的和非统计的量化管理都融合到了一个PA中。它合并了CMMI 1.3版本中的MA, QPM等过程域的实践。  本实践域在落地时,需要使用到一些具体的量化技术,如:  基本的量化...
  • RIP之度量

    千次阅读 2020-08-01 08:39:48
    每种路由协议都定义了路由的度量值,但是它们对度量值的规定可能不尽相同: (1)比如有的路由协议使用到达目的网络沿途需经过的路由器个数作为路由的度量值(距离矢量路由协议), (2)而有的协议则基于链路带宽...
  • 度量 度量的理解 度量的重点应该从“控制”转变为“改进”:精益的一个核心理念是持续改进。在理念上,我们希望把度量的重心从“控制”转向“改进”。虽然控制和改进都是对系统采取的干预性措施,“控制”给人造成的...
  • 另外,如果您只是想自己获取文件,则可以直接下载当前的稳定或。 设定 文本度量支持AMD(例如RequireJS),CommonJS(例如Node.js)和直接使用(例如,使用[removed]标签全局加载)加载方法。 您应该几乎可以执行...
  • 度量学习DML之Contrastive Loss及其变种

    千次阅读 2021-12-26 17:20:55
    度量学习的目标: 相似的或者属于同一类的样本提取到的embedding向量之间具有更高的相似度,或者具有更小的空间距离 对于out-of samples的样本,也就是未见过的样本,希望也能提取到有效的embedding,也就是模型的...
  • 转载:快速学习COSMIC软件规模度量方法 – 绿盟科技技术博客 最近与某运营商开展合作项目时,客户需要我方输出一份COSMIC软件规模度量数据用于评估项目预算,由于此前未接触过COSMIC软件规模度量方法,故翻阅相关...
  • 八个经典实用的绩效提升工具 1 、 swot 分析法: ...意义:帮您清晰地把握全局,分析自己在资源方面的优势与劣势,把握环境 提供的机会,防范可能存在的风险与威胁,对我们的成功有非常重要的意义。
  • 这将需要一个Google帐户,但是您无需在自己的计算机上安装任何软件。 对于第一个编码演示,请单击以下链接: : 对于第二个编码演示,请单击以下链接: : 要使用该代码,您需要单击“连接”按钮: 单击此按钮...
  • 或者自己安装: $ gem install string_metric 用法 莱文斯坦距离 Levenshtein Distance 的公共 api 是StringMetric::Levenshtein.distance方法。 选项 :max_distance :它设置计算距离的上限。 可以是Fixnum或...
  • 为了满足特定领域对组件特性的特殊要求,提出了一种基于神经网络的组件质量度量算法。该算法采用了定量度量的方法,为不同特性赋予不同权重,取代了传统度量过程中对...该算法通过机器学习的方法增强了自己度量能力。
  • 该导出程序通过查询具有给定存储桶和前缀的API并基于返回的对象构造度量标准,从而为AWS S3存储桶对象提供度量标准。 我发现通过比较对象的大小/数量随时间的增长,或将上次修改日期与预期值进行比较,可以确保备份...
  • 作者简介:茹炳晟,腾讯T4级专家,腾讯研究院特约研究员,业界知名实战派研发效能和软件质量双领域专家。“软件研发效能度量规范”团体标准的核心编写专家,Certified DevOps Ent...
  • 学习笔记——数据的度量

    千次阅读 2019-07-19 20:42:20
    抽样 概率抽样(随机抽样):可以推断总体 。 ...遵循随机原则进行的抽样,总体中每一个单位都有一定的机会被选入样本。具有随机性,不能有带有主观性。概率抽样与等概率抽样是不同的...谨以此文献给明天的自己
  • 在下午的DevOps分论坛上,来自嘉为蓝鲸的DevOps首席专家邹姝虹发表了主题《如何有效的构建DevOps下的度量体系与相关指标》的专题演讲。 一、为什么企业需要建设度量体系? 1. 度量建设的核心目标 度量建设的核心...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 112,778
精华内容 45,111
关键字:

如何让自己度量大