Aplikasi stateful vs non-stateful [ditutup]

9

Saya telah belajar tentang aplikasi stateful vs non-stateful, tapi saya masih sedikit bingung dengan topik ini.

Sebagai contoh, katakanlah saya memiliki aplikasi yang berjalan di Node di mana pengguna ditugaskan ke kamar acak segera setelah mereka terhubung melalui socket.io. Ini adalah kamar 4 dan tidak persisten dengan cara apa pun, tetapi mereka disimpan dalam variabel global sebagai peta hash. Saya tidak menggunakan db (terlalu banyak permintaan) atau redis (terlalu mahal).

Apakah ini contoh aplikasi stateful atau tidak?

kejujuran
sumber
5
Jika tidak memiliki kewarganegaraan maka tidak akan ada yang disimpan di dalam hashmap.
candied_orange

Jawaban:

17

Dalam konteks aplikasi web, kami memanggil server stateful jika server mempertahankan keadaan sementara dalam memori , daripada menyimpan data apa pun secara eksternal (misalnya dalam database).

Aplikasi Stateful memiliki sejumlah masalah, misalnya:

  • Anda tidak dapat menjalankan lebih dari satu server tanpa menyematkan sesi ke server tertentu
  • status hilang ketika server dihidupkan ulang

Oleh karena itu, ini adalah praktik terbaik untuk menghindari keadaan sisi-server (sekali lagi: kecuali jika disimpan secara eksternal dalam database).

Backend aplikasi web biasanya tidak perlu menyimpan status sesi apa pun karena mereka dapat menggunakan prinsip REST: status ditransfer antara klien dan server. Keadaan ini diwakili oleh URL, cookie, badan HTTP, dan sebagainya. Ini diperlukan karena HTTP adalah protokol stateless (semantik, tidak harus dalam dasar-dasar teknisnya).

Dengan soket web prinsip-prinsip ini sedikit rusak karena klien mempertahankan sesi / koneksi jangka panjang dengan server - dan koneksi itu melibatkan keadaan. Ini tidak bisa dihindari, tetapi Anda mengontrol apakah dan sampai taraf apa penggunaan soket web akan membahayakan desain backend yang tidak memiliki kewarganegaraan.

  • Benar-benar baik untuk mempertahankan struktur data dalam memori yang mengontrol koneksi mana yang dilanggankan pada peristiwa apa.

  • Itu bermasalah jika struktur data dalam memori adalah "sumber kebenaran" untuk informasi itu.

    • Jika langganan seharusnya bersifat sementara, semuanya baik-baik saja.
    • Jika Anda ingin membangun kembali langganan yang sama ketika klien menghubungkan kembali, Anda perlu menyimpan status ini di tempat lain. Misalnya sisi server dalam database, atau sisi klien melalui cookie atau LocalStorage.

Secara umum, mempertahankan keadaan server internal baik-baik saja ketika salah satu dari yang berikut ini berlaku

  • negara disimpan secara eksternal
  • negara tidak dibagikan di antara permintaan
  • negara hanyalah akuisisi sumber daya mahal yang dapat digunakan kembali, mis. koneksi basis data
  • negara adalah cache untuk beberapa sumber data otoritatif, meskipun hal ini menimbulkan masalah sulit seperti pembatalan cache dan akhirnya konsistensi
amon
sumber
1
Saya tidak berpikir berada dalam memori diperlukan, karena "sementara" di sini lebih seperti konsep daripada implementasi. Ada banyak implementasi sesi yang menggunakan database atau sistem file untuk menyimpan data sesi, namun kami masih tidak bisa menyebutnya stateless.
tia
"Oleh karena itu praktik terbaik untuk menghindari keadaan sisi server (sekali lagi: kecuali jika disimpan secara eksternal dalam database)" - Saya akan mempertimbangkan kembali istilah "praktik terbaik" di sini. Mungkin ada situasi di mana bisnis lebih suka koneksi hilang daripada biaya mempertahankan negara dll. Itu benar-benar tergantung pada pro dan kontra per kasus.
Ron Klein
6

Jika Anda menyimpan status pada server yang diperlukan untuk memproses permintaan masuk dari klien, maka server tersebut stateful. Dengan kata lain, itu menyatakan bahwa ia menyimpan dan perlu mengakses untuk memproses permintaan dari klien. Jadi, hashmap Anda adalah state sehingga server Anda stateful.

Sekarang, ada beberapa aplikasi web nyata yang melakukan hal-hal kaya yang tidak stateful sama sekali. Lagi pula, jika Anda akan memiliki login pengguna dan kemudian memproses permintaan atas perintah klien yang login, maka agak menurut definisi, Anda menyimpan status pada server yang berkaitan dengan klien tertentu dan server stateful , meskipun hanya untuk info masuk.

Jadi, saya tidak akan terlalu terpaku pada status nol di server. Yang penting adalah seberapa banyak keadaan yang ada di server, seberapa mahal (dalam hal pemrosesan, penyimpanan, dll ...) untuk menyimpan dan mengakses keadaan ini dan dapatkah Anda masih menskalakan aplikasi secara horizontal dengan keadaan ini. Dan, di mana pun keadaan praktis tetap dalam klien, bukan pada server. Sebagai contoh sepele, misalkan Anda memiliki aplikasi klien yang memiliki tombol "halaman berikutnya". Anda dapat menerapkan "halaman berikutnya" dengan kondisi sisi klien dari sisi sisi server.

Jika Anda memiliki keadaan sisi server untuk halaman saat ini dari klien, Anda bisa mengirim perintah ke server yang ingin Anda lihat halaman "selanjutnya". Server akan melihat statusnya untuk klien itu, menambah halaman, lalu mengembalikan data untuk halaman berikutnya.

Atau, Anda dapat menyimpan halaman saat ini di klien. Ketika klien menginginkan halaman berikutnya, ia mengambil nomor halaman saat ini, menambahnya dengan satu dan membuat permintaan umum untuk nomor halaman tertentu yang ingin dilihat selanjutnya.

Manakah dari implementasi ini yang menurut Anda memiliki skala yang lebih baik? Manakah yang lebih sederhana untuk diterapkan ketika pengguna membuka tab kedua melihat halaman yang berbeda? Yang lebih sederhana untuk skala horizontal. Jawaban untuk semua itu adalah yang tidak menyimpan halaman saat ini di server, tetapi menyimpannya di klien dan hanya membuat permintaan umum untuk halaman N ke server. Menjaga agar sisi klien sisi membuatnya lebih mudah untuk skala secara individual dan horizontal dan mendukung banyak tampilan untuk klien yang sama.

pacar00
sumber