将 Evernote 笔记导入到 Obsidian

不久之前看到 Obsidian 推出了一个官方的插件可以将 Evernote 的笔记导入到 Obsidian 中,于是就把「将 Evernote 笔记导入到 Obisidian」列为了一项我的待办事项,虽然已经很多年没有用 Evernote 了,但里面还有一些摘录,我一直认为笔记只有能被检索到才有价值,而 Obsidian 的检索速度也非常快,虽然没有 OCR,但纯文本的检索如果能被反复找到,那么可能那些笔记还有价值。

准备老版本的 Evernote

如果使用最新版本的 Evernote,那么登录的时候 Evernote 就会弹窗让你付费,或者试用 7 天,如果点击取消只能退出账户。所以这个时候可以下载一个老版本的,比如 7.10 版本的 Evernote。你可以从 MacUpldate 这个网站上下载到老版本的 Evernote。

登录 Evernote 之后等待同步下载笔记,

Uwa2

选中 All Notes,然后 Cmd + A 选中所有的笔记。然后右击,导出笔记,然后勾选「Include tags for each node」。接下来就是漫长的导出时间。

安装 Importer 插件

打开 Obsidian,然后在插件安装列表中搜索「Importer」,找到 Obsidian 官方出的插件,下载。之后在侧边栏会多出一个按钮,通过这个按钮调出导入的对话框。

U79G

在该对话框中设置刚刚导出的 .enex 文件,然后导出到的文件夹。点击 Import,之后就根据笔记的数量会有一段很长的时间等待。

导入完成之后就能在 Obsidian 的对应的文件夹中找到从 Evernote 中到处的笔记了。


2023-08-02 evernote , wiznote , obsidian , markdown , note-taking

Blaze 一个在局域网中点对点传输的网站

今天在了解一个根据英语搜索日语的网站 —- hiki 的时候,发现这个网站是使用一个叫做 [[Preact]] 的非常轻量的框架写的,然后我就沿着 Preact 的线索去查了一下那些网站是用 Preact 实现的,然后就发现了本文的主人公 —- [[blaze]]。

blaze 是一个基于 P2P 技术的文件共享 Web 应用程序。它允许用户通过直接连接和共享文件,而无需通过云存储服务或中央服务器。使用 blaze,用户可以轻松地共享大型文件、照片、视频等,并与其他用户进行实时的 P2P 传输。该应用程序提供了一个简单直观的界面,使用户能够快速上传和下载文件。blaze 利用 WebRTC 技术实现点对点连接,并使用 WebTorrent 协议进行文件传输。这种去中心化的方法不仅提高了速度和效率,同时也增强了隐私和安全性。

我简单的试用了一下 blaze ,发现真的太神奇了,它是一个文件分享的网站,但是不需要任何的注册,验证,而只需要设备在同一个局域网中就可以相互分享文件。于是为了测试我在 macOS 上打开了 blaze,然后起一个昵称,之后会得到一个链接,然后我在 Android 平板上打开同样的链接,网站就自动找到了局域网中的设备,我测试直接从 macOS 上发送文件,在 Android 上立即就收到了发送的文件。

我测试发送一个大文件,虽然没有跑满全部的局域网带宽,但因为 WiFi 传输的原因,也能维持在 3+M/s 的速度,一个 600+M 的文件,传输的时间也在接受的范围内。

D3qh

技术原理

好奇这个网站是如何实现的,但好在这个网站是开源的,并且作者在 README 中也提到了网站使用的技术 —- [[WebTorrent]] 和 [[WebSocket]],文件分享通过 WebTorrent 建立点对点的连接(内部使用 WebRTC)这意味着文件的传输是不需要经过中间服务器的,直接在发送者传输到接受者。需要注意的是这个地方 WebTorrent 其中有一个 Torrent,如果看过我之前的 BitTorrent 协议 一文的读者应该会对这个协议比较了解,WebTorrent 是一个纯 Web 的实现,但是和 BitTorrent 协议一样 tracker 服务器不存储任何文件,只存储 metadata 和必要的文件描述,节点信息等。


2023-07-26 blaze , preact , javascript , webtorrent , websockets , p2p , file-sharing

Lossless Cut 使用记录

Lossless Cut 一款跨平台的 [[FFmpeg]] 的 GUI,可以用来快速、无损地剪辑视频,音频。使用 Lossless Cut,用户可以轻松地选择视频或音频文件并进行剪辑操作。该工具支持各种常见的视频和音频格式,并且能够在不重新编码的情况下进行快速剪辑。

D4P8

除了基本的剪辑功能之外,Lossless Cut 还提供了其他一些高级功能。例如,它允许用户选择特定的时间段进行裁剪,并且还支持批量处理多个文件。此外,它还提供了一些实用的工具,如帧精确切分、截图等。

Lossless Cut 的界面简洁易用,使得即使对于没有编码经验的用户也能够轻松上手。它还提供了一些预设选项,以便用户能够快速应用常见的剪辑设置。

我经常会有一些简单的视频剪辑需求,比如一个长视频中剪辑部分内容,或者从一个音频文件剪辑部分,之前我都是用 Adobe Premiere 去处理,但是 Adobe Premiere 一方面非常重,另一方面即使是简单地剪辑导出也非常慢,因为会需要进行编码。

功能:

  • 开源、免费、跨平台
  • 由于 LosslessCut 基于 Chromium,并且使用 HTML5 视频播放器,因此不支持 [[FFmpeg]] 支持的所有格式
  • 支持编解码格式,MP4,MOV,WebM,MKV,OGG,WAV,MP3,AAC,H264,Theora,VP8,VP9。
  • 无损地修剪或剪切视频/音频的部分
  • 合并相同编码的文件
  • 组合来自多个文件的多个轨道
  • 无损提取文件中的音频
  • 重新混合为兼容格式输出
  • 缩放关键帧

Lossless Cut 使用

剪辑

Lossless Cut 的使用非常简单,可以直接将视频拖入应用,或者在应用中打开要处理的视频文件(Ctrl+o)。

Dcln 点击下方的时间轴,然后 「,」和 「。」 可以对选择点进行微调。

找到剪切点,按下「i」选择开头,然后按下 「o」结束。然后使用右下方的 Export 即可到处视频,此时会发现 LosslessCut 的到处处理几乎是瞬间完成的,因为并不需要重新编码,所以磁盘读写的速度就是导出的速度。

对于音频文件,则是如下的样式。

Dvkl

合并视频

Lossless Cut 还支持将多个视频文件合并成一个。只需将要合并的视频文件拖入应用中,然后点击左上角的「+」按钮来添加更多的视频文件。在选择完所有要合并的文件后,点击右上角的「Merge」按钮即可开始合并。

但需要注意的是 Lossless Cut 在合并视频时最好保证视频的编解码是一致的。

关键帧

在视频下方的时间轴上能看到一些自动识别的竖线,这些线是 Lossless Cut 自动识别的关键帧,方便用户定位视频。

缩略图

展开高级菜单,然后在倒数第二行的工具栏中的第三个图标就是自动显示视频的缩略图。

DMvy

