持續整合持續部署持續交付_持續整合與持續部署之間的真正區別

cumian8165發表於2020-08-13

持續整合持續部署持續交付

There is plenty of content out there describing what Continuous Integration, Continuous Delivery, and Continuous Deployment are. But what purposes do these processes serve in the first place?

有很多內容描述什麼是持續整合,持續交付和持續部署。 但是這些過程首先要達到什麼目的?

It is crucial to understand the problems CI and CD solve to use them properly. This will allow your team to improve your process and avoid putting effort into chasing fancy metrics that do not bring any value to your process.

瞭解CI和CD解決的問題以正確使用它們至關重要。 這將使您的團隊可以改善您的流程,並避免花力氣追求那些不會給您的流程帶來任何價值的幻想指標。

持續整合是一個團隊問題 (Continuous Integration is a team problem)

If you work in a team, chances are there are several developers working on the same repository. There is a main branch in the repository carrying the latest version of the code. Developers work on different things on different branches. Once someone is done with their change, they'll push or merge it to the main branch. Eventually the whole team will pull this change.

如果您在團隊中工作,則可能有多個開發人員在同一個儲存庫中工作。 儲存庫中有一個主分支,其中載有最新版本的程式碼。 開發人員在不同分支上從事不同的工作。 變更完成後,他們會將其推送或合併到主分支。 最終,整個團隊將拉動這一變化。

The scenario we want to avoid is that a faulty commit makes it to the main branch. Faulty means the code does not compile or the app won't start or is unusable. Why? Not because the app is broken or because all tests must always be green. That is not a problem–you can decide not to deploy that version and wait for a fix.

我們要避免的情況是錯誤的提交使其進入主分支。 錯誤意味著程式碼無法編譯,或者應用程式無法啟動或無法使用。 為什麼? 不是因為應用程式損壞了,還是因為所有測試必須始終為綠色。 這不是問題,您可以決定不部署該版本,然後等待修復。

The problem is that your entire team is stuck. All the developers who pulled the faulty commit will spend 5 minutes wondering why it doesn't work. Several will probably try to find the faulty commit. Some will try to fix the issue by themselves in parallel of the faulty code author.

問題是您的整個團隊都陷入了困境。 所有提出錯誤提交的開發人員都將花費5分鐘來思考為什麼它不起作用。 有些人可能會嘗試查詢錯誤的提交。 有些人會嘗試與錯誤的程式碼作者並行解決問題。

This is a waste of time for your team. The worst part is that repeated incidents fuel a mistrust of the main branch and encourage developers to work apart.

這對您的團隊來說是浪費時間。 最糟糕的是,重複發生的事件加劇了人們對主要分支機構的不信任,並鼓勵開發人員分開工作。

Continuous Integration is all about preventing the main branch from breaking so your team is not stuck. That's it. It is not about having all your tests green all the time and the main branch deployable to production at every commit.

持續整合就是為了防止主分支中斷,從而使您的團隊不會陷入困境。 而已。 這並不是要讓所有測試一直保持綠色並且主分支在每次提交時都可以部署到生產中。

The process of Continuous Integration is independent of any tool. You could manually verify that the merge of your branch and the main branch works locally, and then only actually push the merge to the repository. But that would be very inefficient. That's why Continuous Integration is implemented using automated checks.

持續整合的過程獨立於任何工具。 您可以手動驗證分支和主分支的合併在本地是否有效,然後僅將合併實際推送到儲存庫。 但這將是非常低效的。 這就是使用自動檢查實現持續整合的原因。

The checks ensure that, at the bare minimum:

檢查確保至少:

  • The app should build and start

    該應用程式應構建並啟動
  • Most critical features should be functional at all times (user signup/login journey and  key business features)

    最關鍵的功能應始終處於工作狀態(使用者註冊/登入過程以及關鍵的業務功能)
  • Common layers of the application that all the developers rely on should be stable. This means unit tests on those parts.

    所有開發人員都依賴的應用程式通用層應該是穩定的。 這意味著對這些零件進行單元測試。

