대규모 사이트에서 백그라운드 작업 서비스


49

우리는 StackOverflow에서 흥미로운 문제를 다루고 있습니다.

우리는 "조만간해야 할"작은 일들이 많이 있습니다. 예를 들어 "관련 질문"목록을 업데이트하고 있습니다. 과거에 우리가 한 일은 이러한 작업을 일부 사용자의 페이지로드로 피기 백하는 것입니다.

이것은 이상적이지 않았지만 실제로 눈에 띄지는 않았습니다. SO가 1,000,000 개의 물음표를 통과 했으므로, 운이 좋지 않은 사용자는 그것을 느끼기 시작했습니다.

자연스러운 해결책은 실제로 이러한 작업을 백그라운드로 푸시하는 것입니다. 내가 생각하고있는 두 가지 광범위한 방법이 있습니다.

1. IIS에서 사용자 정의 Thread-Pool / Work-Queue로

기본적으로, 우리는 몇 개의 ( ThreadPool 이외의 IIS를 방해하지 않기 위해) 스레드를 돌리고 Funcs 에 밀어 넣는 일부 컬렉션을 서비스 하게합니다.

여기서 큰 프로는 단순성입니다. 우리는 마샬링에 대해 걱정할 필요가 없으며 외부 서비스가 작동하고 응답하는지 확인할 필요가 없습니다.

또한 모든 공통 코드에 액세스 할 수 있습니다.

단점은 백그라운드 스레드를 사용해서는 안된다는 것입니다. 내가 아는 이의는 모두 굶주린 IIS (ThreadPool을 사용하는 경우)와 스레드가 임의로 죽는 것 (AppPool 재활용으로 인해)에 집중되어 있습니다.

우리는 랜덤 쓰레드 데스를 이슈가 아닌 것으로 만들 수있는 기존 인프라를 가지고있다.

IIS 프로세스 스레드 풀링 / 작업 큐에서 다른 반대 의견이 누락 되었습니까?

실제로 해결되지 않았으므로 StackOverflow로 이동했습니다 .

2. 서비스로

일부 타사 솔루션 또는 사용자 지정 솔루션

기본적으로 프로세스 경계를 ​​넘어서 서비스를 일부 서비스에 마샬링하고 잊어 버립니다. 아마도 우리는 일부 코드를 링크하거나 원시 SQL + 연결 문자열로 제한하고 있습니다.

전문가는이를위한 "올바른 방법"입니다.

단점은 우리가 할 수있는 일이 매우 제한적이거나이 서비스를 코드 기반과 동기화하기 위해 일부 시스템을 개발해야한다는 것입니다. 또한 모든 모니터링 및 오류 로깅을 어떻게 든 연결해야하며 "IIS에서"옵션으로 무료로 사용할 수 있습니다.

서비스 접근 방식에 다른 이점이나 문제점이 있습니까?

간단히 말해서, 접근 # 1을 실현할 수 없게 만드는 예측할 수없고 극복 할 수없는 문제가 있습니까? 그렇다면 좋은 타사 서비스가 있다면 접근 # 2를 살펴 봐야합니까?


올바른 길은 다른 길로 가기로 결정할 때 우리가 올바른 길을 갔다고 말하는 방식입니다. 현명하게 선택해. 나는이 특정 문제에 대해 언급하기에 IIS 세계에 익숙하지 않습니다.
Chris

2
비슷한 시나리오 (훨씬 작은 규모)가 있기 때문에 궁금합니다. 그리고 임의의 사용자에게 운이 좋지 않은 연결을 피기 백하고 있습니다. 최고의 솔루션에 익숙하지 않으므로 여기에 따라 보겠습니다. :-)
pc1oad1etter

7
왜 이것이 StackOverflow에 없는지 알 수 없습니다. 이것은 주관적인 평가가 아니라 엔지니어링 트레이드 오프입니다. 다양한 접근 방식에 대한 분석을 요청하고 있습니다. 이것이 모두 객관적인 것입니다. 분석이 정확히 어떤 장단점이 무엇인지를 명확하게 한 경우에만 주관성이 있습니까? 그리고 당신의 질문이 '내가 더 중요하게 생각해야하는 시간과 서버 자원 또는 사용자 시간이 아닌가? ' 또는 비슷한 것.
Joren

@Kevin Montrose-귀하의 의견에 따르면, "곧해야 할 필요"와 "간격으로 예약해야 함"을 구분하는 것 같습니다. 왜 서로 다른 패턴 / 인프라가 필요한 두 가지 종류의 백그라운드 작업 인지 자세히 설명 할 수 있습니까 ?
Portman

@Portman - 근본적인 차이는 "곧 틱"작업을 추론 할 수없는, 우리가 정말 우리는 그들이 알고있을 때까지 기다릴 필요가있다 필요로 할 수 있습니다. 엔벨로프 계산의 일부는 "관련 질문"쿼리 (많은 것 중 하나)를 "멍청한"크론 탭으로 옮기는 데 약 1 시간이 걸린다는 것을 보여줍니다. 모든 질문에 대해 일주일 간의 견고한 처형. 일반적으로 우리는 가능한 빨리 사용자 경험에 영향을 미치지 않고 실행하기를 원하지만, 우리의 간격 작업은 5 분 안에 한 번 이상 (그리고 일반적으로 훨씬 덜 자주) 실행함으로써 얻을 수 있습니다.
Kevin Montrose

