Giunsa ug ngano nga nagsulat kami usa ka taas nga karga nga scalable nga serbisyo alang sa 1C: Enterprise: Java, PostgreSQL, Hazelcast

Niining artikuloha maghisgot kita kon sa unsang paagi ug ngano nga kita naugmad Sistema sa Interaksyon – usa ka mekanismo nga nagbalhin sa impormasyon tali sa mga aplikasyon sa kliyente ug 1C:Enterprise server - gikan sa pagtakda og buluhaton ngadto sa paghunahuna pinaagi sa arkitektura ug mga detalye sa pagpatuman.

Ang Sistema sa Interaksyon (gitawag dinhi nga SV) maoy usa ka apod-apod, fault-tolerant nga sistema sa pagmemensahe nga adunay garantiya nga paghatod. Gidisenyo ang SV isip usa ka serbisyo nga adunay taas nga karga nga adunay taas nga scalability, magamit ingon usa ka serbisyo sa online (gihatag sa 1C) ug ingon usa ka produkto nga gihimo sa kadaghanan nga mahimong i-deploy sa imong kaugalingon nga mga pasilidad sa server.

Gigamit sa SV ang giapod-apod nga pagtipig hazelcast ug search engine Elasticsearch. Maghisgot usab kami bahin sa Java ug kung giunsa namon pag-scale ang PostgreSQL.
Giunsa ug ngano nga nagsulat kami usa ka taas nga karga nga scalable nga serbisyo alang sa 1C: Enterprise: Java, PostgreSQL, Hazelcast

Pagbuot sa problema

Aron maklaro kung nganong gibuhat namo ang Sistema sa Interaksyon, isulti ko kanimo ang gamay kung giunsa ang pagpauswag sa mga aplikasyon sa negosyo sa 1C molihok.

Sa pagsugod, usa ka gamay bahin kanamo para sa mga wala pa nahibal-an kung unsa ang among gibuhat :) Naghimo kami nga plataporma sa teknolohiya sa 1C: Enterprise. Ang plataporma naglakip sa usa ka himan sa pagpalambo sa aplikasyon sa negosyo, ingon man usa ka runtime nga nagtugot sa mga aplikasyon sa negosyo nga modagan sa usa ka palibot nga cross-platform.

Client-server development paradigm

Ang mga aplikasyon sa negosyo nga gihimo sa 1C: Enterprise naglihok sa tulo ka lebel kliyente-server arkitektura "DBMS - server sa aplikasyon - kliyente". Ang code sa aplikasyon gisulat sa gitukod-sa 1C nga pinulongan, mahimong ipatuman sa server sa aplikasyon o sa kliyente. Ang tanan nga pagtrabaho sa mga butang sa aplikasyon (mga direktoryo, mga dokumento, ug uban pa), ingon man ang pagbasa ug pagsulat sa database, gihimo lamang sa server. Ang pag-andar sa mga porma ug command interface gipatuman usab sa server. Gihimo sa kliyente ang pagdawat, pag-abli ug pagpakita sa mga porma, "pagpakigsulti" sa tiggamit (mga pasidaan, mga pangutana ...), gagmay nga mga kalkulasyon sa mga porma nga nanginahanglan dali nga tubag (pananglitan, pagpadaghan sa presyo sa gidaghanon), pagtrabaho sa mga lokal nga file, pagtrabaho uban sa mga ekipo.

Sa code sa aplikasyon, ang mga ulohan sa mga pamaagi ug mga gimbuhaton kinahanglan nga tin-aw nga magpakita kung asa ang code ipatuman - gamit ang &AtClient / &AtServer nga mga direktiba (&AtClient / &AtServer sa English nga bersyon sa pinulongan). Ang mga developer sa 1C karon magtul-id kanako pinaagi sa pag-ingon nga ang mga direktiba sa tinuud labaw pa sa, pero para sa amon indi na ini importante karon.

Mahimo nimong tawagan ang code sa server gikan sa code sa kliyente, apan dili ka makatawag sa code sa kliyente gikan sa code sa server. Kini usa ka sukaranan nga limitasyon nga among gihimo tungod sa daghang mga hinungdan. Sa partikular, tungod kay ang code sa server kinahanglan nga isulat sa paagi nga kini nagpatuman sa samang paagi bisan asa kini gitawag - gikan sa kliyente o gikan sa server. Ug sa kaso sa pagtawag sa server code gikan sa laing server code, walay kliyente nga ingon niana. Ug tungod kay sa panahon sa pagpatuman sa code sa server, ang kliyente nga nagtawag niini mahimong magsira, mogawas sa aplikasyon, ug ang server wala nay bisan kinsa nga tawagan.