In practice, this means you need to pull any unit test framework that works for you and secure the common layers of the application. Sometimes it is not that much code and can be done fairly quickly. Also you need to add a "smoke test" verifying that the code compiles and that the application starts. This is especially important in technologies with crazy dependency injections like Java Spring or .NET core. In large projects it is so easy to miswire your dependencies that verifying that the app always starts is a must.

實際上,這意味著您需要提取適用於您的任何單元測試框架並保護應用程式的公共層。 有時,程式碼不是很多,可以很快完成。 另外,您還需要新增“煙霧測試”以驗證程式碼是否已編譯以及應用程式是否啟動。 這對於帶有瘋狂依賴注入的技術(例如Java Spring或.NET core)尤其重要。 在大型專案中,很容易誤連線依賴項,因此必須驗證該應用程式始終啟動。

If you have hundreds or thousands of tests you don't need to run them all for each merge. It will take a lot of time and most tests probably verify "non team blocker" features.
如果您有成百上千的測試,則不需要為每個合併執行所有測試。 這將花費大量時間,並且大多數測試可能會驗證“非團隊阻止者”功能。

We'll see in the next sections how the process of Continuous Delivery will make good use of these many tests.

我們將在接下來的部分中看到連續交付的過程將如何充分利用這許多測試。

與工具無關 (It's not about tools)

Tools and automated checks are all fine. But if your developers only merge giant branches they work on for weeks, they won't help you. The team will spend a good amount of time merging the branches and fixing the code incompatibilities that will arise eventually. It is as much a waste of time as being blocked by a faulty commit.

工具和自動檢查都可以。 但是,如果您的開發人員僅合併他們工作了幾個星期的巨型分支機構,那麼他們將無濟於事。 團隊將花費大量時間合併分支並修復最終將出現的程式碼不相容問題。 與錯誤的提交阻塞在一起一樣浪費時間。

Continuous Integration is not about tools. It is about working in small chunks and integrating your new code to the main branch and pulling frequently.
持續整合與工具無關。 這是關於小塊工作並將新程式碼整合到主分支並頻繁提取的問題。

Frequently means at least daily. Split the task you are working on into smaller tasks. Merge your code very often and pull very often. This way nobody works apart for more than a day or two and problems do not have time to become snowballs.

通常至少每天一次。 將您正在處理的任務拆分為較小的任務。 經常合併您的程式碼,並經常提取。 這樣一來,沒有人能分開工作超過一兩天,問題就沒有時間滾雪球了。

A large task does not need to be all in one branch. It should never be. Techniques to merge work in progress to the main branch are called "branching by abstraction" and "feature toggles". See the blog post How to get started with Continuous Integration  for more details.

一項大型任務不需要全部都在一個分支中。 應該永遠不會。 將進行中的工作合併到主分支的技術稱為“抽象分支”和“功能切換”。 有關更多詳細資訊,請參見部落格文章“ 如何開始進行持續整合 ”。

優質CI的關鍵點 (Key points for a good CI build)

It's very simple. Keep it short. 3-7 minutes should be the max. It's not about CPU and resources. It is about developers' productivity. The first rule of productivity is focus. Do one thing, finish it, then move to the next thing.

非常簡單 保持簡短。 最多3-7分鐘。 這與CPU和資源無關。 這與開發人員的生產力有關。 生產力的首要規則是專注。 做一件事,完成它,然後移到下一件事。

Context switching is costly. Studies show it takes ~23 minutes to deeply refocus on something when you get disturbed.

上下文切換成本很高。 研究表明,當您被打擾時,大約需要23分鐘才能重新專注於某件事。

Imagine you push your branch to merge it. You start another task. You spend 15-20 minutes getting into it. The minute after you are in the zone you receive a "build failed" notification from your 20 minutes long CI build for the previous task. You get back to fix it. You push it again. You easily lost more than 20 minutes moving back and forth.

想象一下,您推動分支進行合併。 您開始另一個任務。 您花了15到20分鐘才能進入。 在您進入區域後的一分鐘,您會從20分鐘長的CI構建中收到針對先前任務的“構建失敗”通知。 您回來修復它。 您再次推動它。 您來回走動很容易超過20分鐘。

Multiply 20 minutes once or twice a day by the number of developers in your team... That's a lot of precious time wasted.
每天一次或兩次將20分鐘乘以團隊中開發人員的數量……這浪費了很多寶貴的時間。

Now imagine if the feedback came within 3 minutes. You probably wouldn't have started the new task at all. You would have proof read your code one more time or reviewed a PR while waiting. The failed notification would come and you would fix it. Then you could move on to the next task. That is the kind of focus your process should enable.

現在,假設反饋是否在3分鐘內到來。 您可能根本不會啟動新任務。 您將有證據再次閱讀您的程式碼,或者在等待時檢查PR。 失敗的通知將到來,您將對其進行修復。 然後,您可以繼續執行下一個任務。 這就是您的流程應啟用的焦點。

Keeping your CI build short makes it a trade off. Tests that run longer or provide little value in the context of CI should be moved to the CD step. And yes, failures there also need to be fixed. But since they are not preventing anybody from doing their thing, you can take the fixes as a "next task" when you finish what you are doing. Just turn off the notifications while working and check every now and then. Keep the context switching to a minimum.

保持CI的構建時間短,這是一個折衷方案。 在CI範圍內執行時間更長或幾乎沒有價值的測試應移至CD步驟。 是的,那裡的故障也需要修復。 但是,由於它們不會阻止任何人做他們的事情,因此您可以在完成工作後將這些修補程式作為“下一項任務”來處理。 只需在工作時關閉通知並不時檢查即可。 保持上下文切換到最小。

持續交付和部署是工程問題 (Continuous Delivery and Deployment are engineering problems)

Let’s settle on the definitions to get that out of the way.

讓我們解決一下定義,以消除這些障礙。

Continuous Delivery is about being able to deploy any version of your code at all times. In practice it means the last or pre-last version of your code. You don’t deploy automatically, usually because you don’t have to or are limited by your project lifecycle. But as soon as someone feels like it, a deployment can be done in a minimal amount of time. That someone can be the test/QA team that wants to test things out on a staging or pre-production environment. Or it can actually be time to roll out the code to production.

持續交付是指能夠隨時部署任何版本的程式碼。 實際上,它是指程式碼的最新版本。 您不會自動部署,通常是因為您不必或不受專案生命週期的限制。 但是隻要有人願意,就可以在最短的時間內完成部署。 有人可以成為想要在暫存或預生產環境中進行測試的測試/ QA團隊。 或者實際上可能是時候將程式碼推向生產了。

The idea of Continuous Delivery is to prepare artifacts as close as possible from what you want to run in your environment. These can be .jar or .war files if you are working with Java, or executables if you are working with .NET. These can also be folders of transpiled JS code or even Docker containers, whatever makes deployment shorter (i.e. you have pre-built as much as you can in advance).

連續交付的想法是準備與您要在環境中執行的專案儘可能接近的工件。 如果使用Java,則可以是.jar或.war檔案;如果使用.NET,則可以是可執行檔案。 它們也可以是已轉譯的JS程式碼的資料夾,甚至是Docker容器的資料夾,無論使部署變得更短(即,您已經預先構建了儘可能多的內容)。

By preparing artifacts, I don't mean turning code into artifacts. This is usually a few scripts and minutes of execution. Preparing means:

通過準備工件,我並不是要把程式碼變成工件。 這通常是一些指令碼和執行時間。 準備方式:

Run all the tests you can to ensure that, once deployed, the code will actually work. Run unit tests, integration tests, end to end tests, and even performance tests if you can automate that.
執行所有測試,以確保一旦部署,該程式碼便會真正起作用。 如果可以自動執行單元測試,整合測試,端到端測試,甚至效能測試。

This way you can filter which versions of your main branch are actually production ready and which are not. The ideal test suite:

這樣,您可以過濾主分支的哪些版本實際上已準備好生產,哪些尚未準備就緒。 理想的測試套件:

  • Ensures that the application's key functionalities work. Ideally all functionalities

    確保應用程式的關鍵功能正常執行。 理想情況下,所有功能
  • Ensures that no performance deal breaker has been introduced so when your new version hits your many users, it has a chance to last

    確保沒有引入任何績效突破者,因此當您的新版本受到眾多使用者的歡迎時,它就有機會持久
  • Dry run any database updates your code needs to avoid surprises

    空執行您的程式碼所需的任何資料庫更新,以免出現意外情況

It does not need to be very fast. 30 minutes or 1 hour is acceptable.

它不需要非常快。 30分鐘或1小時是可以接受的。

Continuous Deployment is the next step. You deploy the most up to date and production ready version of your code to some environment. Ideally production if you trust your CD test suite enough.

持續部署是下一步。 您將最新和生產就緒版本的程式碼部署到某些環境。 如果您對CD測試套件足夠信任,則是理想的生產方式。

Note that, depending on the context, this is not always possible or worth the effort. Continuous Delivery is often enough to be productive, especially if you are working in a close network and have limited environments you can deploy to. It can also be that the release cycle of your software prevents unplanned deploys.

請注意,根據上下文,這並非總是可能或值得付出。 連續交付通常足以提高工作效率,尤其是當您在封閉的網路中工作並且可以部署的環境有限時。 也可能是軟體的釋出週期阻止了計劃外的部署。

Continuous Delivery and Continuous Deployment (let’s call them CD from now on) are not team problems. They are about finding the right balance between execution time, maintenance efforts and relevance of your tests suite to be able to say "This version works as it should."

持續交付和持續部署(從現在起將它們稱為CD)不是團隊問題。 他們的目的是在執行時間,維護工作和測試套件的相關性之間找到適當的平衡,以便能夠說“此版本可以正常工作”。

And it is a balance. If your tests last 30 hours that is a problem. See this epic post about what the Oracle database test suite looks like. But if you spend so much time keeping your tests up to date with the latest code that it impedes the team's progress, that is not good either. Also if your test suite ensures pretty much nothing... it is basically useless.

這是一個平衡。 如果您的測試持續30個小時,那就有問題了。 有關Oracle資料庫測試套件的外觀,請參見這篇史詩般的帖子 。 但是,如果您花費大量時間使測試與最新程式碼保持同步,那會阻礙團隊的進步,那也不是一件好事。 同樣,如果您的測試套件幾乎沒有任何保證,那基本上是沒有用的。

In an ideal world we want one set of deployable artifacts per commit to the main branch. You can see we have a vertical scalability problem: the faster we move from code to artifacts, the more ready we are to deploy the newest version of the code.

在理想的世界中,我們每次提交到主分支都需要一組可部署的工件。 您可以看到我們有一個垂直的可擴充套件性問題:從程式碼到工件的遷移速度越快,我們就越準備好部署最新版本的程式碼。

有什麼大不同? (What’s the big difference?)

Continuous Integration is a horizontal scalability problem. You want developers to merge their code often so the checks must be fast. Ideally within minutes to avoid developers switching context all the time with highly async feedback from the CI builds.

持續整合是一個水平可伸縮性問題。 您希望開發人員經常合併其程式碼,因此檢查必須快速。 理想情況下,幾分鐘之內就可以避免開發人員始終通過CI版本的高度非同步反饋來切換上下文。

The more developers you have, the more computing power you need to run simple checks (build and test) on all the active branches.

您擁有的開發人員越多,則在所有活動分支上執行簡單檢查(構建和測試)所需的計算能力就越高。

A good CI build:

良好的CI構建:

Ensures no code that breaks basic stuff and prevents other team members to work is introduced to the main branch, and
確保沒有將破壞基本內容並阻止其他團隊成員工作的程式碼引入主分支,並且
Is fast enough to provide feedback to developers within minutes to prevent context switching between tasks.
足夠快,可以在幾分鐘內向開發人員提供反饋,以防止任務之間進行上下文切換。

Continuous Delivery and Deployment are vertical scalability problems. You have one rather complex operation to perform.

持續交付和部署是垂直可伸縮性問題。 您需要執行一個相當複雜的操作。

A good CD build:

良好的CD版本:

Ensures that as many features as possible are working properly.
確保儘可能多的功能正常執行。
The faster the better, but it is not a matter of speed. A 30-60 minutes build is OK.
速度越快越好,但這不是速度問題。 30至60分鐘的構建就可以了。

A common misconception is to see CD as a horizontal scalability problem like CI: the faster you can move from code to artifacts, the more commits you can actually process, and the closer to the ideal scenario you can be.

一個常見的誤解是將CD視為諸如CI之類的水平可伸縮性問題:從程式碼到工件的遷移速度越快,實際處理的提交越多,就越接近理想的情況。

But we don't need that. Producing artifacts for every commit and as fast as possible is usually overkill. You can very well approach CD on a best effort basis: have a single CD build that will just pick the latest commit to verify once a given build is finished.

但是我們不需要。 為每次提交儘可能快地生成工件通常是過大的。 您可以盡最大的努力很好地使用CD:只有一個CD構建,它將在給定構建完成後立即選擇最新提交進行驗證。

Make no mistake about CD. It is really hard. Getting to sufficient test confidence to say your software is ready to be deployed automatically usually works on low surface applications like APIs or simple UIs. It is very difficult to achieve on a complex UI or a large monolith system.

毫無疑問CD。 真的很難。 獲得足夠的測試信心才能說您的軟體已準備好自動部署,通常可以在諸如API或簡單UI之類的底層應用程式上使用。 在複雜的UI或大型整體系統上很難實現。

結論 (Conclusion)

Tools and principles used to execute CI and CD are often very similar. The goals are very different though.

用於執行CI和CD的工具和原理通常非常相似。 但是目標是非常不同的。

Continuous Integration is a trade off between speed of feedback loop to developers and relevance of the checks your perform (build and test). No code that would impede the team progress should make it to the main branch.

持續整合是對開發人員的反饋迴圈速度與您執行的檢查(構建和測試)的相關性之間的折衷。 沒有任何妨礙團隊進步的程式碼可以進入主分支。

Continuous Delivery of Deployment is about running as thorough checks as you can to catch issues on your code. Completeness of the checks is the most important factor. It is usually measured in terms code coverage or functional coverage of your tests. Catching errors early on prevents broken code to get deployed to any environment and saves the precious time of your test team.

持續交付部署是要進行全面檢查,以發現程式碼問題。 檢查的完整性是最重要的因素。 通常用測試的程式碼覆蓋率或功能覆蓋率來衡量。 儘早發現錯誤可以防止將損壞的程式碼部署到任何環境,並節省測試團隊的寶貴時間。

Craft your CI and CD builds to achieve these goals and keep your team productive. No workflow is perfect. Problems will arise every now and then. Use them as lessons learned to strengthen your workflow every time they do.

精心設計CI和CD版本以實現這些目標並保持團隊的生產力。 沒有工作流程是完美的。 問題會時不時地出現。 每次使用它們時,都可以將其作為學習的經驗教訓來加強您的工作流程。

Published on 27 Nov 2019 on the Fire CI Blog.

於2019年11月27日釋出在Fire CI部落格上

翻譯自: https://www.freecodecamp.org/news/the-real-difference-between-ci-and-cd/

持續整合持續部署持續交付

相關文章