HEAPS

Golang dla programistów PHP: kiedy Go jest lepszym wyborem na backend

Praktyczny przewodnik dla programistów PHP oceniających Golang. Porównanie współbieżności, wdrożeń, typowania i realnych przypadków, w których Go wygrywa z typowym serwisem PHP.

PHP nadal jest świetny. Go rozwiązuje inne problemy.

Jeśli budujesz produkty webowe w PHP, Symfony albo Laravel pokrywają ogromną część mapy: panele admina, e commerce, integracje CMS, serwisy contentowe i klasyczne API CRUD. Golang pojawia się w rozmowie, gdy potrzebujesz usługi, która zostaje szybka przy wysokiej współbieżności, wdraża się jako jeden binarka i większość życia spędza na rozmowie z siecią, kolejkami i bazami, a nie na renderowaniu HTML.

Ten artykuł jest pisany dla programistów PHP. Celem nie jest wyłonienie zwycięzcy. Celem jest pomoc w decyzji, kiedy nauka Go ma sens.

Model mentalny: workery żądań kontra lekka współbieżność

W PHP FPM każde żądanie zwykle dostaje własny proces albo worker. Ten model jest prosty i sprawdzony bojowo. Oznacza też, że współbieżność to w dużej mierze „dokup więcej workerów”. Pamięć rośnie wraz z liczbą równoległych żądań.

Go używa goroutines. Uruchomienie tysięcy z nich jest normalne. Blokada na I/O nie zamraża całego procesu tak, jak blokujące wywołanie potrafi zagłodzić małą pulę workerów PHP.

package main

import (
    "fmt"
    "net/http"
    "time"
)

func handler(w http.ResponseWriter, r *http.Request) {
    // Symulacja zewnętrznego API bez blokowania innych żądań.
    time.Sleep(50 * time.Millisecond)
    fmt.Fprint(w, "ok")
}

func main() {
    http.HandleFunc("/health", handler)
    http.ListenAndServe(":8080", nil)
}

Podobny endpoint w PHP napiszesz łatwo. Różnica wychodzi, gdy otworzysz 5000 równoległych połączeń czekających na I/O. Go często potrzebuje dużo mniej pamięci, żeby zostać responsywnym.

Różnice językowe, które liczą się na co dzień

Statyczne typowanie jest obowiązkowe. W Go nie ma opcjonalnej fazy, w której „u mnie działa” chowa błąd typu do produkcji. Interfejsy są niejawne, co na początku dziwi, jeśli przychodzisz z interfejsów PHP i autowiringu Symfony.

Błędy to wartości. Zamiast wyjątków lecących przez warstwy funkcje Go często zwracają (result, error). Ta rozwlekłość jest zamierzona. Zmusza do decyzji, co robić, gdy wywołanie bazy się wyłoży.

user, err := repo.FindByID(ctx, id)
if err != nil {
    return fmt.Errorf("find user %d: %w", id, err)
}

Jest mniej magii. Brak adnotacji, które same wymyślają serwisy, brak bogatego cyklu życia żądania w bibliotece standardowej poza net/http. Frameworki jak Gin, Echo czy Chi istnieją, ale wiele produkcyjnych serwisów Go zostaje blisko standard library.

Wdrożenie jest kojąco nudne. go build produkuje binarkę. Wrzucasz ją do małego kontenera albo na VM, wskazujesz process manager i koniec. W porównaniu z PHP omijasz pule FPM, strojenie OPcache i dużą powierzchnię runtime.

Gdzie Go zwykle wygrywa

Bramki o wysokiej współbieżności. Rate limitery, odbiorniki webhooków, reverse proxy dla ruchu wewnętrznego i serwisy fan out wołające wiele backendów równolegle.

Workery bardziej obciążające CPU. Potoki obrazów, procesory logów i konsumenci streamów, które i tak wypchnęłyby Cię w ReactPHP, Swoole albo osobny język.

Małe narzędzia infrastrukturalne. Exportery CLI, helpery migracji, health checkery i sidecary, które powinny startować w milisekundach i zjadać prawie zero RAM.

Długożyjące połączenia. WebSockety, streamy gRPC i własne protokoły TCP są naturalniejsze w Go niż w klasycznym PHP FPM.

Gdzie PHP (i Symfony) nadal mają więcej sensu

Bogate domeny biznesowe w adminie. Formularze, walidacja, macierze uprawnień i rozbudowane modele domenowe szybciej idą w Symfony z Doctrine, Security i Validatorem.

Ekosystemy contentu i commerce. WordPress, PrestaShop, moduły Magento i ogromny rynek wtyczek zostają terytorium PHP.

Szybkość zespołu na produktach CRUD. Jeśli firma już zna PHP, dostarczenie kolejnego modułu Symfony jest tańsze niż wprowadzanie drugiego języka dla zwykłego zasobu REST.

Aplikacje renderowane po stronie serwera. Twig plus Symfony nadal dają mocną produktywność w narzędziach wewnętrznych i serwisach marketingowych.

Hybrydowa architektura, która działa w praktyce

Wiele zespołów zostawia Symfony jako system źródła prawdy i stawia Go na hałaśliwych krawędziach:

  1. Symfony trzyma zamówienia, klientów, uprawnienia i procesy admina.
  2. Serwis Go odbiera webhooki, weryfikuje sygnatury i wrzuca znormalizowane eventy do kolejki.
  3. Konsumenci Symfony Messenger stosują reguły biznesowe w zrównoważonym tempie.
  4. Inny worker Go obsługuje fan out powiadomień, gdy throughput rośnie.

Ten układ używa każdego języka w jego sile. PHP zostaje blisko domeny. Go przejmuje skoki ruchu i gadatliwą pracę sieciową.

Ścieżka nauki dla programisty PHP

  1. Napisz małe JSON API na net/http z routingiem i middleware.
  2. Poznaj context, cancelation i timeouty. W Go context.Context jest równie centralny jak obiekt request w Symfony.
  3. Poćwicz kanały i errgroup do ograniczonej równoległości.
  4. Podłącz Postgres przez database/sql albo lekki wrapper, zanim sięgniesz po ciężki ORM.
  5. Spakuj binarkę do kontenera i porównaj zużycie pamięci z równoważnym endpointem PHP pod obciążeniem.

Nie musisz przepisywać monolitu. Jeden dobrze dobrany serwis Go uczy więcej niż teoretyczna tabelka porównawcza.

Podsumowanie

Wybierz Golang, gdy problemem rządzą współbieżność, niski koszt pamięci, szybki start i obciążenie sieciowe. Zostań przy PHP i Symfony, gdy dominują złożoność domeny, dopasowanie ekosystemu i tempo zespołu. Najlepsza strategia backendu dla wielu firm produktowych to nie PHP albo Go. To PHP w rdzeniu produktu i Go w usługach, które inaczej wymusiłyby bolesne skalowanie monolitu.