Giunsa ug ngano nga nagsulat kami usa ka taas nga karga nga scalable nga serbisyo alang sa 1C: Enterprise: Java, PostgreSQL, Hazelcast
Ang code nga nagdumala sa usa ka pag-klik sa buton: ang pagtawag sa usa ka pamaagi sa server gikan sa kliyente molihok, ang pagtawag sa usa ka pamaagi sa kliyente gikan sa server dili.

Kini nagpasabut nga kung gusto namon magpadala usa ka mensahe gikan sa server ngadto sa aplikasyon sa kliyente, pananglitan, nga ang henerasyon sa usa ka "dugay na" nga taho nahuman na ug ang taho mahimong tan-awon, wala kami ingon nga pamaagi. Kinahanglan nimong gamiton ang mga limbong, pananglitan, matag karon ug unya nga poll ang server gikan sa code sa kliyente. Apan kini nga pamaagi nagkarga sa sistema sa dili kinahanglan nga mga tawag, ug sa kasagaran dili kaayo elegante.

Ug adunay panginahanglan usab, pananglitan, kung moabut ang usa ka tawag sa telepono SIP- sa pagtawag, pahibal-a ang aplikasyon sa kliyente bahin niini aron magamit niini ang numero sa nagtawag aron makit-an kini sa counterparty database ug ipakita ang kasayuran sa tiggamit bahin sa counterparty sa pagtawag. O, pananglitan, kung moabut ang usa ka order sa bodega, ipahibalo ang aplikasyon sa kliyente sa kustomer bahin niini. Sa kinatibuk-an, adunay daghang mga kaso diin ang ingon nga mekanismo mahimong mapuslanon.

Ang produksyon mismo

Paghimo og mekanismo sa pagmemensahe. Paspas, kasaligan, nga adunay garantiya nga paghatud, nga adunay katakus sa dali nga pagpangita sa mga mensahe. Base sa mekanismo, ipatuman ang usa ka messenger (mensahe, video call) nga nagdagan sulod sa 1C nga mga aplikasyon.

Idisenyo ang sistema nga mahimong horizontally scalable. Ang nagkadaghang load kinahanglang matabonan pinaagi sa pagdugang sa gidaghanon sa mga node.

Pagpatuman

Nakahukom kami nga dili i-integrate ang bahin sa server sa SV direkta ngadto sa 1C:Enterprise platform, apan ipatuman kini isip usa ka bulag nga produkto, ang API nga mahimong tawagan gikan sa code sa 1C application solutions. Gihimo kini alang sa daghang mga hinungdan, ang panguna niini mao nga gusto nako nga mahimo’g posible ang pagbinayloay sa mga mensahe tali sa lainlaing mga aplikasyon sa 1C (pananglitan, tali sa Pagdumala sa Trade ug Accounting). Ang lainlaing mga aplikasyon sa 1C mahimong magamit sa lainlaing mga bersyon sa 1C: Platform sa Enterprise, naa sa lainlaing mga server, ug uban pa. Sa ingon nga mga kondisyon, ang pagpatuman sa SV isip usa ka bulag nga produkto nga nahimutang "sa kilid" sa mga instalasyon sa 1C mao ang kamalaumon nga solusyon.

