Dubbo source server Server start of the study notes & Request Handler

 

           To begin, put the overall design a Dubbo official website,

 

A, Server start

     Relying on a unified URL configuration data transfer, extended dynamic loading mechanism, associated with the underlying code is very small. Exchange between the Protocol and the two layers, it is very obvious.

     The dubbo default protocol as an example (each protocol, treatment is not the same, for example httpProtocol start server on simpler). 

     1. Netty4 Server start end, only a code for: server = Exchangers.bind (url, requestHandler); 

       Start Server, just call a static method, passing instantiated ExchangeHandlerAdapter instance requestHandler DubboProtocol class.

       Only a requestHandler reply (ExchangeChannel channel, Object message) method, message is already deserialized Invocation object.

       requestHandler perform two important logic:

     1. The channel data url which acquires Invoker (Invoker is packaged FilterChain filter chain),

     2. Perform invoker calls, access interface service processing results, because Invoker is FilterChain, which will give priority to the implementation of Fitler logic, the last call before the implementation of the final interface logic calls.

    2.  Exchanges.bind()

       Exchanges.bind () one line only the key code, getExchanger (url) .bind (url, handler);

      getExchanger (url) calls: ExtensionLoader.getExtensionLoader (Exchanger.class) .getExtension (type), type is the default header, finally get to HeaderExchanger extension (here without adaptive extension).

  Inside HeaderExchanger the bind method, the handler will be re-packaged, nettyserver listening local port.

      After the code expansion (method calls inside embedded into the front variable, easy to read, understand), as follows:

@Override
    public ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException {
        H of ChannelHandler   = new new DecodeHandler ( new new HeaderExchangeHandler (Handler)); // 1. Handler will again through 2 layers of the packaging, increased functionality 
        Server S = Transporters.bind (URL, H); // 2. Transports action starts listening port netty , realization configuration sequence,
        
        // 3. Return to step on the server netty be established, this packaging again, primarily to increase channel idle detection, detected over a certain period of idle channel, closes 
        return  new new HeaderExchangeServer (S);  
    }

 DecodeHandler: The handler logic is relatively simple, and message content for message identification, extracts the real data of the request, to the subsequent processing handler.   

 HeaderExchangeHandler: processing channel status events, will write the write channel time attribute, for receiving a request filter. Currently just look at the server-side code, based on logic alone, the handler should be also used in netty client response will be processed.

 Transporters.bind () method, starting nettyServer end. The logic behind the large, say the next chapter alone.

 HeaderExchangeServer: will nettyServer packaging, an increase of 2 main functions:

    a. time detection of an idle channel, than it closes the connection to save resources.

    b. If the server is closed, a message is sent to the client to send a request not to the server.

 

Two, nettyServer start 

       Transporters.bind (url, handler), because the default default configuration, eventually to org.apache.dubbo.remoting.transport.netty4.NettyTransporter, direct new NettyServer (url, listener).

      url before the url, listener is above the wrapped handler, followed by the code entered NettyServer.

    public NettyServer (the URL of url, ChannelHandler Handler) throws RemotingException {
         // you CAN Customize Client name and the Thread of the type of the pool by THREAD_NAME_KEY and THREADPOOL_KEY in CommonConstants.
         // at The Handler by Will BE Warped: MultiMessageHandler-> HeartbeatHandler-> Handler 
        Super (url, ChannelHandlers.wrap (handler, ExecutorUtil.setThreadName (url, SERVER_THREAD_POOL_NAME))); // super methods must be on the first line, here not split temporary variables
    }

  1. handler packaging  

NettyServer when you call the super method call ChannelHandlers.wrap method, incoming handler was packed again. code show as below:

protected ChannelHandler wrapInternal(ChannelHandler handler, URL url) {
        return new MultiMessageHandler(new HeartbeatHandler(ExtensionLoader.getExtensionLoader(Dispatcher.class)
                .getAdaptiveExtension () dispatch (handler, url)));. //Dispatch.dispatch () method is actually decorated again to the handler, according to dynamically add new functionality configuration
    }

channelhandler.wrap which will invoke the extension Dispatcher performs dispatch operations, the actual packaging of the handler's dynamic.

  Depending on configuration, handler after the call Dispatch expansion pack is not the same. Defaults AllDispatcher expansion, with AllChannelHandler package once.

  Default configuration, after packaging, the method of passing super package handler chain as follows:

     MultiMessageHandler -> HeartbeatHandler -> AllChannelHandler ->  DecodeHandler ->  HeaderExchangeHandler -> DubboProtocol.requestHandler

    MultiMessageHandler: Check whether the message MutiMessage, if separate single subsequent call handler

    HeartbeatHandler:. 1 operation on each channel, channel marking of time attributes, 2. Check the heartbeat request, the heartbeat is directly returned, subsequent requests do not continue.

    AllChannelHandler: 1. The subsequent handler packaged ChannelEventRunnable, catch exceptions subsequent execution, logging. 2. Packaging runnable thread pool running into independent, asynchronous processes to achieve the full effect.

 

2. codec2 extension implant

    Generating a class diagram NettyServer idea, as follows:  

NettyServer indirect inheritance AbstractEndPoint, in which AbstractEndPoint constructor, calls ExtensionLoader, get Codec2 expansion.

   Codec2 default extension dobbo, is acquired: DubboCountCodec, inside DoubboCountCodec, instantiates DubboCodec, final decoding and encoding operation or DubboCodec.

  DubboCountCodec and DubboCodec involved dubbo communication protocol, this follow-up study carefully.

 Constructor AbstractServer's successor, will call abstract doOpen () method, the actual call doOpen NettyServer of () to open the port to listen.

 

