分类 技术 下的文章

here 文档 here document (LCTT 译注:here 文档又称作 heredoc )不是什么特殊的东西,只是一种 I/O 重定向方式,它告诉 bash shell 从当前源读取输入,直到读取到只有分隔符的行。

redirect output of here document to a text file

这对于向 ftp、cat、echo、ssh 和许多其他有用的 Linux/Unix 命令提供指令很有用。 此功能适用于 bash 也适用于 Bourne、Korn、POSIX 这三种 shell。

here 文档语法

语法是:

command <<EOF
cmd1
cmd2 arg1
EOF

或者允许 shell 脚本中的 here 文档使用 EOF<<- 以自然的方式缩进:

command <<-EOF
  msg1
  msg2 
  $var on line 
EOF

或者

command <<'EOF'
 cmd1
 cmd2 arg1
 $var won't expand as parameter substitution turned off
 by single quoting
EOF

或者 重定向并将其覆盖 到名为 my_output_file.txt 的文件中:

command <<EOF > my_output_file.txt
 mesg1
 msg2
 msg3
 $var on $foo
EOF

重定向并将其追加到名为 my_output_file.txt 的文件中:

command <<EOF >> my_output_file.txt
 mesg1
 msg2
 msg3
 $var on $foo
EOF

示例

以下脚本将所需内容写入名为 /tmp/output.txt 的文件中:

#!/bin/bash
OUT=/tmp/output.txt

echo "Starting my script..."
echo "Doing something..."

cat <<EOF >$OUT
  Status of backup as on $(date)
  Backing up files $HOME and /etc/
EOF

echo "Starting backup using rsync..."

你可以使用cat命令查看/tmp/output.txt文件:

$ cat /tmp/output.txt

示例输出:

 Status of backup as on Thu Nov 16 17:00:21 IST 2017
 Backing up files /home/vivek and /etc/

禁用路径名/参数/变量扩展、命令替换、算术扩展

$HOME 这类变量和像 $(date) 这类命令在脚本中会被解释为替换。 要禁用它,请使用带有 'EOF' 这样带有单引号的形式,如下所示:

#!/bin/bash
OUT=/tmp/output.txt

echo "Starting my script..."
echo "Doing something..."
# No parameter and variable expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word.  
# If any part of word is quoted, the delimiter  is  the  result  of  quote removal  on word, and the lines in the here-document 
# are not expanded. So EOF is quoted as follows
cat <<'EOF' >$OUT
  Status of backup as on $(date)
  Backing up files $HOME and /etc/
EOF

echo "Starting backup using rsync..."

你可以使用 cat 命令查看 /tmp/output.txt 文件:

$ cat /tmp/output.txt

示例输出:

 Status of backup as on $(date)
 Backing up files $HOME and /etc/

关于 tee 命令的使用

语法是:

tee /tmp/filename <<EOF >/dev/null
line 1
line 2
line 3
$(cmd)
$var on $foo
EOF

或者通过在单引号中引用 EOF 来禁用变量替换和命令替换:

tee /tmp/filename <<'EOF' >/dev/null
line 1
line 2
line 3
$(cmd)
$var on $foo
EOF

这是我更新的脚本:

#!/bin/bash
OUT=/tmp/output.txt

echo "Starting my script..."
echo "Doing something..."

tee $OUT <<EOF >/dev/null
  Status of backup as on $(date)
  Backing up files $HOME and /etc/
EOF

echo "Starting backup using rsync..."

关于内存 here 文档的使用

这是我更新的脚本:

#!/bin/bash
OUT=/tmp/output.txt

## in memory here docs 
## thanks https://twitter.com/freebsdfrau
exec 9<<EOF
  Status of backup as on $(date)
  Backing up files $HOME and /etc/
EOF

## continue
echo "Starting my script..."
echo "Doing something..."

## do it
cat <&9 >$OUT

echo "Starting backup using rsync..."

via: https://www.cyberciti.biz/faq/using-heredoc-rediection-in-bash-shell-script-to-write-to-file/

作者:Vivek Gite 译者:Flowsnow 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

零配置工具简化了信息收集,例如在某个命名空间中运行了多少个 pod。

最近我在纽约的 O'Reilly Velocity 就 Kubernetes 应用故障排除的主题发表了演讲,并且在积极的反馈和讨论的推动下,我决定重新审视这个领域的工具。结果,除了 kubernetes-incubator/spartakuskubernetes/kube-state-metrics 之外,我们还没有太多的轻量级工具来收集资源统计数据(例如命名空间中的 pod 或服务的数量)。所以,我在回家的路上开始编写一个小工具 —— 创造性地命名为 krs,它是 Kubernetes Resource Stats 的简称 ,它允许你收集这些统计数据。

你可以通过两种方式使用 mhausenblas/krs

  • 直接在命令行(有 Linux、Windows 和 MacOS 的二进制文件),以及
  • 在集群中使用 launch.sh 脚本部署,该脚本动态创建适当的基于角色的访问控制(RBAC) 权限。

提醒你,它还在早期,并且还在开发中。但是,krs 的 0.1 版本提供以下功能:

  • 在每个命名空间的基础上,它定期收集资源统计信息(支持 pod、部署和服务)。
  • 它以 OpenMetrics 格式公开这些统计。
  • 它可以直接通过二进制文件使用,也可以在包含所有依赖项的容器化设置中使用。

目前,你需要安装并配置 kubectl,因为 krs 依赖于执行 kubectl get all 命令来收集统计数据。(另一方面,谁会使用 Kubernetes 但没有安装 kubectl 呢?)

使用 krs 很简单。下载适合你平台的二进制文件,并按如下方式执行:

$ krs thenamespacetowatch
# HELP pods Number of pods in any state, for example running
# TYPE pods gauge
pods{namespace="thenamespacetowatch"} 13
# HELP deployments Number of deployments
# TYPE deployments gauge
deployments{namespace="thenamespacetowatch"} 6
# HELP services Number of services
# TYPE services gauge
services{namespace="thenamespacetowatch"} 4

这将在前台启动 krs,从名称空间 thenamespacetowatch 收集资源统计信息,并分别在标准输出中以 OpenMetrics 格式输出它们,以供你进一步处理。

 title=

krs 实战截屏

也许你会问,Michael,为什么它不能做一些有用的事(例如将指标存储在 S3 中)?因为 Unix 哲学

对于那些想知道他们是否可以直接使用 Prometheus 或 kubernetes/kube-state-metrics 来完成这项任务的人:是的,你可以,为什么不行呢? krs 的重点是作为已有工具的轻量级且易于使用的替代品 —— 甚至可能在某些方面略微互补。

本文最初发表在 Medium 的 ITNext 上,并获得授权转载。


via: https://opensource.com/article/18/11/kubernetes-resource-statistics