답변:


17

몇 주 전에 나는 비슷한 질문했다 . 간단히 말해, 한동안 나의 접근 방식은 Windows 서비스를 개발하는 것이 었습니다. NServiceBus (본질적으로 MSMQ)를 사용하여 웹 응용 프로그램에서 서비스로 요청을 마샬링합니다. 나는 WCF를 사용했지만 WCF에서 분산 트랜잭션을 올바르게 작동시키는 것은 항상 고통스러운 것처럼 보였습니다. NServiceBus는 트릭을 수행하여 트랜잭션에서 데이터를 커밋하고 작업을 만들 수 있으며 당시 서비스가 작동했는지 여부를 걱정하지 않습니다. 간단한 예로, 전자 메일 (예 : 등록 전자 메일)을 보내야하는 경우 사용자 계정을 만들고 트랜잭션에서 전자 메일을 보내기 위해 Windows 서비스에 신호를 보냅니다. 서비스 측의 메시지 핸들러는 메시지를 픽업하고 그에 따라 처리합니다.

ASP .NET 4.0 및 AppFabric이 릴리스되었으므로 위의 메커니즘에 대한 여러 가지 대안이 있습니다. 위에서 언급 한 질문을 다시 언급하면 ​​이제 AppFabric의 AppInitialize (net.pipe를 통해)와 ASP .NET 4.0의 자동 시작 기능을 통해 웹 서비스로 Windows 서비스를 개발할 수 있습니다. 나는 여러 가지 이유로 지금이 작업을 시작했습니다 (배포되는 가장 큰 것은 더 이상 엉덩이에 고통이 아닙니다).

  1. 웹 앱으로 실행되므로 서비스를 통해 웹 UI를 개발할 수 있습니다. 이것은 런타임에 무슨 일이 일어나고 있는지 볼 때 매우 유용합니다.
  2. 웹 응용 프로그램의 배포 모델이 서비스 응용 프로그램에서 작동합니다.
  3. IIS는 응용 프로그램 오류를 처리하기위한 몇 가지 깔끔한 기능을 제공합니다 (일부 Windows 서비스와 유사).
  4. 웹 개발자는 웹 응용 프로그램 개발에 익숙하지만 자연스럽게 Windows 서비스를 개발할 때 모범 사례를 잘 모릅니다.
  5. 다른 앱이 사용할 API를 노출시키는 여러 가지 대안을 제공합니다.

이 경로를 사용하면 (원래 게시물에서 복사하여 붙여 넣는 것을 용서하십시오) 별도의 웹 응용 프로그램에서 백그라운드 논리를 실행하는 것이 좋습니다. 여기에는 여러 가지 이유가 있습니다.

  1. 보안 . 실행중인 백그라운드 프로세스에 대한 정보를 표시하는 UI에 대해 다른 보안 모델이있을 수 있습니다. 이 UI를 ops 팀 이외의 다른 사람에게 공개하고 싶지 않습니다. 또한 웹 응용 프로그램은 높은 권한 집합을 가진 다른 사용자로 실행될 수 있습니다.
  2. 유지 보수 . 프런트 엔드 웹 사이트를 사용하는 사용자에게 영향을주지 않으면 서 백그라운드 프로세스를 호스팅하는 응용 프로그램에 변경 내용을 배포 할 수 있으면 좋을 것입니다.
  3. 성능 . 사용자 요청을 처리하는 기본 사이트에서 응용 프로그램을 분리하면 백그라운드 스레드가 들어오는 요청 큐를 처리하는 IIS의 기능을 감소시키지 않습니다. 또한 필요한 경우 백그라운드 작업을 처리하는 응용 프로그램을 별도의 서버에 배포 할 수 있습니다.

이렇게하면 마샬링 측면으로 돌아갑니다. WCF, NServiceBus / RabbitMQ / ActiveMQ 등, 바닐라 MSMQ, RESTful API (MVC 생각)가 모두 옵션입니다. Windows Workflow 4.0을 사용하는 경우 웹 앱이 사용할 수있는 호스트 엔드 포인트를 노출시킬 수 있습니다.

서비스에 대한 웹 호스팅 접근 방식은 여전히 ​​나에게 매우 새롭습니다. 올바른 선택인지 시간 만 알 수 있습니다. 그래도 지금까지는 좋습니다. 그건 그렇고, AppFabric을 사용하고 싶지 않다면 (기괴한 이유로 Windows Server Web Edition이 지원되지 않기 때문에) Gu의 게시물에 언급 된 자동 시작 기능이 훌륭하게 작동합니다. 그래도 applicationhost.config 파일에서 벗어나십시오. 해당 게시물의 모든 내용은 IIS 콘솔 (기본 서버 수준의 구성 편집기)을 통해 설정할 수 있습니다.

