分类 Linux 下的文章

虽然家里的迷你服务器(锐角云三角主机)跑了N年,但是一直没有搞定USB硬盘在开机后自动挂载。每次断电重启后,都需要手工执行挂载。终于,通过SystemD的配置,解决了这个问题。

Debian 12上实现开机自动挂载USB磁盘,一般可以在系统启动过程或者系统启动后执行。如果在系统启动过程执行挂载,挂载过程出错,有可能导致系统启动失败(导致不能进入系统)。所以系统启动后执行挂载,相对稳妥。其方案很多,我选择了在fstab文件里通过SystemD的配置实现。

修改/etc/fstab文件,添加以下配置即可。

UUID=7d010a88-bc3c-7a2c-0270-3eae70edd016 /media/ud1 ext4 defaults,auto,nofail,x-systemd.automount,x-systemd.device-timeout=10s 0 0

相关参数解析如下:

  • UUID,填写USB磁盘里需要挂载分区的UUID。可以使用以下其中一条命令查看:

    ls -l /dev/disk/by-uuid/
    lsblk -f
    blkid
  • /media/ud1,设置挂载目录。
  • ext4,分区的文件系统类型。
  • defaults,使用默认选项,即rw,suid,dev,exec,auto,nouser,async

    • rw,挂载该文件系统可读写。
    • suid,从该文件系统执行程序时,遵循用户权限和组权限的设置。
    • dev,解释该文件系统上的字符或块特殊设备。
    • exec,允许执行二进制文件或其它可执行文件。
    • auto,标识mount -a命令可以自动挂载该文件系统,实现开机或重启时自动挂载。
    • nouser,普通用户不能执行挂载。
    • async,该文件系统的所有I/O都应该异步完成。
  • auto,同defaultsauto
  • nofail,设备不存在时,不报告错误信息。
  • x-systemd.automount,为该文件系统创建自动挂载单元(automount unit)。
  • x-systemd.device-timeout=10s,SystemD等待该设备可见(show up)的时间,超过该时间则放弃挂载,避免没有接入该USB磁盘而导致开机等太久。

参考

虽然MP3格式存在很多缺点,但是其通用性强、文件大小范围下保证一定的音质,所以存储的音乐文件还是使用MP3格式。

这里记录一下Ubuntu上的相关工具。

1. SoundConverter

获取到的音频文件,其格式可能是整盘录制成FLAC或APE,先转换成MP3格式,再切分。

2. Mp3splt

如果是整盘音频文件,一般会自带CUE文件,描述包含音轨的时间、名称等信息。音频文件转换成MP3后,需要改一下CUE文件里所指定的音频文件名,才能用Mp3splt执行切分。

参考命令格式:

mp3splt -c music.cue music.mp3

3. EasyTAG

用来修正MP3文件的Tag信息,包括内嵌图片。

上个月,发现“cloudflare.com”被解析为“127.0.0.1”,于是研究了一下DNS污染。

1. 检测

可以直接使用相关网站,检查各个DNS针对指定域名的解析是否正确。例如:

也可以使用命令或工具,查询使用指定DNS解析指定域名的结果。nslookup命令的示例如下:

# nslookup 域名 DNS地址
nslookup cloudflare.com 223.5.5.5

2. 解决方案

一般设置DNS为可靠的共用DNS即可。由于是网络运营商的DNS发现的污染,所以不推荐使用三大运营商的DNS。暂时改为使用“阿里公共DNS”。

最简单的是,修改网络出口设备(例如路由器)的DNS,所有网络设备(例如手机、电脑)都使用其默认DNS。比较麻烦的是,各个网络设备各自设置DNS。

国内外的免费公共DNS,可参考:

几个比较有名的DNS如下:

3. 扩展内容

3.1. 关于nslookup命令

一般各大系统都有nslookup命令。对于Debian 11和Ubuntu 22.04,可能没有默认安装nslookup,需要手动安装。

# Debian或Ubuntu,安装nslookup命令
sudo apt install bind9-dnsutils

