Uygulamada 12 faktör manifestosu
Yeni nesil uygulama mimarisinde modern manifesto
Bir önceki paylaşmış olduğum DevOps ihtiyaç mı? Lüks mü? makalesinden yola çıkarak, bahsettiğimiz “DevOps kültürünü nasıl olgunlaştıracağız?” Sorusunu adım adım makale serisinde işleyeceğiz. DevOps’ta çok kullanılan ürünlere ve kullanımlarına daha sonra ki makalelerde anlatmayı planlıyorum(elimden geldiğince).
Bu makalede ise ürün ve hizmetleri geliştirme aşamasından teslimata kadar nelere dikkat etmemiz gerektiğinden bahsedeceğim.
Tam bu konu ile ilgili olarak literatürde bir manifesto var “Uygulama geliştirmede 12 faktör(The Twelwe Factor App). Bu maddeleri örneklerle detaylandırmaya çalışacağım.
Başlamadan önce herkesin geri planda bildiği bu maddeleri neden bu şekilde manifesto şeklinde verildiğine gelirsek;
Bir kültürden bahsettik, bu kültürü oluşturabilmemiz için ortak bir dil kullanmak önemlidir. Bu dili oluşturabilmemiz için bazı varsayımlarda bulunup, çerçevemizi çizmemiz gerekir.
İşte bu manifesto ile her maddede kurumsal kabulleri detaylandırıp yolumuza devam edersek ortak bir dil kullanmış oluruz.
1 – Kod Tabanı (Codebase)
- Tek bir kaynak kod depolama(source code repository) ürünü kullanılmalı(git, svn,bitbucket v.s.) kullanılmalıdır,
- Her bir uygulama farklı depolama alanı(repository) kullanmalıdır.
Örneğin git kullanılıyorsa kurumda her uygulamanın bir depolama alanı olacağı gibi bu depolama alanları da alt şubelere(branch) ayrılmış olmalı ki inşa edilecek(build) uygulamanın kaynak koddan kaynaklı insan hataları en aza indirilmiş olur.
Bu hatalar nelerdir:
- Kod yazan arkadaş yazacağı kodun tamamını bitirmeden kodunu git’e atmış olabilir.
- Bir uygulama üzerinde birden fazla developer çalışıyorsa, her biri farklı zamanlarda yazdığı kodu göndermiş olabilir
- Bir developer’ın yazdığı kod diğer developer’ın yazdığı kodu ezmiş olabilir v.s.
Bu gibi durumları için git akışınızı belirlemeniz gerekmektedir. Dev branch, test branch, master branch, release branch v.s. Benim hoşuma giden ise git-flow kullanarak feature branch mantığını oturta bilmektir.(sonraki makalelerde detaylandıracağım.)
2 – Bağımlılıklar (Dependencies)
Uygulama kesinlikle developer yada geliştirme ortamı bilgisayarındaki her hangi bir sistem paketlerine bağlı olmamalı yada kullanmamalıdır.
Uygulamanın kullanacağı paketler ilgili dosyada tanımlanır ve bir paket yöneticisi ile uygulamaya özel indirilir ve kullanılır.
Örnek paket yöneticileri:
- Nodejs için npm
- Java için maven
- Python için pip
- Ruby için bundle v.s.
3 – Yapılandırma (Config)
Config dosyaları kod içinde tutulmamalı,
Farklı bir dosyada tutularak kod içinde bu dosyadan okunmalıdır.
Amacımız sürekli entegrasyon, sürekli üretim ve her yerde çalıştırabilmek olduğundan bu yanlışa düşülmemesi gerekmektedir.
Örneğin bir java kodunu test etmek için derledik ve elimizde bir jar veya war dosyası var. Bu jar dosyasını test ortamına atıp çalıştırdığımızda, hiçbir problem yok istediğimiz gibi çalışıyor. Prod ortama attık çalışmıyor. Nedenini debug ettiğimizde db’ye erişemediğini görüyoruz. Peki neden? Prod ortam için yapılandırmasını yapmadık.
Eğer yapılandırma dosyası tutmamışsak hata olasılığı kat kat artıyor. Hatta ilk maddede belirttiğimiz problem burada karşımıza çıkacaktır. Böyle bir durumla karşılaşmamak veya 1. Ve 2. Adımları tekrar tekrar yapmamak için yapılandırma (config)’ler kod içinde tutulmamalıdır.
4 – Arka Plan Servisleri (Backing service)
Tüm arkaplan servislerine (veritabanı, ftp, smtp v.s.) uygulamanızdan bağlanırken sadece dns ve credential kullanılmalı ve bu bilgiler konfig dosyasında bulunmalıdır. Bağlantı için herhangi bir bileşen, paket v.s. ihtiyaç duymamalıdır. Bağlantı noktaları değiştiğinde sadece konfigürasyon dosyası değiştirilmelidir. Kaynak kod içerisinde herhangi bir değişiklik yapılamaz.
5 – İnşa Et, Duyur, Çalıştır (Build, release, run)
- Build: Kaynak koddan uygulama için bir paket oluşturulur(war, jar, docker image v.s.).
- Release: Oluşturulan paket ortam değişkenlerini içinde barındıran dosya ile birleştirilir,
- Run: oluşturulan release ilgili ortamda çalıştırılır.
Bahsettiğimiz (build,release,run) süreçleri birbirinden ayrılmalıdır. Ayrılan süreçler deployment, otomasyon araçları ile otomatize edilmelidir.
6 – Süreçler (Processes)
Süreçler bir birine bağlı durumların sıra ile işletilmesinden oluşuyor ise bellekte durum tutmamalıdır(stateless process). Bu sayede tek bir süreci(process) istediğiniz kadar çalıştırabilirsiniz ve istediğiniz yerde durdurup devam edebilirsiniz. Örneğin sticky sessionlar yerine memcached/redis v.s. kullanımı
7 – Port Bağlama (Port binding)
Uygulama dışarıya açılırken önceden belirlenmiş ip/url port kullanılmalıdır. Bu sayede farklı ortamlarda çalıştırılan servislere erişim kolay olacaktır.
8 – Eşzamanlılık (Concurrency)
Uygulamanızdaki servisler eşzamanlı olarak tasarlanmalıdır. Örneğin önyüz(frontend) ve arkaplan(Backend) servisleri eşzamanlı olarak tasarlanmalıdır. Bu sayede yük dengeleme ve performans ölçeklenebilir olacaktır. Örneğin engine servisinde bir yavaşlık yada çok fazla yük varsa bu servis çoğaltılabilmelidir. Bu sayede bottleneck(dar boğaza) düşülmesi engellenebilecektir.
9 – Tek Kullanımlık yada kullanılabilirlik (Disposability)
Uygulama tek kullanımlık, hızlı bir şekilde başlatılıp durdurulabilir olmalıdır. Bunun maliyeti oldukça düşük olmalıdır. Servisinizi çalıştırmaya başladığınız andan, hazır olup dış dünyaya açılana kadar geçen süre en aza indirilmelidir.
10 – Geliştirme/Sunum Benzerliği (Dev/Prod parity)
Geliştirme ve canlı ortamların birbirlerine olabildiğince benzemesi gap sorununu en aza indirecektir. Bunlardan bazıları zaman farkı, tool/paket farklılıkları v.s.
11 – Günlükler (Logs)
Log’ların sistem üzerinde statik dosyalarda tutulmasından ziyade, bir olay akışı döngüsüne gönderilmelidir. Bu sayede alarm uyarı mekanizmaları kullanılabilir. Ayrıca uygulamanın eğilimi geçmiş günlüklere bakılarak proaktif bir aksiyon alınabilir. Elasticsearch hadoop v.s. altyapısının hazır olmasını öngörür.
12 – Yönetici İşlemleri (Admin processes)
Tek seferlik yapılacak işlerin açıkça belirtilmesi gerekmektedir. Veritabanı taşıması, tek seferlik sistem üzerinde çalıştırılması gereken işler v.s. mümkün olabildiğince otomatize edilmeli ve ortama göre uzaktan tek seferlik çalıştırılabilmelidir.
Kaynaklar:
- www.soaessentials.com/twelve-factors-to-consider-when-developing-cloud-native-applications-saas
- www.12factor.net