참고 : 원래이 메시지에 링크를 몇 개 더 게시했지만 아쉽게도이 교환에 대한 첫 번째 게시물이며 하나의 링크 만 지원됩니다! 기본적으로 두 가지가있었습니다. Google에 "Windows 서비스로의 죽음 ... 긴 라이브 AppFabric!" 및 "auto-start-asp-net-applications". 미안합니다.


별도의 웹 사이트를 서비스로 사용한다는 기본 아이디어는 제가 생각하지 못한 흥미로운 아이디어입니다.
Kevin Montrose

Rohland, 여기에 뭔가 빠졌을 수도 있지만 NServiceBus 처리기 내부에서 Windows 서비스와 상호 작용하고 있다고 말한 것처럼 서비스가 전자 메일을 보냅니다. 내가 옳다면 NServiceBus 메시지 처리기에서 전자 메일을 보내지 않는 이유를 물어볼 수 있습니까? 개발, 테스트 및 배포가 매우 쉽습니다.
Sean Kearon

웹 사이트는 Windows 서비스에 메시지를 보냅니다. Windows 서비스 NServiceBus 메시지 핸들러는 메시지를 받아 메시지를 보냅니다. 본질적으로, 그것은 당신이 묘사하는 과정과 동일합니다.
Rohland

22

실제로 Windows에는 백그라운드 서비스를 실행하는 세 번째 방법이 있으며 UNIX 세계에서는 매우 일반적입니다. 세 번째 방법은 CRON인프라를 실행하는 작업입니다. Windows에서는 이것을라고 task scheduler하며 예약 된 코드 실행에 매우 일반적입니다. 이를 사용하려면 미리 정의 된 일정에 따라 실행되는 명령 줄 앱을 만듭니다. 이 방법의 장점은 프로세스가 서비스처럼 유지되고 실행되는 경우 걱정할 필요가 없다는 것입니다. 어떤 이유로 프로세스가 실패하면 다음 번에 시작되기 때문입니다.

특정 작업을 마샬링하는 경우 이러한 작업을 영구 이진 저장소에 저장하면됩니다. 명령 행 앱이 스토리지에서이를 선택하고 실행할 때까지. 과거에 Cassandra 데이터베이스를 세션 상태 제공자로 사용하여 Cassandra 데이터베이스의 특정 사용자에 대한 백그라운드 작업을 채우고 명령 줄에서이를 선택하여 사용자를 위해 실행했습니다.

이것은 일반적인 마샬링 솔루션은 아니지만 나에게 매우 잘 작동했으며 예약 된 작업이 종료, 네트워크 문제를 극복하고 모든 컴퓨터가 중앙 집중식이므로 작업을 실행할 수 있기 때문에 매우 우아한 솔루션으로 판명되었습니다 저장되었습니다.

부끄러운 승진이지만 이것이 내 프로젝트이며 방금 상세하게 설명한 솔루션이 프로젝트를 만든 이유입니다. http://github.com/managedfusion/fluentcassandra/


2
쉘 액세스 권한이 없으므로 공유 호스팅 서비스 로이 작업을 수행합니다. 중요한 작업을 수행하는 PHP 페이지를 작성한 다음 wget 또는 lynx를 사용하여 주기적으로 페이지를로드하는 크론 작업을 수행하십시오. 이것은이 경우에 효과가 있고 매우 간단하여 현재 수행되는 방식에 대한 변경이 거의 필요하지 않은 것 같습니다.
Ricket

간단한 해결책입니다. 아직 고려하지 않은 내 프로젝트에 대한 아이디어를 얻었습니다. 또한 기존 코드베이스에 대한 전체 액세스 권한이 있습니다. 솔루션에 콘솔 프로젝트를 추가하고 기존 프로젝트를 참조하십시오.
Tim Murphy

10

크론 + 웹 앱

이것은 웹 팜과 함께 수평으로 확장 되고 이미 알고 있는 웹 기술 스택 을 사용하고 있는지 테스트 한 디자인입니다 .

작동 방식은 다음과 같습니다.

  1. 예약 된 백그라운드 작업을 처리하기 위해 웹 응용 프로그램에서 컨트롤러 / 액션을 만듭니다. 관례에 따라, 나는 보통 내 전화 http://mydomain.com/system/cron합니다.
  2. 보안을 위해이 조치는 로컬 네트워크에서 인증 된 IP 주소로만 잠 가야합니다.
  3. 별도의 시스템에서 Wget 을 설치하고 스케줄 된 태스크 를 설정하여 wget이 1 단계에서 자원을 페치하도록하십시오. 태스크를 원하는만큼 자주 실행할 수 있습니다 (보통 30 초 선택). 웹 쿠키를 인증 할 수 있도록 적절한 쿠키 인수를 Wget에 전달하는 것을 잊지 마십시오.
  4. 중복성을 위해 두 번째 시스템에 두 번째 스케줄 된 wget을 설치할 수도 있습니다.

만세! 이제 30 초마다 호출되는 경로가 있습니다. 요청을 처리하는 데 5 분이 걸리면 사용자의 페이지 요청에 포함되지 않기 때문에 아무도 신경 쓰지 않습니다.