# 查看域名的DNS A记录解析
nslookup -type=A cloudflare.com 223.5.5.5

该命令的详细说明,可以参考man nslookup或Debian官方文档:nslookup(1) — bind9-dnsutils — Debian bookworm — Debian Manpages

3.2. 如何修改DNS配置

3.2.1. 总结

  • 路由器,进入其管理后台,修改DNS配置。
  • 网络终端设备(电脑,手机等),需要明确配置DNS的范围,一般是:全局、指定网络接口、指定代理服务。
  • 全局DNS,需确定管理DNS服务的程序,再修改其配置文件。
  • 指定网络接口的DNS,一般修改其网卡设置。
  • 代理服务的DNS,一般不走本地设置,需要参考该代理服务的配置说明。

3.2.2. 关于配置全局DNS

对于Linux(例如Debian 12),一般查看/etc/resolv.conf文件,可以了解当前使用什么DNS。直接修改该文件,可以更改当前全局DNS,例如:

# 设置DNS为阿里DNS
nameserver 223.5.5.5

但是,如果有其它程序接管了/etc/resolv.conf文件,比如systemd-resolved服务,系统重启后会该文件被重置,导致设置无效。注意各个系统的情况不同,比如:

  • Debian 11/12,默认没有安装systemd-resolved
  • Ubuntu 22.04,默认安装并启用systemd-resolved

3.2.3. 关于配置网络接口DNS

  • 图形界面,通过网络配置,修改相应的DNS。

    • 例如Ubuntu 22.04,使用NetworkManager管理。网络接口的配置文件在/etc/NetworkManager/system-connections/
  • 命令界面,一般修改配置文件/etc/network/interfaces

    • 例如Debian 11/12,其示例配置如下:
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug enp3s0
#iface enp3s0 inet dhcp
iface enp3s0 inet static
    address 192.168.0.100
    netmask 255.255.255.0
    gateway 192.168.0.1
    dns-nameservers 223.5.5.5 192.168.0.1

3.3. 管理DNS缓存

3.3.1. Linux的DNS缓存

  1. 使用systemd-resolve,适合Ubuntu 20.04及以下、Debian 11/12等。
# 清除DNS缓存
sudo systemd-resolve --flush-caches

# 查看DNS缓存情况
sudo systemd-resolve --statistics

对于Debian 11/12,需要启用systemd-resolve服务。

sudo systemctl enable systemd-resolved.service
  1. 使用resolvectl,适合Ubuntu 20.04以上。
# 清除DNS缓存
sudo resolvectl flush-caches

# 查看DNS缓存情况
sudo resolvectl statistics
  1. 重启网络服务,清除DNS缓存,适合一般Linux。
# 基于Init.d的系统
sudo /etc/init.d/networking restart

# 基于SystemD的系统
sudo service networking restart

3.3.2. Windows的DNS缓存

rem 清除DNS缓存
ipconfig /flushdns

3.3.3. Chrome浏览器的DNS缓存

Chrome本身建立了自己的DNS缓存,并提供简单的管理功能。打开链接:chrome://net-internals/#dns 即可。

记录一下今天Lubuntu 22.04.2的桌面环境(LXQt 1.2.0)罢工,以及解决办法。

问题

今天打开电脑,直接进入tty1的字符界面(明明昨晚还是好好的)。登录后执行startlxqt,显示以下提示:

qt.qpa.xcb: could not connect to display
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: eglfs, linuxfb, minimal, offscreen, vnc, xcb.

Aborted

就是LXQt不能启动,导致不能进入图形界面环境。

解决

找了几个文章都没有解决。直到看了这个:

[SOLVED]cinnamon doesn't start because of segfault in libgtk-3.so.0.2404.27

该文章提到SDDM。于是执行了安装SSDM命令sudo apt install sddm,重启后就解决了。

总结

  1. 好久没有体验过Linux图形界面的脆弱了。
  2. 这个错误被提及很多,但是涉及的问题各有不同。是Qt5的锅吗?
  3. 习惯了日常升级系统,想不到Lubuntu也踩坑。

