Jak zdebugować losowe występowanie 502 - Bad Gateway?

Jak zdebugować losowe występowanie 502 - Bad Gateway?
DE
  • Rejestracja:ponad 9 lat
  • Ostatnio:11 miesięcy
  • Postów:1788
0

Udało mi się (chyba) znaleźć przyczynę. Użyłem do tego xdebug.auto_trace = 1. Po włączeniu tej opcji dostajemy zajebisty trace (domyślnie) w katalogu /tmp. Wystarczy przewinąć na koniec i widzimy, gdzie się wywalił skrypt.


Koduje... koduje i nagle zaczęło mi randomowo wywalać 502. Na dowolnej podstronie. Nie dzieje się to za każdym razem, ale jak radośnie poprzeklikuję się pomiędzy podstronami to po kilku sekundach dostanę 502.

Jak zmienię branch na mastera, albo cofnę się x commitów to problem ustaje, ale póki co nie udało mi się ustalić czy i jaki kawałek kodu jest za to odpowiedzialny. Nie mam pomysłu, bo kod się wywala w takich miejscach, ze nawet nie przechodzi przez zmiany, które wprowadziłem...

Spróbowałem dać die(123) w różnych miejscach aplikacji, w tym na samym końcu akcji w kontrolerze. Do momentu jak die tam był to kod do tego momentu dochodził, ale jak go usunąłem i kliknąłem pare razy f5 to znowu to samo.

Syslog:

Kopiuj
Nov  2 14:48:13 foo mysqld[1376]: 2017-11-02 14:48:13 140679083760384 [Warning] Aborted connection 3144 to db: 'foo_prod' user: 'root' host: 'localhost' (Got an error reading communication packets)
Nov  2 14:48:13 foo kernel: [21780.492560] traps: php-fpm7.0[11713] general protection ip:55b8b9d5cc94 sp:7ffc9ba8ca00 error:0 in php-fpm7.0[55b8b9b2a000+3ae000]

Próbowałem zrobić core dump i odczytać zrzut z użyciem gdb, ale okazało się ze dostałem jakieś krzaki, z których nic nie rozumiem (tam chyba powinny być nazwy funkcji?);

Kopiuj
#0  0x000055fd8dc23c94 in ?? ()
#1  0x00007ffcc6b098f0 in ?? ()
#2  0x00007fe6d9692d80 in ?? ()
#3  0x00007fe6d965bc00 in ?? ()
#4  0x00007fe6cacc7e30 in ?? ()
#5  0x000055fd8f14f420 in ?? ()
#6  0x0000000000000020 in ?? ()
#7  0x00007ffcc6b09800 in ?? ()
#8  0x00007ffcc6b09808 in ?? ()
#9  0x00007fe6d9692da0 in ?? ()
#10 0x00007fe6d9692d90 in ?? ()
#11 0x00007fe6d97699d8 in ?? ()
#12 0x00007fe600001406 in ?? ()
#13 0x0000000000000165 in ?? ()
#14 0x0000000000000000 in ?? ()

Coś tam wyczytałem ze to może być segmentation fault, ale nie bardzo rozumiem co to, a tym bardziej co to może powodować.

Używam minta 18, nginx, mariadb 10.1, php 7.0.x i phalcona 3.

edytowany 3x, ostatnio: Desu
TR
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 2 miesiące
  • Lokalizacja:700m n.p.m.
  • Postów:677
0

Jak zmienię branch na mastera, albo cofnę się x commitów to problem ustaje

Piszesz w tym momencie o Phalconie, czy czymś innym?


DRY > SOLID (nie bierz tego zbyt poważnie)
DE
  • Rejestracja:ponad 9 lat
  • Ostatnio:11 miesięcy
  • Postów:1788
0

Nie o swojej aplikacji. Nie próbowałem zmieniać wersji phalcona, bo uznałem, ze to moja wina (tak jak napisałem, przy zmianie bracha na master problem ustaje - tak mi się wydaje, albo mam pecha i akurat nie występuje, a brak występowania nie jest związany z kodem).

Skłaniam się ku temu, ze mój kod zainicjował problem, bo jak wgrałem zmiany na środowisko testowe, to tam tez zaczęło się dziać to samo.

edytowany 1x, ostatnio: Desu
TR
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 2 miesiące
  • Lokalizacja:700m n.p.m.
  • Postów:677
0

Jeżeli master Twojej aplikacji dobrze działa, tak samo jak cofnięcie się do jakiejś wcześniejszej wersji, to wskazuje, że w Twojej aplikacji jest coś nie tak.

Możesz wkleić kod który sprawia problemy?


DRY > SOLID (nie bierz tego zbyt poważnie)
edytowany 2x, ostatnio: TomRZ
DE
  • Rejestracja:ponad 9 lat
  • Ostatnio:11 miesięcy
  • Postów:1788
