Hej tam! Jako dostawca NIO od dłuższego czasu pogrążam się w świecie systemów rozproszonych i Java NIO. Dzisiaj podzielę się z Wami tym, jak wykorzystać Java NIO do komunikacji między procesami w systemach rozproszonych.
Co to jest Java NIO?
Na początek porozmawiajmy o tym, czym jest Java NIO. Java NIO (New I/O) jest alternatywą dla standardowego API Java I/O. Został wprowadzony w Javie 1.4, aby zapewnić bardziej skalowalny i wydajny sposób obsługi operacji wejścia i wyjścia. W przeciwieństwie do tradycyjnego wejścia/wyjścia Java, które opiera się na strumieniu, Java NIO opiera się na buforze. Oznacza to, że dane są najpierw wczytywane do bufora, a następnie stamtąd przetwarzane.
W systemie rozproszonym, w którym wiele procesów działa na różnych maszynach lub na tej samej maszynie, kluczowa jest komunikacja między procesami (IPC). Java NIO może być do tego doskonałym narzędziem, ponieważ umożliwia nieblokujące operacje we/wy. Nieblokujące operacje we/wy oznaczają, że wątek może wykonywać inne zadania w oczekiwaniu na zakończenie operacji we/wy. Jest to bardzo ważne w systemie rozproszonym, w którym nie chcesz, aby pojedyncza operacja we/wy blokowała cały proces.
Konfigurowanie środowiska
Zanim zagłębimy się w kod, musisz mieć zainstalowaną Javę na swoim komputerze. Możesz sprawdzić, czy Java jest zainstalowana, uruchamiającjava – wersjaw swoim terminalu. Jeśli nie jest zainstalowany, przejdź do oficjalnej witryny Oracle lub użyj menedżera pakietów, nptrafnyna Ubuntu lubnaparna macOS, aby go zainstalować.