cron작업은 매우 단순 해 보입니다. 특정 주파수에서 실행할 메소드 목록이 있습니다. 요청이 들어 오면 실행해야 할 메소드가 있는지 확인하고 적절한 메소드를 호출합니다. 이는 데이터베이스에서 일정을 제어 할 수 있음을 의미하며 , 이미 사이트에 대한 다른 중요한 구성 데이터가 많이있을 수 있습니다.

더 중요한 것은 (당신을 위해) 고정 된 일정으로 작업을 호출 할 필요가 없다는 것을 의미합니다. 메소드 실행시기를 결정하기 위해 원하는 로직을 작성할 수 있습니다.

장점과 단점

찬성
  • 이미 ASP.NET MVC 코드 작성에 능숙하므로 나머지 솔루션을 작성하는 것과 동일한 플랫폼 에서 백그라운드 작업을 작성할 수 있습니다 .
  • 작업은 웹앱과 동일한 컨텍스트에서 실행되므로 캐시를 공유하고 이미 존재하는 도우미 메서드 를 사용할 수 있습니다 .
  • 로드 밸런싱 된 URI를 wget으로 가져 오면 백그라운드 작업도로드 밸런싱됩니다.
  • 동시 배포 -웹 응용 프로그램을 백그라운드 작업 논리와 동기화 할 필요가 없습니다. 모두 동일한 배포에 있기 때문입니다.
단점
  • 수년에 걸쳐, 몇몇 사람들은이 디자인이 "높게 결합되어있다"고 말했지만, 눌 렸을 때 왜 그것이 나쁜지를 분명히 말할 수 없었습니다.

참고 : 궁금한 점이 있으면 의견을 추가하십시오 . 정교하게 기쁘다.


7

현재 응용 프로그램에서 가능한 모든 방법을 시도하고 사용했습니다. 나는 당신이 현재하고있는 것과 똑같은 일을 시작했습니다. 사용자 요청에 따라 데이터를 채우고 다시 캐시합니다. 나는 이것이 나쁜 생각이기도하다는 것을 깨달았습니다 (특히 여러 웹 서버로 확장할수록 더 많은 사용자가 적중합니다).

또한 ASP.NET 응용 프로그램에서 URL에 도달하는 예약 된 작업이 있습니다. 이것은 괜찮은 솔루션이지만 1 대의 웹 서버를 지나서 확장하는 순간부터 분해되기 시작합니다.

현재 저는 두 가지 다른 방법을 사용하고 있습니다. Quartz.NET은 훌륭한 작은 라이브러리입니다. 첫 번째는 ASP.NET과 함께 프로세스에서 실행되는 Quartz.NET이며 global.asax에 설치되며 몇 분마다 실행됩니다. 이를 사용하여 ASP.NET 캐시를 대역 외로 업데이트합니다. 이것이 ASP.NET의 일부로 실행되는 유일한 이유입니다.

두 번째는 DaemonMaster라는 Quartz.NET을 래핑하기 위해 라이브러리를 작성했다는 것입니다. DLL을 디렉토리에 쉽게 넣고 Windows 서비스에서 실행할 수 있습니다. Windows 서비스 작업의 성가신 부분을 피하고 Quartz.NET API를 정리하는 데 도움이됩니다. DaemonMaster를 통해 실행되는 서비스는 서로 다른 두 가지 방식으로 이루어지며, 첫 번째는 매일 밤 또는 X 분마다 실행해야하는 작업입니다. 다른 작업은 ASP.NET 응용 프로그램에서 들어오는 데이터를 기반으로 대기열에서 작동합니다. ASP.NET 앱은 RabbitMQ에서 JSON 객체를 삭제하고 서비스는 RabbitMQ를 폴링 한 다음 데이터를 처리합니다.

이를 바탕으로 Windows 서비스를 사용하고 DaemonMaster를 확인하고 ASP.NET 앱에서 서비스로 데이터를 전달하기 위해 RabbitMQ와 같은 대기열을 사용하는 것이 좋습니다.이 모든 솔루션 중에서 가장 잘 작동했습니다. . 캐시를로드하는 경우 ASP.NET에서 실행하는 것이 합리적입니다. 그렇지 않으면 그렇지 않습니다.


6

올바른 방법으로 "큐"를 모니터링하는 Windows 서비스를 실행하고 있습니다. MSMQ로 프로그래밍하는 것이 당신의 눈알에 핫 포커를 꽂는 것과 유사하기 때문에 나는 "큐"라고 말합니다.

Delayed :: Job in Rails 의 단순성에 푹 빠졌 으며 .NET에서 비슷한 것을 쉽게 수행 할 수 있습니다.

기본적으로 어떤 종류의 SomethingOperation( Perform()메소드 가있는 것) 을 추가합니다 . 그런 다음 관련 매개 변수를 직렬화하고 우선 순위를 지정하고 일종의 기본 재시도 동작을 데이터베이스에 넣습니다.

서비스는 이것을 모니터하고 대기열의 작업을 수행합니다.