作者:Michael Hausenblas 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

不可变性可以帮助我们更好地理解我们的代码。下面我将讲述如何在不牺牲性能的条件下来实现它。

在这个由两篇文章构成的系列中,我将讨论如何将函数式编程方法论中的思想引入至 Python 中,来充分发挥这两个领域的优势。

本文(也就是第一篇文章)中,我们将探讨不可变数据结构的优势。第二部分会探讨如何在 toolz 库的帮助下,用 Python 实现高层次的函数式编程理念。

为什么要用函数式编程?因为变化的东西更难推理。如果你已经确信变化会带来麻烦,那很棒。如果你还没有被说服,在文章结束时,你会明白这一点的。

我们从思考正方形和矩形开始。如果我们抛开实现细节,单从接口的角度考虑,正方形是矩形的子类吗?

子类的定义基于里氏替换原则。一个子类必须能够完成超类所做的一切。

如何为矩形定义接口?

from zope.interface import Interface

class IRectangle(Interface):
    def get_length(self):
        """正方形能做到"""
    def get_width(self):
        """正方形能做到"""
    def set_dimensions(self, length, width):
        """啊哦"""

如果我们这么定义,那正方形就不能成为矩形的子类:如果长度和宽度不等,它就无法对 set_dimensions 方法做出响应。

另一种方法,是选择将矩形做成不可变对象。

class IRectangle(Interface):
    def get_length(self):
        """正方形能做到"""
    def get_width(self):
        """正方形能做到"""
    def with_dimensions(self, length, width):
        """返回一个新矩形"""

现在,我们可以将正方形视为矩形了。在调用 with_dimensions 时,它可以返回一个新的矩形(它不一定是个正方形),但它本身并没有变,依然是一个正方形。

这似乎像是个学术问题 —— 直到我们认为正方形和矩形可以在某种意义上看做一个容器的侧面。在理解了这个例子以后,我们会处理更传统的容器,以解决更现实的案例。比如,考虑一下随机存取数组。

我们现在有 ISquareIRectangle,而且 ISequereIRectangle 的子类。

我们希望把矩形放进随机存取数组中:

class IArrayOfRectangles(Interface):
    def get_element(self, i):
        """返回一个矩形"""
    def set_element(self, i, rectangle):
        """'rectangle' 可以是任意 IRectangle 对象"""

我们同样希望把正方形放进随机存取数组:

class IArrayOfSquare(Interface):
    def get_element(self, i):
        """返回一个正方形"""
    def set_element(self, i, square):
        """'square' 可以是任意 ISquare 对象"""

尽管 ISquareIRectangle 的子集,但没有任何一个数组可以同时实现 IArrayOfSquareIArrayOfRectangle.

为什么不能呢?假设 bucket 实现了这两个类的功能。

>>> rectangle = make_rectangle(3, 4)
>>> bucket.set_element(0, rectangle) # 这是 IArrayOfRectangle 中的合法操作
>>> thing = bucket.get_element(0) # IArrayOfSquare 要求 thing 必须是一个正方形
>>> assert thing.height == thing.width
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

无法同时实现这两类功能,意味着这两个类无法构成继承关系,即使 ISquareIRectangle 的子类。问题来自 set_element 方法:如果我们实现一个只读的数组,那 IArrayOfSquare 就可以是 IArrayOfRectangle 的子类了。

在可变的 IRectangle 和可变的 IArrayOf* 接口中,可变性都会使得对类型和子类的思考变得更加困难 —— 放弃变换的能力,意味着我们的直觉所希望的类型间关系能够成立了。

可变性还会带来作用域方面的影响。当一个共享对象被两个地方的代码改变时,这种问题就会发生。一个经典的例子是两个线程同时改变一个共享变量。不过在单线程程序中,即使在两个相距很远的地方共享一个变量,也是一件简单的事情。从 Python 语言的角度来思考,大多数对象都可以从很多位置来访问:比如在模块全局变量,或在一个堆栈跟踪中,或者以类属性来访问。

如果我们无法对共享做出约束,那我们可能要考虑对可变性来进行约束了。

这是一个不可变的矩形,它利用了 attr 库:

@attr.s(frozen=True)
class Rectange(object):
    length = attr.ib()
    width = attr.ib()
    @classmethod
    def with_dimensions(cls, length, width):
        return cls(length, width)

这是一个正方形:

@attr.s(frozen=True)
class Square(object):
    side = attr.ib()
    @classmethod
    def with_dimensions(cls, length, width):
        return Rectangle(length, width)

使用 frozen 参数,我们可以轻易地使 attrs 创建的类成为不可变类型。正确实现 __setitem__ 方法的工作都交给别人完成了,对我们是不可见的。

修改对象仍然很容易;但是我们不可能改变它的本质。

too_long = Rectangle(100, 4)
reasonable = attr.evolve(too_long, length=10)

Pyrsistent 能让我们拥有不可变的容器。

# 由整数构成的向量
a = pyrsistent.v(1, 2, 3)
# 并非由整数构成的向量
b = a.set(1, "hello")

尽管 b 不是一个由整数构成的向量,但没有什么能够改变 a 只由整数构成的性质。

如果 a 有一百万个元素呢?b 会将其中的 999999 个元素复制一遍吗?Pyrsistent 具有“大 O”性能保证:所有操作的时间复杂度都是 O(log n). 它还带有一个可选的 C 语言扩展,以在“大 O”性能之上进行提升。

修改嵌套对象时,会涉及到“变换器”的概念:

blog = pyrsistent.m(
    title="My blog",
    links=pyrsistent.v("github", "twitter"),
    posts=pyrsistent.v(
        pyrsistent.m(title="no updates",
                     content="I'm busy"),
        pyrsistent.m(title="still no updates",
                     content="still busy")))
new_blog = blog.transform(["posts", 1, "content"],
                          "pretty busy")

new_blog 现在将是如下对象的不可变等价物:

{'links': ['github', 'twitter'],
 'posts': [{'content': "I'm busy",
            'title': 'no updates'},
           {'content': 'pretty busy',
            'title': 'still no updates'}],
 'title': 'My blog'}

不过 blog 依然不变。这意味着任何拥有旧对象引用的人都没有受到影响:转换只会有局部效果。

当共享行为猖獗时,这会很有用。例如,函数的默认参数:

def silly_sum(a, b, extra=v(1, 2)):
    extra = extra.extend([a, b])
    return sum(extra)

在本文中,我们了解了为什么不可变性有助于我们来思考我们的代码,以及如何在不带来过大性能负担的条件下实现它。下一篇,我们将学习如何借助不可变对象来实现强大的程序结构。


via: https://opensource.com/article/18/10/functional-programming-python-immutable-data-structures

作者:Moshe Zadka 选题:lujun9972 译者:StdioA 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

