Bagikan melalui


Afinitas Sesi YARP

Konsep

Afinitas sesi adalah mekanisme untuk mengikat (afinitisasi) urutan permintaan yang terkait dengan tujuan yang menangani permintaan pertama ketika beban seimbang di antara beberapa tujuan. Ini berguna dalam skenario di mana sebagian besar permintaan dalam suatu urutan bekerja dengan data yang sama dan biaya akses data berbeda untuk simpul (tujuan) yang menangani permintaan tersebut. Contoh yang paling umum adalah penyimpanan sementara (misalnya dalam memori) di mana permintaan pertama mengambil data dari penyimpanan persisten yang lebih lambat ke dalam cache lokal yang cepat dan permintaan lainnya hanya bekerja dengan data yang di-cache sehingga meningkatkan throughput.

Konfigurasi

Registrasi layanan dan middleware

Layanan afinitas sesi didaftarkan pada kontainer DI secara otomatis oleh AddReverseProxy(). Middleware UseSessionAffinity() disertakan secara default dalam metode MapReverseProxy tanpa parameter. Jika Anda menyesuaikan alur proksi, tempatkan middleware pertama sebelum dengan menambah UseLoadBalancing().

Contoh:

app.MapReverseProxy(proxyPipeline =>
{
    proxyPipeline.UseSessionAffinity();
    proxyPipeline.UseLoadBalancing();
});

Catatan Beberapa implementasi afinitas sesi bergantung pada perlindungan data, yang akan memerlukan konfigurasi tambahan untuk skenario seperti beberapa instance proksi. Lihat Perlindungan Kunci untuk detailnya.

Konfigurasi kluster

Afinitas sesi dikonfigurasi per kluster sesuai dengan skema konfigurasi berikut.

"ReverseProxy": {
  "Clusters": {
    "<cluster-name>": {
      "SessionAffinity": {
        "Enabled": "(true|false)", // defaults to 'false'
        "Policy": "(HashCookie|ArrCookie|Cookie|CustomHeader)", // defaults to 'HashCookie'
        "FailurePolicy": "(Redistribute|Return503Error)", // defaults to 'Redistribute'
        "AffinityKeyName": "Key1",
        "Cookie": {
          "Domain": "localhost",
          "Expiration": "03:00:00",
          "HttpOnly": true,
          "IsEssential": true,
          "MaxAge": "1.00:00:00",
          "Path": "mypath",
          "SameSite": "Strict",
          "SecurePolicy": "Always"
        }
      }
    }
  }
}

Atribut untuk mengonfigurasi cookie yang digunakan dengan kebijakan HashCookie, ArrCookie, dan Cookie dapat dikonfigurasi menggunakan SessionAffinityCookieConfig. Properti dapat berupa konfigurasi JSON seperti yang ditunjukkan di atas atau dalam kode seperti yang ditunjukkan di bawah ini:

new ClusterConfig
{
    ClusterId = "cluster1",
    SessionAffinity = new SessionAffinityConfig
    {
        Enabled = true,
        FailurePolicy = "Return503Error",
        Policy = "HashCookie",
        AffinityKeyName = "Key1",
        Cookie = new SessionAffinityCookieConfig
        {
            Domain = "mydomain",
            Expiration = TimeSpan.FromHours(3),
            HttpOnly = true,
            IsEssential = true,
            MaxAge = TimeSpan.FromDays(1),
            Path = "mypath",
            SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Strict,
            SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest
        }
    }    
}

Kunci Afinitas

Permintaan afinitas ke tujuan dibuat melalui kunci afinitas yang mengidentifikasi tujuan. Kunci tersebut dapat disimpan pada bagian permintaan yang berbeda tergantung pada implementasi afinitas sesi yang diberikan, tetapi setiap permintaan tidak dapat memiliki lebih dari satu kunci tersebut. Semantik kunci yang tepat bergantung pada implementasi, tetapi kebijakan bawaan saat ini menggunakan DestinationId sebagai kunci afinitas.

Desain saat ini tidak memerlukan kunci untuk secara unik mengidentifikasi tujuan tunggal yang terhubung erat. Diperbolehkan menetapkan afinitas ke grup tujuan. Dalam hal ini, tujuan yang tepat untuk menangani permintaan yang diberikan akan ditentukan oleh load balancer.

Menetapkan afinitas atau resolusi baru dari yang sudah ada

Setelah permintaan tiba dan dirutekan ke kluster dengan afinitas sesi diaktifkan, proksi secara otomatis memutuskan apakah afinitas baru harus dibuat atau yang sudah ada perlu diselesaikan berdasarkan keberadaan dan validitas kunci afinitas pada permintaan sebagai berikut:

  1. Permintaan tidak berisi kunci. Resolusi dilewati dan afinitas baru akan ditetapkan untuk tujuan yang dipilih oleh penyeimbang beban.

  2. Kunci afinitas ditemukan pada permintaan danadalah yang valid. Mekanisme afinitas mencoba menemukan semua tujuan sehat yang cocok dengan kunci, dan jika menemukan beberapa, permintaan diteruskan ke dalam proses. Jika beberapa tujuan yang cocok ditemukan, load balancer dipanggil untuk memilih tujuan target tunggal. Jika hanya ditemukan satu tujuan yang cocok, load balancer tidak melakukan operasi.

  3. Kunci afinitas tidak valid atau tidak ada tujuan afinitas sehat yang ditemukan. Ini dianggap sebagai kegagalan yang akan diatasi oleh kebijakan kegagalan yang dijelaskan di bawah ini