快捷键

  • Space 暂停播放
  • j/l 降低或加快播放速度
  • </> 往前或往后 1 秒
  • ,/. 小幅度(帧)调整时间
  • i 标记开始
  • o 标记结束
  • e 导出选取的区段
  • c 导出快照

相关软件

  • [[HandBrake]] 是一款免费的视频转码软件,支持将视频转换为不同的格式。它具有用户友好的界面和强大的功能,同时还支持批量转码和多线程处理。无论您是想将视频转换为手机、平板电脑、游戏机或其他设备可播放的格式,HandBrake 都能满足您的需求。
  • [[FFmpeg]] 是一个强大的开源多媒体框架,提供了音频、视频和图像处理的功能。它可以用来进行视频剪辑、分割、合并等操作,并且支持各种常用的音视频格式。FFmpeg 具有命令行界面,因此对于熟悉命令行操作的用户来说非常方便。
  • [[Avidemux]] 是一款简单易用的视频剪辑软件,适合初学者使用。它提供了基本的剪辑、分割和合并功能,并支持多种常见的音视频格式。Avidemux 还可以进行简单的滤镜和特效处理,如亮度调整、色彩校正等。同时 Avidemux 支持的格式也非常多。
  • [[MKVToolNix]] 是一款免费的多媒体工具,其中一个功能是 MKV 文件的剪辑和编辑。
  • [[mVideoPlayer]] 一个开源的视频素材管理工具。
  • 其他一些收费的软件 [[BandiCut]]、[[SolveigMM Video Splitter]]

2023-07-22 losslesscut , video , video-manage , ffmpeg , video-cut

使用 k3sup 快速安装 k3s

多次想要学习一下 [[Kubernetes]] 但是多次照着搭建环境尝试失败,并且也没有找到合适的落地场景就「放弃」了,但是之前了解的时候看到了轻量级的 k8s 叫做 k3s,然后了解到了一个可以快速搭建 k3s 的项目 [[k3sup]],所以记录一下。

什么是 k3sup

k3sup 是一个可以在任何 Linux 机器上安装并启动 [[k3s]] 的命令行工具,官方宣称可以在 60 秒内启动一个 k3s。k3sup 是一个可帮助快速轻松地在任何地方部署 Kubernetes 集群的工具。它使用 SSH 连接到远程主机并安装 k3s,然后提供一个可用于与集群交互的 kubeconfig 文件。

k3sup 发音为“ketchup”。相对于 k8s 来说,k3s 系统容器数量少,轻量级,并且默认使用 containerd 作为容器运行时,内部的 ingress 使用的是 go 语言开发的 traefik,集成了 SQLite 代替 Etcd,但在多个 master 节点中最好使用 Etcd 组件,来保证数据一致性,从而可以 HA。

k3sup 需要通过 SSH 连接到对应的服务器进行安装操作,所以配置 SSH 免密码登录是必需的。

  • k3sup 可以在任何 VM,包括 VPS,VM,AWS EC2,物理机上通过命令安装启动
  • 从现有 k3s 集群中获取 KUBECONFIG
  • ks3up join 将节点加入 k3s 集群

安装使用

K3S 部署 Kubernetes 集群,创建集群的 https 证书,Helm 部署 rancher,通过 [[Rancher]] 的 UI 界面手动导入 Kubernetes 集群,使用 Kubernetes 集群。

k3sup 使用 Go 编写,直接下载编译好的二进制文件就能使用。

参考官网

curl -sLS https://get.k3sup.dev | sh
sudo install k3sup /usr/local/bin/

k3sup --help

安装 k3s server

在本地安装 k3s

k3sup install --local
# 指定用户
k3sup install --local --user=$USER --local-path ./kubeconfig
# 指定版本
k3sup install --local --user=$USER --local-path ./kubeconfig --k3s-version=v1.19.5+k3s1

运行 k3sup:

k3sup install --ip <your_ip> --user username

执行该语句之后,会在 IP 主机上安装 k3s 并启动,作为 master。

# Test your cluster with:
export KUBECONFIG=~/kubeconfig
kubectl config set-context default
kubectl get node -o wide

其他的常用参数

  • --local 无需通过 SSH,安装在本地
  • --local-path string 本地路径,kubeconfig 文件的本地路径
  • --merge 合并到 kubeconfig 文件
  • --ssh-key string 用于远程登录的 SSH key 密钥
  • --ssh-port int 如果使用非标准端口,可以使用该参数指定端口
  • --user string SSH 登录用户名

将其他 Agent 加入到 k3s 集群

注意这里的 agent_ip 为另一台机器,而 server_ip 为 master 节点:

k3sup join --ip <agent_ip> --server-ip <server_ip> --user username

其他常用参数

  • --server-ssh-port int 连接服务器的端口

卸载 k3s

在 server 节点上:

/usr/local/bin/k3s-uninstall.sh

在 agent 节点上:

/usr/local/bin/k3s-agent-uninstall.sh

对于失效的节点可以通过如下的命令移除

kubectl delete node <node name>

kubectl 自动补全

kubectl 的自动补全可以在这里查看。

source <(kubectl completion zsh)  # set up autocomplete in zsh into the current shell
echo '[[ $commands[kubectl] ]] && source <(kubectl completion zsh)' >> ~/.zshrc # add autocomplete permanently to your zsh shell

k3s vs Rancher

K3s 是一个轻量级的 Kubernetes 发行版,旨在简化和加速 Kubernetes 的部署和管理。它专注于提供一个更小、更快的 Kubernetes 版本,适用于边缘计算和资源有限的环境。K3s 具有更小的二进制文件大小、更低的内存和 CPU 占用,同时仍然提供了 Kubernetes 的核心功能。

[[Rancher]] 是一个开源的容器管理平台,用于部署和管理 Kubernetes 集群以及其他容器编排平台。Rancher 提供了一个易于使用的用户界面,用于集中管理和监控多个 Kubernetes 集群,并提供了诸如应用程序编排、存储和网络管理等高级功能。Rancher 可以与各种底层的容器编排平台集成,包括 Kubernetes、K3s、Docker Swarm 等。

k3s 端口使用

  • 6443 端口提供 API 服务器
  • 8472:用于flannel网络插件的VXLAN通信端口。
  • 10250:Kubelet API的端口,用于节点与主节点之间的通信。

也可以使用 kubectl get service -A 来查看使用的端口。

  • [[k3s]]
  • [[k3d]]
  • [[Rancher]]
  • [[Multipass]]
  • [[2021-07-25-k3s-vs-k3d-vs-kind-vs-minikube-vs-microk8s]]

2023-07-17 k3s , k8s , kubernetes , docker , google , k3sup , cluster , vps

端到端加密邮箱 Skiff 邮箱使用体验

去年的时候有介绍过一款 Web3 下的协同文档 Skiff,虽然我自己没有在深入使用,但是一直都在观察它的发展,之前也简单的介绍过 Skiff 邮箱,但当时 Skiff 提供的域名邮箱只能够使用 @skiff.com 自己的邮箱后缀,自定义的域名邮箱需要付费。但是今年 Skiff 周年的时候,免费的用户也可以绑定一个域名,因为 Skiff 提供了不错的 Web 界面,并且还提供了不错的客户端,所以如果有朋友不想自己折腾,先尝试一下 Skiff 提供的邮箱也不错。

