Servisler uygulamalarımızın vazgeçilmez bir parçasıdır bu sebeple servislerde meydana gelen yavaşlık, tüm uygulamaları dolayısıylada kullanıcı deneyimini olumsuz etkileyebilir.
Forrester Consulting tarafından belirli aralıklarla yapılan kullanıcı anketlerine göre; bir kullanıcının web sayfasının yüklenmesine ilişkin ortalama tahammül süresi sadece 2 saniye. Bir sayfanın onlarca servis isteği yaptığını göz önünde bulundurursak web servislerimizin milisaniyeler mertebesinde response dönebiliyor olması gerekir.
Servisleriniz yeterince hızlı çalışıyor mu?
Öncelikle bu soruya cevap bulmak gerekiyor. Geliştiriciler, takım veya şirketiniz bu soruyu soruyor mu? Yoksa siz de “Developer arkadaş test etti sıkıntı yok, kullanıcı şikayeti de gelmiyor, demek ki yeterince hızlıyız” mı diyorsunuz?
Bir yerden başlamak istediğinizde öncelikle servislerin performansını izlemek ve daha sonra yük altındaki davranışını gözlemlemek gerekir, sorunu tespit ettikten sonra teşhis koymak daha kolay olacaktır. Bu yazıda performans sorunlarının nasıl tespit edileceği ve iyileştirmek için geliştiricilerin uygulayabileceği ipuçlarına yer verilmiştir.
Performans Sorunlarını Nasıl Tespit Edebiliriz?
1- Monitoring
Servis performansını gözlemlemek için kesinlikle bir APM (App Performance Monitoring) çözümü kullanın. APM araçları uygulamalarınız hakkında bir çok bilgiyi size verecektir (CPU ve Bellek kullanımı, bant genişliği, response süresi, request/response boyutları, vb.). Sakın gelen giden request/response sürelerini, boyutlarını, vb. servis içerisinde ölçümlemeye kalkmayın, bu görevi “third party” bir araca devredin. Her cloud vendor (AWS, Azure, GCP) APM çözümüde sunmaktadır, bunlardan birisini seçip kullanabilirsiniz. On-prime çalışıyorsanız veya kendiniz kurulum yapacaksanız aşağıdaki önereceğim araçlara göz atabilirsiniz.
- Datadog APM
- App Dynamics
- Apache SkyWalking
- Dynatrace
- Splunk APM
2- Logging
Öncelikle APM ile Loglamayı ve de Trace’i birbirinden ayırmak gerekir. Uygulamada oluşabilecek tüm durumlar “best practice” bir şekilde kaydedilmelidir. Uygulama sağlığını ve performansını gözlemlemek için ihtiyaç olan bir çok metriğe bu sayede erişilebilir tabiki loglarınızı monitor edilebiliyorsanız.
3- Test Test Test (Yük Testi, Performans Testi, Stres Testi)
Test, sistemin ne kadar isteği karşılayabildiği, ne kadarını işleyebildiği ve yük altında nasıl davrandığını gözlemleyebilmenize olanak sağlar. Uygulamanızın yük altında nasıl davrandığını development ortamında göremezsiniz, bunu bilmenin en iyi yolu test etmektir aksi takdirde Production ortamında gerçek kullanıcılarınız sizin yerinize bu testleri yapacaktır. Bu testleri yapabileceğiniz birkaç araç gereç önerebilirim.
- Apache JMeter (GUI yerine CLI tercih etmelisiniz)
- loadrunner
- k6
4- Code Profiling
Profiler araçları uygulamanız hakkında size bir çok bilgiyi developer bakış açısından gösterecektir. Bu araçlar; hangi fonksiyonun ne kadar kaynak (CPU, RAM, Disk) tükettiği, hangi class’tan ne kadar instance oluştuğu, hangi kodun kadar süre aldığı gibi yüzlerce metrik sağlamaktadır.
Farklı dil ve teknolojiler için yüzlerce profiler araçları mevcut, başlıca önereceklerim:
- Intellij-idea (JVM Ailesi)
- JProfiler (JVM Ailesi)
- DotTrace ve DotMemory (.Net Ailesi)
- Visual Studio Performance Monitoring (.Net Ailesi)
- Blackfire (Go)
- NodeJS Profiler
- Intel VTune
Performans İyileştirme İpuçları
1- Caching
Client side ve server side caching uygulayın, mümkünse server side için bir caching çözümü de kullanın. (Dağıtık Uygulamalar İçin Önbellekleme Mimarisi )
- Memcached
- Redis
- Hazelcast
2- Request & Response Sıkıştırma
Büyük boyutlarda response dönüyorsanız veya istemciye döndüğünüz response boyutları büyükse, network üzerinde geçen transfer süresini kısaltmak için gzip sıkıştırma yapabilirsiniz. Burada dikkat edilmesi gereken nokta compress ve decompress işlemlerinin bir maliyeti olduğu.
Popüler application server’lar için yapılandırma örnekleri:
– Nginx
– IIS
– Tomcat
3- Null Value Handling
Bir çok framework, varsayılan olarak JSON response içerisinde yer alan null property’leri client’a gönderir. Bunun önüne geçerek response boyutundan tasarruf edebilir ve bu sayede network de geçen süreyi azaltabilirsiniz.
... { "firstName": "Mesut", "middleName": "", "lastName": "Piskin", "avatar": null, "gender": null, "address": null, "phoneNumber": null, "email": null, "userCode": null, "status": 1 } ...
Yukarıdaki reponse’u dönmek yerine aşağıdaki gibi dönmek, property sayısı arttıkça transfer edilen veriden elde edilen kazancı arttıracaktır, buda hız demektir.
... { "firstName": "Mesut", "lastName": "Piskin", "status": 1 } ...
4- Güvenlik ve Limitleme
DDos veya crawling botlarından kaçınmak için servis isteklerini limitleyin, bu sayede aynı kaynaklarla daha fazla gerçek kullanıcıya daha hızlı bir şekilde hizmet verebilirsiniz. Bunu yapmanın birçok yolu var; Cloud vendor’lardan hizmet olarak alabilir veya cloudflare gibi servisleri kullanabilirsiniz veya bir WAF aracı kullanabilirsiniz.
Örnek SaaS ve PaaS hizmetler:
Açık kaynak WAF araçları:
- ModSecurity
- NAXSI
- Shadow Daemon
- IronBee
- Vulture
- WebKnight
5- Pagination
Bir listeleme işlemi yapıyorsanız pagination kullanın, megabaytlarca json veriyi transfer etmekten kurtulursunuz. Büyük boyuttaki verileri transfer ederek istemcinin sayfalamasını beklemek yanlış bir yaklaşımdır. Örnek olarak listeler için aşağıdaki formatta bir response dönebilirsiniz.
{
"_metadata":
{
"page": 1,
"perPage": 50,
"pageCount": 10,
"totalcount": 500
},
"payload": [
{
"orderId": 1,
"name": "Data 1"
},
{
"orderId": 2,
"name": "Data 2"
},
{
"orderId": 3,
"name": "Data 3"
}
]
}
bkz. Pagination best practices https://gist.github.com/mislav/622561
6- JSON Serializer Seçimi
JSON serialization/deserialization işlemleri oldukça maliyetli olabilir bu sebeple kullandığınız framework içerisinde yer alan veya sizin implementasyonunu yaptığınız kütüphane seçimine dikkat etmelisiniz.
Örneğin;
- https://github.com/ngs-doo/json-benchmark (Java & DotNet)
- https://github.com/smallnest/goserco (GoLang)