Bağımlılık Yönetimi

. Sorun bildirin Kaynağı göster Gece · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

Önceki sayfalara bakarken bir tema tekrar tekrar geçiyor: "yönetmek" kodunuz oldukça basittir, ancak onun bağımlılıklarını yönetmek daha zor olabilir. Her çeşit bağımlılık var. Bazen, bağımlılığı ifade eder (örneğin, “bir yayını (tamamlanmış) ve bazen bir esere bağımlılık olur (örneğin, kodumu derlemem için bilgisayar görüşü kitaplığının en son sürümüne sahip olma"). Bazen kod tabanınızın başka bir kısmına iç bağımlılıklar olur ve bazen başka bir ekibe ait koda ya da verilere dış bağımlılıklarınız olur (kuruluşunuzda veya üçüncü bir tarafta). Ama her halükarda, “Ben buna ihtiyaç duydum.” sözleriyle sürekli olarak karşılaşıyoruz. ve bağımlılıkları yönetmek muhtemelen en önemli temel işi olabilir.

Modüller ve Bağımlılıkları Ele Alma

Bazel gibi yapı tabanlı derleme sistemleri kullanan projeler Birbirine bağımlılığı ifade eden modüllerle birlikte BUILD dosyası olarak da kaydedebilir. Bu modüllerin ve bağımlılıkların doğru şekilde düzenlenmesi, hem de derleme işlemi için gereken çalışma miktarına sağlar.

Ayrıntılı Modülleri ve 1:1:1 Kuralını Kullanma

Yapı tabanlı bir yapı yapılandırırken ortaya çıkan ilk soru, her modülün ne kadar işlev içermesi gerektiğine karar verebilirsiniz. Bazel'de, modül, aşağıdaki gibi derlenebilir bir birim belirten bir hedefle temsil edilir: java_library veya go_binary. Bir uçta, tüm proje köke bir BUILD dosyası koyarak ve yinelemeli bir şekilde tüm kaynak dosyalarını globlop olarak görüntüleyebilirsiniz. Diğer taraftan neredeyse her kaynak dosya kendi modülüne dönüştürülebilirdi ve bu nedenle her dosyanın, bağlı olduğu diğer tüm dosyalarda BUILD dosyasında listelenmesi gerekir.

Çoğu proje bu uç noktalar arasında bir yerdedir ve seçim, arasında bir denge kurmaktır. Veri analizi için tek bir modül kullanmak anlamına gelebilir ve tüm uygulamalar için yalnızca BUILD dosyasına bir dış bağımlılık eklerken, derleme sisteminin her zaman tüm projeyi bir kerede derlemeniz gerekir. Bu, kullanıcının paralel yapmayacak veya dağıtmayacak ya da parçalarını önbelleğe alamaz üzerine düşünün. Dosya başına bir modül bunun tersidir: Derleme sistemi Derlemenin önbelleğe alma ve planlama adımlarında maksimum esnekliğe sahiptir, ancak mühendisler, belirli aralıklarla bağımlılık listesi oluşturmak için hangi dosyanın hangi içeriğe referansta bulunacağını değiştirirler.

Kesin ayrıntı düzeyi dile göre değişse de (ve genellikle Google, diğerlerine kıyasla çok daha küçük modülleri tercih ediyor. göreve dayalı derleme sistemleri kullanır. Tipik bir üretim ikili programı Google genellikle on binlerce hedefe dayanır ve hatta orta ölçekli ekip, kod tabanında yüzlerce hedefe sahip olabilir. Örneğin, Güçlü bir yerleşik paketleme kavramına sahip Java'da, her dizin genellikle tek bir paket, hedef ve BUILD dosyası (Pantolon, başka bir derleme sistemi) kullanıyorsanız buna 1:1:1 kuralı denir. Daha zayıf ambalaja sahip diller kuralları genellikle her BUILD dosyası için birden fazla hedef tanımlar.

Daha küçük yapı hedeflerinin avantajları büyük ölçekte görülmeye başlar çünkü Bu durum, daha hızlı dağıtılan derlemelerin ve hedeflerin yeniden oluşturulma sıklığının daha az duyulmasını sağlar. Test başladıktan sonra avantajları daha da cazip hale geliyor. ve daha ayrıntılı hedefler, derleme sisteminin kullandığı yalnızca belirli bir testten etkilenebilecek belirli bir test alt unutmayın. Google, daha küçük boyutlu reklam öğeleri kullanmanın sistemli olmakla birlikte, şu hedeflere ulaşılacak şekilde yatırımlar yaparak olumsuz tarafları araçlarını kullanarak BUILD dosyalarını otomatik olarak yönetmenizi sağlar.

Bu araçlardan bazıları (ör. buildifier ve buildozer) Bazel buildtools dizini.

Modül Görünürlüğünü En Aza İndirme

Bazel ve diğer derleme sistemleri, her bir hedefin bir görünürlük belirtmesine olanak tanır. ona bağlı olabilecek başka hedefleri belirleyen bir mülk. Gizli hedef yalnızca kendi BUILD dosyasında referans verilebilir. Bir hedef, açıkça tanımlanmış BUILD dosyaları listesinin hedefleri için görünürlük veya çalışma alanındaki her hedefe ulaşabilirsiniz.

Çoğu programlama dilinde olduğu gibi, kaynak metinde görünürlüğü en aza indirmek mümkün olduğunca çok şey katın. Google'daki ekipler, hedefleri yalnızca şu durumlarda herkese açık hale getirecektir: bu hedefler Google'daki tüm ekiplerin kullanabileceği yaygın olarak kullanılan kitaplıkları temsil eder. Kodlarını kullanmadan önce başkalarının kendileriyle koordine çalışmasını gerektiren ekipler, hedeflerinin görünürlüğü olarak müşteri hedeflerinin izin verilenler listesini tutmalıdır. Her biri Ekibin dahili uygulama hedefleri yalnızca dizinlerle sınırlandırılacaktır ve çoğu BUILD dosyanın sahibi olmayan tek bir hedefi olur özel.

Bağımlılıkları Yönetme

Modüllerin birbirlerine referans verebilmesi gerekir. Dezavantajı ise ayrıntılı modüllere ayırmanızı sağladığından, bağımlılıkları yönetmeniz gerektiğinde (ancak araçlar bunu otomatikleştirmeye yardımcı olabilir). Bunları ifade etmek, bağımlılıklar genellikle BUILD dosyasındaki içeriğin çoğunluğunu oluşturur.

İç bağımlılıklar

Ayrıntılı modüllere ayrılmış büyük bir projede çoğu bağımlılık dahili olması muhtemeldir; yani aynı dilde tanımlanan ve oluşturulan başka bir hedefte kaynak depodur. İç bağımlılıklar dış bağımlılıklardan farklıdır. önceden oluşturulmuş bir eser olarak indirilmek yerine kaynak kullanılarak oluşturulduklarını yapmanız gerektiğini unutmayın. Bu aynı zamanda, bir dönüşüm için ”sürüm” kavramının İç bağımlılıklar vardır. Bir hedef ve tüm iç bağımlılıkları aynı kayıt/düzeltme üzerinde oluşturulur. Yapılması gereken iç bağımlılıklarla ilgili dikkatli bir şekilde ele alınmak geçişli bağımlılıklar (Şekil 1). Hedef A'nın, ikinci sıradaki hedef B'ye bağlı olduğunu ortak kitaplık hedef C'ye bağlıdır. A'yı hedeflemeli ve sınıfları kullanabilme hedef C'de tanımlanıyor mu?

Geçişli bağımlılıklar

Şekil 1. Geçişli bağımlılıklar

Kullanılan temel araçlar söz konusu olduğunda, bunda bir sorun yok. her ikisi B ve C, oluşturulan hedef A'ya bağlanır. Dolayısıyla, burada tanımlanan tüm simgeler C, A tarafından bilinmektedir. Bazel yıllarca buna izin verdi ancak Google büyüdükçe sorunlar görmeye başladı. B'nin yeniden düzenlendiğini varsayalım. gerekiyor. B’nin C’ye olan bağımlılığı kaldırıldıysa, A ve C'yi kullanan bir hedefin durumu bozulur. Bir hedefin kamu sözleşmesinin bir parçası haline geldi ve güvensiz bir şekilde değiştirildi. Bu da, Google’da bağımlılıkların zamanla birikerek yükselmesi anlamına geliyordu. yavaşlamaya başladı.

Google, sonunda bu sorunu “katı geçişli geçişli bir şarta bağımlılık modu"nu gönderin. Bu modda, Bazel bir hedefin doğrudan bağımlı olmaksızın bir sembole referansta bulunur ve bu durumda hatasını ve desteklenmektedir. Bu değişikliği Google'ın tüm kod tabanında, milyonlarca derleme hedefimizin her birini, kendi fonksiyonlarını açıkça listelemek için bağımlılıkları yıllarca süren bir çalışmaydı ama buna değdi. Yapılarımız hedeflerin artık daha az gereksiz bağımlılıklara sahip olması ve ihtiyaç duymadıkları bağımlılıkları, bu bağımlılığı hakkında daha fazla bilgi edineceksiniz.

Katı geçişli bağımlılıkları uygulamak her zaman olduğu gibi karşılıklı olarak bir denge yaratıyordu. Sağla artık sık kullanılan kitaplıkların listelenmesi gerektiğinden, dosyaları daha ayrıntılı derleme ve mühendisler bunları bir araya getirerek BUILD dosyalarına bağımlılık eklemek için daha fazla çaba harcamanız gerekiyor. Başlangıçta birçok eksikliği otomatik olarak tespit ederek bu yükü azaltan araçlar ve bunları geliştirici olmadan bir BUILD dosyasına ekleyerek izin verilmez. Ancak bu tür araçlar olmadan bile dengenin iyi olduğunu gördük. kod tabanı ölçeklendirildikçe buna değer: BUILD dosyasına açıkça bir bağımlılık ekleme tek seferlik bir maliyettir, ancak örtülü geçişli bağımlılıklarla başa çıkmak, devam eden sorunları çözebilir. Bazel katı geçişli bağımlılıklar uygular üzerinde varsayılan olarak çalışır.

Harici bağımlılıklar

Bağımlılık dahili değilse harici olması gerekir. Dış bağımlılıklar derleme sisteminin dışında derlenen ve depolanan yapılar üzerinde çalışan uygulamalardır. İlgili içeriği oluşturmak için kullanılan bağımlılık doğrudan bir yapı deposundan içe aktarılır (genellikle olarak kullanılır.) kaynağından oluşturulmak yerine olduğu gibi kullanılır. Şunlardan biri: dış ve iç bağımlılıklar arasındaki en büyük fark, dış bağımlılıkların sürümleri vardır ve bu sürümler projenin kaynak kodundan kaynaklanabilir.

Otomatik ve manuel bağımlılık yönetimi

Derleme sistemleri, dış bağımlılıkların sürümlerinin yönetilmesine izin verebilir manuel ya da otomatik olarak yapabilirsiniz. Manuel olarak yönetildiğinde derleme dosyası yapı deposundan indirmek istediği sürümü açıkça listelediğinde çoğu zaman anlamsal sürüm dizesi 1.1.4 olarak. Otomatik olarak yönetildiğinde, kaynak dosya ve derleme sistemi her zaman en yeni sürümü indirir. Örneğin, Örneğin Gradle, bir bağımlılığın her bir sürümü "1.+" olarak tanımlamasını bir bağımlılığın herhangi bir küçük ya da yama sürümünün, ana sürüm 1'dir.

Otomatik olarak yönetilen bağımlılıklar küçük projeler için kullanışlı olabilir ancak bunlar genellikle önemsiz ya da çok küçük veya büyük projelerde felaketin mühendislerden biri. Otomatik olarak ile ilgili sorun bağımlılıkları, sürümün ne zaman kullanılabileceği konusunda kontrol edemediğiniz güncellendi. Harici tarafların zarara yol açmayacağını garanti etmenin bir yolu yoktur (anlamsal sürüm oluşturmayı kullandıklarını iddia etseler bile) böylece bir gün çalıştıktan sonra bozulabilir ve neyin değiştiğini tespit etmenin kolay bir yolu çalışma durumuna geri döndürebilir. Yapı bozulmasa bile tespit edilmesi imkansız olan üstü kapalı davranışlar veya performans değişiklikleri olabilir.

Aksine, manuel olarak yönetilen bağımlılıklar için kaynakta ve bunların kolayca bulunması ve geri çekilebilmesi sayesinde eski bağımlılıklarla derlemek için deponun daha eski bir sürümüne göz atın. Bazel, tüm bağımlılıkların sürümlerinin manuel olarak belirtilmesini gerektirir. Şu saatte: manuel sürüm yönetiminin getirdiği ek yük, performansın sağladığı istikrar üzerine kuruludur.

Tek Sürüm Kuralı

Bir kitaplığın farklı sürümleri genellikle farklı yapılar, Dolayısıyla teoride, aynı harici örneğinin farklı versiyonları için bağımlılığın her ikisi de derleme sisteminde farklı adlarla tanımlanamıyordu. Böylece her hedef, bağımlılığın hangi sürümünü pek de iyi olmadığını unutmayın. Bu, pratikte birçok soruna yol açtığından, Google Tek Sürüm Kuralı bağımlılığınızı kontrol etmektir.

Birden fazla sürüme izin vermenin en büyük sorunu elmas bağımlılığıdır . Hedef A'nın hedef B'ye ve harici bir reklamın v1'e kitaplığını tanıtır. Hedef B daha sonra aynı öğenin v2'sine bağımlılık eklemek için yeniden düzenlenirse artık dolaylı olarak iki kaynağa bağlı olduğundan, A hedefi bozulur emin olmanız gerekir. Etkili bir sisteme bir hedeften birden fazla sürümü olan üçüncü taraf kitaplığına yeni bağımlılıklar, çünkü söz konusu hedefin kullanıcılarından herhangi biri zaten farklı bir sürümünü değil. Tek Sürüm Kuralını izlemek bu çakışmayı hedef, üçüncü taraf kitaplığına, mevcut bağımlılara zaten aynı sürümde olurlar, böylece mutlu bir şekilde bir arada olabilirler.

Geçişli dış bağımlılıklar

Bir dış bağımlılığın geçişli bağımlılıklarıyla başa çıkmak için zor oluyor. Maven Central gibi birçok yapı deposu, ve diğer yapıların belirli sürümlerindeki bağımlılıkları belirlemek için kullanılan seçeceğim. Maven veya Gradle gibi araçlar genellikle her birini tekrar tekrar indirir varsayılan olarak geçişli bağımlılıktır. Yani, projeniz, onlarca yapının indirilmesine neden olabilir. toplamıdır.

Bu çok kullanışlıdır: Yeni bir kitaplığa bağımlılık eklerken, Bu kitaplığın geçişli bağımlılıklarını izlemek zorunda olmak büyük bir zorluk. manuel olarak ekleyebilirsiniz. Ancak çok büyük bir dezavantaj vardır: kitaplıklar aynı üçüncü taraf kitaplığının farklı sürümlerine bağlı olabilir; stratejisi, tek sürüm kuralını ihlal eder ve problemi anlatır. Hedefiniz, aynı bağımlılığın farklı versiyonları varsa, hangi sürümü alın. Bu aynı zamanda bir dış bağımlılığı güncellemenin, yeni sürüm uyumlu olmaya başlarsa kod tabanı boyunca ve bazı bağımlılıklarının çakışan versiyonları olabilir.

Bu nedenle Bazel, geçişli bağımlılıkları otomatik olarak indirmez. Maalesef sihirli bir değnek de yok. Bazel'in alternatifi, depodaki tüm harici verileri listeleyen bir global dosya bağımlılıkları ve bu bağımlılık için kullanılan açık depodur. Neyse ki Bazel, birçok şeyi otomatik olarak bir dizi Maven türünün geçişli bağımlılıklarını içeren böyle bir dosya oluştur olabilir. Bu araç, ilk WORKSPACE dosyasını oluşturmak için bir kez çalıştırılabilir ve bu dosya daha sonra sürümlerin ayarlanması için manuel olarak güncellenebilir inceleyeceğiz.

Burada da, kolaylık ve ölçeklenebilirlik arasında bir tercih olması gerekir. Küçük geçişli bağımlılıkları yönetmekle uğraşmak zorunda kalmamayı tercih edebilir ve otomatik geçişli yayıncılığı kullanarak bu durumdan ve bildirmeyi konuştuk. Kuruluş, bu stratejiye giderek daha az cazip gelir. ve kod tabanı büyür, çakışmalar ve beklenmedik sonuçlar giderek daha da artar. sıklıkla görebilirsiniz. Büyük ölçeklerde bağımlılıkları manuel olarak yönetmenin maliyeti otomatik bağımlılığın neden olduğu sorunlarla ilgilenmenin maliyetinden daha düşüktür. üzerine konuşalım.

Harici bağımlılıkları kullanarak derleme sonuçlarını önbelleğe alma

Dış bağımlılıklar çoğu zaman bir şeyi serbest bırakan üçüncü taraflar kaynak kodu sağlamadan kitaplıkların kararlı sürümlerini kullanır. Biraz kuruluşlar, kendi kodlarını da ve diğer kod parçalarının bunlara bağımlı olmasını sağlayan üçüncü taraf araçlar iç bağımlılıklara kıyasla daha uzun bir zamandır. Bu, teorik olarak yapıların oluşturmaları yavaş ancak indirmeleri hızlıdır.

Ancak bu, birçok ek yüke ve karmaşıklığa da yol açar: bu eserlerin her birini oluşturmak ve bunları sağlamak zorunda olduğundan müşteriler, son teknoloji ürünleri en son sürüme güncelleyin. Çeşitlilik nedeniyle hata ayıklama da çok daha zor hale gelir. ve ekibin farklı noktalarından geliştirilmiştir. ve artık kaynak ağacın tutarlı bir görünümü bulunmaz.

İnşaatı uzun süren eserler sorununu çözmenin daha iyi bir yolu, daha önce açıklandığı gibi uzaktan önbelleğe almayı destekleyen bir derleme sistemi kullanın. Böyle bir derleme sistemi, her derlemeden ortaya çıkan yapıları bir konuma kaydeder mühendisler arasında paylaşılır. Böylece bir geliştirici, başka birisi tarafından geliştirilmişse derleme sistemi bir çözüm bulmaktır. Bu da, kampanyalarınızı geliştirmenin Aynı zamanda derlemelerin gerektiği gibi olduğundan emin olurken her zaman aynı kaynaktan oluşturulmuş gibi tutarlı olur. Bu, strateji olarak kullanılır ve Bazel, uzaktan kumandayı önbellek.

Dış bağımlılıkların güvenliği ve güvenilirliği

Üçüncü taraf kaynaklardan gelen yapılara bağlı olarak doğası gereği risklidir. Bir de üçüncü taraf kaynak (örneğin bir yapı deposu) giderse kullanılabilirlik riski İndirilemezse derlemenizin tamamı durdurulabilir. bir dış bağımlılık teşkil eder. Bir de güvenlik riski vardır: üçüncü taraf sistemin, güvenliği bir saldırgan tarafından ele geçirildiğinde, saldırgan, referans verilen rastgele kod yerleştirmelerine olanak tanıyan bu yapı, kendi tasarımlarından biriyle içine ekleyebilirsiniz. Her iki sorun da, kullandığınız yapıları yansıtarak kontrol ettiğiniz ve derleme sisteminizin erişimini engellediğiniz sunuculara bağlıdır Maven Central gibi üçüncü taraf yapı depoları. Bunun karşılığında, Bu aynaların bakımı için çaba ve kaynak gerekir. Bu nedenle, projenin ölçeğine göre değişir. Güvenlik sorunu ayrıca ve her bir bileşen için karma oluşturma işlemi gerektirerek üçüncü taraf yapısının kaynak depoda belirtilmesi, böylece derleme başarısız olur. Tamamen yeni bir alternatif en önemli iki yanı da projenizin bağımlılıklarını tedarik etmektir. Proje, ve tedarikçinin bağımlılıklarını projenin kaynak kodunu kaynak veya ikili program olarak kullanabilirsiniz. Bu da etkili bir şekilde projenin tüm dış bağımlılıklarının iç bağımlılıklara ve bildirmeyi konuştuk. Google bu yaklaşımı dahili olarak kullanır ve tüm üçüncü taraf Google genelinde, kökte bir third_party dizinine referans verilen kitaplık temel alandır. Ancak, bu yalnızca Google'da işe yarar çünkü Google'ın kaynak kontrol sistemi, aşırı büyük monorepo'yu işleyecek şekilde özel olarak tasarlanmıştır. tedarikçi bulma tüm kurumlar için bir seçenek olmayabilir.