2011-05-08 5 views
2

나는 PHP 환경 (적어도 웹 개발자 측면에서)과 Ruby의 아름다운 세계로 간다. 그래서 나는 바보 같은 질문을할지 모른다. PHP를 사용하지 않을 때 근본적으로 다른 옵션을 사용할 수 있다고 생각합니다.레일스 우수 사례 : 백그라운드 프로세스/스레드?

PHP에서는 memcache를 사용하여 페이지 상단의 막대에 표시 할 경고를 저장합니다. 어떤 일이 발생하면 (예 : 새로운 블로그 게시물이 만들어 짐과 같은) 경고를 생성하면 5 분마다 한 번씩 실행되는 cron 스크립트가 해당 정보를 memcache에 저장합니다.

사용자가 사이트를 방문하면 memcache가 이미 해고하지 않은 경고를 찾아서 표시합니다.

레일스에서 ​​다르게 할 수있는 것은 cron 스크립트의 필요성을 우회하는 것이며 모든 요청에 ​​대해 memcache를 살펴볼 필요가 있습니다. 싱글 톤과 폴링 프로세스를 실행하여 memcache에서이 싱글 톤으로 복사 할 별도의 스레드. 이것은 이론적으로 요청 당 Memcache를 검사하는 것보다 최적화되고 cron 작업과 조회 논리 사이에서 분리되는 대신 폴링 논리를 한 곳으로 캡슐화합니다.

내 질문은 : 레일 앱이 실행되는 동안 배경에 일종의 runloop이 있다는 경고가 있습니까? Objective-C/Java에서 멀티 스레딩의 함축적 의미를 이해하고 있지만 레일스 (Rails) 환경에 대해 구체적으로 묻고 있습니다.

은 기본적으로 같은 일이 :

class SiteAlertsMap < Hash 
    include Singleton 

    def initialize 
    super 
    begin_polling 
    end 

    # ... SNIP, any specific methods etc ... 

    private 

    def begin_polling 
     # Create some other Thread here, which polls at set intervals 
    end 
end 

이 비슷한 질문에 날 리드. 우리는 전자 상거래 및 장기 실행 백그라운드 작업과 관련하여 작업을 SQS 대기열에 푸시 (암호화)합니다. 우리는 이것을 위해 cron을 사용하지 않고 백그라운드에서 실행되는 PHP로 작성된 작업자 데몬을 사용합니다. 현재 배포 할 때이 작업자를 종료하고 새 코드 기반에서 다시 시작해야합니다. Rails에서 어떻게 든이 프로세스를 시작하고 레일 서버 (유니콘) 자체로 멈출 수 있습니까? 우리가 자주 프로세스로 제어하려고하기 때문에 별도의 스레드에서 주 프로세스에서 실행하고 싶지는 않지만 웹 응용 프로그램이 실행 중일 때 편리하게 실행되면 좋을 것입니다.

답변

7

루비의 백그라운드 프로세스에 대한 스레딩은 특히 다중 프로세스 서버를 사용하기 때문에 끔찍한 실수입니다. 유니콘을 사용하여 4 개의 작업자 프로세스를 사용하면 각각의 작업자 프로세스에서 원하는대로 폴링을 수행 할 수 있습니다. Ruby는 실제 쓰레드를 가지고 있지 않다. 1.8에 녹색 쓰레드가 있고, 1.9 IIRC에 전역 인터프리터가있다. 많은 보석과 도서관도 독이 없으며 안전하지 않습니다.

memcache를 사용하는 것이 가장 좋은 방법이며 올바르게 설정했다면 요청 시간에 밀리 초 또는 2 분이 더 걸리는 것을 볼 수 있습니다. 추가적인 오버 헤드를 최소화하면서 이러한 경고를 유지할 수있는 또 다른 옵션은 이러한 경고를 다시 저장하는 것입니다. 이렇게하면 memcache 충돌이나 서버 재부팅과 같은 문제로부터 보호받을 수 있습니다.

백그라운드 작업의 경우 지금까지와 비슷한 방식을 사용해야하지만 여기에는 resque, delayed_job 및 기타 몇 가지 선반 처리기가 있습니다. 백엔드 대기열로 SQS를 절대적으로 사용해야하는 경우 도움이되는 코드를 찾을 수는 있지만 그렇지 않으면 직접 작성할 수 있습니다. 코드 변경이있을 때마다 다른 데몬을 다시 부팅해야합니다. 실제로 배포시 데몬을 바운스하기 위해 규칙을 쉽게 추가 할 수있는 카피 스트라 노 (capistrano)와 같은 배포 시스템을 사용하는 것이 모범 사례이므로 그다지 큰 관심사는 아닙니다. monit을 사용하여 데몬 프로세스를 감시하므로 다시 시작하는 것은 monit에 다시 시작하도록 지시하는 것만큼이나 쉽습니다.

일반적으로 Ruby는 스레드와 관련하여 Java/Objective-C와 다릅니다. 유닉스와 유사한 프로세스 기반 격리 모델을 따르지만 커뮤니티는 모범 사례와 다른 언어보다 고통을 덜 수있는 방법을 제시했습니다. Ruby는 스택을 설정하는 데 좀 더주의를 기울일 필요가 있습니다. mod_php을 활성화하고 일부 파일을 복사하는 것만 큼 간단하지는 않지만 일단 선택 및 아키텍처를 이해하면 응용 프로그램의 작동 방식을 쉽게 추론 할 수 있습니다. 제 생각에 프로세스 모델은 다른 실행중인 작업의 영향으로부터 코드와 상태를 격리하므로 웹 애플리케이션에 훨씬 좋습니다. 또한 격리 기능을 사용하면 분산 시스템에서 응용 프로그램을보다 쉽게 ​​사용할 수 있습니다.

+0

고마워, 당신 말이 맞아, 나는 쓰레드를 사용하지 않기로 결정했다. 쓰레드와의 비 호환성 때문에 나는 dev의 불쾌한 행동을 관찰했다. Resque 및 delayed_job 링크에 감사드립니다. 오늘 아침에 커피 한잔 읽어 줄게. 아마도 Rails 앱과 분리되어있는 것들을 위해 사용할 수 있지만, 여전히 많은 것들이 PHP에 있습니다 (앱은 공존하고 있습니다). 나는 녹색 스레드를 사용하여 루비에 대해 읽었지만,이 경우에 관심이있는 것을 보지 못했습니다. :) – d11wtq