Skiff 介绍

Skiff 本来是一个 Web3 下的协同文档工具,可以帮助用户在区块链上创建和共享文档。但是随着它业务的扩张,现在也提供了邮箱服务,感觉就是要对标 Web 3 下面的 Google 套件,目前 Skiff 不仅有协同文档,邮件,还有日历,同步云盘。

DOPR

Skiff 的主要特点包括:

  1. 去中心化:Skiff 使用区块链技术,将文档存储在多个节点上,而不是集中存储在单个服务器上。这意味着即使某个节点被攻击或故障,其他节点仍然可以继续提供服务。
  2. 安全性:由于 Skiff 使用了区块链技术,所有的文档修改都会被记录在不可篡改的区块链上。这确保了文档的完整性和可追溯性,并防止了潜在的篡改或删除。
  3. 透明性:所有参与者都可以查看和验证文档的历史记录和更改。这使得合作方更加信任和理解彼此的操作,并减少了可能引起纠纷或争议的情况。
  4. 实时协作:Skiff 允许多个用户同时编辑同一份文档,并实时显示其他用户对文档所做的更改。这使得团队成员能够更好地协同工作,提高工作效率。
  5. 智能合约支持:Skiff 可以与智能合约集成,使得文档的创建和访问可以通过智能合约进行管理和控制。这为文档的权限管理和审计提供了更高级别的自动化。

skiff mail

域名邮箱

优点 :

  • 免费的 10GB 空间
  • 免费的一个域名
  • 端到端加密
  • 去中心化
  • 界面干净

缺点:

  • 不提供 SMTP
  • Skiff 这个项目的未来有待观察

注册与登录

Skiff 邮箱可以使用传统的注册(用户名密码),也可以使用 Web 3 的 [[MetaMask]] 小狐狸来登录使用。

收费方案

Skiff 目前提供了三档付费方案,ESSENTIAL,PRO,BUSINESS,另外 Skiff 也支持使用加密货币支付。

D2YM

另外做个广告

如果有人想要使用自定义域名邮箱,不妨试试购买 EV HOST 我在维护的服务,使用 EV_MAIL 可以享受 6 折优惠,最低 30 元一年,无限制域名,无限制别名,但不能恶意滥用,不能发送垃圾邮件,另外每个小时有 300 封邮件的发件限制。购买之后只需要进行简单地几条 DNS 设置就能立即开始使用。我过去也有写过很多关于电子邮件的文章,可以在博客中搜索到。调研的邮箱服务 ,中间还考虑过自建域名邮箱  Mailu, Mailcow 。


2023-07-14 skiff , skiff-mail , custom-domain-mail , mail , email , mailbox

让 AI 无处不在

Obsidian

Obsidian 是我使用频率最高的笔记软件了,所以 Obsidian 的改造不能少。

插件

  • Copilot Chat 生成侧边栏对话框
  • Text Generator ,用来生成文字,提供灵感

DZB2

obsidian text generator

WebStorm EAP

这是我利用新项目学习 [[Gatsby]] ,通过 WebStorm 提供的 AI Assistant 可以快速的对代码进行提问,以加快学习的速度和提高学习效果。

DRXN

Cursor.so

Cursor.so 是一款 AI 支持的编辑器,之前也有推荐过,在我主力的 IntelliJ IDEA 之外,有些时候看代码会打开 Cursor,边看代码边提问,最近在看 [[TypeScript]] 的项目,给我带来了非常大的帮助,我再没有打开用 Google 搜索过,并且我也不需要打开 TypeScript 的开发文档从头看到尾。

下面的演示是我查看一个使用 Ruby 编写的项目,其中有一段方法是对 XML 文件进行签名,我在找到对应代码的前提下,在 AI 对话的帮助下使用 Java 重新实现了一遍。

Cursor

总结

至此,占据我日常大部分时间的工具上都加上了 AI,还有之前提及的 Raycast AImacOS 上好用的 ChatGPT 客户端在命令行下使用 GitHub Copilot CLI。我发现最近是真的三句话离不开 AI 了。


2023-07-13 ai , ai-powered , editor , obsidian , webstorm , intellij-idea , jetbrain , cursor

《每周工作 4 小时》读书笔记 - 寻找生活工作的平衡

怎么知道的这一本书

我已经忘记了最初是因为什么原因把这一本书添加到了书单中了,但是看了一下同期加入书单的图书,还有 [[毫无意义的工作]],可能是不知道从哪边看了一篇关于工作生活的文章,里面可能提到了这一本书,就这个名字就像让人把它加入待看列表。最近在 Twitter 有一个关键词 [[Indie Hacker]] 又再一次被频繁提起,与之关联的 [[Digital Nomad]],独立开发者,[[Company of One 一人公司]]等等,都成为了最近的流行趋势。在 OpenAI,Bard,[[Claude]] 等等 AI 辅助工具的帮助情况下,个人可以找到方式将自己从朝九晚五的工作中解放出来。

无独有偶的是昨天晚上刚刚听到一个播客,这个播客是讲跨境电商的从业人员如何借助 OpenAI,[[Midjourney]] 的能力,将自己的效率提升了 4 倍,原来需要在一天时间内做的事情,可以很快在一个上午,几小时之内完成,之前一个礼拜的工作可以很快在一天时间内完成。而这也恰恰是本书作者 [[蒂莫西 费里斯]] 想要在书中所倡导的,「工作的关键是高效,而不是忙碌」。令我更惊讶的是,本书出版于 2012 年,但他所倡导的理念却在近 10 年之后才慢慢被人所接受。

关于作者

作者 Timothy Ferriss(蒂莫西·费里斯) ,我虽然第一次看到这个名字,但是在读完简单的查询了之下之后,我就发现了另一个我经常见的名字 Tim Ferriss,有一档播客叫做 The Tim Ferriss Show,一下子就对这个作者熟悉来起来,也瞬间知道了为什么他能够这么早就能这样思考生活和工作的关系。

几句话总结书的内容

《每周工作 4 小时》是由蒂莫西·费里斯撰写的一本畅销励志书。在书中探讨了如何通过优化时间和工作流程,实现更高效的工作和更丰富的生活。作者提出了一种颠覆传统工作模式的思维方式 —- 每周工作 4 小时,鼓励读者追求自由、创造性和富足的生活。

  • 只做重要的事情,减少工作时间
    • 少做无意义的工作
    • 作者强调了时间管理的重要性,推崇使用“帕累托法则”来提高工作效率。他鼓励读者学会集中注意力,避免无意义的忙碌,并通过列出优先事项和设定时间限制来实现高效工作。
  • 自动化或外包工作
    • 提倡通过自动化和外包来减轻工作负担。建议将一些重复、低效的任务交给他人处理或自动化处理,从而腾出更多时间和精力投入到更有价值的事务上。
  • 无固定办公地点、远程办公
    • 鼓励读者采取远程办公或灵活工作时间的方式,摆脱传统的朝九晚五的工作模式。他认为,随着科技的进步,人们可以利用互联网和通信工具,在任何地方都能进行工作,从而实现更自由的生活方式。
  • 追求兴趣和激情
    • 强调了追求兴趣和激情的重要性。他鼓励读者寻找自己真正感兴趣的事物,并将其转化为收入来源,从而实现工作与生活的平衡。

