Java (Szerver-Kliens) Mysql alapon futú alkalmazás kliensei random eldobják a kapcsolatot.

Fórumok

Sziasztok!

Adott egy külföldi érdekeltségű , online fogadással foglalkozó cég, amely több fogadóirodából áll.

A lényeg az, hogy van egy telephely, ahol a szerver (DELL-R710) elhelyezve, router (Drayteq Vigor 2925) mögött van , Digi 100/100 Mbps üzleti internet előfizetéssel.
Ezen a szerveren fut a java alkalmazás szerver verziója, ami úgy van megírva, hogy a fogadóirodákból kapja a kliensektől, az adatokat, és ezeket az adatokat adatbázisba írja egy mysql-connector-java segítségével.

A probléma, ami miatt írok a következő:

A kliensek nagyon sokszor lekapcsolódnak a szerverről, és a szerver ilyenkor "ClientListener watchdog timed out. Restarting listener"
hibaüzenetet ír.

Mysql config:
https://pastebin.com/Nfyt6LKr

Nem tudunk rájönni, hogy mi okozza a hibát, de az biztos, hogy egyre gyakoribb volt, minden újraindítást követően pedig egyre tovább tartott a szerver-kliens kapcsolat felépítése.
Múlt héten elkezdtem optimalizálni a mysql configot, mert az még erősen defaulton volt hagyva.
Mysqltuner / Mysqlprimer ajánlata szerint alkottam meg a paramétereket, amit el is fogadott, de sajnos a 190 innodb táblából mindegyik töredezett a mysqltuner szerint.
Mysqlprimer szerint az értékek, amiket megadtam a configban, rendben vannak.
Az alkalmazás csak a fent említett hibát írja, így megakadtam, hogy hol keressem a hibát.

Ami ötletem van, hogy annyira töredezettek az adatbázisban lévő táblák, hogy ez miatt nem hajlandóak becsatlakozni a kliensek sem.
Tekintve, hogy nem szeretnénk adatvesztést, és több hibát, ezért az lenne a kérdés, hogy lenne-e esetleg köztetek valaki, aki olyan szinten van mysqlből illetve java fejlesztésből, hogy egy előzetes diagnosztika után megmondja, hogy xy erőforrás, vagy config okozza a problémát, és erre garanciát is vállal, persze előzetesen egyeztetett anyagi díjazás ellenében.

A válaszokat és a segítséget előre is köszönöm!

Hozzászólások

Szerintem itt MySQL-független problémád van.

Első körben annak érdemes utána járni, hogy a szerver és a kliensek közötti kapcsolat pontosan hogyan néz ki, milyen protokollokkal működik. TCP-n kapcsolódik egyáltalán?

Aztán, utána kellene járni, hogy a klienseken mi történik a lekapcsolódás pillanatában. Futtatnak valamilyen lekérést? Beküldéskor száll el? Vagy csak áll magában, porosodik, egyszercsak a semmiből ráugrik egy nagy fekete Tájmout és beleharap? A hibaüzenet alapján kommunikációs para van, innen érdemes elindulni első körben.

Mi van a kliensek logjában? Van-e egyáltalán? Mi van a szerver logjában? Van-e egyáltalán? Ha bármelyik nincs, van-e hozzáférés a forráskódhoz, bele tudsz-e írni naplózást a kódba? Vagy a fejlesztő elérhető-e?

A MySQL oldal - ha már erre rákérdeztél -: Mekkora az adatbázis összmérete? Ezt a PMA durván meg tudja becsülni. Az érintett táblák durván hány sorosak (nagyságrend érdekes, nem a 45 211 vagy 45 222 sor közötti különbség). Be van-e kapcsolva az innodb_file_per_table? Ha csak most kapcsolod be, akkor az nem fog túl sokat segíteni, mert nem fogja átstrukturálni az adatbázist mágikusan.

Röviden: input, még input!
--
Blog | @hron84

"valahol egy üzemeltetőmaci most mérgesen toppant a lábával" via @snq-