관련 매개 변수를 직렬화하는 것은 실제로 "단지"가 아니라 거의 "모두"입니다. 별도의 프로세스 접근 방식에 대한 저의 큰 예약 중 하나입니다.
Kevin Montrose

예, 그것은 내가 사용한 것과 같은 해결책이지만, 전체 객체를 데이터베이스에 바이너리로 직렬화 한 다음 실행하기 위해 꺼내 었습니다. Cassandra를 영구 저장소로 사용하고 작업 스케줄러를 작업을 실행하고 실행할 명령 줄 앱의 CRON 스케줄러로 사용했습니다.
Nick Berardi

메시지에 간단한 데이터를 포함시키고 전체 객체를 던지는 것으로 시작했습니다. 여전히 훌륭하게 작동했습니다. 다른 이점도 있기 때문에 분리를 고려할 것입니다.
Nathan Palmer

@ 케빈 (Kevin)-만약 우리가 직렬화 역사가 많은 사람들 만 있다면 ...
Marc Gravell

4

우리는 Service Bus / Message Queue / Service 접근 방식에 매우 만족했습니다. 기본 아키텍처는 이것입니다.

웹 사이트가 대기열에 메시지를 보냅니다.

bus.Send(new ProjectApproved()); // returns immediately

Windows 서비스는 자체 시간에 메시지를 받고 처리합니다.

public class DoesSomethingAwesome : ConsumerOf<ProjectApproved>
{
   public void Consume(ProjectApproved Message)
   {
      // Do something "offline"
   }
}

사용자가 연결된 프런트 엔드 서비스에 대한 지연이 없다는 장점이 있습니다. 기본 서비스를 중단하지 않고 Windows 서비스를 종료하고 업그레이드 할 수 있습니다. 또한 매우 빠릅니다 .

메시지 내에 모든 데이터를 저장할 수없는 경우 언제든지 데이터를 저장하고 나중에 검색 할 수 있습니다. RavenDB 또는 MongoDB 와 같은 문서 저장 메커니즘 을 사용하여 클래스를 변경하지 않고 바로 저장하는 것이 좋습니다 .

웹 사이트가 대기열에 메시지를 보냅니다.

// Save your object
store.Save(completeProject);

// Send a message indicating its ready to be processed
bus.Send(new ProjectApproved() { ProjectId = completeProject.Id });

Windows 서비스는 자체 시간에 메시지를 받고 처리합니다.

public class DoesSomethingAwesome : ConsumerOf<ProjectApproved>
{
   public void Consume(ProjectApproved Message)
   {
      // Retrieve your object back
      var completeProject = store.Get(Message.ProjectId);
   }
}

Rhino ESBTopshelf : 우리는 간단한 작업을 위해 사용 합니다. 구성은 매우 간단하며 기존 응용 프로그램에 적용하면 시간이 거의 걸리지 않습니다.


어쨌든, CQRS와 서비스 버스를 사용하면 확장 성을 향상시킬 수있는 좋은 방법 항상
thinkbeforecoding

3

두 가지의 조합이 실행 가능한 옵션이 아닌 이유가 궁금합니다. 지금은 페이지보기에서 작업을 시작합니다. 불행한 수액이 페이지가 나타날 때까지 10 초 동안 멈추는 현상이 발생합니다. 적어도 그것은 당신의 현재 방법에 대한 나의 이해입니다.

그러나 사이트가 커짐에 따라 이러한 작업을 실행하는 데 점점 더 오랜 시간이 걸리며 사이트에서 사용자 경험을 방해하고 싶지 않습니다. 하루 종일 불행한 사용자 몇 명 (혹은 많은 사람)조차도 아니므로 이제는 백그라운드에서 작업을 예약하는 것을 생각하고 있습니다.

정기적으로 백그라운드 작업을 실행하여 방문자를 모방 할 수없는 이유는 알 수 없습니다. 이제 저는 Windows 프로그래머는 아니지만 Linux 세계에서는 정기적으로 실행되는 cron 작업을 설정하고 2 줄의 코드가 있습니다.

#!/bin/bash
wget -O /dev/null http://stackoverflow.com/specially_crafted_url

두 시스템의 장점을 결합한 것입니다. 백그라운드에서 수행됩니다. 사용자에게는 영향을 미치지 않습니다. 여전히 페이지보기를 사용하여 작업을 시작합니다. 나는이 접근법이 전에 사용 된 것을 보았습니다. 그것은 예전의 단순한 방법과 길을 내려 오는 복잡한 방법 사이의 중간 지점 인 경향이 있습니다.

최신 정보

웹 서버 자체에서 작업 실행기를 실행하여 부하 분산 문제를 해결할 수 있다고 생각합니다. 작업 러너는 작업 큐에서 URL을 가져 와서 다음과 같이 실행합니다.

wget -O /dev/null http://localhost/specially_crafted_url

작업 / 메시징 대기열의 특성으로 인해 작업은 작업 실행자간에 균등하게 분배됩니다. 이는 특별히 _eded_url이 결국 웹 서버에 분산됨을 의미합니다.