Tim Ferriss 在书中所倡导的思想,和 FIRE 理念 所倡导的思想非常相似,Tim Ferriss 则更关注于时间管理和有效工作,倡导[[迷你退休]],将退休生活拆分到日常生活中。而 FIRE 运动的理念则更强调通过控制支出,增加收入,累积财富,给退休设定了一个「标准」。而这两种「思考」的方式殊途同归,我们的终极目标并不是放弃工作去旅行,去放纵,而是为自己争取一些自由的时间和空间,让我们可以在世界的任何地方都可以享受自我。这两种思想可以相互补充,他们即不矛盾,也不相互排斥。

大部分人,包括过去的我,总是试图尽力说服自己相信生活本就是如此。用朝九晚五的劳作去换取短暂的周末或极为短暂的假期,还要冒着随时可能被解雇的风险。

千万不要做的 9 件事情

  • 不接不熟悉的电话
  • 别把收发邮件当成早上的第一件事
  • 不要在没有详细日程表或结束时间的情况下去参加会议或接听某个电话
  • 别给人闲扯的机会
  • 不要连续查看邮件,只应该在固定时间段查看
  • 不要和低效能高维护成本的顾客过度沟通
  • 不要靠加班来解决过剩的工作,要有优先级
  • 不要 24 小时带着手机或电脑
  • 不要期待工作能够填补非工作关系或工作之外的活动能带给你的那些东西

11 个信条提高利润

  • 恰当的定位(目标市场)
    • 制定市场战略的时候,向大众描述产品
  • 可度量的事情,才是可以驾驭的
    • 度量学的原理很有价值。统计一起可以度量的数据,运营统计,投入产出比,计算广告,完成度,期望收益,付款人拒付,坏帐等,回报率等等
  • 定价优先于产品,先找好销售渠道
  • 少即是多,减少中间环节以扩大利润
  • 创造需求而不是提供措施
  • 广告只在第一次做时有用,好形象通常是多余的
  • 降低负面,保障正面。牺牲掉边际贡献,以确保投资安全
  • 不要急于谈判,应先让对手跟自己讨价还价
  • 高活跃度 VS 产出率—- 80/20 法则和帕雷托定律
    • 所期待的 80% 的效果来自 20% 的努力
  • 顾客并不总是对的—-「解雇」难缠的客户
  • 截止日期甚于细节 —- 先测试可信赖性,再测试能力

总结

虽然书中有一些具体的建议,如今来看已经过时,比如作者推荐的 Evernote,就刚刚出现被并购,并裁去了所有员工的新闻,但是作者想要表达的思想却是对的,那就是 Evernote 可以让我们可以在一个地方查询到所有的信息,不管是在网页上看到的,还是自己记录的,还是发表的内容,合同的内容,通过 OCR 识别,都可以被找到。虽然 Evernote 看起来不行了,但是还存在很多其他的工具可以让我们去使用。

作者在书中所倡导的工作方式,引发了对传统工作模式的反思,并且以个人案例和经验提供了实用建议和技巧,让读者更好地管理时间、提高工作效率,并追求更自由和富足的生活。

启发或想法

忙碌的人忙于任何事情,除了生活

作者通过思考工作和生活,提出了一个引人深思的问题,「我们必须要在每周的工作上花费 40 小时吗?」,显然答案是否定的,「先成为企业家,再成为雇员」囊括了作者核心思想。在过去的全球化发展过程中,尤其是互联网的发展将全世界拉到了一起,可以利用互联网将产品直接销售给客户,从而实现被动收入,通过创造的方式来建立自己的品牌和资产,通过自动化或外包的形式将不重要的或不想做的事情分包出去,从而提高自己的效率。而在具体的工作中,作者也提供了具体的细节行动,比如区分优先级,使用 80/20 法则选择客户来缩短工作时间。

谁应该看这本书

  • 疲惫于每周 40 个小时的工作的人
  • 渴望从事远程工作,希望过上数字游民生活的人

印象深刻的句子

  • 重新定义一下「懒惰」,懒惰是容忍令人不满的现状,让客观环境或其他人决定自己的生活。
  • 良性压力(enstress),英文中 eu- 前缀,在希腊语中是「有益的、良好的」意思。激励我们超越自我的行为榜样,消除腰部赘肉的体育训练,拓展我们适应范畴的冒险都是良性压力。有益健康,能促进我们成长。
  • 并非所有的顾客都生而平等。
  • 关键是高效,而不是忙碌
  • 刻意安排的时间永远都不准确
  • 不欢迎任何批评的人必定会失败。我们需要避免的是那种毁灭性的批评,而不是所有的批评。

2023-07-10 work , work-life-balance , life , reading , reading-2023q2 , reading-2023

开源的数据分析工具 Metabase

Metabase 是一个开源的商业数据分析(Business Intelligence,缩写 BI)工具。Metabase 可以将数据库中的数据以各种图表的方式展示出来,分析师只需要通过简单的查询语句就可以通过 Dashboard 展示出来。Metabase 提供一个直观易用的用户界面,非技术人员也能够轻松地进行数据分析和可视化。它支持多种类型的数据库,包括 MySQL、PostgreSQL、Oracle 等,并提供了一些预定义的查询和报告模板,帮助用户快速开始分析工作。

什么是 BI

BI 是 Business Intelligence 的缩写,代表的是一种通用商业分析的解决方案,即:用一系列技术手段对数据加工和分析,转化为知识进而支持商业决策的系统。

BI 的范围需要涵盖大量工具,包括数据源连接、数据准备、数据可视化、数据报表、数据输出等。常见的 BI 工具有:Microsoft Power BI、Tableau 等,国内有 阿里云 Quick BI、FineBI 等。开源方案,包括 [[Superset]]、Hue、[[Redash]]、以及本文介绍的重点 Metabase 等。

DGZy

Metabase

Metabase 的主要特点包括:

  • 数据可视化:Metabase 提供了各种图表类型,如柱状图、折线图、饼图等,使用户能够以直观的方式展示数据,并通过交互式控件进行数据筛选和过滤。
    • 支持的图表类型包括:折线图、柱状图、饼图、面积图、组合图、地图、漏斗、散点、仪表盘等
  • 支持的数据源:Postgres、MySQL、Druid、SQL Server、Redshift、MongoDB、Google BigQuery、SQLite、H2、Oracle、Vertica、Presto、Snowflake、SparkSQL。
  • 邮件报警:可以使用已有查询配置数据阈值报警,发送邮件。
  • 查询构建器:Metabase 提供了一个简单而强大的查询构建器,用户可以通过拖放方式选择字段和条件来构建查询语句,无需编写复杂的 SQL 语句。
  • Dashboard:Metabase 允许用户创建仪表板(Dashboard),将多个图表组合在一起展示,并支持自定义布局和样式。
  • 数据分享:用户可以将他们创建的报表和仪表板分享给其他人,在权限控制的基础上共享数据分析结果。
  • 内置问题库:Metabase 内置了一个问题库(Question),为常见问题提供了标准化答案模板,帮助用户快速回答常见问题。
  • 自动化报告:Metabase 可以根据用户设定的时间表,自动执行查询和生成报告,方便用户定期获取数据分析结果。
  • 仪表板功能:支持参数传递、一键全屏、公开分享、iframe 嵌入、定时刷新
  • 用户集成:LDAP、OAuth2(需做一点开发)
  • 权限:支持按数据源或者报表文件夹分配权限给用户组。