Linux系统,使用initd时,想要开机启动时执行指定Shell脚本,只需修改/etc/rc.local。现在的分发版基本改用Systemd,找不到rc.local了。要实现类似的功能,有两个方案:

  1. 启用rc-local.service服务。
  2. 创建一个开机启动的服务。

推荐方案2,可以设置服务关联。比如设置网络服务启动后才执行指定脚本。

以Debian 11为例,记录一下两个方案的具体操作。

方案1,启用rc-local.service服务

  1. 创建/etc/rc.local文件,并设置执行权限
cat <<EOF >/etc/rc.local
#!/bin/sh -e
# run at the end of each multiuser runlevel

exit 0 EOF
chmod +x /etc/rc.local

exit 0之前,编写要执行的Shell脚本。一定不要删除结尾的exit 0

  1. 启用服务
sudo systemctl enable --now rc-local

方案2,创建开机启动服务

就是配置一个Systemd服务,并设置开机启动。其启动的代码,就是执行指定Shell脚本。

  1. 创建配置文件。

在目录/etc/systemd/system,创建文件startup.service(文件名可自取),并添加以下内容:

#################################
# Run at startup
#################################

[Unit]
Description=Run the shell script at system startup.
Wants=network-online.target
After=network.target network-online.target

[Service]
Type=simple
WorkingDirectory=/opt/startup
ExecStart=/opt/startup/run.sh
User=root

[Install]
WantedBy=multi-user.target

其中ExecStart就是配置要执行的Shell脚本。这里假设Shell脚本需要联网后才能执行。

  1. 启用等待网络正常启动的服务。

服务配置依赖network-online.target时,需要开启systemd-networkd-wait-online.service服务,才能确保在网卡正确启动并获取IP地址后执行。

sudo systemctl enable systemd-networkd-wait-online.service
  1. 设置开机启动。
sudo systemctl daemon-reload
sudo enable startup.service

注:升级Chrome 114.0.5735.90后,问题已解决。

Lunbuntu 22.04.2,昨晚升级安装系统升级包后,Chrome浏览器渲染页面不正常了。具体是,页面背景色正常,布局正常,也能显示一些布局样式,但完全不显示相关文字,甚至有些图片也不能显示。

尝试Shell里直接运行/opt/google/chrome/chrome,会弹出以下信息:

MESA-INTEL: warning: Haswell Vulkan support is incomplete

应该是显卡与其驱动,不支持Chrome的新特性吧。

于是找到这个文章:Linux: Chrome Starts Very Slowly After Enable Nvidia Driver

根据文章的相关内容,尝试出三个可以正常渲染页面的Chrome浏览器的启动参数(如下)。

启动参数说明效果
--disable-gpu禁用GPU硬件加速。正常
--disable-gpu-driver-bug-workarounds禁用各种GPU驱动程序错误的解决方法。正常
--enable-features=Vulkan开启Vulkan特性可以渲染页面,但有些图片显示为黑块

最后的解决方案:

  1. 选用启动参数--disable-gpu-driver-bug-workarounds
  2. 修改/usr/bin/google-chrome文件,在最后一行exec -a "$0" "$HERE/chrome" "$@"中添加启动参数。即该文件的最后一行修改为:
#exec -a "$0" "$HERE/chrome" "$@"
exec -a "$0" "$HERE/chrome" --disable-gpu-driver-bug-workarounds "$@"

另外,关于Chrome浏览器的各个启动参数,有个文章整理得很详细:List of Chromium Command Line Switches

