Çawa û çima me ji bo 1C karûbarek berbelavkirî ya bargiran nivîsand: Pargîdanî: Java, PostgreSQL, Hazelcast

Di vê gotarê de em ê li ser ka çawa û çima em pêşkeftî biaxivin Pergala Têkilî - mekanîzmayek ku di navbera serîlêdanên xerîdar û serverên 1C: Enterprise de agahdarî vediguhezîne - ji danîna peywirê bigire heya fikirîna bi hûrguliyên mîmarî û pêkanînê.

Pergala Danûstandinê (ji vir şûnde wekî SV tê binavkirin) pergalek peyamsaziyê ya belavbûyî, berterefker e ku bi teslîmkirina garantîkirî ye. SV wekî karûbarek bargiraniyek bi pîvana bilind hatî sêwirandin, hem wekî karûbarek serhêl (ji hêla 1C ve hatî peyda kirin) hem jî wekî hilberek girseyî ya ku dikare li ser dezgehên servera we were bicîh kirin peyda dibe.

SV hilanînê belavkirî bikar tîne hazelcast û motora lêgerînê Elasticsearch. Em ê her weha li ser Java-yê biaxivin û ka meriv çawa PostgreSQL-ê bi horizontî pîvand dike.
Çawa û çima me ji bo 1C karûbarek berbelavkirî ya bargiran nivîsand: Pargîdanî: Java, PostgreSQL, Hazelcast

Formulkirina pirsgirêkê

Ji bo ku em zelal bikin ka çima me Pergala Têkilî çêkir, ez ê hinekî ji we re vebêjim ka çawa pêşkeftina serîlêdanên karsaziyê di 1C de dixebite.

Ji bo destpêkê, hinekî li ser me ji bo kesên ku hîn nizanin em çi dikin :) Em platforma teknolojiya 1C: Enterprise çêdikin. Platform di nav xwe de amûrek pêşkeftina serîlêdana karsaziyê, û her weha demek xebitandinê heye ku dihêle serîlêdanên karsaziyê di hawîrdorek cross-platform de bixebitin.

Paradîgmaya pêşveçûna muwekîlê-server

Serlêdanên karsaziyê yên ku li ser 1C hatine afirandin: Enterprise di sê-ast de dixebite muwekîlê-server mîmarî "DBMS - servera serîlêdanê - xerîdar". Koda serîlêdanê tê de hatî nivîsandin di zimanê 1C de çêkirî, dikare li ser servera serîlêdanê an li ser xerîdar were darve kirin. Hemî karên bi tiştên serîlêdanê (rêveber, belge, hwd.), û hem jî xwendin û nivîsandina databasê, tenê li ser serverê têne kirin. Karbidestiya form û navgîniya fermanê jî li ser serverê tête bicîh kirin. Xerîdar wergirtin, vekirin û nîşandana forman, "ragihandina" bi bikarhêner re (hişyarî, pirs...), di formên ku bersivek bilez hewce dike de hesabên piçûk pêk tîne (mînak, pirkirina nirxê li gorî hejmarê), bi pelên herêmî re dixebite, bi alavan re dixebitin.

Di koda serîlêdanê de, sernavên prosedur û fonksiyonan divê bi eşkere destnîşan bikin ku kod dê li ku derê were darve kirin - bi karanîna rêwerzên &AtClient / &AtServer (&AtClient / &AtServer di guhertoya zimanî ya Englishngilîzî de). Pêşdebirên 1C naha dê min rast bikin bi gotina ku rêwerzan bi rastî ne bêtir, lê ji bo me ev niha ne girîng e.

Hûn dikarin koda serverê ji koda xerîdar re bang bikin, lê hûn nikarin koda xerîdar ji koda serverê vebêjin. Ev sînorek bingehîn e ku me ji ber çend sedeman çêkiriye. Bi taybetî, ji ber ku koda serverê divê bi vî rengî were nivîsandin ku ew bi heman rengî bêyî ku jê re tê gotin - ji xerîdar an ji serverê ve were nivîsandin. Û di mijara gazîkirina koda serverê de ji kodek serverek din, bi vî rengî xerîdar tune. Û ji ber ku di dema pêkanîna koda serverê de, muwekîlê ku jê gazî kiriye dikaribû bigire, ji serîlêdanê derkeve, û server dê êdî kesek tune ku gazî bike.

Çawa û çima me ji bo 1C karûbarek berbelavkirî ya bargiran nivîsand: Pargîdanî: Java, PostgreSQL, Hazelcast
Koda ku bişkojek bikirtîne: bangkirina prosedurek serverê ji xerîdar dê bixebite, bangkirina prosedurek xerîdar ji serverê dê ne

