actix http消息处理源码剖析

发布于:2022-12-30 ⋅ 阅读:(246) ⋅ 点赞:(0)

之前的文章中我们小小地剖析了一下actix中websocket的处理流程:actix websocket消息处理流程源码剖析_聆听--风雨的博客-CSDN博客_actix

本文以官方示例https://github.com/actix/examples/blob/master/basics/hello-world/src/main.rs入手,剖析一下http消息的处理流程。

main函数很简单,就是实例化一个 HttpServer然后bind一个地址,然后run

bind 可以接受多个地址,里面做了socket的listen操作,并且为每个socket对应一个StreamNewService

actix-server --> builder.rs -->listen

 HttpServer.run里面是将上一步的socket开始accept:

actix-server --> server.rs -->ServerInner --> run_async

Accept::start里做了两件事情:【1】根据线程数配置开启多个ServerWorker【2】开一个线程不断的poll socket,也就是接收链接。

 actix-server --> accept.rs -->start

先来看poll_with,里面就是不断的建立链接,然后采用某种负载均衡策略,均衡地将链接send到各个worker中。

actix-server -->accept.rs --> poll_with

 actix-server -->accept.rs --> accept

 actix-server -->accept.rs --> accept_one

再回过头来worker里做了什么。woker里就是开启一个线程,然后不断的poll自己。

 actix-server -->worker.rs -->start

woker的poll方法里就是recv到链接,然后将链接作为参数call到service中。 

actix-server --> worker.rs -->poll

虽然这里的service还不是HttpService,但是经过层层的call,这些参数就会call到HttpService

HttpService的call方法中会根据不同的协议new不同的HttpServiceHandlerResponse,HttpServiceHandlerResponse时一个future可以被wait,即可以被poll。这里以http1为例:实际上就是把各种参数传递给了Dispatcher。而后,所有这个链接上的读数据-->处理数据-->返回数据都是再Dispatcher中做的。

 我们看dispatcher中的poll方法,里面会不断地从链接中读取数据,编码成请求,处理请求,得到响应,再编码响应,再发送响应。其中从io上读写数据都是由缓存的,目前版本读缓存为128k,写缓存为32k。

 

官方的这张图也清晰地描述了http消息处理的流程。结合流程图再看代码会更容易些。

 

参考:   HTTP Server Initializationhttps://actix.rs/docs/http_server_init/ 

总结:actix的代码难读主要是里面运用了大量的future和stream,如果对异步不熟悉的话,里面poll来poll去的逻辑的确是比较难看懂的。

本文含有隐藏内容,请 开通VIP 后查看