这些开源的工具能够通过输出帮助用户了解系统的运行状况,并对可能发生的潜在问题作出告警。

你大概已经知道(或猜到) 告警可视化 alerting and visualization 工具是用来做什么的了。下面我们就要来说一下,为什么要讨论这样的工具,甚至某些系统专门将可视化作为特有的功能。

可观察性 Observability 的概念来自 控制理论 control theory ,这个概念描述了我们通过对系统的输入和输出来了解其的能力。本文将重点介绍具有可观察性的输出组件。

告警可视化工具可以对其它系统的输出进行分析,进而对输出的信息进行结构化表示。告警实际上是对系统异常状态的描述,而可视化则是让用户能够直观理解的结构化表示。

常见的可视化告警

告警

首先要明确一下 告警 alert 的含义。在人员无法响应告警内容情况下,不应该发送告警 —— 包括那些发给多个人但只有其中少数人可以响应的告警,以及系统中的每个异常都触发的告警。因为这样会产生告警疲劳,告警接收者也往往会对这些过多的告警采取忽视的态度 —— 直到系统恶化到以少见的方式告警。

例如,如果管理员每天都会收到告警系统发来的数百封告警邮件,他就很容易会忽略告警系统的所有邮件。除非他真的看到问题发生,或者受到了客户或上级的询问时,管理员才会重新重视告警信息。在这种情况下,告警已经失去了原有的意义和用途。

告警不是一个持续的信息流或者状态更新。告警的目的在于暴露系统无法自动恢复的问题,而且告警应该只发送给最有可能解决问题的人员。超出这个定义的内容都不应该作为告警,否则将会对实际工作造成不良的影响。

不同的告警体系都会有各自的告警类型,因此不能用优先级(P1-P5)或者诸如“信息”、“警告”、“严重”之类的字眼来一概而论,下面我会介绍一些新兴的复杂系统的事件响应中出现的通用分类方式。

刚才我提到了一个“信息”这个告警类型,但实际上告警不应该是一个信息,尽管有些人可能会不这样认为。但我觉得如果一个告警没有发送给任何一个人,它就不应该是警报,而只是一些在许多系统中被视为警报的数据点,代表了一些应该知晓但不需要响应的事件。它更应该作为告警可视化工具的一部分,而不是会导致触发告警的事件。《实用监控》是这个领域的必读书籍,其作者 Mike Julian 在书中就介绍了他自己关于告警的看法。

而非信息警报则代表告警需要被响应以及需要相关的操作。我将这些告警大致分为内部故障和外部故障两种类型,而对于大多数公司来说,通常会有两个以上的级别来确定响应告警的优先级。系统性能下降就是一种故障,因为其对用户的影响通常都是未知的。

内部故障比外部故障的优先级低,但也需要快速响应。内部故障通常包括公司员工使用的内部系统或仅对公司员工可见的应用故障。

外部故障则包括任何马上会产生业务影响的系统故障,但不包括影响系统更新的故障。外部故障一般包括客户所面临的应用故障、数据库故障和导致系统可用性或一致性失效的网络故障,这些都会影响用户的正常使用。对于不直接影响用户的依赖组件故障也属于外部故障,随着应用程序的不断运行,一旦依赖组件发生故障,系统的性能也会受到波及。这种情况对于使用某些外部服务或数据源的系统来说很常见,尽管这些外部服务或数据源对于可能不涉及到系统的主要功能,但是当系统在处理相关依赖组件的错误时可能会出现较明显的延迟。

可视化

可视化的种类有很多,我就不一一赘述了。这是一个有趣的研究领域,在我这些年的数据分析经历当中,学习和应用可视化方面的知识可以说是相当有挑战性。我们需要将复杂的系统输出通过直观的方式来向他人展示,才能有效地把信息传播出去。Google ChartsTableau 都提供了很多可视化方面的工具。下面将会介绍一些最常见的可视化创新解决方案。

折线图

折线图可能是最常见的可视化方式了,它可以让用户很直观地按照时间维度了解系统的情况。系统中每个单一或聚合的指标都会以一条折线在图表中体现。但当同一个图表中同时存在多条折线时,就可能会对阅读有所影响(如下图所示),所以大多数情况下都可以选择仅查看其中的少数几条折线,而不是让所有折线同时显示。如果某个指标的数值产生了大于正常范围的波动,就会很容易发现。例如下图中异常的紫线、黄线、浅蓝线。

折线图的另一个用法是可以将多条折线堆叠起来以显示它们之间的关系。例如对于通过折线图反映服务器的请求数量,可以单独看到每台服务器上的请求,也可以聚合在一起看。这就可以在同一个图表中灵活查看整个系统以及每个实例的情况了。

热力图

另一种常见的可视化方式是热力图。热力图与条形图比较类似,还可以在条形图的基础上显示某部分在整体中占比的变化情况。例如在查看网络请求延时的时候,就可以使用热力图快速查看到所有网络请求的总体趋势和分布情况,另外,它可以使用不同颜色来表示不同部分的数值。

在以下这个热力图中,通过竖直方向上每个时间段的色块数量分布,可以清楚地看到大部分数据集中在整个范围的中心位置。我们还可以发现,大多数时间段的色块分布都是比较宽松的,而 14:00 到 15:00 这一段则分布得很密集,这样的分布有可能意味着一种不健康的状态。

仪表图

还有一种常见的可视化方式是仪表图,用户可以通过仪表图快速了解单个指标。仪表一般用于单个指标的显示,例如车速表代表汽车的行驶速度、油量表代表油箱中的汽油量等等。大多数的仪表图都有一个共通点,就是会划分出所示指标的对应状态。如下图所示,绿色表示正常的状态,橙色表示不良的状态,而红色则表示极差的状态。下图中间一行模拟了真实仪表的显示情况。

上面图表中,除了常规仪表样式的显示方式之外,还有较为直接的数据显示方式,配合相同的配色方案,一眼就可以看出各个指标所处的状态,这一点与和仪表的特点类似。所以,最下面一行可能是仪表图的最佳显示方式,用户不需要仔细阅读,就可以大致了解各个指标的不同状态。这种类型的可视化是我最常用的类型,在数秒钟之间,我就可以全面地总览系统各方面地运行情况。

火焰图

Netflix 的 Brendan Gregg 在 2011 年开始使用的火焰图是一种较为少见地可视化方式。它不像仪表图那样可以从图表中快速得到关键信息,通常只会在需要解决某个应用的问题的时候才会用到这种图表。火焰图主要用于 CPU、内存和相关帧方面的表示,X 轴按字母顺序将帧一一列出,而 Y 轴则表示堆栈的深度。图中每个矩形都是一个标明了调用的函数的堆栈帧。矩形越宽,就表示它在堆栈中出现越频繁。在分析系统性能问题的时候,火焰图能够起到很大的作用,大家不妨尝试一下。

工具的选择

在告警工具方面,有几个商用的工具相当不错。但由于这是一篇介绍开源技术的文章,我只会介绍那些已经被广泛使用的免费工具。希望你也能够为这些工具贡献你自己的代码,让它们更加完善。

告警工具

Bosun

如果你的电脑出现问题,得多亏 Stack Exchange 你才能在网上查到解决办法。Stack Exchange 以众包问答的模式运营着很多不同类型的网站。其中就有广受开发者欢迎的 Stack Overflow,以及运维方面有名的 Super User。除此以外,从育儿经验到科幻小说、从哲学讨论到单车论坛,Stack Exchange 都有涉猎。

Stack Exchange 开源了它的告警管理系统 Bosun,同时也发布了 Prometheus 及其 AlertManager 系统。这两个系统有共通点。Bosun 和 Prometheus 一样使用 Golang 开发,但 Bosun 比 Prometheus 更为强大,因为它可以使用 指标聚合 metrics aggregation 以外的方式与系统交互。Bosun 还可以从日志和事件收集系统中提取数据,并且支持 Graphite、InfluxDB、OpenTSDB 和 Elasticsearch。

Bosun 的架构包括一个单一的服务器的二进制文件,一个诸如 OpenTSDB 的后端、Redis 以及 scollector 代理。 scollector 代理会自动检测主机上正在运行的服务,并反馈这些进程和其它的系统资源的情况。这些数据将发送到后端。随后 Bosun 的二进制服务文件会向后端发起查询,确定是否需要触发告警。也可以通过 Grafana 这些工具通过一个通用接口查询 Bosun 的底层后端。而 Redis 则用于存储 Bosun 的状态信息和元数据。

Bosun 有一个非常巧妙的功能,就是可以根据历史数据来测试告警。这是我几年前在使用 Prometheus 的时候就非常需要的功能,当时我有一个异常的数据需要产生告警,但没有一个可以用于测试的简便方法。为了确保告警能够正常触发,我不得不造出对应的数据来进行测试。而 Bosun 让这个步骤的耗时大大缩短。

Bosun 更是涵盖了所有常用过的功能,包括简单的图形化表示和告警的创建。它还带有强大的用于编写告警规则的表达式语言。但 Bosun 默认只带有电子邮件通知配置和 HTTP 通知配置,因此如果需要连接到 Slack 或其它工具,就需要对配置作出更大程度的定制化(其文档中有)。类似于 Prometheus,Bosun 还可以使用模板通知,你可以使用 HTML 和 CSS 来创建你所需要的电子邮件通知。

Cabot

CabotArachnys 公司开发。你或许对 Arachnys 公司并不了解,但它很有影响力:Arachnys 公司构建了一个基于云的先进解决方案,用于防范金融犯罪。在之前的公司时,我也曾经参与过类似“了解你的客户(KYC)”的工作。大多数公司都认为与恐怖组织产生联系会造成相当不好的影响,因为恐怖组织可能会利用自己的系统来筹集资金。而这些解决方案将有助于防范欺诈类犯罪,尽管这类犯罪情节相对较轻,但仍然也会对机构产生风险。

Arachnys 公司为什么要开发 Cabot 呢?其实只是因为 Arachnys 的开发人员对 Nagios 不太熟悉。Cabot 的出现对很多人来说都是一个好消息,它基于 Django 和 Bootstrap 开发,因此如果想对这个项目做出自己的贡献,门槛并不高。(另外值得一提的是,Cabot 这个名字来源于开发者的狗。)

与 Bosun 类似,Cabot 也不对数据进行收集,而是使用监控对象的 API 提供的数据。因此,Cabot 告警的模式是拉取而不是推送。它通过访问每个监控对象的 API,根据特定的指标检索所需的数据,然后将告警数据使用 Redis 缓存,进而持久化存储到 Postgres 数据库。

Cabot 的一个较为少见的特点是,它原生支持 Graphite,同时也支持 Jenkins。Jenkins 在这里被视为一个集中式的定时任务,它会以对待故障的方式去对待构建失败的状况。构建失败当然没有系统故障那么紧急,但一旦出现构建失败,还是需要团队采取措施去处理,毕竟并不是每个人在收到构建失败的电子邮件时都会亲自去检查 Jenkins。

Cabot 另一个有趣的功能是它可以接入 Google 日历安排值班人员,这个称为 Rota 的功能用处很大,希望其它告警系统也能加入类似的功能。Cabot 目前仅支持安排主备联系人,但还有继续改进的空间。它自己的文档也提到,如果需要全面的功能,更应该考虑付费的解决方案。

StatsAgg

Pearson 作为一家开发了 StatsAgg 告警平台的出版公司,这是极为罕见的,当然也很值得敬佩。除此以外,Pearson 还运营着另外几个网站以及和 O'Reilly Media 合资的企业。但我仍然会将它视为出版教学书籍的公司。

StatsAgg 除了是一个告警平台,还是一个指标聚合平台,甚至也有点类似其它系统的代理。StatsAgg 支持通过 Graphite、StatsD、InfluxDB 和 OpenTSDB 输入数据,也支持将其转发到各种平台。但随着中心服务的负载不断增加,风险也不断增大。尽管如此,如果 StatsAgg 的基础架构足够强壮,即使后端存储平台出现故障,也不会对它产生告警的过程造成影响。

StatsAgg 是用 Java 开发的,为了尽可能降低复杂性,它仅包括主服务和一个 UI。StatsAgg 支持基于正则表达式匹配来发送告警,而且它更注重于服务方面的告警,而不是服务器基础告警。我认为它填补了开源监控工具方面的空白,而这正式它自己的目标。

可视化工具

Grafana

Grafana 的知名度很高,它也被广泛采用。每当我需要用到数据面板的时候,我总是会想到它,因为它比我使用过的任何一款类似的产品都要好。Grafana 由 Torkel Ödegaard 开发的,像 Cabot 一样,也是在圣诞节期间开发的,并在 2014 年 1 月发布。在短短几年之间,它已经有了长足的发展。Grafana 基于 Kibana 开发,Torkel 开启了新的分支并将其命名为 Grafana。

Grafana 着重体现了实用性以及数据呈现的美观性。它天生就可以从 Graphite、Elasticsearch、OpenTSDB、Prometheus 和 InfluxDB 收集数据。此外有一个 Grafana 商用版插件可以从更多数据源获取数据,但是其他数据源插件也并非没有开源版本,Grafana 的插件生态系统已经提供了各种数据源。

Grafana 能做什么呢?Grafana 提供了一个中心化的了解系统的方式。它通过 web 来展示数据,任何人都有机会访问到相关信息,当然也可以使用身份验证来对访问进行限制。Grafana 使用各种可视化方式来提供对系统一目了然的了解。Grafana 还支持不同类型的可视化方式,包括集成告警可视化的功能。

