分类 技术 下的文章

当我们还在体验 Linux 5.5 稳定发行版带来更好的硬件支持时,Linux 5.6 已经来了。

说实话,Linux 5.6 比 5.5 更令人兴奋。即使即将发布的 Ubuntu 20.04 LTS 发行版将自带 Linux 5.5,你也需要切实了解一下 Linux 5.6 内核为我们提供了什么。

我将在本文中重点介绍 Linux 5.6 发布版中值得期待的关键更改和功能:

Linux 5.6 功能亮点

当 Linux 5.6 有新消息时,我会努力更新这份功能列表。但现在让我们先看一下当前已知的内容:

1、支持 WireGuard

WireGuard 将被添加到 Linux 5.6,出于各种原因的考虑它可能将取代 OpenVPN

你可以在官网上进一步了解 WireGuard 的优点。当然,如果你使用过它,那你可能已经知道它比 OpenVPN 更好的原因。

同样,Ubuntu 20.04 LTS 将支持 WireGuard

2、支持 USB4

Linux 5.6 也将支持 USB4

如果你不了解 USB 4.0 (USB4),你可以阅读这份文档

根据文档,“USB4 将使 USB 的最大带宽增大一倍并支持 多并发数据和显示协议 multiple simultaneous data and display protocols 。”

另外,虽然我们都知道 USB4 基于 Thunderbolt 接口协议,但它将向后兼容 USB 2.0、USB 3.0 以及 Thunderbolt 3,这将是一个好消息。

3、使用 LZO/LZ4 压缩 F2FS 数据

Linux 5.6 也将支持使用 LZO/LZ4 算法压缩 F2FS 数据。

换句话说,这只是 Linux 文件系统的一种新压缩技术,你可以选择待定的文件扩展技术。

4、解决 32 位系统的 2038 年问题

Unix 和 Linux 将时间值以 32 位有符号整数格式存储,其最大值为 2147483647。时间值如果超过这个数值则将由于整数溢出而存储为负数。

这意味着对于 32 位系统,时间值不能超过 1970 年 1 月 1 日后的 2147483647 秒。也就是说,在 UTC 时间 2038 年 1 月 19 日 03:14:07 时,由于整数溢出,时间将显示为 1901 年 12 月 13 日而不是 2038 年 1 月 19 日。

Linux kernel 5.6 解决了这个问题,因此 32 位系统也可以运行到 2038 年以后。

5、改进硬件支持

很显然,在下一个发布版中,硬件支持也将继续提升。而支持新式无线外设的计划也同样是优先的。

新内核中将增加对 MX Master 3 鼠标以及罗技其他无线产品的支持。

除了罗技的产品外,你还可以期待获得许多不同硬件的支持(包括对 AMD GPU、NVIDIA GPU 和 Intel Tiger Lake 芯片组的支持)。

6、其他更新

此外,Linux 5.6 中除了上述主要的新增功能或支持外,下一个内核版本也将进行其他一些改进:

  • 改进 AMD Zen 的温度/功率报告
  • 修复华硕飞行堡垒系列笔记本中 AMD CPU 过热
  • 开源支持 NVIDIA RTX 2000 图灵系列显卡
  • 内建 FSCRYPT 加密

Phoronix 跟踪了 Linux 5.6 带来的许多技术性更改。因此,如果你好奇 Linux 5.6 所涉及的全部更改,则可以亲自了解一下。

现在你已经了解了 Linux 5.6 发布版带来的新功能,对此有什么看法呢?在下方评论中留下你的看法。


via: https://itsfoss.com/linux-kernel-5-6/

作者:Ankush Das 选题:lujun9972 译者:LazyWolfLin 校对:wxy

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

介绍

在完成了界面的实现后,接下来可以开始进行和云开发相关的数据对接。完成数据对接后,应用基础就打好了,接下来的就是发布上线以及一些小的功能的加入。

配置

在进行相关的配置调用的时候,你需要先登录腾讯云控制台,进行一些配置。使用你的小程序账号登录腾讯云,并在其中找到“云开发”产品。进入到“产品控制台”。

在“产品控制台”中找到你的环境,点击进入“详情页”:

在环境“详情页面”选择“用户管理”->“登录设置”->“匿名登录”:

启用匿名登录。

云开发的数据查询目前必须登录后才可以查询,因为希望给用户提供的是免登录的解决方案,因此,必须开通匿名登录,确保可以进行数据查询。

由于需要在网页中调用相应的函数,因此,也需要在同一个页面的 WEB 安全域名中添加应用的上线域名(本地调试用的 localhost 无需添加)。

为应用程序添加匿名登录的逻辑

此部分代码位置:https://github.com/LCTT/tldr.linux.cn/blob/master/src/main.js

由于希望用户可以打开网页就可以查询数据,因此,必须在用户无感的情况下,完成匿名登录逻辑。