Ev tê wê wateyê ku heke em bixwazin hin peyamek ji serverê bişînin serîlêdana xerîdar, mînakî, ku hilberîna raporek "dûr-dirêj" qediyaye û rapor dikare were dîtin, rêbazek me tune. Pêdivî ye ku hûn hîleyan bikar bînin, mînakî, bi awayekî periyodîk serverê ji koda xerîdar bipirsin. Lê ev nêzîkatî pergalê bi bangên nehewce bar dike, û bi gelemperî pir xweşik xuya nake.

Û her weha pêdivî ye, wek nimûne, gava ku têlefonek tê JÊDERXISTIN- dema ku têlefonek çêdikin, serîlêdana xerîdar li ser vê yekê agahdar bikin da ku ew bikaribe nimreya bangker bikar bîne da ku wê di databasa hevalbendê de bibîne û agahdariya bikarhêner li ser hevalbendê gazî nîşan bide. An jî, wek nimûne, gava ku fermanek digihîje depoyê, serîlêdana xerîdar a xerîdar li ser vê yekê agahdar bike. Bi gelemperî, gelek rewş hene ku mekanîzmayek wusa dê kêrhatî be.

Hilberîna xwe bixwe

Mekanîzmaya şandina peyaman çêbikin. Zû, pêbawer, bi radestkirina garantîkirî, bi şiyana lêgerîna bi nermî li peyaman. Li ser bingeha mekanîzmayê, peyamberek (peyam, bangên vîdyoyê) ku di hundurê serîlêdanên 1C de dixebite bicîh bikin.

Pergalê dîzayn bikin ku bi rengek horizontî berbelav be. Pêdivî ye ku barkirina zêde bi zêdebûna hejmara nokan ve were vegirtin.

Реализация

Me biryar da ku em beşa serverê ya SV rasterast di platforma 1C: Enterprise de yek nekin, lê em wê wekî hilberek cihêreng bicîh bikin, API-ya ku dikare ji koda çareseriyên serîlêdana 1C were gazî kirin. Ev ji ber çend sedeman hate kirin, ya sereke ev bû ku min dixwest ku ez viya bikim danûstendina peyaman di navbera serîlêdanên cihêreng ên 1C de (mînakî, di navbera Rêvebiriya Bazirganî û Hesabkirinê de). Serlêdanên cihêreng ên 1C dikarin li ser guhertoyên cihêreng ên platforma 1C: Enterprise bimeşînin, li ser serverên cihêreng bicîh bibin, hwd. Di şert û mercên weha de, pêkanîna SV-ê wekî hilberek veqetandî ku "li alî" sazkirinên 1C-ê ye çareseriya çêtirîn e.

