我有一个Node后端,该后端在被调用时需要向Python后端发出单独的请求以进行图像分类预测。在本地运行两个服务器时,该调用都可以正常运行,但是在托管时会引发503错误。
Node服务器接收一个multipart / form-data图像,然后将其重新发送到Python服务器。同样,整个路由呼叫都在本地工作。我还用Postman测试了Python后端,它工作正常。
两个服务器都托管在Heroku上。 Node服务器正在运行v8.1.4,Python服务器正在运行v3.5.6
这是Python代码:
import os
from flask import Flask, request
from flask_cors import CORS, cross_origin
app = Flask(__name__)
CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'
# prediction route
@app.route('/predict', methods=['POST', 'OPTIONS'])
@cross_origin()
def predict():
req_image = request.files['image']
# do stuff with req_image
return prediction
#hosted locally for testing
if __name__ == '__main__':
port = int(os.environ.get('PORT', 3001))
app.run(host='0.0.0.0', port=port)
和节点代码:
const config = require('../config/main');
const axios = require('axios');
const FormData = require('form-data');
const express = require('express');
const multer = require('multer')
const upload = multer()
var predictionRouter = express.Router();
predictionRouter.use(upload.single('image'));
predictionRouter.post('/predict', function(req, res, next) {
if (!req.file)
throw new NoDataError('No image provided');
var formData = new FormData();
formData.append('image', req.file.buffer, {
filename: 'image.png'
});
return axios.post(`${config.model.api_base_url}/predict`, formData, {
headers: formData.getHeaders()
})
.then(results => res.status(200).send({ prediction: results.data }))
.catch(err => {
console.log(err)
next(err)
});
});
这是Python错误:
2018-09-19T19:03:14.520797+00:00 heroku[router]: sock=backend at=error code=H18 desc="Server Request Interrupted" method=POST path="/predict" host=python-backend.herokuapp.com request_id=2dbaa4f2-3d58-4f84-ba60-83cf721fd803 fwd="130.15.59.3" dyno=web.1 connect=0ms service=103ms status=503 bytes=379 protocol=https
2018-09-19T19:03:14.434838+00:00 app[web.1]: 10.157.202.232 - - [19/Sep/2018:19:03:14 +0000] "POST /predict HTTP/1.1" 400 192 "-" "axios/0.18.0"
和丑陋的Node错误:
{ Error: Request failed with status code 503
at createError (/project/node_modules/axios/lib/core/createError.js:16:15)
at settle (/project/node_modules/axios/lib/core/settle.js:18:12)
at IncomingMessage.handleStreamEnd (/project/node_modules/axios/lib/adapters/http.js:201:11)
at emitNone (events.js:110:20)
at IncomingMessage.emit (events.js:207:7)
at endReadableNT (_stream_readable.js:1047:12)
at _combinedTickCallback (internal/process/next_tick.js:102:11)
at process._tickCallback (internal/process/next_tick.js:161:9)
config:
{ adapter: [Function: httpAdapter],
transformRequest: { '0': [Function: transformRequest] },
transformResponse: { '0': [Function: transformResponse] },
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
headers:
{ Accept: 'application/json, text/plain, */*',
'Content-Type': 'multipart/form-data; boundary=--------------------------087672685077373181485002',
'User-Agent': 'axios/0.18.0' },
method: 'post',
url: 'https://python-backend.herokuapp.com/predict',
data:
FormData {
_overheadLength: 151,
_valueLength: 38528,
_valuesToMeasure: [],
writable: false,
readable: true,
dataSize: 0,
maxDataSize: 2097152,
pauseStreams: true,
_released: true,
_streams: [],
_currentStream: null,
_boundary: '--------------------------087672685077373181485002',
_events: {},
_eventsCount: 0 } },
request:
ClientRequest {
domain: null,
_events:
{ socket: [Function],
abort: [Function],
aborted: [Function],
error: [Function],
timeout: [Function],
prefinish: [Function: requestOnPrefinish] },
_eventsCount: 6,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: true,
_last: true,
upgrading: false,
chunkedEncoding: true,
shouldKeepAlive: false,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket:
TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: null,
npnProtocol: undefined,
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object],
_eventsCount: 9,
connecting: false,
_hadError: false,
_handle: null,
_parent: null,
_host: 'python-backend.herokuapp.com',
_readableState: [Object],
readable: false,
domain: null,
_maxListeners: undefined,
_writableState: [Object],
writable: false,
allowHalfOpen: false,
_bytesDispatched: 39047,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: null,
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular],
read: [Function],
_consuming: true,
_idleNext: null,
_idlePrev: null,
_idleTimeout: -1,
[Symbol(asyncId)]: 45,
[Symbol(bytesRead)]: 710 },
connection:
TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: null,
npnProtocol: undefined,
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object],
_eventsCount: 9,
connecting: false,
_hadError: false,
_handle: null,
_parent: null,
_host: 'python-backend.herokuapp.com',
_readableState: [Object],
readable: false,
domain: null,
_maxListeners: undefined,
_writableState: [Object],
writable: false,
allowHalfOpen: false,
_bytesDispatched: 39047,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: null,
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular],
read: [Function],
_consuming: true,
_idleNext: null,
_idlePrev: null,
_idleTimeout: -1,
[Symbol(asyncId)]: 45,
[Symbol(bytesRead)]: 710 },
_header: 'POST /predict HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nContent-Type: multipart/form-data; boundary=--------------------------087672685077373181485002\r\nUser-Agent: axios/0.18.0\r\nHost: python-backend.herokuapp.com\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n',
_onPendingData: [Function: noopPendingOutput],
agent:
Agent {
domain: null,
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object],
requests: {},
sockets: [Object],
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: [Object] },
socketPath: undefined,
timeout: undefined,
method: 'POST',
path: '/predict',
_ended: true,
res:
IncomingMessage {
_readableState: [Object],
readable: false,
domain: null,
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
socket: [Object],
connection: [Object],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers: [Object],
rawHeaders: [Array],
trailers: {},
rawTrailers: [],
upgrade: false,
url: '',
method: null,
statusCode: 503,
statusMessage: 'Service Unavailable',
client: [Object],
_consuming: true,
_dumped: false,
req: [Circular],
responseUrl: 'https://python-backend.herokuapp.com/predict',
redirects: [],
read: [Function] },
aborted: undefined,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
_redirectable:
Writable {
_writableState: [Object],
writable: true,
domain: null,
_events: [Object],
_eventsCount: 2,
_maxListeners: undefined,
_options: [Object],
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 38735,
_requestBodyBuffers: [],
_onNativeResponse: [Function],
_currentRequest: [Circular],
_currentUrl: 'https://python-backend.herokuapp.com/predict' },
[Symbol(outHeadersKey)]:
{ accept: [Array],
'content-type': [Array],
'user-agent': [Array],
host: [Array] } },
response:
{ status: 503,
statusText: 'Service Unavailable',
headers:
{ connection: 'close',
server: 'Cowboy',
date: 'Wed, 19 Sep 2018 19:03:14 GMT',
'content-length': '506',
'content-type': 'text/html; charset=utf-8',
'cache-control': 'no-cache, no-store' },
config:
{ adapter: [Function: httpAdapter],
transformRequest: [Object],
transformResponse: [Object],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
headers: [Object],
method: 'post',
url: 'https://python-backend.herokuapp.com/predict',
data: [Object] },
request:
ClientRequest {
domain: null,
_events: [Object],
_eventsCount: 6,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: true,
_last: true,
upgrading: false,
chunkedEncoding: true,
shouldKeepAlive: false,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [Object],
connection: [Object],
_header: 'POST /predict HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nContent-Type: multipart/form-data; boundary=--------------------------087672685077373181485002\r\nUser-Agent: axios/0.18.0\r\nHost: python-backend.herokuapp.com\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Object],
socketPath: undefined,
timeout: undefined,
method: 'POST',
path: '/predict',
_ended: true,
res: [Object],
aborted: undefined,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
_redirectable: [Object],
[Symbol(outHeadersKey)]: [Object] },
data: '<!DOCTYPE html>\n\t<html>\n\t <head>\n\t\t<meta name="viewport" content="width=device-width, initial-scale=1">\n\t\t<meta charset="utf-8">\n\t\t<title>Application Error</title>\n\t\t<style media="screen">\n\t\t html,body,iframe {\n\t\t\tmargin: 0;\n\t\t\tpadding: 0;\n\t\t }\n\t\t html,body {\n\t\t\theight: 100%;\n\t\t\toverflow: hidden;\n\t\t }\n\t\t iframe {\n\t\t\twidth: 100%;\n\t\t\theight: 100%;\n\t\t\tborder: 0;\n\t\t }\n\t\t</style>\n\t </head>\n\t <body>\n\t\t<iframe src="//www.herokucdn.com/error-pages/application-error.html"></iframe>\n\t </body>\n\t</html>' } }
Error: Request failed with status code 503
at createError (/project/node_modules/axios/lib/core/createError.js:16:15)
at settle (/project/node_modules/axios/lib/core/settle.js:18:12)
at IncomingMessage.handleStreamEnd (/project/node_modules/axios/lib/adapters/http.js:201:11)
at emitNone (events.js:110:20)
at IncomingMessage.emit (events.js:207:7)
at endReadableNT (_stream_readable.js:1047:12)
at _combinedTickCallback (internal/process/next_tick.js:102:11)
at process._tickCallback (internal/process/next_tick.js:161:9)
POST /api/predictions/predict 500 443.837 ms - 74