AWS Türkçe Blog

Bir web uygulamasını AWS Serverless’a kaldırma ve kaydırma: Bölüm 2

Orijinal makale: Link (Marcia Villalba)

1. bölümde, çok fazla kod değiştirmeden sunucusuz olmayan bir web uygulamasını sunucusuz bir ortama taşımanın mümkün olup olmadığını öğreniyorsunuz. Lambda Web Adapter ve AWS Amplify gibi bu süreçte size yardımcı olabilecek farklı araçları öğreniyorsunuz. Sonunda, bir uygulamayı sunucusuz bir ortama geçiriyorsunuz.

Ancak, taşınan uygulamayı test ederseniz iki sorun görürsünüz. Birincisi, kullanıcı oturumunun yapışkan (sticky) olmamasıdır. Her giriş yaptığınızda, uygulamadan beklenmedik bir şekilde çıkış yapıyorsunuz. İkincisi, yeni bir ürün oluşturduğunuzda o ürünün yeni görsellerini yükleyemezsiniz.

Bu son gönderi, sorunların her birini ayrıntılı olarak analiz eder ve çözümleri gösterir. Ayrıca, çözümün maliyetini ve performansını analiz eder.

Kimlik doğrulama ve yetkilendirme geçişi

Orijinal uygulama, kimlik doğrulama ve yetkilendirmeyi kendi başına gerçekleştirdi. Veritabanında, her bir kullanıcı için şifreler ve e-postaların bulunduğu bir kullanıcı dizini vardır. Uygulamayı göstermeden önce kullanıcının oturum açtığını doğrulamaya özen gösteren API’lar ve ara katman yazılımları vardır. Bunun için tüm mantık, Node.js/Express uygulamasının içinde geliştirilmiştir.

Ancak, mevcut taşınan uygulama ile her oturum açtığınızda, uygulamadan beklenmedik bir şekilde oturumunuz kapatılır. Bunun nedeni, kullanıcıların kimlik doğrulamasını ve yetkilendirmesini yapmaktan sunucu kodunun sorumlu olmasıdır ve artık sunucumuz bir AWS Lambda işlevinde çalışmaktadır ve işlevler durum bilgisizdir (stateless). Bu, istek başına çalışan bir işlev olacağı anlamına gelir (bir istek açılış sayfasındaki tüm ürünleri yükleyebilir, bir ürünün ayrıntılarını alabilir veya siteye giriş yapabilir) ve bu işlevlerden birinde bir şey yaparsanız durum paylaşılmaz.

Bunu çözmek için, işlevden kimlik doğrulama ve yetkilendirme mekanizmalarını kaldırmanız ve işlevlerin birden çok çağrılmasında durumu koruyabilen bir hizmet kullanmanız gerekir.

Bu zorluğu çözmenin birçok yolu var. Redis gibi bir veritabanıyla bir kimlik doğrulama ve oturum yönetimi katmanı ekleyebilir veya durumu işleyebilen kimlik doğrulama ve yetkilendirmeden sorumlu yeni bir mikroservis oluşturabilir veya bunun için mevcut bir yönetilen hizmeti kullanabilirsiniz.

Geçiş gereklilikleri nedeniyle, uygulamada en az değişiklikle maliyeti mümkün olduğunca düşük tutmak istiyoruz. Daha iyi çözüm, kimlik doğrulama ve yetkilendirme için mevcut bir yönetilen hizmeti kullanmaktır.

Bu demo, yönetilen, kullandıkça öde yöntemiyle AWS kaynaklarına kullanıcı kimlik doğrulaması ve yetkilendirme sağlayan Amazon Cognito‘yu kullanır. Hızlı bir yaklaşım, tüm sunucu kodunu AWS SDK kullanarak Amazon Cognito’ya yapılan çağrılarla değiştirmektir. Ancak bu, yalnızca React uygulamasından Amazon Cognito API’larını çağırarak tamamen değiştirilebilecek bir karmaşıklık ekler.

Using Cognito

Örneğin, yeni bir kullanıcı kaydedildiğinde uygulama, kullanıcıyı uygulama veritabanının yanı sıra Amazon Cognito kullanıcı havuzu dizininde oluşturur. Ancak bir kullanıcı web uygulamasında oturum açtığında, uygulama doğrudan AWS Amplify uygulamasından Amazon Cognito API’i çağırır. Bu şekilde gerekli kod miktarını en aza indirir.

Orijinal uygulamada, kimliği doğrulanmış tüm sunucu API’ları, bir erişim belirteci (access token) sağlayarak kullanıcının kimliğinin doğrulandığını geçerli kılan bir ara yazılımla korunur. Yeni kurulumla bu değişmez, ancak belirteç Amazon Cognito tarafından oluşturulur ve ardından arka uçta doğrulanabilir.