Mao nga, nakahukom kami nga himuon ang SV ingon usa ka lahi nga produkto. Girekomenda namon nga ang gagmay nga mga kompanya mogamit sa CB server nga among gi-install sa among cloud (wss://1cdialog.com) aron malikayan ang mga gasto sa overhead nga adunay kalabotan sa lokal nga pag-install ug pag-configure sa server. Dagko nga mga kliyente mahimo’g makit-an nga maayo nga i-install ang ilang kaugalingon nga CB server sa ilang mga pasilidad. Gigamit namo ang susamang pamaagi sa among cloud SaaS nga produkto 1c Bag-o - kini gihimo isip usa ka mass-produced nga produkto alang sa pag-instalar sa mga site sa mga kliyente, ug gi-deploy usab sa among cloud https://1cfresh.com/.

Paggamit

Sa pag-apod-apod sa load ug fault tolerance, dili usa ka Java nga aplikasyon ang among i-deploy, apan daghan, nga adunay load balancer sa ilang atubangan. Kung kinahanglan nimo nga ibalhin ang usa ka mensahe gikan sa node ngadto sa node, gamita ang pagmantala / pag-subscribe sa Hazelcast.

Ang komunikasyon tali sa kliyente ug sa server pinaagi sa websocket. Maayo kini alang sa mga sistema sa real-time.

Giapod-apod nga cache

Nagpili kami tali sa Redis, Hazelcast ug Ehcache. 2015 na diay. Bag-o lang gipagawas ni Redis ang usa ka bag-ong cluster (bag-o ra kaayo, makahadlok), adunay Sentinel nga adunay daghang mga pagdili. Wala mahibal-an ni Ehcache kung giunsa ang pag-assemble sa usa ka cluster (kini nga function nagpakita sa ulahi). Nakahukom kami nga sulayan kini sa Hazelcast 3.4.
Ang Hazelcast gitigum sa usa ka kumpol gikan sa kahon. Sa single node mode, kini dili kaayo mapuslanon ug mahimo lamang gamiton isip usa ka cache - wala kini mahibal-an kung unsaon pag-dump ang data ngadto sa disk, kung mawala nimo ang bugtong node, mawala nimo ang data. Nag-deploy kami daghang mga Hazelcast, diin among gi-backup ang kritikal nga datos. Dili namo i-back up ang cache - wala namo kini hunahunaa.

Alang kanamo, ang Hazelcast mao ang:

  • Pagtipig sa mga sesyon sa tiggamit. Nagkinahanglan kini og taas nga panahon sa pag-adto sa database alang sa usa ka sesyon matag higayon, mao nga gibutang namo ang tanang mga sesyon sa Hazelcast.
  • Cache. Kung nangita ka usa ka profile sa gumagamit, susiha ang cache. Nagsulat og bag-ong mensahe - ibutang kini sa cache.
  • Mga hilisgutan alang sa komunikasyon tali sa mga higayon sa aplikasyon. Ang node nagmugna og usa ka panghitabo ug gibutang kini sa Hazelcast nga hilisgutan. Ang ubang mga node sa aplikasyon nga naka-subscribe sa kini nga hilisgutan nakadawat ug nagproseso sa kalihokan.
  • Mga kandado sa cluster. Pananglitan, naghimo kami og diskusyon gamit ang usa ka talagsaon nga yawe (usa ka diskusyon sulod sa 1C database):

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

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

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

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

Among gisusi nga walay channel. Among gikuha ang kandado, gisusi kini pag-usab, ug gibuhat kini. Kung dili nimo susihon ang kandado pagkahuman makuha ang kandado, adunay higayon nga ang lain nga hilo nagsusi usab nianang higayuna ug karon mosulay sa paghimo sa parehas nga diskusyon - apan naglungtad na kini. Dili ka maka-lock gamit ang synchronized o regular nga java Lock. Pinaagi sa database - kini hinay, ug kini usa ka kalooy alang sa database; pinaagi sa Hazelcast - mao kana ang imong gikinahanglan.

Pagpili sa usa ka DBMS

Kami adunay halapad ug malampuson nga kasinatian nga nagtrabaho kauban ang PostgreSQL ug nakigtambayayong sa mga nag-develop niini nga DBMS.

Dili kini sayon ​​sa usa ka PostgreSQL cluster - adunay XL, XC, Citus, apan sa kinatibuk-an dili kini mga NoSQL nga wala sa kahon. Wala namo isipa ang NoSQL isip nag-unang tipiganan; igo na nga among gikuha ang Hazelcast, nga wala pa namo magamit kaniadto.

Kung kinahanglan nimo nga sukdon ang usa ka relational database, kana nagpasabut sharding. Sama sa imong nahibal-an, uban sa sharding gibahin namon ang database sa lainlaing mga bahin aron ang matag usa kanila mabutang sa usa ka lahi nga server.

Ang una nga bersyon sa among sharding nag-angkon sa abilidad sa pag-apod-apod sa matag usa sa mga lamesa sa among aplikasyon sa lainlaing mga server sa lainlaing mga proporsyon. Adunay daghang mga mensahe sa server A - palihog, ibalhin nato ang bahin niini nga lamesa ngadto sa server B. Kini nga desisyon nagsinggit lang mahitungod sa ahat nga pag-optimize, mao nga nakahukom kami nga limitahan ang among kaugalingon sa usa ka multi-tenant nga pamaagi.

Mahimo nimong basahon ang bahin sa multi-tenant, pananglitan, sa website Data sa Citus.

Ang SV adunay mga konsepto sa aplikasyon ug subscriber. Ang aplikasyon usa ka piho nga pag-install sa usa ka aplikasyon sa negosyo, sama sa ERP o Accounting, kauban ang mga tiggamit niini ug datos sa negosyo. Ang usa ka subscriber usa ka organisasyon o indibidwal nga alang kang kinsa ang aplikasyon narehistro sa SV server. Ang usa ka subscriber mahimong adunay daghang mga aplikasyon nga narehistro, ug kini nga mga aplikasyon mahimong magbayloay og mga mensahe sa usag usa. Ang subscriber nahimong tenant sa among sistema. Ang mga mensahe gikan sa daghang mga subscriber mahimong mahimutang sa usa ka pisikal nga database; kon atong makita nga ang usa ka subscriber nagsugod sa pagmugna sa usa ka daghan sa trapiko, kita mobalhin niini ngadto sa usa ka bulag nga pisikal nga database (o bisan sa usa ka lain nga database server).

Kami adunay usa ka nag-unang database diin ang usa ka routing table gitipigan nga adunay kasayuran bahin sa lokasyon sa tanan nga mga database sa subscriber.

Giunsa ug ngano nga nagsulat kami usa ka taas nga karga nga scalable nga serbisyo alang sa 1C: Enterprise: Java, PostgreSQL, Hazelcast

Aron mapugngan ang nag-unang database nga mahimong usa ka bottleneck, among gitipigan ang routing table (ug uban pang gikinahanglan nga data) sa usa ka cache.

Kung ang database sa subscriber magsugod sa paghinay, among putlon kini sa mga partisyon sa sulod. Sa ubang mga proyekto nga among gigamit pg_pathman.

Tungod kay ang pagkawala sa mga mensahe sa tiggamit dili maayo, among gipadayon ang among mga database nga adunay mga replika. Ang kombinasyon sa mga synchronous ug asynchronous nga mga replika nagtugot kanimo nga masiguro ang imong kaugalingon kung mawala ang panguna nga database. Ang pagkawala sa mensahe mahitabo lamang kung ang nag-unang database ug ang dungan nga replika niini mapakyas sa dungan.

Kung nawala ang usa ka dungan nga replika, ang asynchronous nga replika mahimong dungan.
Kung nawala ang panguna nga database, ang dungan nga replika mahimong panguna nga database, ug ang asynchronous nga replika mahimong usa ka dungan nga replika.

Elasticsearch alang sa pagpangita

Tungod kay, taliwala sa ubang mga butang, ang SV usa usab ka mensahero, nanginahanglan kini usa ka paspas, kombenyente ug flexible nga pagpangita, nga gikonsiderar ang morpolohiya, gamit ang dili tukma nga mga posporo. Nakahukom kami nga dili na usbon ang ligid ug gamiton ang libre nga search engine nga Elasticsearch, nga gihimo base sa librarya Lucene. Gi-deploy usab namo ang Elasticsearch sa usa ka cluster (master - data - data) aron mawagtang ang mga problema kung mapakyas ang mga node sa aplikasyon.

Sa github among nakit-an Russian nga morphology plugin para sa Elasticsearch ug gamita kini. Sa index sa Elasticsearch gitipigan namon ang mga ugat sa pulong (nga gitino sa plugin) ug N-grams. Samtang ang tiggamit mosulod sa teksto aron pangitaon, among gipangita ang gi-type nga teksto taliwala sa mga N-grams. Kung gitipigan sa indeks, ang pulong nga "mga teksto" mabahin sa mosunod nga N-grams:

[kadtong, tek, tex, text, text, ek, ex, ext, texts, ks, kst, ksty, st, sty, ikaw],

Ug ang lintunganay sa pulong nga "teksto" mapreserbar usab. Kini nga pamaagi nagtugot kanimo sa pagpangita sa sinugdanan, sa tunga-tunga, ug sa katapusan sa pulong.

Ang dako nga litrato

Giunsa ug ngano nga nagsulat kami usa ka taas nga karga nga scalable nga serbisyo alang sa 1C: Enterprise: Java, PostgreSQL, Hazelcast
Balika ang hulagway gikan sa sinugdanan sa artikulo, apan uban sa mga pagpasabut:

  • Balancer nga gibutyag sa Internet; kita adunay nginx, kini mahimo nga bisan unsa.
  • Ang mga higayon sa aplikasyon sa Java nakigsulti sa usag usa pinaagi sa Hazelcast.
  • Aron magtrabaho sa usa ka web socket nga among gigamit Netty.
  • Ang aplikasyon sa Java gisulat sa Java 8 ug naglangkob sa mga bundle OSGi. Ang mga plano naglakip sa paglalin sa Java 10 ug pagbalhin sa mga module.

Pag-uswag ug pagsulay

Sa proseso sa pagpauswag ug pagsulay sa SV, nakit-an namon ang daghang makapaikag nga mga bahin sa mga produkto nga among gigamit.

Load testing ug memory leaks

Ang pagpagawas sa matag pagpagawas sa SV naglakip sa pagsulay sa pagkarga. Kini malampuson kung:

  • Ang pagsulay nagtrabaho sa daghang mga adlaw ug wala’y mga kapakyasan sa serbisyo
  • Ang oras sa pagtubag alang sa hinungdanon nga mga operasyon wala molapas sa komportable nga sukaranan
  • Ang pagkadaot sa performance kumpara sa miaging bersyon dili molapas sa 10%

Gipuno namon ang database sa pagsulay sa datos - aron mahimo kini, nakadawat kami kasayuran bahin sa labing aktibo nga suskritor gikan sa server sa produksiyon, gipadaghan ang mga numero niini sa 5 (ang gidaghanon sa mga mensahe, mga diskusyon, mga tiggamit) ug gisulayan kini nga paagi.

Naghimo kami og pagsulay sa pagkarga sa sistema sa interaksiyon sa tulo ka mga pag-configure:

  1. pagsulay sa stress
  2. Mga koneksyon lamang
  3. Pagparehistro sa subscriber

Atol sa stress test, naglunsad kami og pipila ka gatos nga mga hilo, ug ilang gikarga ang sistema nga walay paghunong: pagsulat og mga mensahe, paghimo og mga panaghisgot, pagdawat og listahan sa mga mensahe. Gisundog namo ang mga aksyon sa mga ordinaryong tiggamit (pagkuha og lista sa akong wala pa mabasa nga mga mensahe, pagsulat sa usa ka tawo) ug mga solusyon sa software (pagpadala og usa ka pakete sa lain nga configuration, pagproseso og alerto).

Pananglitan, kini ang hitsura sa bahin sa pagsulay sa stress:

  • User log in
    • Nangayo sa imong wala pa mabasa nga mga diskusyon
    • 50% lagmit nga mobasa sa mga mensahe
    • 50% ang posibilidad nga mag-text
    • Sunod nga tiggamit:
      • Adunay 20% nga kahigayonan sa paghimo og bag-ong diskusyon
      • Random nga gipili ang bisan unsang mga diskusyon niini
      • Misulod sa sulod
      • Nangayo og mga mensahe, mga profile sa user
      • Naghimo og lima ka mga mensahe nga gitumong ngadto sa mga random nga tiggamit gikan niini nga diskusyon
      • Mga dahon sa diskusyon
      • Gisubli 20 ka beses
      • Pag-log out, balik sa sinugdanan sa script

    • Ang usa ka chatbot mosulod sa sistema (nag-emulate sa pagmemensahe gikan sa code sa aplikasyon)
      • Adunay 50% nga kahigayonan sa paghimo og bag-ong channel alang sa pagbayloay sa datos (espesyal nga diskusyon)
      • Ang 50% lagmit nga magsulat usa ka mensahe sa bisan unsang naa na nga mga channel

Ang senaryo nga "Mga Koneksyon Lamang" nagpakita sa usa ka rason. Adunay usa ka sitwasyon: ang mga tiggamit nagkonektar sa sistema, apan wala pa maapil. Ang matag user mo-on sa computer sa 09:00 sa buntag, magtukod og koneksyon sa server ug magpabilin nga hilom. Kini nga mga lalaki delikado, adunay daghan kanila - ang mga pakete lamang nga anaa kanila mao ang PING/PONG, apan ilang gipadayon ang koneksyon sa server (dili nila kini mapadayon - unsa man kung adunay bag-ong mensahe). Ang pagsulay nagpatunghag usa ka sitwasyon diin ang usa ka dako nga gidaghanon sa maong mga tiggamit misulay sa pag-log in sa sistema sa tunga sa oras. Kini susama sa usa ka stress test, apan ang focus niini mao ang tukma sa niini nga unang input - aron nga walay mga kapakyasan (usa ka tawo dili sa paggamit sa sistema, ug kini nahulog na - kini mao ang lisud nga sa paghunahuna sa usa ka butang nga mas grabe).

Ang script sa pagparehistro sa subscriber magsugod gikan sa unang paglansad. Naghimo kami og usa ka stress test ug nakasiguro nga ang sistema dili mohinay panahon sa mga sulat. Apan ang mga tiggamit miabut ug ang pagrehistro nagsugod sa pagkapakyas tungod sa usa ka timeout. Sa pagparehistro among gigamit / dev / sulagma, nga may kalabutan sa entropy sa sistema. Ang server walay panahon sa pagtigom og igong entropy ug sa dihang gihangyo ang bag-ong SecureRandom, kini nagyelo sulod sa napulo ka segundos. Adunay daghang mga paagi gikan niini nga sitwasyon, pananglitan: pagbalhin ngadto sa dili kaayo luwas nga /dev/urandom, pag-instalar og espesyal nga board nga makamugna og entropy, pagmugna og mga random nga numero sa daan ug ibutang kini sa usa ka pool. Temporaryo nga gisirado namo ang problema sa pool, apan sukad niadto nagpadagan kami og bulag nga pagsulay alang sa pagparehistro sa bag-ong mga subscriber.

Gigamit namon ingon usa ka generator sa pagkarga JMeter. Wala kini mahibal-an kung unsaon pagtrabaho sa websocket; kinahanglan kini usa ka plugin. Ang una sa mga resulta sa pagpangita alang sa pangutana nga "jmeter websocket" mao ang: mga artikulo gikan sa BlazeMeter, nga nagrekomendar plugin ni Maciej Zaleski.

Didto mi nag decide nga mag sugod.

Hapit diha-diha dayon human sa pagsugod sa seryoso nga pagsulay, among nadiskobrehan nga ang JMeter nagsugod sa pagtulo sa panumduman.

Ang plugin usa ka bulag nga dako nga istorya; nga adunay 176 ka bituon, kini adunay 132 ka tinidor sa github. Ang tagsulat mismo wala mopasalig niini sukad sa 2015 (gikuha namon kini kaniadtong 2015, unya wala kini nagpataas sa mga pagduda), daghang mga isyu sa github bahin sa mga pagtulo sa memorya, 7 nga wala gisirado nga mga hangyo sa pagbitad.
Kung magdesisyon ka nga maghimo pagsulay sa pagkarga gamit kini nga plugin, palihug hatagi'g pagtagad ang mosunod nga mga diskusyon:

  1. Sa usa ka multi-threaded nga palibot, usa ka regular nga LinkList ang gigamit, ug ang resulta mao NPE sa runtime. Mahimo kini nga masulbad pinaagi sa pagbalhin sa ConcurrentLinkedDeque o pinaagi sa mga gi-synchronize nga mga bloke. Gipili namo ang unang kapilian para sa among kaugalingon (https://github.com/maciejzaleski/JMeter-WebSocketSampler/issues/43).
  2. Memory leak; sa dihang nagdiskonekta, ang impormasyon sa koneksyon dili matangtang (https://github.com/maciejzaleski/JMeter-WebSocketSampler/issues/44).
  3. Sa streaming mode (kung ang websocket dili sirado sa katapusan sa sample, apan gigamit sa ulahi sa plano), Ang mga pattern sa pagtubag dili molihok (https://github.com/maciejzaleski/JMeter-WebSocketSampler/issues/19).

Usa kini sa naa sa github. Ang among gibuhat:

  1. Gikuha tinidor Elyran Kogan (@elyrank) - giayo niini ang mga problema 1 ug 3
  2. Nasulbad ang problema 2
  3. Gi-update nga jetty gikan sa 9.2.14 hangtod 9.3.12
  4. Giputos nga SimpleDateFormat sa ThreadLocal; Ang SimpleDateFormat dili luwas sa thread, nga misangpot sa NPE sa runtime
  5. Giayo ang lain nga pagtulo sa memorya (ang koneksyon nasira nga dili husto kung gidiskonekta)

Ug bisan pa kini nagdagayday!

Ang memorya nagsugod sa pagkahurot dili sa usa ka adlaw, apan sa duha. Wala nay panahon nga nahabilin, mao nga nakahukom kami nga maglunsad og mas diyutay nga mga hilo, apan sa upat ka mga ahente. Kini igo na unta sulod sa labing menos usa ka semana.

Duha ka adlaw ang milabay...

Karon ang Hazelcast nahutdan na sa memorya. Gipakita sa mga troso nga pagkahuman sa pila ka adlaw nga pagsulay, si Hazelcast nagsugod sa pagreklamo bahin sa kakulang sa panumduman, ug pagkahuman sa pila ka oras ang cluster nahulog, ug ang mga node nagpadayon sa pagkamatay sa usag usa. Among gikonektar ang JVisualVM sa hazelcast ug nakakita og "rising saw" - kini kanunay nga gitawag nga GC, apan dili malimpyohan ang memorya.

Giunsa ug ngano nga nagsulat kami usa ka taas nga karga nga scalable nga serbisyo alang sa 1C: Enterprise: Java, PostgreSQL, Hazelcast

Nahibal-an nga sa hazelcast 3.4, kung gitangtang ang usa ka mapa / multiMap (map.destroy()), ang memorya dili hingpit nga gipagawas:

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

Ang bug naayo na karon sa 3.5, apan kini usa ka problema kaniadto. Naghimo kami og bag-ong multiMaps nga adunay dinamikong mga ngalan ug gitangtang kini sumala sa among lohika. Ang code ingon niini:

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();
    }
}

Tawag:

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

Ang multiMap gihimo alang sa matag suskrisyon ug gitangtang kung wala kini kinahanglana. Nakahukom mi nga sugdan namo ang Map , ang yawe mao ang ngalan sa suskrisyon, ug ang mga kantidad mao ang mga identifier sa sesyon (diin mahimo nimong makuha ang mga identifier sa gumagamit, kung kinahanglan).

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

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

Ang mga tsart miuswag.

Giunsa ug ngano nga nagsulat kami usa ka taas nga karga nga scalable nga serbisyo alang sa 1C: Enterprise: Java, PostgreSQL, Hazelcast

Unsa pa ang atong nahibal-an bahin sa pagsulay sa pagkarga?

  1. Ang JSR223 kinahanglang isulat sa groovy ug ilakip ang compilation cache - mas paspas kini. link.
  2. Ang mga graph sa Jmeter-Plugins mas sayon ​​sabton kay sa mga standard. link.

Mahitungod sa among kasinatian sa Hazelcast

Ang Hazelcast usa ka bag-ong produkto alang kanamo, nagsugod kami sa pagtrabaho uban niini gikan sa bersyon 3.4.1, karon ang among production server nagpadagan sa bersyon 3.9.2 (sa panahon sa pagsulat, ang pinakabag-o nga bersyon sa Hazelcast mao ang 3.10).

Pagmugna sa ID

Nagsugod kami sa mga integer identifier. Atong hunahunaon nga nagkinahanglan kita og laing Long para sa bag-ong entidad. Ang pagkasunod-sunod sa database dili angay, ang mga lamesa nalangkit sa sharding - kini nahimo nga adunay mensahe ID = 1 sa DB1 ug usa ka mensahe ID = 1 sa DB2, dili nimo ibutang kini nga ID sa Elasticsearch, ni sa Hazelcast , apan ang pinakagrabe nga butang mao kung gusto nimo nga i-combine ang data gikan sa duha ka database ngadto sa usa (pananglitan, ang pagdesisyon nga ang usa ka database igo na alang niini nga mga subscriber). Mahimo nimong idugang ang daghang mga AtomicLongs sa Hazelcast ug itago ang counter didto, unya ang pasundayag sa pagkuha usa ka bag-ong ID mao ang pagdugangAndGet ug ang oras alang sa usa ka hangyo sa Hazelcast. Apan ang Hazelcast adunay mas maayo nga butang - FlakeIdGenerator. Kung nakigkontak sa matag kliyente, gihatagan sila usa ka hanay sa ID, pananglitan, ang una - gikan sa 1 hangtod 10, ang ikaduha - gikan sa 000 hangtod 10, ug uban pa. Karon ang kliyente mahimo nang mag-isyu og bag-ong mga identifier sa iyang kaugalingon hangtod matapos ang range nga gihatag niini. Kini dali nga molihok, apan kung imong gi-restart ang aplikasyon (ug ang kliyente sa Hazelcast), usa ka bag-ong pagkasunod-sunod nagsugod - busa ang mga paglaktaw, ug uban pa. Dugang pa, ang mga nag-develop wala gyud makasabut kung ngano nga ang mga ID integer, apan dili managsama. Among gitimbang ang tanan ug gibalhin sa UUID.

Pinaagi sa dalan, alang niadtong gusto nga mahisama sa Twitter, adunay ingon nga Snowcast library - kini usa ka pagpatuman sa Snowflake sa ibabaw sa Hazelcast. Mahimo nimo kini tan-awon dinhi:

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

Apan wala na mi makaabot niini.

TransactionalMap.ilisan

Laing surpresa: Ang TransactionalMap.replace dili mogana. Ania ang usa ka pagsulay:

@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

Kinahanglan kong isulat ang akong kaugalingon nga puli gamit ang getForUpdate:

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);
}