现在你可以更直观地设置告警了。通过 Grafana,可以查看图表,还可以查看由于系统性能下降而触发告警的位置,单击要触发报警的位置,并告诉 Grafana 将告警发送何处。这是一个对告警平台非常强大的补充。告警平台不一定会因此而被取代,但告警系统一定会由此得到更多启发和发展。

Grafana 还引入了很多团队协作的功能。不同用户之间能够共享数据面板,你不再需要为 Kubernetes 集群创建独立的数据面板,因为由 Kubernetes 开发者和 Grafana 开发者共同维护的一些数据面板已经可用了。

团队协作过程中一个重要的功能是注释。注释功能允许用户将上下文添加到图表当中,其他用户就可以通过上下文更直观地理解图表。当团队成员在处理某个事件,并且需要沟通和理解时,这个功能就十分重要了。将所有相关信息都放在需要的位置,可以让整个团队中快速达成共识。在团队需要调查故障原因和定位事件责任时,这个功能就可以发挥作用了。

Vizceral

Vizceral 由 Netflix 开发,用于在故障发生时更有效地了解流量的情况。Grafana 是一种通用性更强的工具,而 Vizceral 则专用于某些领域。 尽管 Netflix 表示已经不再在内部使用 Vizceral,也不再主动对其展开维护,但 Vizceral 仍然会定期更新。我在这里介绍这个工具,主要是为了介绍它的的可视化机制,以及如何利用它来协助解决问题。你可以在样例环境中用它来更好地掌握这一类系统的特性。


via: https://opensource.com/article/18/10/alerting-and-visualization-tools-sysadmins

作者:Dan Barker 选题:lujun9972 译者:HankChow 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

在基于 RPM 的系统上,例如 RHEL、CentOS 等,我们中的许多人使用 yum 包管理器来管理软件的安装、删除、更新、搜索等。

Linux 发行版的大部分软件都来自发行版官方仓库。官方仓库包含大量免费和开源的应用和软件。它很容易安装和使用。

由于一些限制和专有问题,基于 RPM 的发行版在其官方仓库中没有提供某些包。另外,出于稳定性考虑,它不会提供最新版本的核心包。

为了克服这种情况,我们需要安装或启用需要的第三方仓库。对于基于 RPM 的系统,有许多第三方仓库可用,但所建议使用的仓库很少,因为这些不会替换大量的基础包。

建议阅读:

这可以在基于 RPM 的系统上完成,比如 RHEL, CentOS, OEL, Fedora 等。

  • Fedora 系统使用 dnf config-manager [options] [section …]
  • 其它基于 RPM 的系统使用 yum-config-manager [options] [section …]

如何列出启用的仓库

只需运行以下命令即可检查系统上启用的仓库列表。

对于 CentOS/RHEL/OLE 系统:

# yum repolist
Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
repo id                                                       repo name                                                                 status
base                                                          CentOS-6 - Base                                                           6,706
extras                                                        CentOS-6 - Extras                                                            53
updates                                                       CentOS-6 - Updates                                                        1,255
repolist: 8,014

对于 Fedora 系统:

# dnf repolist

如何在系统中添加一个新仓库

每个仓库通常都提供自己的 .repo 文件。要将此类仓库添加到系统中,使用 root 用户运行以下命令。在我们的例子中将添加 EPEL 仓库 和 IUS 社区仓库,见下文。

但是没有 .repo 文件可用于这些仓库。因此,我们使用以下方法进行安装。

对于 EPEL 仓库,因为它可以从 CentOS 额外仓库获得,所以运行以下命令来安装它。

# yum install epel-release -y

对于 IUS 社区仓库,运行以下 bash 脚本来安装。

# curl 'https://setup.ius.io/' -o setup-ius.sh
# sh setup-ius.sh

如果你有 .repo 文件,在 RHEL/CentOS/OEL 中,只需运行以下命令来添加一个仓库。

# yum-config-manager --add-repo http://www.example.com/example.repo

Loaded plugins: product-id, refresh-packagekit, subscription-manager
adding repo from: http://www.example.com/example.repo
grabbing file http://www.example.com/example.repo to /etc/yum.repos.d/example.repo
example.repo                                             |  413 B     00:00
repo saved to /etc/yum.repos.d/example.repo

对于 Fedora 系统,运行以下命令来添加一个仓库:

# dnf config-manager --add-repo http://www.example.com/example.repo
adding repo from: http://www.example.com/example.repo

如果在添加这些仓库之后运行 yum repolist 命令,你就可以看到新添加的仓库了。Yes,我看到了。

注意:每当运行 yum repolist 命令时,该命令会自动从相应的仓库获取更新,并将缓存保存在本地系统中。

# yum repolist

Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
epel/metalink                                                                                                          | 6.1 kB     00:00
* epel: epel.mirror.constant.com
* ius: ius.mirror.constant.com
ius                                                                                                                    | 2.3 kB     00:00
repo id                                     repo name                                                                                   status
base                                        CentOS-6 - Base                                                                              6,706
epel                                        Extra Packages for Enterprise Linux 6 - x86_64                                              12,505
extras                                      CentOS-6 - Extras                                                                               53
ius                                         IUS Community Packages for Enterprise Linux 6 - x86_64                                         390
updates                                     CentOS-6 - Updates                                                                           1,255
repolist: 20,909

每个仓库都有多个渠道,比如测试(Testing)、开发(Dev)和存档(Archive)等。通过导航到仓库文件位置,你可以更好地理解这一点。

# ls -lh /etc/yum.repos.d
total 64K
-rw-r--r-- 1 root root 2.0K Apr 12 02:44 CentOS-Base.repo
-rw-r--r-- 1 root root 647 Apr 12 02:44 CentOS-Debuginfo.repo
-rw-r--r-- 1 root root 289 Apr 12 02:44 CentOS-fasttrack.repo
-rw-r--r-- 1 root root 630 Apr 12 02:44 CentOS-Media.repo
-rw-r--r-- 1 root root 916 May 18 11:07 CentOS-SCLo-scl.repo
-rw-r--r-- 1 root root 892 May 18 10:36 CentOS-SCLo-scl-rh.repo
-rw-r--r-- 1 root root 6.2K Apr 12 02:44 CentOS-Vault.repo
-rw-r--r-- 1 root root 7.9K Apr 12 02:44 CentOS-Vault.repo.rpmnew
-rw-r--r-- 1 root root 957 May 18 10:41 epel.repo
-rw-r--r-- 1 root root 1.1K Nov 4 2012 epel-testing.repo
-rw-r--r-- 1 root root 1.2K Feb 23 2017 ius-archive.repo
-rw-r--r-- 1 root root 1.2K Feb 23 2017 ius-dev.repo
-rw-r--r-- 1 root root 1.1K May 18 10:41 ius.repo
-rw-r--r-- 1 root root 1.2K Feb 23 2017 ius-testing.repo

