Jak zarządzasz rozszerzalnością w systemach z wieloma dzierżawcami?

13

Mam teraz kilka dużych, opartych na sieci produktów dla wielu najemców, i wkrótce zobaczę, że będzie wiele dostosowań, które są specyficzne dla najemcy.

Dodatkowe pole tu czy tam, może dodatkowa strona lub dodatkowa logika w środku przepływu pracy - tego rodzaju rzeczy.

Niektóre z tych dostosowań można wprowadzić do podstawowego produktu i to świetnie. Niektóre z nich są bardzo specyficzne i mogłyby wchodzić w drogę innym.

Mam na myśli kilka pomysłów na zarządzanie tym, ale żaden z nich nie wydaje się dobrze skalować. Oczywistym rozwiązaniem jest wprowadzenie mnóstwa ustawień na poziomie klienta, umożliwiających włączenie różnych „funkcji” dla poszczególnych klientów. Minusem tego jest oczywiście ogromna złożoność i bałagan. Możesz wprowadzić naprawdę ogromną liczbę ustawień, az czasem różne rodzaje logiki (prezentacja, biznes) mogą wymknąć się spod kontroli. Następnie pojawia się problem pól specyficznych dla klienta, który prosi o coś czystszego niż dodanie do istniejących tabel kilku pól zerowalnych.

Co więc robią ludzie, aby sobie z tym poradzić? Force.com wydaje się być mistrzem rozszerzalności; oczywiście stworzyli platformę od podstaw, która jest super rozszerzalna. Możesz dodać do prawie wszystkiego za pomocą interfejsu internetowego. FogBugz zrobił coś podobnego, gdy stworzył solidny model wtyczki, który, jeśli się nad tym zastanowić, mógł być zainspirowany Mocą. Wiem, że poświęcili na to dużo czasu i pieniędzy i jeśli się nie mylę, zamierzałem wykorzystać je wewnętrznie do przyszłego rozwoju produktu.

Brzmi jak coś, co kusiło by mnie do zbudowania, ale prawdopodobnie nie powinno. :)

Czy jedyna droga to ogromna inwestycja w architekturę wtykową? Jak radzisz sobie z tymi problemami i jakie widzisz wyniki?

EDYCJA: Wygląda na to, że FogBugz poradził sobie z tym problemem, budując dość solidną platformę, a następnie wykorzystując ją do złożenia swoich ekranów. Aby go rozszerzyć, należy utworzyć bibliotekę DLL zawierającą klasy, które implementują interfejsy, takie jak ISearchScreenGridColumn, i która staje się modułem. Jestem pewien, że zbudowanie tego urządzenia było niezwykle drogie, biorąc pod uwagę, że mają dużą liczbę programistów i pracowali nad nim przez miesiące, a ich powierzchnia wynosi prawdopodobnie 5% wielkości mojej aplikacji.

W tej chwili poważnie zastanawiam się, czy Force.com jest właściwym sposobem na poradzenie sobie z tym problemem. Jestem twardym facetem ASP.Net, więc jest to dziwna pozycja, w której mogę się znaleźć.

Brian MacKay
źródło
3
Zgaduję, że to jest pytanie SO, co czyni z tego identyczny krzyżowy post. Nie rób tego, poproś o migrację tutaj pytania SO lub jeśli szukasz różnych odpowiedzi, powiedz nam dokładnie, dlaczego odpowiedzi na pytanie SO nie są satysfakcjonujące.
yannis
Masz rację, pytanie jest lepsze dla programistów, ale nadal wydaje się, że masz dość przyzwoite odpowiedzi. Zredagowałem pytanie, aby odwołać się do pytania SO.
wałek klonowy

Odpowiedzi:

8

Napotkałem podobny problem i powiem ci, jak to zrobiłem.

  1. Po pierwsze, istnieje biblioteka lub silnik „rdzenia”. To w zasadzie prowadzi program, o ile już się zorientowałeś. Obsługuje rzeczy wspólne dla każdego systemu, od dynamicznego renderowania formularzy, zarządzania użytkownikami i kontami, ról, jak go nazywasz, robi to.

  2. Każda część systemu jest zawarta w module. Moduł ma zależności (inne moduły, od których zależy). Na przykład system „podstawowy” ma zabezpieczenia (użytkownicy, grupy, role, zasady haseł), ustawienia regionalne (tłumaczenia, kraje, kultury), repozytorium plików, e-mail itp. Każdy moduł definiuje się za pomocą pliku xml. Plik xml zasadniczo określa schematy, tabele, klasy obliczeniowe, definicje ekranów itp. Są one odczytywane podczas uruchamiania aplikacji, jeśli data pliku uległa zmianie .

  3. Moduły specyficzne dla klienta mają własne pliki xml i własną bibliotekę DLL. Wszystko plus i działa odpowiednio i przejrzyście z resztą systemu. Aż do zastąpienia istniejących widoków MVC niestandardowymi, niestandardowym kodem i niestandardowymi modelami widoków.

  4. Jeśli klient chce rozszerzyć istniejącą funkcjonalność, xml / system zapewnia metodę, w której mogę „wyprowadzić” jeden moduł z drugiego. Nowy moduł ma wszystkie istniejące funkcje, ale ze specyficznymi wymaganiami klienta w nowej bibliotece DLL oraz z rozszerzonym plikiem XML, który może dokonywać modyfikacji. Zastrzeżenie polega na tym, że w rzeczywistości nie mogą usunąć istniejących pól w tym systemie, ale możemy go rozszerzyć i zapewnić zupełnie nowe obiekty i funkcje.