Sulayi dili lamang ang mga regular nga istruktura sa datos, apan usab ang ilang mga bersyon sa transaksyon. Nahitabo nga ang IMap nagtrabaho, apan ang TransactionalMap wala na.

Pagsulod ug bag-ong JAR nga walay downtime

Una, nakahukom kami nga irekord ang mga butang sa among mga klase sa Hazelcast. Pananglitan, kami adunay klase sa Application, gusto namon nga i-save ug basahon kini. Tipigi:

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

ngalan:

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

Ang tanan nagtrabaho. Dayon nakahukom kami nga maghimo ug indeks sa Hazelcast aron pangitaon pinaagi sa:

map.addIndex("subscriberId", false);

Ug sa pagsulat sa usa ka bag-ong entidad, nagsugod sila sa pagdawat sa ClassNotFoundException. Si Hazelcast misulay sa pagdugang sa index, apan wala mahibalo sa bisan unsa mahitungod sa among klase ug gusto nga usa ka JAR uban niini nga klase ang ihatag niini. Gibuhat ra namon kana, ang tanan nagtrabaho, apan usa ka bag-ong problema ang nagpakita: kung giunsa ang pag-update sa JAR nga wala’y hingpit nga paghunong sa cluster? Ang Hazelcast wala magkuha sa bag-ong JAR atol sa usa ka node-by-node update. Niini nga punto nakahukom kami nga mabuhi kami nga wala’y pagpangita sa indeks. Pagkahuman, kung gigamit nimo ang Hazelcast ingon usa ka tindahan nga hinungdanon nga kantidad, nan ang tanan molihok? Dili gyud. Dinhi usab lahi ang pamatasan sa IMap ug TransactionalMap. Diin ang IMap wala magtagad, ang TransactionalMap naglabay sa usa ka sayup.