lsof -i:3306 parancs kimenete szerint TCP-n kapcsolódnak a kliensek , azaz most csak egy kliens, mert a többi hely már kapcsolódni sem hajlandó a program újraindítása után.
A program csak az adatbázis műveleteket naplózza, de azt ész nélkül másodpercenként több tíz sort beír a naplóba, azt viszont , hogy mi történik a lekapcsolódás pillanatában nem tudjuk kideríteni. Annyi biztos, hogy internet van, mysql-el fel lehet kapcsolódni a szerverre és ssh-n is, a program viszont szerver oldali újraindítást követően valamikor pöccre felkapcsolódik, valamikor meg nem hajlandó egy hétig felcsatlakozni.
Van fent fail2ban a szerveren, de annak a naplója teljesen üres, és gondolom szólna, mivel be van állítva, ha blokkol valamit. mert egyébként mysqlt- és ssh-t figyeli.
A fejlesztő tőmondatokban válaszolgat a viber üzenetekre, mert a telefont persze nem hajlandó felvenni, és mindig az a vége, hogy nincs kapacitása ezzel foglalkozni, mert az elején működött 5 irodával a program.

A az adatbázis össze mérete 5,3gb pma szerint, bár a /var/lib/mysql/libdata1 file mérete 12gb.

Mivel a fejlesztőt úgy tűnik nem érdekli már ez az egész, ezért keresünk olyan embert, aki ha rá tud nézni a forrásra, illetve ssh-n a szerverre, akkor meg tudja mondani, némi diagnosztikát követően, hogy mi a hiba, és, hogy ő ki tudja-e javítani, illetve mennyiért tenné ezt meg!

random ötlet, de:
nincs valami fail2ban vagy egyéb WAF ami beletilt a kapcsolatokba?

Szerk:
látom, csak röpke 4 órája írtad le, hogy nincs a mysql mellett fail2ban... fail.
És a túloldalt? vagy menet közben?

Most ideiglenesen kikapcsoltam a fail2ban-t, hogy lássuk, beleszól-e a kommunikációba attól függetlenül, hogy nem naplóz semmilyen eseményt.
Minden irodában egy TP-Link WR842ND-router került beüzemelésre, de nem spórolási okokból, hanem azért mert a DRAYTEQ Vigor 2225 , vagy a Mikrotik RB750Gr3, mögül nem volt hajlandó egyik teremben lévő SLOT gép sem kapcsolódni a WiFi, vagy vezetékes ethernet hálózathoz, kizárólag az egyszerű TP-link mögött voltak hajlandóak kommunikálni, azaz egyáltalán csatlakozni.

Átnéztük az összes logot a fent említett 2 router naplójában, de semmi nem volt benne, hogy miért nem hajlandóak csatlakozni, és a kliensek sem voltak beszédesebbek sajnos, így a gyártó javaslatára tettünk be TP-link routereket, amin fel is csatlakoztak, minden probléma nélkül.

A slot gépek , illetve az említett java kliens program függetlenek egymástól, olyan szinten, hogy a slot gépek RS-232-n küldik az adatot egy-egy banán-pc-nek, amik továbbküldik az adatot a programnak vezetékes etherneten keresztül.

Menet közben elvileg nincs blokkolva kapcsolat, bár mindenhol DIGI üzleti előfizetés van 100/100 Mbps sebességgel, és DIGI-től azt nyilatkozták, hogy nincs szűrés.

Hm, pedig ha timeoutol, akkor valami elveszhet menet közben.

Esetleg wiresharkkal nézd logold a forgalmat és retransmission-öket keress. Ha van elvesző csomag, akkor azt valamelyik router dobhatja el.

A szimptómák egybeesnek a tplinkek berakásával, vagy bármi mással? (mittomén, jött a meleg és főnek a routerek)

