“当新的主版本发布时,不要低估那些在更新日志中可能是两三行字来描述的功能哦。这5个新功能虽然很小,但仍然会使你的日常监控工作变得更加轻松便捷。”
——Dmitrijs Lamberts,
高级技术支持&培训师,Zabbix SIA
本文整理自Dmitrijs 在2020Zabbix中国峰会的演讲,更多演讲视频可关注官方Bilibili账号主页(ID:Zabbix中国)。
01 - Zabbix sender的输入文件支持纳秒级
首先,Zabbix sender的输入文件支持纳秒级。那么这个Zabbix sender是什么?何时使用,以及为什么要使用?像我们通常谈论Zabbix监控时一样,我们需要采集一些值。比如我们会使用Zabbix agent,通过SNMP协议来采集数据。同时,我们有时会有一些外部源,可能是一些外部脚本在采集数据,我们唯一的任务就是将这些数据传递到我们的Zabbix server或proxy那里。而Zabbix sender正是为此服务的,当我们在主机上收集完数据后,我们就使用Zabbix sender。正如这里所示,我们只需从shell调用Zabbix sender,限定几个参数即可,例如-z是Zabbix server或proxy的位置。-s是主机名,它必须与前端中的主机名完全匹配的。-k代表你要向其发送数据的单元。-o代表我们所发送的值。因此,我们能够在用户需要调用时发送一个单值,同时也可以将所有值存储在text文档中。只需为输入文件限定额外参数-i,Zabbix sender就会执行操作,即从text文档中读取这些值,这些值可以用一些外部脚本来获取,并将它们发送到你的Zabbix server上进行分析。
那为什么以前是个问题?我们无法指明纳秒级支持吗?原因在于复制,因为需要确保监控服务的正常运行,一些高可用性设置或某些集群大规模安装的Zabbix使用了数据库的复制。例如,galera数据库的复制,我们知道MySQL8是数据库集群最广泛的呈现方式。它们数据库内部的所有表格都必须使用主键。但是,在Zabbix数据库中,并非所有表格都具有主键。例如历史记录表和DB版本表都没有主键。那么我们该怎样才能解决这个问题?当然,我们可以手动添加主键,但是问题随后就会出现。
因此,我们如何添加这些主键,就像在历史记录表上查看的这个例子一样,基本上有两个选项。一是将主键添加到三个列上(即item id,clock和ns上),这很好,或者说在这种情况下是我们可以得到的最好结果。第二个,只在item id和clock列上添加一个主键,这样就不是很理想。这里列出了原因,假设我们用Zabbix sender从文件输入中发送值,你可以看到主机是Zabbix Rocks,item只是一项,然后有一个Unix时间用于时间戳支持,值为5。当我们将该值发送到Zabbix server时,在Zabbix server日志文件中,我们会收到很多查询失败的错误消息。因为我们的主键违规。在这个例子中,相同数据中我们无法在item id,value和clock插入多个条目。因此,以秒为单位的Unix时间是相同的,但纳秒级是变化的。以前我们没有办法在文件输入中指明纳秒级支持。但是现在,我们可以在我们的Zabbix sender行添加额外的参数。-N的含义就是有纳秒级的支持,这使我们也可以在输入中标明纳秒级。发送值时也会将该值发送到我们的Zabbix server。如你所见,所有五行都成功输入到数据库中,没有主键问题导致的查询失败。
02 - 关于NODATA触发器和Proxy可用性
第二个功能是关于NODATA触发器和Proxy可用性的问题。实际上这个是一个很大的点。正如你所见,关于这项功能请求已有17年历史了。在“Zabbix 5.0新功能”的文章中,关于这个功能的描述并没有占用很多空间,但实际上是一个很大的点。
那么,NODATA触发器功能是什么呢?它只是查看是否有来自某些特定监控项的数据。如果在越来越密集的明确时间内没有数据,就会创建一个问题。最大的问题是Proxy,所以我们可能有一个Proxy,这个Proxy可能正在监控数千台服务器。如果Proxy失去作用怎么办?如果Proxy与Server之间有网络通信有问题,agent在报告数据时,Proxy无法将此数据发送到Zabbix server。当问题实际上出现在Proxy上而不是在主机上时,我们将会看到大量的NODATA触发器的存储。简单图示说明一下,如果只有一个Zabbix agent向一个Zabbix proxy报告数据,proxy又向Zabbix server报告数据,一切正常,大家都开心。接下来,仍然是一个agent向Zabbix proxy成功报告数据,但该proxy无法将数据发送到Zabbix server。我们在前端看到什么?我们看到一个NO DATA的问题,显示agent无法获取,但是事实上问题是proxy无法获取。我们假设proxy后面有5000个agent,这些agent可以成功向proxy报告,但是proxy却无法将数据发送到Server。我们会在前端收到5000条提示,也会收到大量的邮件通知,甚至会执行一些我们远程的操作命令。
所以现在,有个NODATA考虑proxy的可用性, 例如我们在proxy后面成功报告了5000个agent,但是proxy无法将该数据发送到服务器。我们在Zabbix前端只会生成一个问题,Zabbix server只会执行一项操作,指明是Zabbix proxy不可访问,而不是说5000个Zabbix agent有问题。那么在Zabbix 5.0之前有解决此问题的方法吗?技术上来讲的话是做得到的,但实际上很难,因为唯一的选项就是手动添加触发器依赖项。所以,你必须手工添加agent可用性,创建有NODATA功能的触发器,依赖于proxy的可用性。基本上需要在每个主机或者在模板级别上,对每个agent手动创建此类触发器。这需要大量时间,而且太不方便。
从Zabbix5.0开始,我们需要多少时间来完成类似的配置?基本不用花时间。因为默认状态下会启用此功能,默认的触发器具有NODATA触发功能。触发器是在proxy之后,因此主机监控项位于proxy之后,那么默认情况下NODATA触发器会自动考虑proxy的可用性。如果proxy停机的话,你将不会收到这些事件风暴。那么,如果我有同样的设置但是我想接收那些5000条通知怎么办?是的,主要的问题还是在proxy,我仍然没有从那5000个agent那里接收到数据。这不是问题。如果你仍想接收这些事件风暴,则只需在现有的NODATA触发功能中添加一个参数,如幻灯片上所示,虽然没有数据,把5作为一个时间阈值。然后在逗号之后第二个参数strict,这意味着NODATA将不反映proxy的可用性。并且只有在超过指定时间段后没有数值,它才会立即报告。可以解决此问题的另一种选项是全局关联,虽然这种选项的使用很早就有,但是目前触发器功能还是更好的选项,加上NODATA触发器这个可选功能即可。
03 - 用户界面上测试监控项
第三个功能是在用户界面上测试监控项的功能,这个也会让你在日常工作中Zabbix的使用更加轻松。因为在有些情况下,当我们创建某种更复杂的监控项时,我们不确定是否正确地设置了此监控项。我们是否正确的设定了参数,特别是在预处理流程设置时,对一个监控项可能有很多的设置。我们不能确定一切都正确,我们能提前做什么?我们可以提前做什么来测试?我们只能等,对吧?我们在主机上创建一个监控项,然后等待下一个更新间隔,看一下我们究竟将收到什么样的数值。或者我们可以使用zabbix_agentd-t,它限制我们只在这个Zabbix agent上使用,但是我们可以有很多监控项类型来接收数据,就像前面介绍的Zabbix sender一样。或者我们可以使用zabbix_get-s,当然,也限定在Zabbix agent。所以即便用了Zabbix get,也不能从网络设备上接收数值。甚至于说,尽管我们使用了zabbix_get和 zabbix_agentd -t,我们仍然无法查询到预处理流程的步骤。所以问题来了,更新的间隔可能太长,Zabbix_agentd和Zabbix_get不是跟着预处理流程,因此我们仍然只能获得原始值,所以我们看不到说我们的JSON或者是表达式是否正确。
如何解决呢?从5.0开始可以使用的新功能,如果你已经在使用5.0,那么你可能已经注意到,前端有一个名为Test的新按钮。当你单击此按钮时,只需在弹出屏幕上填写几个参数即可。你需要填写IP地址和端口,它将标明数据源,你从那里接收数值。如果该主机位于proxy之后,也不会有问题,你只需从下拉列表中选择你要检验值的列表选项,你可以有两个选项。你可以单击获取值,仅从主机获取原始数值,也可以单击获取值并进行测试。为了在同一时间获得相同的原始值,你还应该检查测试所有预处理步骤,方法是在每次执行预处理后查看其值是多少。非常的简单!这就是我们在前端获得结果的方式,当我们测试时就会获得所有预处理的输出,例如正则表达式、替换、左修剪、乘以值、检查其是否在范围内。如果我们仅使用Zabbix get来获得相同的项密钥,系统主机名,那么我们只会得到demo2.zabbix.lan,对吗?我们也可以使用模板中的相同功能,这个很棒!在之前,我们必须向主机添加一个监控项,重新加载配置缓存并开始监控。但是有了新的监控项测试功能,我们可以测试这些监控项并尝试接收模板级别的值。你也可以尝试着创建自己的模板,并在你所有数据源中对其进行测试,以确保不会出现会严重错误影响到监控系统。
04 - 媒体类型的默认信息
第四种功能,媒体类型的默认信息,你可能认为这是一个很小的功能点。像以前,当你创建一个动作,对动作做了什么,都会有一条带有默认主题的默认消息,可以对其进行更改。但是如果我们要自定义,比如,自定义一些符合公司要求的消息。我们必须手动编辑每个操作,发送给终端用户的不同消息。但是有什么问题?就像以前一样,考虑可拓展性,当有10个动作、15个、20个动作时,独立编辑每个动作并指定该自定义消息或主题可能不是一个大问题。但是如果有500多个动作,有500多种媒体类型,不同的消息发送标准,不同问题源的政策。假设如果是数据库,你想发送这个消息,如果是网络设备,你想发送附带其他信息的另外一个消息。如果是开发环境,需要发送这个,而在生产环境中,则要发送另外一个。因此很不方便,并且很难管理。设想一下打开配置操作页面,有20个页面,每个页面都有50个操作,你必须手动执行所有这些操作,并指定要发送的某种消息类型。
因此,在新版本中这个问题的解决方案变得非常简单。只需为媒体类型定义标准消息,这意味着我们要设定默认主题,默认的消息正文,设定默认发送的消息类型给这些场景:比如问题解决时、问题发生时、有更新时、设备被发现时、设备自动注册时等。我们对所有可能触发某种动作的潜在事件源在媒体类型级别的主题中都定义消息为默认值。有了这些不同的预设,我们就不必手动去编辑每个动作。当然,在某些情况下,也可以对500个动作列表中的某一个特定动作使用某种独特的消息类型。可以在配置操作中打开那个需要更改的单个操作,只需在操作级别上覆盖默认主题和正文消息即可。同时媒体类型级别上仍然具有默认的设置,很棒的功能,对吗?
05 - 在主机接口级别上获得SNMP管理协议认证的信息
最后一个功能:在主机接口级别上获得SNMP管理协议认证的信息。将SNMP视为监控项类型。像Zabbix agent,ssh,SNMP traps,telnet IPMI这些一样。对SNMP管理协议来说,有三个版本,我们要看到版本3,这些需要在Zabbix前端中定义很多参数。老实说,这些参数并非友好。很容易有错别字。这些参数很复杂,比如开始的OID,中间有很多位,有点,有上下文名称,安全名称通常遵循一些安全性准则,大写,小写,符号数字等等。非常容易犯简单的书写错误。如果我们谈论的是常规监控项,那么就是一个错误,造成一个无法正常工作的监控项,但如果我们说的是低级别自动发现,我们在一个监控项原型中出现一个拼写错误,这个监控项应用在模板中,模板应用于成千上万的主机,那么我们就会收到成千上万个不支持的监控项,会让我们的主机可用性整个都乱掉,仅仅是因为我们刚开始的一个拼写错误。之前的解决方案是使用用户宏,将所有那些安全凭据保留存储在用户的宏里面。但是根据我们的经验,经常有错误发生,而且大多数是我们平时不那么容易注意到的简单的错别字。
我们如何解决这个问题呢?我们通常在SNMP监控项上指定所有参数,上下文名称、密码、口令、社区名称等等,不需要在每一个创建的监控项上指定。现在,所有配置都在主机的接口级别上完成。当你创建新主机时,如果是网络设备,你就要添加一个SNMP接口,且必须选择SNMP版本。选择SNMP版本时(本示例中是SNMPv2),你还必须指明SNMP版本的所有必需参数。对于v2来说,只需要指定社区名称就可以了。然后,当你要在主机上创建所有监控项并选择该监控项类型为SNMPv2时,这些监控项可能是主机上或模板上创建的标准监控项,也可能是监控项原型。所有这些信息都从主机界面获取,因此输入错误的几率要小得多。而且即使出现问题,你不小心打错了字,你的所有监控项都无法使用。因此,即使主机上有2000个监控项,你也会注意到小错误,并将它修复。所以不会出现如下场景:监控项原型因为一个小错字而导致2000项中有1800项可以使用,而200项却无法使用,这种情况不会出现。所以我相信,对于所有Zabbix用户来说,这更加方便。我确信这些小功能会让你Zabbix的日常工作变得更加轻松。
我今天的演讲到此为止,我真心希望大家已经在使用5.0所有的这些功能了。