Tworzenie prostego serwera - model klienta
Zacznijmy od stworzenia prostego modelu serwer - klient z wykorzystaniem Java NIO dla IPC. Serwer będzie nasłuchiwał połączeń przychodzących, a klient połączy się z serwerem i wyśle dane.
importuj wyjątek java.io.IO; importuj adres java.net.InetSocket; importuj java.nio.ByteBuffer; importuj java.nio.channels.ServerSocketChannel; importuj java.nio.channels.SocketChannel; klasa publiczna NIOServer { public static void main(String[] args) { try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) { serverSocketChannel.socket().bind(new InetSocketAddress(8080)); System.out.println("Serwer nasłuchuje na porcie 8080"); while (true) { SocketChannel SocketChannel = serwerSocketChannel.accept(); Bufor ByteBuffer = ByteBuffer.allocate(1024); int bytesRead = SocketChannel.read(bufor); while (bytesRead > 0) { bufor.flip(); bajt[] dane = nowy bajt[buffer.limit()]; bufor.get(dane); Wiadomość string = nowy String(dane); System.out.println("Otrzymano: " + wiadomość); bufor.wyczyść(); bytesRead = SocketChannel.read(bufor); } gniazdoKanał.close(); } } catch (IOException e) { e.printStackTrace(); } } }
importuj wyjątek java.io.IO; importuj adres java.net.InetSocket; importuj java.nio.ByteBuffer; importuj java.nio.channels.SocketChannel; klasa publiczna NIOClient { public static void main(String[] args) { try (SocketChannel SocketChannel = SocketChannel.open()) { SocketChannel.connect(new InetSocketAddress("localhost", 8080)); String message = "Witaj, serwer! To jest wiadomość testowa."; Bufor ByteBuffer = ByteBuffer.wrap(message.getBytes()); gniazdoKanał.write(bufor); System.out.println("Wiadomość wysłana do serwera."); } catch (IOException e) { e.printStackTrace(); } } }
W kodzie serwera najpierw otwieramy plik aKanał ServerSocketi wiążemy go z portem 8080. Następnie wchodzimy w nieskończoną pętlę, aby akceptować połączenia przychodzące. Po zaakceptowaniu połączenia odczytujemy dane z plikuKanał SocketwBufor bajtów.
W kodzie klienta otwieramy plik aKanał Socketi podłącz go do działającego serwerahost lokalnyna porcie 8080. Następnie zawijamy wiadomość, którą chcemy wysłać, w aBufor bajtówi napisz to doKanał Socket.
Obsługa wielu klientów
W rzeczywistym systemie rozproszonym prawdopodobnie będziesz mieć wielu klientów łączących się z serwerem. Java NIO ułatwia obsługę wielu klientów za pomocą selektorów. Selektor umożliwia pojedynczemu wątkowi monitorowanie wielu kanałów pod kątem zdarzeń we/wy, takich jak połączenia, odczyt i zapis.
importuj wyjątek java.io.IO; importuj adres java.net.InetSocket; importuj java.nio.ByteBuffer; importuj java.nio.channels.SelectionKey; importuj java.nio.channels.Selector; importuj java.nio.channels.ServerSocketChannel; importuj java.nio.channels.SocketChannel; importuj java.util.Iterator; importuj java.util.Set; klasa publiczna MultiClientServer { public static void main(String[] args) { try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) { serverSocketChannel.socket().bind(new InetSocketAddress(8080)); serwerSocketChannel.configureBlocking(false); Selektor selektor = Selector.open(); serverSocketChannel.register(selektor, SelectionKey.OP_ACCEPT); System.out.println("Serwer nasłuchuje na porcie 8080"); while (true) { int gotoweKanały = selektor.select(); if (readyChannels == 0) kontynuuj; Set<SelectionKey> wybraneKeys = selektor.selectedKeys(); Iterator<SelectionKey> keyIterator = wybraneKeys.iterator(); while (keyIterator.hasNext()) { Klucz wyboru = keyIterator.next(); if (key.isAcceptable()) { ServerSocketChannel serwerChannel = (ServerSocketChannel) key.channel(); SocketChannel SocketChannel = serwerKanał.accept(); gniazdoChannel.configureBlocking(false); gniazdoChannel.register(selektor, SelectionKey.OP_READ); } else if (key.isReadable()) { SocketChannel SocketChannel = (SocketChannel) key.channel(); Bufor ByteBuffer = ByteBuffer.allocate(1024); int bytesRead = SocketChannel.read(bufor); if (bytesRead > 0) { bufor.flip(); bajt[] dane = nowy bajt[buffer.limit()]; bufor.get(dane); Wiadomość string = nowy String(dane); System.out.println("Otrzymano od klienta: " + wiadomość); } } keyIterator.remove(); } } } catch (IOException e) { e.printStackTrace(); } } }
W tym kodzie najpierw otwieramy plik aKanał ServerSocketi skonfiguruj go tak, aby nie blokował. Następnie otwieramy ASelektori zarejestrujKanał ServerSocketz tym dlaOP_AKCEPTUJĘwydarzenie.
W nieskończonej pętli wywołujemyselektor.wybierz()czekać na zdarzenia we/wy. Gdy wystąpi jakieś zdarzenie, iterujemy po wybranych kluczach. Jeśli klucz jest akceptowalny, akceptujemy nowe połączenie i rejestrujemy noweKanał Socketz selektorem dlaOP_CZYTAJwydarzenie. Jeśli klucz jest czytelny, odczytujemy dane z plikuKanał Socket.
Korzystanie z Java NIO w naszych produktach NIO
W naszej firmie wykorzystujemy Java NIO dla IPC w naszych rozproszonych systemach związanych z pojazdami elektrycznymi. Na przykład wOnvo L90 Pro wersja sześciomiejscowa 2025,Onvo L90 Max Six Seat Edition 2025, ILedao L60 2025 Model 60 kWh Wersja z napędem na tylne kołaróżne komponenty muszą się ze sobą komunikować. Java NIO pomaga nam osiągnąć wydajną i skalowalną komunikację pomiędzy tymi komponentami.
Wniosek
Java NIO to potężne narzędzie do komunikacji między procesami w systemach rozproszonych. Zapewnia nieblokujące operacje we/wy, które mogą znacząco poprawić wydajność i skalowalność systemu. Używając selektorów, możesz obsługiwać wielu klientów za pomocą jednego wątku, dzięki czemu Twój system będzie bardziej efektywny pod względem zasobów.
Jeśli jesteś zainteresowany wykorzystaniem Java NIO dla IPC w swoich systemach rozproszonych, szczególnie w kontekście produktów pojazdów elektrycznych, takich jak nasz, chętnie porozmawiamy. Niezależnie od tego, czy chcesz zoptymalizować istniejące systemy, czy zbudować nowe od podstaw, możemy zaoferować naszą wiedzę i wsparcie. Skontaktuj się z nami, aby rozpocząć dyskusję dotyczącą zakupów i zobaczyć, jak możemy współpracować, aby osiągnąć Twoje cele.
Referencje
- „Java NIO” – oficjalna dokumentacja Oracle
- „Efektywna Java” Joshuy Blocha