安装 Metabase

简单使用 Docker 安装

version: '3'

services:
  metabase:
    image: metabase/metabase:latest
    container_name: metabase
    restart: always
    ports:
      - ${PORT:-3000}:3000
    environment:
      - MB_JAVA_TIMEZONE=${MB_JAVA_TIMEZONE:-Asia/Shanghai}

通过 Docker 运行 Metabase,将其映射到本地 3000 端口。然后可以通过浏览器访问 http://localhost:3000 来打开 Metabase 的用户界面。

首次访问时,会要求设置管理员账号和密码。设置完成后,就可以开始使用 Metabase 了。Metabase 提供了一个直观的用户界面,首先需要关联数据源,然后就可以轻松地查询数据库中的数据,并将其以各种图表的方式展示出来。用户可以通过提问(Question)功能来创建查询,然后将查询结果保存为仪表盘(Dashboard)。

Metabase 使用

Metabase 的使用主要是分成如下步骤:

  • 创建数据源
  • 创建查询语句
    • 简单查询,简单的数据,可以界面操作完成直接展示数据
    • 自定义查询,过滤条件和查询条件
    • 原生查询,直接使用 SQL 语句查询

如果在初始化的时候没有设置自己的数据源,那么也可以在 Admin 页面中添加数据源。

DTcg

reference

  • https://t.co/EDIHgxiH0I

2023-07-07 metabase , open-source , business-intelligence , data-analytics , mysql

使用 k6 做一次负载性能测试

负载测试(性能测试,压力测试)是一个较为复杂的任务,包括了测试目标,工具开发,脚本开发,CI 集成,结果分析,性能调优等等部分,可以衡量服务是否是一个高可用,高性能的服务。负载测试能检验在不同的工作负荷下,服务的硬件消耗和响应,从而得到不同负载情况下的性能指标。压力测试能检验软硬件环境下服务所能承受的最大负荷并帮助找出系统瓶颈所在。

k6 是什么

k6 是用 Go 语言编写的一种高性能的负载测试工具。

k6 具有下面几个特点

  • 可配置的负载生成(Configurable load generation),低配置的机器就可以生成大量流量
  • 利用代码进行测试(Tests as code),重用测试脚本,模块化逻辑,版本控制,和 CI 集成
  • 功能齐全的 API(A full-featured API),脚本 API 提供多种模拟真实应用程序流量的功能。
    • 强大的 CLI 工具。
  • 内嵌的 JavaScript 引擎(An embedded JavaScript engine),提供了 Go 的性能,和 JavaScript 脚本的熟悉度灵活度
    • k6 嵌入了 JavaScript 运行时,可以使用 JavaScript ES2015/ES6 来编写脚本。
  • 多种协议的支持(Multiple Protocol support),HTTP,WebSockets 和 gRPC
  • 庞大的插件支持生态(Large extension ecosystem),借助 k6 来扩展需求,并且很多人通过社区分享他们的扩展
  • 灵活的指标存储和可视化(Flexible metrics storage and visualization),汇总统计数据或粒度指标,导出到您选择的服务。
  • 使用 Checks 和 Thresholds 可以更加轻松的做面向目标的自动化的负载测试。

为什么选择 k6

性能测试工具有很多

  • [[Hey]] Hey 是一个使用 Golang 实现的 HTTP 压测工具。
  • [[Apache Bench]] Apache Bench 是一个轻量的 HTTP 压力测试工具。
  • [[vegeta]] vegeta 是一个开源的 HTTP 压力测试工具。
  • [[Apache JMeter]],使用 Java 编写的开源的性能测试工具
  • [[Tsung]] Tsung 是一个 Erlang 编写的多协议支持的测试工具。
  • [[LOCUST]],LOCUST Python 编写的性能测试工具,基于代码的方式定义用户行为,支持分布式测试
  • [[Gatling]],Scala 编写,使用异步,非阻塞的方式模拟用户访问,提示实时的结果和报告
  • [[Siege]], Siege 是一款使用 C 语言编写的性能测试工具
  • [[Artillery]],Artillery 是一个 JavsScript 编写的,基于云端的压力测试工具。
  • [[Drill]],drill 是一个 [[Rust]] 编写的 HTTP 压力测试工具。

DLFh

k6 的优势在于 :

  • k6 支持 TypeScript 编写脚本,如果熟悉 TypeScript 学习成本比较低
  • 支持 metrics 输出,可以记录到 [[InfluxDB]] 等
  • 可以与多种 CI 工具集成,可以于 Grafana 进行集成展示结果数据

k6 vs JMeter

虽然 JMeter 在支持的协议数量上要优于 k6,但是 K6 相对于 JMeter 还是有不少的优势的 :

  • 因为 k6 是 Go 编写的,相对于 Java 编写的 JMeter 有性能上的差距,K6 可以只用较少的资源就能达到指定数量的负载。
  • 支持阈值
  • TypeScript 的脚本可以更好的促进协作和版本管理
  • 资源利用率远远强于 JMeter
  • 丰富的可视化方案

Load-testing

测试的类型

  • spike,尖峰测试,短时间内突然遭受到突发流量
  • stress,压力测试,将系统置于极限负载下
  • soak tests,持续性测试,连续时间内进行测试,通常是几小时或几天,这种测试旨在评估系统在长时间运行和持续负载下的稳定性,性能和资源管理能力

安装 k6

Debian/Ubuntu 可以执行如下命令1

sudo apt-get update && sudo apt-get install ca-certificates gnupg2 -y
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6

Docker

docker pull loadimpact/k6

HTTP 请求

新建一个 script.js 文件

Get 请求 get(url, [params])

import http from 'k6/http';
// 默认控制选项
export let options = {
  vus: 10,         // 指定要同时运行的虚拟用户(VUs)数
  duration: '10s', // 指定测试运行的总持续时间
};
// default 默认函数
export default function() {
  // 标头
  let params = { headers: { 'Content-Type': 'application/json' } };
  var res=http.get("https://test.k6.io", params)
}

说明:

  • VUs, virtual users, 虚拟用户,更多的虚拟用户意味着更高的并发流量

对于 options 也可以通过设置可变的形式来设置不同阶段

export const options = {
  stages: [
    { duration: '30s', target: 20 },
    { duration: '1m30s', target: 10 },
    { duration: '20s', target: 0 },
  ],
};

Post 请求 Post( url, [body],[params])

import http from 'k6/http';
export let options = {
  vus: 100,
  duration: '10s',
};
// default 默认函数
export default function() {
  let json = { content: 'linhui', image: 'images' };
  let params = { headers: { 'Content-Type': 'application/json' } };
  var res = http.post("https://host/api/feedback", JSON.stringify(json), params)
  console.log(res.status);
}