Én már a hibaleírásban elakadtam: "java alkalmazás szerver verziója" és aztán 3306-os (mysql) portokat vizsgálsz.
Ha a kliensek a 3306-ra kapcsolódnak akkor ez egy kétrétegű alkalmazás.
Ha egy Java-ban írt serverhez (ami aztán lokálisan a 3306-ra) akkor háromrétegű alkalmazás.
Utóbbi esetben értelemszerűen a klienseknek nem a 3306-ra kell bejönnie hanem a server alkalmazás megfelelő portjára.

Érdemes lenne felrajzolni a kommunikációs utat. Persze nem feltételezések hanem "bizonyítékok" alapján.

Más: "nem szeretnénk adatvesztést": ugye mentés van?
--
Gábriel Ákos

Igazad van, mert a 12121-es porton csatlakoznak be a kliensek a java alkalmazáshoz, és az adja át mysql-connector-java segítségével a 3306-os porton a mysql szerver felé az adatokat.
Így az lsof -i:12121 parancs kimenete ugyanúgy TCP kapcsolatokat mutatnak, de a felépített kapcsolatokból van kb 114 db az alább írtam részletet a kimenetből:

java 1923 root 11u IPv6 426024 0t0 TCP *:12121 (LISTEN)
java 1923 root 12u IPv6 386446 0t0 TCP server.xy.ro:12121->X.X.229.118:41686 (CLOSE_WAIT)
java 1923 root 14u IPv6 321998 0t0 TCP server.xy.ro:12121->X.X.229.118:18120 (CLOSE_WAIT)
java 1923 root 15u IPv6 338962 0t0 TCP server.xy.ro:12121->xy.ro:44752 (CLOSE_WAIT)
java 1923 root 16u IPv6 323449 0t0 TCP server.xy.ro:12121->X.X.229.118:18121 (CLOSE_WAIT)
java 1923 root 17u IPv6 326419 0t0 TCP server.xy.ro:12121->X.X.229.117:44861 (CLOSE_WAIT)
java 1923 root 19u IPv6 324744 0t0 TCP server.xy.ro:12121->X.X.229.117:37765 (CLOSE_WAIT)

Így ezek szerint ez egy három rétegű alkalmazás.

Persze van minden hajnalban egy mysql dump, ami az összes adatbázis elkülönítve dumpolja, de mivel nem vagyok túl gyakorlott mysql-ban , így nem tudom-ez elég-e arra az esetre, ha /var/lib/mysql/ibdata1 file is megsérülne.

"CLOSE_WAIT means that the local end of the connection has received a FIN from the other end, but the OS is waiting for the program at the local end to actually close its connection.

The problem is your program running on the local machine is not closing the socket. It is not a TCP tuning issue. A connection can (and quite correctly) stay in CLOSE_WAIT forever while the program holds the connection open.

Once the local program closes the socket, the OS can send the FIN to the remote end which transitions you to LAST_ACK while you wait for the ACK of the FIN. Once that is received, the connection is finished and drops from the connection table (if your end is in CLOSE_WAIT you do not end up in the TIME_WAIT state)."

Szóval programhiba, szerver oldalon.
--
Gábriel Ákos

Ha dobódik Exception és látszik a szerver alkalmazás (vagy a servlet container) logjában, akkor abból elég jól megtippelhető, mi lehet a gond. Lehet, hogy állítani kell a log level-en (mondjuk DEBUG-ra), hogy több infót lássatok. Ilyen tüneteket okozhat egy memory leak az adatbázist kezelő osztályokban, vagy egy elavult/nem megfelelő ConnectionPool is.

A szerver oldali program logját nagy nehezen megtaláltam, amiben az alábbi sorok szerepelnek:

https://pastebin.com/YEpUPQNm

Ebből annyit látok, én , hogy a fogadott adattal problémázik, azaz , mintha a kliensek nem megfelelő mennyiségű / formájú adatokat küldenének, vagyis, ha jól látom kliens oldalon van a gond, de legyetek szívesek erősítsetek meg, ha valamit félre értek.

Elképzelhető, hogy a program adatbázis kezelésével is gondok lehetnek, mert ha egy új helyet nyitunk, és oda bekerül egy pc, minek egy authentikációs kulcsot generálok le, akkor az csak úgy hajlandó becsatlakozni a rendszerben, ha a fejlesztő valamit csinál a mysql-ben, de azt persze nem árulja el, hogy mit kell ilyenkor csinálni.

