以下组合若没有特殊说明,基本都是键位组合。
vim翻页
vim翻半页
ctr-d:向后翻半页ctr-u:向前翻半页
vim整整页
ctr+f:向后翻整页ctr+b:向前翻整页
vim跳转
vim跳首行
g+g:1
第二种方式需要输入:
先按shift+:
再输入1
vim跳尾行
shift+g:$
第二种方式需要输入:
先按shift+:
再输入$
以下组合若没有特殊说明,基本都是键位组合。
ctr-d:向后翻半页ctr-u:向前翻半页ctr+f:向后翻整页ctr+b:向前翻整页g+g:1shift+:1shift+g:$shift+:$需要一个正常的可工作仓库,而不是裸镜像仓库。以下是在不使用 --mirror 选项的情况下,拉取所有分支和标签并推送到新仓库的步骤:
首先,正常克隆源仓库:
# 克隆源仓库(默认只会检出 main 或 master 分支)
git clone <源仓库URL> repo-copy
cd repo-copy
默认情况下,git clone 只会创建和检出默认分支。你需要额外步骤来获取和创建所有远程分支的本地跟踪:
# 获取所有远程分支的信息
git fetch --all
# 为每个远程分支创建本地跟踪分支
git branch -r | grep -v '\->' | while read remote; do
git branch --track "${remote#origin/}" "$remote"
done
# 拉取所有分支的最新更改
git fetch --all
git pull --all
确保所有标签也被获取:
# 拉取所有标签
git fetch --tags
# 添加目标远程仓库
git remote add target <目标仓库URL>
# 推送所有分支到目标仓库
git push target --all
# 推送所有标签到目标仓库
git push target --tags
下面是一个完整的脚本,可以一键完成整个过程:
# 克隆源仓库
git clone <源仓库URL> repo-copy
cd repo-copy
# 获取所有远程分支信息
git fetch --all
# 为远程分支创建本地跟踪分支
git branch -r | grep -v '\->' | while read remote; do
git branch --track "${remote#origin/}" "$remote"
done
# 拉取所有分支和标签的最新更改
git fetch --all
git pull --all
git fetch --tags
# 添加目标远程仓库
git remote add target <目标仓库URL>
# 推送所有内容到目标仓库
git push target --all
git push target --tags
echo "所有分支和标签已成功推送到目标仓库"
在较新版本的 Git 中,你可以使用以下简化命令:
# 克隆仓库
git clone <源仓库URL> repo-copy
cd repo-copy
# 获取所有分支并设置本地跟踪
git fetch origin
git checkout -b local_branch origin/remote_branch # 对需要的每个远程分支重复此命令
# 获取所有标签
git fetch --tags
# 添加新远程仓库并推送
git remote add target <目标仓库URL>
git push target --all
git push target --tags
rack-mini-profiler 和 bullet 是ruby 开发中两个广受欢迎的性能分析工具。
Bullet 更加实用,提得建议更加直接有效,rack-mini-profiler 信息丰富,需要更细致的排查时使用。
rack-mini-profilerrack-mini-profiler 是一个轻量级的性能分析工具,它能够实时显示页面加载时间和数据库查询详情。在页面右上角显示一个小窗口,展示了页面加载的总时间,并可以展开查看详细的性能数据。它的主要特点包括:
使用 rack-mini-profiler 只需要在 Gemfile 中添加 gem 'rack-mini-profiler',并重启服务器即可生效。默认情况下它会在开发环境中自动启用。
BulletBullet 则专注于解决 N+1 查询问题和检测未使用的预加载。N+1 查询是 Rails 应用中常见的性能问题,当获取关联数据时可能导致过多的数据库查询。Bullet 通过以下方式帮助开发者:
要使用 Bullet,需要在 Gemfile 中添加 gem 'bullet',并在 config/environments/development.rb 中进行配置:
config.after_initialize do
Bullet.enable = true
Bullet.alert = true
Bullet.rails_logger = true
end
这两个工具的结合使用能够帮助开发者全面了解应用的性能状况,及时发现和解决性能问题。rack-mini-profiler 提供了整体性能的详细视图,而 Bullet 则专注于数据库查询优化,它们互相补充,是 Rails 开发中不可或缺的性能优化工具。
以 JSON、MYSQL、PSQL、SQLITE、XML、YAML 和 CSV 格式提供城市、州、国家/地区的完整数据库。所有国家、州和城市都覆盖并填充了不同的组合和版本。
link: https://github.com/dr5hn/countries-states-cities-database
主要命令
rake db:migrate
rake db:rollback
rake db:migrate:up
rake db:migrate:down
rake db:migrate:redo
指定版本号的回滚
rake db:migrate:down VERSION=20141119130134
回滚最近几个迁移
rake db:rollback STEP=n
n 代表个数。注意:是最近几个,它们会被一起移除。
其它类似命令:
只执行指定版本号的迁移
rake db:migrate VERSION=20141119130134
只执行最近几次迁移
rake db:migrate STEP=n
回滚、然后重新执行最近几次迁移
rake db:migrate:redo STEP=n
来源:Rake 简介与编写
Rake 用法简介
Rake 的意思是 Ruby Make,一个用 ruby 开发的代码构建工具。
1.以任务的方式创建和运行脚本 当然,你可以用脚本来创建每一个你希望自动运行的任务。但是,对于大型的应用来说,你几乎总是需要为数据库迁移 (比如 Rails 中 db:migrate 任务)、清空缓存、或者代码维护等等编写脚本。对于每一项任务,你可能都需要写若干脚本,这会让你的管理变得复杂。那么,把它们用任务的方式整理到一起,会让管理变得轻松很多。
2.追踪和管理任务之间的依赖 Rake 还提供了轻松管理任务之间依赖的方式。比如,”migrate”任务和”schema:dump”任务都依赖于 “connect_to_database”任务,那么在”migrate”任务调用之前,”connect_to_database”任务都会被执行。
首先 rake 文件的后缀是.rake,存放在 lib/tasks 文件夹下。 可以通过 rake –tasks 来查看当前程序下所已存在的 rake 脚本。 看下面这个例子:
desc "study rake about rails" #desc 是Rake定义的方法,表示对下面定义任务的描述.这个描述会在使用Rake --tasks(或者Rake -T)命令时输出在屏幕上.
task :study_rake do #cmd 命令行中执行 rake study_rake 开始执行脚本,task是Rake最重要的方法.它的方法定义是:task(args, &block).任务体是一个block。
%w(a b c).each do |d|
puts d #编写你所需的功能代码。
end
end
这就是创建了一个 rake 脚本,这个脚本的作用是循环遍历 [“a”, “b”, “c”] 这个数组。
依赖关系
desc "rake1"
task :rake1 do
puts "rake1"
end
desc "rake2"
task ::rake2=> :rake1 do
puts "rake2"
end
输出结果:
rake1
rake2
命名空间
namespace :today do
desc "rake1"
task :rake1 do
puts "rake1"
end
end
那执行命令就是:rake today:rake1
在一个任务中调用另外一个任务
desc "today rake"
task :today do
Rake::Task["rakes:rake1"].invoke
Rake::Task["rakes:rake2"].invoke
Rake::Task["rakes:rake3"].invoke
end
namespace :rakes do
desc "rake1"
task :rake1 do
puts "rake1"
end
desc "rake2"
task :rake2 do
puts "rake2"
end
desc "rake3"
task :rake3 do
puts "rake3"
end
end
默认任务
task :default => [:today]
Rails 预定义了大量的 Rake 任务,在 Rails 应用的开发过程中,你想必已经在大量使用它们了。在 Rails 中,所有的 Rake 任务都放在 rails 目录的 lib/tasks 目录下 (在作者的环境下是 C:\Ruby\lib\ruby\gems\1.8\gems\rails-2.3.5 \lib\tasks),所有的 rake 任务都以.rake 作为后缀名,这些以.rake 结尾的文件会被自动加载到你的环境中。你可以到一个已有的 Rails 工程根目录下键入 rake –tasks,可以看到很多的 rake 任务已经为你整装待发了。
E. 参考资料 http://blog.sina.com.cn/s/blog_4748c4d20100y9iu.html
来源: 如何调试 Vim 脚本
使用 -D 参数可以开启 Debug 模式, 在 Debug 模式中可以使用 cont, next, interrupt, step, quit 等调试命令, 以及 breakadd, breakdel 来添加和移除断点。 使用 -u 来禁止加载任何配置文件,使用 :source 命令逐个加载。 使用 :set verbose 和 :set verbosefile 等 配置变量 可以设置日志级别和输出文件, -V 启动参数也可以起到同样的作用。
在介绍 Debug 之前有必要先介绍如何查看运行日志,本文只介绍到日志级别的设置方法和日志文件的设置方法。 日志级别是由 verbose 配置变量 控制的。这是一个默认为零的数字,级别越高输出越详细。 verbose 非零时 Vim 就会在当前窗口显示日志信息,例如 :set verbose=20 就可以开启几乎所有日志。 这些级别的描述如下:
>= 1 读写 viminfo 文件时
>= 2 当 ":source" 一个文件时,通常是载入一个配置文件
>= 5 所有搜索到的 tag 文件和 include 文件
>= 8 执行到 autocommands 的文件
>= 9 每次执行到 autocommand 时
>= 12 每次执行到 function 时
>= 13 产生、捕获、结束处理、忽略一个异常时
>= 14 ":finally" 语句中等待的所有命令
>= 15 每一个执行到的 Ex 命令(截断到 200 字符)
更多 verbose 选项变量的信息可以参考 :help vbs。 日志级别也可以通过 -V 启动参数来设置。例如:
vim -V20 main.cpp
如果你试过上述日志级别的设置方式会发现日志直接输出在当前屏幕,这会影响在当前 Vim 中的连贯操作。 我们可以通过 :set verbosefile 把日志输出到文件中。例如把它输出到 vim.log 文件:
set verbosefile=vim.log
然后在另一个 Shell 中 tail 这个文件,我们就可以一边使用 Vim 一边查看它的日志了:
tail -f vim.log
更多 verbosefile 选项变量的信息可以参考 :help verbosefile。 日志文件也可以通过 -V 启动参数来设置。例如设置级别为 20,输出文件名为 vim.log:
vim -V20vim.log main.cpp
注意级别与文件名之间不能加空格,且文件名不得以数字开头(否则会被识别为级别的一部分)。
有时为了定位问题,我们可以禁止 Vim 自动加载配置文件和插件,手动地逐个加载 Vim 脚本。 需要先零配置启动 Vim,通常设置 -u 即可:
vim -u NONE main.cpp
如果你在使用 GVim 可能需要使用 -U,具体情况可参考 :help -U 或 StackOverflow。 启动后使用 :source {filename} 命令来逐个加载 Vim 配置即可。
在启动 Vim 时添加 -D 参数即可开启调试模式,Vim 会在第一行配置文件出中断并进入 Debug 模式:
vim -D main.cpp
中断后会进入 Debug 模式,你可以看到 > 提示符。此时你就可以输入 Debug 命令,操作方式和 gdb 非常类似:
掌握 Debug 命令后下一个事情就是打断点,可以在函数和文件的相应行号处添加断点:
breakadd func [lineNumber] functionName
breakadd file [lineNumber] fileName
breakadd here
同样的语法可以用来移除断点,关键字从 breakadd 换为 breakdel:
breakdel func [lineNumber] functionName
breakdel file [lineNumber] fileName
breakdel here
还可以按照编号移除 breakdel {number} 和移除全部 breakdel *。 更详细的参数和命令可以参考 :help debug。
上述日志和调试命令已经足够定位 Vim 脚本的问题了。 下面介绍几个小技巧可以方便一些场景下的操作:
像 Chrome 控制台一样,可以 Debug 某个命令:
:debug CommandName
也可以直接 debug 某个函数,不需要 Vim 先进入 Debug 模式:
:debug call Foo()
类似地,日志级别也可以在调用函数时进行设置:
:20verbose call Foo()
References: Gemini 2.5 Pro
本文对比一下 Tailscale、ZeroTier 和 WireGuard 这三个流行的虚拟网络/VPN 解决方案。
需要明确一点:
以下是它们的详细对比:
| 特性 | Tailscale | ZeroTier | WireGuard (协议本身) |
|---|---|---|---|
| 核心技术 | 基于 WireGuard 协议 | 自有协议 (类似 L2 虚拟交换机) | WireGuard 协议 |
| 易用性/设置 | 非常高:通过 SSO (Google/Microsoft/GitHub 等) 登录,自动配置和密钥管理。 | 高:创建网络,安装客户端,加入网络即可。需要手动授权设备。 | 低:需要手动生成密钥对、交换公钥、配置 IP 地址和路由。 |
| 管理方式 | 中心化控制平面:Tailscale 服务器(官方托管)或自托管 Headscale 管理设备、ACL 等。 | 中心化控制平面:ZeroTier Central (官方托管) 或自托管 Controller 管理网络、成员、规则等。 | 去中心化:每个节点独立配置,没有中央管理点。 |
| NAT 穿透 | 优秀:使用 ICE (STUN/TURN) 和 DERP 中继服务器,穿透成功率高。 | 优秀:使用 UDP 打洞和中继服务器,穿透能力强。 | 基本/无:协议本身不处理 NAT 穿透,需要手动端口转发或依赖其他工具。 |
| 网络模型 | 点对点 Mesh 网络 (设备间尽可能直连,失败则通过 DERP 中继)。更像 L3 网络。 | 虚拟 L2 以太网 (支持广播/多播)。更像一个虚拟交换机。 | 点对点隧道。 |
| 性能 | 非常高:继承 WireGuard 的高性能,中继时会有损耗。 | 高:性能良好,但协议开销通常略高于 WireGuard。 | 非常高:协议简洁,内核态实现,开销极小。 |
| 安全性 | 基于 WireGuard 的强加密。通过身份提供商进行认证。ACL 控制访问。 | 自有加密协议。通过网络 ID 和管理员授权控制成员。规则引擎可定义 L2/L3 策略。 | 现代、公认的强加密 (ChaCha20, Poly1305)。基于公钥认证。 |
| 灵活性/定制 | 中等:专注于简化连接,配置选项相对较少,但够用。 | 高:提供虚拟 L2 网络,更灵活地构建复杂网络拓扑,规则引擎强大。 | 非常高:完全控制配置的方方面面,但需要专业知识。 |
| 跨平台 | 广泛支持 (Linux, Windows, macOS, iOS, Android, Synology 等) | 广泛支持 (Linux, Windows, macOS, iOS, Android, NAS 等) | 广泛支持 (内核集成或用户态实现) |
| 开源情况 | 客户端开源。官方控制平面闭源,但有开源替代 Headscale。 | 核心和 Controller 开源,可完全自托管。 | 完全开源。 |
| 价格模式 | Freemium:免费版功能慷慨 (个人用户足够),提供付费订阅计划。 | Freemium:免费版限制网络成员数量 (25 个),提供付费订阅计划。 | 完全免费 (协议本身)。 |
| 主要使用场景 | 个人设备互联、小型团队远程访问、简单的站点到站点连接、替代传统 VPN。 | 创建复杂的虚拟局域网、IoT 设备连接、需要 L2 功能 (如广播) 的场景、跨地域组网。 | 作为 VPN 协议的基础、性能要求极高的点对点连接、需要完全控制和透明度的场景。 |
总结和选择建议:
简单来说:
Tailscale 和 ZeroTier 解决了 WireGuard 原生配置复杂和缺乏管理功能的问题,但引入了中心化的控制平面(尽管可以自托管)。你需要根据自己的具体需求、技术能力和对中心化/易用性的偏好来做出选择。
我们来深入对比一下这三者在自托管(Self-Hosted)场景下的情况。
这里需要明确:
wg-easy, WireGuard UI 等)来辅助管理配置文件和密钥,但这本质上还是点对点配置的延伸,没有像 Headscale 或 ZeroTier Controller 那样的动态协调能力。自托管场景对比:
| 特性 | Headscale (自托管 Tailscale) | 自托管 ZeroTier Controller | 手动 WireGuard / 简单管理 UI |
| 易用性 (设置) | 中等:部署 Headscale (二进制/Docker),配置数据库,可能需要反向代理。需要 Linux/容器知识。官方文档和社区支持较好。 | 中等到困难:部署 Controller (二进制/Docker),配置较为复杂,需要理解其网络和身份概念。文档相对 Headscale 可能略少或分散。 | 非常困难 (纯手动) / 中等 (用 UI):纯手动极繁琐。简单 UI 降低了密钥/配置生成难度,但网络拓扑和路由仍需较多手动干预。 |
| 易用性 (客户端添加/管理) | 较容易:客户端使用 `tailscale login –login-server | ||
| ` 指向自建服务器,通过 Headscale CLI 或 Web UI 授权。 | 中等:客户端加入网络 ID,需要在 Controller UI/API 手动授权每个设备。流程相对 Headscale 稍繁琐。 | 困难:需要手动在每个相关节点上添加对端公钥、IP、路由等信息。极易出错且耗时。 | |
| 性能 (数据平面) | 优异:基于 WireGuard,P2P 直连性能极佳。若通过自托管 DERP 中继,性能取决于中继服务器的配置和网络。 | 良好:P2P 直连性能好,但协议开销比 WireGuard 稍大。通过自托管 Moons 中继,性能取决于 Moon 服务器。 | 最优异:纯 WireGuard 隧道,无额外开销,性能仅受限于硬件和网络路径。 |
| 灵活性 | 中等:专注于 L3 连接和 ACL 访问控制。支持子网路由、出口节点。缺乏 L2 功能。配置相对标准化。 | 高:提供虚拟 L2 网络,支持广播/多播,规则引擎强大,可实现复杂的网络拓扑和策略。 | 非常高:完全控制所有网络参数、路由、防火墙规则。可以构建任何拓扑,但一切都需要手动实现。 |
| 拓展性 (Scalability) | 良好:Headscale 设计上可支持大量设备。可通过优化数据库、部署多个 Headscale 实例和自建 DERP 网络来扩展。 | 良好:Controller 可以管理大量设备和网络。可通过优化主机、自建 Moons 网络来扩展。大规模部署经验社区分享可能略少。 | 差 (纯手动) / 依赖工具:纯手动管理方式无法扩展。依赖的管理工具决定了其扩展性。 |
| 延迟 (Latency) | 低:P2P 直连延迟极低 (WireGuard 本身)。自托管控制平面和 DERP 可以部署在离用户更近的位置,可能优化信令和中继延迟。 | 较低:P2P 直连延迟好。自托管 Controller 和 Moons 可以就近部署,优化信令和中继延迟。协议本身可能有微小额外延迟。 | 最低:无任何外部依赖(除网络路径本身),纯 P2P 延迟最低。 |
| 维护复杂度 | 中等:需要维护 Headscale 服务、数据库、可能的反向代理和 DERP 服务器。关注 Headscale 和 Tailscale 客户端的更新。 | 中等到高:需要维护 Controller 服务、可能的数据库、Moons 服务器。Controller 本身的配置和升级可能比 Headscale 复杂。 | 低 (稳定后) / 高 (变更时):一旦配置好且不变,几乎无需维护。但任何节点增减、IP 变更都需要手动修改大量配置。 |
| 关键优势 | 平衡易用性与自托管控制,继承 Tailscale 优点,社区活跃。 | 强大的 L2 网络能力和规则引擎,完全开源的 Controller。 | 极致性能、简单协议、完全控制、无中心依赖。 |
| 关键劣势 | 缺乏 L2 功能,依赖社区维护 Headscale 及相关生态。 | 设置和管理相对复杂,性能相比 WireGuard 略逊。 | 管理噩梦(尤其节点多时),无自动 NAT 穿透,需要大量手动配置。 |
总结与建议:
选择 Headscale (自托管 Tailscale):
选择自托管 ZeroTier Controller:
选择手动 WireGuard / 简单管理 UI:
核心考量:自托管 Headscale 和 ZeroTier Controller 都是为了解决纯 WireGuard 在规模化部署和易用性上的短板,它们引入了控制平面来自动化协调工作。你需要付出的代价是部署和维护这个控制平面。选择哪个,主要看你对 L2 功能的需求、对易用性/管理复杂度的偏好以及对社区生态的依赖程度。
三个方案都使用过,tailscale 接入最快,wiregard 最灵活,zerotier 似乎延迟较低。总之得在自己的环境下尝试,最后选择最合适的那一个。
必需:将 env
DERP_DOMAIN设置为您的域docker run -e DERP_DOMAIN=derper.your-domain.com -p 80:80 -p 443:443 -p 3478:3478/udp fredliang/derper也有其他不使用域名的方法,参考文献自行探索
好的,在 Ceph 中查看哪个 RBD (RADOS Block Device) 镜像的 I/O 读写最高,最常用的方法是使用 rbd perf image iotop 或 rbd perf image iostat 命令。
这两个命令都需要指定 存储池 (pool) 的名称,因为 RBD 镜像是存在于特定的存储池中的。
方法一:使用 rbd perf image iotop (推荐)
这个命令会实时显示指定存储池中各个 RBD 镜像的 I/O 统计信息,并默认按总 I/O 操作数 (IOPS) 或总带宽排序,非常直观。
rbd pool ls 或 ceph osd lspools 列出所有存储池。rbd perf image iotop
<poolname>将 `
` 替换为实际的存储池名称。 例如,如果你的 RBD 镜像在名为 `rbd_images` 的存储池中: “`bash rbd perf image iotop rbd_images “` 3. **查看输出:** 该命令会持续刷新输出,通常包含以下列: * `image`: RBD 镜像的名称。 * `rd_ops`, `wr_ops`, `total_ops`: 每秒读、写、总操作次数 (IOPS)。 * `rd_bytes`, `wr_bytes`, `total_bytes`: 每秒读、写、总带宽 (Bytes/s)。 输出通常会按 `total_ops` 或 `total_bytes` 降序排列,排在最前面的就是当前 I/O 最高的 RBD 镜像。按 `Ctrl+C` 退出。 **方法二:使用 `rbd perf image iostat`** 这个命令与 `iotop` 类似,也显示 I/O 统计,但格式可能略有不同,有时显示的是累积值或平均值,具体取决于 Ceph 版本和配置。 1. **确定存储池名称。** 2. **执行命令:** “`bash rbd perf image iostat “` 同样,将 ` ` 替换为实际的存储池名称。 例如: “`bash rbd perf image iostat rbd_images “` 3. **查看输出:** 分析输出中的读写 IOPS 和带宽列,找出数值最高的镜像。这个命令也可能持续刷新,按 `Ctrl+C` 退出。 **重要注意事项:** 1. **指定存储池:** 这两个命令都**必须**指定存储池名称。你需要对每个包含 RBD 镜像的存储池分别运行这些命令,才能找到整个集群中 I/O 最高的镜像。 2. **性能计数器:** 这些命令依赖于 Ceph 的性能计数器 (performance counters)。通常这些计数器是默认启用的,但如果遇到问题,可能需要检查相关配置。 3. **权限:** 执行这些命令需要相应的 Ceph 用户权限(通常是 client.admin 或具有针对特定存储池读写权限的用户)。 4. **Ceph 版本:** 命令的具体行为和输出格式可能随 Ceph 版本略有变化。 5. **Ceph Dashboard:** 如果你部署了 Ceph Dashboard(Web UI),通常在 Dashboard 的 “Block” -> “Images” 部分也能方便地查看各个 RBD 镜像的实时性能指标,包括 IOPS 和带宽,并且可以进行排序。这对于图形化监控来说更加友好。 **总结:** 使用 `rbd perf image iotop ` 是查找指定存储池中当前 I/O 活动最密集的 RBD 镜像的最直接和常用的命令行方法。记得要检查所有相关的存储池。