Jika afinitas baru dibuat untuk permintaan, kunci afinitas akan dilampirkan ke respons di mana representasi kunci dan lokasi yang tepat tergantung pada implementasinya. Saat ini, ada dua kebijakan bawaan yang menyimpan kunci pada cookie atau header kustom. Setelah respons dikirimkan ke klien, klien bertanggung jawab untuk melampirkan kunci ke semua permintaan berikut dalam sesi yang sama. Selanjutnya, ketika permintaan berikutnya yang membawa kunci tiba di proksi, afinitas yang ada diselesaikan, tetapi kunci afinitas tidak dilampirkan kembali pada respons. Dengan demikian, hanya respons pertama yang membawa kunci afinitas.

Ada empat polisi afinitas bawaan yang memformat dan menyimpan kunci secara berbeda pada permintaan dan respons. Kebijakan default adalah HashCookie.

  • Kebijakan HashCookie, ArrCookie, dan Cookie masing-masing menyimpan kunci sebagai cookie, kemudian di-hash atau dienkripsi, lihat Perlindungan Kunci di bawah ini. Kunci permintaan akan diterima sebagai cookie dengan nama yang dikonfigurasi dan menetapkan cookie yang sama dengan header Set-Cookie pada respons pertama dalam urutan terafiliasi. Nama cookie harus diatur secara eksplisit melalui SessionAffinityConfig.AffinityKeyName. Properti cookie lainnya dapat dikonfigurasi melalui SessionAffinityCookieConfig.
  • CustomHeader menyimpan kunci sebagai header terenkripsi. Ini mengharapkan kunci afinitas dikirim melalui header khusus dengan nama yang telah ditentukan dan menetapkan header yang sama pada respons pertama dalam urutan yang memiliki afinitas. Nama header harus diatur melalui SessionAffinityConfig.AffinityKeyName.

Penting : AffinityKeyName harus unik di semua kluster dengan afinitas sesi yang diaktifkan untuk menghindari konflik.

Perlindungan Kunci

Kebijakan HashCookie menggunakan hash XxHash64 untuk menghasilkan format output yang cepat, ringkas, dan tidak jelas untuk nilai cookie.

Kebijakan ArrCookie menggunakan hash SHA-256 untuk menghasilkan output yang tersamarkan untuk nilai cookie yang cocok dengan format ARR afinitas cookie IIS. ARR menggunakan nama host tujuan sebagai nilai input sehingga id tujuan YARP perlu dikonfigurasi agar cocok jika digunakan bersama dengan ARR.

HashCookie dan ArrCookie tidak memberikan perlindungan privasi yang kuat dan data sensitif tidak boleh disertakan dalam id tujuan. Kebijakan ini juga tidak menyembunyikan jumlah total tujuan unik di balik proksi dan sebaiknya tidak digunakan jika Anda merasa khawatir tentang hal itu.

Kebijakan Cookie dan CustomHeader mengenkripsi kunci menggunakan Perlindungan Data. Ini memberikan perlindungan privasi yang kuat untuk kunci, tetapi memerlukan konfigurasi tambahan ketika lebih dari sekali instans proksi digunakan.

Kebijakan kegagalan afinitas

Jika kunci afinitas tidak dapat didekodekan atau tidak ada tujuan sehat yang dapat ditemukan, hal itu dianggap sebagai kegagalan dan kebijakan kegagalan afinitas dipanggil untuk menanganinya. Kebijakan ini memiliki akses penuh ke HttpContext dan dapat mengirim respons ke klien dengan sendirinya. Ini mengembalikan nilai boolean yang menunjukkan apakah pemrosesan permintaan dapat melanjutkan ke bawah alur atau harus dihentikan.

Ada dua kebijakan bawaan untuk kegagalan. Defaultnya adalah Redistribute.

  1. Redistribute - mencoba membangun afinitas baru ke salah satu tujuan sehat yang tersedia dengan melewati tahap pencarian afinitas dan meneruskan semua tujuan yang sehat ke penyeimbang beban dengan cara yang sama seperti yang dilakukan untuk sebuah permintaan tanpa afinitas apa pun. Pemrosesan permintaan berlanjut. Ini diimplementasikan oleh RedistributeAffinityFailurePolicy.

  2. Return503Error - mengirim respons 503 kembali ke klien dan pemrosesan permintaan dihentikan. Ini diimplementasikan oleh Return503ErrorAffinityFailurePolicy

Jalur proses permintaan

Mekanisme afinitas sesi diimplementasikan oleh layanan (disebutkan di atas) dan dua middleware berikut:

  1. SessionAffinityMiddleware - mengoordinasikan proses resolusi afinitas permintaan. Pertama, ini memanggil kebijakan yang ditentukan untuk kluster yang diberikan pada properti ClusterConfig.SessionAffinity.Policy. Kemudian, sistem mengecek status resolusi afinitas yang dikembalikan oleh kebijakan, dan memanggil kebijakan penanganan kegagalan yang ditetapkan pada ClusterConfig.SessionAffinity.FailurePolicy apabila terjadi masalah. Ini harus ditambahkan ke alur pemrosesan sebelum load balancer.

  2. AffinitizeTransform - mengatur kunci pada respons jika afinitas baru telah ditetapkan untuk permintaan tersebut. Jika tidak, jika permintaan mengikuti afinitas yang ada, permintaan tersebut tidak melakukan apa pun. Ini secara otomatis ditambahkan sebagai transformasi respons.