0

Chętnie, ale za cholerę nie wiem, który to :D

Próbowałem zrobić checkout HEAD i zakomentowac wszystkie zmiany, które wprowadziłem przez X commitów, ale problem nadal występował.

Najlepsze jest to, ze do końca akcji wszystko działa. Wszystkie najcięższe akcje jak zaczytywanie czegoś z bazy itp. już sie wykonały. Jak nie dam die i kod pójdzie dalej to się wywala. Możliwe, ze plik jakoś złe się zapisał? Nie wiem ze złym encodowaniem czy coś?

A tak poza tym, to dlaczego jak kilka razy odświeże to zaczyna działać? To jest podejrzane dla mnie.

Powalczę jeszcze w domu, jak ochłonę.. bo trochę mnie ten problem wpienił.

edytowany 4x, ostatnio: Desu
TR
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 2 miesiące
  • Lokalizacja:700m n.p.m.
  • Postów:677
1

To ma coś wspólnego z PHQL / Modelami. Tak jak Tobie chyba wczesiej wspomniałem - nie używaj w Phalconie nazw tabel tylko ściezki do klas które są modelami dla danej tabeli SQL.

Np. masz tabelę "product" a jej modelem jest np. \sklep\product\ProductModel, wtedy lepszy jest taki SQL:

Kopiuj
SELECT * FROM \sklep\product\ProductModel

niż

Kopiuj
SELECT * FROM product

Nalezy pamiętać o backslashu na początku przestrzeni nazw dla klasy czyli \sklep\product\ProductModel a nie sklep\product\ProductModel.

Dodatkowo nie używaj nazw kolumn oryginalnych tylko właściwości z modelu.

Przykładowe mapowanie właściwości do nazw kolumn:

Kopiuj
  public function columnMap() {
    
    return array(
        
        'id' => 'id',
        'name' => 'name',
        'php_manager_class' => 'phpManager',
        'profit_margin_pct_default' => 'profitMarginPctDefault',
        'profit_margin_rates' => 'profitMarginRates',
        'properties' => 'properties',
        'active' => 'active',
        'category_map' => 'categoryMap',
        'products_block' => 'productsBlock'
        
        );
  }

DRY > SOLID (nie bierz tego zbyt poważnie)
edytowany 4x, ostatnio: TomRZ
DE
Dzięki, spróbuje podebugowac pod tym katem.
DE
  • Rejestracja:ponad 9 lat
  • Ostatnio:11 miesięcy
  • Postów:1788
0

Phalcon to cachuje? Ta mapę? Bo na początku, przez nieuwagę zrobiłem nazwa kolumny => pusty string i dostałem błąd po czym poprawiłem i CHYBA gdzieś wtedy się zaczęło.

edytowany 1x, ostatnio: Desu
TR
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 2 miesiące
  • Lokalizacja:700m n.p.m.
  • Postów:677
2

Jak najbardziej można włączyć cache dla modeli.

Ja to robię np. tak:

Kopiuj
$di->set('modelsMetadata', function () {
          
            
            $metadata = new \Phalcon\Mvc\Model\MetaData\Files(
                [
                    'lifetime' => 86400,
                    'metaDataDir'   => \INOPX_NOPUB_FILE_CACHE_DIR,
                ]
            );
            
            /*$metadata = new \Phalcon\Mvc\Model\MetaData\Session(
                [
                    'lifetime' => 86400
                ]
            );*/

            return $metadata;
        });

Gdzie INOPX_NOPUB_FILE_CACHE_DIR to akurat taka stała moja własna, ale trzeba tam podać ścieżke do katalogu, można też keszować w memcached.

A tutaj keszowanie annotacji:

Kopiuj
$di->set('annotations', function () {
          
            
            $metadata = new \Phalcon\Annotations\Adapter\Files(
                [
                    'lifetime' => 86400,
                    'annotationsDir' => \INOPX_NOPUB_ANNOTATION_CACHE_DIR,
                ]
            );

            return $metadata;
        });

Oczywiście ma to sens na produkcyjnym, przy testowaniu keszowanie może przeszkadzać.

Tylko kwestia jest jeszcze taka - że najlepiej nie robić SQL/PHQL z ręki, tylko korzystać z metod find i findFirst jeżeli to możliwe. Później w parametrach jeżeli chcesz po czymś posortować albo zrobić warunek to używasz nazw z właściwości klasy a nie kolumy SQL.

Przykład: kolumna SQL ma nazwę "search_string" a właściwość w klasy która mapuje do tej kolumny to "wyszukiwanie" po polsku, a właściwość której użyjesz do sortowania to "wiek" (w bazie kolumna "age") wtedy:

