반응 기 모드

리 트 윗 reactor 모드
reactor 모델 에 대한 이해.
reactor 디자인 모델: 이벤트 구동 을 바탕 으로 하 는 디자인 모델 입 니 다.현 재 는 주로 reactor 디자인 모델 에 대해 네트워크 프로 그래 밍 을 사용 하기 때문에 reactor 의 주요 사건 은 연결, 수용, 읽 기, 쓰기 등 네 가지 사건 유형 으로 나 뉜 다.물론 reactor 는 이벤트 구동 외 에 도 폴 링 선택 기 가 있 습 니 다. 어떤 파일 이 어떤 상태 에 있 는 지 확인 하 는 것 입 니 다.또는 어떤 채널 이 어떤 상태 에 있 는 지 확인 하고 이 상 태 를 선택 기의 대기 열 에 넣 습 니 다.마지막 으로 reactor 배포 기 는 구체 적 인 이벤트 유형 에 따라 스케줄 러 배포 로 구체 적 인 실행 작업 을 수행 합 니 다.다음은 구체 적 인 코드 에 대한 분석 이다.
우선 reactor 클래스 분석 (구성 요소)
    class Reactor implements Runnable
{
    //   :
        /**
         Selector        。
        abstract class Selector {
         static Selector open() throws IOException;
         Set keys();
         Set selectedKeys();
         int selectNow() throws IOException;
         int select(long timeout) throws IOException;
         int select() throws IOException;
         void wakeup();
         void close() throws IOException;
  } */
  
    //       
    final Selector selector;

   //       serverSocket;
    final ServerSocketChannel serverSocket;

   //           。
    Reactor(int port) throws IOException
    { //Reactor   
         //        
        selector = Selector.open();
        //         
        serverSocket = ServerSocketChannel.open();
        //         
        serverSocket.socket().bind(new InetSocketAddress(port));
        //            。     ,          ,          。
        serverSocket.configureBlocking(false);

        //    ,   ,  accept  ,          。                。           
        //        。
        SelectionKey sk =
                serverSocket.register(selector, SelectionKey.OP_ACCEPT);
        //attach callback object, Acceptor
        //     ,         ,          (      ,        ,      ,         ,     )
        sk.attach(new Acceptor());
        //                 。
    }

    public void run()
    {
    //     ,run()       
        try
        {
            while (!Thread.interrupted())
            {
               //select             ,            
                selector.select();
                //    ,         
                Set selected = selector.selectedKeys();
                //       
                Iterator it = selected.iterator();
                while (it.hasNext())
                {
                    //Reactor  dispatch     ,          handle   。
                    dispatch((SelectionKey) (it.next()));
                }
                selected.clear();
            }
        } catch (IOException ex)
        { /* ... */ }
    }

    void dispatch(SelectionKey k)
    {
       //        handler 
        Runnable r = (Runnable) (k.attachment());
        //       callback  
        if (r != null)
        {
            r.run();
        }
    }

    // inner class
    class Acceptor implements Runnable
    {
        public void run()
        {
            try
            {
              //       ,       serverSocket      。
                SocketChannel channel = serverSocket.accept();
                if (channel != null)
                    new Handler(selector, channel);
            } catch (IOException ex)
            { /* ... */ }
        }
    }
}

/ / 여기 서 Handler 류 를 분석 합 니 다.
class Handler implements Runnable
{
    final SocketChannel channel;
    final SelectionKey sk;
    ByteBuffer input = ByteBuffer.allocate(SystemConfig.INPUT_SIZE);
    ByteBuffer output = ByteBuffer.allocate(SystemConfig.SEND_SIZE);
    static final int READING = 0, SENDING = 1;
    int state = READING;

    Handler(Selector selector, SocketChannel c) throws IOException
    {
        channel = c;
        c.configureBlocking(false);
        // Optionally try first read now
        sk = channel.register(selector, 0);

        // Handler  callback  
        sk.attach(this);

        //   ,  Read    
        sk.interestOps(SelectionKey.OP_READ);
        //       ,   run  ,          。             ,OP_READ        handle  。    Acceptor   run()   。
        selector.wakeup();
    }

    boolean inputIsComplete()
    {
        /* ... */
        return false;
    }

    boolean outputIsComplete()
    {

        /* ... */
        return false;
    }

    void process()
    {
        /* ... */
        return;
    }

    public void run()
    {
        try
        {
            if (state == READING)
            {
                read();
            }
            else if (state == SENDING)
            {
                send();
            }
        } catch (IOException ex)
        { /* ... */ }
    }

    void read() throws IOException
    {
        channel.read(input);
        if (inputIsComplete())
        {

            process();

            state = SENDING;
            // Normally also do first write now

            //   ,  write    
            sk.interestOps(SelectionKey.OP_WRITE);
        }
    }

    void send() throws IOException
    {
        channel.write(output);

        //write     ,   select key
        if (outputIsComplete())
        {
            sk.cancel();
        }
    }
}

위 는 주로 reactor 의 단일 스 레 드 모드 입 니 다. 단일 스 레 드 모드 가 모드 가 아니 어야 합 니 다. 스 레 드 가 데 이 터 를 처리 할 때 (process () 가 막 히 면 뒤의 연결 이 들 어가 지 못 하고 뒤의 연결 이 실 패 됩 니 다.따라서 reactor 단일 스 레 드 는 높 은 병행 상황 에서 사용 하지 않 는 다.
그 다음 에 reactor 다 중 스 레 드 모델 을 고려 하 겠 습 니 다. 다 중 스 레 드 모델 은 데 이 터 를 처리 하 는 데 다 중 스 레 드 처 리 를 하 는 것 입 니 다. 그러면 스 레 드 가 막 히 지 않 습 니 다.다음 코드 는 단일 스 레 드 의 Handle 류 를 바탕 으로 수정 되 었 습 니 다.
synchronized void read() throws IOException
    {
        // ...
        channel.read(input);
        if (inputIsComplete())
        {
            state = PROCESSING;
            //    pool    
            pool.execute(new Processer());
        }
    }

다 중 스 레 드 처 리 는 후속 Handle 처리 과정 에서 의 차단 문제 만 해 결 했 습 니 다. 그러나 Reactor 의 메 인 스 레 드 가 연결 을 받 아들 이 느 냐, 단일 연결 을 받 아들 이 느 냐, 높 은 병행 또는 연결 을 받 아들 이 는 과정 에서 어떤 안전 인증 처 리 를 해 야 하 느 냐 에 따라 연결 이 막 힐 수도 있 습 니 다. 이 럴 때 Reactor 도 여러 스 레 드 를 열 어야 합 니 다.그럼 마지막 으로 Reactor 는 스 레 드 그룹 으로 바 뀌 었 습 니 다.
main 방법 이 실행 되 었 는데 도 프로 세 스 가 종료 되 지 않 았 습 니 다. 그것 은 스 레 드 탱크 의 하위 스 레 드 안의 작업 스 레 드 가 차단 대기 열 에서 데 이 터 를 가 져 올 때 데 이 터 를 가 져 갈 수 없 기 때 문 입 니 다. 데이터 가 있 기 를 기다 리 고 있 기 때 문 입 니 다.데 이 터 를 받 은 후에 작업 스 레 드 를 제외 하고 다시 가 져 갑 니 다. 이렇게 순환 하면 작업 스 레 드 가 죽지 않 고 프로 세 스 도 죽지 않 습 니 다.
NGINX 의 백만 연결 에 대한 링크 설명 추가
리 액 터 모드

좋은 웹페이지 즐겨찾기