为什么 Flask 不使用 HttpURLConnection 与来自 Java 应用程序的多个请求建立持久的 HTTP 连接?

问题描述 投票:0回答:1

我有一个小项目,它将涉及 Java 应用程序和 Flask Web 服务器之间的重复 HTTPS 通信,因此保持 TCP 连接有效很重要。为了测试和了解这些技术的功能,我设置了一个简单的 GET 请求生成器,它将多个带有时间倒数的 GET 请求发送到我的简单 Flask Web 服务器应用程序并返回响应。在这样的设置中,我希望缓存 TCP 连接,但我认为我的 Flask 应用程序会在每次响应后断开连接。请注意,我对 Java 很生疏,这是我第一次熟悉 Flask。

我的 Java GET 请求生成器如下所示:

package com.deu;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class Main {

    public static void main(String[] args) {
        try {
            sendHttpRequests("http://127.0.0.1:5000", 1000, 5);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void sendHttpRequests(String url, int interval, int count) throws IOException, InterruptedException {
        URL hostURL = new URL(url);

        for (int i = 0; i < count; i++) {
            HttpURLConnection httpConn = (HttpURLConnection) hostURL.openConnection();
            httpConn.setRequestMethod("GET");

            BufferedReader reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
            StringBuilder response = new StringBuilder();
            String line;

            while ((line = reader.readLine()) != null)
                response.append(line);

            System.out.println("Response to i="+i+" "+response.toString());
            reader.close();

            Thread.sleep(interval);
        }
    }

}

我的 Flask Web 服务器应用程序如下所示:

import flask
from flask import Flask, request
from werkzeug.serving import WSGIRequestHandler

app = Flask(__name__)


@app.route('/', methods=['GET'])
def hello_world():
    resp = flask.Response("Hello World!")
    print(request.headers)
    print(resp.headers)

    return resp


if __name__ == '__main__':
    WSGIRequestHandler.protocol_version = "HTTP/1.1"
    app.run()

Java 应用程序终止后,我得到的 Java 和 Flask 应用程序的输出分别是:

Response to i=0 Hello World!
Response to i=1 Hello World!
Response to i=2 Hello World!
Response to i=3 Hello World!
Response to i=4 Hello World!
FLASK_APP = app.py
FLASK_ENV = development
FLASK_DEBUG = 0
In folder B:/Development/Projects/Python/ProjectABC
B:\Development\Projects\Python\ProjectABC\venv\Scripts\python.exe -m flask run
 * Serving Flask app 'app.py'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit
User-Agent: Java/17.0.1
Host: 127.0.0.1:5000
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive


Content-Type: text/html; charset=utf-8
Content-Length: 12


127.0.0.1 - - [08/Apr/2023 01:26:28] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [08/Apr/2023 01:26:29] "GET / HTTP/1.1" 200 -
User-Agent: Java/17.0.1
Host: 127.0.0.1:5000
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive


Content-Type: text/html; charset=utf-8
Content-Length: 12


User-Agent: Java/17.0.1
Host: 127.0.0.1:5000
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive


Content-Type: text/html; charset=utf-8
Content-Length: 12


127.0.0.1 - - [08/Apr/2023 01:26:30] "GET / HTTP/1.1" 200 -
User-Agent: Java/17.0.1
Host: 127.0.0.1:5000
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive


Content-Type: text/html; charset=utf-8
Content-Length: 12


127.0.0.1 - - [08/Apr/2023 01:26:31] "GET / HTTP/1.1" 200 -
User-Agent: Java/17.0.1
Host: 127.0.0.1:5000
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive


Content-Type: text/html; charset=utf-8
Content-Length: 12


127.0.0.1 - - [08/Apr/2023 01:26:32] "GET / HTTP/1.1" 200 -

可以看出,请求收到了预期的响应,甚至 Flask 应用程序收到的请求标头也显示了

Connection: keep-alive
的存在。但我认为每次都会创建一个新的 TCP 连接的原因是响应标头不包含
Connection: keep-alive
netstat
cmd 命令的输出:

Active Connections

  Proto  Local Address          Foreign Address        State
  TCP    127.0.0.1:5000         DESKTOP-XXXXXXX:52821  TIME_WAIT
  TCP    127.0.0.1:5000         DESKTOP-XXXXXXX:52823  TIME_WAIT
  TCP    127.0.0.1:5000         DESKTOP-XXXXXXX:52824  TIME_WAIT
  TCP    127.0.0.1:5000         DESKTOP-XXXXXXX:52830  TIME_WAIT
  TCP    127.0.0.1:5000         DESKTOP-XXXXXXX:52831  TIME_WAIT

如果我对输出的理解是正确的(如果我错了请纠正我),建立了 5 个不同的 TCP 连接,现在操作系统正在等待清除它们,这表明

keep-alive
失败了。我搜索了其他问题的答案并尝试输入
WSGIRequestHandler.protocol_version = "HTTP/1.1"
但无济于事。

注意:我尝试先使用HTTP实现持久连接,之后再应用到HTTPS。

java flask httpurlconnection keep-alive persistent-connection
1个回答
0
投票

我一直在尝试使用 WSGI 服务器 Flask 与 Werkzeug 一起打包来实现持久连接。当我切换到部署 WSGI 服务器时,在我的例子中是 Waitress,

keep-alive
开始工作并且 TCP 连接停止被丢弃。这个问题是由 Werkzeug 实施的变化引起的。他们在 2022-04-28 发布的
Version 2.1.2
变更日志指出:

在开发服务器中禁用保持活动连接,Python 的

http.server
对此支持不足。 #2397

Werkzeug 团队删除了持久连接支持,因为它扩展了

http.server
的缺点。虽然可以理解缺少
keep-alive
功能在开发环境中可能不是必需的,但令人沮丧的是,在 Internet 上几乎没有关于此的交流。

© www.soinside.com 2019 - 2024. All rights reserved.