우리는 이미 예측 가능한 간격으로 실행되는 모든 것에 대해 이미 그렇게하고 있습니다. 우리가 남긴 것은 너무 멀리 예측할 수없는 것입니다. 예를 들어, "관련 질문 블록"은 최근에 본 질문에 대해서만 업데이트됩니다. 태그가 지정된 질문 목록도 마찬가지로 누군가가 해당 태그를 확인하려는 경우에만 캐시됩니다. 우리는 백만 건이 넘는 질문에 25k 태그에 접근하기 때문에 "만약을 위해"모든 관련 작업을 실행할 수는 없습니다.
Kevin Montrose

SO가 여러 서버에 분산되어 있으므로로드 밸런스 문제도 있습니다. 기본적으로 stackoverflow.com으로 이동하면 항상 같은 서버에 도달합니다. wget 방식을 사용하면 모든 작업을 단일 서버로 마샬링해야하며 (또는 실제로로드 밸런싱 설정을 재 작업해야 함) 이는 매우 고통스러운 일입니다.
Kevin Montrose

그래도 물건이 규칙적인 간격으로 실행된다면 좋을까요? 나는 당신이 말하는 것을 이해하지만 위에서 설명한 방법론 (그리고 다른 사람들이 언급 한 것)은 바뀌지 않습니다. 페이지보기에 "이 작업을 실행할 시간입니다"라고 표시되면 작업을 메시지 큐에 고정시킵니다. 오래 실행되는 백그라운드 작업은 찾은 작업을 실행합니다. 이 경우 작업은 요청해야하는 URL에 지나지 않습니다. hehe 아마도 코드베이스가 필요하지 않기 때문에 한 달에 $ 20 공유 서버에 이것을 설정할 수 있습니다. 메시징 서비스를 쉽게 사용할 수 있도록 Amazon SQS를 살펴보십시오.
mellowsoon

로드 밸런스 문제와 관련하여. 뜻이있는 곳에 길이있다! stackoverflow.com에 요청하는 대신 IP 주소를 사용하여 서버에 무작위로 도달 할 수 있습니다. 로드 밸런서가 요청을 파이프하기 위해 쿠키를 확인하면 쿠키를 위조 할 수 있습니다. IP 주소를 확인하면 서버의 응답에 신경 쓰지 않기 때문에 가짜 일 수도 있습니다.
mellowsoon

로드 밸런싱이 이를 수행하지 않는 이유는 아니라고 동의했습니다 . 요청 specially_crafted_url은 알려진 IP에서 온 것이기 때문에로드 밸런서에 규칙을 추가하여 해당 IP의 요청에 대해서만 라운드 로빈을 수행 할 수 있습니다.
Portman

2

순수한 서비스 접근 방식의 단점은 서비스에 코드가 흩어져 있고 핵심 앱에서 떨어져 있다는 것입니다.

시간에 민감하지 않은 대규모 백그라운드 작업으로 수행 한 작업은 다음과 같습니다. 코드를 함께 유지하고 서비스를 단순화합니다.

  1. 작업 대기열을 생성합니다 (작업 유형에 필요한 지속성에 관계없이 메모리 내 또는 DB).
  2. 대기중인 작업을 실행할 웹 서비스를 만듭니다.
  3. 지정된 간격으로 웹 서비스를 호출하는 죽은 간단한 서비스 응용 프로그램은 모든 복잡한 작업 (작업 검색 및 실행)을 핵심 코드베이스의 웹 서비스에 남겨 둡니다.

더 간단하게 콘솔 응용 프로그램에서 전화를 걸고 작업 스케줄러 또는 VisualCron을 사용하여 "서비스"로 바꾸십시오.


1
나는 웹 응용 프로그램을 주기적으로 트리거하는 Windows 서비스 인 직장의 중요한 응용 프로그램에서 정확하게 이것을 얻었습니다. 웹 앱은 상태 비 저장 상태로 유지되며 필요에 따라 데이터베이스에서 상태를 가져옵니다. 치료를합니다.
Bevan

1

나는 TopShelf를 좋아했다. 단순성을 유지하면서도 Windows 서비스로 실행되는 올바른 방법을 수행하십시오. 기본적으로 콘솔 응용 프로그램을 만들고 약 15-20 줄의 코드를 추가 한 다음 서비스로 설치하십시오.

http://code.google.com/p/topshelf/


1

웹 서버에서 실행되고 기타 작업을 수행하는 유지 관리 URL에 주기적으로 도달하는 매우 간단한 Windows 서비스를 사용하는 것은 어떻습니까? 주어진 요청에서 얼마나 많은 작업을 수행하는지 조절하십시오.


1

나는 여기서 명백한 추세를 극복하고 in-IIS 모델로 갈 것을 제안합니다. 나는 그것을 직접 사용했으며 실제로 잘 작동합니다. 적절한 스레드 풀 클래스를 구현하는 것은 그리 어렵지 않습니다 (수년에 걸쳐 스레드의 동적 생성 및 삭제, 작업 재시도 등을 지원하도록 스레드 풀 클래스를 확장했습니다). 장점은 다음과 같습니다.

  • 모니터링 할 외부 서비스가 없습니다.
  • 구현의 단순성 : 프로세스 간 마샬링, 고급 작업 모니터링 없음
  • 여전히 IIS 프로세스 내부에 있으므로 일반적인 모든 로깅 등을 수행 할 수 있습니다 (여러 로그 파일 필요 없음)
  • 크게 단순화 된 배포 (서비스를 업데이트 할 때 서비스를 중지하고 파일을 복사하고 서비스를 시작해야합니다. 웹 사이트 코드에 대한 일반적인 업데이트에 추가됨)

