Python 多线程服务器和与 Android 客户端的异步 websocket 通信

Posted

技术标签:

【中文标题】Python 多线程服务器和与 Android 客户端的异步 websocket 通信【英文标题】:Python multithreaded server and asynchronuous websocket communication with Android clients 【发布时间】:2019-02-19 11:26:56 【问题描述】:

我有一个 android 客户端应用程序,它将一些数据发送到 Python 中的服务器,Python 服务器应该运行一个耗时的操作/计算并将结果返回给客户端。

为此,我最初开始在服务器端使用 Flask 和 Python,并在客户端使用 asynchronous android http library 通过 http POST 发送数据。但是,我很快注意到这不是要走的路,因为服务器上的计算需要时间,这会导致客户端出现超时错误等问题。

然后,我开始在服务器端使用Tornado's Websockets,在客户端使用android library for websockets。但是,第一个主要问题是,当服务器为给定客户端运行耗时操作时,其他潜在客户端需要等待……而且让 tornado 在多线程中工作似乎有点痛苦设置(因为它最初计划是单线程的)。另一个小问题是,如果客户端在服务器处理他的请求时离线,那么客户端在连接回来时可能永远不会得到结果。

因此,我想问一下,如果我想对异步多线程 Python 服务器进行这样的设置,该服务器应该使用来自没有让其他潜在客户等待轮到他们的客户;并可能使客户端在连接回来时能够从服务器获取结果。

【问题讨论】:

【参考方案1】:

首先,如果您要在后端执行cpu-heavy 操作,您[很可能] 需要在单独的进程 中运行它。不在线程/coro/等中。原因是 python 有时仅限于单线程(您可以阅读有关GIL 的更多信息)。在多线程中执行 cpu-heavy 操作可为您的后端提供一些可用性,但会影响整体性能。

    对此的简单/旧解决方案 - 在多个进程(最好是线程)中运行您的后端。 IE。使用gunicorn 部署您的烧瓶,为其提供多个工作进程。这样,您将拥有能够进行number_of_processes - 1 繁重计算的系统,并且仍可用于处理请求。进程限制通常高达cpu_cores * 2,具体取决于 CPU 架构。

    稍微复杂一点:

    接受数据 在不同的进程中运行繁重的函数 收集结果,返回

    这个很好的界面是ProcessPoolExecutor。缺点是——处理失败/进程挂起更难

    另一种方法是任务队列+工人。最常用的一种是celery。想法是

    打开 WS 连接 将任务放入队列 worker(在不同的进程甚至不同的物理节点)最终拿起任务,计算它,把结果放到一些数据库中 主进程获取回调/长轮询结果数据库的结果 主进程通过 WS 发送结果

    这更适合真正繁重而非实时的任务,但为您提供开箱即用的故障/重启/等处理。

【讨论】:

以上是关于Python 多线程服务器和与 Android 客户端的异步 websocket 通信的主要内容,如果未能解决你的问题,请参考以下文章

C#多线程之旅——介绍和基本概念

python笔记9-多线程Threading之阻塞(join)和守护线程(setDaemon)

牛客每日一题 和与或 数位dp+状态压缩

android AsyncTask 怎么返回值给UI线程

使用 Python 全栈打造淘宝客微信机器人(上)

CPU上下文