代碼字體mono
by Chetan Sharma
由Chetan Sharma
如何構建代碼存儲庫:Multi,Mono或Organic? (How to Structure Code Repositories: Multi, Mono, or Organic?)
The newest debate in town is whether you should keep your services in a single repository or multiple small repositories.
城里最新的爭論是您應該將服務保存在單個存儲庫還是多個小型存儲庫中。
The idea of multiple small repositories is that code for each of your app’s micro service is kept in a repository of its own. With a mono-repo, you keep the all the code in a single repository and deploy the code as microservices.
多個小型存儲庫的想法是,每個應用程序微服務的代碼都保存在自己的存儲庫中。 使用mono-repo,您??可以將所有代碼保存在單個存儲庫中,并將代碼部署為微服務。
So which should you use? Being too rigid about any one approach — without considering the purpose and uses of each approach — can lead to negative outcomes in the long run. If you’re aware of when to use each, it can increase your productivity and improve your project.
那么您應該使用哪個呢? 從長遠來看,對任何一種方法過于僵化(不考慮每種方法的目的和用途)都可能導致負面結果。 如果您知道何時使用它們,則可以提高生產率并改善項目。
要改變規則,我們首先需要了解它們為什么存在。 (To bend the rules, we need to first understand why they exist.)
A common recommendation is to have an independent repository for every app/service. But why? Because, by having one repository for each micro-service, we gain:
常見的建議是為每個應用程序/服務都有一個獨立的存儲庫。 但為什么? 因為,通過為每個微服務擁有一個存儲庫,我們可以獲得:
Freedom to write code differently and independently of all other services.
自由編寫代碼不同,獨立于其他所有服務。
Velocity in making code changes while fixing bugs, making updates, testing and deploying. Since changes only have to be tested in a single repository, deployment of the code is faster and more reliable.
在速度修改代碼,而修正錯誤,進行更新,測試和部署。 由于更改只需在單個存儲庫中進行測試,因此代碼的部署更加快捷,可靠。
Separation of code as independent units, which prevents bug leakages and performance bottlenecks between services.
將代碼分隔為獨立的單元,從而防止錯誤泄漏和服務之間的性能瓶頸。
Clear ownership of each repository and service, which is especially helpful for large teams.
明確每個存儲庫和服務的所有權 ,這對于大型團隊尤其有用。
但是,為什么會出現單一回購協議的需求? (But why did the need for mono-repos arise?)
Clearly, the multi-repo approach has its benefits. But it also comes with its own challenges, especially in projects with a large number of microservices that use the same frameworks, language, tech stacks etc.
顯然,多重回購方法有其好處。 但這也帶來了自己的挑戰,特別是在使用相同框架,語言,技術堆棧等具有大量微服務的項目中。
A few of these challenges are:
這些挑戰包括:
Enforcing standards and best practices across all repositories. With a multi-repo, changes in code standards and best practices need to be replicated across repositories. With a mono-repo, all the changes can be done in one place.
在所有存儲庫中執行標準和最佳實踐 。 對于多倉庫,需要在存儲庫之間復制代碼標準和最佳實踐的更改。 使用單倉庫,所有更改都可以在一個地方完成。
The effort of maintaining shared or common components. Security patches, version upgrades and bug fixes involve making sure that these changes are made across all repositories and that they work seamlessly everywhere. (On a side note, the repeated code in each service also bloats its size.) In a mono-repo, we can make updates in one place, saving both time and headaches.
維護共享或通用組件的努力。 安全補丁,版本升級和錯誤修復涉及確保在所有存儲庫中進行這些更改,并且確保它們在任何地方都可以無縫運行。 (順便說一句,每個服務中重復的代碼也增加了它的大小。)在單一倉庫中,我們可以在一個地方進行更新,既省時又省力。
End-to-end testing in tandem with closely related or dependent services right from the developer’s machine. By having all the code in one place, we ease the process of starting up all the related services and running end-to-end tests.
直接從開發人員的機器進行與緊密相關或依存服務的端到端測試 。 通過將所有代碼放在一個位置,我們簡化了啟動所有相關服務和運行端到端測試的過程。
On-premise deployments of code for other businesses. By deploying a mono-repo as microservices, we save time and reduce the redundant effort of bootstrapping each repository.
用于其他業務的本地代碼部署 。 通過將單存儲庫部署為微服務,我們可以節省時間并減少引導每個存儲庫的冗余工作。
Clearly, there are advantages and disadvantages to both approaches, and each approach will have its own benefits under different circumstances.
顯然,這兩種方法都有優點和缺點,并且每種方法在不同的情況下都會有自己的優點。
Therefore, we have adopted the approach of remaining flexible and using both multi-repos and mono-repos, but only after completely understanding why we have chosen to use each for each service. This has led us to have multiple repos containing several microservices, segregated in a way that has made:
因此,我們采取了保持靈活性的方法,并同時使用了多倉庫和單倉庫,但要完全理解為什么我們選擇為每種服務使用每種倉庫。 這導致我們有多個包含多個微服務的存儲庫,這些存儲庫以如下方式隔離:
- Maintenance and updates both easy and fast. 維護和更新既簡便又快速。
- Locating the code to debug or change much more structured. 查找要調試或更改的代碼要結構化得多。
- Onboarding new teammates easier. 新隊友的入職更加輕松。
我們如何決定使用哪種類型的存儲庫 (How we decide what type of repository to use)
The following considerations have helped us decide when to use mono-repos vs. multi-repos.
以下考慮因素幫助我們決定了何時使用單存儲庫和多存儲庫。
1.考慮將用作服務基礎的代碼。 (1. Think about the code that will serve as the foundation of the service.)
Begin by identifying any similarities in code, maintenance, and updates. If multiple repositories have identical code, it would be better to club them in a single repository.
首先確定代碼,維護和更新中的任何相似之處。 如果多個存儲庫具有相同的代碼,最好將它們合并在一個存儲庫中。
The freedom to write code differently and independently in a service is one of the benefits of multiple small repositories. But often services will have a lot of identical scaffolds if they use the same language, framework, logging, bootstrap scripts, middle-wares, etc. Reusing these shared scaffolds saves time.
在服務中以不同方式獨立地編寫代碼的自由是多個小型存儲庫的好處之一。 但是,如果服務使用相同的語言,框架,日志記錄,引導腳本,中間件等,則它們通常會有很多相同的支架。重用這些共享的支架可以節省時間。
For example, Collect — our primary data collection tool — has multiple micro-services built on an identical framework. These services are built on Node.js, Express and Parse Server. They share a lot of libraries like Winston, Mongoose and other third-party integrations. Earlier, when each of these services had a repository of its own, updating or fixing a bug in any of these shared modules meant updating and testing each repository separately. This was slow and cumbersome.
例如, 收集 (我們的主要數據收集工具)具有在相同框架上構建的多個微服務。 這些服務基于Node.js , Express和Parse Server構建。 他們共享許多庫,例如Winston , Mongoose和其他第三方集成。 早先,當這些服務中的每一個都有自己的存儲庫時,更新或修復這些共享模塊中的任何一個中的錯誤就意味著分別更新和測試每個存儲庫。 這既緩慢又麻煩。
However, when we clubbed them together in a mono-repo, testing and updating the shared modules became easier and faster. Applying security patches and enforcing standards became easier since developers can do all the changes in once place.
但是,當我們將它們組合成一個單體倉庫時,測試和更新共享模塊變得更加容易和快捷。 由于開發人員可以一次完成所有更改,因此應用安全補丁和執行標準變得更加容易。
The potential risk of a mono-repo is that a developer can reuse code originally written for an unrelated module. When the two modules share code, then change in this common code can lead to bugs. If these bugs go unchecked, they can affect the CI/CD (Continuous Integration and Delivery) pipelines of unrelated micro-services. To avoid such issues, it is important to have a strong testing suite in place.
單一倉庫的潛在風險是開發人員可以重用最初為無關模塊編寫的代碼。 當兩個模塊共享代碼時,更改此公共代碼可能會導致錯誤。 如果不檢查這些錯誤,它們可能會影響不相關的微服務的CI / CD(連續集成和交付)管道。 為避免此類問題,重要的是要有一個強大的測試套件。
2.檢查是否有與其余模塊完全不同的模塊。 (2. Check whether you have any modules that are very distinct from the rest.)
Are you developing a module that demands a very different technology, language, framework or persistence? Then separating it out into a separate repository will be better.
您是否正在開發一個需要非常不同的技術,語言,框架或持久性的模塊? 然后將其分離到一個單獨的存儲庫中會更好。
In Collect, there are services that handle processing of events in bulk. They maintain queues, execute custom scripts and have a completely different error-handling mechanism. These services are written in Python, and quite often they need to do CPU-intensive tasks.
在“收集”中,有一些服務可以批量處理事件。 它們維護隊列,執行自定義腳本,并具有完全不同的錯誤處理機制。 這些服務是用Python編寫的,并且經常需要執行CPU密集型任務。
So when we were thinking about restructuring the code for Collect, keeping these services in a separate repo came across as self evident. These services were very different from Collect’s main repository (described above). While the main repository was for user-facing requests, this repo was all about background tasks and executions. Also, the change management in these services was going to be different and isolated from the main repository.
因此,當我們考慮重組Collect的代碼時,很明顯地將這些服務保存在單獨的存儲庫中。 這些服務與Collect的主要存儲庫(如上所述)非常不同。 雖然主要存儲庫是用于面向用戶的請求,但此回購全是關于后臺任務和執行的。 而且,這些服務中的變更管理將有所不同,并且與主存儲庫隔離。
Thinking about the code maintenance and how it is going to evolve over time led us to club these services in a separate repository. By doing that, we were able to put up a completely different change management system, which turned out to be very helpful and more productive.
考慮到代碼維護及其隨著時間的發展,我們將這些服務合并到一個單獨的存儲庫中。 通過這樣做,我們能夠建立一個完全不同的變更管理系統,事實證明該系統非常有用,而且效率更高。
3.考慮不確定性,因此要考慮服務可能經歷的更改頻率。 (3. Consider the uncertainty and therefore the frequency of changes a service might go through.)
When you start working on something that is highly uncertain (either in terms of the scope of the problem or the implementation itself), then having a different repository can give you with the velocity and freedom you need to test things.
當您開始進行高度不確定的事情(無論是問題的范圍還是實現本身)時,擁有不同的存儲庫可以為您提供測試事物的速度和自由度。
For example, say that you want to test a new way of processing images to identify objects. You want to dabble with machine learning, but you are still unsure how it will evolve or if the problem statement will change dramatically. In this case, it would be clearly better to have a separate repository and then get to a point of certainty. Conversely, if you think that the API has reached stability and will remain unchanged for a large amount of time, you can take a call to merge it with one of your main repositories.
例如,假設您要測試一種處理圖像以識別對象的新方法。 您想涉足機器學習,但仍不確定它會如何發展或問題陳述是否會發生巨大變化。 在這種情況下,最好有一個單獨的存儲庫,然后再確定一點。 相反,如果您認為該API已達到穩定性,并且會在相當長的時間內保持不變,則可以調用將其與您的主要存儲庫之一合并。
The blog was originally published on blog.socialcops.com. The above is how we handle our repository decisions. I hope it can help you in thinking from first principles if you approach this problem. Do subscribe to our newsletter for more updates from SocialCops Engineering and Data Science Team.
該博客最初發布在blog.socialcops.com上。 以上是我們處理存儲庫決策的方式。 我希望,如果您解決此問題,它可以幫助您從首要原則出發進行思考。 請訂閱我們的新聞通訊,以獲取SocialCops工程和數據科學團隊的更多更新。
翻譯自: https://www.freecodecamp.org/news/how-to-structure-code-repositories-multi-mono-or-organic-eda67b397d38/
代碼字體mono