Three,  doOpen start listening port NettyServer

Less doOpen method code, provided mainly NettyServer & startup.

Because netty package, a simple nettyserver start focusing: 1. The message processing handler, 2 & encoded message decoding.

as follows:

@Override
    protected void doOpen() throws Throwable {
        bootstrap = new ServerBootstrap();

        bossGroup = new NioEventLoopGroup(1, new DefaultThreadFactory("NettyServerBoss", true));
        workerGroup = new NioEventLoopGroup(getUrl().getPositiveParameter(IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS),
                new DefaultThreadFactory("NettyServerWorker", true));

        // 1. nettyServerHandler constructor need to pass through the chain packing Handler 
        Final NettyServerHandler nettyServerHandler = new new NettyServerHandler (getUrl (), the this );
        channels = nettyServerHandler.getChannels();

        bootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childOption(ChannelOption.TCP_NODELAY, Boolean.TRUE)
                .childOption(ChannelOption.SO_REUSEADDR, Boolean.TRUE)
                .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        // FIXME: should we use getTimeout()?
                        int idleTimeout = UrlUtils.getIdleTimeout(getUrl());

                        // 2. & encode decode encoded adapter, parent objects need to obtain codec2 injected, 
                        NettyCodecAdapter Adapter = new new NettyCodecAdapter (getCodec (), getUrl (), NettyServer. The this );
                        ch.pipeline () // .addLast ( "the logging", new new LoggingHandler (LogLevel.INFO)) // for Debug 
                                .addLast ( "Decoder", adapter.getDecoder ())   // 3. receive message decoder 
                                .addLast ( "encoder", adapter.getEncoder ()) // encoder 4. send message 
                                .addLast ( "Server-IDLE-Handler", new new IdleStateHandler (0, 0 , the idleTimeout, MILLISECONDS))
                                .addLast ( "Handler", nettyServerHandler); // Handler 5. The message transceiver 
                    }
                });
        // bind
        ChannelFuture channelFuture = bootstrap.bind(getBindAddress());
        channelFuture.syncUninterruptibly();
        channel = channelFuture.channel();
    }

 

1,5 Note, the message handler is instantiated netty provided.

Note 2,3,4, message decoder is netty, Coder provided. In Note 2, the internal NettyCodecAdapter, de-coding will be achieved by means of the incoming Codec2 object.

 

1. Channel processing conversion & 

   NettyServerHandler netty message processing is implemented, in the method channelRead, write, etc. which will be acquired from the actual channel parameters into the data netty ChannelHandlerContext inside converted into Dubbo NettyChannel defined class, performing the corresponding subsequent service operation.

Class FIG follows:

Channel, ChannelHandler is dubbo defined abstract interface.

NettyChannel is a wrapper class that holds the actual data path channel of a netty, while achieving the Dubbo Channel, ChannelHandler abstract interface, which requires the actual channel Handler reads, when data is written, will be achieved by the inside of the channel attribute nettychannel .

NettyChannel is a middle class, there should be a similar MinaChannel, the main function of the underlying transport package implemented, packaged into logical interface frame. The intermediate layer is a spacer.

 

In the above in Note 1., nettyserverhandler initialization of new NettyServerHandler (getUrl (), this), was introduced to nettyserver object. Because nettyserver inherited AbstractPeer, once again considered the package of channelhandler.

So when netty receive the message, NettyServerHandler of channelRead method is called:

  public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);
        try {
            handler.received (Channel, MSG); // actual data transmission channel 1. channel is NettyChannel, which has a netty, 
        } the finally {
            NettyChannel.removeChannelIfDisconnected(ctx.channel());
        }
    }

channelRead method which will get from netty inside the ctx data channel, then the success of nettychannel package, when you call the method nettychannel sent, the subject will be written to the real channel, send!

The method handler inside the object, the chain wraps the call as follows:

NettyServer -> MultiMessageHandler -> HeartbeatHandler -> AllChannelHandler ->  DecodeHandler ->  HeaderExchangeHandler -> DubboProtocol.requestHandler

HeaderExchangeHandler last a whole handler, the method in which it received, will perform handleRequest method, method invocation reply held DubboProtocol.requestHandler, do invoke operations, acquisition method results res, channel.send execution 
method, the result is written res aisle.
Res here is the result of calling, call Netty will encode encoder disposed at startup, sends its target sequence number & encoding.
channel is packaged in HeaderExchangeHandler once inside the ExchangeChannel. channel chain: ExchangeChannel -> NettyChannel



IV Summary 

Dubbo Server startup process, is channel handler layers of packaging. Dubbo decorative patterns, chained calls, throughout the entire process. Invoke, Handler, Channel, etc., are true. Not recorded, very difficult to understand.

The highest level in the handler chain is NettyServerHandler, Channel Netty responsible for the conversion of specific channel and Dubbo framework, different application frameworks transmission, should the existence of such a handler.
At the very bottom handler chain is HeaderExchangeHandler, call Invoke, Filter chain execution, access to services results, writes the result to channel, sent to the client.
In the middle of the handler chain, there will be an extension, AllChannelHandler position. So that users can customize their hannler, to perform specific operations. The default is to follow-up the implementation of AllChannelHandler into the thread pool of asynchronous execution.

Incoming server startup when encoder, decoder, calls codec objects, dynamic access to serialized works, the serial number of the object & coding output.

After recording again, the process more clearly. 

Guess you like

Origin www.cnblogs.com/keep-code/p/11066233.html