根据对 Vue 生命周期的预研,将相应的逻辑放在了 beforeCreate 中,确保在应用初始化完成后,就可以自动完成匿名登录。

具体实现代码如下:

// main.js
new Vue({
  router,
  vuetify,
  render: h => h(App),
  beforeCreate: function(){                   // 新增匿名登陆逻辑
        const auth = this.$tcb.auth();        // 新增匿名登陆逻辑
        auth.signInAnonymously();             // 新增匿名登陆逻辑
  }                                           // 新增匿名登陆逻辑
}).$mount('#app')

加入完成后,你可以使用云开发的数据库等命令,来完成相应的数据库调用,验证自己的调用是否正常。

在这里需要注意,由于 Vue 默认的 ESLint 规则限制,默认是无法在 Vue 项目代码中使用 console.log 的,你需要使用一些命令来跳过相应的检查 只需要在你需要打印变量的前一行加入 // eslint-disable-next-line 就可以避免对应的检查了。

调用数据

此部分代码位置:https://github.com/LCTT/tldr.linux.cn/blob/master/src/views/Result.vue

完成初始化后,就需要完成相应的数据调用,这里不再针对每一个进行讲解,选择一个例子来说明。

const db = this.$tcb.database();
const cmd = db.collection('command');
if(this.id){ // 这里的 id 是 props 传入的参数,为命令对应的 doc id
    cmd.doc(this.id).get().then(res => {
      this.command = res.data
    })
    }else{
    cmd.where({
      name: this.$route.params.cmd // 命令可以从 Route 中获取,但实际场景下,因为开启了 `props: true`,也可以直接从 props 中获取。
    }).limit(1).get().then(res => {
      this.command = res.data[0]
    }).catch((err) => {
      alert("命令查询出错,请联系我们")
      // eslint-disable-next-line
      console.error(err)
    })
}

在这段代码中,首先是前期挂载的 $tcb 中抽取 database() 对象,并基于 database() 对象构建 collection() 对象。 然后就是使用 collection() 对象进行查询。

由于这里涉及到不同的页面逻辑,使用了一个 if 来判断数据。上下两种分别是获取单个数据和使用多个数据的方法。获取到数据以后,将数据更新,同步到 Vue 的 Data 中,完成相应的逻辑的调用。

云开发登录的坑

此部分代码位置:https://github.com/LCTT/tldr.linux.cn/blob/master/src/main.js

由于为用户提供的是快速查询功能,因此希望用户无论何时都是无感进行查询的。但实际测试的时候,发现用户如果直接通过命令行登录的时候,会导致报错。根据控制台返回的信息来看,是用户登录状态尚未完成,就进行了数据查询。

通过查询云开发的文档,发现云开发的 auth 对象在登录的时候,可以传入一个 persistence 参数来控制身份信息的持久化。

由于默认使用的是会话 ,所以导致用户的登录态丢失。为了确保应用的状态正常进行,将 persistence 设置为 local,确保应用在一次登录后可以将用户登录状态下放到用户的存储 中,这样可以避免用户总是会遭遇请求失败的问题。

// main.js
new Vue({
  router,
  vuetify,
  render: h => h(App),
  beforeCreate: async function(){
        const auth = this.$tcb.auth({ persistence: 'local' });
        await auth.signInAnonymously();
  }
}).$mount('#app')

总结

在实际开发中,如果你需要通过云开发的 Web SDK 调用相应的数据,则需要先行开启云开发的匿名登录并配置 Web 安全域名;在数据调用的部分和在小程序端调用云开发没有太大的区别;并通过设置 presistence 设置搞定了登录状态丢失的问题。

有一些命令可以用来检查 Linux 系统中的内存使用情况,下面是一些更好的命令。

Fancycrave

有许多工具可以查看 Linux 系统中的内存使用情况。一些命令被广泛使用,比如 freeps。而另一些命令允许通过多种方式展示系统的性能统计信息,比如 top。在这篇文章中,我们将介绍一些命令以帮助你确定当前占用着最多内存资源的用户或者进程。

下面是一些按照进程查看内存使用情况的命令:

按照进程查看内存使用情况

使用 top

top 是最好的查看内存使用情况的命令之一。为了查看哪个进程使用着最多的内存,一个简单的办法就是启动 top,然后按下 shift+m,这样便可以查看按照内存占用百分比从高到底排列的进程。当你按下了 shift+m ,你的 top 应该会得到类似于下面这样的输出结果:

$top
top - 09:39:34 up 5 days, 3 min,  3 users,  load average: 4.77, 4.43, 3.72
Tasks: 251 total,   3 running, 247 sleeping,   1 stopped,   0 zombie
%Cpu(s): 50.6 us, 35.9 sy,  0.0 ni, 13.4 id,  0.2 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   5944.4 total,    128.9 free,   2509.3 used,   3306.2 buff/cache
MiB Swap:   2048.0 total,   2045.7 free,      2.2 used.   3053.5 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  400 nemo      20   0 3309580 550188 168372 S   0.3   9.0   1:33.27 Web Content
32469 nemo      20   0 3492840 447372 163296 S   7.3   7.3   3:55.60 firefox
32542 nemo      20   0 2845732 433388 140984 S   6.0   7.1   4:11.16 Web Content
  342 nemo      20   0 2848520 352288 118972 S  10.3   5.8   4:04.89 Web Content
 2389 nemo      20   0 1774412 236700  90044 S  39.7   3.9   9:32.64 vlc