제 생각에 IIS 내 솔루션은 작업을 임의의 페이지보기로 피기 백하는 것에서 "다음 단계"입니다.


1

Resque 는 좋습니다. 또는 일단 완료되면 결과 값을 통보 받아야하는 경우 Kthxbye 조차도 .

Redis / Ruby 기반 tho.

솔직히 서비스 기반 접근 방식을 사용하는 경우 실제로 현재 플랫폼과 슈퍼 통합 할 필요가 없습니다. 나는 (어떤 종류의 모니터링으로) 실행되고 완전한 작업을 수행하는 설정 및 잊어 버린 시스템이되기를 바랍니다. 데이터베이스 정보를 업데이트 / 수정하기 때문에 동일한 플랫폼에서 전혀 실행하지 않아야합니다.

이 종류의 작업을 별도의 엔터티로 농사하면 스레드 문제를 다루는 것처럼 보이기 때문에 훨씬 더 많은 것을 얻을 수 있습니다. 두 ResqueKthxbye는 OS를 병행 처리 할 수 있도록 별도의 프로세스로 처리를 이동한다.

Resque

Kthxbye


위대한 이름 때문에 Kthxbye를 시도해야합니다!
Nathan Palmer

거의 굉장합니다. 다음은 ORLY가 될까요? 도서관. 아마 어떤 종류의 통계 모니터링을 위해 ...;)
Lukas

0

MSMQ 큐를 수신하는 WAS 호스팅 WCF 서비스를 사용합니다.

프로

  • 웹 앱에서 단방향 메시지를 실행하고 잊어 버리십시오.

  • MSMQ / WCF 조절 및 재시도

  • 배달 보장; D

  • 데드 레터 관리

  • 분산 처리

  • WAS / MSMQ 활성화

사기

  • MSMQ (죽지 않았다 ... 아직)

WCF의 MSMQ 기능은 MSMQ 사용을 정말 멋지게 만듭니다. 그렇습니다. 당신은 구성에서 피를 흘리지 만 이점은 희생보다 중요합니다.


0

웹 응용 프로그램을 개발할 때이 문제를 두 번 겪었습니다. 우리는 작업을 수행하는 Windows 콘솔 응용 프로그램을 만들고 실제로 작업을 수행하기 위해 너무 자주 실행되는 예약 된 작업을 만들어서 해결했습니다.


0

Rx 및 다음과 같은 것을 사용하여 백그라운드 스레드 (또는 많은 백그라운드 스레드)로 작업을 분류 할 수 있습니다.

var scheduler = new EventLoopScheduler( SchedulerThreadName );
_workToDo = new Subject<Action>();
var queueSubscription = _workToDo.ObserveOn( scheduler ).Subscribe( work => work() );
_cleanup = new CompositeDisposable( queueSubscription, scheduler );

사용:

var work = () => { ... };
_workToDo.OnNext( work ); // Can also put on error / on complete in here

하나의 클래스 (일명 싱글 톤이지만 올바르게 수행하십시오-라이프 스타일을 결정하기 위해 IoC 컨테이너를 사용하십시오)가있는 클래스 내부의 모든 것을 호스팅하십시오.

단일 스레드를 실행하는 EventLoopScheduler를 사용하는 대신 사용자 정의 스케줄러를 작성하여 스레드 풀의 크기 등을 제어 할 수 있습니다.


0

이 유형의 것을 몇 번 구현했습니다. Windows에서는 다양한 시간에 무언가를 수행하는 Python 명령 줄 프로그램을 설정했습니다. 이 프로그램은 또한 포트에서 xmlrpc 인터페이스를 제공합니다. 그런 다음 예약 된 작업이 1 분마다 실행되고 xmlrpc 인터페이스를 쿼리합니다. 작동하지 않으면 시작을 시도합니다. 이메일을 보낼 수 없으면 이메일로 알려줍니다.

장점은 실행되는 작업이 크론 또는 스케줄 제한이 없다는 것입니다. 매초마다 실행되는 프로세스 작업이 있지만 작업이 있는지 여부에 따라 새 작업을 시작할 때까지 더 오래 기다릴 것입니다. 또한 결과에 따라 지능적으로 행동하는 데 사용될 수 있습니다. 500 오류가 있습니까? 정말 긴 지연이 있습니까? 다른 것을하십시오. 다른 서비스에 알립니다. 기타.

그리고 동일한 시스템이 약간의 수정으로 유닉스에서 작동합니다.


0

나는 당신에게 스스로 답을 얻지 못했지만 문제는 울려 퍼졌다. 나는 팟 캐스트에서 한 번 이야기 했던 임의의 사람들을 기억한다 .