IMap. Nagsulat kami ug 5000 ka butang, basaha kini. Gidahom ang tanan.

@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());
    }
}

Apan dili kini molihok sa usa ka transaksyon, nakakuha kami usa ka ClassNotFoundException:

@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();
        }
    });
}

Sa 3.8, nagpakita ang mekanismo sa User Class Deployment. Mahimo nimong itudlo ang usa ka master node ug i-update ang JAR file niini.

Karon hingpit namong gibag-o ang among pamaagi: among gi-serialize kini sa among kaugalingon sa JSON ug gitipigan kini sa Hazelcast. Dili kinahanglan nga mahibal-an ni Hazelcast ang istruktura sa among mga klase, ug mahimo kaming mag-update nga wala’y downtime. Ang pag-bersyon sa mga butang sa domain kontrolado sa aplikasyon. Ang lainlaing mga bersyon sa aplikasyon mahimong magdagan sa parehas nga oras, ug posible ang usa ka sitwasyon kung ang bag-ong aplikasyon nagsulat sa mga butang nga adunay bag-ong mga natad, apan ang daan wala pa nahibal-an bahin sa kini nga mga natad. Ug sa samang higayon, ang bag-ong aplikasyon nagbasa sa mga butang nga gisulat sa daan nga aplikasyon nga walay bag-ong mga natad. Gidumala namo ang ingon nga mga sitwasyon sulod sa aplikasyon, apan alang sa kayano dili namo usbon o tangtangon ang mga field, gipalapdan lang namo ang mga klase pinaagi sa pagdugang og bag-ong mga field.

