JAVA NIO 사용 소감

15368 단어 프로젝트 경험
이전에 접 한 항목 은 tcp / ip 가 상위 기기 에 대한 데이터 감청 입 니 다. 전통 적 인 바 이오 방식 을 사용 하기 시 작 했 지만 ip 수량 이 너무 많아 socket 연결 No 가 자주 발생 합 니 다. buffer space 사용 가능 한 문제 로 인터페이스 대면 적 호출 (웹 서비스, httpclient) 이 실 패 했 고 서버 를 다시 시작 한 후 정상 으로 돌 아 왔 습 니 다.오 류 는 다음 과 같 습 니 다. Caused by: java. net. SocketException: No buffer space available (maximum connections reached?):connect。나중에 대기 열 을 사용 하 는 방식 을 개선 한 결과 오래 버 티 지 못 하고 똑 같은 오류 가 발생 할 수 있 음 을 발견 했다.나중에 NIO 를 사용 하 는 이 유 는 nio 의 메커니즘 이 동기 화 비 차단 이 고 연결 수량 이 많 으 며 연결 이 비교적 짧 은 구조 에 적용 되 기 때 문 이 라 고 생각 했다.
먼저 BIO, NIO, AIO 를 비교 해 보 겠 습 니 다.
BIO (IO) 동기 화 차단, 전통 io 방식.연결 수량 이 비교적 작고 고정된 구조 에 적용 되 는데 이런 방식 은 서버 자원 에 대한 요구 가 비교적 높 고 병발 은 응용 에 국한 된다.NIO 동기 화 비 차단, jdk 4 지원 시작.연결 수량 이 많 고 연결 이 비교적 짧 은 구조, 예 를 들 어 채 팅 서버 에 적용 된다.AIO 비동기 비 차단, jdk 7 지원 시작.연결 수량 이 많 고 연결 이 비교적 긴 구조 에 적용 된다.이미지 의 이해 NIO 와 AIO: 커 널 을 배달 에 비유 하면 NIO 는 배달 이 아래층 에 도 착 했 는 지 확인 하고 택 배 를 찾 으 러 가 는 것 이다.에 이 오 는 배달 원 이 집 까지 배달 해 줬 어 요.
프로젝트 코드 는 다음 과 같 습 니 다.
public boolean processData() throws Exception {
   logger.info("processData....Start...");

   initQueue();

   logger.info("  selector  ");

   Thread t = new Thread(new Runnable() {
      @Override
      public void run() {

         Selector selector = null;
         try {
            selector = Selector.open();

            for (String serverIP : ipSet) {

               
               SocketChannel sChannel = createSocketChannel(serverIP, 8000);
               //            (                 ) validOps:       ,           。
               //SelectionKey.validOps  
               SelectionKey key = sChannel.register(selector, sChannel.validOps());
               System.out.println("CreateSocketChannel ip:" + serverIP + " SelectionKey:" + key);
               // SocketChannel Selector        map
               selKeyMap.put(key, serverIP);

               
            }

            logger.info("processData....End...");

            //        
            while (true) {
               logger.info("loading...");
               try {
                  //                        
                  selector.select();
               } catch (IOException e) {
                  logger.error("select   ");
                  e.printStackTrace();
               }
               //          selectionKey        
               Iterator it = selector.selectedKeys().iterator();
               //        
               while (it.hasNext()) {
                  //      
                  SelectionKey selKey = it.next();
                  //           
                  try {
                     //     
                     processSelectionKey(selKey);
                  } catch (IOException e) {
                     //     
                     // selKey.cancel();
                     logger.error("    ,key:" + selKeyMap.get(selKey));
                     e.printStackTrace();
                  }
                  //    key                  it.remove();

                  
               }

               //     1  
               try {
                  Thread.sleep(1000);
               } catch (InterruptedException e) {
                  e.printStackTrace();
               }
            }

            

         } catch (IOException e) {
            e.printStackTrace();
         } finally {
            try {
               if (selector != null) {
                  selector.close();
               }
               // if (ssc != null) {
               // ssc.close();
               // }
            } catch (IOException e) {
               e.printStackTrace();
            }
         }

      }
   });
   t.setDaemon(true);
   t.start();

   //          
   Timer heartBeatTimer = new Timer();
   TimerTask heartBeatTimerTask = new TimerTask() {
      @Override
      public void run() {
         logger.info("heartBeatTimerTask timer");
         logger.info("selKeyMap size is " + selKeyMap.size());
         for (SelectionKey key : selKeyMap.keySet()) {
            try {
               
               SocketChannel channel = (SocketChannel) key.channel();
               heartBeat.clear();
               byte value = (byte)0x7e;
               heartBeat.put(value);
               heartBeat.put(value);
               heartBeat.flip();
               if (key.isValid() && key.isWritable()) {
                  channel.write(heartBeat);
               }                 
            }
            catch (Exception e) {
               logger.info(e.getMessage());
               e.printStackTrace();
            }
         }
      }
   };
   //   10        
   heartBeatTimer.schedule(heartBeatTimerTask, 10000, 10000);
   
   

   return true;
}

좋은 웹페이지 즐겨찾기