29527 nemo      20   0 2735792 225980  84744 S   9.6   3.7   3:02.35 gnome-shell
30497 nemo      30  10 1088476 159636  88884 S   0.0   2.6   0:11.99 update-manager
30058 nemo      20   0 1089464 140952  33128 S   0.0   2.3   0:04.58 gnome-software
32533 nemo      20   0 2389088 104712  79544 S   0.0   1.7   0:01.43 WebExtensions
 2256 nemo      20   0 1217884 103424  31304 T   0.0   1.7   0:00.28 vlc
 1713 nemo      20   0 2374396  79588  61452 S   0.0   1.3   0:00.49 Web Content
29306 nemo      20   0  389668  74376  54340 S   2.3   1.2   0:57.25 Xorg
32739 nemo      20   0  289528  58900  34480 S   1.0   1.0   1:04.08 RDD Process
29732 nemo      20   0  789196  57724  42428 S   0.0   0.9   0:00.38 evolution-alarm
 2373 root      20   0  150408  57000   9924 S   0.3   0.9  10:15.35 nessusd

注意 %MEM 排序。列表的大小取决于你的窗口大小,但是占据着最多的内存的进程将会显示在列表的顶端。

使用 ps

ps 命令中的一列用来展示每个进程的内存使用情况。为了展示和查看哪个进程使用着最多的内存,你可以将 ps 命令的结果传递给 sort 命令。下面是一个有用的示例:

$ ps aux | sort -rnk 4 | head -5
nemo       400  3.4  9.2 3309580 563336 ?      Sl   08:59   1:36 /usr/lib/firefox/firefox -contentproc -childID 6 -isForBrowser -prefsLen 9086 -prefMapSize 210653 -parentBuildID 20200107212822 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 32469 true tab
nemo     32469  8.2  7.7 3492840 469516 ?      Sl   08:54   4:15 /usr/lib/firefox/firefox -new-window
nemo     32542  8.9  7.6 2875428 462720 ?      Sl   08:55   4:36 /usr/lib/firefox/firefox -contentproc -childID 2 -isForBrowser -prefsLen 1 -prefMapSize 210653 -parentBuildID 20200107212822 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 32469 true tab
nemo       342  9.9  5.9 2854664 363528 ?      Sl   08:59   4:44 /usr/lib/firefox/firefox -contentproc -childID 5 -isForBrowser -prefsLen 8763 -prefMapSize 210653 -parentBuildID 20200107212822 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 32469 true tab
nemo      2389 39.5  3.8 1774412 236116 pts/1  Sl+  09:15  12:21 vlc videos/edge_computing.mp4

在上面的例子中(文中已截断),sort 命令使用了 -r 选项(反转)、-n 选项(数字值)、-k 选项(关键字),使 sort 命令对 ps 命令的结果按照第四列(内存使用情况)中的数字逆序进行排列并输出。如果我们首先显示 ps 命令的标题,那么将会便于查看。

$ ps aux | head -1; ps aux | sort -rnk 4 | head -5
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
nemo       400  3.4  9.2 3309580 563336 ?      Sl   08:59   1:36 /usr/lib/firefox/firefox -contentproc -childID 6 -isForBrowser -prefsLen 9086 -prefMapSize 210653 -parentBuildID 20200107212822 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 32469 true tab
nemo     32469  8.2  7.7 3492840 469516 ?      Sl   08:54   4:15 /usr/lib/firefox/firefox -new-window
nemo     32542  8.9  7.6 2875428 462720 ?      Sl   08:55   4:36 /usr/lib/firefox/firefox -contentproc -childID 2 -isForBrowser -prefsLen 1 -prefMapSize 210653 -parentBuildID 20200107212822 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 32469 true tab
nemo       342  9.9  5.9 2854664 363528 ?      Sl   08:59   4:44 /usr/lib/firefox/firefox -contentproc -childID 5 -isForBrowser -prefsLen 8763 -prefMapSize 210653 -parentBuildID 20200107212822 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 32469 true tab
nemo      2389 39.5  3.8 1774412 236116 pts/1  Sl+  09:15  12:21 vlc videos/edge_computing.mp4

如果你喜欢这个命令,你可以用下面的命令为他指定一个别名,如果你想一直使用它,不要忘记把该命令添加到你的 ~/.bashrc 文件中。

$ alias mem-by-proc="ps aux | head -1; ps aux | sort -rnk 4"

下面是一些根据用户查看内存使用情况的命令:

