标签 GitLab 下的文章

通过使用 Ansible 镜像 Git 存储库,保护对重要项目的访问。

开源无处不在。它在家里的计算机上、在工作场所的计算机上、在互联网上,并且很多都由 Git 管理。由于 Git 是分布式的,因此许多人也将其视为一种众包的备份解决方案。从理论上讲,每当有人将 Git 存储库克隆到其本地计算机时,他们就创建了该项目源代码的备份。如果有 100 个人这样做,则存储库就有 100 个备份副本。

从理论上讲,这可以缓解“灾难”的影响,例如当项目维护者突然决定删除存储库莫名其妙地阻止所有流量,导致开发人员们无头苍蝇般地寻找谁拥有主分支的最新版本。类似的,整个代码托管站点也会消失。没有人会想到 Google Code、Microsoft CodePlex 或 Gitorious 会在鼎盛时期将被关闭。

简而言之,如果在过去的几十年中互联网教给了我们一些东西,那就是依靠互联网神奇地创建备份并不是冗余的最可靠途径。

此外,对于许多人来说,很多开源项目都托管在 GitHub 上是个问题 —— GitHub 并不是开放平台。许多开发人员和用户都希望支持诸如 GitLab 之类的堆栈并与之交互,它具有开源社区版本。

使用 Ansible 管理 Git

Git 的去中心方式对于解决这个问题很有用。使用纯 Git,你可以使用一个 push 命令轻松地将其推到两个或多个存储库。但是,为了使其在发生意外故障时有用,你必须经常与 Git 存储库进行交互(特别是推送)。此外,即使你可能永远不会自己推送或拉出代码,也可能有一些要备份的存储库。

但是,使用 Ansible,你可以自动执行项目主分支(或其他任何分支)的 Git 拉取,然后自动进行存储库到“异地”镜像的 Git 推送。换句话说,你可以让你的计算机定期从 GitHub 拉取并推送到 GitLab 或 Gitolite 或 Gitea(或你喜欢的任何 Git 托管主机)。

Ansible 模块

如果不是因其出色的模块集合,那么 Ansible 就没那么出色。像 Python 的第三方库或 Linux 的应用程序一样,这个技术引擎的一个有用而令人惊讶的简单技巧是,Ansible 以其他人贡献的组件而闻名。因为本文正在研究如何有效和可靠地备份 Git 存储库,所以这里使用的模块是 Git 模块ini\_file 模块。

首先,创建一个名为 mirror.yaml 的文件作为 剧本 playbook 。你可以像通常使用 Ansible 一样,从 nametask 条目开始。本示例将 localhost 添加到 hosts 列表中,以便在控制器计算机(你现在坐在前面的计算机)上运行 动作 play ,但是在现实生活中,你可能会在特定的主机或一组网络上的主机上运行它。

---
- name: "Mirror a Git repo with Ansible"
  hosts: localhost
  tasks:

Git 拉取和克隆

如果要进行备份,则需要最新代码的副本。明显,在 Git 仓库中实现这一目标的方法是执行 git pull。 但是,pull 会假定克隆已经存在,而写得很好的 Ansible 动作(Ansible 脚本)则尽可能少的假定。最好告诉 Ansible 先克隆存储库。

将你的第一个任务添加到剧本:

---
- name: "Mirror a Git repo with Ansible"
  hosts: localhost
  vars:
    git_dir: /tmp/soso.git
  tasks:

  - name: "Clone the git repo"
    git:
       repo: 'https://github.com/ozkl/soso.git'
       dest: '{{ git_dir }}'
       clone: yes
       update: yes

这个例子使用了开源的、类似于 Unix 的操作系统 soso 作为我要镜像的存储库。这是一个完全任意的选择,绝不意味着我对该存储库的未来缺乏信心。它还使用变量来引用目标文件夹 /tmp/soso.git,这很方便,并且如果以后你希望将它扩展为一个通用的镜像脚本也会受益。在现实生活中,你的工作机上可能会比 /tmp 具有更永久的位置,例如 /home/gitmirrors/soso.git/opt/gitmirrors/soso.git

运行你的剧本:

$ ansible-playbook mirror.yaml

首次运行该剧本时,Ansible 会正确检测到 Git 存储库在本地尚不存在,因此将其克隆。

PLAY [Ansible Git mirror] ********

TASK [Gathering Facts] ***********
ok: [localhost]

TASK [Clone git repo] ************
changed: [localhost]

PLAY RECAP ***********************
localhost: ok=2 changed=1 failed=0 [...]

如果你再次运行该剧本,Ansible 会正确检测到自上次运行以来没有任何更改,并且会报告未执行任何操作:

localhost: ok=2 changed=0 failed=0 [...]

接下来,必须指示 Ansible 将存储库推送到另一个 Git 服务器。

Git 推送

Ansible 中的 Git 模块不提供 push 功能,因此该过程的一部分是手动的。但是,在将存储库推送到备用镜像之前,你必须具有一个镜像,并且必须将镜像配置为备用 远程服务器 remote

首先,必须将备用的远程服务器添加到 Git 配置。因为 Git 配置文件是 INI 样式的配置,所以你可以使用 ini_file Ansible 模块轻松地添加所需的信息。将此添加到你的剧本:

 - name: "Add alternate remote"
    ini_file: dest={{ git_dir }}/.git/config section='remote \"mirrored\"' option=url value='[email protected]:example/soso-mirror.git'
    tags: configuration

为此,你必须在目标服务器上有一个空的存储库(在本例中为 GitLab.com)。如果需要在剧本中创建目标存储库,可以按照 Steve Ovens 的出色文章《如何使用 Ansible 通过 SSH 设置 Git 服务器》来完成。

最后,直接使用 Git 将 HEAD 推送到备用远程服务器:

 - name: "Push the repo to alternate remote"
    shell: 'git --verbose --git-dir={{ git_dir }}/.git push mirrored HEAD'

像往常一样运行该剧本,然后使该过程自动化,这样你就不必再次直接运行它了。你可以使用变量和特定的 Git 命令来调整脚本以适应你的需求,但是通过常规的拉取和推送操作,可以确保驻留在一台服务器上的重要项目可以安全地镜像到另一台服务器上。

这是完整的剧本,供参考:

---
- name: "Mirror a Git repository with Ansible"
  hosts: localhost
  vars:
    git_dir: /tmp/soso.git

  tasks:

  - name: "Clone the Git repo"
    git:
       repo: 'https://github.com/ozkl/soso.git'
       dest: '{{ git_dir }}'
       clone: yes
       update: yes

  - name: "Add alternate remote"
    ini_file: dest={{ git_dir }}/.git/config section='remote \"mirrored\"' option=url value='[email protected]:example/soso-mirror.git'
    tags: configuration
 
  - name: "Push the repo to alternate remote"
    shell: 'git --verbose --git-dir={{ git_dir }}/.git push mirrored HEAD'

via: https://opensource.com/article/19/11/how-host-github-gitlab-ansible

作者:Seth Kenlon 选题:lujun9972 译者:wxy 校对:wxy

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

通过 GitLab 或 GitHub Pages 来提供一个 WordPress 镜像站点, 从而最小化安全问题。

很久以前,我为一个家庭成员建立了一个 WordPress 博客。如今有很多选择,但是当时如果你需要一个带有所见即所得的编辑器的基于 Web 的 CMS,那么就没什么像样的的选择了。而一切运行良好的不幸的副作用是随着时间的推移该博客产生了很多内容。这意味着我要经常更新 WordPress 以防止不断出现的漏洞。