Nmon (Nigel's Monitor) 是AIX系统与Linux 系统上,开源免费的监控资源的工具。Njmon则是其下一代的形态。

Njmon的主要特点是:

  • 采用JSON保存数据。
  • 原生支持发送数据到InfluxDB。
  • 可配置不监控的数据。
  • 不支持终端显示数据。
  • 添加了相关工具,包括njmond、nmeasure、njmonchart等。

由于想玩玩InfluxDB,于是按照官方建议,部署了Njmon + InfluxDB + Grafana。然后总结以下缺点:

  • Njmon对Linux支持不足。比如Debian系统,需要自己编译。但是编译过程没什么困难。
  • Njmon虽然支持InfluxDB v2+,但Grafana上没找到能直接使用的模板。Grafana找到的模板是针对InfluxDB v1。
  • 相对Nmon,Njmon参考资料比较少。但是官方有提供Youtube视频教程。

Njmon + InfluxDB + Grafana的部署要点:

  1. njmon命令运行于“nimon”模式,直接连接到InfluxDB时,需要加参数-I
  2. njmon命令连接InfluxDB v2+,需要使用-O 组织名称 -T token这两个参数进行验证。

    # 示例,njmon连接到InfluxDB v2
    sudo ./njmon_Debian11_unknown_v80 -I -s 1 -i 127.0.0.1 -p 8086 -x bucket -O 组织名 -T xxxxxxxxxxx
  3. InfluxDB v2+同时提供v1接口时,需要创建对应数据库(Database)和保存策略(Retention Policies)。

    # 示例,InfluxDB v2创建对应的v1数据库和保存策略
    influx v1 dbrp create --db bucket-db --rp bucket-rp --bucket-id xxxxxx --default --org '组织名' --token 'xxxxxxxxxxx'
  4. InfluxDB可以使用Docker部署。

    # 示例,使用Docker部署InfluxDB v2.4.0
    docker run --name influxdb -p 8086:8086 -v /opt/influxdb/config.yml:/etc/influxdb2/config.yml --volume /opt/influxdb/data:/var/lib/influxdb2 influxdb:2.4.0
  5. Grafana如果没找到相关模板,只能找接近的,再自己修改一下。

总结。体验过InfluxDB + Grafana,挺爽的。只是,如果是用作监控,那么采集数据端不一定使用Njmon。

dstat是一个Linux监控工具。可定制采集数据,可设置采集频率,可输出字符界面和导出CSV。默认一秒一条监测数据。其中以top开头的参数,可以记录检测类型最大值的进程。比如--top-cpu记录CPU占用最大的命令,--top-cpu-adv还会记录CPU占用最大的进程ID等。参数--time的时间格式,需要通过环境变量DSTAT_TIMEFMT进行定义。

示例操作命令:

# 设置时间格式
export DSTAT_TIMEFMT='%Y-%m-%d %H:%M:%S'

# 执行监测,并导出CSV文件
dstat --time --cpu --mem --disk --io --net --sys --top-cpu-adv --top-mem --top-bio-adv --top-io-adv --output /opt/dstat_log/dstat_$(date +%Y%m%d).csv

使用时,可结合tmux,随时查看其采集数据,即时输出在终端。导出的CSV文件,需要下载到本地,并使用第三方工具生成图表。

在众多监控方案中,dstat不算优秀的解决方案,而且只有采集数据的功能。其记录数据,采用CSV格式。如果终端不够宽时,不能完整显示每行的采集数据。而且CSV格式不好扩展,比如--top-cpu-adv记录的数据,不适合机器理解。这里记录一下相关经验。

1 正式版的bug

安装过0.7.3和0.7.4两个版本,并使用Python3运行,都存在以下两个Bug。幸好是使用Python开发,可以直接修复。其安装路径为/usr/bin/dstat

a)在Debian 10以上使用Python3运行时,出现以下Bug:

/usr/bin/dstat:2619: DeprecationWarning: the imp module is deprecated in favour of importlib and slated for removal in Python 3.12; see the module's documentation for alternative uses
  import imp
Terminal width too small, trimming output.
Traceback (most recent call last):
  File "/usr/bin/dstat", line 2847, in <module>
    main()
  File "/usr/bin/dstat", line 2687, in main
    scheduler.run()
  File "/usr/lib/python3.10/sched.py", line 151, in run
    action(*argument, **kwargs)
  File "/usr/bin/dstat", line 2806, in perform
    oline = oline + o.showcsv() + o.showcsvend(totlist, vislist)
  File "/usr/bin/dstat", line 547, in showcsv
    if isinstance(self.val[name], types.ListType) or isinstance(self.val[name], types.TupleType):