按用户查看内存使用情况

使用 top

按照用户检查内存使用情况会更复杂一些,因为你需要找到一种方法把用户所拥有的所有进程统计为单一的内存使用量。

如果你只想查看单个用户进程使用情况,top 命令可以采用与上文中同样的方法进行使用。只需要添加 -U 选项并在其后面指定你要查看的用户名,然后按下 shift+m 便可以按照内存使用有多到少进行查看。

$ top -U nemo
top - 10:16:33 up 5 days, 40 min,  3 users,  load average: 1.91, 1.82, 2.15
Tasks: 253 total,   2 running, 250 sleeping,   1 stopped,   0 zombie
%Cpu(s): 28.5 us, 36.8 sy,  0.0 ni, 34.4 id,  0.3 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   5944.4 total,    224.1 free,   2752.9 used,   2967.4 buff/cache
MiB Swap:   2048.0 total,   2042.7 free,      5.2 used.   2812.0 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  400 nemo      20   0 3315724 623748 165440 S   1.0  10.2   1:48.78 Web Content
32469 nemo      20   0 3629380 607492 161688 S   2.3  10.0   6:06.89 firefox
32542 nemo      20   0 2886700 404980 136648 S   5.6   6.7   6:50.01 Web Content
  342 nemo      20   0 2922248 375784 116096 S  19.5   6.2   8:16.07 Web Content
 2389 nemo      20   0 1762960 234644  87452 S   0.0   3.9  13:57.53 vlc
29527 nemo      20   0 2736924 227260  86092 S   0.0   3.7   4:09.11 gnome-shell
30497 nemo      30  10 1088476 156372  85620 S   0.0   2.6   0:11.99 update-manager
30058 nemo      20   0 1089464 138160  30336 S   0.0   2.3   0:04.62 gnome-software
32533 nemo      20   0 2389088 102532  76808 S   0.0   1.7   0:01.79 WebExtensions

使用 ps

你依旧可以使用 ps 命令通过内存使用情况来排列某个用户的进程。在这个例子中,我们将使用 grep 命令来筛选得到某个用户的所有进程。

$ ps aux | head -1; ps aux | grep ^nemo| sort -rnk 4 | more
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
nemo     32469  7.1 11.5 3724364 701388 ?      Sl   08:54   7:21 /usr/lib/firefox/firefox -new-window
nemo       400  2.0  8.9 3308556 543232 ?      Sl   08:59   2:01 /usr/lib/firefox/firefox -contentproc -childID 6 -isForBrowser -prefsLen 9086 -prefMapSize 210653 -parentBuildID 20200107212822 -greomni /usr/lib/firefox/omni.ja -appomni/usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 32469 true tab
nemo     32542  7.9  7.1 2903084 436196 ?      Sl   08:55   8:07 /usr/lib/firefox/firefox -contentproc -childID 2 -isForBrowser -prefsLen 1 -prefMapSize 210653 -parentBuildID 20200107212822 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 32469 true tab
nemo       342 10.8  7.0 2941056 426484 ?      Rl   08:59  10:45 /usr/lib/firefox/firefox -contentproc -childID 5 -isForBrowser -prefsLen 8763 -prefMapSize 210653 -parentBuildID 20200107212822 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 32469 true tab
nemo      2389 16.9  3.8 1762960 234644 pts/1  Sl+  09:15  13:57 vlc videos/edge_computing.mp4
nemo     29527  3.9  3.7 2736924 227448 ?      Ssl  08:50   4:11 /usr/bin/gnome-shell

使用 ps 和其他命令的搭配

如果你想比较某个用户与其他用户内存使用情况将会比较复杂。在这种情况中,创建并排序一个按照用户总的内存使用量是一个不错的方法,但是它需要做一些更多的工作,并涉及到许多命令。在下面的脚本中,我们使用 ps aux | grep -v COMMAND | awk '{print $1}' | sort -u 命令得到了用户列表。其中包含了系统用户比如 syslog。我们对每个任务使用 awk 命令以收集每个用户总的内存使用情况。在最后一步中,我们展示每个用户总的内存使用量(按照从大到小的顺序)。

#!/bin/bash

stats=””
echo "%   user"
echo "============"

# collect the data
for user in `ps aux | grep -v COMMAND | awk '{print $1}' | sort -u`
do
  stats="$stats\n`ps aux | egrep ^$user | awk 'BEGIN{total=0}; \
    {total += $4};END{print total,$1}'`"
done

# sort data numerically (largest first)
echo -e $stats | grep -v ^$ | sort -rn | head

这个脚本的输出可能如下:

$ ./show_user_mem_usage
%   user
============
69.6 nemo
5.8 root
0.5 www-data
0.3 shs
0.2 whoopsie
0.2 systemd+
0.2 colord
0.2 clamav
0 syslog
0 rtkit

在 Linux 有许多方法可以报告内存使用情况。可以通过一些用心设计的工具和命令,来查看并获得某个进程或者用户占用着最多的内存。


