Redis ile Önbellek ve Oturum Yönetimi

Bu yazımda sizlere mevcut önbellek sistemimizi Redis’e nasıl taşıdığımızdan, oturum yönetimini Redis tarafına almak için yaptığımız işlemlerden ve Redis için kullandığımız docker konfigürasyonundan bahsedeceğim.

İlk olarak CacheManager’ın ne olduğundan bahsedecek olursam, CacheManager .Net için C# ile yazılmış açık kaynaklı bir Caching Framework’üdür. CacheManager çeşitli caching provider’larını destekler.

Yazıyı fazla uzatmamak adına CacheManager Kullanımının detaylarına değinmeyeceğim. Sitesinden CacheManager kütüphanesi ile ilgili detaylara erişebilirsiniz.

Önbellek (Cache) Sisteminin Redis’e Taşınması

İlk olarak Nuget ile CacheManager.StackExchange.Redis kütüphanesini yüklememiz gerekiyor.

Bu işlemden sonra DI Container tarafında CacheManager ile ilgili bir konfigürasyon yapmamız gerekiyor. Biz DI Container olarak Autofac kullandığımızdan bu işlemi AutofacModule’de Load Metodu içinde gerçekleştirdik. Yaptığımız işlem basitçe aşağıdaki gibidir.

Önbellek yönetiminin Redis tarafına alınması için AutofacModule içinde yazılması gereken kodlar bu şekilde olmalıdır. Expiration gibi diğer konfigürasyonları sizler sisteminize uygun bir şekilde değiştirebilirsiniz. Konfigürasyonda dikkat ederseniz Redis’ e ait bağlantı bilgisini almak için GetConnectionString adında bir metod bulunmaktadır. Bu metodun içeriği aşağıdaki gibidir.

Connection string’te bulunan ifadeleri açıklayacak olursam;

redis:6379 => Buradaki redis kısmı benim docker-compose.yml dosyasında Redis için oluşturduğum servisin ismidir. Siz Redis için farklı bir servis adı belirlerseniz burada onu kullanabilirsiniz. Servis adınızdan sonra “:” ekleyip hemen yanına Redis’i dışarıya açtığınız port hangisi ise onu yazmanız gerekmektedir. Ben Redis’in default olarak kullandığı 6379 port’unu tercih ettim.

abortConnect=false => abortConnect’in false set edilme sebebi, ilk bağlantı denemesi başarısız olursa ConnectionMultiplexer’ın bir exception fırlatmak yerine arka planda yeniden bağlantı denemesi yapmasını sağlamak.

password={configuration[“REDIS_PASSWORD”]} => Redis sunucunuza Authentication için bir şifre belirlediyseniz bu kısımda da şifrenizi set etmek durumundasınız. Ben şifremi docker-compose.yml dosyasında belirttiğim şekilde Environment Variable’dan almaktayım.

allowAdmin=true => Bu kısımda önbellekte bulunan tüm verilerin silinmesi gibi riskli olduğu düşünülen bir dizi komutun etkinleştirimesi sağlanır. Eğer uygulamanızda bir önbellek yönetimi ekranı varsa ve bu ekranda manuel olarak önbelleği kısmen ya da tamamen temizleme gibi ihtiyaçlarınız varsa bu ayarı true set etmeniz gerekmektedir. Aksi halde hata alırsınız.

syncTimeout=10000 => Bu ayar buradaki dokümana göre default olarak 5000 ms olarak ayarlı durumdaydı. Production ortamında “Session read exception” aldıktan sonra yaptığım araştırma sonucunda support.aspnetzero’da okuduğum yazıda bu ayarın 10000 set edilmesinin bu problemi çözdüğünü gördüm ve bu şekilde konfigüre ettikten sonra bu problemden kurtulmuş olduk.

Genel olarak Redis’e ait connection string’te bulunan parametreleri elimden geldiğince açıklamaya çalıştım. Daha detaylı bilgiye buradan erişebilirsiniz.