del 请求 del(url,[body],[params])

import http from 'k6/http';
export let options = {
  vus: 1,
  duration: '10s',
};
// default 默认函数
export default function () {
  let json = {id:1};
  let params = { headers: { 'Content-Type': 'application/json' } };
  http.del('https://host/delete', json, params);
}

batch 批处理,可以用来做页面并发,批处理并不能保证执行顺序,batch(method,url,[body],[params])

import http from 'k6/http';
export let options = {
  vus: 1,
  duration: '10s',
};
export default function () {
  let get = {
    method: 'GET',
    url: 'https://host/get',
  };
  let get1 = {
    method: 'GET',
    url: 'https://host/get',
  };
  let post = {
    method: 'POST',
    url: 'https://host/post',
    body: {
      hello: 'world!',
    },
    params: {
      headers: { 'Content-Type': 'application/json' },
    },
  };
  let res = http.batch([req1, req2, req3]);
}

使用 request 发送求 request(method, url, [body], [params])

import http from 'k6/http';
export let options = {
  vus: 1,
  duration: '10s',
};
export default function () {
  let json = { content: 'linhui', image: 'images' };
  let params = { headers: { 'Content-Type': 'application/json' } };
  let res = http.request('POST', 'http://host/post', JSON.stringify(json), params);
  let res1 = http.request('GET', 'http://host/get', null, params);
}

执行脚本,进入脚本根目录

k6 run test.js
# 使用 docker
docker run -i loadimpact/k6 run - <test.js

常见指标说明

指标类型

名称描述
Counter计数器,对值进行累加
Gauge最小值、最大值和最后一个值。
Rate百分比
Trend最小值、最大值、平均值和百分位数的统计数据指标

k6 一直都会收集的指标

名称类型描述
vueGauge当前活动的虚拟用户数
vue_maxGauge虚拟用户的最大数量
iterationsCounter脚本中的函数被执行的次数
data_receivedCounter接收到的数据量大小
data_sentCounter发送的数据量大小
iteration_durationTrend完成默认/主函数的一次完整迭代所花费的时间。
checksRatechecks 项的成功率

HTTP 协议特有的指标

名称类型描述
http_reqsCounter总请求数量
http_req_blockedTrend在发起请求之前被阻塞的时间
http_req_connectingTrend建立到远程主机的TCP连接所花费的时间。
http_req_tls_handshakingTrend与远程主机握手建立TLS会话所花费的时间
http_req_sendingTrend将数据发送到远程主机所花费的时间
http_req_waitingTrend等待远程主机响应所花费的时间
http_req_receivingTrend从远程主机接收响应数据所花费的时间
http_req_durationTrend请求的总时间。它等于http_req_sending + http_req_waiting + http_req_receiving(即,远程服务器处理请求和响应花了多长时间,而没有初始DNS查找/连接时间)
http_req_failedRate失败请求率

每一个 http 都会返回一个 HTTP Response 对象,下面是常用的一些属性。

属性类型
Response.bodyHTTP 响应正文
Response.cookies响应 cookies ,属性是 cookie 名称,值是 cookie 对象数组
Response.error发送请求失败后的错误信息。
Response.error_code错误码
Response.headers标头,键值对
Response.status从服务器收到的 HTTP 响应代码
Response.timings耗时(以毫秒为单位)
Response.timings.blocked= http_req_blocked
Response.timings.connecting= http_req_connecting
Response.timings.tls_handshaking= http_req_tls_handshaking
Response.timings.sending= http_req_sending
Response.timings.waiting= http_req_waiting
Response.timings.receiving= http_req_receiving
Response.timings.duration= http_req_duration

自定义指标

import http from 'k6/http';
import { Trend } from 'k6/metrics';
export let options = {
  vus: 100,
  duration: '10s',
};
// 新建一个类型为 Trend 名为 sending_time 的自定制指标
let sendingTime = new Trend('sending_time');

export default function () {
  let res = http.get('http://www.baidu.com');
  sendingTime.add(res.timings.sending);
}

设置了 sending_time 这个自定义指标之后在 k6 运行的结果中就能看到新定义的指标。

常用 Option 选项

VUs:指定同时运行的虚拟用户数量,必须是一个整数,和 duration 搭配使用。默认值:1

export let options = {
  vus: 10,
  duration: '10s',
};

或者在执行命令时指定:

k6 run -u 10 test.js
k6 run --vus 10 test.js

Duration:字符串,指定测试运行的总持续时间,与 vus 选项一起使用。默认值:null

export let options = {
  vus: 10,
  duration: '10s',
};

执行命令时指定:

k6 run -u 10 --d 20s  test.js
k6 run --vus 10 --duration 20s  test.js

User Agent:发送 HTTP 请求时指定 User-Agent 标头。默认值:k6/0.27.0 (https://k6.io/) 取决于你 k6 的版本

export let options = {
  userAgent: 'Mozilla/5.0',
};
k6 run  --user-agent 'Mozilla/5.0'  test.js

TLS Version:表示允许在与服务器交互中使用的唯一 SSL/TLS 版本的字符串,或者一个指定允许使用的“最小”和“最大”版本的对象。 默认值:null (允许所有版本)

export let options = {
  tlsVersion: 'tls1.2',
};

export let options = {
  tlsVersion: {
    min: 'ssl3.0',
    max: 'tls1.2',
  },
};

TLS Cipher Suites:允许在与服务器的 SSL/TLS 交互中使用的密码套件列表。由于底层 go 实现的限制,不支持更改 TLS 1.3 的密码,并且不会执行任何操作。 默认值:null(允许所有)

export let options = {
  tlsCipherSuites: [
    'TLS_RSA_WITH_RC4_128_SHA',
    'TLS_RSA_WITH_AES_128_GCM_SHA256',
  ],
};

TLS Auth: tls 身份验证。默认值:null

export let options = {
  tlsAuth: [
    {
      domains: ['example.com'],
      cert: open('mycert.pem'),
      key: open('mycert-key.pem'),
    },
  ],
};

Throw:一个布尔值,true or false ,指定是否在失败的 HTTP 请求上抛出异常。 默认值:false

export let options = {
  throw: true,
};
k6 run  --throw test.js
k6 run  -w test.js

Thresholds:一组阈值规范,用于根据指标数据配置在何种条件下测试成功与否,测试通过或失败。默认值:null

export let options = {
  thresholds: {
    http_req_duration: ['avg<100', 'p(95)<200'],
    'http_req_connecting{cdnAsset:true}': ['p(95)<100'],
  },
};

Tags:指定应在所有指标中设置为测试范围的标签。如果在请求、检查或自定义指标上指定了同名标签,它将优先于测试范围的标签。 默认值:null

export let options = {
  tags: {
    name: 'value',
  },
};
k6 run --tag NAME=VALUE test.js

RPS:指的是每秒发出的最大请求数。 默认值:0

export let options = {
  rps: 500,
};

或者:

k6 run --rps 500  test.js

Paused:是否可以暂停和和恢复的方式运行脚本,暂停启动后需要使用另外的窗口执行k6 resume 恢复使用。在恢复窗口可以实时的查看脚本的运行情况。 启动后不支持暂停, 默认值:false

export let options = {
  paused: true,
};
k6 run --paused  test.js
k6 run --p test.js

No VU Connection Reuse:布尔值,是否复用 TCP 链接。默认值:false

export let options = {
  noVUConnectionReuse: true,
};
run --no-vu-connection-reuse  test.js

No Usage Report:布尔值,是否给 k6 发送使用报告,true 值不会发使用报告。 默认值:false

k6 run --no-usage-report test.js

No Thresholds:布尔值,是否禁用阈值。默认是:fasle

k6 run --no-thresholds test.js

No Summary:是否禁用测试结束生成的概要。默认值:false

k6 run --no-summary test.js

No Cookies Reset:是否重置 Cookies,fasle 每次迭代都会重置 Cookie ,true 会在迭代中持久化 Cookie 。默认值:false

export let options = {
  noCookiesReset: true,
};

No Connection Reuse:是否禁用保持活动连接,默认值:false

export let options = {
  noConnectionReuse: true,
};
k6 run --no-connection-reuse test.js

Minimum Iteration Duration:指定默认函数每次执行的最短持续时间,任何小于此值的迭代都将剩余时间内休眠,直到达到指定的最小持续时间。默认值:0

export let options = {
  minIterationDuration: '10s',
};
k6 run --min-iteration-duration '1s' test.js

Max Redirects:最大重定向,默认值:10

export let options = {
  maxRedirects: 10,
};
k6 run -max-redirects 10 test.js

Batch: batch 同时调用的最大连接总数,如果同时有 20 api 请求需要发出 ,batch 值是 15,那么将会立即发出 15 个请求,其余的请求会进行一个排队。默认值:20

export let options = {
  batch: 15,
};

k6 run --batch 10 test.js

Batch per host:batch 对同一个主机名同时进行的最大并行连接数。默认值:6

export let options = {
  batchPerHost: 5,
};
k6 run --batch-per-host 10 test.js

Blacklist IPs:黑名单。默认值:null

export let options = {
  blacklistIPs: ['10.0.0.0/8'],
};
k6 run --blacklist-ip= ['10.0.0.0/8'] test.js

Block Hostnames:基于模式匹配字符串来阻止主机,如 *.example.com , 默认值:null

export let options = {
  blockHostnames: ["test.k6.io" , "*.example.com"],
};
k6 run --block-hostnames="test.K6.io,*.example.com" test.js

Discard Response Bodies:是否应丢弃响应正文,将 responseType 的默认值修改成 none,建议设置成 true,可以减少内存暂用和 GC 使用,有效的较少测试机的负载。默认值:false

export let options = {
  discardResponseBodies: true,
};

HTTP Debug:记录所有 HTTP 请求和响应。默认情况下排除正文,包括正文使用 –http debug=full 默认值:false

export let options = {
  httpDebug: 'full',
};
k6 run --http-debug test.js

Options 的顺序

k6 提供了很多方式来设置 Options.

  • CLI 选项
  • 环境变量
  • 脚本中的 options 对象

执行的顺序,优先级从低到高:

  • Defaults,默认使用
  • --config
  • Script options
  • Environment variables
  • CLI Flags

如果 Options 发生冲突,那么 k6 会遵循上面的优先级,CLI flags 中的是最高优先级,会覆盖其他所有设置。

Checks 检查

Checks 类似断言,不同在于 Checks 不会停止当前的脚本。指标都可以作为检查的项目。

import http from 'k6/http';
import { sleep } from 'k6';
import { check } from 'k6';

export let options = {
  vus: 100,
  duration: '10s',
};
export default function () {
  let res = http.get('http://test.k6.io/');
  check(res, {
    '状态码为200': (r) => r.status === 200,
    '响应时间小于200ms': (r) => r.timings.duration < 200,
    '等待远程主机响应时间小于200ms': (r) => r.timings.waiting < 200,
  });
}

Thresholds 阈值

阈值是用来指定被测系统的性能预期的通过/失败标准。阈值用来分析性能指标并确定最终测试结果。内置的指标都可以作为阈值。

k6 中包含的四种度量类型每一种都提供了自己的一组可用于阈值表达式的聚合方法。

  • Counter: count and rate
  • Gauge:value
  • Rate:rate
  • Trend:p(N)
import http from 'k6/http';
import { Trend, Rate, Counter, Gauge } from 'k6/metrics';
export let GaugeContentSize = new Gauge('ContentSize');
export let TrendRTT = new Trend('RTT');
export let options = {
  vus: 10,
  duration: '10s',
  thresholds: {
    // 发出的请求数量需要大于1000
    http_reqs:['count>1000'],
    // 错误率应该效率 0.01%
    http_req_failed: ['rate<0.01'],
    // 返回的内容必须小于 4000 字节。
    ContentSize: ['value<4000'],
    // p(N) 其中 N 是一个介于 0.0 和 100.0 之间的数字,表示要查看的百分位值,例如p(99.99) 表示第 99.99 个百分位数。这些值的单位是毫秒。
    // 90% 的请求必须在 400 毫秒内完成,95% 必须在 800 毫秒内完成,99.9% 必须在 2 秒内完成
    http_req_duration: ['p(90) < 400', 'p(95) < 800', 'p(99.9) < 2000'],
    // 99% 响应时间必须低于 300 毫秒,70% 响应时间必须低于 250 毫秒,
    // 平均响应时间必须低于 200 毫秒,中位响应时间必须低于 150 毫秒,最小响应时间必须低于 100 毫秒
    RTT: ['p(99)<300', 'p(70)<250', 'avg<200', 'med<150', 'min<100'],
  },
};

export default function () {

  let res = http.get('http://www.baidu.com');
  TrendRTT.add(res.timings.duration);
  GaugeContentSize.add(res.body.length);
}

阈值标签,测试中可以给指定的 url 或者特定标签上使用阈值。

import http from 'k6/http';
import { sleep } from 'k6';
import { Rate } from 'k6/metrics';

export let options = {
  vus: 10,
  duration: '10s',
  thresholds: {
    // type 为 baidu 使用
    'http_req_duration{type:baidu}': ['p(95)<500'],
    // type 为 bing 使用
    'http_req_duration{type:bing}': ['p(95)<200'],
  },
};

export default function () {
  let res1 = http.get('https://www.baidu.com', {
    tags: { type: 'baidu' },
  });
  let res2 = http.get('https://cn.bing.com/', {
    tags: { type: 'bing' },
  });

  let res3 = http.batch([
    [
      'GET',
      'https://www.baidu,com',
      null,
      { tags: { type: 'baidu' } },
    ],
    [
      'GET',
      'https://cn.bing.com/',
      null,
      { tags: { type: 'bing' } },
    ],
  ]);

}

默认情况下没有达标阈值标准是不会停止脚本的,通过设置阈值的 abortOnFail: true 来终止。

import http from 'k6/http';
export let options = {
  vus: 10,
  duration: '10s',
  thresholds: {
    http_req_duration: [{threshold: 'p(99) < 10', abortOnFail: true}],
  },
};

export default function () {
  let res = http.get('http://www.baidu.com');
}

对通过的阈值前面会有一个 ✓,而失败的则会有一个 ✗ 。只有满足所有阈值的情况下测试才算通过。

日志输出

输出到控制台。

import http from 'k6/http';
export let options = {
  vus: 10,
  duration: '2s',
};

export default function () {
  let res = http.get('http://www.baidu.com');
   console.log('log')
   console.info('info');
   console.error('err');
   console.debug('debug')
   console.warn('warn')
}

输出到文件,输出到文件的同时控制台不在输出。

k6 run  test.js --console-output=test.log

InfluxDB Grafana 可视化测试结果

Docker 启动 [[InfluxDB]]

docker pull tutum/influxdb
# 8083是 influxdb 的 web 管理工具端口,8086 是 influxdb 的 HTTP API 端口
docker run -d -p 8083:8083 -p8086:8086 --expose 8090 --expose 8099 --name influxsrv tutum/influxdb

Docker 启动 Grafana,

docker pull grafana/grafana
docker run -d -p 3000:3000 grafana/grafana

新建一个 k6test 数据库,访问 “http://xxxxx:8083” InfluxDB web 管理页面,新建一个 K6test 数据库

DaYC

配置 Grafana 数据源

DiNH

选择 InfluxDB, 填写域名端口和数据库,点击 sava&test 。出现 Data source is working 表示成功,如遇到问题查看一下端口是否放行。

导入仪表盘

DCTD

通过 ID 导入,输入 2587 点击 load 数据源选择 InfluxDB 点击 Import

官方还有几款仪表盘

将 k6 的测试指标导入到 InfluxDB

k6 run --out influxdb=http://xxxxx:8086/K6test test.js

效果图

DEgL

Scenarios

Scenarios (场景)配置 VU 和迭代计划的方式,通过 Scenarios 配置,可以在负载测试中对不同的工作负载或流量模式进行建模。

使用场景的优势 :

  • 同一个脚本中可以声明多个场景,每个场景都可以执行不同的 JavaScript 函数
  • 模拟更真实的流量,每个场景都可以使用不同的 VU 和调度模式
  • 并行或顺序执行测试
  • 每个场景都可以设置不同的环境变量和指标
export const options = {
  scenarios: {
    example_scenario: {
      // name of the executor to use
      executor: 'shared-iterations',

      // common scenario configuration
      startTime: '10s',
      gracefulStop: '5s',
      env: { EXAMPLEVAR: 'testing' },
      tags: { example_tag: 'testing' },

      // executor-specific configuration
      vus: 10,
      iterations: 200,
      maxDuration: '10s',
    },
    another_scenario: {
      /*...*/
    },
  },
};

executor 场景必须使用预定义的 executor 来配置,设置运行的时间,流量是否保持恒定,工作负载是按 VU 还是按到达率。

  • 按迭代次数
    • shared-iterations 在 VUs 之前 shares iterations,在所有并发的 VUs 中共享迭代,当所有的迭代完成时,测试结束
    • per-vu-iterations 让每一个 VU 运行配置的迭代,每个 VU 执行一定数量的迭代。
  • 按 VU 数量
    • constant-VUs 恒定数量发送 VU,在指定的时间内以恒定的并发虚拟用户数 (VUs) 执行
    • ramping-vus 根据配置阶段性增加 VU 数量,缓慢增加并发用户数
  • 按 iteration rate
    • constant-arrival-rate 以恒定速率开始迭代,
    • ramping-arrival-rate 根据配置的阶段提高 iteration rate

Scenario example

import http from "k6/http";

export const options = {
  scenarios: {
    shared_iter_scenario: {
      executor: "shared-iterations",
      vus: 10,
      iterations: 100,
      startTime: "0s",
    },
    per_vu_scenario: {
      executor: "per-vu-iterations",
      vus: 10,
      iterations: 10,
      startTime: "10s",
    },
  },
};

export default function () {
  http.get("https://test.k6.io/");
}
  • shared_iter_scenario 10 个 VU 进行 100 次迭代
  • per-vu-iterations 在 10 秒之后开始,10 个 VU 每个运行 10 次迭代

总结

k6 是一个非常强大的性能测试工具,只需要稍微了解一下 TypeScript,熟悉一下调用过程,就可以很快上手使用。

reference


2023-07-01 k6 , grafana , load-testing , typescript , open-source , go-lang , jmeter

修复 Ledger Nano X 转轴松垮问题

之前有写过一篇文章说我买了一个Ledger Nano S Plus ,整体来看 Nano S Plus 没有蓝牙功能,机身塑料质感非常强,后来看到 Nano X 打折,价格基本上已经快接近 Nano S Plus 的价格了,所以就又下单了一个 Nano X。但是没想到收货之后,发现其塑料质感和做工更加不行,并且我到货的 X,转轴部分非常松垮,只要稍微侧着拿起外面的部分,中间的机身就会溜出来。

DIs8

后来简单的查了一下之后才发现原来这是 Nano X 的通病,很多人都遇到了和我一样的问题,没想到的是 100 多美元的东西做工质量这么差。但是好在这个问题可以手动进行修复。

查了之后才发现原来 Nano X 的机身和外部的铁质的外壳是可以分离的,不像 Nano S Plus 的那样是一体的。将 Nano X 的外壳铁质部分分离之后,可以将铁质部分用手或者工具稍微向内弯曲一下。力度不要太大,只需要有一个合理的弯度,可以正好卡住机身的转轴即可。

当弯曲合适之后,再将机身放入到外壳部分卡住。测试一下摩擦是否合适,如果还是太松,就重复上面的动作,直到一个合适的贴合度。


2023-06-30 ledger , ledger-nano-x , cryptocurrency , hardware-wallet , cryptocurrency-wallet

电子书

最近文章

  • 对象存储服务提供商提供的免费存储容量 [[对象存储]] 的英文是 Object-based Storage System,是一种将数据以对象的形式存储在分布式系统中的服务,而不是传统的文件系统或者块存储。
  • 反查一个域名的所有子域名 前段时间看到一篇文章说因为 Nginx 的一个「特性」,在直接访问 IP ,并且没有配置默认证书的情况下 Nginx 就会返回一个 SSL 证书从而倒置域名的泄露,进而泄露了网站的源 IP,使得一些扫描网站,比如 [[censys]] 可以直接查询到域名背后的网站 IP,从而导致网站即使用了 CDN 也会遭受到攻击。在这个契机下,我又开始了衍生,因为在 censys,[[fofa]],[[Shodan]] 等等网站上你只需要输入一个域名就可以获得所有这个站点相关的信息,那么有没有办法可以在只知道一个网站域名的情况下知道所有的二级域名呢。
  • 使用 Dokku 构建属于你自己的 PaaS Dokku 是一个开源的 PaaS,用户可以非常轻松地构建自己的 PaaS 云平台。
  • zlibrary 使用技巧 之前 zlibrary 的域名被取缔也曾经是一度的热门,但是 zlibrary 并没有就此消失。这篇文章就介绍几个继续使用 zlibraray 的小技巧。
  • 《日本的细节》读书笔记 怎么知道的这一本书