Berbagai utilitas untuk modul lain. Termasuk LambdaReflection
yang memungkinkan untuk mengatur dan mendapatkan nilai bidang suatu instans atau mengakses konstruktor melalui antarmuka fungsional yang dibuat oleh LambdaMetafactory
.
Pustaka serialisasi abstrak yang mendukung implementasi buffer apa pun. Secara otomatis (membatalkan) serialisasi kelas yang ditandai dengan @AutoSerializable
yang terdiri dari bidang tipe default, implementasi Proto4jSerializable
, atau anggota @AutoSerializable
lainnya.
Juga mendukung pewarisan: kelas serializable dapat memperluas @AutoSerializable
lainnya dalam hal ini semua bidang induk juga akan menjadi serial transitif.
Bidang yang harus diabaikan selama serialisasi harus dianotasi dengan @Transient
.
Pustaka jaringan dengan implementasi berbasis UDP khusus dengan keandalan yang dapat dikonfigurasi.
Proto4jServer
dan Proto4jClient
memungkinkan Anda mentransfer data menggunakan datagram antar soket.
Secara default, setiap data yang dikirimkan terurut, dapat diandalkan, diperbolehkan untuk dipecah menjadi beberapa paket UDP dan digabungkan kembali di sisi penerima dan dijamin terkirim.
Semua paket UDP yang dikirim memiliki struktur berikut:
Itu adalah pilihan Anda untuk memilih cara mengirimkan data. Ini dapat dikonfigurasi dengan menentukan tanda untuk metode pengiriman. Semuanya terletak di Proto4jPacket
. Flag
.
Bendera berikut tersedia:
Nama | Nilai | Arti |
---|---|---|
CONFIRMATION | 0x01 | Menandai bahwa paket ini merupakan indikator paket lain telah berhasil diterima. Diperlukan untuk keandalan transmisi. Secara umum, hanya untuk penggunaan internal. |
PARTIAL | 0x02 | Menandai bahwa paket UDP ini adalah bagian dari paket yang lebih besar. Ketika digunakan dengan flag CONFIRMATION secara bersamaan, ini menunjukkan bahwa beberapa bagian dari paket yang lebih besar telah dikirimkan. |
UNORDERED | 0x04 | Menandai bahwa paket ini dapat ditangani secara tidak berurutan. |
UNSIGNED_BODY | 0x08 | Secara default, semua paket yang dikirim ditandatangani menggunakan CRC32 , tetapi untuk paket dengan flag yang ditentukan, hanya header paket yang akan ditandatangani. Ini berarti bahwa paket mungkin berisi byte yang tidak valid (walaupun tetap tidak ada jaminan kehilangan data). |
UNRELIABLE | 0x10 | Menandai paket ini sebagai tidak memerlukan konfirmasi. Jika penerima tidak menerima paket ini, pengirim tidak akan berbuat apa-apa. |
INDIVISIBLE | 0x20 | Panjang paket UDP terbatas, sehingga Proto4J membagi data besar menjadi beberapa paket kecil. Bendera ini menunjukkan bahwa jika paket melebihi batas ukuran paket tunggal, pengecualian akan diberikan alih-alih melakukan pemisahan. |
Tidak ada jabat tangan atau ping yang didukung pada tingkat ini tetapi Anda dapat mengatur penangan paket Anda sendiri menggunakan metode Proto4jSocket
.setInitialPacketHandler(BiConsumer<C, Proto4jPacket>)
. Paket yang sampai pada titik ini tidak pernah ditandai dengan flag CONFIRMATION
atau PARTIAL
sehingga semua instance Proto4jPacket
yang ditangani di sana berisi data persis yang dikirim oleh pengirim (hingga flag UNSIGNED_BODY
).
Selain itu, saat Anda memulai soket, CompletionStage<Void>
akan dikembalikan yang dapat membantu Anda memulai logika komunikasi antar soket.
Saat Anda akan membuat instance soket apa pun di Proto4J, Anda harus meneruskan jumlah thread pekerja dan handler ke konstruktor soket.
Pekerja hanya digunakan untuk membaca data dari soket.
Penangan digunakan untuk menangani logika ketika paket baru muncul.
Ini adalah antarmuka tingkat yang lebih tinggi dari tingkat sebelumnya. Untuk mulai menggunakannya, lihat Proto4jHighServer
dan Proto4jHighClient
atau implementasi dasarnya: BaseProto4jHighServer
dan BaseProto4jHighClient
.
Ketika klien berinteraksi dengan server pada awalnya ia memulai jabat tangan . Setelah selesai, server dan klien akan saling melakukan ping untuk memastikan koneksi tidak terputus.
Berbeda dengan Level rendah , Anda dapat mengirim paket tingkat tinggi melalui jaringan tidak hanya dengan memanipulasi byte mentah tetapi juga menggunakan entitas yang kompleks. Untuk melakukannya, buat kelas Anda sendiri yang memperluas EnumeratedProto4jPacket
atau CallbackProto4jPacket
. Yang harus Anda lakukan untuk membuatnya berfungsi adalah mengimplementasikan metode write(Buffer)
dan read(Buffer)
dan mendaftarkan paket Anda di PacketManager
di kedua sisi.
Selain itu, ada kelas PacketHandler
alternatif yang bekerja dengan paket-paket tersebut, bukan Proto4jPacket
s.
Merupakan skenario umum untuk menunggu beberapa paket merespons paket yang dikirim. Fungsionalitas ini sudah diterapkan pada tingkat ini. Anda dapat menentukan waktu tunggu maksimal dan menangani respons sesuai keinginan Anda. Hal ini dapat dilakukan dengan mengirimkan paket awal menggunakan HighChannel
. metode sendWithCallback(CallbackProto4jPacket)
.
Berikut ini adalah daftar properti sistem yang dapat digunakan untuk mempengaruhi cara modul berperilaku secara internal. Semua nilai waktu ditentukan dalam milidetik.
Nama | Nilai bawaan | Keterangan |
---|---|---|
proto4j.maxDatagramSize | 508 | Ukuran datagram maksimum yang diperbolehkan. Sadarilah bahwa ini menghitung seluruh ukuran paket UDP. |
proto4j.maxSequenceNumber | 2_000_000_000 | Nomor urut maksimum paket. Ketika penghitung internal mencapai nilai ini maka akan direset ke nol. |
proto4j.reliabilityThreshold | 20 | Penundaan paket yang belum dikonfirmasi (dan tidak ditandai dengan tanda UNRELIABLE ). |
proto4j.callbacksRegistryDelay | 100 | Nilai di mana pemeriksaan registri panggilan balik mengambil panggilan balik yang waktunya habis. |
proto4j.callbacksInitialDelay | 500 | Ini adalah waktu default yang digunakan setiap kali paket dikirim dan ditunggu setiap kali waktu tunggu tidak ditentukan secara eksplisit. |
proto4j.highTimeout | 10_000 | Jika server tidak menerima paket apa pun dari klien selama itu, maka klien akan memutuskan sambungannya. |
proto4j.highPingDelay | 1_000 | Jika server menunjukkan bahwa tidak ada penerimaan dari atau pengiriman ke klien selama itu, server akan mengirimkan respons ke klien dan menunggu paket ping. |
Ini adalah API tingkat yang lebih tinggi daripada API tingkat Tinggi . Daripada mengimplementasikan paket secara manual dan penanganannya, Anda bekerja melalui layanan.
Untuk mulai bekerja dengannya gunakan RpcServer
dan RpcClient
.
Server pada tingkat ini hanya digunakan untuk tujuan routing tetapi klien bertindak baik sebagai pengguna layanan maupun pelaksana.
Layanan terdiri dari bagian antarmuka dan implementasi. Sebagai pengguna layanan, Anda dapat memperoleh instance antarmuka layanan melalui RpcClient
.getServiceManager().getService(Class<S>)
. Semua metodenya akan diproksikan ke implementasi terdaftar dan akan dieksekusi dari jarak jauh.
Untuk membuat layanan Anda sendiri, mulailah dengan antarmuka dan beri anotasi dengan @Proto4jService.
Antarmuka layanan diperbolehkan memiliki metode default dan statis tetapi tipe pengembaliannya harus void
, serializable, atau CompletionStage
dari tipe sebelumnya. Selain itu, semua argumen harus dapat diserialkan.
Jenis yang dapat diserialkan adalah sebagai berikut:
String
dan UUID
@AutoSerializable
BufferSerializable
List
, Set
, dan Map
tipe yang dapat diserialkan Jika suatu metode harus dijalankan pada semua implementasi layanan terdaftar, metode tersebut harus dianotasi dengan @Broadcast
namun metode tersebut hanya dapat mengembalikan void
atau CompletionStage<Void>
.
Secara default, saat Anda memanggil metode ini, metode tersebut akan dieksekusi pada implementasi acak. Jika Anda ingin mengontrol distribusi eksekusi, tandai beberapa argumen metode dengan @Index
: setiap kali metode dipanggil, implementasi akan dipilih berdasarkan kode hash dari argumen yang ditandai.
Setiap kali layanan didaftarkan, semua metode dikonversi ke pengidentifikasi bilangan bulat. Tidak mungkin ada dua metode dengan pengidentifikasi yang sama tetapi situasi seperti itu mungkin terjadi. Untuk mengatasinya, beri anotasi metode dengan @MethodIdentifier
dengan pengidentifikasi statis yang ditentukan secara eksplisit.
Jika Anda sudah membuat antarmuka layanan, sekarang buat implementasinya dan daftarkan menggunakan RpcClient
.getServiceManager().registerService(Class<S>, I)
.
Skenario umum adalah memiliki antarmuka layanan pada dua set klien namun implementasinya hanya pada salah satu klien.
Ini adalah lapisan tingkat yang lebih tinggi di atas RPC dasar.
Saat membuat back-end terdistribusi (yaitu layanan mikro), praktik yang baik adalah meminimalkan jumlah titik kegagalan. Hanya ada satu titik kegagalan dalam skema yang dijelaskan di bagian sebelumnya yaitu contoh server tunggal. Conclave adalah sekumpulan server yang bekerja secara bersamaan.
Semua server di Conclave terhubung satu sama lain tetapi setiap klien hanya terhubung ke satu server. Kueri RPC didistribusikan dan dirutekan dengan baik ke seluruh jaringan sehingga Anda tidak perlu mengkhawatirkannya.
Untuk mulai bekerja dengan Conclave , lihat RpcConclaveServer
dan RpcConclaveClient
. Untuk membuat instance salah satunya, Anda harus memberikan List<InetSocketAddress>
- daftar titik tujuan semua server.
Sedangkan untuk modul Transport , ada sekumpulan properti sistem yang dicari di modul RPC .
Nama | Nilai bawaan | Keterangan |
---|---|---|
proto4j.conclaveWorkers | 2 | Jumlah thread pekerja yang digunakan oleh masing-masing klien internal server (yang digunakan untuk mengakses server lain). |
proto4j.conclaveHandlers | 2 | Jumlah thread handler yang digunakan oleh masing-masing klien internal server (yang digunakan untuk mengakses server lain). |
proto4j.conclaveTimeout | 1_000 | Waktu maksimum server akan menunggu hingga jabat tangan dengan server lain selesai. Jika tidak, maka koneksi tersebut akan dianggap sebagai koneksi yang tidak berjalan dan mengakhiri upaya koneksinya sendiri, sehingga koneksi hanya akan dimulai ulang jika ada permintaan dari koneksi lain pada permulaannya. |