Bu noktada CacheManager ile ilgili yaşadığım bir problemden bahsetmek istiyorum. CacheManager Serialization ve Deserialization işlemleri için Newtonsoft’a ait methodları kullanmaktaydı. Fakat biz projede Json alanlar için .Net Core ile gelen System.Text.Json’a ait JsonElement tipini kullandığımız için Serialization ve Deserialization işlemlerinde problem yaşadık. Çünkü JsonElement tipindeki alanlar için Serialization ve Deserialization işlemlerinin doğru yürümesi adına System.Text.Json’a ait Serialization ve Deserialization metodlarını kullanmak gerekiyor. Fakat CacheManager kendi yazdığınız serializer’ı kullanmanıza olanak tanıyor. CacheManager’ın Newtonsoft serializer’ını inceleyerek System.Text.Json ile uyumlu serializer’ı yazarak projeye aşağıdaki gibi ekledim.

Yazdığımız Serializer’ın CacheSerializer adında bir abstract class’tan türemesi gerekiyor. Bu işlemden sonra gerekli abstract metodların implementasyonunu tamamlarsanız sonuca kolaylıkla ulaşmış olursunuz.

Yukarıdaki konfigürasyonda eğer dikkatinizi çektiyse CacheItem adında bir obje bulunmaktadır. Bu da CacheManager kütüphanesinde bulunan internal bir class. Modifier’ ı internal tanımlandığından projeye dahil etmek için githubdaki kodları projeye eklemek durumunda kaldım. Kodlar basitçe aşağıdaki gibidir.

CacheItem sınıfından da basitçe bahsedecek olursam redis-cli’da keyleri ile sorguladığınız önbellek objelerinin belirli bir formatta sunulmasını sağlayarak detaylı bilgi edinmenizi sağlıyor.

Sıra geldi WithSystemTextJsonSerializer metodunun içeriğinden bahsetmeye. Metod içeriği aşağıdaki gibidir. Konfigürasyonda kolaylık olması adına ConfigurationBuilderCachePart’a bir extension metod yazdım ve CacheManager’ın serializer olarak yazmış olduğum Serializer’ı kullanmasını sağlayacak şekilde konfigüre ettim.

Oturum (Session) Yönetiminin Redis’e Taşınması

İlk olarak Nuget’ten Microsoft.Extensions.Caching.StackExchangeRedis kütüphanesinin yüklenmesi gerekmektedir. Yükleme işlemi tamamlandıktan sonra Startup’ta ConfigureServices metodu içinde aşağıdaki düzenlemeyi yapmamız gerekiyor.

StackExchangeRedis kütüphanesinin yüklenmesinden sonra otomatik olarak AddStackExchangeRedisCache adındaki extension metodu kullanabilecek ve oturum yönetiminin Redis ile sağlanması için gerekli konfigürasyonu tamamlamış olacaksınız.

options.InstanceName’e verilen değer oturumlara ait keylere ön ek olarak ekleniyor.
options.Configuration ise redis sunucunuza bağlantı kurabilmek için gerekli bağlantı adresini istiyor. Bu metodun içeriğinden yukarıda bahsetmiştim. Bu işlemden sonra uygulamamızdaki oturum yönetimi de Redis tarafında sağlanacaktır.

Redis için docker konfigürasyonuna geçmeden önce karşılabileceğiniz bir hatadan ve çözümünden bahsetmek istiyorum. Uygulamamızda arkaplan görevleri için Hangfire kullandığımızdan Hangfire yönetim paneline erişim sağlarken,
Exception:Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The antiforgery token could not be decrypted. — -> System.Security.Cryptography.CryptographicException: The key… şeklinde devam eden bir hata aldık. Sebebi ise Redis’e ait DataProtection konfigürasyonunu yapmamış olmamdı. Bu hatanın çözümü ise; nuget’ten Microsoft.AspNetCore.DataProtection.StackExchangeRedis kütüphanesinin yüklenmesi ve ConfigureServices metodu içine aşağıdaki kodların eklenmesidir.

docker-compose.yml Konfigürasyonu

Bu yazımda elimden geldiğince bir Asp.Net Core uygulamasında Redis ile önbelleğe alma ve oturum yönetimini nasıl konfigüre ettiğimize ve Redis’in docker konfigürasyonuna dair konulara değinmek istedim.

Yazı ile ilgili eksikleri ya da karşılaştığınız problemleri yorum olarak yazarsanız düzeltmek / yardımcı olmak için elimden geleni yaparım. Bir sonraki yazımda görüşmek üzere 👋

--

--