如何在系统中启用一个仓库

当你在默认情况下添加一个新仓库时,它将启用它们的稳定仓库,这就是为什么我们在运行 yum repolist 命令时获取了仓库信息。在某些情况下,如果你希望启用它们的测试、开发或存档仓库,使用以下命令。另外,我们还可以使用此命令启用任何禁用的仓库。

为了验证这一点,我们将启用 epel-testing.repo,运行下面的命令:

# yum-config-manager --enable epel-testing

Loaded plugins: fastestmirror
==================================================================================== repo: epel-testing =====================================================================================
[epel-testing]
bandwidth = 0
base_persistdir = /var/lib/yum/repos/x86_64/6
baseurl =
cache = 0
cachedir = /var/cache/yum/x86_64/6/epel-testing
cost = 1000
enabled = 1
enablegroups = True
exclude =
failovermethod = priority
ftp_disable_epsv = False
gpgcadir = /var/lib/yum/repos/x86_64/6/epel-testing/gpgcadir
gpgcakey =
gpgcheck = True
gpgdir = /var/lib/yum/repos/x86_64/6/epel-testing/gpgdir
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
hdrdir = /var/cache/yum/x86_64/6/epel-testing/headers
http_caching = all
includepkgs =
keepalive = True
mdpolicy = group:primary
mediaid =
metadata_expire = 21600
metalink =
mirrorlist = https://mirrors.fedoraproject.org/metalink?repo=testing-epel6&arch=x86_64
mirrorlist_expire = 86400
name = Extra Packages for Enterprise Linux 6 - Testing - x86_64
old_base_cache_dir =
password =
persistdir = /var/lib/yum/repos/x86_64/6/epel-testing
pkgdir = /var/cache/yum/x86_64/6/epel-testing/packages
proxy = False
proxy_dict =
proxy_password =
proxy_username =
repo_gpgcheck = False
retries = 10
skip_if_unavailable = False
ssl_check_cert_permissions = True
sslcacert =
sslclientcert =
sslclientkey =
sslverify = True
throttle = 0
timeout = 30.0
username =

运行 yum repolist 命令来检查是否启用了 “epel-testing”。它被启用了,我可以从列表中看到它。

# yum repolist
Loaded plugins: fastestmirror, security
Determining fastest mirrors
epel/metalink                                                                                                                                                         |  18 kB     00:00
epel-testing/metalink                                                                                                                                                 |  17 kB     00:00
 * epel: mirror.us.leaseweb.net
 * epel-testing: mirror.us.leaseweb.net
 * ius: mirror.team-cymru.com
base                                                                                                                                                                  | 3.7 kB     00:00
centos-sclo-sclo                                                                                                                                                      | 2.9 kB     00:00
epel                                                                                                                                                                  | 4.7 kB     00:00
epel/primary_db                                                                                                                                                       | 6.0 MB     00:00
epel-testing                                                                                                                                                          | 4.7 kB     00:00
epel-testing/primary_db                                                                                                                                               | 368 kB     00:00
extras                                                                                                                                                                | 3.4 kB     00:00
ius                                                                                                                                                                   | 2.3 kB     00:00
ius/primary_db                                                                                                                                                        | 216 kB     00:00
updates                                                                                                                                                               | 3.4 kB     00:00
updates/primary_db                                                                                                                                                    | 8.1 MB     00:00 ...
repo id                                                                repo name                                                                                                       status
base                                                                   CentOS-6 - Base                                                                                                  6,706
centos-sclo-sclo                                                       CentOS-6 - SCLo sclo                                                                                               495
epel                                                                   Extra Packages for Enterprise Linux 6 - x86_64                                                                  12,509
epel-testing                                                           Extra Packages for Enterprise Linux 6 - Testing - x86_64                                                           809
extras                                                                 CentOS-6 - Extras                                                                                                   53
ius                                                                    IUS Community Packages for Enterprise Linux 6 - x86_64                                                             390
updates                                                                CentOS-6 - Updates                                                                                               1,288
repolist: 22,250

如果你想同时启用多个仓库,使用以下格式。这个命令将启用 epel、epel-testing 和 ius 仓库:

# yum-config-manager --enable epel epel-testing ius

对于 Fedora 系统,运行下面的命令来启用仓库:

# dnf config-manager --set-enabled epel-testing

如何在系统中禁用一个仓库

无论何时你在默认情况下添加一个新的仓库,它都会启用它们的稳定仓库,这就是为什么我们在运行 yum repolist 命令时获取了仓库信息。如果你不想使用仓库,那么可以通过下面的命令来禁用它。

为了验证这点,我们将要禁用 epel-testing.repoius.repo,运行以下命令:

# yum-config-manager --disable epel-testing ius

Loaded plugins: fastestmirror
==================================================================================== repo: epel-testing =====================================================================================
[epel-testing]
bandwidth = 0
base_persistdir = /var/lib/yum/repos/x86_64/6
baseurl =
cache = 0
cachedir = /var/cache/yum/x86_64/6/epel-testing
cost = 1000
enabled = 0
enablegroups = True
exclude =
failovermethod = priority
ftp_disable_epsv = False
gpgcadir = /var/lib/yum/repos/x86_64/6/epel-testing/gpgcadir
gpgcakey =
gpgcheck = True
gpgdir = /var/lib/yum/repos/x86_64/6/epel-testing/gpgdir
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
hdrdir = /var/cache/yum/x86_64/6/epel-testing/headers
http_caching = all
includepkgs =
keepalive = True
mdpolicy = group:primary
mediaid =
metadata_expire = 21600
metalink =
mirrorlist = https://mirrors.fedoraproject.org/metalink?repo=testing-epel6&arch=x86_64
mirrorlist_expire = 86400
name = Extra Packages for Enterprise Linux 6 - Testing - x86_64
old_base_cache_dir =
password =
persistdir = /var/lib/yum/repos/x86_64/6/epel-testing
pkgdir = /var/cache/yum/x86_64/6/epel-testing/packages
proxy = False
proxy_dict =
proxy_password =
proxy_username =
repo_gpgcheck = False
retries = 10
skip_if_unavailable = False
ssl_check_cert_permissions = True
sslcacert =
sslclientcert =
sslclientkey =
sslverify = True
throttle = 0
timeout = 30.0
username =

