Program online do awizacji dostaw działa w przeglądarce, a wszystkie dane i reguły leżą na serwerze. Dostawca i dyspozytor otwierają ten sam adres, logują się przypisaną rolą i widzą ten sam kalendarz ramp. Na komputerach użytkowników nic się nie instaluje, więc zmiana reguły w programie działa dla wszystkich od razu.

Funkcje samej awizacji opisują osobne artykuły: moduł awizacji w VSS.net oraz proces po stronie przewoźnika. Ten tekst dotyczy infrastruktury: co dzieje się w przeglądarce, co na serwerze i jakie decyzje techniczne wpływają na niezawodność rezerwacji.

Program online do awizacji dostaw - co robi przeglądarka, a co serwer

Model online opiera się na podziale zadań. Przeglądarka wyświetla kalendarz i formularze awizacji, a serwer przechowuje dane i rozstrzyga, czy operacja jest dozwolona. Ten podział wyjaśnia, dlaczego użytkownik nie musi znać konfiguracji programu, a administrator zmienia ją w jednym miejscu.

ZagadnieniePo stronie przeglądarkiPo stronie serwera
Wygląd i obsługawyświetla kalendarz i formularzedostarcza dane oraz reguły walidacji
Walidacja pólszybka kontrola formatu, na przykład numeru rejestracyjnegoostateczna kontrola i zapis w bazie
Stan sesjiprzechowuje plik cookie z identyfikatorem sesjiwiąże sesję z kontem i rolą użytkownika
Rezerwacja oknawysyła żądanie z wybranym terminemrozstrzyga, kto zajął okno pierwszy

Reguła: przeglądarka pokazuje i zbiera dane, a o tym, czy okno jest wolne, decyduje wyłącznie serwer.

Zalety modelu online dla dostawcy i dyspozytora

Najważniejsza zaleta jest organizacyjna: nowy dostawca zaczyna pracę po założeniu konta, bez konfiguracji stacji roboczej. Dla magazynu oznacza to niższy próg wejścia dla przewoźników, którzy przyjeżdżają kilka razy w roku i nie zainstalują programu tylko dla jednej dostawy. Cztery cechy modelu mają znaczenie techniczne.

  • Dostęp bez instalacji - wystarczą przeglądarka i konto z łącznością HTTPS do serwera.
  • Jedna wersja programu - poprawki wdraża się na serwerze, więc nie ma rozjazdu wersji między użytkownikami.
  • Wspólne dane - dyspozytor widzi awizację w chwili, w której dostawca ją zapisuje.
  • Dowolne urządzenie - komputer lub telefon kierowcy, o ile ekran pozwala obsłużyć formularz.

W programie opisanym w materiałach SoftwareStudio nowe awizo dopisuje się z pozycji menu DOPISZ NOWE AWIZO, a rejestry rozdzielają awiza w buforze od zatwierdzonych. W bazie tę różnicę zapisuje kolumna statusu: wartość 0 oznacza bufor, 1 zatwierdzone, a X awizo anulowane. Rozbudowany opis kalendarza i okien znajduje się w tekście o oknach czasowych, a ogólną definicję pojęcia wyjaśnia strona o programie do awizacji dostaw.

Ilustracja planowania dostaw w programie do awizacji działającym w przeglądarce
Planowanie dostaw w programie online, do którego odnosi się podział zadań między przeglądarkę i serwer.

Droga żądania od przeglądarki do bazy danych

Każde kliknięcie użytkownika przechodzi przez kilka etapów, a czas odpowiedzi jest sumą ich opóźnień. Zrozumienie tej drogi pozwala znaleźć źródło wolnego działania bez zgadywania.

EtapCo się dziejeTypowe źródło opóźnienia
Połączenieprzeglądarka ustala adres serwera i otwiera połączenie TCPwolne łącze lub zapora blokująca port 443
Szyfrowanieuzgodnienie TLS i weryfikacja certyfikatucertyfikat wygasły albo źle skonfigurowany
Serwer WWWIIS przekazuje żądanie do puli aplikacjiuruchamianie puli po okresie bezczynności
Aplikacjakod sprawdza rolę użytkownika i wywołuje procedurykosztowne zapytania w pętli
Baza danychSQL Server odczytuje lub zapisuje wierszeblokady i brak indeksu
Wyświetlenieprzeglądarka rysuje odpowiedźbardzo duża liczba wierszy w jednej tabeli