Giunsa nato pagsiguro ang taas nga performance

Upat ka mga biyahe sa Hazelcast - maayo, duha sa database - dili maayo

Ang pag-adto sa cache alang sa datos kanunay nga mas maayo kaysa pag-adto sa database, apan dili nimo gusto nga magtipig sa wala magamit nga mga rekord usab. Gibiyaan namon ang desisyon kung unsa ang i-cache hangtod sa katapusan nga yugto sa pag-uswag. Kung ang bag-ong gamit gi-code, among gi-on ang pag-log sa tanan nga mga pangutana sa PostgreSQL (log_min_duration_statement to 0) ug gipadagan ang pagsulay sa pagkarga sa mga minuto nga 20. Gamit ang mga nakolekta nga mga troso, ang mga utilities sama sa pgFouine ug pgBadger makahimo og analytical nga mga taho. Sa mga taho, pangitaon namon ang hinay ug kanunay nga mga pangutana. Alang sa hinay nga mga pangutana, nagtukod kami usa ka plano sa pagpatuman (PASASABOT) ug pagtimbang-timbang kung ang ingon nga pangutana mahimo nga mapadali. Ang kanunay nga mga hangyo alang sa parehas nga data sa pag-input mohaum sa cache. Gisulayan namon nga ipadayon ang mga pangutana nga "flat", usa ka lamesa matag pangutana.

Operasyon

Ang SV isip usa ka online nga serbisyo gibutang sa operasyon sa tingpamulak sa 2017, ug isip usa ka bulag nga produkto, ang SV gibuhian sa Nobyembre 2017 (niadtong panahona sa beta version status).

Sa sobra sa usa ka tuig nga operasyon, wala’y seryoso nga mga problema sa operasyon sa CB online nga serbisyo. Among gimonitor ang online nga serbisyo pinaagi sa Zabbix, pagkolekta ug pag-deploy gikan sa Bamboo.

Ang pag-apod-apod sa SV server gihatag sa porma sa lumad nga mga pakete: RPM, DEB, MSI. Dugang pa alang sa Windows naghatag kami usa ka installer sa porma sa usa ka EXE nga nag-install sa server, Hazelcast ug Elasticsearch sa usa ka makina. Gitawag namo kini nga bersyon sa pag-instalar isip "demo" nga bersyon, apan karon nahimong tin-aw nga kini ang labing popular nga kapilian sa pag-deploy.

Source: www.habr.com

Idugang sa usa ka comment