NameError: name 'types' is not defined. Did you mean: 'type'?

解决办法,参考以下文档:

简单来说,改两行代码。如下:

# 第547行,改为:
if isinstance(self.val[name], (tuple, list)):

# 第552行,改为:
elif isinstance(self.val[name], str):

b)--top-mem参数统计错误的bug

参考文章:

修改方法def proc_splitline(filename, sep=None),改为:

if filename.startswith("/proc/") and filename.endswith("/stat") and filename != "/proc/stat":
    tmp = linecache.getline(filename, 1).split(sep)
    it = [i for i,c in enumerate(tmp) if c.endswith(')')]
    it = 2 if not it else it[-1]+1
    return tmp[0:1] + [' '.join(tmp[1:it])] + tmp[it:]
else:
    return linecache.getline(filename, 1).split(sep)

2 应用场景

感觉比较适合单机版,或者指定采集一些系统数据。不适合生产机大规模部署。如果非要用dstat不可,可以考虑 dstat + Fluentd + Influxdb + Grafana 这种组合方案。

最近因工作需要,研究了一下Linux服务器的监控方案,收获颇丰。

1 监控需求

服务器需要监控什么?可以分为硬件和软件,或者系统数据和业务数据。一般的监控解决方案,都是针对硬件、操作系统和常用软件(比如数据库、Docker之类)。涉及业务数据,需要二次开发。

2 监控方案设计

一般的监控方案,分为采集、存储、展示、告警,这四大模块或者功能。针对被监控服务器的数量,可灵活实施四个模块的部署方式。比较完善的整体解决方案,还包括“控制”模块,实现服务器集群的统一管理。

2.1 采集

数据采集程序,或者叫“探针”,一般是部署在被监控服务器上的程序。用于采集相关数据,要求占用系统资源小(主要是CPU、内存、磁盘、网络等),对系统影响小。

数据采集的方式,可以采用“推”(push)和“拉”(pull)模式。

“推”是数据采集程序主动把数据从采集端发到存储端。数据具有良好的实时性,方便内网部署并推送到外网服务器。但采集端太多,或者采集的数据比较大,需要考虑存储端的承受能力。遇到存储端没有收到数据时,不能确定是网络问题还是采集端问题。

“拉”是数据采集程序暴露出来,例如开放HTTP服务的端口,存储端去访问并获取数据。存储端也有更多的主动权,决定拉取频率,甚至决定采集样本,能降低带宽、减轻存储端的压力。采集不到数据时,能区分网络问题和采集端问题。如果对数据有实时需求,采集端需要保存未拉走的数据。

针对采集端有时只能部署在内网的情况,有的解决方案会提供“代理”或者“跳板”功能,实现采集端与存储断之间的数据连接。

2.2 存储

数据存储,就是把监控数据持久化,可以是文件(比如CSV文件),也可以是数据库(比如MySQL、InfluxDB)。目前主流的方案,基本采用时序数据库,例如InfluxDB。专门针对这种大量连续时间的数据,提供存储、查询、统计等功能。

2.3 展示

数据展示,一般是把监控数据生成图表,以便更直观地查看和分析。简单的方案是用Microsoft Excel之类的软件,根据导出CSV文件的数据,生成各种图表。主流和灵活的方案是使用可视化软件,例如Grafana,连接时序数据库并生成各种图表。Grafana能够实现实时展示和历史分析。

2.4 告警

通过检测采集的数据,发现超过指定危险指标时,向相关人员发送消息,就是告警。由于相关人员一般不会24小时盯着服务器,所以需要机器进行告警。InfluxDB、Prometheus、Grafana等都有告警功能。一般开源系统只提供邮件或Web Hook(调用钉钉接口)通知,商业系统(例如:阿里云的云监控)会有短信或电话通知。

3 解决方案

服务器监控的解决方案,像编程语言一样,没有一个万能方案,需要根据情况进行选择。这里列举一些相关软件或方案。

3.1 dstat