let auth = (req, res, next) => {
    const token = req.headers.authorization;
    const jwtToken = token.replace('Bearer ', '');

    verifyToken(jwtToken)
        .then((valid) => {
            if (valid) {
                getCognitoUser(jwtToken).then((email) => {
                    User.findByEmail(email, (err, user) => {
                        if (err) throw err;
                        if (!user)
                            return res.json({
                                isAuth: false,
                                error: true,
                            });

                        req.user = user;
                        next();
                    });
                });
            } else {
                throw Error('Not valid Token');
            }
        })
        .catch((error) => {
            return res.json({
                isAuth: false,
                error: true,
            });
        });
};
JavaScript

Bunun nasıl yapıldığını bu videoda adım adım görebilirsiniz.

Depolama geçişi

Orijinal uygulamada, yeni bir ürün oluşturulduğunda, Node.js/Express sunucusuna yeni bir görsel yüklenir. Ancak, uygulama artık bir Lambda işlevinde bulunuyor. Bu işlevin parçası olan kod (ve dosyalar), işlev yeniden dağıtılmadıkça değişemez. Sonuç olarak, kullanıcı deposunu sunucu kodundan ayırmanız gerekir.

Bunu yapmak için birkaç çözüm vardır: Amazon Elastic File System (EFS) veya Amazon S3 kullanmak. EFS bir dosya deposudur ve bunu, yeni görüntüleri yüklediğiniz dinamik bir depolamaya sahip olmak için kullanabilirsiniz. Orijinal uygulama, EFS’in sağladığı gibi sunucu içindeki bir dizini kullandığından, EFS’in kullanılması kodun çoğunu değiştirmez. Ancak, EFS’i kullanan işlevlerin bir Amazon Virtual Private Cloud (Amazon VPC) içinde olması gerektiğinden, EFS’in kullanılması uygulamaya daha fazla karmaşıklık katar.

Görüntülerinizi uygulamaya yüklemek için S3’yi kullanmak, yalnızca bir S3 klasörünün mevcut olmasını gerektirdiğinden daha kolaydır. Bunu yapmak için, görüntüyü uygulama API’ına yüklemekten, S3’den görüntüleri yükleyen ve alan AWS Amplify kitaplığını kullanmaya kadar uygulamayı yeniden düzenlemeniz gerekir.

export function uploadImage(file) {
    const fileName = `uploads/${file.name}`;

    const request = Storage.put(fileName, file).then((result) => {
        return {
            image: fileName,
            success: true,
        };
    });

    return {
        type: IMAGE_UPLOAD,
        payload: request,
    };
}
JavaScript

S3 kullanmanın önemli bir avantajı, görüntülerin buluttan alınmasını hızlandırmak için Amazon CloudFront‘u da kullanabilmenizdir. Bu sayede sayfanızın yüklenme süresini hızlandırabilirsiniz. Bunun nasıl yapıldığını bu videoda adım adım görebilirsiniz.

Bu uygulamanın maliyeti nedir?

Bu uygulamayı boş bir AWS hesabına dağıtırsanız bu uygulamanın kullanımının büyük bir kısmı AWS Ücretsiz Kullanımı kapsamındadır. Lambda ve Amazon Cognito gibi sunucusuz hizmetler, uygulamayı barındırmanın ömrü boyunca fiyatlandırmada size avantajlar sağlayan sonsuza kadar ücretsiz bir katmana sahiptir.

  • AWS Lambda—Saatte 100 istek, ortalama 10 ms çağırma ve yapılandırılmış 1 GB bellek ile ayda 0 USD’ye mal olur.
  • Amazon S3S3 standardını kullanarak, ayda 1 GB ve ayda 10k PUT ve GET isteklerini barındırmak, aylık 0,07 USD ücrete tabidir. Bu, S3 Intelligent-Tiering kullanılarak optimize edilebilir.
  • Amazon Cognito—Ücretsiz olarak aylık 50.000 aktif kullanıcı sağlar.
  • AWS Amplify—İstemci uygulamanızı haftada bir oluşturur, 3 GB sunar ve ayda 1 GB depolarsanız bunun maliyeti 0,87 USD’dir.
  • AWS Secrets ManagerSecrets Manager kullanılarak depolanan iki gizli bilgi vardır ve bunun maliyeti aylık 1,16 USD’dir. Bu, AWS System Manager Parameter Store ve AWS Key Management Service (AWS KMS) kullanılarak optimize edilebilir.
  • MongoDB Atlas Sonsuza kadar ücretsiz paylaşılan küme.

