2010-01-16 7 views
2

나는 트위터 응용 프로그램을 만들고 있는데, 사용자가 페이지를 업데이트 할 때마다 트위터에서 최신 메시지를 다시로드하고 이전에 이미 작성하지 않은 한 로컬 데이터베이스에 저장합니다. 이것은 개발 환경 (데이터베이스 : sqlite3)에서 잘 작동하지만 프로덕션 환경 (mysql)에서는 이미 생성 되었더라도 항상 메시지를 다시 만듭니다.레일즈 프로덕션 환경에서 디버그

메시지 생성은 각 메시지가 가지고있는, twitter_id에 의해 확인된다 : 내가 저장 한 데이터베이스를 볼 때

msg = Message.find_by_twitter_id(message_hash['id'].to_i) 
if msg.nil? 
    # creates new message from message_hash (and possibly new user too) 
end 
msg.save 

분명히, 생산 환경에서은 (어떤 이유로 트위터 ID로 메시지를 찾을 수 없습니다입니다 모든 속성은 정확하게 전에).

이 긴 소개로, 내 주요 질문은 어떻게 디버깅합니까? 이미 주요 문제에 대한 답변을하지 않는 한 나는 production.log에서 볼 때 (물론 :), 그것은 단지 같은 것을 보여줍니다

Processing MainPageController#feeds (for 91.154.7.200 at 2010-01-16 14:35:36) [GET] 
Rendering template within layouts/application 
Rendering main_page/feeds 
Completed in 9774ms (View: 164, DB: 874) | 200 OK [http://www.tweets.vidious.net/] 

을 ...하지만 데이터베이스 요청, logger.debug 텍스트 또는 문제를 찾는 데 도움이 될만한 자료가 필요합니다.

+1

MySQL을 개발 중에 사용하지 않는 이유는 무엇입니까? –

+0

메시지 해시는 무엇으로 구성 되나요? – Eimantas

+0

John, sqlite3이 기본값으로 제공됩니다.하지만 실제로 개발 및 프로덕션 모두에서 동일한 데이터베이스를 사용하는 것이 더 쉽습니다. – JussiR

답변

9

당신은/production.rb 설정/환경에서 로그 레벨을 설정하여 생산에 로그 레벨을 변경할 수 있습니다 SQL 및 다른 모든 사용자가 디바이스에보고하는 데 사용됩니다를 기록합니다

config.log_level = :debug 

- 그것은 것 앱의 속도를 약간 늦추면 로그가 커질 수 있으므로 신중하게 사용하십시오.

하지만 문제 뒤에 실제 문제로 ...

는 때문에 MySQL을 액세스하는 여러 개의 연결이 될 수 있을까요?

트위터 항목이 아직 커밋되지 않은 경우 다른 연결에서 해당 항목에 대한 쿼리가이를 반환하지 않으므로 커밋 이전에 해당 항목에 대한 쿼리가 호출되면 대신 해당 항목을 찾을 수 있습니다. 동일한 항목을 다시 삽입하십시오. 이것은 sqlite에 대한 단독 테스트보다 많은 사용자가있는 프로덕션 환경에서 발생할 가능성이 훨씬 큽니다.

mysql을 사용하고 있기 때문에 트위터 ID에 고유 키를 사용하여 속는 것을 방지 한 다음 속임수를 삽입하려고하면 ActiveRecord 예외를 잡을 수 있습니다. 하지만 이것은 오류를 처리하는 것을 의미합니다.이 방법을 사용하는 것은 좋지 않습니다 (백업 방지 수단으로 백업하는 것이 좋습니다 - mysql이이를 사용하고, 사용하는 것이 좋습니다).

또한 사기를 삽입하지 못하게해야합니다. 한 가지 방법은 공통 레코드에 잠금을 사용하는 것입니다. 즉, 모든 트윗이 관련되어있는 사용자 레코드를 말합니다. 그러면 다른 프로세스가 해당 잠금을 얻을 수있을 때까지 사용자의 트윗을 추가 할 수 없습니다. 트랜잭션이 완료 됨) 동일한 정보를 동시에 커밋하지 못하게합니다.

