2016-11-10 11 views
0

마이크로 웹 서비스가 구축되었지만 많이 중단되었습니다. 멈춤으로써 나는 모든 요청이 단지 시간 초과 될 것이라는 것을 의미한다. 서버가 정상적으로 약 15MB 메모리 만 사용하여 프로세스가 잘 돌아가고 있음을 알 수있다. 나는 게시하는 것이 매우 흥미로운 문제라고 생각합니다. 코드는 매우 간단합니다. 내가 뭘 잘못하고 있는지 말해주십시오.Python 마이크로 웹 서비스가 항상 끊어집니다.

app = Bottle() 
# static routing 
@app.route('/') 
def server_static_home(): 
    return static_file('index.html', root='client/') 

@app.route('/<filename>') 
def server_static(filename): 
    return static_file(filename, root='client/') 

@app.get('/api/data') 
def getData(): 
    data = {} 
    arrayToReturn = [] 
    with open("data.txt", "r") as dataFile: 
     entryArray = json.load(dataFile) 
     for entry in entryArray: 
      if not entry['deleted']: 
       arrayToReturn.append(entry) 
     data["array"] = arrayToReturn 

    return data 

@app.put('/api/data') 
def changeEntry(): 

    jsonObj = request.json 
    with open("data.txt", "r+") as dataFile: 
     entryArray = json.load(dataFile) 
     for entry in entryArray: 
      if entry['id'] == jsonObj['id']: 
       entry['val'] = jsonObj['val'] 
     dataFile.seek(0) 
     json.dump(entryArray, dataFile, indent=4) 
     dataFile.truncate() 

    return {"success":True} 

run_simple('0.0.0.0', 80, app, use_reloader=True) 

는 기본적으로 mydomain.comindex.html 및로드 필요한 JS, CSS 파일, 즉 정적 라우팅 부분이 무엇을하고 있는지의 노선입니다. 페이지가로드되면 Ajax GET 요청이 /api/data으로 시작되어 데이터를로드하고 데이터를 수정할 때 /api/data에 다른 Ajax Put 요청을 발생시켜 데이터를 수정합니다. 그것은 요령을 재현하기가 매우 쉽다

를 재현하는 방법

, 나는 단지 그 때 응답을 중지합니다, mydomain.com를 방문하여 빠른 속도로 10 ~ 30 배의 페이지를 새로 고침 할 필요가있다. 그러나 나는이 로컬에서 얼마나 빨리 새로 고침을하고 data.txt이 내 로컬 컴퓨터에서 동일하게 재현 할 수 없었습니다.

업데이트

는 읽기/파일에 쓸 수 있지만 파이프를 깨진 쓰기를 시도하는 문제와 문제가 아니에요 밝혀졌습니다. 요청을 보낸 클라이언트가 모든 데이터를 받기 전에 연결을 닫습니다. 지금 솔루션을 찾고 있습니다 ...

+0

당신이 병 프레임 워크에 포함 된 개발 서버를 사용하는 경우와 같은 뭔가, 내가 깨진 파이프 오류가 실질적으로 피할 것으로 나타났습니다 충분한 가동 시간 부여 (그것은 결국 dev에 서버입니다). 그게 당신에게 적용되는 경우, 더 생산 준비가 된 서버 위에 병 응용 프로그램을 실행하는 것으로 전환하는 것이 좋습니다. 개인적으로 cherrypy와 병을 사용하여 정말 좋은 결과를 얻었습니다. – user3351605

답변

3

모든 PUT 요청과 함께 동일한 data.txt 파일을 열어 읽으려는 것 같습니다. 결국 같은 파일을 열거 나 쓸 때 여러 요청을 할 것이므로이 아키텍처에서 동시성 문제가 발생하게됩니다.

가장 좋은 해결책은 디스크의 플랫 파일에 쓰는 대신 데이터베이스 (MySQL, Postgres, Mongodb)에 데이터를 저장하는 것입니다.

그러나 플랫 파일에 써야하는 경우 파일 이름이 jsonObj['id'] 일 수있는 요청 당 다른 파일에 작성해야합니다. 이렇게하면 읽기/쓰기를 시도하는 여러 요청의 문제를 피할 수 있습니다 같은 파일에 동시에 적용됩니다.

+0

서비스가 정말 간단하기 때문에 어떤 데이터베이스도 사용하고 싶지 않습니다. 저는 json 형식의 텍스트 파일에서 항목을 읽고 수정하고 있으므로 별도의 파일에 쓸 수 있다고 생각하지 않습니다. 그런 다음 데이터를 읽는 것은 매우 복잡 할 것입니다. – Arch1tect

+0

또한 문제를 재현하기 위해 데이터를 수정할 필요가 없기 때문에 'GET'요청이 'PUT'이 아닌 문제가 있다고 생각합니다. 새로 고침하면 데이터를 읽는 'GET'요청 만 실행됩니다. – Arch1tect

1

귀하의 data.txt 파일을 읽고 쓰는 것은 Calvin이 언급 한 경쟁 조건으로 인해 희생 될 것입니다. 데이터베이스는 특히 Python에서 SqlAlchemy와 같은 라이브러리를 사용하면 매우 쉽습니다. 그러나 주장하는 경우 웹 서버가 여러 프로세스로 실행되고 있지 않다는 가정하에 전역 사전과 잠금을 사용할 수도 있습니다.

entryArray = {} 
mylock = threading.Lock() 
@app.put('/api/data') 
def changeEntry(): 

    jsonObj = request.json 
    with mylock.lock: 
     for entry in entryArray: 
      if entry['id'] == jsonObj['id']: 
       entry['val'] = jsonObj['val'] 
+0

나는 이것을 좋아한다, 나는 지금 시험해 볼 것이다! 감사! – Arch1tect

+0

지금은 경쟁 조건이라고 생각하지 않습니다. 기본적으로 싱글 스레드 인 것처럼 보입니다. - http://werkzeug.pocoo.org/docs/0.11/serving/ – Arch1tect