Heroku가 HTTP 응답을 자릅니다.


78

Heroku Cedar dyno에서 Flask / Gunicorn Python 앱을 실행하고 있습니다. 앱 반환JSON responses 이 클라이언트에게 됩니다 ( API server실제로는).

가끔 클라이언트는 0 바이트 응답을받습니다. 그러나 그것들을 돌려주는 것은 내가 아닙니다. 다음은 내 앱 로그의 일부입니다.

3 월 14 일 13:13:31 d.0b1adf0a-0597-4f5c-8901-dfe7cda9bce0 app [web.1] [2013-03-14 13:13:31 UTC] 10.104.41.136 apisrv-api_get_credits_balance () : session_token = [MASKED ]

위의 첫 번째 줄은 요청을 처리하기 시작하는 것입니다.

3 월 14 일 13:13:31 d.0b1adf0a-0597-4f5c-8901-dfe7cda9bce0 app [web.1] [2013-03-14 13:13:31 UTC] 10.104.41.136 apisrv 1252148511 api_get_credits_balance () : 반환 [{ ' credits_balance ': 0}]

두 번째 줄은 값을 반환하는 것입니다 (Flask에-Flask "Response"객체입니다).

3 월 14 일 13:13:31 d.0b1adf0a-0597-4f5c-8901-dfe7cda9bce0 app [web.1] "10.104.41.136--[2013 년 3 월 14 일 : 13 : 13 : 31]"POST / get_credits_balance? session_token = MASKED HTTP / 1.1 "200 22"- ""Appcelerator Titanium / 3.0.0.GA (iPhone / 6.1.2; iPhone OS; en_US;) "

세 번째 줄은 Gnicorn의 것입니다. 여기에서 Gunicorn이 상태가 200이고 HTTP 본문이 22 바이트 인 것을 볼 수 있습니다 ( " 200 22").

그러나 클라이언트는 0 바이트를 얻었습니다. 다음은 Heroku 라우터 로그입니다.

3 월 14 일 13:13:30 d.0b1adf0a-0597-4f5c-8901-dfe7cda9bce0 heroku [router] at = info method = POST path = / get_credits_balance? session_token = MASKED host = matchspot-apisrv.herokuapp.com fwd = "66.87. 116.128 "dyno = web.1 대기열 = 0 대기 = 0ms 연결 = 1ms 서비스 = 19ms 상태 = 200 바이트 = 0

Gunicorn이 22 바이트를 반환하지만 Heroku가 0을보고 실제로 0 바이트를 클라이언트에 다시 전달하는 이유는 무엇입니까? 이것은 Heroku 버그입니까?


1
heroku 타임 스탬프가 proccess 타임 스탬프 이전이라는 것을 알았습니까? gevent를 사용하십니까? 동기화에 문제가 있다고 생각합니다.
Tigra

2
하지만 타임 스탬프는 1 초의 차이가 아니라 1 초의 차이를 나타냅니다 ... 저는 heroku로 작업하지 않았으므로 제안 일뿐입니다. 1ms와 1999ms 모두 타임 스탬프에서 1 초 차이를 줄 수 있습니다. 서비스 19ms도 너무 낮아 클라우드 서비스에서 사실이 아닙니다. 그래서 내 요점은 아마도 일종의 시간 초과가 있고 시간 초과시 오류 heroku가 빈 페이지를 제공한다는 것입니다. 이 제안은 장거리 슛이지만, 어쩌면 당신은 오래 요청을 모방 무슨 일이 일어납니다
Tigra 호텔

9
(호기심으로) 연락했을 때 Heroku가 얼마나 도움이 되었나요?
orokusaki

6
지금까지는 그리 많지 않습니다. 나는 10 일 전에 그들에게 접근했고, 파이썬 사람들이 먼저 그것을 볼 것이라고 들었고 그들이 나를 도울 수 없다면 라우팅 사람들이 살펴볼 것이라고 들었습니다. 5 일 후 나는 파이썬 직원이 이것을 라우팅 담당자에게 전달했다는 소식을 받았고, 오늘 "라우팅 담당자"로부터 이메일을 받았는데 그가 다시 만들 수없고 더 많은 정보를 요청했습니다. 그렇습니다. 그들은 올바른 과정을 거치고 있지만 영원히 걸리고 있습니다.
Nitzan Shaked 2013 년

