Netty 상세 설명 중 하나:IO 모델 과 자바 NIO

6638 단어 Netty
Netty 는 네트워크 IO 프레임 워 크 로 Netty 를 파악 하려 면 TCP 프로 토 콜,Socket 등 기초 지식 에 대해 알 아야 합 니 다.이 분야 의 고전 서적 은'유 닉 스 네트워크 프로 그래 밍 권 1:소켓 인터넷 API'와'TCP-IP 상세 해 권 1'이다.물론 이렇게 깊 은 기초 지식 도 없고 넷 티 를 사용 하 는 데 방해 가 되 지 않 는 다.
Netty 는 자바 분야 의 프레임 워 크 이기 때문에 본 시 리 즈 는 관련 개념 을 다 룰 때 자바 분야 의 표현 을 우선 사용 합 니 다.따라서 어떤 곳 에 서 는 엄밀 하지 못 해 보일 수 있 습 니 다.이것 은 먼저 본인 의 수준 이 유한 하기 때 문 이 고,어떤 때 는 의도 적 으로 한 것 입 니 다.
IO 모델
자바 네트워크 프로 그래 밍 분야 에서 우 리 는 보통 세 가지 네트워크 IO 모델 이 있다.bio(Blocking io),nio(non-blocking io),ao.
bio:동기 블록 모델
모든 IO 작업 이 차단 되 어 있 기 때문에 서버 는 모든 연결 에 하나의 스 레 드 를 만들어 간단 해 야 합 니 다.대량의 연결 이 존재 하 는 업무 장면 을 감당 할 수 없다.
nio:동기 화 비 차단 모델
selector 모델 이 라 고도 합 니 다.모든 작업 은 동기 화 되 지만 하나의 selector 로 여러 연결 을 조회 할 수 있 습 니 다.어떤 링크 가 응답 처리 되 는 지,네트워크 이 벤트 를 막 히 게 기다 리 는 것 을 피 할 수 있 습 니 다.하나의 스 레 드 는 여러 socket 연결 서 비 스 를 동시에 제공 할 수 있 습 니 다.
aio:비동기 응답 모델
완전한 비동기 응답 식 모델 은 바 텀 운영 체제 가 많은 일 을 했 고 상층 프로그램 은 시스템 의 응답 을 기다 리 기만 하면 된다.비교적 새 롭 습 니 다(자바 7 시작 지원).현재 운용 이 광범 위 하지 않 습 니 다.
자 바 는 상기 3 가지 모델 을 실 현 했 지만 전체적으로 보면 IO 모델 은 밑바닥 에 있 는 API 로 구체 적 인 업 무 를 실현 할 때 개발 자가 대량의 네트워크 관련 업 무 를 해 야 한다.netty 는 마침 이 부분 을 도와 주 었 습 니 다.바 텀 IO 모델 을 패키지 할 뿐만 아니 라 reactor 모델 을 블 루 북 으로 하여 완전 하고 사용 하기 쉬 운 네트워크 응용 상 자 를 실현 하 였 습 니 다.
reactor 모델 지식 은 모두 스스로 검색 합 니 다.
Netty 바 텀 에서 사용 하 는 socket 인 터 페 이 스 는 플랫폼 에 따라 다 르 지만 자바 니 오 는 가장 전형 적 인 방식 입 니 다.넷 티 를 공부 할 때 는 먼저 넷 티 니 오 관련 부분 에 초점 을 맞 추 는 것 을 권장 합 니 다.
자바 NIO 소개
자바 니 오 에 관 한 지식 을 간단히 소개 하 겠 습 니 다.
핵심 유형:
자바 니 오 는 채널,버 퍼,Selector 세 가지 핵심 캐릭터 가 있 습 니 다.
채널:socket 연결 에 대한 추상;
  • Buffer:channel 과 socket 사이 에 버퍼 를 추가 하여 비 차단 을 실현 합 니 다
  • selector:selector 는 채널 의 상태 변 화 를 관리 하고 이벤트 발생 채널 을 선택 하여 처리 합 니 다

  • nio buffer:
    buffer 는 하나의 메모리 블록 으로 업무 코드 와 nio 간 에 데 이 터 를 전달 하 는 데 사 용 됩 니 다.모든 buffer 유형 은 4 개의 속성 이 있 습 니 다(추상 적 인 기본 클래스 Buffer 에 정의).
  • capacity:데이터 용량,생 성 시 지정,수정 할 수 없습니다
  • limit:현재 조작 모드 에서 의 효과 적 인 종점 위치,즉 조작 은 이 위 치 를 초과 할 수 없다
  • position:다음 작업(읽 기,쓰기)의 위치,제약 position 만족
    4.567918.4.567917.mark:현재 의 position 를 기억 하고 후속 회복(약간 비망록 모델 의 사상)이 준비 되 어 있 습 니 다

  • Buffer 의 디자인 은 성능 을 추구 하기 때문에 인터페이스의 가 독성 이 약간 떨 어 지 므 로 buffer 를 사용 하려 면 내부 구조 와 작업 방식 을 충분히 이해 해 야 합 니 다.
    nio channel
    추상 적 인 IO 읽 기와 쓰기 채널 은 보통 바 텀 스 트림 을 바탕 으로 작업 을 하 는데 자주 사용 되 는 실현 은 FileChannel,DatagramChannel(UDP),ServerSocketChannel,SocketChannel 이다.
    nio selector:
    selector 는 여러 채널 을 관리 하 는데 다 중 재 활용 선택 기 라 고도 합 니 다.채널 에 사건 이 발생 했 을 때 selector 는 그것 을 발견 하고 처리 할 수 있 습 니 다.그래서 한 라인 으로 여러 채널 을 처리 하 는 효과 가 있어 시스템 비용 을 줄 였 다.
    Selector 는 추상 적 인 유형 으로 핵심 적 인 방법 입 니 다.
  • open():정적 공장 방법,선택 기 를 엽 니 다
  • selectXXX():모든 등 록 된 channel 을 감시 하고 사건 발생 여 부 를 확인 합 니 다
  • wakeup():막 힌 selector 를 깨 웁 니 다(예 를 들 어 막 힌 selection 방법 을 호출 했 습 니 다)

  • SelectionKey
    selection Key 는 channel 과 selector 간 의 등록 관 계 를 대표 하여 channel 등록 시 사용자 에 게 만 들 고 되 돌려 줍 니 다.selection Key 내부 에 두 개의 상태 집합(bit 비트 표시)이 있 습 니 다.하 나 는 selector 가 검 측 해 야 할 channel 상태 집합(등록 시 지정)을 대표 합 니 다.selector 를 대표 하 는 현재 ready 채널 상태 입 니 다.채널 마다 지원 하 는 동작 이 다 릅 니 다.
    여기 서 말 하 는'상태'는 channel 이 현재 실행 할 수 있 는 조작 을 말 합 니 다.예 를 들 어'읽 을 수 있 고 쓸 수 있 습 니 다',상태 변 화 는'사건'이 라 고도 부 릅 니 다.따라서 서로 다른 의미 장면 에서'상태','조작','사건'이라는 몇 단 어 는 교체 되 어 사 용 될 수 있다.
    NIO 예시
    자바 니 오의 용법 을 간단 한 메아리 프로그램 으로 보 여 줍 니 다.서버 코드 는 다음 과 같 습 니 다.
    public class NIOServer {
        public static void main(String[] args) throws IOException {
        	  
        	 //  channel,    
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.bind(new InetSocketAddress(6666));
            serverSocketChannel.configureBlocking(false);
    
    		 //  Selector,   channel,    OP_ACCEPT  
            Selector selector = Selector.open();
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    
            while (true) {
                if (selector.select() > 0) {
                    Set selectionKeys = selector.selectedKeys();
                    for (SelectionKey key : selectionKeys) {
                        if (key.isAcceptable()) {
                        	//         
                            ServerSocketChannel channel = (ServerSocketChannel) key.channel();			
                            //    ,   socketChannel   selector
                            SocketChannel clientChannel = channel.accept();
                            clientChannel.configureBlocking(false);
                            clientChannel.register(selector, SelectionKey.OP_READ);
                        } else if (key.isReadable()) {
                        	//           ,     
                            SocketChannel channel = (SocketChannel) key.channel();
                            ByteBuffer buffer = ByteBuffer.allocate(1024);
                            channel.read(buffer);
                            buffer.flip();
    
                            String text = new String(buffer.array(), 0, buffer.limit()).trim();
                            System.out.println("     :" + text);
                            channel.close();
                        }
                    }
                    selectionKeys.clear();
                }
            }
        }
    }
    

    클 라 이언 트 코드 는 다음 과 같 습 니 다.
    public class NIOClient {
        public static void main(String[] args) throws IOException {
        
        	 //    SocketChannel
            SocketChannel clientChannel = SocketChannel.open();
            clientChannel.configureBlocking(false);
    
    		 //     
            InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 6666);
            if (!clientChannel.connect(inetSocketAddress)) {
                while (!clientChannel.finishConnect()) {
                    System.out.println("      ");
                }
            }
    		
    		 //  Selector,   channel,     OP_WRITE(  )  
            Selector selector = Selector.open();
            clientChannel.register(selector, SelectionKey.OP_WRITE);
    
            if (selector.select() > 0) {
                Set selectionKeys = selector.selectedKeys();
                for (SelectionKey key : selectionKeys) {
                    if (key.isWritable()) {
                    		//         
                        SocketChannel channel = (SocketChannel) key.channel();
                        ByteBuffer buffer = ByteBuffer.wrap("Hello Netty".getBytes());
                        channel.write(buffer);
                    }
                }
                selectionKeys.clear();
            }
            clientChannel.close();
        }
    }
    

    우리 가 Netty 를 배 우 는 데 는 먼저 자바 nio 를 완전 하 게 파악 할 필요 가 없 지만 위의 코드 를 볼 수 있 고 자바 nio 의 작업 방식 을 이해 하 는 것 이 필요 합 니 다.

    좋은 웹페이지 즐겨찾기