via: https://www.networkworld.com/article/3516319/showing-memory-usage-in-linux-by-process-and-user.html

作者:Sandra Henry-Stocker 选题:lujun9972 译者:萌新阿岩 校对:wxy

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

工作量分析

在我们进行这部分开发的时候,接下来我们需要进行相应的功能安排和分类。

简单看来,我需要开发 3 个页面:

  1. 首页:首页负责用户默认访问。
  2. 列表页:列表页面则是在搜索过程中,如果有多个结果,则进入到列表页面。如果有单个结果,则应该进入到详情页面。
  3. 结果页:结果页负责显示命令的具体的翻译结果。

根据实际的工作拆分组件的化,我需要有一个 Layout 组件来负责整体的页面的环境渲染。但是,考虑到组件的复用,于是决定将首页的 Title 进行优化,使首页和详情页保持一致。

在新版的布局情况下,我就可以将顶部的的 title 和底部的 Link 放在最外侧的组件中。

创建 Router & Page

在思考情况后,接下来我们来创建 Router 和 Page。首先,删除 views 下的 About.vue(因为这个页面我们不需要)。然后创建 List.vueResult.vue ,用作后续的开发准备。

创建完成后,修改 router/index.js 中的 routes 部分:

const routes = [
  {
    path: '/',
    name: 'home',
    component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue')
  },
  {
    path: '/list/:cmd',
    name: 'list',
    component: () => import(/* webpackChunkName: "list" */ '../views/List.vue')
  },
  {
    path: '/cmd/:cmd',
    name: 'command',
    component: () => import(/* webpackChunkName: "cmd" */ '../views/Result.vue')
  }
]

完成定义后,我们就可以通过形如 https://tldr.linux.cn/list/ls和https://tldr.linux.cn/cmd/ls 这样的方式来访问具体的命令了。

定义页面

接下来需要编写 Home、List 和 Result 这三个页面。由于这三个页面在内容方面没有太多的可以借鉴的点,所以我们更多关注于使用页面中 <script> 的部分。

<template>
  <div class="home">
        <v-text-field
        v-model="cmd"
        @keydown="onKeyDown"
        autofocus
        ></v-text-field>        
  </div>
</template>

<script>
export default {
  name: 'home',
  data:function(){
    return {
      cmd:""
    }
  },
  methods:{
    onKeyDown: function(e)  {
     
    }
  },
  computed:{
    isLoaded:function(){
        return !this.loaded
    }
  }
}
</script>

上述代码是我在三个页面几乎都会使用到的结构,删除其中的一些无用的代码以后,基本上在每个页面都可以看到。这里我重点说一下其中的一些比较特殊的用法。

首先第一个是在 v-text-field 上加入的 @keydown="onKeyDown" 这个绑定,这个绑定将会帮助实现用户点击回车以后,自动触发事件。这样在用户输入完命令后,按下回车就自动执行后续的操作,而不需要再移动鼠标指针去点击按钮启动搜索。

其次,在 v-text-field 上加入了autofocus ,来实现进入页面后,自动为输入框加入focus,从而实现页面加载完成后,用户就可以输入命令。

这样的一些配置,可以让用户的体验做到最好

除此之外,我还用到了 computed ,来做数据调整,确保我可以控制内容。

一些小的特性的点

使用骨架图来优化体验

由于我们的应用在列表页面和详情页面存在数据的查询时间,为了让应用在加载的时候,不会因为加载中而退出页面,我加入了 v-skeleton-loader 组件,这样用户在数据查询的时候,看骨架图来缓解用户的焦虑。

在组件层面,我配置了 v-if 来做显示的控制,并将 type 设置为 card,article,card,article 来实现多样化的组件加载支持。

 <v-skeleton-loader
    v-if="isLoaded"
    type="card,article,card,article"
    min-height="800"
    ></v-skeleton-loader>

总结

在这一部分中,借助 Vue 的 methodonkeydowncomputed 实现了页面基本逻辑的构建。并借助 Vuetify 的一些基础组件来构建页面。

在这一部分,我想告诉大家的更多是在 UI 的部分,我们在做的时候不仅仅需要考虑的是界面,更多还需要考虑在 UX 侧体验的优化,组件库提供给我们的配置项目,可以优化产品体验。

了解分布式跟踪中的主要体系结构决策,以及各部分如何组合在一起。

早在十年前,认真研究过分布式跟踪基本上只有学者和一小部分大型互联网公司中的人。对于任何采用微服务的组织来说,它如今成为一种筹码。其理由是确立的:微服务通常会发生让人意想不到的错误,而分布式跟踪则是描述和诊断那些错误的最好方法。

也就是说,一旦你准备将分布式跟踪集成到你自己的应用程序中,你将很快意识到对于不同的人来说“ 分布式跟踪 Distributed Tracing ”一词意味着不同的事物。此外,跟踪生态系统里挤满了具有相似内容的重叠项目。本文介绍了分布式跟踪系统中四个(可能)独立的功能模块,并描述了它们间将如何协同工作。