========================================================================================= repo: ius =========================================================================================
[ius]
bandwidth = 0
base_persistdir = /var/lib/yum/repos/x86_64/6
baseurl =
cache = 0
cachedir = /var/cache/yum/x86_64/6/ius
cost = 1000
enabled = 0
enablegroups = True
exclude =
failovermethod = priority
ftp_disable_epsv = False
gpgcadir = /var/lib/yum/repos/x86_64/6/ius/gpgcadir
gpgcakey =
gpgcheck = True
gpgdir = /var/lib/yum/repos/x86_64/6/ius/gpgdir
gpgkey = file:///etc/pki/rpm-gpg/IUS-COMMUNITY-GPG-KEY
hdrdir = /var/cache/yum/x86_64/6/ius/headers
http_caching = all
includepkgs =
keepalive = True
mdpolicy = group:primary
mediaid =
metadata_expire = 21600
metalink =
mirrorlist = https://mirrors.iuscommunity.org/mirrorlist?repo=ius-centos6&arch=x86_64&protocol=http
mirrorlist_expire = 86400
name = IUS Community Packages for Enterprise Linux 6 - x86_64
old_base_cache_dir =
password =
persistdir = /var/lib/yum/repos/x86_64/6/ius
pkgdir = /var/cache/yum/x86_64/6/ius/packages
proxy = False
proxy_dict =
proxy_password =
proxy_username =
repo_gpgcheck = False
retries = 10
skip_if_unavailable = False
ssl_check_cert_permissions = True
sslcacert =
sslclientcert =
sslclientkey =
sslverify = True
throttle = 0
timeout = 30.0
username =

运行 yum repolist 命令检查 “epel-testing” 和 “ius” 仓库是否被禁用。它被禁用了,我不能看到那些仓库,除了 “epel”。

# yum repolist
Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
 * epel: mirror.us.leaseweb.net
repo id                                                                     repo name                                                                                                  status
base                                                                        CentOS-6 - Base                                                                                             6,706
centos-sclo-sclo                                                            CentOS-6 - SCLo sclo                                                                                          495
epel                                        Extra Packages for Enterprise Linux 6 - x86_64                                              12,505
extras                                                                      CentOS-6 - Extras                                                                                              53
updates                                                                     CentOS-6 - Updates                                                                                          1,288
repolist: 21,051

或者,我们可以运行以下命令查看详细信息:

# yum repolist all | grep "epel*\|ius*"
 * epel: mirror.steadfast.net
epel                       Extra Packages for Enterprise Linux 6 enabled: 12,509
epel-debuginfo             Extra Packages for Enterprise Linux 6 disabled
epel-source                Extra Packages for Enterprise Linux 6 disabled
epel-testing               Extra Packages for Enterprise Linux 6 disabled
epel-testing-debuginfo     Extra Packages for Enterprise Linux 6 disabled
epel-testing-source        Extra Packages for Enterprise Linux 6 disabled
ius                        IUS Community Packages for Enterprise disabled
ius-archive                IUS Community Packages for Enterprise disabled
ius-archive-debuginfo      IUS Community Packages for Enterprise disabled
ius-archive-source         IUS Community Packages for Enterprise disabled
ius-debuginfo              IUS Community Packages for Enterprise disabled
ius-dev                    IUS Community Packages for Enterprise disabled
ius-dev-debuginfo          IUS Community Packages for Enterprise disabled
ius-dev-source             IUS Community Packages for Enterprise disabled
ius-source                 IUS Community Packages for Enterprise disabled
ius-testing                IUS Community Packages for Enterprise disabled
ius-testing-debuginfo      IUS Community Packages for Enterprise disabled
ius-testing-source         IUS Community Packages for Enterprise disabled

对于 Fedora 系统,运行以下命令来启用一个仓库:

# dnf config-manager --set-disabled epel-testing

或者,可以通过手动编辑适当的 repo 文件来完成。为此,打开相应的 repo 文件并将值从 enabled=0 改为 enabled=1(启用仓库)或从 enabled=1 变为 enabled=0(禁用仓库)。

即从:

[epel]
name=Extra Packages for Enterprise Linux 6 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch
failovermethod=priority
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6

改为:

[epel]
name=Extra Packages for Enterprise Linux 6 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6

via: https://www.2daygeek.com/how-to-add-enable-disable-a-repository-dnf-yum-config-manager-on-linux/

作者:Prakash Subramanian 选题:lujun9972 译者:MjSeven 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

欢迎回到我们为了构建更快网页所写的系列文章。上一篇文章讨论了只通过图片压缩实现这个目标的方法。这个例子从一开始有 1.2MB 的“浏览器脂肪”,然后它减轻到了 488.9KB 的大小。但这还不够快!那么本文继续来给浏览器“减肥”。你可能在这个过程中会认为我们所做的事情有点疯狂,但一旦完成,你就会明白为什么要这么做了。

准备工作

本文再次从对网页的分析开始。使用 Firefox 内置的截图功能来对整个页面进行截图。你还需要用 sudo 来安装 Inkscape:

$ sudo dnf install inkscape

如果你想了解 Inkscape 的用法,Fedora 杂志上有几篇现成的文章。本文仅会介绍一些基本的 SVG 优化方法以供 Web 使用。

分析

我们再来用 getfedora.org 的网页来举例。

Getfedora 的页面,对其中的图片做了标记

这次分析以图形方式完成更好,这也就是它从屏幕截图开始的原因。上面的截图标记了页面中的所有图形元素。Fedora 网站团队已经针对两种情况措施(也有可能是四种,这样更好)来替换图像了。社交媒体的图标变成了字体的字形,而语言选择器变成了 SVG.

我们有几个可以替换的选择:

  • CSS3
  • 字体
  • SVG
  • HTML5 Canvas

HTML5 Canvas

简单来说,HTML5 Canvas 是一种 HTML 元素,它允许你借助脚本语言(通常是 JavaScript)在上面绘图,不过它现在还没有被广泛使用。因为它可以使用脚本语言来绘制,所以这个元素也可以用来做动画。这里有一些使用 HTML Canvas 实现的实例,比如三角形模式动态波浪字体动画。不过,在这种情况下,似乎这也不是最好的选择。

CSS3

使用层叠式样式表,你可以绘制图形,甚至可以让它们动起来。CSS 常被用来绘制按钮等元素。然而,使用 CSS 绘制的更复杂的图形通常只能在技术演示页面中看到。这是因为使用视觉来制作图形依然要比使用代码来的更快一些。

字体

另外一种方式是使用字体来装饰网页,Fontawesome 在这方面很流行。比如,在这个例子中你可以使用字体来替换“Flavor”和“Spin”的图标。这种方法有一个负面影响,但解决起来很容易,我们会在本系列的下一部分中来介绍。

SVG

这种图形格式已经存在了很长时间,而且它总是在浏览器中被使用。有很长一段时间并非所有浏览器都支持它,不过现在这已经成为历史了。所以,本例中图形替换的最佳方法是使用 SVG.

为网页优化 SVG

优化 SVG 以供互联网使用,需要几个步骤。