Ji ber vê yekê, me biryar da ku em SV wekî hilberek cûda çêbikin. Em pêşniyar dikin ku pargîdaniyên piçûk servera CB-ya ku me di ewrê xwe de saz kiriye (wss://1cdialog.com) bikar bînin da ku ji lêçûnên zêde yên ku bi sazkirin û veavakirina herêmî ya serverê re têkildar in dûr bixin. Dibe ku xerîdarên mezin şîret bibînin ku servera xweya CB-ê li sazgehên xwe saz bikin. Me di hilbera xweya cloudê SaaS de nêzîkatiyek wusa bikar anî 1cFresh - ew wekî hilberek girseyî ya ji bo sazkirinê li malperên xerîdar tê hilberandin, û di ewrê me de jî tê bicîh kirin https://1cfresh.com/.

App

Ji bo belavkirina tolerasyona bar û xeletiyê, em ê ne yek serîlêdana Java-yê, lê çendan, bi hevsengek barkirinê li pêş wan bicîh bikin. Heke hûn hewce ne ku peyamek ji nod to node veguhezînin, di Hazelcast-ê de weşandin / abonetiyê bikar bînin.

Têkiliya di navbera xerîdar û serverê de bi riya websocketê ye. Ew ji bo pergalên rast-ê baş e.

Cache belav kirin

Me di navbera Redis, Hazelcast û Ehcache de hilbijart. 2015 e. Redis tenê komek nû derxist (pir nû, tirsnak), Sentinel bi gelek qedexeyan heye. Ehcache nizane meriv çawa di nav komekê de bicive (ev fonksiyon paşê xuya bû). Me biryar da ku wê bi Hazelcast 3.4 biceribîne.
Hazelcast ji qutikê di nav komekê de tê berhev kirin. Di moda yek girêk de, ew ne pir bikêr e û tenê dikare wekî cache were bikar anîn - ew nizane meriv çawa daneyan davêje dîskê, heke hûn girêka yekane winda bikin, hûn daneyê winda dikin. Em gelek Hazelcasts bi cih dikin, di navbera wan de em daneyên krîtîk hildiweşînin. Em cache paşve nagirin - em jê aciz nabin.

Ji bo me, Hazelcast ev e:

  • Storage danişînên bikarhêner. Demek dirêj hewce dike ku meriv her carê ji bo danişînê biçin databasê, ji ber vê yekê em hemî danişînan di Hazelcast de dihêlin.
  • Cache. Heke hûn li profîlek bikarhênerek digerin, cache-ê kontrol bikin. Peyamek nû nivîsand - wê têxe kaşê.
  • Mijarên ji bo danûstendina di navbera mînakên serîlêdanê de. Girêk bûyerek çêdike û di mijara Hazelcast de cîh dike. Girêdanên din ên serîlêdanê yên ku di vê mijarê de hatine qeyd kirin bûyerê distînin û pêvajoyê dikin.
  • Girtiyên komê. Mînakî, em bi karanîna mifteyek bêhempa (gotûbêjek yekane di nav databasa 1C de) nîqaşek diafirînin:

conversationKeyChecker.check("БЕНЗОКОЛОНКА");

      doInClusterLock("БЕНЗОКОЛОНКА", () -> {

          conversationKeyChecker.check("БЕНЗОКОЛОНКА");

          createChannel("БЕНЗОКОЛОНКА");
      });

Me kontrol kir ku kanal tune. Me kilît girt, dîsa ew kontrol kir û ew çêkir. Ger hûn piştî girtina qeflê kontrol nekin, wê hingê şansek heye ku mijarek din jî di wê gavê de were kontrol kirin û naha dê hewl bide ku heman nîqaşê biafirîne - lê ew jixwe heye. Hûn nikarin bi karanîna Locka java ya hevdemkirî an birêkûpêk kilît bikin. Bi navgîniya databasê - ew hêdî ye, û ji bo databasê xemgîn e; bi navgîniya Hazelcast - ya ku hûn hewce ne ev e.

Hilbijartina DBMS

Tecrubeya me ya berfireh û serketî heye ku bi PostgreSQL re dixebitin û bi pêşdebirên vê DBMS re hevkariyê dikin.

Bi komek PostgreSQL re ne hêsan e - heye XL, XC, Citus, lê bi gelemperî ev ne NoSQL-yên ku ji qutîkê derdikevin ne. Me NoSQL wekî depoya sereke nehesiband; bes bû ku me Hazelcast girt, ku me berê pê re nexebitî.

Heke hûn hewce ne ku databasek pêwendiyek pîvan bikin, ev tê vê wateyê parvekirin. Wekî ku hûn dizanin, bi parvekirinê re em databasê li beşên cuda dabeş dikin da ku her yek ji wan li ser serverek cihê were danîn.

Guhertoya yekem a parvekirina me şiyana belavkirina her tabloyên serîlêdana me li ser serverên cihêreng bi rêjeyên cûda destnîşan kir. Li ser server A-yê gelek peyam hene - ji kerema xwe, em beşek ji vê tabloyê biguhezînin servera B. Vê biryarê bi tenê li ser xweşbîniya pêşwext diqîriyan, ji ber vê yekê me biryar da ku xwe bi nêzîkatiyek pir-kirêdar ve sînordar bikin.

Ji bo nimûne, hûn dikarin li ser malpera pir-kirêdar bixwînin Daneyên Citus.

SV têgehên serîlêdanê û abonetiyê heye. Serlêdan sazkirinek taybetî ya serîlêdana karsaziyê ye, wekî ERP an Hesabkirin, digel bikarhêner û daneyên karsaziya xwe. Abonet rêxistinek an kesek e ku li ser navê wî serîlêdan di servera SV de qeydkirî ye. Abonetek dikare çend serlêdanan tomar bike, û ev serîlêdan dikarin bi hev re peyaman biguhezînin. Abonet di pergala me de bû kirêdar. Peyamên ji çend aboneyan dikarin di yek databasa laşî de werin cîh kirin; heke em bibînin ku aboneyek dest bi çêkirina gelek seyrûseferê kiriye, em wê diguhezînin databasek fîzîkî ya cihê (an tewra serverek databasek cihê).

Me databasek sereke heye ku tê de tabloyek rêvekirinê bi agahdariya cîhê hemî databasên aboneyan tê hilanîn.

Çawa û çima me ji bo 1C karûbarek berbelavkirî ya bargiran nivîsand: Pargîdanî: Java, PostgreSQL, Hazelcast

Ji bo ku nehêle databasa bingehîn bibe kêşek, em tabloya rêvekirinê (û daneyên din ên ku pir caran hewce ne) di cache de digirin.

Ger databasa aboneyê dest bi hêdîbûnê bike, em ê wê di hundurê de dabeşan bikin. Li ser projeyên din em bikar tînin pg_pathman.

Ji ber ku windakirina peyamên bikarhêner xirab e, em databasên xwe bi kopiyan diparêzin. Kombûna kopiyên hevdem û asînkron dihêle hûn di rewşa windabûna databasa sereke de xwe sîgorte bikin. Wendabûna peyamê tenê dê çêbibe heke databasa bingehîn û kopya wê ya hevdem bi hevdemî têk biçin.

Heke kopiyek hevdem winda bibe, replika asynchronous dibe hemdem.
Ger databasa sereke winda bibe, kopya hevdem dibe databasa sereke, û kopya asynchronous dibe kopiyek hemdem.

Elastics ji bo lêgerînê digerin

Ji ber ku, di nav tiştên din de, SV di heman demê de qasidek e, ew hewceyê lêgerînek bilez, hêsan û maqûl e, ku morfolojiyê li ber çavan bigire, bi karanîna maçên nerast ve. Me biryar da ku em çerxê ji nû ve neafirînin û motora lêgerînê ya belaş Elasticsearch, ku li ser bingeha pirtûkxaneyê hatî afirandin, bikar bînin Lucene. Em di heman demê de Elasticsearch-ê di komek (master - dane - dane) de bicîh dikin da ku di bûyera têkçûna girêkên serîlêdanê de pirsgirêkan ji holê rakin.

Li ser github me dît Pêveka morfolojiya rûsî ji bo Elasticsearch û wê bikar bînin. Di navnîşa Elasticsearch de em kokên peyvan (yên ku pêvek destnîşan dike) û N-gram hilînin. Gava ku bikarhêner ji bo lêgerînê têkeve nivîsê, em di nav N-graman de li metna çapkirî digerin. Dema ku li indexê were hilanîn, peyva "nivisan" dê li N-gramên jêrîn were dabeş kirin:

[ewên, tek, tex, nivîsar, nivîsar, ek, berê, ext, nivîsar, ks, kst, ksty, st, stî, hûn],

Û koka peyva ”text” jî dê were parastin. Ev nêzîkatî dihêle hûn di destpêkê, navîn û dawiya peyvê de bigerin.

Wêneyê mezin

Çawa û çima me ji bo 1C karûbarek berbelavkirî ya bargiran nivîsand: Pargîdanî: Java, PostgreSQL, Hazelcast
Wêneyê ji destpêka gotarê dubare bikin, lê bi ravekirinan:

  • Balanser li ser Înternetê tê xuyang kirin; me nginx heye, ew dikare her be.
  • Mînakên serîlêdana Java-yê bi Hazelcast bi hevûdu re têkilî daynin.
  • Ji bo ku em bi soketek webê re bixebitin Nettie.
  • Serlêdana Java di Java 8-ê de hatî nivîsandin û ji pakêtan pêk tê OSGi. Di planan de koçkirina Java 10 û derbasbûna modulan vedihewîne.

Pêşveçûn û ceribandin

Di pêvajoya pêşkeftin û ceribandina SV de, em rastî gelek taybetmendiyên balkêş ên hilberên ku em bikar tînin de hatin.

Testkirina barkirinê û leaksên bîranînê

Serbestberdana her serbestberdana SV ceribandina barkirinê pêk tîne. Ew serketî ye dema ku:

  • Testê çend rojan xebitî û tu têkçûna xizmetguzariyê çênebû
  • Dema bersivdayînê ji bo operasyonên sereke ji tixûbek rehet derbas nebû
  • Xerabûna performansê li gorî guhertoya berê ji %10 ne zêdetir e

Em databasa testê bi daneyan tijî dikin - ji bo vê yekê, em agahdariya li ser aboneyê herî çalak ji servera hilberînê digirin, hejmarên wê bi 5 (hejmara peyaman, nîqaşan, bikarhêneran) zêde dikin û bi vî rengî ceribandinê dikin.

Em ceribandina barkirinê ya pergala danûstendinê di sê mîhengan de pêk tînin:

  1. testa stresê
  2. Tenê girêdan
  3. Qeydkirina abonetiyê

Di dema ceribandina stresê de, em çend sed mijaran dest pê dikin, û ew pergalê bêyî rawestan bar dikin: nivîsandina peyaman, afirandina nîqaşan, wergirtina navnîşek peyaman. Em tevgerên bikarhênerên asayî simulasyonê dikin (lîsteyek ji peyamên min ên nexwendî bistînin, ji kesek re binivîsin) û çareseriyên nermalavê (pakêtek veavakirinek cûda veguhezînin, hişyariyek pêvajo bikin).

Mînakî, beşek ji testa stresê ev e:

  • Bikarhêner têketinê
    • Daxwaza nîqaşên we yên nexwendî dike
    • 50% îhtîmal e ku peyaman bixwînin
    • 50% îhtîmala nivîsandinê
    • Bikarhênerê din:
      • Ji %20 şansê çêkirina nîqaşek nû heye
      • Bi rasthatinî yek ji nîqaşên xwe hildibijêre
      • Dikeve hundir
      • Daxwaza peyaman, profîlên bikarhêneran dike
      • Ji vê nîqaşê pênc peyamên ku ji bikarhênerên rasthatî re têne navnîş kirin diafirîne
      • Gotûbêjê berdide
      • 20 caran dubare dike
      • Têkeve, vedigere destpêka senaryoyê

    • Chatbotek dikeve pergalê (peyamên ji koda serîlêdanê mîna hev dike)
      • 50% şansê çêkirina kanalek nû ji bo danûstendina daneyê heye (gotûbêja taybetî)
      • 50% îhtîmal e ku ji yek ji kanalên heyî re peyamek binivîse

Senaryoya "Tenê Têkilî" ji ber sedemek xuya bû. Rewşek heye: bikarhêneran pergalê ve girêdaye, lê hîn jî tevlî nebûne. Her bikarhênerek serê sibê saet di 09:00 de kompîturê vedike, bi serverê re têkiliyek saz dike û bêdeng dimîne. Van xortan xeternak in, gelek ji wan hene - tenê pakêtên wan PING / PONG in, lê ew pêwendiya bi serverê re diparêzin (ew nikanin wê bidomînin - heke peyamek nû hebe çi). Test rewşek ku hejmareke mezin ji bikarhênerên weha hewl didin ku di nîv saetê de têkevin pergalê dubare dike. Ew mîna ceribandinek stresê ye, lê bala wê bi rastî li ser vê têketina yekem e - da ku têkçûn nebin (kesek pergalê bikar neyîne, û ew berê xwe davêje - dijwar e ku meriv tiştek xirabtir bifikire).

Skrîpta qeydkirina aboneyan ji destpêka yekem dest pê dike. Me testek stresê pêk anî û pê bawer bûn ku di dema ragihandinê de pergal hêdî nebû. Lê bikarhêner hatin û qeydkirin ji ber demdirêjiyê dest pê kir. Dema qeydkirinê me bi kar anî / dev / bêhemdî, ku bi entropiya pergalê ve girêdayî ye. Pêşkêşkar wext neda ku têra entropiyê berhev bike û dema ku SecureRandomek nû hate xwestin, ew bi deh saniyan cemidand. Gelek rêyên derketina ji vê rewşê hene, wek nimûne: veguherînin /dev/urandom-ya kêmtir ewledar, tabloyek taybetî ya ku entropiyê çêdike saz bikin, hejmarên rasthatî ji pêş ve çêbikin û wan di hewzê de hilînin. Me bi demkî pirsgirêka hewzê girt, lê ji hingê ve me ceribandinek cihêreng ji bo tomarkirina aboneyên nû dimeşîne.

Em wekî jeneratorê barkirinê bikar tînin JMeter. Ew nizane meriv çawa bi websocket re bixebite; pêvekek pêdivî ye. Di encamên lêgerînê de yekem ji bo pirsa "jmeter websocket" ev in: gotarên ji BlazeMeter, ku pêşniyar dikin pêveka Maciej Zaleski.

Li wir me biryar da ku em dest pê bikin.

Hema hema tavilê piştî destpêkirina ceribandina ciddî, ​​me kifş kir ku JMeter dest bi rijandina bîranînê kir.

Pêvek çîrokek mezin a cihê ye; bi 176 stêrkan, 132 forkên wê li ser github hene. Nivîskar bi xwe ji sala 2015-an vir ve (me ew di sala 2015-an de girt, dûv re ew guman nekiriye), gelek pirsgirêkên github ên di derheqê rijandinên bîranînê de, 7 daxwazên vekişînê yên negirtî.
Ger hûn biryar didin ku bi karanîna vê pêvekê ceribandina barkirinê bikin, ji kerema xwe bala xwe bidin nîqaşên jêrîn:

  1. Di hawîrdorek pir-mijarî de, LinkedListek birêkûpêk hate bikar anîn, û encam bû NPE di dema xebatê de. Ev dikare bi veguheztina ConcurrentLinkedDeque an bi blokên hevdemkirî ve were çareser kirin. Me ji xwe re vebijarka yekem hilbijart (https://github.com/maciejzaleski/JMeter-WebSocketSampler/issues/43).
  2. Leza bîranînê; dema veqetandinê, agahdariya girêdanê nayê jêbirin (https://github.com/maciejzaleski/JMeter-WebSocketSampler/issues/44).
  3. Di moda weşanê de (gava ku websocket di dawiya nimûneyê de girtî nebe, lê paşê di planê de tê bikar anîn), Nimûneyên bersivê naxebitin (https://github.com/maciejzaleski/JMeter-WebSocketSampler/issues/19).

Ev yek ji wan ên li ser github e. Me çi kir:

  1. birin fork Elyran Kogan (@elyrank) - ew pirsgirêkên 1 û 3 rast dike
  2. Pirsgirêk çareser kirin 2
  3. Ji 9.2.14 heta 9.3.12 keştiya nûvekirî
  4. SimpleDateFormat di ThreadLocal de pêça; SimpleDateFormat ne ewledar e, ku di dema xebitandinê de bû sedema NPE
  5. Lezgîniyek din a bîranînê rast kir (Gava ku hate qut kirin girêdan xelet hate girtin)

Û dîsa jî diherike!

Bîr ne di rojekê de, lê di du rojan de dest pê kir. Bê guman dem nemabû, ji ber vê yekê me biryar da ku em kêmtir mijaran bidin destpêkirin, lê li ser çar ajanan. Ev divê herî kêm hefteyekê bes bûya.

Du roj derbas bûn...

Niha Hazelcast ji bîrê diqede. Têketin destnîşan kirin ku piştî ceribandinek du rojan, Hazelcast dest bi gilîkirina kêmbûna bîranînê kir, û piştî demekê kom ji hev ket, û girêk yek bi yek mirina xwe domandin. Me JVisualVM bi hazelcast ve girêda û "dîrek rabûn" dît - wê bi rêkûpêk gazî GC kir, lê nekarî bîranînê paqij bike.

Çawa û çima me ji bo 1C karûbarek berbelavkirî ya bargiran nivîsand: Pargîdanî: Java, PostgreSQL, Hazelcast

Derket holê ku di hazelcast 3.4 de, dema ku nexşeyek / multiMap (map.destroy() jêbirin, bîra bi tevahî nayê azad kirin:

github.com/hazelcast/hazelcast/issues/6317
github.com/hazelcast/hazelcast/issues/4888

Bûk naha di 3.5-ê de hatî rast kirin, lê wê hingê ew pirsgirêkek bû. Me pirNexşeyên nû bi navên dînamîk afirandin û li gorî mantiqa xwe jêbirin. Kod tiştek bi vî rengî xuya bû:

public void join(Authentication auth, String sub) {
    MultiMap<UUID, Authentication> sessions = instance.getMultiMap(sub);
    sessions.put(auth.getUserId(), auth);
}

public void leave(Authentication auth, String sub) {
    MultiMap<UUID, Authentication> sessions = instance.getMultiMap(sub);
    sessions.remove(auth.getUserId(), auth);

    if (sessions.size() == 0) {
        sessions.destroy();
    }
}

Vыzov:

service.join(auth1, "НОВЫЕ_СООБЩЕНИЯ_В_ОБСУЖДЕНИИ_UUID1");
service.join(auth2, "НОВЫЕ_СООБЩЕНИЯ_В_ОБСУЖДЕНИИ_UUID1");

multiMap ji bo her abonetiyê hate afirandin û gava ku ne hewce bû hate jêbirin. Me biryar da ku em dest bi Nexşeyê bikin , mift dê navê abonetiyê be, û nirx dê bibin nasnavên danişînê (heke hewce be hûn dikarin nasnameyên bikarhêner jê bistînin).

public void join(Authentication auth, String sub) {
    addValueToMap(sub, auth.getSessionId());
}

public void leave(Authentication auth, String sub) { 
    removeValueFromMap(sub, auth.getSessionId());
}

Nexşe çêtir bûne.

Çawa û çima me ji bo 1C karûbarek berbelavkirî ya bargiran nivîsand: Pargîdanî: Java, PostgreSQL, Hazelcast

Em di derbarê ceribandina barkirinê de çi hîn bûne?

  1. JSR223 pêdivî ye ku bi groovy were nivîsandin û cache berhevkirinê tê de hebe - ew pir zûtir e. link.
  2. Grafikên Jmeter-Plugins ji yên standard hêsantir têne fêm kirin. link.

Li ser ezmûna me bi Hazelcast re

Hazelcast ji bo me hilberek nû bû, me ji guhertoya 3.4.1 pê re dest bi xebatê kir, naha servera hilberîna me guhertoya 3.9.2 dimeşîne (di dema nivîsandinê de, guhertoya herî dawî ya Hazelcast 3.10 e).

nifşê ID

Me bi nasnameyên yekjimar dest pê kir. Ka em bifikirin ku ji bo hebûnek nû ji me re Dirêjek din hewce ye. Rêzeya di databasê de ne guncaw e, tablo bi parvekirinê re têkildar e - derket holê ku di DB1 de ID=1 û di DB1 de ID=2 peyamek heye, hûn nekarin vê ID-ê li Elasticsearch, ne jî di Hazelcast-ê de bixin. , lê ya herî xirab ew e ku hûn dixwazin daneyên du databasan di yek de bidin hev (mînak, biryar bidin ku yek databas ji bo van aboneyan bes e). Hûn dikarin çend AtomicLongs li Hazelcast zêde bikin û jimarvan li wir bihêlin, wê hingê performansa wergirtina nasnameyek nû zêde dibe û wextê daxwazek ji Hazelcastê re zêde dibe. Lê Hazelcast tiştek çêtir e - FlakeIdGenerator. Dema ku bi her xerîdar re têkilî daynin, rêzek nasnameyê ji wan re tê dayîn, mînakî, ya yekem - ji 1 heta 10, ya duyemîn - ji 000 heta 10, û hwd. Naha xerîdar dikare bi tena serê xwe nasnameyên nû derxîne heya ku qada ku jê re hatî dayîn bi dawî bibe. Ew zû dixebite, lê gava ku hûn serîlêdanê (û xerîdar Hazelcast) ji nû ve bidin destpêkirin, rêzek nû dest pê dike - ji ber vê yekê avêtin, hwd. Wekî din, pêşdebiran bi rastî fêm nakin ka çima nasnameyên yekjimar in, lê ew qas nakokî ne. Me her tişt giran kir û berê xwe da UUID.

Bi awayê, ji bo kesên ku dixwazin bibin mîna Twitter-ê, pirtûkxaneyek Snowcast-ê ya wusa heye - ev pêkanîna Snowflake li ser Hazelcast-ê ye. Hûn dikarin li vir bibînin:

github.com/noctarius/snowcast
github.com/twitter/snowflake

Lê em êdî li dora wê negeriyan.

TransactionalMap.replace

Surprîzek din: TransactionalMap.replace naxebite. Li vir testek heye:

@Test
public void replaceInMap_putsAndGetsInsideTransaction() {

    hazelcastInstance.executeTransaction(context -> {
        HazelcastTransactionContextHolder.setContext(context);
        try {
            context.getMap("map").put("key", "oldValue");
            context.getMap("map").replace("key", "oldValue", "newValue");
            
            String value = (String) context.getMap("map").get("key");
            assertEquals("newValue", value);

            return null;
        } finally {
            HazelcastTransactionContextHolder.clearContext();
        }        
    });
}

Expected : newValue
Actual : oldValue

Diviya bû ku ez şûna xwe bi karanîna getForUpdate binivîsim:

protected <K,V> boolean replaceInMap(String mapName, K key, V oldValue, V newValue) {
    TransactionalTaskContext context = HazelcastTransactionContextHolder.getContext();
    if (context != null) {
        log.trace("[CACHE] Replacing value in a transactional map");
        TransactionalMap<K, V> map = context.getMap(mapName);
        V value = map.getForUpdate(key);
        if (oldValue.equals(value)) {
            map.put(key, newValue);
            return true;
        }

        return false;
    }
    log.trace("[CACHE] Replacing value in a not transactional map");
    IMap<K, V> map = hazelcastInstance.getMap(mapName);
    return map.replace(key, oldValue, newValue);
}

Ne tenê strukturên daneya birêkûpêk, lê di heman demê de guhertoyên wan ên danûstendinê jî ceribandin. Diqewime ku IMap dixebite, lê TransactionalMap êdî nemaye.

JARek nû bêyî demdirêj têxin

Pêşî, me biryar da ku em tiştên dersên xwe li Hazelcast tomar bikin. Mînakî, çînek me ya Serlêdanê heye, em dixwazin wê hilînin û bixwînin. Rizgarkirin:

IMap<UUID, Application> map = hazelcastInstance.getMap("application");
map.set(id, application);

Em dixwînin:

IMap<UUID, Application> map = hazelcastInstance.getMap("application");
return map.get(id);

Her tişt dixebite. Dûv re me biryar da ku em di Hazelcast de navnîşek ava bikin ku li gorî:

map.addIndex("subscriberId", false);

Û dema ku saziyek nû dinivîsin, wan dest bi wergirtina ClassNotFoundException kir. Hazelcast hewl da ku li indexê zêde bike, lê di derbarê pola me de tiştek nizanibû û dixwest ku JARek bi vê polê re jê re were peyda kirin. Me wiya kir, her tişt xebitî, lê pirsgirêkek nû xuya bû: meriv çawa JAR-ê nûve bike bêyî ku komê bi tevahî rawestîne? Hazelcast di dema nûvekirina nod-bi-node de JAR-ya nû hilnagire. Di vê xalê de me biryar da ku em dikarin bêyî lêgerîna navnîşan bijîn. Beriya her tiştî, heke hûn Hazelcast-ê wekî firotgehek nirxa sereke bikar bînin, wê hingê her tişt dê bixebite? Ne rast. Li vir dîsa tevgera IMap û TransactionalMap cûda ye. Cihê ku IMap eleqedar nake, TransactionalMap xeletiyek derdixe.

IMap. Em 5000 tiştan dinivîsin, dixwînin. Her tişt tê hêvîkirin.

@Test
void get5000() {
    IMap<UUID, Application> map = hazelcastInstance.getMap("application");
    UUID subscriberId = UUID.randomUUID();

    for (int i = 0; i < 5000; i++) {
        UUID id = UUID.randomUUID();
        String title = RandomStringUtils.random(5);
        Application application = new Application(id, title, subscriberId);
        
        map.set(id, application);
        Application retrieved = map.get(id);
        assertEquals(id, retrieved.getId());
    }
}

Lê ew di danûstendinê de naxebite, em ClassNotFoundException digirin:

@Test
void get_transaction() {
    IMap<UUID, Application> map = hazelcastInstance.getMap("application_t");
    UUID subscriberId = UUID.randomUUID();
    UUID id = UUID.randomUUID();

    Application application = new Application(id, "qwer", subscriberId);
    map.set(id, application);
    
    Application retrievedOutside = map.get(id);
    assertEquals(id, retrievedOutside.getId());

    hazelcastInstance.executeTransaction(context -> {
        HazelcastTransactionContextHolder.setContext(context);
        try {
            TransactionalMap<UUID, Application> transactionalMap = context.getMap("application_t");
            Application retrievedInside = transactionalMap.get(id);

            assertEquals(id, retrievedInside.getId());
            return null;
        } finally {
            HazelcastTransactionContextHolder.clearContext();
        }
    });
}

Di 3.8-ê de, mekanîzmaya Dabeşkirina Dersa Bikarhêner xuya bû. Hûn dikarin yek nodek sereke destnîşan bikin û pelê JAR-ê li ser wê nûve bikin.

Naha me nêzîkatiya xwe bi tevahî guhart: em wê bi xwe di JSON de rêzdar dikin û di Hazelcast de hilînin. Hazelcast ne hewce ye ku strukturên dersên me zanibe, û em dikarin bêyî demdirêj nûve bikin. Guhertoya tiştên domainê ji hêla serîlêdanê ve tê kontrol kirin. Guhertoyên cihêreng ên serîlêdanê dikarin di heman demê de werin xebitandin, û rewşek mimkun e dema ku serîlêdana nû tiştên bi qadên nû dinivîse, lê ya kevin hîna van qadan nizane. Û di heman demê de, serîlêdana nû tiştên ku ji hêla serîlêdana kevn ve hatine nivîsandin ku qadên nû nînin dixwîne. Em di hundurê serîlêdanê de rewşên weha birêve dibin, lê ji bo sadebûnê em qadan naguherînin an jêbirin, em tenê bi lê zêdekirina qadên nû çînan berfireh dikin.

Em çawa performansa bilind piştrast dikin

Çar rêwîtiyên Hazelcast - baş, du ji databasê - xirab

Çûyîna kaşê ji bo daneyan her gav ji çûna databasê çêtir e, lê hûn naxwazin tomarên neyên bikar anîn jî hilînin. Em biryara li ser ka çi bihêlin heya qonaxa paşîn a pêşkeftinê dihêlin. Dema ku fonksiyona nû tê kod kirin, em têketina hemî pirsnameyên di PostgreSQL de vedikin (log_min_duration_statement ber 0) û ceribandina barkirinê ji bo 20 hûrdeman dimeşînin. Bi karanîna têketinên berhevkirî, karûbarên wekî pgFouine û pgBadger dikarin raporên analîtîk ava bikin. Di raporan de, em di serî de li pirsên hêdî û pir caran digerin. Ji bo lêpirsînên hêdî, em plansaziyek darvekirinê (EXPLAIN) ava dikin û dinirxînin ka gelo pirsek weha dikare were bilez kirin. Daxwazên pir caran ji bo heman daneya têketinê baş di cache de cih digirin. Em hewl didin ku pirsan "dûr" bihêlin, her pirsê tabloyek.

Operasyona

SV wekî karûbarek serhêl di bihara 2017-an de hate xebitandin, û wekî hilberek cihêreng, SV di Mijdara 2017-an de hate berdan (wê demê di statûya guhertoya beta de).

Di zêdetirî salek xebitandinê de, di xebata karûbarê serhêl a CB de ti pirsgirêkek cidî tune. Em bi riya karûbarê serhêl çavdêrî dikin Zabbix, komkirin û bicîkirin ji Saz.

Dabeşkirina servera SV di forma pakêtên xwemalî de tê peyda kirin: RPM, DEB, MSI. Zêdeyî ji bo Windows-ê em sazkerek yekane di forma yek EXE de peyda dikin ku server, Hazelcast û Elasticsearch li ser yek makîneyê saz dike. Me di destpêkê de vê guhertoya sazkirinê wekî guhertoya "demo" binav kir, lê naha eşkere bû ku ev vebijarka bicîhkirinê ya herî populer e.

Source: www.habr.com

Add a comment