分布式跟踪:一种思维模型

大多数用于跟踪的思维模型来源于 Google 的 Dapper 论文OpenTracing 使用相似的术语,因此,我们从该项目借用了以下术语:

 title=

  • 跟踪 Trace :事物在分布式系统运行的过程描述。
  • 跨度 Span :一种命名的定时操作,表示工作流的一部分。跨度可接受键值对标签以及附加到特定跨度实例的细粒度的、带有时间戳的结构化日志。
  • 跨度上下文 Span context :携带分布式事务的跟踪信息,包括当它通过网络或消息总线将服务传递给服务时。跨度上下文包含跟踪标识符、跨度标识符以及跟踪系统所需传播到下游服务的任何其他数据。

如果你想要深入研究这种思维模式的细节,请仔细参照 OpenTracing 技术规范

四大功能模块

从应用层分布式跟踪系统的观点来看,现代软件系统架构如下图所示:

 title=

现代软件系统的组件可分为三类:

  • 应用程序和业务逻辑:你的代码。
  • 广泛共享库:他人的代码
  • 广泛共享服务:他人的基础架构

这三类组件有着不同的需求,驱动着监控应用程序的分布式跟踪系统的设计。最终的设计得到了四个重要的部分:

  • 跟踪检测 API A tracing instrumentation API :修饰应用程序代码
  • 线路协议 Wire protocol :在 RPC 请求中与应用程序数据一同发送的规定
  • 数据协议 Data protocol :将异步信息(带外)发送到你的分析系统的规定
  • 分析系统 Analysis system :用于处理跟踪数据的数据库和交互式用户界面

为了更深入的解释这个概念,我们将深入研究驱动该设计的细节。如果你只需要我的一些建议,请跳转至下方的四大解决方案。

需求,细节和解释

应用程序代码、共享库以及共享式服务在操作上有显著的差别,这种差别严重影响了对其进行检测的请求操作。

检测应用程序代码和业务逻辑

在任何特定的微服务中,由微服务开发者编写的大部分代码是应用程序或者商业逻辑。这部分代码规定了特定区域的操作。通常,它包含任何特殊、独一无二的逻辑判断,这些逻辑判断首先证明了创建新型微服务的合理性。基本上按照定义,该代码通常不会在多个服务中共享或者以其他方式出现。

也即是说你仍需了解它,这也意味着需要以某种方式对它进行检测。一些监控和跟踪分析系统使用 黑盒代理 black-box agents 自动检测代码,另一些系统更想使用显式的白盒检测工具。对于后者,抽象跟踪 API 提供了许多对于微服务的应用程序代码来说更为实用的优势:

  • 抽象 API 允许你在不重新编写检测代码的条件下换新的监视工具。你可能想要变更云服务提供商、供应商和监测技术,而一大堆不可移植的检测代码将会为该过程增加有意义的开销和麻烦。
  • 事实证明,除了生产监控之外,该工具还有其他有趣的用途。现有的项目使用相同的跟踪工具来驱动测试工具、分布式调试器、“混沌工程”故障注入器和其他元应用程序。
  • 但更重要的是,若将应用程序组件提取到共享库中要怎么办呢?由上述内容可得到结论:

检测共享库

在大多数应用程序中出现的实用程序代码(处理网络请求、数据库调用、磁盘写操作、线程、并发管理等)通常情况下是通用的,而非特别应用于某个特定应用程序。这些代码会被打包成库和框架,而后就可以被装载到许多的微服务上并且被部署到多种不同的环境中。

其真正的不同是:对于共享代码,其他人则成为了使用者。大多数用户有不同的依赖关系和操作风格。如果尝试去使用该共享代码,你将会注意到几个常见的问题:

  • 你需要一个 API 来编写检测。然而,你的库并不知道你正在使用哪个分析系统。会有多种选择,并且运行在相同应用下的所有库无法做出不兼容的选择。
  • 由于这些包封装了所有网络处理代码,因此从请求报头注入和提取跨度上下文的任务往往指向 RPC 库。然而,共享库必须了解到每个应用程序正在使用哪种跟踪协议。
  • 最后,你不想强制用户使用相互冲突的依赖项。大多数用户有不同的依赖关系和操作风格。即使他们使用 gRPC,绑定的 gRPC 版本是否相同?因此任何你的库附带用于跟踪的监控 API 必定是免于依赖的。

因此,一个(a)没有依赖关系、(b)与线路协议无关、(c)使用流行的供应商和分析系统的抽象 API 应该是对检测共享库代码的要求。

检测共享式服务

最后,有时整个服务(或微服务集合体)的通用性足以使许多独立的应用程序使用它们。这种共享式服务通常由第三方托管和管理,例如缓存服务器、消息队列以及数据库。

