Git 服务于服务器上的不同分支
Git serve different branches on server
我考虑在网络服务器上进行一些高级 A/B 测试,我希望我可以使用 git 轻松实现它。
简单示例
让我用一个简单的例子进一步解释一下,假设我有以下 3 个分支:
- 高手
- 蓝色按钮
- 红色按钮
这些分支都包含了一个HTML文件,区别在按钮颜色上很明显。
通常 master 分支会被提供给访问者,但是我想测试其他分支的 10% 的访问者,看看哪个分支提供最好的转换率(点击按钮)。
这将需要一些脚本来将用户分组,然后为该用户提供正确的分支。
问题范围
我正在做的项目:
- 在 PHP > 5.5 上运行,并且可以使用 Java 代码对其进行扩展。
- (当前)包含 2.84 GB 存储,不包括作曲家依赖项、缓存和数据库存储
- 应该能够同时服务多达 100 个实验
- 最好,如果需要,也应该能够提供较旧的实验
任何实验都必须能够在 git 分支中拥有任何替代文件。 A/B 在这种情况下的测试不限于用户界面,但它应该(除其他外)还支持不同的:
- 内容(需要修改数据库和缓存)
- 基本代码(用于测试速度差异)
- 更多人会关注
其中一些点需要更改底层框架、它们的使用方式或其他文件。因此,必须可以更改分支中的任何文件。
现在我想知道我有哪些选项可以让服务器同时访问所有分支。
我想到的选项:
- 在每个请求上切换分支(结帐),显然会很慢
- 将每个分支克隆到一个子文件夹中,这将复制文件
我希望有一个更强大的解决方案来解决这个问题:
- 不重复文件。
- 哪个快。最佳情况下,它应该与访问任何普通文件一样快。
- 最好在 Java 或 PHP
中采用程序化方法
如何实现?
您可以使用智能部署系统实施您的架构。您需要执行以下步骤:
- 将每 3 个分支(master、blue 和 red)克隆到单独的文件夹
- master 分支是规范的,我们不碰它
- 进入blue分支比较根目录下的文件和master分支根目录下的文件。如果文件的哈希值相等,则将 "blue" 文件替换为硬 link 到 "master" 文件(可能是符号 link,这是性能问题)。递归地将文件放入嵌套目录中。
- 进入红色分支并重复与蓝色分支相同的操作
您可以使用 capistrano 和 Ruby 语言的自定义任务来实施此类部署策略。
我加说明图
更新算法:
这种方法比较复杂,但我们不克隆 3 个分支:
- 克隆主分支并为蓝色和红色版本创建文件夹
- master 分支是规范的,我们不碰它
- 进入蓝色版本文件夹
- 使用命令
git diff --name-status blue..master
获取更改的文件
假设我们得到 diff 命令的输出
A test_added.txt
D test_deleted.txt
M text_modified.txt
D test/test.txt
- 所以我们可以为每个 file/folder 创建 links,在 diff 命令的输出中没有提到
- 如果文件标有
A
或 M
字母(例如 test_added.txt
、text_modified.txt
),我们应该 运行 git cat-file blob blue:test_added.txt > test_added.txt
- 如果文件标有
D
(例如test_deleted.txt
)我们应该忽略这个文件
- 对于嵌套的文件夹(例如
test/
),我们需要递归地继续上述步骤
- 进入红色版本文件夹并重复与蓝色版本相同的操作
我考虑在网络服务器上进行一些高级 A/B 测试,我希望我可以使用 git 轻松实现它。
简单示例
让我用一个简单的例子进一步解释一下,假设我有以下 3 个分支:
- 高手
- 蓝色按钮
- 红色按钮
这些分支都包含了一个HTML文件,区别在按钮颜色上很明显。
通常 master 分支会被提供给访问者,但是我想测试其他分支的 10% 的访问者,看看哪个分支提供最好的转换率(点击按钮)。
这将需要一些脚本来将用户分组,然后为该用户提供正确的分支。
问题范围
我正在做的项目:
- 在 PHP > 5.5 上运行,并且可以使用 Java 代码对其进行扩展。
- (当前)包含 2.84 GB 存储,不包括作曲家依赖项、缓存和数据库存储
- 应该能够同时服务多达 100 个实验
- 最好,如果需要,也应该能够提供较旧的实验
任何实验都必须能够在 git 分支中拥有任何替代文件。 A/B 在这种情况下的测试不限于用户界面,但它应该(除其他外)还支持不同的:
- 内容(需要修改数据库和缓存)
- 基本代码(用于测试速度差异)
- 更多人会关注
其中一些点需要更改底层框架、它们的使用方式或其他文件。因此,必须可以更改分支中的任何文件。
现在我想知道我有哪些选项可以让服务器同时访问所有分支。
我想到的选项:
- 在每个请求上切换分支(结帐),显然会很慢
- 将每个分支克隆到一个子文件夹中,这将复制文件
我希望有一个更强大的解决方案来解决这个问题:
- 不重复文件。
- 哪个快。最佳情况下,它应该与访问任何普通文件一样快。
- 最好在 Java 或 PHP 中采用程序化方法
如何实现?
您可以使用智能部署系统实施您的架构。您需要执行以下步骤:
- 将每 3 个分支(master、blue 和 red)克隆到单独的文件夹
- master 分支是规范的,我们不碰它
- 进入blue分支比较根目录下的文件和master分支根目录下的文件。如果文件的哈希值相等,则将 "blue" 文件替换为硬 link 到 "master" 文件(可能是符号 link,这是性能问题)。递归地将文件放入嵌套目录中。
- 进入红色分支并重复与蓝色分支相同的操作
您可以使用 capistrano 和 Ruby 语言的自定义任务来实施此类部署策略。
我加说明图
更新算法:
这种方法比较复杂,但我们不克隆 3 个分支:
- 克隆主分支并为蓝色和红色版本创建文件夹
- master 分支是规范的,我们不碰它
- 进入蓝色版本文件夹
- 使用命令
git diff --name-status blue..master
获取更改的文件
假设我们得到 diff 命令的输出
A test_added.txt
D test_deleted.txt
M text_modified.txt
D test/test.txt
- 所以我们可以为每个 file/folder 创建 links,在 diff 命令的输出中没有提到
- 如果文件标有
A
或M
字母(例如test_added.txt
、text_modified.txt
),我们应该 运行git cat-file blob blue:test_added.txt > test_added.txt
- 如果文件标有
D
(例如test_deleted.txt
)我们应该忽略这个文件 - 对于嵌套的文件夹(例如
test/
),我们需要递归地继续上述步骤 - 进入红色版本文件夹并重复与蓝色版本相同的操作