我有一个基于烧瓶的 Web 应用程序,客户端发送 POST 请求以提交图像以在其上运行 YOLO。然后,客户端定期发送 GET 请求以获取分类结果。
我能够在不使用任何 docker 的情况下运行代码。但是,当我尝试在 docker compose 内部运行时,我的工作人员无法工作。这是 docker-compose 文件:
version: "3"
services:
redis:
image: redis:latest
container_name: redis
hostname: "redis"
command: --port 6380
ports:
- "6380:6380"
expose:
- "6380"
restart: always
worker:
build: worker/
command: python3 ./worker.py
hostname: "worker"
depends_on:
- redis
app:
build: app/
ports:
- "5000:5000"
depends_on:
- worker
- redis
req:
build: req/
command: python3 ./req.py
network_mode: host
depends_on:
- redis
- worker
- app
以下是源文件的一些详细信息: app.py:包含烧瓶服务器,提供 POST 和 GET 服务,将作业添加到 redis 队列。worker.py:设置 RQ worker req.py:客户端代码
工人.py:
from rq import Worker, Queue, Connection
from rq.job import Job
listen = ['default']
redis_url = os.getenv('REDISTOGO_URL', 'redis://redis:6380')
conn = redis.from_url(redis_url)
if __name__ == '__main__':
print(redis_url)
with Connection(conn):
worker = Worker(list(map(Queue, listen)))
worker.work()
app.py 有 get_prediction2(),worker 试图执行它:
import os
import io
import json
from torchvision import models
import torchvision.transforms as transforms
from PIL import Image
from flask import Flask, jsonify, request
import torch
import redis
import time
import numpy as np
import cv2
import imageio
from scipy.optimize import linear_sum_assignment
from torchvision.models.detection import fasterrcnn_resnet50_fpn
from torchvision.transforms.functional import to_tensor
from rq import Worker, Queue, Connection
from rq.job import Job
def get_prediction2(image_byes):
model2 = torch.hub.load('ultralytics/yolov5', 'yolov5s')
model2.eval()
results = model2(image_byes)#, size=640
return results.pandas().xyxy[0].to_json()
app = Flask(__name__)
#setup the rq queue and worker:
listen = ['default'] #listen to a queue named 'default'
redis_url = os.getenv('REDISTOGO_URL', 'redis://redis:6380')
print('Redis url: ' + redis_url)
conn = redis.from_url(redis_url)
q = Queue(connection=conn)
@app.route('/')
def hello_whale():
return 'Whale, Hello there!'
@app.route('/task/<task_id>', methods=['GET'])
def task_status(task_id):
print(task_id)
if request.method == 'GET':
with Connection(conn):
q = Queue(connection=conn)
task = q.fetch_job(task_id)
if task:
response_object = {"status": "success","data": {"task_id": task.get_id(),"task_status": task.get_status(),"task_result": task.result,},}
else:
response_object = {"status": "error"}
return jsonify(response_object)
#complete
@app.route('/predict', methods=['GET','POST'])
def predict():
#from app import tracking_prediction
print('inside the predict function')
if request.method == 'POST':
r = request
nparr = np.frombuffer(r.data, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
task = q.enqueue_call(func=get_prediction2, args=(img,), result_ttl=5000)
print('task id is "'+task.get_id())
response_object = {"status": "success","data":{"task_id": task.get_id()}}
print(response_object)
return jsonify(response_object), 202
else:
response_object = {"status": "success","data":{"task_id": 12345}}
#print(response_object)
return jsonify(response_object), 202
if __name__ == '__main__':
app.run(host="0.0.0.0", debug=True) #,
这是我在运行“sudo docker-compose up”时收到的错误消息:
<pre><font color="#3465A4">worker_1 |</font> redis://redis:6380
<font color="#3465A4">worker_1 |</font> 00:33:38 Worker rq:worker:60c1591ab20a4ec0a4d30b8e62ab9db0: started, version 1.9.0
<font color="#3465A4">worker_1 |</font> 00:33:38 Subscribing to channel rq:pubsub:60c1591ab20a4ec0a4d30b8e62ab9db0
<font color="#3465A4">worker_1 |</font> 00:33:38 *** Listening on default...
<font color="#3465A4">worker_1 |</font> 00:33:38 Cleaning registries for queue: default
<font color="#06989A">app_1 |</font> * Running on all addresses.
<font color="#06989A">app_1 |</font> WARNING: This is a development server. Do not use it in a production deployment.
<font color="#06989A">app_1 |</font> * Running on http://172.19.0.5:5000/ (Press CTRL+C to quit)
<font color="#06989A">app_1 |</font> * Restarting with stat
<font color="#3465A4">worker_1 |</font> 00:33:38 default: __main__.get_prediction2(array([[[124, 148, 172],
<font color="#3465A4">worker_1 |</font> [119, 145, 169],
<font color="#3465A4">worker_1 |</font> [127, 153, 177],
<font color="#3465A4">worker_1 |</font> ...) (2d9a489b-2e4d-4a15-803e-12270361494e)
<font color="#3465A4">worker_1 |</font> 00:33:38 Traceback (most recent call last):
<font color="#3465A4">worker_1 |</font> File "/usr/local/lib/python3.8/dist-packages/rq/worker.py", line 1031, in perform_job
<font color="#3465A4">worker_1 |</font> rv = job.perform()
<font color="#3465A4">worker_1 |</font> File "/usr/local/lib/python3.8/dist-packages/rq/job.py", line 749, in perform
<font color="#3465A4">worker_1 |</font> self._result = self._execute()
<font color="#3465A4">worker_1 |</font> File "/usr/local/lib/python3.8/dist-packages/rq/job.py", line 772, in _execute
<font color="#3465A4">worker_1 |</font> result = self.func(*self.args, **self.kwargs)
<font color="#3465A4">worker_1 |</font> File "/usr/local/lib/python3.8/dist-packages/rq/job.py", line 225, in func
<font color="#3465A4">worker_1 |</font> return import_attribute(self.func_name)
<font color="#3465A4">worker_1 |</font> File "/usr/local/lib/python3.8/dist-packages/rq/utils.py", line 158, in import_attribute
<font color="#3465A4">worker_1 |</font> attribute_owner = getattr(module, attribute_owner_name)
<font color="#3465A4">worker_1 |</font> AttributeError: module '__main__' has no attribute ''
<font color="#3465A4">worker_1 |</font> Traceback (most recent call last):
<font color="#3465A4">worker_1 |</font> File "/usr/local/lib/python3.8/dist-packages/rq/worker.py", line 1031, in perform_job
<font color="#3465A4">worker_1 |</font> rv = job.perform()
<font color="#3465A4">worker_1 |</font> File "/usr/local/lib/python3.8/dist-packages/rq/job.py", line 749, in perform
<font color="#3465A4">worker_1 |</font> self._result = self._execute()
<font color="#3465A4">worker_1 |</font> File "/usr/local/lib/python3.8/dist-packages/rq/job.py", line 772, in _execute
<font color="#3465A4">worker_1 |</font> result = self.func(*self.args, **self.kwargs)
<font color="#3465A4">worker_1 |</font> File "/usr/local/lib/python3.8/dist-packages/rq/job.py", line 225, in func
<font color="#3465A4">worker_1 |</font> return import_attribute(self.func_name)
<font color="#3465A4">worker_1 |</font> File "/usr/local/lib/python3.8/dist-packages/rq/utils.py", line 158, in import_attribute
<font color="#3465A4">worker_1 |</font> attribute_owner = getattr(module, attribute_owner_name)
<font color="#3465A4">worker_1 |</font> AttributeError: module '__main__' has no attribute ''
<font color="#06989A">app_1 |</font> * Debugger is active!
<font color="#06989A">app_1 |</font> * Debugger PIN: 838-716-436
</pre>
不确定设计自定义 rq worker 的正确方法是什么。我看到这个链接中有一些建议:https ://python-rq.org/docs/#considerations-for-jobs