从应用程序开发者的角度来看,理解共享式服务本质上是黑盒子是极其重要的。它不可能将你的应用程序监控注入到共享式服务。恰恰相反,托管服务通常会运行它自己的监控方案。

四个方面的解决方案

因此,抽象的跟踪应用程序接口将会帮助库发出数据并且注入/抽取跨度上下文。标准的线路协议将会帮助黑盒服务相互连接,而标准的数据格式将会帮助分离的分析系统合并其中的数据。让我们来看一下部分有希望解决这些问题的方案。

跟踪 API:OpenTracing 项目

如你所见,我们需要一个跟踪 API 来检测应用程序代码。为了将这种工具扩展到大多数进行跨度上下文注入和提取的共享库中,则必须以某种关键方式对 API 进行抽象。

OpenTracing 项目主要针对解决库开发者的问题,OpenTracing 是一个与供应商无关的跟踪 API,它没有依赖关系,并且迅速得到了许多监控系统的支持。这意味着,如果库附带了内置的本地 OpenTracing 工具,当监控系统在应用程序启动连接时,跟踪将会自动启动。

就个人而言,作为一个已经编写、发布和操作开源软件十多年的人,在 OpenTracing 项目上工作并最终解决这个观察性的难题令我十分满意。

除了 API 之外,OpenTracing 项目还维护了一个不断增长的工具列表,其中一些可以在这里找到。如果你想参与进来,无论是通过提供一个检测插件,对你自己的 OSS 库进行本地测试,或者仅仅只想问个问题,都可以通过 Gitter 向我们打招呼。

线路协议: HTTP 报头 trace-context

为了监控系统能进行互操作,以及减轻从一个监控系统切换为另外一个时带来的迁移问题,需要标准的线路协议来传播跨度上下文。

w3c 分布式跟踪上下文社区小组在努力制定此标准。目前的重点是制定一系列标准的 HTTP 报头。该规范的最新草案可以在此处找到。如果你对此小组有任何的疑问,邮件列表Gitter 聊天室是很好的解惑地点。

(LCTT 译注:本文原文发表于 2018 年 5 月,可能现在社区已有不同进展)

数据协议 (还未出现!!)

对于黑盒服务,在无法安装跟踪程序或无法与程序进行交互的情况下,需要使用数据协议从系统中导出数据。

目前这种数据格式和协议的开发工作尚处在初级阶段,并且大多在 w3c 分布式跟踪上下文工作组的上下文中进行工作。需要特别关注的是在标准数据模式中定义更高级别的概念,例如 RPC 调用、数据库语句等。这将允许跟踪系统对可用数据类型做出假设。OpenTracing 项目也通过定义一套标准标签集来解决这一事务。该计划是为了使这两项努力结果相互配合。

注意当前有一个中间地带。对于由应用程序开发者操作但不想编译或以其他方式执行代码修改的“网络设备”,动态链接可以帮助避免这种情况。主要的例子就是服务网格和代理,就像 Envoy 或者 NGINX。针对这种情况,可将兼容 OpenTracing 的跟踪器编译为共享对象,然后在运行时动态链接到可执行文件中。目前 C++ OpenTracing API 提供了该选项。而 JAVA 的 OpenTracing 跟踪器解析也在开发中。

这些解决方案适用于支持动态链接,并由应用程序开发者部署的的服务。但从长远来看,标准的数据协议可以更广泛地解决该问题。

分析系统:从跟踪数据中提取有见解的服务

最后不得不提的是,现在有足够多的跟踪监视解决方案。可以在此处找到已知与 OpenTracing 兼容的监控系统列表,但除此之外仍有更多的选择。我更鼓励你研究你的解决方案,同时希望你在比较解决方案时发现本文提供的框架能派上用场。除了根据监控系统的操作特性对其进行评级外(更不用提你是否喜欢 UI 和其功能),确保你考虑到了上述三个重要方面、它们对你的相对重要性以及你感兴趣的跟踪系统如何为它们提供解决方案。

结论

最后,每个部分的重要性在很大程度上取决于你是谁以及正在建立什么样的系统。举个例子,开源库的作者对 OpenTracing API 非常感兴趣,而服务开发者对 trace-context 规范更感兴趣。当有人说一部分比另一部分重要时,他们的意思通常是“一部分对我来说比另一部分重要”。

然而,事实是:分布式跟踪已经成为监控现代系统所必不可少的事物。在为这些系统进行构建模块时,“尽可能解耦”的老方法仍然适用。在构建像分布式监控系统一样的跨系统的系统时,干净地解耦组件是维持灵活性和前向兼容性地最佳方式。

感谢你的阅读!现在当你准备好在你自己的应用程序中实现跟踪服务时,你已有一份指南来了解他们正在谈论哪部分部分以及它们之间如何相互协作。


via: https://opensource.com/article/18/5/distributed-tracing

作者:Ted Young 选题:lujun9972 译者:chenmu-kk 校对:wxy

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

“Linux” 小程序是 Linux 中国在 2019 年 2 月(恰恰是去年春节)发布的小程序,该小程序采用众包模式,对著名的 TLDR 项目中的 Linux 命令示例进行了翻译,并通过微信小程序的形式展现。在 2020 年的春节,我们面向更多的 PC 端用户,开放了 Web 版的 Linux 命令查询。Web 版和小程序版数据同步,让你在使用桌面计算机时也可以进行命令查询。

从今天起,我们将在 Linux 中国官网和公众号上,连载 TL;DR Web 应用开发背后的故事。接下来,请看来自开发 gg 的文章。

背景描述

Linux 中国曾在过去的一年开发和运行了一个中国版 TL;DR 客户端。不过当时做的版本是小程序的版本,一直以来,受限于小程序·云开发没有 Web SDK ,因此无法将应用能力迁移到更多的平台上。刚好最近云开发提供了 Web SDK,并已经逐步成熟,于是我们便可以借此机会,将业务实现 PC 化,服务更多人群。

在开发出初步的版本之后,我们决定以这个项目作为范例,将我们开发经验分享给大家,大家可以参考开发自己的云应用。

项目设计

在进行项目开发时,先对项目进行了基本的 UI 设计:

主页

详情页

这里用到的是 balsamiq 的手绘线框图来完成产品设计,以避免我个人过度追求完美,而让产品延期迟迟不能上线的问题(这样的事情在历史上发生了非常多次)

技术选项

由于需要的是一个前端页面,因此,在技术选型方面,几乎没有太多的异议。使用最为熟悉的技术栈来完成。

  • 前端框架:Vue
  • 路由器:Vue Router
  • CSS 框架:Vuetify.js

镜像配置

因为身处国内, npm 的速度必然不太好,因此需要进行相应的镜像设定,确保 npm 和 yarn 在安装依赖。这里使用的是腾讯云提供的镜像。

# Npm 设置
npm config set registry http://mirrors.cloud.tencent.com/npm/

# yarn 设置
yarn config set registry http://mirrors.cloud.tencent.com/npm/ -g

初始化 Vue 项目

首先,需要安装 Vue CLI,以进行项目的生成,这里我已经完成安装,就不再赘述。(Vue CLI 的安装教程点击这里

执行如下命令初始化项目:

vue create tldr

等待其完成安装以后,进入项目,并启动项目。

cd tldr
yarn serve

随即,可以在浏览器中访问 localhost:8080 查看项目:

预览

记得引入 git 做版本控制,文章里就不介绍了。没意思。

安装 Vue Router

在完成 Vue 项目的初始化以后,接下来需要进行 Vue Router 的配置了。

Vue Router 的配置在引入了 Vue 3 以后,显得非常的简单,直接执行如下命令即可:

vue add router

执行过程中,会问你是否需要启用 History Mode,根据需要选取,我使用的是 History Mode。

设置完成以后,保存并重启 Vue 的开发服务器,你会在预览中看到 Router 添加的 “Home” 和 “About”。

安装 Vuetify.js

接下来安装的是 Vuetify.js ,由于框架提供了相应的支持,因此在开发时也非常简单,只需要执行如下命令就可以完成初始化。

vue add vuetify

会问你选择那种预设,直接使用 Default 即可。

保存并重启开发服务器,你会看到这样的界面,则说明配置完成。

部署测试应用

在进行下一步开发的时候,需要先进行一下项目的部署,从而获得一个测试的域名,方便后续的开发。

这里项目的开发我并没有使用云开发自己的 Web 托管 (因为我们不是按量付费套餐,所以没有办法开启),而是使用了 Now.sh 的,这里就不再过多赘述。

引入云开发 SDK

云开发提供了 Web SDK ,可以通过 npm 安装,并引用。

执行如下命令来安装:

yarn add tcb-js-sdk

安装完成后,在 main.js 中引入 tcb,并通过修改 Vue 的原型来实现挂载 Vue。

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import vuetify from './plugins/vuetify';
const tcb = require('tcb-js-sdk')  // 新增的引入 TCB

Vue.config.productionTip = false

Vue.prototype['$tcb'] = tcb.init({ // 新增的修改原型
    env: 'prod-2c59c7'             // 新增的修改原型
})                                 // 新增的修改原型

new Vue({
  router,
  vuetify,
  render: h => h(App)
}).$mount('#app')

这样就可以在应用运行的整个周期中使用 this.$tcb 来调用云开发的相关逻辑。

总结

在完成了项目的初始化以后,回过头来看一看这在初始化项目过程中,都做了哪些事情。

  1. 配置 npm 镜像,以确保 Node 包的安装速度
  2. 使用 Vue CLI 来初始化项目
  3. 安装 Vue Router & Vuetify.js
  4. 部署应用
  5. 安装 tcb-js-sdk 以调用云开发数据

请期待本系列的下一篇关于界面开发的文章。