• Elasticsearch-HttpServerModule


    HttpServerModule的请求主要由HttpServer中的HttpServerTransport(默认为NettyHttpServerTransport)类处理。

    NettyHttpServerTransport基于netty框架,负责监听并建立连接,信息的处理由内部类HttpChannelPipelineFactory完成。

    每当产生一个连接时,都会发出一个ChannelEvent,该Event由一系列的ChannelHandler进行处理。

    为了方便组织,这些ChannelHandler被放在一条“流(pipeline)”里,一个ChannelEvent并不会主动的”流”经所有的Handler,而是由上一个Handler显式的调用ChannelPipeline.sendUp(Down)stream产生,并交给下一个Handler处理。

    换句话说,每个Handler接收到一个ChannelEvent,并处理结束后,如果需要继续处理,那么它需要调用sendUp(Down)stream新发起一个事件。如果它不再发起事件,那么处理就到此结束,即使它后面仍然有Handler没有执行。这个机制可以保证最大的灵活性,当然对Handler的先后顺序也有了更严格的要求。

    在流Pipeline里有一个Map(name2ctx)和一个链表(记录head和tail),pipeline里面会调度关联的多个channelhandler的运行,这里抄一张图:

    在NettyHttpServerTransport中,会流过的channelhandler就包括解码http请求(把多个HttpChunk拼起来并按http协议进行解析)和http请求处理。

    在处理http请求,数据流向为:HttpRequestHandler-><span class="s1">NettyHttpServerTransport</span>->HttpServerAdapter(HttpServer的内部类Dispatche)->RestController。

    RestController中的处理代码为:

    void executeHandler(RestRequest request, RestChannel channel) throws Exception {
            final RestHandler handler = getHandler(request);
            if (handler != null) {
                handler.handleRequest(request, channel);
            } else {
                if (request.method() == RestRequest.Method.OPTIONS) {
                    // when we have OPTIONS request, simply send OK by default (with the Access Control Origin header which gets automatically added)
                    channel.sendResponse(new BytesRestResponse(OK));
                } else {
                    channel.sendResponse(new BytesRestResponse(BAD_REQUEST, "No handler found for uri [" + request.uri() + "] and method [" + request.method() + "]"));
                }
            }
        }
    
        private RestHandler getHandler(RestRequest request) {
            String path = getPath(request);
            RestRequest.Method method = request.method();
            if (method == RestRequest.Method.GET) {
                return getHandlers.retrieve(path, request.params());
            } else if (method == RestRequest.Method.POST) {
                return postHandlers.retrieve(path, request.params());
            } else if (method == RestRequest.Method.PUT) {
                return putHandlers.retrieve(path, request.params());
            } else if (method == RestRequest.Method.DELETE) {
                return deleteHandlers.retrieve(path, request.params());
            } else if (method == RestRequest.Method.HEAD) {
                return headHandlers.retrieve(path, request.params());
            } else if (method == RestRequest.Method.OPTIONS) {
                return optionsHandlers.retrieve(path, request.params());
            } else {
                return null;
            }
        }

    可以看到,这里会根据注册的handler,选择合适的处理逻辑。

    这些handler由函数registerHandler进行注册,函数签名如下:

    public void registerHandler(RestRequest.Method method, String path, RestHandler handler)

    比如对RestGetIndicesAction类,有如下构造函数:

    public RestGetIndicesAction(Settings settings, RestController controller, Client client) {
            super(settings, controller, client);
            controller.registerHandler(GET, "/{index}", this);
            controller.registerHandler(GET, "/{index}/{type}", this);
    }

    netty参考:

    http://my.oschina.net/flashsword/blog/162936

    http://my.oschina.net/flashsword/blog/164237

    http://my.oschina.net/flashsword/blog/169361

    http://my.oschina.net/flashsword/blog/178561

    http://my.oschina.net/flashsword/blog/197963

  • 相关阅读:
    angular笔记_6
    angular笔记_5(全选/反选)
    angular笔记_4(函数)
    angular笔记_3
    angular笔记_2
    常用Sql语句
    IIS服务器环境下某路径下所有PHP接口无法运行报500.19错误
    #前端#文字、图像等元素居中方式之
    nginx如何设置禁止访问文件或文件夹
    git克隆和上传项目
  • 原文地址:https://www.cnblogs.com/luosha/p/3034078.html
Copyright © 2020-2023  润新知