Pierwsze żądanie po dłuższej przerwie bywa wolniejsze, bo pula aplikacji w IIS zwalnia zasoby po ustalonym czasie bezczynności i musi się uruchomić od nowa. Ustawienia puli i sposób działania serwera opisuje przegląd serwera IIS w Microsoft Learn.

Źródło opóźnienia można zmierzyć w narzędziach deweloperskich przeglądarki. Zakładka Network pokazuje dla każdego żądania osobno czas oczekiwania na pierwszy bajt odpowiedzi i czas pobierania. Długie oczekiwanie oznacza wolny serwer lub bazę, a długie pobieranie - dużą odpowiedź albo słabe łącze użytkownika.

Aplikacje przeglądarkowe utrzymują aktualność kalendarza zapytaniami AJAX wysyłanymi w stałym odstępie. Krótki odstęp poprawia świeżość widoku, ale zwiększa liczbę żądań, a przy kilkudziesięciu otwartych oknach dyspozytorów obciąża serwer bez potrzeby. Poniższy przykład w jQuery odświeża widok co 30 sekund i pokazuje komunikat, gdy serwer nie odpowiada; nazwy funkcji i adresu są przykładowe.

function odswiezKalendarz(dzien) {
    $.getJSON('/api/okna', { dzien: dzien })
        .done(function (dane) { rysujOkna(dane); })
        .fail(function () { pokazKomunikat('Brak połączenia z serwerem'); });
}

setInterval(function () { odswiezKalendarz(biezacyDzien); }, 30000);

Serwer IIS i baza SQL Server w centrum danych

Według materiałów SoftwareStudio program do awizacji działa w chmurze prywatnej zlokalizowanej w centrum danych ATM w Warszawie i opiera się na technologiach Microsoft IIS oraz SQL Server. Użytkownik nie utrzymuje więc własnego serwera, ale zyskuje pytania, które warto zadać przed wdrożeniem: gdzie leżą dane, kto robi kopie i w jakich godzinach serwer przechodzi prace serwisowe.

Alternatywą jest instalacja na serwerach firmy. Daje ona pełną kontrolę nad danymi i siecią, a w zamian przenosi na klienta odpowiedzialność za aktualizacje i kopie zapasowe. Porównanie obu modeli z kryteriami kosztu i bezpieczeństwa zawiera artykuł o programie magazynowym w chmurze i on-premise, a budowę warstw serwerowych systemu awizacji - tekst o architekturze systemu zarządzania awizacjami.

Produkt SoftwareStudio w tym obszarze to Studio VSS.net, a przykłady zastosowań zebrano w serwisie awizacje.softwarestudio.com.pl. Przy ocenie hostingu liczy się lokalizacja serwera, a równie ważne jest to, czy umowa opisuje czas przywrócenia usługi po awarii.

Rezerwacja okna bez podwójnego zajęcia

W godzinach szczytu dwóch dostawców może wybrać to samo okno w odstępie ułamka sekundy. Aplikacja, która najpierw sprawdza wolne miejsce, a potem je zajmuje w osobnym kroku, dopuści obu, bo drugi odczyt zobaczy jeszcze stary stan. Rozwiązaniem jest jedna transakcja z blokadą aktualizacji na odczycie.

DECLARE @OknoId int = 42, @Wolne int;

BEGIN TRANSACTION;

SELECT @Wolne = Pojemnosc - Zajete
FROM dbo.OknoCzasowe WITH (UPDLOCK, HOLDLOCK)
WHERE OknoId = @OknoId;

IF @Wolne > 0
BEGIN
    UPDATE dbo.OknoCzasowe SET Zajete = Zajete + 1 WHERE OknoId = @OknoId;
    INSERT INTO dbo.Awizo (OknoId, NumerRejestracyjny, Status)
    VALUES (@OknoId, N'PO 12345', '0');
    COMMIT TRANSACTION;
END
ELSE
BEGIN
    ROLLBACK TRANSACTION;
    THROW 50002, N'Okno zostało zajęte przez inne awizo.', 1;
END;

