2011-11-28 12 views
8

Pracuję nad aplikacją internetową, która jest aplikacją opartą na chmurze dla wielu dzierżawców (wieloma klientami, z których każde ma osobne "środowisko", ale wszystkie na wspólnych zestawach sprzętu) i wprowadzamy możliwość grupowania przez użytkownika zadań do późniejszego przetworzenia. Typy pracy grupowanej naprawdę nie są ważne, to tylko wystarczająca ilość, że robienie tego bez kolejki pracy nie jest zbyt praktyczne. Wybraliśmy RabbitMQ jako naszą podstawową strukturę kolejkową.Pule pracownicze i kolejki dla wielu dzierżawców z RabbitMQ

Ponieważ jesteśmy aplikacją dla wielu dzierżawców, niekoniecznie chcemy, aby klienci mogli powodować długie czasy kolejkowania dla innego klienta, więc jednym z pomysłów, które wprowadziliśmy, jest utworzenie kolejki na w oparciu o klienta i posiadające wspólną pulę pracowników wskazaną we WSZYSTKICH kolejek klienta. Problem polega na tym, że najlepiej jak mogę sobie wyobrazić, pracownicy są bezpośrednio związani z konkretną kolejką, a nie z wymianą. W naszym idealnym świecie nasze kolejki klientów będą nadal przetwarzane, bez jednego klienta blokującego inne, z udostępnionej puli pracowników, którą będziemy mogli powiększać lub zmniejszać w razie potrzeby, uruchamiając więcej pracowników lub zamykając nieaktywne. Posiadanie pracowników przywiązanych do określonej kolejki przeszkadza nam w praktycznym tego sensie, ponieważ często mamy wielu pracowników, którzy pracują w kolejce bezczynności.

Czy jest to stosunkowo proste, aby to osiągnąć? Jestem całkiem nowy w RabbitMQ i naprawdę nie mogliśmy osiągnąć tego, o co nam chodzi. Nie chcemy też pisać bardzo złożonej wielowątkowej aplikacji konsumenckiej, to czas na dev i czas testów, na które prawdopodobnie nie możemy sobie pozwolić. Nasz stos jest oparty na Windows/.Net/C, jeśli to jest germaine, ale nie sądzę, że powinno to mieć istotny wpływ na to pytanie.

Odpowiedz

1

Możesz po prostu mieć swoją pulę pracowników wszystkie zużywają tę samą unikalną kolejkę. Prace zostaną następnie rozproszone, a Ty będziesz w stanie zwiększyć/zmniejszyć swoją pulę, aby zwiększyć/zmniejszyć zdolność do pracy.

+1

Nie pytam o przypisanie wielu pracowników do tej samej kolejki, raczej pytam o odwrotność. Chcę, aby skończona pula pracowników zużywała się z dużej (powiedzmy, że ~ 500) liczby kolejek. – bakasan

+1

Sam eksperymentowałem z tego rodzaju podejściem i to nie jest ładne: ciężko jest znaleźć odpowiednią heurystykę do przetworzenia wszystkich tych kolejek. Czy najpierw przetwarzasz najpełniejsze kolejki? Czy te ze starszymi wiadomościami? W obu przypadkach jesteś poza protokołem AMQP i musisz zacząć zajmować się API zarządzania Rabbit. Wtedy myślisz: miejmy taką samą liczbę kolejek niż pracownicy i dodaj spójne hashowanie między 500 Q a kolejek roboczych. Wtedy zdajesz sobie sprawę, że wystarczy jedna kolejka i n robotników, którzy na niej rywalizują. –

+0

Mam podobne wymagania, ale chcę, aby wiadomości od konkretnego klienta były przetwarzane sekwencyjnie. Kontakt nie zostanie usunięty przed utworzeniem itp. Czy istnieje jakaś konfiguracja lub konfiguracja RabbitMQ, która może to zrobić, ale udostępnia kolejkę między pracownikami? (Czy to nowy Q ...?) – Aaron

1

Nie rozumiem, dlaczego nie korzystasz z vhosts RabbitMQ i masz login do aplikacji RabbitMQ i uwierzytelniasz się w oddzielnym połączeniu dla każdego użytkownika.

Nie oznacza to, że nie można mieć pracownika nadzorującego, który przypisuje pracowników jednemu lub drugiemu użytkownikowi. Ale to oznacza, że ​​wszystkie wiadomości dla każdego użytkownika są przetwarzane przez całkowicie oddzielne wymiany i kolejki.

