Ugostiteljstvo / putovanja
PMS i channel manager za ugostiteljstvo
Sistem za upravljanje objektom i channel manager koji drži raspoloživost, cene i rezervacije sinhronizovanim kroz OTA i GDS kanale — gde jedno neslaganje znači prebukiranje.
Pregled
Objekti koji prodaju sobe ne prodaju ih na jednom mestu. Ista soba se pojavljuje na Booking.com-u, Airbnb-ju, Expediji, na par GDS kanala i na hotelovom sopstvenom sajtu — a svaki od njih želi da mu se odmah kaže kada je soba rezervisana ili se cena promeni. Ovaj projekat je bio sistem u sredini: sistem za upravljanje objektom (PMS) i channel manager koji sve te površine tretira kao jedan inventar.
Problem
Način otkazivanja ovde nije suptilan. Ako raspoloživost odluta između dva kanala — makar na par sekundi pod opterećenjem — ili istu sobu prodaš dva puta (prebukiranje, i ljut gost na recepciji) ili sakriješ sobu koja je zapravo bila slobodna (izgubljen prihod). Cene imaju isti problem u tišoj formi: zastarela cena na jednom kanalu potkopava svaki drugi.
Raditi ovo ručno, ili noćnim batch poslom, nije dovoljno dobro. Prozor u kome se sistemi ne slažu jeste bag. Pravi zahtev je bila dvosmerna sinhronizacija — i guramo svoju istinu napolje i prihvatamo ažuriranja koja se vraćaju — sa prozorom odstupanja održanim što manjim možemo.
Rešenje
PMS i channel manager sa dvosmernom sinhronizacijom raspoloživosti, cena i rezervacija. Integriše se sa PMS i channel-management sistemima trećih strana, glavnim OTA kanalima i GDS distribucijom, i objektu ih predstavlja kao jedan izvor istine. Kada rezervacija sleti na bilo koji kanal, inventar koji je potrošila reflektuje se svuda drugde pre nego što naredni kanal može da ga proda.
Arhitektura
Jezgro je Laravel servis koji drži kanonski model inventara i cena, sa Vue.js operaterskim UI-jem povrh njega. Zanimljiv deo je sloj integracije: svaki kanal govori drugačiji dijalekt, drugačijim tempom, sa drugačijim shvatanjem o tome šta je „ista soba”, pa svaki sedi iza adaptera koji normalizuje u naše interne događaje.
- Ulazna ažuriranja kanala i izlazna guranja razdvojena su kroz redove (Redis), tako da spor ili nepouzdan partnerski API nikada ne blokira operaterski UI ni ostatak fan-out-a.
- Promene rezervacija i raspoloživosti modelirane su kao događaji, što dvosmerni tok čini razumljivim: ažuriranje je ili naše koje ide napolje ili njihovo koje dolazi unutra, a pravila rekoncilijacije žive na jednom mestu.
- Sve to radi u Dockeru, što je ovde bilo važnije nego obično — reprodukcija partnerovog rubnog payload-a lokalno je način na koji se većina ovih bagova zapravo popravi.
Tehnički izazovi
Teški problemi su svi bili o konzistentnosti pod konkurentnošću. Dva kanala koja potvrđuju rezervaciju za poslednju sobu u istoj sekundi jeste stvarna trka, a „samo zaključaj sve” nije opcija kada zaključavanje držano tokom HTTP poziva treće strane može da zaglavi ceo objekat. Ispravno postaviti granice — šta mora biti jako konzistentno (poslednja jedinica inventara) naspram onoga što može da se slegne trenutak kasnije (korekcija cene) — bio je najveći deo posla.
Partnerski API-jevi su takođe izvor beskrajnog, nedokumentovanog iznenađenja: ograničenja brzine koja nisu objavljena, ponovni pokušaji koji tiho postavljaju duplo, polja koja znače suptilno različite stvari po kanalu. Dobar deo otpornosti je odbrambena vodovodna instalacija oko tuđih sistema.
Naučene lekcije
Modeliraj domen kao događaje pre nego što dotakneš i jednu integraciju. Kada su „raspoloživost se promenila” i „rezervacija primljena” postali prvorazredne stvari u našem sistemu umesto sporednih efekata API poziva, svaki novi kanal je postao vežba mapiranja umesto prepisivanja. I odluči rano, eksplicitno, za koje invarijante vredi blokirati — većina ne vredi, a pretvarati se da sve vrede je način na koji izgradiš nešto što je tačno i neupotrebljivo sporo.