Sok Moo
źródło
+1: Wygląda na to, że zajęło to godzinę lub dwie. :)
Brian MacKay,
1
@BrianMacKay, cóż, po zakończeniu pracy (i było to hasło reklamowe) nasi klienci byli bardzo zadowoleni z szybkości, z jaką mogliśmy zmieniać personalizacje. Zauważ, że środowisko MVC (tak jak liczba wyświetleń / stron jest zaniepokojona) nie nadaje się zbyt dobrze do bycia wieloma projektami. Rozwiązaliśmy ten problem, korzystając z funkcji właściwości SVN i mając widoki rdzeni sprowadzone z głównego repozytorium, i wykorzystaliśmy CSS / układy, aby to dostosować. Ale rok, dobre kilka godzin: P
Moo-Juice
Ciekawe, jak myślisz, ile czasu zajęło wdrożenie samej architektury i ilu deweloperów było zaangażowanych?
Brian MacKay,
1
@BrianMacKay, to było 5 miesięcy. Jeden programista interfejsu użytkownika, który wykonuje wszystkie widoki CSS / HTML / Częściowe, javascript itp., I jeden programista zaplecza (ja), aby wykonać resztę.
Moo-Juice,
4

Posiadanie dużej ilości logiki wersjonowania i warstw kodu do zarządzania nie stanowi wartości dodanej dla Twojej aplikacji / witryny internetowej. Wymaga także większej mocy mózgu, aby zrozumieć, co się dzieje, i odwraca uwagę od rdzenia tego, co robisz.

Radzę inaczej. Radzę, aby sprawy były proste, a nie złożone.

Zachowaj jedną bazę kodu, która jest taka sama dla wszystkich. Każda dodana funkcja jest funkcją dla wszystkich. Ograniczaj tylko liczbę przedmiotów lub miejsca do przechowywania lub jakieś wymierne rzeczy, a nie funkcje. Powodem jest ilościowe określenie rzeczy, takich jak pamięć, liczba wpisów danych itp., Których programowanie jest tak proste i można je zastosować do niewielkiej garści rzeczy, które naprawdę ograniczają użytkownika do szaleństwa w Twojej aplikacji. To musi być zaprogramowane tylko po dodaniu elementów zamiast logiki funkcji. Co jeśli funkcje są powiązane z innymi funkcjami? Kodowanie tego jest bardzo skomplikowane.

Aby zakwalifikować moją odpowiedź, zbudowałem platformę e-commerce, którą mam dla wielu klientów i nauczyłem się trudnego sposobu zachowania wszystkich ich osobliwości. Skończyło się na zerwaniu łańcucha i stworzyłem jedną stronę administracyjną, która jest wielodostępna dla e-commerce. Następnie mam strony internetowe, które pobierają dane z połączeń serwisowych. Dzięki temu różne zespoły w różnych technologiach mogą wdrażać określone funkcje witryn e-commerce, a ja co miesiąc zarabiam na tej samej infrastrukturze i nie dbam o to, co robią. Ograniczam użycie tylko liczbami, a nie funkcjami. To łatwiejsze. Klient może wybrać własnego dostawcę do budowy swojej witryny i nie jestem już zaangażowany w te decyzje.

Mam również usługę subskrypcji SAAS do zarządzania treścią. Działa to również według poziomów użytkowania, a klienci mogą dodawać własne wtyczki, jeśli chcą, podczas gdy mój zespół dodaje więcej funkcji dla wszystkich.

To tylko moje doświadczenie z uderzenia głową w ścianę po tak długim czasie, a następnie natknięcia się na coś prostszego.

Jeśli coś zawsze będzie specyficzne dla każdego klienta, nie twórz ram dla tego. Podziel go na najprostsze części, aby część ramowa działała dla wszystkich, a następnie wytnij resztę, abyś mógł ją rozszerzyć dla osoby.