0

Pracownicy otrzymują 0 lub więcej kolejek, a nie wymieniają.

Logika, dla której zostaną wykonane zadania, w których kolejki dla każdego pracownika są zaimplementowane w klasie wskazanej przez CELERYD_CONSUMER, która domyślnie jest .

Możesz utworzyć niestandardową klasę użytkownika ro, która implementuje dowolną logikę. Najtrudniejszą częścią będzie ustalenie szczegółów algorytmu "uczciwości", którego chcesz użyć; ale gdy już to postanowisz, możesz zaimplementować tworzenie niestandardowej klasy konsumenta i przypisanie jej odpowiednim pracownikom.

1

Można spojrzeć na realizację priorytetu kolejki (które nie zostało wykonane, gdy kwestia ta została pierwotnie zadawane): https://www.rabbitmq.com/priority.html

Jeśli to nie zadziała, możesz spróbować innych sieka się osiągnąć to, co chcesz (który powinien działać ze starszymi wersjami RabbitMQ):

Możesz mieć 100 kolejek powiązanych z giełdą tematów i ustawić klucz routingu na mieszanie o identyfikatorze użytkownika% 100, tzn. każde zadanie będzie miało klucz między 1 a 100 i zadania dla tego samego użytkownika będą miały ten sam klucz. Każda kolejka jest powiązana z unikalnym wzorem od 1 do 100.Teraz masz flotę pracowników, którzy zaczynają od losowego numeru kolejki, a następnie zwiększają kolejkę po każdym zadaniu, ponownie% 100, aby wrócić do kolejki 1 po kolejce 100.

Teraz Twoja flota może obsłużyć do 100 pracowników unikalni użytkownicy równolegle lub wszyscy pracownicy mogą skoncentrować się na pojedynczym użytkowniku, jeśli nie ma innej pracy do zrobienia. Jeśli pracownicy muszą przechodzić przez wszystkie 100 kolejek między poszczególnymi zadaniami, w scenariuszu, w którym tylko jeden użytkownik ma wiele zadań w pojedynczej kolejce, naturalnie będziesz mieć pewien nadmiar między każdą pracą. Mniejsza liczba kolejek jest jednym ze sposobów radzenia sobie z tym. Każdy pracownik może również utrzymywać połączenie z każdą kolejką i zużywać do jednej niepotwierdzonej wiadomości od każdej z nich. Pracownik może następnie cyklicznie przechodzić przez oczekujące wiadomości w pamięci znacznie szybciej, pod warunkiem, że ustawiony limit czasu wiadomości jest wystarczająco wysoki.

Alternatywnie można utworzyć dwie wymiany, każda z powiązaną kolejką. Cała praca przechodzi do pierwszej wymiany i kolejki, którą zużywa grupa pracowników. Jeśli jednostka pracy trwa zbyt długo, pracownik może ją anulować i przesunąć do drugiej kolejki. Pracownicy przetwarzają tylko drugą kolejkę, gdy nic nie znajduje się w pierwszej kolejce. Możesz także chcieć dwóch pracowników o odmiennym priorytecie kolejkowym, aby upewnić się, że długo działające zadania są nadal przetwarzane, gdy nadchodzi niekończący się strumień krótkich zadań, tak aby partia użytkowników była ostatecznie przetwarzana. Nie będzie to prawdziwa dystrybucja floty pracowników we wszystkich zadaniach, ale zatrzyma długotrwałe zadania jednego użytkownika powstrzymującego pracowników przed wykonywaniem krótkich zadań dla tego samego użytkownika lub innego. Zakłada także, że możesz anulować zadanie i ponownie uruchomić je później bez żadnych problemów. Oznacza to również, że zostaną zmarnowane zasoby z zadań, których przekroczenie limitu czasu będzie wymagało ponownego uruchomienia z niskim priorytetem. Jeśli nie możesz szybko zidentyfikować zadań szybkich i wolnych

Pierwsza propozycja ze 100 kolejkami może również stwarzać problemy, jeśli istnieje 100 powolnych zadań dla pojedynczego użytkownika, a następnie inny użytkownik wysyła pakiet zadań. Zadania te nie zostaną wyświetlone, dopóki jedno z powolnych zadań nie zostanie zakończone. Jeśli okaże się, że jest to uzasadniony problem, potencjalnie można połączyć oba rozwiązania.

Powiązane problemy