+0

디버그 코드를 보내 주셔서 감사합니다. 로그를 조사 할 때 문제가 발견되었습니다. 프로덕션/mysql 데이터베이스의 어떤 이유로 인해 항상 동일한 twitter_id를 메시지에 저장합니다 (2147483647). 어떤 메시지에 대해서도 유효한 ID가 아닙니다. Dunno는 전에 그걸 알아 채지 못했습니다. 사실, production.log에 다음과 같은 생성 메시지에 올바른 ID가 표시됩니다. [4; 36; 1mMessage] [0m [0; (0, 7852958107, ...) ... 그러나 데이터베이스에서 모든 twitter_id :가 2147483647로 변경되었습니다. – JussiR

+1

(으)로 변경되었습니다. 트위터 ID는 분명히 열에 비해 너무 크다. 기본적으로 MySQL은 열에 유효하지 않은 값을 받아들이고 가장 가까운 값으로 자른다. 이 잘못을 막기 위해 SQL_MODE를 'TRADITIONAL'과 같은 것으로 설정하십시오. 문제를 해결하려면 열을 더 큰 int 유형 또는 다른 것으로 변경하십시오. 오 예 - 항상 동일한 데이터베이스 서버 (및 기타 모든 소프트웨어)를 프로덕션으로 테스트하십시오. 다른 작업을 수행 할 가치가 없습니다. – MarkR

+0

감사! 그것은 그 문제를 해결했습니다. SQL_MODE (myPHPAdmin에서)를 변경하는 방법을 찾지 못했습니다. 아마도 그렇게 할 수있는 SQL 명령이 있습니까? 어쨌든, 문제가 해결되면, 나는 행복하다. :) – JussiR

1

전자 메일을 데이터베이스에 저장하는 동안 비슷한 문제가 발생했습니다. 정확히 무슨 일이 일어나고 있는지에 대한 자세한 내용은 로그 수준을 디버그로 설정합니다.

실제 문제는 두 항목이 동일한 매개 변수로 저장되지 않도록 데이터베이스에 고유 인덱스를 추가하는 것입니다. 이것은 validates_uniqueness와 같으나 데이터베이스 레벨에서 매우 효과적입니다 : Mysql Constraign Database Entries in Rails.

예를 들어 데이터베이스에 메시지 본문이 중복되어 있고 중복 된 트위터 ID (동일한 사람이 동일한 텍스트를 트윗했음을 의미)가 필요하지 않은 경우입니다. 아이디에 대한 쿼리가 아무튼

add_index(:message, [:twitter_id, :body] , :unique => true) 

그것은 실제로 데이터베이스에 도달하기 전에, 저장 레일의 개체에게 후 작은 시간이 걸린다, 그게 아니면 왜 그런 다음 당신은 당신의 마이그레이션이를 추가 할 수 있습니다 아직 아무것도 찾지 못해.

+0

고마워, 나는 그것에 대해 조사해야한다. 기이 한 일은 내가 정상적인 "validates_uniqueness : twitter_id"를했을 때에도 여전히 메시지를 생성하고 앤드루스의 대답에 대한 설명에 설명 된 것처럼 동일한 twitter_id를 모두 주었다는 것입니다. ps. 죄송합니다. 설명이 혼란 스럽지만 twitter_id가 트위터 데이터베이스의 id라는 메시지를 참조하기 때문에 사용자 ID가 아닙니다. – JussiR

+0

나는 문제가 해결되었다는 것을 알고 기쁘다.하지만 나는 validates_uniqueness가 끔찍하다는 것을 언급해야한다고 생각한다 - 수표와 실제 커밋 사이의 지연으로 인해 쉽게 우연한 일이 일어날 수 있기 때문에 작동하지 않는다. –

+0

잘 알고 있습니다. 위에 표시된 방법을 사용하여 시작해야합니다. – JussiR

관련 문제