Bu uygulamanın toplam aylık maliyeti yaklaşık 2,11 USD’dir.

Performans analizi

Uygulamayı taşıdıktan sonra, bu uygulamanın performansını ölçmek için bir sayfa hızı bilgi aracı çalıştırabilirsiniz. Bu araç, çoğunlukla ön uç ve kullanıcının algıladığı deneyim hakkında sonuçlar verir. Sonuçlar aşağıdaki resimde gösterilmektedir. İçgörü aracı performans puanına göre bu web sitesinin performansı iyidir – hızlı yanıt verir ve kullanıcı deneyimi iyidir.

Page speed insight tool results

Uygulama sunucusuz bir ortama taşındıktan sonra, genel performansı daha da artırmak için yeniden düzenleme yapabilirsiniz. Bir alternatif, her yeni görüntü yüklendiğinde, S3’nin sağladığı olaya dayalı yetenekler kullanılarak otomatik olarak yeniden boyutlandırılır ve doğru yeni nesil formatta biçimlendirilir. Başka bir alternatif de, bir dağıtımdan sunarken görüntüleri anında biçimlendirmek mümkün olduğundan, cihaz için doğru görüntü boyutunu sunmak üzere Lambda on Edge kullanmaktır.

Arka uç ve veritabanınızın nasıl performans göstereceğini anlamak için yük testleri çalıştırabilirsiniz. Bunun için yük testleri yapmanızı sağlayan açık kaynaklı bir kütüphane olan Artillery‘i kullanabilirsiniz. Sitenizin alacağı beklenen maksimum yük ile testler yapabilir ve sitenizin bunu kaldırabileceğinden emin olabilirsiniz.

Örneğin, uygulamanızın nasıl tepki verdiğini görmek için saniyede 30 istek gönderen bir test yapılandırabilirsiniz:

config:
  target: 'https://xxx.lambda-url.eu-west-1.on.aws'
  phases:
    - duration: 240
      arrivalRate: 30
      name: Testing
scenarios:
  - name: 'Test main page'
    flow:
      - post:
          url: '/api/product/getProducts/'
JavaScript

Bu test arka uç API’larında gerçekleştirilir, yalnızca arka ucunuzu değil, aynı zamanda MongoDB ile entegrasyonunuzu da test eder. Çalıştırdıktan sonra Lambda işlevinin Amazon CloudWatch panosunda nasıl performans gösterdiğini görebilirsiniz.

Bu yük testini çalıştırmak, sisteminizin sınırlamalarını anlamanıza yardımcı olur. Örneğin, çok fazla eşzamanlı kullanıcıyla bir test yaparsanız, işlevinizdeki kısma sayısının arttığını görebilirsiniz. Bu, aynı anda sahip olabileceğiniz işlevlerin çağrı sınırını kaldırmanız gerektiği anlamına gelir.

Veya saniye başına istekleri artırırken, MongoDB kümesinin isteklerinizi kısmaya başladığını görebilirsiniz. Bunun nedeni, ücretsiz katmanı kullanıyor olmanız ve bunun belirli sayıda bağlantıya sahip olmasıdır. Daha büyük bir kümeye veya veritabanınızı Amazon DynamoDB gibi büyük bir ücretsiz katman sağlayan başka bir hizmete taşımanız gerekebilir.

Cloudwatch dashboard

Sonuç

İki bölümden oluşan bu makalede, sunucusuz olmayan bir web uygulamasını çok fazla kod değiştirmeden sunucusuz bir ortama taşımanın mümkün olup olmadığını öğrenirsiniz. AWS Lambda Web Adapter ve AWS Amplify gibi bu süreçte size yardımcı olabilecek farklı araçları ve depolama ve kimlik doğrulama gibi karşılaştığımız bazı tipik zorlukların nasıl çözüleceğini öğrenirsiniz.

Uygulama tamamen sunucusuz bir ortamda barındırıldıktan sonra, ihtiyaçlarınızı karşılamak için yukarı ve aşağı ölçeklenebilir. Bu web uygulaması, arka uç bir Lambda işlevinde barındırıldığında da performans gösterir.

Gerekirse buradan, olaya dayalı mimarinin avantajlarından yararlanmak adına uygulamayı yeniden düzenlemek için strangler modelini kullanmaya başlayabilirsiniz.

Geçişin tüm adımlarını görmek için izlemeniz gereken tüm eğitimleri içeren bir oynatma listesi vardır.

Daha fazla sunucusuz öğrenme kaynağı için Serverless Land‘i ziyaret edin.