基于Python。默认一秒采集一条数据,数据定制性高。数据可显示在终端,也可导出CSV文件。需要使用第三方软件,例如Microsoft Excel之类,生成图表和分析数据。高级玩法是,搭配Fluentd,保存数据到InfluxDB,再用Grafana展示、分析。

优点是占用资源小,数据简单。缺点是由于使用CSV格式,复杂数据记录得不够好。而且当前版本(0.7.4)有bug,部署时需要自己修正。

3.2 njmon

C语言开发。nmon的升级版,可设置不收集的数据,数据格式采用JSON。不支持终端显示,原生支持导出文件和发送到InfluxDB。有官方工具处理保存的JSON文件。推荐的玩法是njmon + InfluxDB + Grafana。

优点是占用资源小,作者对整个监控方案考虑比较全面。缺点是对AIX较好但对Linux支持不足。比如Debian 11需要自己编译。Grafana的njmon模板大多针对AIX,而且仅有的Linux模板是针对InfluxDB v1,即使用InfluxQL而不是Flux。

3.3 glances

基于Python,开源跨平台,界面优秀。支持三种模式:单独运行、C/S、Web。提供XML-RPC服务、RESTful JSON接口,也可把数据保存到其它系统,包括InfluxDB。本身支持配置“Actions”,根据事件触发相应脚本,实现告警。

占用资源较大(包括CPU和磁盘空间),界面优秀,玩法多。适合桌面系统的监控。

3.4 InfluxDB

InfluxDB只是个时序数据库,但是该公司开发了Telegraf作为数据收集工具(采用“推”模式),并且InfluxDB新增了告警和图形化展示,形成一个完整的数据收集方案。

3.5 Prometheus

基于Go,监控、告警工具,使用“拉”模式采集数据。

3.6 Zabbix

企业级的开源的服务器监控管理系统,是完整的解决方案,基本可以替代阿里云的云监控之类的系统。Web控制台基于PHP,支持中文显示;采集端基于C,升级版改为Go;数据存储使用MySQL,未支持时序数据库是最突出的缺点。另外,告警功能不支持电话和短信通知。

非常适合企业内部管理服务器集群,便于运维人员使用。

3.7 阿里云的云监控

一般云主机的服务商都提供云监控功能,且基本监控免费,高级功能收费。阿里云的云监控,还能监控非阿里云的主机。使用这些云监控前,要确定是否可以把服务器监控数据发给云厂商,甚至安装云厂商的采集软件。

4 方案选型

根据不同的情况,总结一下各个方案的选型。

4.1 云主机

如果是购买云主机,可以考虑云服务提供商的云监控,一般免费提供基础监控功能,例如阿里云的云监控。但前提是,云主机可以安装云监控的采集端软件,并且接受相关数据上传到云服务提供商那边。另外,高级监控功能,需要付额使用。

4.2 运维管理的服务器集群

企业内部,有专门的运维人员管理服务器,针对硬件或操作系统相关数据的监控,则可以考虑Zabbix。

4.3 业务数据

node_exporter + Prometheus + Grafana,或者 Telegraf + InfluxDB + Grafana,这种方案适合收集业务日志。部署了InfluxDB,还能存储其它数据,个人觉得比较好玩。

最近接触了两款开源、跨平台、支持多种SQL数据库的数据库管理工具,值得记录一下。

DBeaver
官网:https://dbeaver.io/
2020年疫情期间,在家办公,想找个数据库管理工具,可以在Linux上访问SQL Server数据库,于是遇到DBeaver。界面像Eclipse,容易上手;基于Java,可以跨平台使用;使用JDBC,几乎支持所有数据库。在Linux上,几乎是万能的数据库管理工具了。

HeidiSQL
官网:https://www.heidisql.com/
在Windows上安装MariaDB 10.4.12时,发现自带了HeidiSQL数据库管理工具。界面及操作都跟MySQL Workbench相似,清晰明了,而且支持各种SQL数据。比较意外的是,其基于Delphi开发,所以Linux上需要利用Wine运行。