A log alapján én valami olyasmit látok, hogy vannak bejövő kapcsolatok, de adatok nem nagyon jönnek, valahol elakad a kommunikáció, aztán kB. 30 sec múlva timeout-ol. Aztán van ott egy Lock wait timeout Exception, ami már a mysql-connector-tól jön, és semmi jót nem jelent, valószínűleg kifogy a használható kapcsolatokról a JDBC. Alighanem nem zárja le az adatbázis kapcsolatokat a szerveroldali app, ha nem zárul sikeresen a klienssel a kommunikáció. Ez is gond, de az eredeti ok szerintem az, hogy a klienstől nem jön rendesen az adat, vagy a szervertől vár valami nyugtára a kliens, és azért lesz timeout. A kliens oldali logokban még lehet valami érdekes.

Én ezt az egész problémát odahajítanám a fejlesztőnek, tisztán látszik, hogy nem MySQL oldali gond van. Nem a MySQL szerver a hibás, nem is kell azt debugolni. A fejlesztő azért van tartva, hogy a programjával kapcsolatos hibákat fejtse fel.

De én leginkább keresnék egy új fejlesztőt. Szerintem ennek az alkalmazásrendszernek még rendes dokumentációja sincs.
--
Blog | @hron84

"valahol egy üzemeltetőmaci most mérgesen toppant a lábával" via @snq-

Alapvetően a fejlesztő kapott egy egyszeri díjazást, aminek fejében meg volt bízva egy teljes értékűen üzemelő program + a dokumentáció és a forráskód átadásával , előzetesen megszabott feltételek mellet, mind a program működésére, mind a program forrására vonatkozólag. Tekintve, hogy mi a forrás felhasználásával nem módosítottuk a programot, és annak semmilyen komponensét, viszont a program mégsem üzemelt üzemszerűen, így vállalta, hogy az általam leírt tapasztalatok alapján elindul a hiba feltárásán és megoldásán.

A hibát elvileg vasárnap este feltárta és megoldotta, és most működik a program, mert minden kliens képes becsatlakozni, és (ESTABLISHED) minden kapcsolat, amin a program kommunikál.

Mivel az Én tapasztalataim javarészt a Ti válaszaitokból tevődött össze, és világosodott meg a hiba jellege, ezért szeretném még egyszer megköszönni minden építő és segítő jellegű választ, amit tőletek itt kaptam!

Örülök, hogy segíthettem.

És remélem, hogy tanultatok ebből az esetből, hogy egy kritikus szoftverhez mindig venni kell/kötni kell támogatási szerződést is. Mert a programok néha elromlanak, és nem mindig lehet üzletileg a fejlesztő jófejségére alapozni.
--
Blog | @hron84

"valahol egy üzemeltetőmaci most mérgesen toppant a lábával" via @snq-

"A töksötét bárban a pulton fekve, csukott szemmel, a jobb kezemmel sört iszogatva a bal kezemből a hátam mögé pöckölve egy dartot"-szintű tipp (értsd: jó eséllyel nem fog találni...), de egy próbát megér, hogy a szerveren kikapcsolod a selective ack-ot (echo "0" > /proc/sys/net/ipv4/tcp_sack), digi hálózat felől láttam egyszer olyat, hogy random sequence numberek jöttek, ami miatt minimális forgalom és/vagy idő után timeoutolt valamelyik oldal (akármi is módosította őket, a SACK-ban már nem bántotta az értékeket, így mindkét gép ack-ra várt, aztán dobta a kapcsolatot).

De egy tcpdump-ot mindenképp megérne a sztori, hátha abból kiderül a szakadás oka, ez nekem inkább tűnik a szerver-kliens mint a szerver-adatbázis közti hibának.

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

Sysctl a mysql kornyeken hasonlo beallitasokkal tuzdelt-e..? ->
"...
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
..."