Jason Sebring
źródło
+1 za dzielenie się wrażeniami. Wydaje mi się, że wiele z tego, co słyszę to „to bardzo trudny problem”. Rzeczywistość, z którą mam do czynienia, polega na tym, że ten system będzie miał mnóstwo dostosowań i nie wszystkie są odpowiednie dla wszystkich ... Wygląda na to, że mówisz, że podjąłeś podejście polegające na odsłonięciu warstwy usługi, a następnie pozwoleniu innym jakkolwiek chcą - mam tę zaletę, że wszystkie rozszerzenia piszemy wewnętrznie. Ale wciąż jest bałagan do zarządzania (cntd)
Brian MacKay
Doszedłem do wniosku, że musisz napisać platformę, która obsługuje własne pojęcie składników interfejsu i dynamicznej kompozycji, a następnie zbudować całą aplikację przy użyciu tej platformy. Zaczynam więc myśleć, że mądrze byłoby napisać całą treść na force.com, bo taka właśnie jest force.com!
Brian MacKay
Brian, FYI kitgui.com i hubsoft.com, jeśli jesteś ciekawy.
Jason Sebring
2

Oprogramowanie, nad którym pracuję, ma dodatkowe pola dla rozszerzenia użytkownika. Każdy element danych dla tych pól można przypisać do istniejącego wiersza w głównych tabelach aplikacji. Na przykład jeśli twoje oprogramowanie zawiera klientów, a każdy klient listę zamówień, wówczas dostosowywana tabela danych będzie zawierała kolumnę dla kluczy obcych do tabeli klientów i tabeli zamówień, z których tylko jedna będzie inna niż null. Albo to, albo kilka tabel, z których każda ma niestandardowe pola dla jednej tabeli.

Jest to prosty i wydajny sposób przechowywania dodatkowych danych dla użytkownika. Konieczne byłoby przechowywanie dodatkowych informacji o nazwach i typach tych pól.

Dotyczy to niestandardowych pól dla klienta. W przypadku niestandardowego zachowania interfejs API usług internetowych zezwala na rozszerzenia.

krąg
źródło
1

1) Uruchamianie kodu innej osoby na posiadanych urządzeniach jest dość trudnym problemem. Albo możesz im zaufać, albo rozsądnie odroczyć odpowiedzialność, będziesz musiał bardzo mocno wyodrębnić ich kod i mieć ponadprzeciętne przywiązanie do bezpieczeństwa. Ponieważ system wtyczek pozwala na większą funkcjonalność, rośnie trudność zapewnienia bezpieczeństwa. Rzeczy takie jak odmowa usługi (wtyczki zużywają zbyt dużo zasobów), wyciek informacji (wtyczki mogą uzyskiwać dostęp do danych innych najemców) itp. Mogą być bardzo realne i kłopotliwe, nie wziąłbym w tym udziału, chyba że mógłbym bardzo dobrze poznać ludzi te problemy lub bardzo zdolni ludzie, którzy mają dużo czasu, aby to naprawić.

2) Tak, modułowość i możliwości dostosowania są trudne. Takie rzeczy jak wzorzec strategii może pomóc (wymyślna nazwa wskaźników funkcji; w Javie jest zwykle implementowana przez zadeklarowanie interfejsu, który użytkownicy klasy mogą zaimplementować w celu dostosowania zachowania twojego kodu), ale będziesz chciał być bardzo odizolowany i oddzielony kod, aby to działało.

3) Pod względem danych może to być jeden z przykładów przydatnego przechowywania bez schematów. Jeśli masz relacyjny model danych, problematyczne są tabele z dużą ilością kolumn dla różnych klientów (tak, masz wiele zerowalnych kolumn, co jest złe ; jednym z powodów jest to, że ustawienie poprawnych ograniczeń jest trudne lub niemożliwe) ograniczenia, które nie pozwalają na pojawienie się nieprawidłowych kombinacji wartości null]). Dodawanie klienta konkretnych tabel (czyli usersa foo_users, z usersgospodarstwa pól ważny dla wszystkich klientów i foo_usersposiadające specyficzne fileds Foo) jest lepszy; możesz łatwo mieć poprawne ograniczenia, ale RDBMS może nie poradzić sobie z tym płynnie (z powodu eksplozji łączenia, ograniczeń liczby tabel itp.) i prawdopodobnie będzie wyglądał brzydko w twoim kodzie.

Może się zdarzyć, że zaimplementujesz magazyn kluczy i wartości w twoim systemie RDBMS, co sprawi, że Twój model danych będzie mniej relacyjny i spowoduje dyskomfort (tj. Relacyjne bazy danych działają najlepiej z modelami relacyjnymi). Nie jestem pewien, czy rozwiązanie NoSQL ogólnie pasuje do problemu, ale niefrasobliwość większości implementacji może być zaletą.

alex
źródło