简体   繁体   English

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

[英]Python multithreaded server and asynchronuous websocket communication with Android clients

I have an Android client app that sends some data to a server in Python, where the Python server is supposed to run a long time-consuming operation/computation and return the results to the client. 我有一个Android客户端应用程序,该应用程序将一些数据发送到Python中的服务器,在该服务器中,Python服务器应运行耗时的操作/计算并将结果返回给客户端。

To do so, I initially started using Flask with Python on the server side, and an asynchronous android http library on the client side to send the data via http POST. 为此,我最初在服务器端开始使用Flask和Python,并在客户端开始使用异步android http库 ,以通过http POST发送数据。 However, I quickly noticed that this is not the way to go, because the computation on the server takes time which causes problems such as the client getting timeout errors ... etc. 但是,我很快注意到这不是可行的方法,因为服务器上的计算需要时间,这会导致诸如客户端出现超时错误等问题。

Then, I started using Tornado's Websockets on the server side, and an android library for websockets on the client side. 然后,我开始在服务器端使用Tornado的Websockets ,并在客户端使用用于websocketsandroid库 However, the first main problem is that when the server is running the time-consuming operation for a given client, the other potential clients need to wait ... and it seems a bit of a pain to make tornado work in a multi-threaded setting (as it is originally planned to be single-threaded). 但是,第一个主要问题是,当服务器为给定客户端运行耗时的操作时,其他潜在客户端需要等待……让龙卷风在多线程中工作似乎有些痛苦设置(因为最初计划是单线程的)。 Another minor problem, is if the client goes off-line while the server is processing his request, then the client might never get the result when he connects back. 另一个小问题是,如果客户端在服务器处理其请求时脱机,则客户端重新连接时可能永远无法获得结果。

Therefore, I would like to ask if you have any solutions or recommendation on what to use if I want to have such a setting with an asynchronous multi-threaded Python server who is supposed to do heavy-cpu computations with data from a client without making the other potential clients wait for their turn; 因此,我想问一下,如果我想对异步多线程Python服务器进行这样的设置,而该服务器应该使用来自客户端的数据进行大量cpu计算而又不做任何事情,那么您是否对使用什么有任何解决方案或建议?其他潜在客户等待轮到他们; and potentially making the client able to get the result from the server when he connects back. 并可能使客户端在重新连接时能够从服务器获取结果。

FIrst of all, if you're going to do cpu-heavy operations in your backend, you [most probably] need to run it in separate process . 首先,如果要在后端执行大量CPU操作,则[最有可能]您需要在单独的进程中运行它。 Not in thread/coro/etc. 不在thread / coro / etc中。 The reason is that python is limited to single thread at time (you may read more about GIL ). 原因是python一次只限于单线程(您可以阅读有关GIL的更多信息)。 Doing cpu-heavy operation in multithreading gives your backend some availability, but hits performance overall. 在多线程中执行大量CPU操作会为后端提供一些可用性,但会影响整体性能。

  1. Simple/old solution for this — run your backend in multiple process (and threads, preferably). 简单/旧的解决方案-在多个进程(最好是线程)中运行后端。 Ie deploy your flask with gunicorn , give it multiple worker processes. 也就是说,将您的烧瓶与gunicorn一起部署 ,为它分配多个工作进程。 This way, you'll have system that capable of doing number_of_processes - 1 heavy computations and still be available for handling requests. 这样,您将拥有能够执行number_of_processes - 1繁重计算并且仍然可用于处理请求的系统。 Limit for processes is usually up to cpu_cores * 2 , depending on cpu arch. 进程的限制通常最多为cpu_cores * 2 ,具体取决于cpu cpu_cores * 2

  2. Slightly more complicated: 稍微复杂一点:

    • accept data 接受数据
    • run heavy function in different process 在不同的过程中运行繁重的功能
    • gather result, return 收集结果,返回

    Great interface for this would be ProcessPoolExecutor . 很好的接口是ProcessPoolExecutor The drawback is — it's harder to handle failures/process hanging over 缺点是-更难处理失败/挂起的流程

  3. Another way around is task queue + workers. 另一种解决方法是任务队列+工作者。 One of most used is celery . celery是最常用的一种。 Idea is to 想法是

    • open WS connection 打开WS连接
    • put task in queue 将任务放入队列
    • worker (in different process or even different physical node) eventually picks up task, compute it, put result in some DB 工作人员(在不同的流程甚至不同的物理节点中)最终选择任务,对其进行计算,并将结果放入某个数据库中
    • main process gets callback/result of long polling over result DB 主进程获取对结果数据库的长时间轮询的回调​​/结果
    • main process sends result over WS 主流程通过WS发送结果

    This is more suited for really heavy and not real-time tasks, but gives you out-of-the-box handling for failures/restarts/etc. 这更适合真正繁重而不是实时的任务,但是可以为您提供开箱即用的故障/重启/等处理功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM