Kata pengantar:
Baru -baru ini, ketika menganalisis RPC Hadoop (Protokol Panggilan Prosedur Jarak Jauh), sebuah protokol yang meminta layanan dari program komputer jarak jauh melalui jaringan tanpa memahami teknologi jaringan yang mendasarinya. Anda dapat merujuk ke: http://baike.baidu.com/view/32726.htm) Mekanisme, ditemukan bahwa implementasi mekanisme RPC Hadoop terutama menggunakan dua teknologi: proxy dinamis (Anda dapat merujuk ke blog: http://weixy.iteye.com/blog/http://weixye.iteye.com/blog/http:). Untuk menganalisis kode sumber RPC dengan benar, saya pikir perlu untuk terlebih dahulu mempelajari prinsip -prinsip dan implementasi spesifik Java Nio.
Di blog ini, saya terutama menganalisis java nio dari dua arah
Daftar isi:
satu. Perbedaan antara java nio dan memblokir I/O
1. Memblokir model komunikasi I/O
2. Java NIO Prinsip dan Komunikasi Model 2. Java Nio Server dan Implementasi Kode Klien
Analisis Khusus:
satu. Perbedaan antara java nio dan memblokir I/O
1. Memblokir model komunikasi I/O
Jika Anda memiliki pemahaman tertentu tentang memblokir I/O sekarang, kami tahu bahwa memblokir I/O diblokir saat memanggil metode inputStream.read (), ia akan menunggu sampai data tiba (atau batas waktu) sebelum kembali; Demikian pula, saat memanggil metode ServerSocket.accept (), itu akan memblokir sampai ada koneksi klien sebelum kembali. Setelah setiap klien terhubung, server akan memulai utas untuk memproses permintaan klien. Diagram model komunikasi pemblokiran I/O adalah sebagai berikut:
Jika Anda menganalisisnya dengan cermat, Anda pasti akan menemukan bahwa ada beberapa kelemahan dari memblokir I/O. Berdasarkan model komunikasi I/O yang memblokir, saya merangkum dua kelemahannya:
1. Ketika ada banyak klien, sejumlah besar utas pemrosesan akan dibuat. Dan setiap utas membutuhkan ruang tumpukan dan beberapa waktu CPU
2. Pemblokiran dapat menyebabkan pergantian konteks yang sering, dan sebagian besar switching konteks mungkin tidak ada artinya.
Dalam hal ini, I/O non-blocking memiliki prospek aplikasinya.
2. Java Nio Prinsip dan Model Komunikasi
Java Nio dimulai di JDK1.4, dan dapat dikatakan sebagai "I/O baru" atau I/O yang tidak memblokir. Begini cara kerja Java Nio:
1. Utas khusus menangani semua acara IO dan bertanggung jawab atas distribusi.
2. Mekanisme yang digerakkan oleh peristiwa: memicu ketika suatu peristiwa tiba, daripada memantau peristiwa secara bersamaan.
3. Komunikasi Thread: Thread berkomunikasi melalui menunggu, memberi tahu dan cara lainnya. Pastikan setiap sakelar konteks masuk akal. Kurangi switching utas yang tidak perlu.
Setelah membaca beberapa informasi, saya memposting diagram skematik kerja Java nio yang saya pahami:
(Catatan: Aliran pemrosesan masing -masing utas mungkin membaca data, decoding, pemrosesan komputasi, pengkodean, dan mengirim tanggapan.)
Server Java Nio hanya perlu memulai utas khusus untuk menangani semua acara IO. Bagaimana model komunikasi ini diimplementasikan? Haha, mari kita jelajahi misteri bersama. Java Nio menggunakan saluran dua arah untuk transmisi data, daripada aliran satu arah, dan peristiwa yang menarik dapat didaftarkan di saluran. Ada empat acara secara total:
| Nama Acara | Nilai yang sesuai |
| Server menerima acara koneksi klien | Selectionkey.op_accept (16) |
| Acara Server Koneksi Klien | Selectionkey.op_connect (8) |
| Baca acara | Selectionkey.op_read (1) |
| Tulis acara | Selectionkey.op_write (4) |
Server dan klien masing -masing mempertahankan objek yang mengelola saluran, yang kami sebut pemilih, yang dapat mendeteksi acara di satu atau lebih saluran. Mari kita ambil server sebagai contoh. Jika acara baca terdaftar di pemilih server, klien mengirimkan beberapa data ke server di beberapa titik. Saat memblokir I/O, itu akan memanggil metode baca () untuk memblokir data, dan server NIO akan menambahkan acara baca ke pemilih. Utas pemrosesan server akan melakukan polling untuk mengakses pemilih. Jika suatu peristiwa yang menarik ditemukan tiba ketika mengakses pemilih, itu akan memproses peristiwa ini. Jika tidak ada kejadian yang menarik, utas pemrosesan akan diblokir sampai peristiwa menarik tiba. Di bawah ini adalah diagram skematik dari model komunikasi Java nio yang saya pahami:
dua. Java Nio Server dan Implementasi Kode Klien
Untuk lebih memahami Java Nio, berikut ini adalah implementasi kode sederhana untuk server dan klien.
Server:
paket cn.nio; impor java.io.ioException; impor java.net.inetsocketaddress; impor java.nio.bytebuffer; impor java.nio.channels.selectionKey; impor java.nio.channels.elector; impor java.nio.channels.serversocketchannel; impor java.nio.channels.socketchannel; impor java.util.iterator; /*** NIO Server* @Author Path kecil*/kelas publik NioServer {// Channel Manager Pemilih Private Selector; / ** * Dapatkan saluran server dan lakukan beberapa pekerjaan inisialisasi pada saluran * @param port port terikat * @throws ioException */ public void initserver (int port) melempar ioException {// Dapatkan server server server serverSocketchannel serverChannel = serversocketchannel.open (); // Atur saluran ke serverChannel.configureblocking yang tidak memblokir (false); // ikat server yang sesuai dengan saluran ini ke port port serverchannel.socket (). Bind (inetsocketaddress baru (port)); // Dapatkan manajer saluran this.selector = selector.open (); // Bind The Channel Manager ke saluran dan daftarkan acara selectionKey.op_accept untuk saluran. Setelah mendaftarkan acara, // Saat acara tiba, selector.select () akan kembali. Jika acara tidak mencapai selector.select () akan memblokir. serverchannel.register (selector, selectionkey.op_accept); } /*** Gunakan polling untuk mendengarkan apakah ada peristiwa pada pemilih yang perlu diproses. Jika demikian, itu akan diproses * @throws ioException */ @suppressWarnings ("Uncecked") public void listen () melempar ioException {System.out.println ("Server-side Start dengan sukses!"); // Polling untuk mengakses pemilih sementara (true) {// Ketika acara terdaftar tiba, metode kembali; Jika tidak, metode ini akan terus memblokir selector.select (); // Dapatkan iterator item yang dipilih di pemilih, dan item yang dipilih adalah item Iterator Acara Terdaftar = this.selector.selectedKeys (). Iterator (); while (ite.hasnext ()) {selectionKey key = (selectionKey) ite.next (); // hapus tombol yang dipilih untuk mencegah pemrosesan berulang item.remove (); // klien meminta acara koneksi jika (key.isacceptable ()) {serversocketchannel server = (serversocketchannel) kunci .channel (); // Dapatkan saluran untuk terhubung ke klien socketchannel channel = server.accept (); // diatur ke channel non-blocking.configureblocking (false); // Anda dapat mengirim informasi ke klien di sini channel.write (bytebuffer.wrap (string baru ("Kirim pesan ke klien"). GetBytes ())); // Setelah koneksi dengan klien berhasil, untuk menerima informasi klien, Anda perlu menetapkan izin baca untuk saluran. channel.Register (this.selector, selectionKey.op_read); // acara yang dapat dibaca diperoleh} lain jika (key.isreadable ()) {baca (key); }}}} / ** * Peristiwa pemrosesan yang membaca pesan yang dikirim oleh klien * @param key * @throws ioException * / public void baca (kunci seleksi) melempar ioException {// server dapat membaca pesan: Dapatkan saluran soket di mana peristiwa terjadi. Socketchannel channel = (socketchannel) key.channel (); // Buat buffer back buffer bytebuffer buffer = byteBuffer.allocate (10); channel.read (buffer); byte [] data = buffer.array (); String msg = string baru (data) .trim (); System.out.println ("Server menerima pesan:"+msg); Bytebuffer outbuffer = byteBuffer.wrap (msg.getbytes ()); channel.write (outbuffer); // Kirim pesan kembali ke klien}/ *** Mulai tes server* @throws ioException*/ public static void main (string [] args) melempar ioException {nioServer server = new nioServer (); server.initserver (8000); server.listen (); }} Klien:
paket cn.nio; impor java.io.ioException; impor java.net.inetsocketaddress; impor java.nio.bytebuffer; impor java.nio.channels.selectionKey; impor java.nio.channels.elector; impor java.nio.channels.socketchannel; impor java.util.iterator; /*** klien nio* @author Path kecil*/kelas publik nioclient {// channel manager pemilih pemilih swasta; /** * Get a Socket channel and do some initialization of the channel * @param ip The ip of the server connected to * @param port The port number of the server connected to * @throws IOException */ public void initClient(String ip,int port) throws IOException { // Get a Socket channel SocketChannel channel = SocketChannel.open(); // atur saluran ke saluran non-blocking.configureblocking (false); // Dapatkan manajer saluran this.selector = selector.open (); // Klien terhubung ke server. Bahkan, eksekusi metode tidak mengimplementasikan koneksi. Anda perlu menelepon // menggunakan channel.finishConnect (); dalam metode Listen () untuk menyelesaikan saluran koneksi.connect (inetsocketAddress baru (IP, port)); // Bind The Channel Manager ke saluran dan daftarkan acara seleksie.op_connect untuk saluran. channel.register (selector, selectionKey.op_connect); } /*** Gunakan polling untuk mendengarkan apakah ada peristiwa pada pemilih yang perlu diproses. Jika demikian, itu akan diproses * @throws IoException */ @suppressWarnings ("Uncecked") public void listen () melempar ioException {// polling untuk mengakses pemilih sementara (true) {selector.select (); // Dapatkan iterator untuk item yang dipilih dalam item iterator pemilih = this.selector.selectedKeys (). Iterator (); while (ite.hasnext ()) {selectionKey key = (selectionKey) item.next (); // hapus tombol yang dipilih untuk mencegah pemrosesan berulang item.remove (); // acara koneksi terjadi jika (key.isconnectable ()) {socketchannel channel = (socketchannel) key .channel (); // jika menghubungkan sedang terhubung, lengkapi koneksi jika (channel.isconnectionpending ()) {channel.finishConnect (); } // diatur ke channel non-blocking.configureblocking (false); // Anda dapat mengirim informasi ke server channel.write (bytebuffer.wrap (string baru ("Kirim pesan ke server"). GetBytes ())); // Setelah koneksi dengan server berhasil, untuk menerima informasi server, saluran perlu diatur untuk membaca izin. channel.Register (this.selector, selectionKey.op_read); // acara yang dapat dibaca diperoleh} lain jika (key.isreadable ()) {baca (key); }}}} /*** Peristiwa pemrosesan yang membaca pesan yang dikirim oleh server* @param key* @throws IoException* /public void baca (Kunci Seleksi) Melempar ioException {// Sama seperti metode baca server} /*** MULAI Klien* @throws IoException* /Main Static Main (String] @throws IoException (String Public Static (String @Throws IoException (String Public Static (String @Throws IoException (String @thowsception* Nioclient (); Client.InitClient ("LocalHost", 8000); client.listen (); }}ringkasan:
Akhirnya, analisis proxy dan java nio dinamis selesai. Haha, berikut ini adalah untuk menganalisis kode sumber mekanisme RPC Hadoop. Alamat blog adalah: http://weixiaolu.iteye.com/blog/1504898. Namun, jika Anda memiliki keberatan terhadap pemahaman Anda tentang Java Nio, Anda dipersilakan untuk membahasnya bersama.
Jika Anda perlu dicetak ulang, harap tunjukkan sumbernya: http://weixiaolu.iteye.com/blog/1479656