Spolsky : 블로그에서 질문 한 질문 중 하나가 일반적인 유지 관리 작업을 어떻게 처리해야하는지 알았습니다.

앳 우드 : 그렇습니다.

Spolsky : 이것이 공정한 특성입니까? 모든 웹 사이트에는 웹 페이지를로드 할 때 실행하고 싶지 않은 작업이 있지만 어떤 종류의 되풀이로 실행하려고합니다.

Atwood : Ya, 백그라운드 작업은 일종의 것입니다.

Spolsky : 예, 무엇을 알아 냈습니까?

Atwood : 글쎄, 나는 단지 가벼운 무게를 원했기 때문에 원래 트위터에 물었다. Windows 서비스를 작성하고 싶지 않았습니다. 나는 그것이 밴드 코드를 벗어난 것처럼 느꼈다. 또한 실제로 작업을 수행하는 코드는 실제로 웹 페이지입니다. 왜냐하면 웹 사이트의 논리적 작업 단위이기 때문에 웹 페이지이기 때문입니다. 따라서 웹 사이트를 다시 호출하는 것과 마찬가지로 웹 사이트의 다른 요청과 똑같으므로 인라인으로 유지해야하는 것으로 보았으며 우리가 제안한 작은 접근 방식은 Twitter에서 나에게 권장되었습니다. 본질적으로 고정 만료로 응용 프로그램 캐시에 무언가를 추가하는 것이 었습니다. 그러면 콜백되므로 만료되면 작업을 수행하는 특정 함수를 호출 한 다음 동일한 만료로 캐시에 다시 추가합니다.


1
예, StackOverflow보다 훨씬 작은 사이트에서 작동합니다. 불행히도 (또는 운 좋게도 어떻게 보느냐에 따라) 스케일은 큰 문제입니다.
Kevin Montrose

@Kevin Montrose, 나는 완전한 도메인 무지를 여기에서 요구한다. 비밀 웹 페이지가 왜 작업을 수행하고 (아마도 작은 단위로) 확장 할 수없는 다른 페이지 / 크론 작업에 의해 호출되는지 이유를 설명해 주시겠습니까? 당신이 옳다는 것을 의심하지는 않지만 배우고 싶습니다.
Oddthinking

ASP.NET의 모든 캐시 만료가 단일 스레드를 실행하기 때문에 특정 제안 (캐시 만료)은 확장되지 않습니다 (SO와 같은 소규모 사이트의 영리한 해킹입니다). 우리는 단일 서버를 타격 할 것이다 단일 서버 (아직도 성장 SO 지금 3 등) 및 크론 작업을 넘어 섰지 때문에 크론 작업이 확장되지 않습니다 (적어도, 그 불변을 변경하는 것이 정말 우리의 하중 - 고통스러운 밸런스 설정). cron 작업은 분 단위로 반복되므로 매우 자주 실행해야합니다.
Kevin Montrose

우리는 덜 자주 실행되는 고정 된 간격, 이미 수행 된 작업, 배지 부여 및 일일 전자 메일 알림과 같은 작업에 대해 "크론 스타일"일정을 사용한다는 점에 주목할 가치가 있습니다.
Kevin Montrose

0

작업 대기열 Java API 개요

작업 개념
App Engine 백그라운드 처리에서 작업은 작은 작업 단위에 대한 완전한 설명입니다. 이 설명은 두 부분으로 구성됩니다.

  • 작업을 매개 변수화하는 데이터 페이로드.
  • 작업을 구현하는 코드입니다.

오프라인 웹 후크
와 같은 작업 다행히도 인터넷은 이미 HTTP 요청 및 응답 형식으로 이러한 솔루션을 제공합니다. 데이터 페이로드는 웹 양식 변수, XML, JSON 또는 인코딩 된 이진 데이터와 같은 HTTP 요청의 내용입니다. 코드 참조는 URL 자체입니다. 실제 코드는 서버가 응답을 준비 할 때 실행하는 모든 로직입니다.


GAE 작업 대기열 API를 사용하는 것이 아니라 모델을 따르는 것이 좋습니다. 그들은 잠시 동안 그것을 통해 생각하고 구현을 썼습니다.
antony.trupe

0

둘 다

현재 사용자 요청에 대해 피기 백 작업을 수행하는 질문 경로에 선택적 매개 변수를 추가하십시오.

대규모 사이트에서 백그라운드 작업 서비스

각 서버에서 실행되는 콘솔 응용 프로그램을 만들고 IIS 로그 공유 바이너리를 열어 파일의 현재 끝에서 읽습니다. IIS가 로그를 플러시 할 때 업데이트를 수집하려면 파일 시스템 감시자 또는 시간 간격을 사용하여 앞으로 읽습니다.

이 정보를 사용하여 현재 본 페이지를 판별하십시오.

구문 분석 된 로그의 페이지 URL을 사용하여 웹 클라이언트 객체를 사용하여 localhost에서 URL의 "추가"버전을 호출하십시오.

각 로그 기간이 끝날 때 파일을 전환하려면 일부 코드를 추가하거나 각 로그 기간마다 프로세스를 다시 시작하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.