因此,当我决定劝说家人切换到 Hugo 会相对容易,然后可以在 GitLab 上托管博客。但是尝试提取所有内容并将其转换为 Markdown 变成了一个巨大的麻烦。有自动脚本完成了 95% 的工作,但并不完美。手动更新所有帖子不是我想做的事情,所以最终,我放弃了试图移动博客。

最近,我又开始考虑这个问题,并意识到有一个我没有考虑过的解决方案:我可以继续维护 WordPress 服务器,但将其设置为发布静态镜像,并使用 GitLab Pages(或 GitHub Pages ,如果你喜欢的话)提供服务。这能让我自动化 Let’s Encrypt 证书续订并消除与托管 WordPress 站点相关的安全问题。然而,这意味着评论将无法使用,但在这种情况下感觉就像是一个小损失,因为博客没有收到很多评论。

这是我提出的解决方案,到目前为止似乎运作良好:

  • 托管 WordPress 站点中的 URL 没有链接到或来自其他任何地方,以减少它被利用的几率。在此例中,我们将使用 http://private.localconspiracy.com(即使此站点实际上是使用 Pelican 构建的)。
  • 将公共 URL https://www.localconspiracy.com 托管到 GitLab Pages 上
  • 添加 cron 任务,确定两个 URL 之间的最后构建日期何时不同。如果构建日期不同,则镜像 WordPress 版本。
  • 使用 wget 镜像后,将所有链接从“私有”更新成“公共”。
  • 运行 git push 来发布新内容。

这是我使用的两个脚本:

check-diff.sh (cron 每 15 分钟调用一次):

#!/bin/bash

ORIGINDATE="$(curl -v --silent http://private.localconspiracy.com/feed/ 2>&1|grep lastBuildDate)"
PUBDATE="$(curl -v --silent https://www.localconspiracy.com/feed/ 2>&1|grep lastBuildDate)"

if [ "$ORIGINDATE" !=  "$PUBDATE" ]
then
  /home/doc/repos/localconspiracy/mirror.sh
fi

mirror.sh

#!/bin/sh

cd /home/doc/repos/localconspiracy

wget \
--mirror \
--convert-links  \
--adjust-extension \
--page-requisites  \
--retry-connrefused  \
--exclude-directories=comments \
--execute robots=off \
http://private.localconspiracy.com