1
소규모 업데이트 : 아직 해결되지 않았습니다. 저는 Heroku 지원을주고 받았으며 지금 제가 모을 수있는 최선의 방법은 그들이 "그것은 당신의 끝입니다"라고 저를 해고하지 않았고, 앱 트래픽을 tcpdump-capture 할 도구를 작성하려고 노력하고 있다는 것입니다. , "이와 같은 디버깅 사례"의 경우.
Nitzan Shaked 2013-04-23

답변:


1

나는 내가 여기서 벽에서 약간 벗어난 것으로 간주 될 수 있지만 다른 옵션이 있습니다.

우리는 때때로 운송 중에 발생하는 버그가 있다는 것을 알고 있으며, 문제를 막기 위해 지금 당장 할 수있는 일이 많지 않다는 것을 알고 있습니다. API 만 제공하는 경우 읽기를 중지하고 클라이언트도 작성하는 경우 계속 진행하십시오.

오류는 알려진 경우이며 알려진 원인입니다. 빈 반환 값의 결과는 문제가 발생했음을 의미합니다. 그러나 값을 사용할 수 있고 가져오고 계산했습니다. 개발자로서 내 본능은 빈 결과를 HTTP 오류로 처리하고 데이터를 다시 전송하도록 요청하는 것입니다. 그런 다음 재전송 요청을 추적하고 이것이 얼마나 자주 발생하는지 확인할 수 있습니다.

나는 당신이 요청을 세고 사용자에게 "네트워크 오류"에 응답하기위한 적절한 값을 설정하도록 제안합니다 (당신이 이것도 생각하는 종류의 개발자라고 생각하지만). 내 본능은 바로 재 시도한 다음 조금 더 기다렸다가 다시 시도하는 것입니다.

설명하는 첫 번째 재 시도에서 데이터를 올바르게 선택합니다. 물론 이것은 가장 적절한 것으로 보이는 것에 따라 오래된 요청을 몇 분 동안 캐시에 보관하거나 요청을 두 번 실행하는 것을 의미 할 수 있습니다.

이것은 또한 다른 지점 간 네트워킹 오류를 우회하여 연결 문제가 발생하더라도 앱을 훨씬 더 견고하게 만듭니다.

개발자로서의 본능은 알려진 결함을 수정하는 것이지만 때로는 결함에도 불구하고 작동 할 수있는 시스템을 향해 작업하는 것이 더 좋습니다. 그것은 오류와 문제를 기록하고 어쨌든 수정하려고 노력하는 것이 결코 아프지 않다고 말했습니다.


사실 그것은 나쁜 댓글이 아닙니다. (아마도 답변이 아닌 댓글에 있어야하지만) 제가 그것에 대해 생각하지 않았다고 생각하지 마세요 ... 문제는 클라이언트가 요청을 다시 발행 할 수 없다는 것입니다. 요청에 서버 측 부작용이있을 수 있기 때문입니다 (예 : 두 번째로 돈을 이체하는 것과 같은). 이에 대한 해결책은 클라이언트가 request_id를 발행하고 서버가 "최근 60 초 동안 어떤 request_id가 제공되었는지"목록을 유지하는 것입니다. 클라이언트가 0 바이트 본문의 200 응답을 받으면 동일한 ID의 요청을 다시 발행하고 서버는 다시 수행하지 않습니다 (계속)
Nitzan Shaked

(계속) 다시 모든 것을. 그러나 그것은 너무 추하여 구현하지 않기로 결정했습니다.
Nitzan Shaked 2013 년

나는 캐싱에 거의 초보자이지만 나에게 보인다. 임의의 문자열을 요청의 일부로 보내고 결과를 캐시합니다. 동일한 임의의 문자열로 요청을 재전송하면 자연스럽게 캐시 된 결과 (동일한 콘텐츠, 동일한 소스 ...)를 가져 오지만 합법적 인 새 요청을 전송하면 새로운 임의의 문자열이 있으므로 캐시되지 않습니다. 결과.
Narfanator
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.