Ö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?
Ş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.