git rm -rf public/*
mv private.localconspiracy.com/* public/.
rmdir private.localconspiracy.com
find ./public/ -type f -exec sed -i -e 's|http://private.localconspiracy|https://www.localconspiracy|g' {} \;
find ./public/ -type f -exec sed -i -e 's|http://www.localconspiracy|https://www.localconspiracy|g' {} \;
git add public/*
git commit -m "new snapshot"
git push origin master

就是这些了!现在,当博客发生变化时,在 15 分钟内将网站镜像到静态版本并推送到仓库,这将在 GitLab Pages 中反映出来。

如果你想在本地运行 WordPress,这个概念可以进一步扩展。在这种情况下,你不需要服务器来托管你的 WordPress 博客。你可以在本机运行它。在这种情况下,你的博客不可能被攻击利用。只要你可以在本地运行 wget,就可以使用上面的方法在 GitLab Pages 上托管 WordPress 站点。

这篇文章最初发表于 Local Conspiracy。允许转载。


via: https://opensource.com/article/18/8/publish-wordpress-static-gitlab-pages-site

作者:Christopher Aedo 选题:lujun9972 译者:geekpi 校对:wxy

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

最近在开源社区发生了很多事情。首先,微软收购了 GitHub,然后人们开始寻找 GitHub 替代套餐,甚至在 Linus Torvalds 发布 Linux Kernel 4.17 时没有花一点时间考虑它。好吧,如果你一直关注我们,我认为你知道这一切。

但是,如今,GitLab 做出了一个明智的举措,为教育机构和开源项目免费提供高级套餐。当许多开发人员有兴趣将他们的开源项目迁移到 GitLab 时,没有更好的时机来提供这些了。

GitLab 的高级套餐现在对开源项目和教育机构免费

GitLab Logo

在今天(2018/6/7)发布的博客中,GitLab 宣布其旗舰和黄金套餐现在对教育机构和开源项目免费。虽然我们已经知道为什么 GitLab 做出这个举动(一个完美的时机!),但他们还是解释了他们让它免费的动机:

我们让 GitLab 对教育机构免费,因为我们希望学生使用我们最先进的功能。许多大学已经运行了 GitLab。如果学生使用 GitLab 旗舰和黄金套餐的高级功能,他们将把这些高级功能的经验带到他们的工作场所。

我们希望有更多的开源项目使用 GitLab。GitLab.com 上的公共项目已经拥有 GitLab 旗舰套餐的所有功能。像 GnomeDebian 这样的项目已经在自己的服务器运行开源版 GitLab 。随着今天的宣布,在专有软件上运行的开源项目可以使用 GitLab 提供的所有功能,同时我们通过向非开源组织收费来建立可持续的业务模式。

GitLab 提供的这些“免费”套餐是什么?

GitLab Pricing

GitLab 有两类产品。一个是你可以在自己的云托管服务如 Digital Ocean 上运行的软件。另一个是 Gitlab 软件既服务,其中托管由 GitLab 本身管理,你在 GitLab.com 上获得一个帐户。

GitLab Pricing for hosted service

黄金套餐是托管类别中最高的产品,而旗舰套餐是自托管类别中的最高产品。

你可以在 GitLab 定价页面上获得有关其功能的更多详细信息。请注意,支持服务不包括在套餐中。你必须单独购买。

你必须符合某些条件才能使用此优惠

GitLab 还提到 —— 该优惠对谁有效。以下是他们在博客文章中写的内容:

  1. 教育机构:任何为了学习、教育的机构,并且/或者由合格的教育机构、教职人员、学生训练。教育目的不包括商业,专业或任何其他营利目的。
  2. 开源项目:任何使用标准开源许可证且非商业性的项目。它不应该有付费支持或付费贡献者。

虽然免费套餐不包括支持,但是当你迫切需要专家帮助解决问题时,你仍然可以支付每用户每月 4.95 美元的额外费用 —— 当你特别需要一个专家来解决问题时,这是一个非常合理的价格。

GitLab 还为学生们添加了一条说明:

为减轻 GitLab 的管理负担,只有教育机构才能代表学生申请。如果你是学生并且你的教育机构不申请,你可以在 GitLab.com 上使用公共项目的所有功能,使用私人项目的免费功能,或者自己付费。

总结

现在 GitLab 正在加快脚步,你如何看待它?

你有 GitHub 上的项目吗?你会切换么?或者,幸运的是,你从一开始就碰巧使用 GitLab?

请在下面的评论栏告诉我们你的想法。


via: https://itsfoss.com/gitlab-free-open-source/

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

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

fleetster, 我们搭建了自己的 Gitlab 实例,而且我们大量使用了 Gitlab CI。我们的设计师和测试人员也都在用它,也很喜欢用它,它的那些高级功能特别棒。

Gitlab CI 是一个功能非常强大的持续集成系统,有很多不同的功能,而且每次发布都会增加新的功能。它的技术文档也很丰富,但是对那些要在已经配置好的 Gitlab 上使用它的用户来说,它缺乏一个一般性介绍。设计师或者测试人员是无需知道如何通过 Kubernetes 来实现自动伸缩,也无需知道“镜像”和“服务”之间的不同的。

但是,他仍然需要知道什么是“管道”,知道如何查看部署到一个“环境”中的分支。因此,在本文中,我会尽可能覆盖更多的功能,重点放在最终用户应该如何使用它们上;在过去的几个月里,我向我们团队中的某些人包括开发者讲解了这些功能:不是所有人都知道 持续集成 Continuous Integration (CI)是个什么东西,也不是所有人都用过 Gitlab CI。

如果你想了解为什么持续集成那么重要,我建议阅读一下 这篇文章,至于为什么要选择 Gitlab CI 呢,你可以去看看 Gitlab.com 上的说明。

简介

开发者保存更改代码的动作叫做一次 提交 commit 。然后他可以将这次提交 推送 push 到 Gitlab 上,这样可以其他开发者就可以 复查 review 这些代码了。

Gitlab CI 配置好后,Gitlab 也能对这个提交做出一些处理。该处理的工作由一个 运行器 runner 来执行的。所谓运行器基本上就是一台服务器(也可以是其他的东西,比如你的 PC 机,但我们可以简单称其为服务器)。这台服务器执行 .gitlab-ci.yml 文件中指令,并将执行结果返回给 Gitlab 本身,然后在 Gitlab 的图形化界面上显示出来。

开发者完成一项新功能的开发或完成一个 bug 的修复后(这些动作通常包含了多次的提交),就可以发起一个 合并请求 merge request ,团队其他成员则可以在这个合并请求中对代码及其实现进行 评论 comment

我们随后会看到,由于 Gitlab CI 提供的两大特性, 环境 environment 制品 artifact ,使得设计者和测试人员也能(而且真的需要)参与到这个过程中来,提供反馈以及改进意见。

管道 pipeline

每个推送到 Gitlab 的提交都会产生一个与该提交关联的 管道 pipeline 。若一次推送包含了多个提交,则管道与最后那个提交相关联。管道就是一个分成不同 阶段 stage 作业 job 的集合。

同一阶段的所有作业会并发执行(在有足够运行器的前提下),而下一阶段则只会在上一阶段所有作业都运行并返回成功后才会开始。

只要有一个作业失败了,整个管道就失败了。不过我们后面会看到,这其中有一个例外:若某个作业被标注成了手工运行,那么即使失败了也不会让整个管道失败。

阶段则只是对批量的作业的一个逻辑上的划分,若前一个阶段执行失败了,则后一个执行也没什么意义了。比如我们可能有一个 构建 build 阶段和一个 部署 deploy 阶段,在构建阶段运行所有用于构建应用的作业,而在部署阶段,会部署构建出来的应用程序。而部署一个构建失败的东西是没有什么意义的,不是吗?

同一阶段的作业之间不能有依赖关系,但它们可以依赖于前一阶段的作业运行结果。

让我们来看一下 Gitlab 是如何展示阶段与阶段状态的相关信息的。

pipeline-overview

pipeline-status

作业 job

作业就是运行器要执行的指令集合。你可以实时地看到作业的输出结果,这样开发者就能知道作业为什么失败了。

作业可以是自动执行的,也就是当推送提交后自动开始执行,也可以手工执行。手工作业必须由某个人手工触发。手工作业也有其独特的作用,比如,实现自动化部署,但只有在有人手工授权的情况下才能开始部署。这是限制哪些人可以运行作业的一种方式,这样只有信赖的人才能进行部署,以继续前面的实例。

作业也可以建构出 制品 artifacts 来以供用户下载,比如可以构建出一个 APK 让你来下载,然后在你的设备中进行测试; 通过这种方式,设计者和测试人员都可以下载应用并进行测试,而无需开发人员的帮助。

除了生成制品外,作业也可以部署环境,通常这个环境可以通过 URL 访问,让用户来测试对应的提交。

做作业状态与阶段状态是一样的:实际上,阶段的状态就是继承自作业的。

running-job

制品 Artifacts

如前所述,作业能够生成制品供用户下载来测试。这个制品可以是任何东西,比如 Windows 上的应用程序,PC 生成的图片,甚至 Android 上的 APK。

那么,假设你是个设计师,被分配了一个合并请求:你需要验证新设计的实现!

要该怎么做呢?

你需要打开该合并请求,下载这个制品,如下图所示。

每个管道从所有作业中搜集所有的制品,而且一个作业中可以有多个制品。当你点击下载按钮时,会有一个下拉框让你选择下载哪个制品。检查之后你就可以评论这个合并请求了。

你也可以从没有合并请求的管道中下载制品 ;-)

我之所以关注合并请求是因为通常这正是测试人员、设计师和相关人员开始工作的地方。

但是这并不意味着合并请求和管道就是绑死在一起的:虽然它们结合的很好,但两者之间并没有什么关系。

download-artifacts

环境 environment

类似的,作业可以将某些东西部署到外部服务器上去,以便你可以通过合并请求本身访问这些内容。

如你所见, 环境 environment 有一个名字和一个链接。只需点击链接你就能够转至你的应用的部署版本上去了(当前,前提是配置是正确的)。

Gitlab 还有其他一些很酷的环境相关的特性,比如 监控 monitoring ,你可以通过点击环境的名字来查看。

environment

总结

这是对 Gitlab CI 中某些功能的一个简单介绍:它非常强大,使用得当的话,可以让整个团队使用一个工具完成从计划到部署的工具。由于每个月都会推出很多新功能,因此请时刻关注 Gitlab 博客

若想知道如何对它进行设置或想了解它的高级功能,请参阅它的文档

在 fleetster,我们不仅用它来跑测试,而且用它来自动生成各种版本的软件,并自动发布到测试环境中去。我们也自动化了其他工作(构建应用并将之发布到 Play Store 中等其它工作)。

说起来,你是否想和我以及其他很多超棒的人一起在一个年轻而又富有活力的办公室中工作呢? 看看 fleetster 的这些招聘职位 吧!

赞美 Gitlab 团队 (和其他在空闲时间提供帮助的人),他们的工作太棒了!

若对本文有任何问题或回馈,请给我发邮件:[email protected] 或者发推给我:-) 你可以建议我增加内容,或者以更清晰的方式重写内容(英文不是我的母语)。

那么,再见吧,

R.

P.S:如果你觉得本文有用,而且希望我们写出其他文章的话,请问您是否愿意帮我买杯啤酒给我 让我进入 鲍尔默峰值


via: https://rpadovani.com/introduction-gitlab-ci

作者:Riccardo 译者:lujun9972 校对:wxy

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

在扩展 GitLab 数据库和我们应用的解决方案,去帮助解决我们的数据库设置中的问题时,我们深入分析了所面临的挑战。

很长时间以来 GitLab.com 使用了一个单个的 PostgreSQL 数据库服务器和一个用于灾难恢复的单个复制。在 GitLab.com 最初的几年,它工作的还是很好的,但是,随着时间的推移,我们看到这种设置的很多问题,在这篇文章中,我们将带你了解我们在帮助解决 GitLab.com 和 GitLab 实例所在的主机时都做了些什么。

例如,数据库长久处于重压之下, CPU 使用率几乎所有时间都处于 70% 左右。并不是因为我们以最好的方式使用了全部的可用资源,而是因为我们使用了太多的(未经优化的)查询去“冲击”服务器。我们意识到需要去优化设置,这样我们就可以平衡负载,使 GitLab.com 能够更灵活地应对可能出现在主数据库服务器上的任何问题。

在我们使用 PostgreSQL 去跟踪这些问题时,使用了以下的四种技术:

  1. 优化你的应用程序代码,以使查询更加高效(并且理论上使用了很少的资源)。
  2. 使用一个连接池去减少必需的数据库连接数量(及相关的资源)。
  3. 跨多个数据库服务器去平衡负载。
  4. 分片你的数据库

在过去的两年里,我们一直在积极地优化应用程序代码,但它不是一个完美的解决方案,甚至,如果你改善了性能,当流量也增加时,你还需要去应用其它的几种技术。出于本文的目的,我们将跳过优化应用代码这个特定主题,而专注于其它技术。

连接池

在 PostgreSQL 中,一个连接是通过启动一个操作系统进程来处理的,这反过来又需要大量的资源,更多的连接(及这些进程)将使用你的数据库上的更多的资源。 PostgreSQL 也在 max\_connections 设置中定义了一个强制的最大连接数量。一旦达到这个限制,PostgreSQL 将拒绝新的连接, 比如,下面的图表示的设置:

这里我们的客户端直接连接到 PostgreSQL,这样每个客户端请求一个连接。

通过连接池,我们可以有多个客户端侧的连接重复使用一个 PostgreSQL 连接。例如,没有连接池时,我们需要 100 个 PostgreSQL 连接去处理 100 个客户端连接;使用连接池后,我们仅需要 10 个,或者依据我们配置的 PostgreSQL 连接。这意味着我们的连接图表将变成下面看到的那样:

这里我们展示了一个示例,四个客户端连接到 pgbouncer,但不是使用了四个 PostgreSQL 连接,而是仅需要两个。

对于 PostgreSQL 有两个最常用的连接池:

pgpool 有一点特殊,因为它不仅仅是连接池:它有一个内置的查询缓存机制,可以跨多个数据库负载均衡、管理复制等等。

另一个 pgbouncer 是很简单的:它就是一个连接池。

数据库负载均衡

数据库级的负载均衡一般是使用 PostgreSQL 的 “ 热备机 hot-standby ” 特性来实现的。 热备机是允许你去运行只读 SQL 查询的 PostgreSQL 副本,与不允许运行任何 SQL 查询的普通 备用机 standby 相反。要使用负载均衡,你需要设置一个或多个热备服务器,并且以某些方式去平衡这些跨主机的只读查询,同时将其它操作发送到主服务器上。扩展这样的一个设置是很容易的:(如果需要的话)简单地增加多个热备机以增加只读流量。

这种方法的另一个好处是拥有一个更具弹性的数据库集群。即使主服务器出现问题,仅使用次级服务器也可以继续处理 Web 请求;当然,如果这些请求最终使用主服务器,你可能仍然会遇到错误。

然而,这种方法很难实现。例如,一旦它们包含写操作,事务显然需要在主服务器上运行。此外,在写操作完成之后,我们希望继续使用主服务器一会儿,因为在使用异步复制的时候,热备机服务器上可能还没有这些更改。

分片

分片是水平分割你的数据的行为。这意味着数据保存在特定的服务器上并且使用一个分片键检索。例如,你可以按项目分片数据并且使用项目 ID 做为分片键。当你的写负载很高时,分片数据库是很有用的(除了一个多主设置外,均衡写操作没有其它的简单方法),或者当你有大量的数据并且你不再使用传统方式保存它也是有用的(比如,你不能把它简单地全部放进一个单个磁盘中)。

不幸的是,设置分片数据库是一个任务量很大的过程,甚至,在我们使用诸如 Citus 的软件时也是这样。你不仅需要设置基础设施 (不同的复杂程序取决于是你运行在你自己的数据中心还是托管主机的解决方案),你还得需要调整你的应用程序中很大的一部分去支持分片。

反对分片的案例

在 GitLab.com 上一般情况下写负载是非常低的,同时大多数的查询都是只读查询。在极端情况下,尖峰值达到每秒 1500 元组写入,但是,在大多数情况下不超过每秒 200 元组写入。另一方面,我们可以在任何给定的次级服务器上轻松达到每秒 1000 万元组读取。

存储方面,我们也不使用太多的数据:大约 800 GB。这些数据中的很大一部分是在后台迁移的,这些数据一经迁移后,我们的数据库收缩的相当多。

接下来的工作量就是调整应用程序,以便于所有查询都可以正确地使用分片键。 我们的一些查询包含了一个项目 ID,它是我们使用的分片键,也有许多查询没有包含这个分片键。分片也会影响提交到 GitLab 的改变内容的过程,每个提交者现在必须确保在他们的查询中包含分片键。

最后,是完成这些工作所需要的基础设施。服务器已经完成设置,监视也添加了、工程师们必须培训,以便于他们熟悉上面列出的这些新的设置。虽然托管解决方案可能不需要你自己管理服务器,但它不能解决所有问题。工程师们仍然需要去培训(很可能非常昂贵)并需要为此支付账单。在 GitLab 上,我们也非常乐意提供我们用过的这些工具,这样社区就可以使用它们。这意味着如果我们去分片数据库, 我们将在我们的 Omnibus 包中提供它(或至少是其中的一部分)。确保你提供的服务的唯一方法就是你自己去管理它,这意味着我们不能使用主机托管的解决方案。

最终,我们决定不使用数据库分片,因为它是昂贵的、费时的、复杂的解决方案。

GitLab 的连接池

对于连接池我们有两个主要的诉求:

  1. 它必须工作的很好(很显然这是必需的)。
  2. 它必须易于在我们的 Omnibus 包中运用,以便于我们的用户也可以从连接池中得到好处。

用下面两步去评估这两个解决方案(pgpool 和 pgbouncer):

  1. 执行各种技术测试(是否有效,配置是否容易,等等)。
  2. 找出使用这个解决方案的其它用户的经验,他们遇到了什么问题?怎么去解决的?等等。

pgpool 是我们考察的第一个解决方案,主要是因为它提供的很多特性看起来很有吸引力。我们其中的一些测试数据可以在 这里 找到。

最终,基于多个因素,我们决定不使用 pgpool 。例如, pgpool 不支持 粘连接 sticky connection 。 当执行一个写入并(尝试)立即显示结果时,它会出现问题。想像一下,创建一个 工单 issue 并立即重定向到这个页面, 没有想到会出现 HTTP 404,这是因为任何用于只读查询的服务器还没有收到数据。针对这种情况的一种解决办法是使用同步复制,但这会给表带来更多的其它问题,而我们希望避免这些问题。

另一个问题是, pgpool 的负载均衡逻辑与你的应用程序是不相干的,是通过解析 SQL 查询并将它们发送到正确的服务器。因为这发生在你的应用程序之外,你几乎无法控制查询运行在哪里。这实际上对某些人也可能是有好处的, 因为你不需要额外的应用程序逻辑。但是,它也妨碍了你在需要的情况下调整路由逻辑。

由于配置选项非常多,配置 pgpool 也是很困难的。或许促使我们最终决定不使用它的原因是我们从过去使用过它的那些人中得到的反馈。即使是在大多数的案例都不是很详细的情况下,我们收到的反馈对 pgpool 通常都持有负面的观点。虽然出现的报怨大多数都与早期版本的 pgpool 有关,但仍然让我们怀疑使用它是否是个正确的选择。

结合上面描述的问题和反馈,最终我们决定不使用 pgpool 而是使用 pgbouncer 。我们用 pgbouncer 执行了一套类似的测试,并且对它的结果是非常满意的。它非常容易配置(而且一开始不需要很多的配置),运用相对容易,仅专注于连接池(而且它真的很好),而且没有明显的负载开销(如果有的话)。也许我唯一的报怨是,pgbouncer 的网站有点难以导航。

使用 pgbouncer 后,通过使用 事务池 transaction pooling 我们可以将活动的 PostgreSQL 连接数从几百个降到仅 10 - 20 个。我们选择事务池是因为 Rails 数据库连接是持久的。这个设置中,使用 会话池 session pooling 不能让我们降低 PostgreSQL 连接数,从而受益(如果有的话)。通过使用事务池,我们可以调低 PostgreSQL 的 max_connections 的设置值,从 3000 (这个特定值的原因我们也不清楚) 到 300 。这样配置的 pgbouncer ,即使在尖峰时,我们也仅需要 200 个连接,这为我们提供了一些额外连接的空间,如 psql 控制台和维护任务。

对于使用事务池的负面影响方面,你不能使用预处理语句,因为 PREPAREEXECUTE 命令也许最终在不同的连接中运行,从而产生错误的结果。 幸运的是,当我们禁用了预处理语句时,并没有测量到任何响应时间的增加,但是我们 确定 测量到在我们的数据库服务器上内存使用减少了大约 20 GB。

为确保我们的 web 请求和后台作业都有可用连接,我们设置了两个独立的池: 一个有 150 个连接的后台进程连接池,和一个有 50 个连接的 web 请求连接池。对于 web 连接需要的请求,我们很少超过 20 个,但是,对于后台进程,由于在 GitLab.com 上后台运行着大量的进程,我们的尖峰值可以很容易达到 100 个连接。

今天,我们提供 pgbouncer 作为 GitLab EE 高可用包的一部分。对于更多的信息,你可以参考 “Omnibus GitLab PostgreSQL High Availability”。

GitLab 上的数据库负载均衡

使用 pgpool 和它的负载均衡特性,我们需要一些其它的东西去分发负载到多个热备服务器上。

对于(但不限于) Rails 应用程序,它有一个叫 Makara 的库,它实现了负载均衡的逻辑并包含了一个 ActiveRecord 的缺省实现。然而,Makara 也有一些我们认为是有些遗憾的问题。例如,它支持的粘连接是非常有限的:当你使用一个 cookie 和一个固定的 TTL 去执行一个写操作时,连接将粘到主服务器。这意味着,如果复制极大地滞后于 TTL,最终你可能会发现,你的查询运行在一个没有你需要的数据的主机上。

Makara 也需要你做很多配置,如所有的数据库主机和它们的角色,没有服务发现机制(我们当前的解决方案也不支持它们,即使它是将来计划的)。 Makara 也 似乎不是线程安全的,这是有问题的,因为 Sidekiq (我们使用的后台进程)是多线程的。 最终,我们希望尽可能地去控制负载均衡的逻辑。

除了 Makara 之外 ,还有一个 Octopus ,它也是内置的负载均衡机制。但是 Octopus 是面向分片数据库的,而不仅是均衡只读查询的。因此,最终我们不考虑使用 Octopus。

最终,我们直接在 GitLab EE构建了自己的解决方案。 添加初始实现的 合并请求 merge request 可以在 这里找到,尽管一些更改、提升和修复是以后增加的。

我们的解决方案本质上是通过用一个处理查询的路由的代理对象替换 ActiveRecord::Base.connection 。这可以让我们均衡负载尽可能多的查询,甚至,包括不是直接来自我们的代码中的查询。这个代理对象基于调用方式去决定将查询转发到哪个主机, 消除了解析 SQL 查询的需要。

粘连接

粘连接是通过在执行写入时,将当前 PostgreSQL WAL 位置存储到一个指针中实现支持的。在请求即将结束时,指针短期保存在 Redis 中。每个用户提供他自己的 key,因此,一个用户的动作不会导致其他的用户受到影响。下次请求时,我们取得指针,并且与所有的次级服务器进行比较。如果所有的次级服务器都有一个超过我们的指针的 WAL 指针,那么我们知道它们是同步的,我们可以为我们的只读查询安全地使用次级服务器。如果一个或多个次级服务器没有同步,我们将继续使用主服务器直到它们同步。如果 30 秒内没有写入操作,并且所有的次级服务器还没有同步,我们将恢复使用次级服务器,这是为了防止有些人的查询永远运行在主服务器上。

检查一个次级服务器是否就绪十分简单,它在如下的 Gitlab::Database::LoadBalancing::Host#caught_up? 中实现:

def caught_up?(location)
  string = connection.quote(location)

  query = "SELECT NOT pg_is_in_recovery() OR " \
    "pg_xlog_location_diff(pg_last_xlog_replay_location(), #{string}) >= 0 AS result"

  row = connection.select_all(query).first

  row && row['result'] == 't'
ensure
  release_connection
end

这里的大部分代码是运行原生查询(raw queries)和获取结果的标准的 Rails 代码,查询的最有趣的部分如下:

SELECT NOT pg_is_in_recovery()
OR pg_xlog_location_diff(pg_last_xlog_replay_location(), WAL-POINTER) >= 0 AS result"

这里 WAL-POINTER 是 WAL 指针,通过 PostgreSQL 函数 pg_current_xlog_insert_location() 返回的,它是在主服务器上执行的。在上面的代码片断中,该指针作为一个参数传递,然后它被引用或转义,并传递给查询。

使用函数 pg_last_xlog_replay_location() 我们可以取得次级服务器的 WAL 指针,然后,我们可以通过函数 pg_xlog_location_diff() 与我们的主服务器上的指针进行比较。如果结果大于 0 ,我们就可以知道次级服务器是同步的。

当一个次级服务器被提升为主服务器,并且我们的 GitLab 进程还不知道这一点的时候,添加检查 NOT pg_is_in_recovery() 以确保查询不会失败。在这个案例中,主服务器总是与它自己是同步的,所以它简单返回一个 true

后台进程

我们的后台进程代码 总是 使用主服务器,因为在后台执行的大部分工作都是写入。此外,我们不能可靠地使用一个热备机,因为我们无法知道作业是否在主服务器执行,也因为许多作业并没有直接绑定到用户上。

连接错误

要处理连接错误,比如负载均衡器不会使用一个视作离线的次级服务器,会增加主机上(包括主服务器)的连接错误,将会导致负载均衡器多次重试。这是确保,在遇到偶发的小问题或数据库失败事件时,不会立即显示一个错误页面。当我们在负载均衡器级别上处理 热备机冲突 的问题时,我们最终在次级服务器上启用了 hot_standby_feedback ,这样就解决了热备机冲突的所有问题,而不会对表膨胀造成任何负面影响。

我们使用的过程很简单:对于次级服务器,我们在它们之间用无延迟试了几次。对于主服务器,我们通过使用越来越快的回退尝试几次。

更多信息你可以查看 GitLab EE 上的源代码:

数据库负载均衡首次引入是在 GitLab 9.0 中,并且 支持 PostgreSQL。更多信息可以在 9.0 release postdocumentation 中找到。

Crunchy Data

我们与 Crunchy Data 一起协同工作来部署连接池和负载均衡。不久之前我还是唯一的 数据库专家,它意味着我有很多工作要做。此外,我对 PostgreSQL 的内部细节的和它大量的设置所知有限 (或者至少现在是),这意味着我能做的也有限。因为这些原因,我们雇用了 Crunchy 去帮我们找出问题、研究慢查询、建议模式优化、优化 PostgreSQL 设置等等。

在合作期间,大部分工作都是在相互信任的基础上完成的,因此,我们共享私人数据,比如日志。在合作结束时,我们从一些资料和公开的内容中删除了敏感数据,主要的资料在 gitlab-com/infrastructure#1448,这又反过来导致产生和解决了许多分立的问题。

这次合作的好处是巨大的,它帮助我们发现并解决了许多的问题,如果必须我们自己来做的话,我们可能需要花上几个月的时间来识别和解决它。

幸运的是,最近我们成功地雇佣了我们的 第二个数据库专家 并且我们希望以后我们的团队能够发展壮大。

整合连接池和数据库负载均衡

整合连接池和数据库负载均衡可以让我们去大幅减少运行数据库集群所需要的资源和在分发到热备机上的负载。例如,以前我们的主服务器 CPU 使用率一直徘徊在 70%,现在它一般在 10% 到 20% 之间,而我们的两台热备机服务器则大部分时间在 20% 左右:

CPU Percentage

在这里, db3.cluster.gitlab.com 是我们的主服务器,而其它的两台是我们的次级服务器。

其它的负载相关的因素,如平均负载、磁盘使用、内存使用也大为改善。例如,主服务器现在的平均负载几乎不会超过 10,而不像以前它一直徘徊在 20 左右:

CPU Percentage

在业务繁忙期间,我们的次级服务器每秒事务数在 12000 左右(大约为每分钟 740000),而主服务器每秒事务数在 6000 左右(大约每分钟 340000):

Transactions Per Second

可惜的是,在部署 pgbouncer 和我们的数据库负载均衡器之前,我们没有关于事务速率的任何数据。

我们的 PostgreSQL 的最新统计数据的摘要可以在我们的 public Grafana dashboard 上找到。

我们的其中一些 pgbouncer 的设置如下:

设置
default_pool_size100
reserve_pool_size5
reserve_pool_timeout3
max_client_conn2048
pool_modetransaction
server_idle_timeout30

除了前面所说的这些外,还有一些工作要作,比如: 部署服务发现(#2042), 持续改善如何检查次级服务器是否可用(#2866),和忽略落后于主服务器太多的次级服务器 (#2197)。

值得一提的是,到目前为止,我们还没有任何计划将我们的负载均衡解决方案,独立打包成一个你可以在 GitLab 之外使用的库,相反,我们的重点是为 GitLab EE 提供一个可靠的负载均衡解决方案。

如果你对它感兴趣,并喜欢使用数据库、改善应用程序性能、给 GitLab上增加数据库相关的特性(比如: 服务发现),你一定要去查看一下我们的 招聘职位数据库专家手册 去获取更多信息。


via: https://about.gitlab.com/2017/10/02/scaling-the-gitlab-database/

作者:Yorick Peterse 译者:qhwdw 校对:wxy

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

GitLab 是一个基于 git 的仓库管理程序,也是一个方便软件开发的强大完整应用。

GitLab 拥有一个“用户新人友好”的界面,通过图形界面和命令行界面,使你的工作更加具有效率。GitLab 不仅仅对开发者是一个有用的工具,它甚至可以被集成到你的整个团队中,使得每一个人获得一个独自唯一的平台。

GitLab 工作流逻辑符合使用者思维,使得整个平台变得更加易用。相信我,使用一次,你就离不开它了!

GitLab 工作流

GitLab 工作流 是在软件开发过程中,在使用 GitLab 作为代码托管平台时,可以采取的动作的一个逻辑序列。

GitLab 工作流遵循了 GitLab Flow 策略,这是由一系列由基于 Git 的方法和策略组成的,这些方法为版本的管理,例如分支策略Git最佳实践等等提供了保障。

通过 GitLab 工作流,可以很方便的提升团队的工作效率以及凝聚力。这种提升,从引入一个新的项目开始,一直到发布这个项目,成为一个产品都有所体现。这就是我们所说的“如何通过最快的速度把一个点子在 10 步之内变成一个产品”。

FROM IDEA TO PRODUCTION IN 10 STEPS

软件开发阶段

一般情况下,软件开发经过 10 个主要阶段;GitLab 为这 10 个阶段依次提供了解决方案:

  1. IDEA: 每一个从点子开始的项目,通常来源于一次闲聊。在这个阶段,GitLab 集成了 Mattermost
  2. ISSUE: 最有效的讨论一个点子的方法,就是为这个点子建立一个工单讨论。你的团队和你的合作伙伴可以在 工单追踪器 issue tracker 中帮助你去提升这个点子
  3. PLAN: 一旦讨论得到一致的同意,就是开始编码的时候了。但是等等!首先,我们需要优先考虑组织我们的工作流。对于此,我们可以使用 工单看板 Issue Board
  4. CODE: 现在,当一切准备就绪,我们可以开始写代码了。
  5. COMMIT: 当我们为我们的初步成果欢呼的时候,我们就可以在版本控制下,提交代码到功能分支了。
  6. TEST: 通过 GitLab CI,我们可以运行脚本来构建和测试我们的应用。
  7. REVIEW: 一旦脚本成功运行,我们测试和构建成功,我们就可以进行 代码复审 code review 以及批准。
  8. STAGING:: 现在是时候将我们的代码部署到演示环境来检查一下,看看是否一切就像我们预估的那样顺畅——或者我们可能仍然需要修改。
  9. PRODUCTION: 当一切都如预期,就是部署到生产环境的时候了!
  10. FEEDBACK: 现在是时候返回去看我们项目中需要提升的部分了。我们使用 周期分析 Cycle Analytics 来对当前项目中关键的部分进行的反馈。

简单浏览这些步骤,我们可以发现,提供强大的工具来支持这些步骤是十分重要的。在接下来的部分,我们为 GitLab 的可用工具提供一个简单的概览。

GitLab 工单追踪器

GitLab 有一个强大的工单追溯系统,在使用过程中,允许你和你的团队,以及你的合作者分享和讨论建议。

issue tracker - view list

工单是 GitLab 工作流的第一个重要重要特性。以工单的讨论为开始; 跟踪新点子的改变是一个最好的方式。

这十分有利于:

  • 讨论点子
  • 提交功能建议
  • 提问题
  • 提交错误和故障
  • 获取支持
  • 精细化新代码的引入

每一个在 GitLab 上部署的项目都有一个工单追踪器。找到你的项目中的 Issues > New issue 来创建一个新的工单。建立一个标题来总结要被讨论的主题,并且使用 Markdown 来形容它。看看下面的“专业技巧”来加强你的工单描述。

GitLab 工单追踪器提供了一个额外的实用功能,使得步骤变得更佳易于管理和考虑。下面的部分仔细描述了它。

new issue - additional settings

秘密工单

无论何时,如果你仅仅想要在团队中讨论这个工单,你可以使该工单成为秘密的。即使你的项目是公开的,你的工单也会被保密起来。当一个不是本项目成员的人,就算是 报告人级别,想要访问工单的地址时,浏览器也会返回一个 404 错误。

截止日期

每一个工单允许你填写一个截止日期。有些团队工作时间表安排紧凑,以某种方式去设置一个截止日期来解决问题,是有必要的。这些都可以通过截止日期这一功能实现。

当你对一个多任务项目有截止日期的时候——比如说,一个新的发布活动、项目的启动,或者按阶段追踪任务——你可以使用里程碑

受托者

要让某人处理某个工单,可以将其分配给他。你可以任意修改被分配者,直到满足你的需求。这个功能的想法是,一个受托者本身对这个工单负责,直到其将这个工单重新赋予其他人。

这也可以用于按受托者筛选工单。

标签

GitLab 标签也是 GitLab 流的一个重要组成部分。你可以使用它们来分类你的工单,在工作流中定位,以及通过优先级标签来安装优先级组织它们。

标签使得你与GitLab 工单看板协同工作,加快工程进度以及组织你的工作流。

新功能: 你可以创建组标签。它可以使得在每一个项目组中使用相同的标签。

工单权重

你可以添加个工单权重使得一个工单重要性表现的更为清晰。01 - 03 表示工单不是特别重要,07 - 09 表示十分重要,04 - 06 表示程度适中。此外,你可以与你的团队自行定义工单重要性的指标。

注:该功能仅可用于 GitLab 企业版和 GitLab.com 上。

GitLab 工单看板

在项目中,GitLab 工单看板是一个用于计划以及组织你的工单,使之符合你的项目工作流的工具。

看板包含了与其相关的相应标签,每一个列表包含了相关的被标记的工单,并且以卡片的形式展示出来。

这些卡片可以在列表之间移动,被移动的卡片,其标签将会依据你移动的位置相应更新到列表上。

GitLab Issue Board

新功能: 你也可以通过点击列表上方的“+”按钮在看板右边创建工单。当你这么做的时候,这个工单将会自动添加与列表相关的标签。

新功能: 我们最近推出了 每一个 GitLab 项目拥有多个工单看板的功能(仅存在于 GitLab 企业版);这是为不同的工作流组织你的工单的好方法。

Multiple Issue Boards

通过 GitLab 进行代码复审

在工单追踪器中,讨论了新的提议之后,就是在代码上做工作的时候了。你在本地书写代码,一旦你完成了你的第一个版本,提交你的代码并且推送到你的 GitLab 仓库。你基于 Git 的管理策略可以在 GitLab 流中被提升。

第一次提交

在你的第一次提交信息中,你可以添加涉及到工单号在其中。通过这样做你可以将两个阶段的开发工作流链接起来:工单本身以及关于这个工单的第一次提交。

这样做,如果你提交的代码和工单属于同一个项目,你可以简单的添加 #xxx 到提交信息中(LCTT 译注:git commit message),xxx是一个工单号。如果它们不在一个项目中,你可以添加整个工单的整个URL(https://gitlab.com/<username>/<projectname>/issues/<xxx>)。

git commit -m "this is my commit message. Ref #xxx" 

或者

git commit -m "this is my commit message. Related to https://gitlab.com/<username>/<projectname>/issues/<xxx>"

当然,你也可以替换 gitlab.com,以你自己的 GitLab 实例来替换这个 URL。

注: 链接工单和你的第一次提交是为了通过 GitLab 周期分析追踪你的进展。这将会衡量计划执行该工单所采取的时间,即创建工单与第一次提交的间隔时间。

合并请求

一旦将你的改动提交到功能分支,GitLab 将识别该修改,并且建议你提交一次 合并请求 Merge Request (MR)。

每一次 MR 都会有一个标题(这个标题总结了这次的改动)并且一个用 Markdown 书写的描述。在描述中,你可以简单的描述该 MR 做了什么,提及任何工单以及 MR(在它们之间创建联系),并且,你也可以添加个关闭工单模式,当该 MR 被合并的时候,相关联的工单就会被关闭。

例如:

## 增加一个新页面

这个 MR 将会为这个项目创建一个包含该 app 概览的 `readme.md`。

Closes #xxx and https://gitlab.com/<username>/<projectname>/issues/<xxx>

预览:

![预览新页面](#image-url)

cc/ @Mary @Jane @John

当你创建一个如上的带有描述的 MR,它将会:

  • 当合并时,关闭包括工单 #xxx 以及 https://gitlab.com/<username>/<projectname>/issues/<xxx>
  • 展示一张图片
  • 通过邮件提醒用户 @Mary@Jane,以及给 @John

你可以分配这个 MR 给你自己,直到你完成你的工作,然后把它分配给其他人来做一次代码复审。如果有必要的话,这个 MR 可以被重新分配多次,直到你覆盖你所需要的所有复审。

它也可以被标记,并且添加一个里程碑来促进管理。

当你从图形界面而不是命令行添加或者修改一个文件并且提交一个新的分支时,也很容易创建一个新的 MR,仅仅需要标记一下复选框,“以这些改变开始一个新的合并请求”,然后,一旦你提交你的改动,GitLab 将会自动创建一个新的 MR。

commit to a feature branch and add a new MR from the UI

注: 添加关闭工单样式到你的 MR 以便可以使用 GitLab 周期分析追踪你的项目进展,是十分重要的。它将会追踪“CODE”阶段,衡量第一次提交及创建一个相关的合并请求所间隔的时间。

新功能: 我们已经开发了审查应用,这是一个可以让你部署你的应用到一个动态的环境中的新功能,在此你可以按分支名字、每个合并请求来预览改变。参看这里的可用示例

WIP MR

WIP MR 含义是 在工作过程中的合并请求,是一个我们在 GitLab 中避免 MR 在准备就绪前被合并的技术。只需要添加 WIP: 在 MR 的标题开头,它将不会被合并,除非你把 WIP: 删除。

当你改动已经准备好被合并,编辑工单来手动删除 WIP: ,或者使用就像如下 MR 描述下方的快捷方式。

WIP MR click to remove WIP from the title

新功能: WIP 模式可以通过斜线命令 /wip 快速添加到合并请求中。只需要在评论或者 MR 描述中输入它并提交即可。

复审

一旦你创建一个合并请求,就是你开始从你的团队以及合作方收取反馈的时候了。使用图形界面中的差异比较功能,你可以简单的添加行内注释,以及回复或者解决它们。

你也可以通过点击行号获取每一行代码的链接。

在图形界面中可以看到提交历史,通过提交历史,你可以追踪文件的每一次改变。你可以以行内差异或左右对比的方式浏览它们。

code review in MRs at GitLab

新功能: 如果你遇到合并冲突,可以快速地通过图形界面来解决,或者依据你的需要修改文件来修复冲突。

mr conflict resolution

构建、测试以及发布

GitLab CI 是一个强大的内建工具,其作用是持续集成、持续发布以及持续分发,它可以按照你希望的运行一些脚本。它的可能性是无止尽的:你可以把它看做是自己运行的命令行。

它完全是通过一个名为 .gitlab-ci.yml 的 YAML 文件设置的,其放置在你的项目仓库中。使用 Web 界面简单的添加一个文件,命名为 .gitlab-ci.yml 来触发一个下拉菜单,为不同的应用选择各种 CI 模版。

GitLab CI templates - dropdown menu

Koding

Use GitLab's Koding integration to run your entire development environment in the cloud. This means that you can check out a project or just a merge request in a full-fledged IDE with the press of a button.

可以使用 GitLab 的 Koding 集成功能在云端运行你的整个云端开发环境。这意味着你可以轻轻一键即可在一个完整的 IDE 中检出以个项目,或者合并一个请求。

使用案例

GitLab CI 的使用案例:

我们已经准备一大堆 GitLab CI 样例工程作为您的指南。看看它们吧!

反馈:周期分析

当你遵循 GitLab 工作流进行工作,你的团队从点子到产品,在每一个过程的关键部分,你将会在下列时间获得一个 GitLab 周期分析的反馈:

  • Issue: 从创建一个工单,到分配这个工单给一个里程碑或者添加工单到你的工单看板的时间。
  • Plan: 从给工单分配一个里程碑或者把它添加到工单看板,到推送第一次提交的时间。
  • Code: 从第一次提交到提出该合并请求的时间。
  • Test: CI 为了相关合并请求而运行整个过程的时间。
  • Review: 从创建一个合并请求到合并它的时间。
  • Staging: 从合并到发布成为产品的时间。
  • Production(Total): 从创建工单到把代码发布成产品的时间。

加强

工单以及合并请求模版

工单以及合并请求模版允许你为你的项目去定义一个特定内容的工单模版和合并请求的描述字段。

你可以以 Markdown 形式书写它们,并且把它们加入仓库的默认分支。当创建工单或者合并请求时,可以通过下拉菜单访问它们。

它们节省了您在描述工单和合并请求的时间,并标准化了需要持续跟踪的重要信息。它确保了你需要的一切都在你的掌控之中。

你可以创建许多模版,用于不同的用途。例如,你可以有一个提供功能建议的工单模版,或者一个 bug 汇报的工单模版。在 GitLab CE project 中寻找真实的例子吧!

issues and MR templates - dropdown menu screenshot

里程碑

里程碑 是 GitLab 中基于共同的目标、详细的日期追踪你队伍工作的最好工具。

不同情况下的目的是不同的,但是大致是相同的:你有为了达到特定的目标的工单的集合以及正在编码的合并请求。

这个目标基本上可以是任何东西——用来结合团队的工作,在一个截止日期前完成一些事情。例如,发布一个新的版本,启动一个新的产品,在某个日期前完成,或者按季度收尾一些项目。

milestone dashboard

专业技巧

工单和 MR

  • 在工单和 MR 的描述中:

    • 输入 # 来触发一个已有工单的下拉列表
    • 输入 ! 来触发一个已有 MR 的下拉列表
    • 输入 / 来触发斜线命令
    • 输入 : 来出发 emoji 表情 (也支持行中评论)
  • 通过按钮“附加文件”来添加图片(jpg、png、gif) 和视频到行内评论
  • 通过 GitLab Webhooks 自动应用标签
  • 构成引用: 使用语法 >>> 来开始或者结束一个引用
>>>
Quoted text

Another paragraph
>>>
- [ ] Task 1
- [ ] Task 2
- [ ] Task 3
订阅

你是否发现你有一个工单或者 MR 想要追踪?展开你的右边的导航,点击订阅,你就可以在随时收到一个评论的提醒。要是你想要一次订阅多个工单和 MR?使用批量订阅

添加代办

除了一直留意工单和 MR,如果你想要对它预先做点什么,或者不管什么时候你想要在 GitLab 代办列表中添加点什么,点击你右边的导航,并且点击添加代办

寻找你的工单和 MR

当你寻找一个在很久以前由你开启的工单或 MR——它们可能数以十计、百计、甚至千计——所以你很难找到它们。打开你左边的导航,并且点击工单或者合并请求,你就会看到那些分配给你的。同时,在那里或者任何工单追踪器里,你可以通过作者、分配者、里程碑、标签以及重要性来过滤工单,也可以通过搜索所有不同状态的工单,例如开启的、合并的,关闭的等等。

移动工单

一个工单在一个错误的项目中结束了?不用担心,点击Edit,然后移动工单到正确的项目。

代码片段

你经常在不同的项目以及文件中使用一些相同的代码段和模版吗?创建一个代码段并且使它在你需要的时候可用。打开左边导航栏,点击Snipptes。所有你的片段都会在那里。你可以把它们设置成公开的,内部的(仅为 GitLab 注册用户提供),或者私有的。

Snippets - screenshot

GitLab 工作流用户案例概要

作为总结,让我们把所有东西聚在一起理顺一下。不必担心,这十分简单。

让我们假设:你工作于一个专注于软件开发的公司。你创建了一个新的工单,这个工单是为了开发一个新功能,实施于你的一个应用中。

标签策略

为了这个应用,你已经创建了几个标签,“讨论”、“后端”、“前端”、“正在进行”、“展示”、“就绪”、“文档”、“营销”以及“产品”。所有都已经在工单看板有它们自己的列表。你的当前的工单已经有了标签“讨论”。

在工单追踪器中的讨论达成一致之后,你的后端团队开始在工单上工作,所以他们把这个工单的标签从“讨论”移动到“后端”。第一个开发者开始写代码,并且把这个工单分配给自己,增加标签“正在进行”。

编码 & 提交

在他的第一次提交的信息中,他提及了他的工单编号。在工作后,他把他的提交推送到一个功能分支,并且创建一个新的合并请求,在 MR 描述中,包含工单关闭模式。他的团队复审了他的代码并且保证所有的测试和建立都已经通过。

使用工单看板

一旦后端团队完成了他们的工作,他们就删除“正在进行”标签,并且把工单从“后端”移动到“前端”看板。所以,前端团队接到通知,这个工单已经为他们准备好了。

发布到演示

当一个前端开发者开始在该工单上工作,他(她)增加一个标签“正在进行”,并且把这个工单重新分配给自己。当工作完成,该实现将会被发布到一个演示环境。标签“正在进行”就会被删除,然后在工单看板里,工单卡被移动到“演示”列表中。

团队合作

最后,当新功能成功实现,你的团队把它移动到“就绪”列表。

然后,就是你的技术文档编写团队的时间了,他们为新功能书写文档。一旦某个人完成书写,他添加标签“文档”。同时,你的市场团队开始启动并推荐该功能,所以某个人添加“市场”。当技术文档书写完毕,书写者删除标签“文档”。一旦市场团队完成他们的工作,他们将工单从“市场”移动到“生产”。

部署到生产环境

最后,你将会成为那个为新版本负责的人,合并“合并请求”并且将新功能部署到生产环境,然后工单的状态转变为关闭

反馈

通过周期分析,你和你的团队节省了如何从点子到产品的时间,并且开启另一个工单,来讨论如何将这个过程进一步提升。

总结

GitLab 工作流通过一个单一平台帮助你的团队加速从点子到生产的改变:

  • 它是有效的:因为你可以获取你想要的结果
  • 它是高效的:因为你可以用最小的努力和成本达到最大的生产力
  • 它是高产的:因为你可以非常有效的计划和行动
  • 它是简单的:因为你不需要安装不同的工具去完成你的目的,仅仅需要 GitLab
  • 它是快速的:因为你不需要在多个平台间跳转来完成你的工作

每一个月的 22 号都会有一个新的 GitLab 版本释出,让它在集成软件开发解决方案上变得越来越好,让团队可以在一个单一的、唯一的界面下一起工作。

在 GitLab,每个人都可以奉献!多亏了我们强大的社区,我们获得了我们想要的。并且多亏了他们,我们才能一直为你提供更好的产品。

还有什么问题和反馈吗?请留言,或者在推特上@我们@GitLab!


via: https://about.gitlab.com/2016/10/25/gitlab-workflow-an-overview/

作者:Marcia Ramos 译者:svtter 校对:wxy

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