Kopiuj
\sklep\product\ProductModel::find(
"conditions" => "wyszukiwanie = :wyszukiwanie:",
"bind" => ["wyszukiwanie" => 'kasza'],
"orderBy" => 'wiek DESC'
);

DRY > SOLID (nie bierz tego zbyt poważnie)
edytowany 4x, ostatnio: TomRZ
TR
Dodałem kod pozwalający na keszowanie metadaty modeli, oraz annotacji.
vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
1

Nie znam platformy o ktorej mowa, ale zwykle cos takiego szukam przez binary search.

Czyli masz dobra wersje i zla.
Znajdujesz wersje posrodku (w git/svn) i testujesz.
Jesli masz blad - badasz wersje blizej poprawnej. Jesli nie ma bledu - badasz wersje blizej blednej.
I tak w kolko az dochodzisz do konkretnego commita.

Potem szukasz konkretnie pliku ktorego zmiana powoduje blad.

Potem linii.

A jesli chodzi o samo testowanie to mozesz wykorzystac jakis stress tester, np Apache JMeter.

Uwaga: blad moze sie nie pojawic przy die / echo.
Lepiej wtedy logowac do pliku.

GV
git ma wbudowane narzędzie do takiego poszukiwania "złego" commita - git bisect
vpiotr
GoodVibesDev: +1
DE
  • Rejestracja:ponad 9 lat
  • Ostatnio:11 miesięcy
  • Postów:1788
0

@TomRZ: debuggerem podczas sesji gdy występuje błąd dochodzę do widoku (pliku .volt, a raczej .php :P), czy eliminuje to problem z baza?

edytowany 3x, ostatnio: Desu
TR
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 2 miesiące
  • Lokalizacja:700m n.p.m.
  • Postów:677
1

Niekoniecznie, zależy co w tym widoku masz. Trudno wróżyć z fusów, najlepiej gdybyś wkleił kod widoku. Przy czym ja nie korzystam z volta, widoki robię w czystym PHP.

Na marginesie: naprawdę nie rozumiem za bardzo sensu używania takich wynalazków jak volt, smarty, czy inne systemy szablonów. NIe dość, że trzeba się uczyć dodatkowej składni np. pętli, to w dodatku wszystko to co "daje" taki system szablonów (np. keszowanie) można bez problemu osiągnąć w czystym PHP / funkcjami frameworka. Jedyny ewentualny sens jest wtedy, kiedy ktoś inny miesza w szblonach, i chcemy mu ograniczyć prawa.


DRY > SOLID (nie bierz tego zbyt poważnie)
edytowany 3x, ostatnio: TomRZ
DE
Nic nie poradzę, tak już było :)
DE
  • Rejestracja:ponad 9 lat
  • Ostatnio:11 miesięcy
  • Postów:1788
0

@TomRZ: Chyba znalazłem.

Kopiuj
class Tag extends \Phalcon\Tag
{
    public static function getUrlService()
    {
        self::$_urlService = self::getDI()->get('url');

        return self::$_urlService;
    }
}

Jak to wywale, to wydaje się działać. W tej metodzie chyba chodzi o to, żeby nie cacheować serwisu, tak jak robi to Phalcon (L189), bo ->get('url') zwraca obiekt typu UrlInterface.

Masz jakiś pomysł dlaczego? I dlaczego do diabła tylko czasami się to wykrzacza?

Ostatni wpis w trace:

Kopiuj
-> Phalcon\Mvc\Url->setDI() /home/vagrant/Code/xxx/apps/Plugins/Tag.php:15 (15 to self::$_urlService = self::getDI()->get('url');)

Jak rozkminie czemu to powoduje segmentation fault to dam znać..

edytowany 5x, ostatnio: Desu
TR
Poza tym to powinno raczej być: return self::getDI()->get('url'); Nie ma tu sensu za bardzo ustawianie statycznej właściwości self::$_urlService
TR
A najlepiej tak: return \Phalcon\Di::getDefault()->get('url');
TR
Popatrz też tutaj, na samym dole masz listę standardowych usług które są w domyślnym DI: https://docs.phalconphp.com/en/3.2/di
TR
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 2 miesiące
  • Lokalizacja:700m n.p.m.
  • Postów:677
0

Di pobieraj przez \Phalcon\Di::getDefault() czy jakoś tak - w każdym razie statyczną metodą


DRY > SOLID (nie bierz tego zbyt poważnie)
DE
  • Rejestracja:ponad 9 lat
  • Ostatnio:11 miesięcy
  • Postów:1788
1

To chyba coś z phalconem/zephirem.
https://github.com/phalcon/zephir/issues/1596

TR
No widzisz, prawdopodobnie odkryłeś przyczynę / buga.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)