我也是一个后端开发,但是做的都是和客户端直接建立长连接的,例如 TCP 或者 Web socket 。所以对 HTTP 的服务端的实现方式有点好奇。
主要问题在于,如果一个 HTTP 请求是需要去数据库取数据的或者耗时较长的,那么服务器怎么异步的处理这个请求呢?还是说不管请求是什么类型的,都同步的处理完,然后再返回?
举个栗子:
客户端发起登录,服务器收到请求需要去数据库中获取玩家数据。
对于长链接,可以在收到客户端请求之后,发起数据库操作,流程就此中止,服务器可以在此时处理其他请求,异步等数据库返回结果,再回调完成登录的后续处理,返回给客户端下行协议。
HTTP 好像不能把请求缓存起来,等待后边数据库触发之后再处理。是可以缓存再处理而我不知道呢?还是大家用 Redis 等查询耗时低的数据库解决呢?
纯小白,还请大家不吝赐教去。
1
lidongyo 2021-03-10 16:38:45 +08:00
所以类似场景都一般不用 HTTP
|
2
fireleaves OP @lidongyo 那对于网站来说,像登录这种请求,都是先建立好长链接吗? Web socket ?
|
3
j0hnj 2021-03-10 16:40:19 +08:00
这种一般是先请求创建一个任务,服务端返回一个任务 ID,之后客户端轮询这个任务 ID,直到任务完成
|
4
fireleaves OP @j0hnj 牛啊,这种方式可以的
|
6
hello2060 2021-03-10 16:50:15 +08:00 via iPhone
@fireleaves 登录应该就是同步的啊,登陆能用多久,没有异步的登录吧
|
7
clayyj1210 2021-03-10 16:51:52 +08:00
你可以从长连接的角度来看 HTTP,每次 HTTP 请求①相当于长连接中的客户端请求,HTTP 请求到服务器端之后流程中止,中止之后(如果业务场景允许,就是等待长时间的操作;如果业务场景不允许,那可能就是返回失败或者采用别的方式如 Redis 来减小时间)。
这时候客户端可以发起其它的 HTTP 请求②,不过这两个 HTTP 请求是相互独立的,没有采用相同的 TCP 链接。 当前面的中止结束之后,通过 HTTP 请求①链接将数据返回。 HTTP 请求②的处理同理返回。 |
8
fireleaves OP @lidongyo 我是真的不懂呀,不知道网站那种的 HTTP 请求是怎么实现的
|
9
fireleaves OP @clayyj1210 理解了,就是类似于#4 的那种任务 ID,不断轮询,直到服务器完成的时候在某次的轮询中下行结果
|
10
baiyi 2021-03-10 17:05:34 +08:00 2
对于 HTTP 协议本身来说是有异步这个响应结果的,它的 202 Accepted 状态码的响应就是告诉客户端请求已经接受了,但还没有处理,并且不保证在处理的过程中是否一定能成功。
从这个角度来说,只用 HTTP 就需要服务端再提供一个查询的接口,客户端在请求结束后不断的查询请求的处理状态。 还有一种情况是你的处理结果可以分批次传输,比如去数据库读取数据需要较长时间,那么就分别读取,分批次交给客户端,这时是可以在一个 HTTP 连接中完成的,通过 chunked 传输编码,让客户端和服务端保持长连接。 |
11
kikione 2021-03-10 17:35:52 +08:00
异步的话,不是应该有个回调地址么
|
12
yamasa 2021-03-10 17:39:39 +08:00
楼上哥们儿说的很好了。我们的服务里 chunked transfer encoding 和异步接口轮询两种做法都涉及了。
|
13
acmore 2021-03-10 17:54:11 +08:00
一种简单的异步任务 HTTP 请求方案:
1. 第一次请求返回 202 Accepted 和一个 Job ID; 2. 之后轮询这个 Job ID,直到拿到结果为止; |
14
YokitCoder 2021-03-10 17:59:07 +08:00
HTTP 一般不处理耗时较长的请求,非要处理一个是可以采用 redis 缓存加快查询结果,另一个就是借助 js 的 ajax 异步处理。
|
15
ikas 2021-03-10 19:11:26 +08:00
依赖的是操作系统 IO 的支持,想真的搞明白就看下 IO 模型,http 只不过是个上层应用协议
|
16
also24 2021-03-10 19:41:27 +08:00 via Android
关键词:
1 、长连接 2 、轮询 3 、长轮询 |
17
FucUrFrd 2021-03-10 21:48:48 +08:00 via Android
Oltp 大部分 200ms 以下,而 http nginx 尽量配成 10s 超时
|
18
fireleaves OP @baiyi 感谢
|
19
fireleaves OP @also24 老哥稳,我去了解一下。
|
20
laowudxf 2021-03-11 08:43:04 +08:00
比如我用 php 开发后台,就比较简单了,php-fpm 有个连接池,比如可以同时处理 10 个请求,其他的框架的话我知道有些是非阻塞类型的框架这种阻塞操作也不会影响下一个请求。
|
21
wangritian 2021-03-11 10:05:52 +08:00
http 本质是一来一回的 tcp 包,访问数据库或其他 IO 操作时一般会切换线程 /转让协程,让服务器同时处理其他请求,拿到 IO 结果再给客户端返回 tcp 包
|
22
mmdsun 2021-03-11 12:46:47 +08:00 via Android
了解下 SSE(Sever-Sent Event)
|
23
muzuiget 2021-03-11 13:50:37 +08:00
HTTP 也可以长时间等待,没说一定要马上返回,一样可以做长时间请求。
说白了你要做到在呈现在用户界面这一层,不要样用户有“卡住”的感觉,服务端和客户端做都行,但是客户端责任更大,毕竟服务器挂掉时,也是相当于一次长时间请求。 |