Podpowiedź UPDLOCK powoduje, że druga transakcja czeka na zwolnienie blokady, a po jej uzyskaniu widzi już zwiększoną liczbę zajętych miejsc i dostaje błąd. Przeglądarka odbiera go jako odpowiedź serwera i wyświetla prośbę o wybór innego terminu. Nazwy tabel i kolumn są przykładowe, a status 0 odpowiada buforowi opisanemu wyżej.

Reguła: sprawdzenie i zajęcie okna musi być jedną transakcją, bo dwa oddzielne kroki dopuszczają podwójną rezerwację.

Obciążenie takiego programu jest nierówne: szczyt przypada na godziny, w których przewoźnicy potwierdzają terminy na następny dzień, a resztę doby serwer jest prawie bezczynny. Testy wydajności obejmują więc scenariusz szczytowy z kilkudziesięcioma równoległymi próbami zajęcia tego samego okna. Sprawdzają one zarówno działanie blokad, jak i limit połączeń w puli, który przy zbyt małej wartości ustawia żądania w kolejce przed bazą.

Czas serwera i strefy czasowe w kalendarzu

Kalendarz okien jest wrażliwy na czas bardziej niż większość aplikacji biznesowych. Zegary serwera i bramy muszą pokazywać tę samą godzinę co telefon kierowcy, inaczej przyjazd o 7:58 raz mieści się w oknie, a raz nie. Serwery synchronizuje się z wzorcem czasu protokołem NTP, a urządzenia przy bramie warto konfigurować tym samym źródłem.

Osobnym problemem jest zmiana czasu. W Polsce zegary przesuwa się w ostatnią niedzielę marca i października, więc raz w roku godzina 2:00 nie istnieje, a raz występuje dwa razy. Zapis czasu lokalnego w bazie nie odróżnia wtedy dwóch takich samych odczytów. Bezpieczniejszy jest zapis w UTC i konwersja przy wyświetlaniu.

Sposób zapisuZaletaRyzyko
Czas lokalny w kolumnie datetimeprosty odczyt bez konwersjiniejednoznaczność podczas zmiany czasu
UTC i konwersja przy odczyciejednoznaczne porównania i sortowaniekonwersja musi być wykonana w każdym widoku
Kolumna datetimeoffsetzapis zawiera przesunięcie względem UTCprzesunięcie nie zastępuje nazwy strefy
SELECT OknoId,
       PoczatekUtc AT TIME ZONE 'UTC'
                   AT TIME ZONE 'Central European Standard Time' AS PoczatekLokalny
FROM dbo.OknoCzasowe
WHERE OknoId = @OknoId;

Składnia AT TIME ZONE jest dostępna od SQL Server 2016, a nazwa strefy pochodzi z rejestru Windows. Podział doby na okna, na przykład co 20 minut, liczy się wtedy w UTC, a wyświetla w czasie lokalnym magazynu. Sposób planowania kalendarza z punktu widzenia użytkownika opisuje tekst o kalendarzu transportów.

Ilustracja programu do awizacji dostaw udostępnianego w chmurze prywatnej
Program udostępniany w chmurze, o której mowa w sekcji o serwerze IIS i bazie SQL Server.

Dostęp przez Internet i konta użytkowników

Program dostępny z Internetu wystawia adres serwera każdemu, kto go zna, więc pierwszą linią ochrony są konta i role. Dostawca powinien widzieć wyłącznie własne awizacje, a dyspozytor wszystkie w obrębie swojego magazynu. Ograniczenie musi działać na serwerze, w warunku zapytania, bo ukrycie przycisku w przeglądarce nie chroni danych: użytkownik może wysłać żądanie ręcznie.

CREATE PROCEDURE dbo.AwizaDostawcy
    @DostawcaId int,   -- z sesji na serwerze, nie z formularza
    @Dzien date
AS
BEGIN
    SET NOCOUNT ON;
    SELECT AwizoId, OknoId, NumerRejestracyjny, Status
    FROM dbo.Awizo
    WHERE DostawcaId = @DostawcaId
      AND PoczatekUtc >= @Dzien
      AND PoczatekUtc < DATEADD(DAY, 1, @Dzien);
END;