SVG 是一种 XML 方言。它用节点来描述圆形、矩形或文本路径等组件。每个节点都是一个 XML 元素。为了保证代码简洁,SVG 应该包含尽可能少的元素。

我们选用的 SVG 实例是带有一个咖啡杯的圆形图标。你有三种选项来用 SVG 描述它。

一个圆形元素,上面有一个咖啡杯

<circle
style="opacity:1;fill:#717d82;fill-opacity:1;stroke:none;stroke-width:9.51950836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
id="path36"
cx="68.414307"
cy="130.71523"
r="3.7620001" />

一个圆形路径,上面有一个咖啡杯

<path
style="opacity:1;fill:#717d82;fill-opacity:1;stroke:none;stroke-width:1.60968435;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
d="m 68.414044,126.95318 a 3.7618673,3.7618673 0 0 0 -3.76153,3.76204 3.7618673,3.7618673 0 0 0 3.76153,3.76205 3.7618673,3.7618673 0 0 0 3.76206,-3.76205 3.7618673,3.7618673 0 0 0 -3.76206,-3.76204 z"
id="path20" />

单一路径

<path
style="opacity:1;fill:#717d82;fill-opacity:1;stroke:none;stroke-width:1.60968435;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
d="m 68.414044,126.95318 a 3.7618673,3.7618673 0 0 0 -3.76153,3.76204 3.7618673,3.7618673 0 0 0 3.76153,3.76205 3.7618673,3.7618673 0 0 0 3.76206,-3.76205 3.7618673,3.7618673 0 0 0 -3.76206,-3.76204 z m -1.21542,0.92656 h 2.40554 c 0.0913,0.21025 0.18256,0.42071 0.27387,0.63097 h 0.47284 v 0.60099 h -0.17984 l -0.1664,1.05989 h 0.24961 l -0.34779,1.96267 -0.21238,-0.003 -0.22326,1.41955 h -2.12492 l -0.22429,-1.41955 -0.22479,0.003 -0.34829,-1.96267 h 0.26304 l -0.16692,-1.05989 h -0.1669 v -0.60099 h 0.44752 c 0.0913,-0.21026 0.18206,-0.42072 0.27336,-0.63097 z m 0.12608,0.19068 c -0.0614,0.14155 -0.12351,0.28323 -0.185,0.42478 h 2.52336 c -0.0614,-0.14155 -0.12248,-0.28323 -0.18397,-0.42478 z m -0.65524,0.63097 v 0.21911 l 0.0594,5.2e-4 h 3.35844 l 0.0724,-5.2e-4 v -0.21911 z m 0.16846,0.41083 0.1669,1.05937 h 2.80603 l 0.16693,-1.05937 -1.57046,0.008 z m -0.061,1.25057 0.27956,1.5782 1.34411,-0.0145 1.34567,0.0145 0.28059,-1.5782 z m 1.62367,1.75441 -1.08519,0.0124 0.19325,1.2299 h 1.79835 l 0.19328,-1.2299 z"
id="path2714"
inkscape:connector-curvature="0" />

你应该可以看出,代码变得越来越复杂,需要更多的字符来描述它。当然,文件中包含更多的字符,就会导致更大的尺寸。

节点清理

如果你在 Inkscape 中打开了实例 SVG 按下 F2,就会激活一个节点工具。你应该看到这样的界面:

Inkscape - 激活节点工具

这个例子中有五个不必要的节点——就是直线中间的那些。要删除它们,你可以使用已激活的节点工具依次选中它们,并按下 Del 键。然后,选中这条线的定义节点,并使用工具栏的工具把它们重新做成角。

Inkscape - 将节点变成角的工具

如果不修复这些角,我们还有方法可以定义这条曲线,这条曲线会被保存,也就会增加文件体积。你可以手动清理这些节点,因为它无法有效的自动完成。现在,你已经为下一阶段做好了准备。

使用“另存为”功能,并选择“优化的 SVG”。这会弹出一个窗口,你可以在里面选择移除或保留哪些成分。

Inkscape - “另存为”“优化的 SVG”

虽然这个 SVG 实例很小,但它还是从 3.2KB 减小到了 920 字节,不到原有的三分之一。

回到 getfedora 的页面:页面主要部分的背景中的灰色沃罗诺伊图,在经过本系列第一篇文章中的优化处理之后,从原先的 211.12 KB 减小到了 164.1 KB.

页面中导出的原始 SVG 有 1.9 MB 大小。经过这些 SVG 优化步骤后,它只有 500.4 KB 了。太大了?好吧,现在的蓝色背景的体积是 564.98 KB。SVG 和 PNG 之间只有很小的差别。

压缩文件

$ ls -lh
insgesamt 928K
-rw-r--r--. 1 user user 161K 19. Feb 19:44 grey-pattern.png
-rw-rw-r--. 1 user user 160K 18. Feb 12:23 grey-pattern.png.gz
-rw-r--r--. 1 user user 489K 19. Feb 19:43 greyscale-pattern-opti.svg
-rw-rw-r--. 1 user user 112K 19. Feb 19:05 greyscale-pattern-opti.svg.gz

这是我为可视化这个主题所做的一个小测试的输出。你可能应该看到光栅图形——PNG——已经被压缩,不能再被压缩了。而 SVG,它是一个 XML 文件正相反。它是文本文件,所以可被压缩至原来的四分之一不到。因此,现在它的体积要比 PNG 小 50 KB 左右。

现代浏览器可以以原生方式处理压缩文件。所以,许多 Web 服务器都打开了 mod\_deflate (Apache) 和 gzip (Nginx) 模式。这样我们就可以在传输过程中节省空间。你可以在这儿看看你的服务器是不是启用了它。

生产工具

首先,没有人希望每次都要用 Inkscape 来优化 SVG. 你可以在命令行中脱离 GUI 来运行 Inkscape,但你找不到选项来将 Inkscape SVG 转换成优化的 SVG. 用这种方式只能导出光栅图像。但是我们替代品:

  • SVGO (看起来开发过程已经不活跃了)
  • Scour

本例中我们使用 scour 来进行优化。先来安装它:

$ sudo dnf install scour

要想自动优化 SVG 文件,请运行 scour,就像这样:

[user@localhost ]$ scour INPUT.svg OUTPUT.svg -p 3 --create-groups --renderer-workaround --strip-xml-prolog --remove-descriptive-elements --enable-comment-stripping --disable-embed-rasters --no-line-breaks --enable-id-stripping --shorten-ids

这就是第二部分的结尾了。在这部分中你应该学会了如何将光栅图像替换成 SVG,并对它进行优化以供使用。请继续关注 Feroda 杂志,第三篇即将出炉。


via: https://fedoramagazine.org/design-faster-web-pages-part-2-image-replacement/

作者:Sirko Kemter 选题:lujun9972 译者:StdioA 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出