Poniższe parametry konfiguracji ograniczają skutki najczęstszych nadużyć.

  • Sesja - identyfikator w pliku cookie z atrybutami Secure i HttpOnly oraz z limitem czasu bezczynności.
  • Hasła - minimalna długość i blokada konta po serii nieudanych logowań.
  • Dziennik zdarzeń - zapis, kto i kiedy dopisał albo anulował awizację.
  • Minimum danych - kierowca podaje tylko dane potrzebne do wjazdu, bo każde dodatkowe pole to dane osobowe wymagające ochrony.

Potwierdzenia e-mail i integracja z systemem magazynowym

Program opisany w materiałach SoftwareStudio wysyła potwierdzenie awizacji e-mailem i powiązuje awizację z dokumentami systemu magazynowego. Od strony technicznej wysyłka wiadomości nie powinna blokować odpowiedzi dla użytkownika: serwer SMTP bywa wolny, a chwilowa awaria poczty nie może cofnąć rezerwacji okna.

Stosuje się więc kolejkę. Żądanie zapisuje awizację i wiersz kolejki w jednej transakcji, a osobne zadanie odbiera wiersze i wysyła wiadomości; może to być zadanie SQL Agent albo usługa systemowa. Nieudana wysyłka zwiększa licznik prób i zostaje powtórzona później.

BEGIN TRANSACTION;

INSERT INTO dbo.Awizo (OknoId, DostawcaId, NumerRejestracyjny, Status)
VALUES (@OknoId, @DostawcaId, @Numer, '0');

INSERT INTO dbo.KolejkaPowiadomien (AwizoId, Typ, Adresat, Proba, Wyslano)
VALUES (SCOPE_IDENTITY(), 'POTWIERDZENIE', @Email, 0, NULL);

COMMIT TRANSACTION;

-- zadanie wysyłające pobiera paczkę niewysłanych wiadomości
SELECT TOP (50) KolejkaId, AwizoId, Adresat
FROM dbo.KolejkaPowiadomien
WHERE Wyslano IS NULL AND Proba < 5
ORDER BY KolejkaId;

Przy integracji z systemem magazynowym obowiązuje ta sama zasada oddzielenia zapisu od dalszej obróbki. Dane o awizacji trafiają do bazy WMS, gdzie dział logistyki widzi zajętość rampy i planuje pracę magazynierów, a przyjęcie towaru korzysta z tych samych danych. Ten mechanizm opisuje strona o roli systemu WMS i tekst o planowaniu transportu.

Dostępność serwera i kopie zapasowe

Program awizacji jest dla magazynu zależnością krytyczną: gdy serwer nie działa, dostawcy nie mogą rezerwować okien, a dyspozytor traci widok kolejki. Dwie miary opisują tolerancję na awarię i powinny znaleźć się w umowie.

  • RPO - największa dopuszczalna utrata danych, wyrażona czasem; przy RPO równym 15 minut kopie dzienników transakcji wykonuje się co najwyżej co kwadrans.
  • RTO - największy dopuszczalny czas przywrócenia usługi po awarii, liczony do chwili, gdy użytkownicy znów mogą pracować.

W SQL Server kopia pełna wykonywana raz na dobę i kopie dzienników transakcji w krótszych odstępach pozwalają odtworzyć bazę na wybrany moment. Zasady opisuje przegląd kopii zapasowych i odtwarzania w Microsoft Learn. Kopia, której nikt nie próbował odtworzyć, jest tylko założeniem, więc test odtworzenia na osobnym serwerze należy do rutyny.

Aktualizacje po stronie serwera nie wymagają udziału użytkowników, ale powinny mieć okno serwisowe poza godzinami dostaw i zapowiedź widoczną w programie. Po każdej zmianie sprawdza się krótką listę: logowanie każdej roli, dopisanie awizacji, zajęcie ostatniego wolnego okna i wysłanie potwierdzenia e-mail. Powiązanie awizacji z dokumentami magazynowymi, na przykład z przyjęciem towaru, jest kolejnym punktem, który przechodzi przez integrację z systemem WMS.

Ilustracja automatycznych potwierdzeń rezerwacji i powiadomień o zmianach w systemie awizacji
Potwierdzenia rezerwacji i powiadomienia, które po aktualizacji serwera trzeba sprawdzić na krótkiej liście testowej.

Szerszy opis aplikacji dla dostawców i kierowców, w tym kodów QR i powiadomień, zawiera artykuł o aplikacji webowej i mobilnej do awizacji, a ogólny opis procesu - strona o awizacji dostaw w siatce ramp.