Чӣ гуна ва чаро мо як хидмати миқёспазири сарбории баландро барои 1C навиштем: Enterprise: Java, PostgreSQL, Hazelcast

Дар ин мақола мо дар бораи чӣ гуна ва чаро мо таҳия кардаем Системаи мутақобила – механизме, ки маълумотро байни замимаҳои муштарӣ ва серверҳои 1C: Enterprise интиқол медиҳад - аз гузоштани вазифа то тафаккур тавассути меъморӣ ва тафсилоти татбиқ.

Системаи Муошират (минбаъд SV номида мешавад) системаи паёмнависии тақсимшуда ва ба хатоҳо таҳаммулпазир бо интиқоли кафолатнок мебошад. SV ҳамчун як хидмати сарбории баланд бо миқёспазирии баланд тарҳрезӣ шудааст, ки ҳам ҳамчун хидмати онлайн (аз ҷониби 1C пешниҳод шудааст) ва ҳам ҳамчун як маҳсулоти оммавӣ, ки метавонад дар иншооти сервери худ ҷойгир карда шавад.

SV нигаҳдории тақсимшударо истифода мебарад фундук ва муҳаррики ҷустуҷӯ Ҷустуҷӯи Elastics. Мо инчунин дар бораи Java сӯҳбат хоҳем кард ва чӣ гуна мо PostgreSQL-ро ба таври уфуқӣ миқёс мекунем.
Чӣ гуна ва чаро мо як хидмати миқёспазири сарбории баландро барои 1C навиштем: Enterprise: Java, PostgreSQL, Hazelcast

Тартиб додани масъала

Барои равшан кардани он ки чаро мо системаи муштаракро офаридаем, ман ба шумо каме дар бораи чӣ гуна кор кардани таҳияи замимаҳои тиҷоратӣ дар 1С нақл мекунам.

Барои оғоз, каме дар бораи мо барои онҳое, ки ҳанӯз намедонанд, ки мо чӣ кор мекунем :) Мо платформаи технологии 1C: Enterprise-ро месозем. Платформа як асбоби таҳияи барномаҳои тиҷоратӣ ва инчунин вақти корро дар бар мегирад, ки имкон медиҳад барномаҳои тиҷоратӣ дар муҳити кросс-платформа кор кунанд.

Парадигмаи рушди мизоҷ-сервер

Барномаҳои тиҷорӣ, ки дар 1С: Enterprise сохта шудаанд, дар се сатҳ амал мекунанд муштарӣ-сервер меъмории «DBMS – сервери барнома – муштарӣ». Рамзи барнома навишта шудааст забони дарунсохташудаи 1C, метавонад дар сервери барнома ё дар муштарӣ иҷро карда шавад. Ҳама корҳо бо объектҳои барномавӣ (директорҳо, ҳуҷҷатҳо ва ғ.), инчунин хондан ва навиштани базаи маълумотҳо танҳо дар сервер иҷро карда мешаванд. Функсияи формаҳо ва интерфейси фармонҳо инчунин дар сервер амалӣ карда мешавад. Мизоҷ қабул, кушодан ва намоиш додани шаклҳо, "муошират" бо корбар (огоҳӣ, саволҳо ...), ҳисобҳои хурдро дар шаклҳое, ки посухи зудро талаб мекунанд (масалан, зарб кардани нарх аз рӯи миқдор), кор бо файлҳои маҳаллӣ, кор бо тачхизот.

Дар коди барнома, сарлавҳаҳои тартиб ва функсияҳо бояд ба таври возеҳ нишон диҳанд, ки код дар куҷо иҷро карда мешавад - бо истифода аз дастурҳои &AtClient / &AtServer (&AtClient / &AtServer дар версияи англисии забон). Таҳиягарони 1C ҳоло маро ислоҳ хоҳанд кард ва мегӯянд, ки дастурҳо воқеан ҳастанд бештар аз, аммо барои мо ин ҳоло муҳим нест.

Шумо метавонед рамзи серверро аз коди муштарӣ занг занед, аммо шумо наметавонед ба коди муштарӣ аз коди сервер занг занед. Ин як маҳдудияти асосӣест, ки мо бо якчанд сабабҳо кардаем. Аз ҷумла, азбаски коди сервер бояд тавре навишта шавад, ки он новобаста аз он ки дар куҷо даъват карда мешавад, ҳамон тавр иҷро шавад - аз муштарӣ ё аз сервер. Ва дар сурати занг задани коди сервер аз дигар коди сервер, чунин муштарӣ вуҷуд надорад. Ва азбаски ҳангоми иҷрои рамзи сервер муштарӣ, ки онро даъват кардааст, метавонад баста шавад, аз барнома хориҷ шавад ва сервер дигар касе барои занг задан надорад.

Чӣ гуна ва чаро мо як хидмати миқёспазири сарбории баландро барои 1C навиштем: Enterprise: Java, PostgreSQL, Hazelcast
Рамзе, ки пахши тугмаро идора мекунад: даъват кардани процедураи сервер аз муштарӣ кор хоҳад кард, даъват кардани процедураи муштарӣ аз сервер кор намекунад

Ин маънои онро дорад, ки агар мо мехоҳем, ки аз сервер ба замимаи муштарӣ ягон паём фиристем, масалан, тавлиди гузориши "дарозмуддат" ба анҷом расид ва гузоришро дидан мумкин аст, мо чунин усул надорем. Шумо бояд ҳилаҳоро истифода баред, масалан, давра ба давра серверро аз рамзи муштарӣ пурсед. Аммо ин равиш системаро бо зангҳои нолозим бор мекунад ва умуман он қадар шево ба назар намерасад.

Ва инчунин зарурат, масалан, вақте ки занги телефон меояд БИД- ҳангоми занг задан, ба барномаи муштарӣ дар ин бора хабар диҳед, то он рақами зангзанандаро барои дарёфти он дар пойгоҳи додаи контрагент истифода барад ва ба корбар маълумотро дар бораи контрагенти зангзананда нишон диҳад. Ё, масалан, вақте ки фармоиш ба анбор ворид мешавад, аризаи муштарии муштариро дар ин бора огоҳ кунед. Умуман, бисьёр ходисахое хастанд, ки чунин механизм фоиданок мебуд.

Худи истехсолот

Механизми паёмнависиро эҷод кунед. Тез, боэътимод, бо интиқоли кафолатнок, бо қобилияти ҷустуҷӯи чандир паёмҳо. Дар асоси механизм, мессенҷер (паёмҳо, зангҳои видеоӣ), ки дар дохили замимаҳои 1С кор мекунад, татбиқ кунед.

Системаро тарҳрезӣ кунед, ки ба таври уфуқӣ миқёспазир бошад. Сарбории афзоянда бояд бо зиёд кардани шумораи гиреҳҳо пӯшонида шавад.

Реализация

Мо тасмим гирифтем, ки қисми серверии SV-ро мустақиман ба платформаи 1C:Enterprise ворид накунем, балки онро ҳамчун маҳсулоти алоҳида, ки API-и онро метавон аз коди ҳалли барномаҳои 1С номид, татбиқ кунем. Ин бо як қатор сабабҳо анҷом дода шуд, ки яке аз онҳо дар он буд, ки ман мехостам мубодилаи паёмҳоро байни замимаҳои гуногуни 1C имконпазир созам (масалан, байни идоракунии савдо ва ҳисобдорӣ). Барномаҳои гуногуни 1С метавонанд дар версияҳои гуногуни платформаи 1C: Enterprise кор кунанд, дар серверҳои гуногун ҷойгир шаванд ва ғайра. Дар чунин шароит татбиқи SV ҳамчун маҳсулоти алоҳидаи "дар паҳлӯи" дастгоҳҳои 1C ҷойгиршуда ҳалли беҳтарин аст.

Ҳамин тавр, мо тасмим гирифтем, ки SV-ро ҳамчун маҳсулоти алоҳида созем. Мо тавсия медиҳем, ки ширкатҳои хурд сервери CB-ро, ки мо дар абри худ насб кардем (wss://1cdialog.com) истифода баранд, то хароҷоти изофии марбут ба насб ва конфигуратсияи серверро пешгирӣ кунанд. Мизоҷони калон метавонанд тавсия дода шаванд, ки сервери CB-и худро дар иншооти худ насб кунанд. Мо як равиши шабеҳро дар маҳсулоти абрии SaaS истифода кардем 1cTresh - он ҳамчун маҳсулоти оммавӣ барои насб дар сайтҳои муштариён истеҳсол карда мешавад ва инчунин дар абри мо ҷойгир карда мешавад https://1cfresh.com/.

Ариза

Барои тақсим кардани сарборӣ ва таҳаммулпазирии хатогиҳо, мо на як замимаи Java, балки якчанд барномаи мувозинати сарборро дар назди онҳо ҷойгир мекунем. Агар ба шумо лозим ояд, ки паёмро аз гиреҳ ба гиреҳ интиқол диҳед, интишор/обунаро дар Hazelcast истифода баред.

Алоқа байни муштарӣ ва сервер тавассути websocket сурат мегирад. Он барои системаҳои вақти воқеӣ хеле мувофиқ аст.

Кэши тақсимшуда

Мо байни Redis, Hazelcast ва Ehcache интихоб кардем. Соли 2015 аст. Redis танҳо як кластери навро баровард (хеле нав, даҳшатнок), Sentinel дорои маҳдудиятҳои зиёд аст. Ehcache намедонад, ки чӣ тавр ба кластер ҷамъ карда шавад (ин функсия баъдтар пайдо шуд). Мо тасмим гирифтем, ки онро бо Hazelcast 3.4 санҷем.
Hazelcast дар як кластер аз қуттӣ ҷамъ карда мешавад. Дар реҷаи як гиреҳ он чандон муфид нест ва онро танҳо ҳамчун кэш истифода бурдан мумкин аст - он намедонад, ки чӣ гуна маълумотро ба диск партофтан мумкин аст, агар шумо гиреҳи ягонаро гум кунед, маълумотро гум мекунед. Мо якчанд Hazelcast-ро ҷойгир мекунем, ки дар байни онҳо маълумоти муҳимро захира мекунем. Мо кэшро нусхабардорӣ намекунем - мо аз он зид нестем.

Барои мо, Hazelcast ин аст:

  • Нигоҳдории сессияҳои корбар. Ҳар дафъа ба пойгоҳи додаҳо барои сессия рафтан вақти зиёдро мегирад, аз ин рӯ мо ҳама сессияҳоро дар Hazelcast мегузорем.
  • Кэш. Агар шумо профили корбарро ҷустуҷӯ кунед, кэшро тафтиш кунед. Паёми нав навишт - онро дар кэш ҷойгир кунед.
  • Мавзӯъҳо барои иртибот байни мисолҳои барнома. Гиреҳ ҳодиса тавлид мекунад ва онро дар мавзӯи Hazelcast ҷойгир мекунад. Гиреҳҳои дигари барнома, ки ба ин мавзӯъ обуна шудаанд, ҳодисаро қабул ва коркард мекунанд.
  • Қулфҳои кластерӣ. Масалан, мо мубоҳисаро бо истифода аз калиди нодир (мубоҳисаи ягона дар дохили базаи 1С) эҷод мекунем:

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

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

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

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

Мо тафтиш кардем, ки ягон канал нест. Мо қуфлро гирифта, бори дигар тафтиш кардем ва онро офаридем. Агар шумо пас аз гирифтани қулф қулфро тафтиш накунед, пас имкони он вуҷуд дорад, ки риштаи дигар низ дар он лаҳза тафтиш карда шуд ва ҳоло кӯшиш мекунад, ки ҳамон муҳокимаро эҷод кунад - аммо он аллакай вуҷуд дорад. Шумо наметавонед бо истифода аз қуфлҳои ҳамоҳангшуда ё муқаррарии java қулф кунед. Тавассути пойгоҳи додаҳо - он суст аст ва барои пойгоҳи додаҳо афсӯс аст; тавассути Hazelcast - ин ба шумо лозим аст.

Интихоби DBMS

Мо таҷрибаи васеъ ва муваффақ дар кор бо PostgreSQL ва ҳамкорӣ бо таҳиягарони ин DBMS дорем.

Бо кластери PostgreSQL осон нест - вуҷуд дорад XL, XC, Ситус, аммо дар маҷмӯъ инҳо NoSQL нестанд, ки аз қуттӣ васеъ карда мешаванд. Мо NoSQL-ро ҳамчун анбори асосӣ ҳисоб намекардем; кофӣ буд, ки мо Hazelcast-ро гирифтем, ки қаблан бо он кор намекардем.

Агар ба шумо миқёси пойгоҳи додаҳои релятсионӣ лозим бошад, ин маънои онро дорад шикастан. Тавре ки шумо медонед, бо sharding мо пойгоҳи додаҳоро ба қисмҳои алоҳида тақсим мекунем, то ҳар яки онҳо дар сервери алоҳида ҷойгир карда шаванд.

Варианти якуми sharding мо қобилияти паҳн кардани ҳар як ҷадвали замимаи моро дар серверҳои гуногун бо таносуби гуногун дар назар дошт. Дар сервери А паёмҳои зиёд мавҷуданд - лутфан, биёед як қисми ин ҷадвалро ба сервери B интиқол диҳем. Ин қарор танҳо дар бораи оптимизатсияи бармаҳал дод зад, аз ин рӯ мо тасмим гирифтем, ки худро бо равиши бисёр иҷорагир маҳдуд кунем.

Шумо метавонед дар бораи иҷорагир бисёрсоҳавӣ хонед, масалан, дар вебсайт Маълумоти Citus.

SV дорои мафҳумҳои барнома ва муштарӣ мебошад. Ариза як насби мушаххаси замимаи тиҷоратӣ, ба монанди ERP ё ҳисобдорӣ бо корбарон ва маълумоти тиҷоратӣ мебошад. Муштарӣ ташкилот ё шахсе мебошад, ки аз номи онҳо барнома дар сервери SV ба қайд гирифта шудааст. Муштарӣ метавонад якчанд замимаро ба қайд гирифта бошад ва ин барномаҳо метавонанд бо ҳамдигар паём мубодила кунанд. Дар системаи мо абонент ичоракор шуд. Паёмҳои якчанд муштарӣ метавонанд дар як базаи физикӣ ҷойгир шаванд; агар мо бинем, ки муштарӣ ба тавлиди трафики зиёд шурӯъ кардааст, мо онро ба пойгоҳи додаҳои физикии алоҳида (ё ҳатто сервери алоҳидаи пойгоҳи додаҳо) интиқол медиҳем.

Мо базаи асосие дорем, ки дар он ҷадвали масир бо маълумот дар бораи ҷойгиршавии ҳамаи базаҳои муштарӣ нигоҳ дошта мешавад.

Чӣ гуна ва чаро мо як хидмати миқёспазири сарбории баландро барои 1C навиштем: Enterprise: Java, PostgreSQL, Hazelcast

Барои он ки махзани маълумотҳои асосӣ монеа шавад, мо ҷадвали масирро (ва дигар маълумоти зуд-зуд лозим) дар кэш нигоҳ медорем.

Агар базаи муштарӣ ба сустшавӣ шурӯъ кунад, мо онро ба қисмҳои дохили он бурида хоҳем кард. Дар дигар лоиҳаҳое, ки мо истифода мебарем pg_pathman.

Азбаски гум кардани паёмҳои корбар бад аст, мо пойгоҳи додаҳои худро бо нусхабардорӣ нигоҳ медорем. Маҷмӯи репликаҳои синхронӣ ва асинхронӣ ба шумо имкон медиҳад, ки худро дар сурати гум шудани базаи асосӣ суғурта кунед. Талафоти паём танҳо дар ҳолате рух медиҳад, ки пойгоҳи додаҳои асосӣ ва репликаи синхронии он ҳамзамон ноком шаванд.

Агар нусхаи синхронӣ гум шавад, репликаи асинхронӣ синхронӣ мешавад.
Агар базаи асосӣ гум шавад, репликаи синхронӣ ба пойгоҳи додаҳои асосӣ ва репликаи асинхронӣ нусхаи синхронӣ мегардад.

Elasticsearch барои ҷустуҷӯ

Азбаски, дар байни чизҳои дигар, SV низ паёмнавис аст, он ҷустуҷӯи зуд, қулай ва фасеҳро бо назардошти морфология, бо истифода аз мувофиқати номуайян талаб мекунад. Мо тасмим гирифтем, ки чархро аз нав ихтироъ накунем ва аз системаи ҷустуҷӯии ройгони Elasticsearch, ки дар асоси китобхона сохта шудааст, истифода набарем Люсен. Мо инчунин Elasticsearch-ро дар кластер (мастер - додаҳо - додаҳо) ҷойгир мекунем, то мушкилотро дар ҳолати нокомии гиреҳҳои барнома бартараф кунем.

Дар github мо ёфтем Васлкунаки морфологияи русӣ барои Elasticsearch ва истифода аз он. Дар индекси Elasticsearch мо решаҳои калимаро (ки плагин муайян мекунад) ва N-граммҳоро нигоҳ медорем. Вақте ки корбар матнро барои ҷустуҷӯ ворид мекунад, мо матни чопшударо дар байни N-grams ҷустуҷӯ мекунем. Вақте ки дар индекс захира карда мешавад, калимаи "матнҳо" ба N-граммҳои зерин тақсим карда мешавад:

[онҳо, tek, tex, матн, матнҳо, ek, ex, ext, texts, ks, kst, ksty, st, sty, you],

Ва решаи вожаи «матн» низ ҳифз хоҳад шуд. Ин равиш ба шумо имкон медиҳад, ки дар аввал, мобайн ва охири калима ҷустуҷӯ кунед.

Сурати умумӣ

Чӣ гуна ва чаро мо як хидмати миқёспазири сарбории баландро барои 1C навиштем: Enterprise: Java, PostgreSQL, Hazelcast
Тасвирро аз аввали мақола такрор кунед, аммо бо тавзеҳот:

  • Тавозуни дар Интернет ошкоршуда; мо nginx дорем, он метавонад ҳама гуна бошад.
  • Намунаҳои барномаҳои Java тавассути Hazelcast бо ҳамдигар муошират мекунанд.
  • Барои кор бо васлаки веб мо истифода мебарем Нотик.
  • Замимаи Java дар Java 8 навишта шудааст ва аз бастаҳо иборат аст ОСГи. Нақшаҳо муҳоҷират ба Java 10 ва гузариш ба модулҳоро дар бар мегиранд.

Таҳия ва озмоиш

Дар ҷараёни таҳия ва озмоиши SV мо бо як қатор хусусиятҳои ҷолиби маҳсулоте, ки мо истифода мебарем, дучор омадем.

Санҷиши сарборӣ ва ихроҷи хотира

Нашри ҳар як версияи SV санҷиши сарбориро дар бар мегирад. Он вақте муваффақ мешавад:

  • Санҷиш чанд рӯз кор кард ва ягон камбудии хидматрасонӣ вуҷуд надошт
  • Вақти вокуниш ба амалиёти асосӣ аз ҳадди қулай зиёд набуд
  • Пастшавии кор дар муқоиса бо версияи қаблӣ на бештар аз 10%

Мо базаи санҷиширо бо маълумот пур мекунем - барои ин, мо маълумотро дар бораи муштарии фаъолтарин аз сервери истеҳсолӣ мегирем, рақамҳои онро ба 5 (шумораи паёмҳо, муҳокимаҳо, корбарон) зарб мезанем ва онро ҳамин тавр месанҷем.

Мо озмоиши сарбории системаи мутақобиларо дар се конфигуратсия мегузаронем:

  1. санҷиши стресс
  2. Танҳо пайвастҳо
  3. Бақайдгирии муштарӣ

Ҳангоми санҷиши стресс, мо садҳо риштаҳоро оғоз мекунем ва онҳо системаро бе таваққуф бор мекунанд: навиштани паёмҳо, эҷоди муҳокимаҳо, гирифтани рӯйхати паёмҳо. Мо амалҳои корбарони оддиро тақлид мекунем (рӯйхати паёмҳои нохондаи маро гиред, ба касе нависед) ва ҳалли нармафзор (интиқоли бастаи конфигуратсияи дигар, коркарди огоҳӣ).

Масалан, қисми санҷиши стресс чунин аст:

  • Корбар ворид мешавад
    • Муҳокимаҳои нохондаатонро талаб мекунад
    • 50% эҳтимоли хондани паёмҳо
    • 50% эҳтимоли навиштани матн
    • Корбари навбатӣ:
      • 20% имкони эҷоди як баҳси нав дорад
      • Ба таври тасодуфӣ ягон муҳокимаи худро интихоб мекунад
      • Дарун медарояд
      • Паёмҳо, профилҳои корбарро дархост мекунад
      • Панҷ паёмеро, ки аз ин муҳокима ба корбарони тасодуфӣ фиристода мешаванд, эҷод мекунад
      • Муҳокимаро тарк мекунад
      • 20 маротиба такрор мешавад
      • Хуруҷ мешавад, ба оғози скрипт бармегардад

    • Чатбот ба система ворид мешавад (ба паёмнависӣ аз рамзи барнома тақлид мекунад)
      • 50% имкони эҷоди канали нав барои табодули маълумот дорад (баҳси махсус)
      • 50% эҳтимол ба ягон канали мавҷуда паём менависанд

Сенарияи "Танҳо Пайвастшавӣ" бо як сабаб пайдо шуд. Вазъият вуҷуд дорад: корбарон системаро пайваст кардаанд, аммо ҳанӯз ба он ҷалб нашудаанд. Ҳар як корбар соати 09:00 саҳар компютерро даргиронда, ба сервер пайваст мешавад ва хомӯш мемонад. Ин бачаҳо хатарноканд, бисёре аз онҳо ҳастанд - ягона бастаҳои онҳо PING/PONG мебошанд, аммо онҳо пайвастагиро бо сервер нигоҳ медоранд (онҳо онро нигоҳ дошта наметавонанд - чӣ мешавад, агар паёми нав бошад). Санҷиш вазъиятеро такрор мекунад, ки шумораи зиёди чунин корбарон кӯшиш мекунанд, ки дар ним соат ба система ворид шаванд. Он ба санҷиши стресс монанд аст, аммо тамаркузи он маҳз ба ин вуруди аввал аст - то ки ҳеҷ гуна нокомиҳо вуҷуд надошта бошанд (одам системаро истифода намебарад ва он аллакай меафтад - дар бораи чизи бадтар фикр кардан душвор аст).

Скрипти бақайдгирии муштарӣ аз оғози аввалин оғоз меёбад. Мо санҷиши стресс гузаронидем ва боварӣ доштем, ки система ҳангоми мукотиба суст намешавад. Аммо корбарон омаданд ва сабти ном бо сабаби танаффус ноком шуд. Ҳангоми бақайдгирӣ мо истифода мебурдем / dev / random, ки ба энтропияи система вобаста аст. Сервер барои ҷамъ кардани энтропияи кофӣ вақт надошт ва вақте ки SecureRandom-и нав дархост шуд, он даҳҳо сония ях кард. Роҳҳои зиёде аз ин вазъият вуҷуд дорад, масалан: гузаштан ба /dev/urandom камтар бехатар, насб кардани тахтаи махсус, ки энтропия тавлид мекунад, рақамҳои тасодуфиро пешакӣ тавлид кунед ва онҳоро дар ҳавз нигоҳ доред. Мо муваққатан мушкилотро бо ҳавз баста будем, аммо аз он вақт мо барои бақайдгирии муштариёни нав санҷиши алоҳида мегузаронем.

Мо ҳамчун генератори сарборӣ истифода мебарем JMeter. Он намедонад, ки чӣ тавр бо websocket кор кунад; барои он плагин лозим аст. Аввалин дар натиҷаҳои ҷустуҷӯ барои дархости "jmeter websocket" инҳоянд: мақолаҳо аз BlazeMeter, ки тавсия медиҳанд плагин аз ҷониби Maciej Zaleski.

Дар он ҷо мо тасмим гирифтем, ки оғоз кунем.

Қариб дарҳол пас аз оғози санҷиши ҷиддӣ, мо фаҳмидем, ки JMeter ба ихроҷи хотира шурӯъ кардааст.

Васлкунак як ҳикояи алоҳидаи калон аст; бо 176 ситора, он дар github 132 фард дорад. Худи муаллиф аз соли 2015 инҷониб ба он ӯҳдадор нашудааст (мо онро соли 2015 гирифта будем, пас он шубҳаҳоро ба вуҷуд наовард), якчанд масъалаҳои github дар бораи ихроҷи хотира, 7 дархости пӯшиданашуда.
Агар шумо қарор диҳед, ки бо истифода аз ин плагин санҷиши сарборӣ кунед, лутфан ба муҳокимаҳои зерин диққат диҳед:

  1. Дар муҳити бисёр ришта, як LinkedList муқаррарӣ истифода мешуд ва натиҷа буд NPE дар вақти корӣ. Инро тавассути гузариш ба ConcurrentLinkedDeque ё бо блокҳои ҳамоҳангшуда ҳал кардан мумкин аст. Мо варианти аввалро барои худ интихоб кардем (https://github.com/maciejzaleski/JMeter-WebSocketSampler/issues/43).
  2. Ихроҷи хотира; ҳангоми ҷудокунӣ, маълумоти пайвастшавӣ нест карда намешавад (https://github.com/maciejzaleski/JMeter-WebSocketSampler/issues/44).
  3. Дар реҷаи ҷараён (вақте ки веб-сокет дар охири намуна баста намешавад, аммо дертар дар нақша истифода мешавад), Намунаҳои вокуниш кор намекунанд (https://github.com/maciejzaleski/JMeter-WebSocketSampler/issues/19).

Ин яке аз онҳо дар github аст. Мо чӣ кор кардем:

  1. гирифтаанд вилка Элиран Коган (@elyrank) - он мушкилоти 1 ва 3-ро ҳал мекунад
  2. Масъалаи ҳалшуда 2
  3. Истгоҳи нав аз 9.2.14 то 9.3.12
  4. SimpleDateFormat дар ThreadLocal печонида шудааст; SimpleDateFormat аз ришта бехатар нест, ки дар вақти кор ба NPE оварда расонд
  5. Боз як ихроҷи хотираро ислоҳ кард (пайваст ҳангоми ҷудо шудан нодуруст баста шуд)

Ва аммо он ҷорист!

Хотира на дар як руз, балки дар ду руз тамом шудан гирифт. Мутлақо вақт боқӣ намондааст, бинобар ин мо тасмим гирифтем, ки риштаҳои камтарро оғоз кунем, аммо дар чор агент. Ин бояд ҳадди аққал як ҳафта кофӣ бошад.

Ду рӯз гузашт...

Ҳоло Hazelcast хотира тамом мешавад. Гузоришҳо нишон доданд, ки пас аз чанд рӯзи санҷиш, Ҳазелкаст аз нарасидани хотира шикоят кард ва пас аз чанд вақт кластер аз ҳам ҷудо шуд ва гиреҳҳо як ба як мурданд. Мо JVisualVM-ро ба hazelcast пайваст кардем ва "арраи болошаванда" дидем - он мунтазам GC-ро меноманд, аммо хотираро тоза карда натавонист.

Чӣ гуна ва чаро мо як хидмати миқёспазири сарбории баландро барои 1C навиштем: Enterprise: Java, PostgreSQL, Hazelcast

Маълум шуд, ки дар hazelcast 3.4, ҳангоми нест кардани харита / multiMap (map.destroy ()), хотира пурра озод карда намешавад:

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

Хатогӣ ҳоло дар 3.5 ислоҳ шудааст, аммо он вақт мушкилот буд. Мо харитаҳои навро бо номҳои динамикӣ офаридаем ва мувофиқи мантиқи худ онҳоро нест кардем. Рамз чунин менамуд:

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

Занг занед:

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

multiMap барои ҳар як обуна сохта шуда буд ва вақте ки лозим набуд, нест карда шуд. Мо тасмим гирифтем, ки Map-ро оғоз кунем , калид номи обуна хоҳад буд ва арзишҳо идентификаторҳои сессия хоҳанд буд (агар лозим бошад, шумо метавонед аз онҳо идентификаторҳои корбарро гиред).

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

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

Диаграммаҳо беҳтар шуданд.

Чӣ гуна ва чаро мо як хидмати миқёспазири сарбории баландро барои 1C навиштем: Enterprise: Java, PostgreSQL, Hazelcast

Мо дар бораи санҷиши сарборӣ боз чиро омӯхтем?

  1. JSR223 бояд ба таври зебо навишта шавад ва кэши компиляцияро дар бар гирад - он хеле тезтар аст. пайванд.
  2. Графикаи Jmeter-Plugins нисбат ба графикҳои стандартӣ осонтар аст. пайванд.

Дар бораи таҷрибаи мо бо Hazelcast

Hazelcast барои мо маҳсулоти нав буд, мо бо он аз версияи 3.4.1 кор кардем, ҳоло сервери истеҳсолии мо версияи 3.9.2-ро иҷро мекунад (дар вақти навиштан, версияи охирини Hazelcast 3.10 аст).

Насли ID

Мо бо идентификаторҳои бутун оғоз кардем. Биёед тасаввур кунем, ки ба мо дигар Лонг барои як сохтори нав лозим аст. пайдарпаии дар базаи маълумот мувофиқ нест, ҷадвалҳо дар sharding иштирок доранд - маълум мешавад, ки паём ID=1 дар DB1 ва паём ID=1 дар DB2 вуҷуд дорад, шумо наметавонед ин ID-ро дар Elasticsearch ҷойгир кунед ва на дар Hazelcast , аммо бадтарин чиз он аст, ки агар шумо хоҳед, ки маълумотро аз ду пойгоҳи додаҳо ба як муттаҳид кунед (масалан, қарор қабул кунед, ки як пойгоҳи додаҳо барои ин муштариён кофӣ аст). Шумо метавонед якчанд AtomicLong-ро ба Hazelcast илова кунед ва ҳисобкунакро дар он ҷо нигоҳ доред, пас иҷрои гирифтани ID-и нав incrementAndGet ва вақти дархост ба Hazelcast аст. Аммо Hazelcast дорои чизи оптималтар аст - FlakeIdGenerator. Ҳангоми тамос бо ҳар як муштарӣ ба онҳо диапазони ID дода мешавад, масалан, якум – аз 1 то 10 000, дуюм – аз 10 001 то 20 000 ва ғайра. Акнун муштарӣ метавонад мустақилона идентификаторҳои навро то ба охир расидани диапазони ба он додашуда диҳад. Он зуд кор мекунад, аммо вақте ки шумо барномаро (ва муштарии Hazelcast) бозоғоз мекунед, пайдарпайии нав оғоз мешавад - аз ин рӯ гузаришҳо ва ғайра. Илова бар ин, таҳиягарон аслан намефаҳманд, ки чаро ID-ҳо адад мебошанд, аммо ин қадар номувофиқанд. Мо ҳама чизро баркашида, ба UUID гузаштем.

Дар омади гап, барои онҳое, ки мехоҳанд ба Twitter монанд бошанд, чунин китобхонаи Snowcast мавҷуд аст - ин татбиқи Snowflake дар болои Hazelcast аст. Шумо метавонед онро дар ин ҷо бубинед:

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

Аммо мо дигар ба он нарасидем.

TransactionalMap.replace

Дигар ҳайратовар: TransactionalMap.replace кор намекунад. Ин як санҷиш аст:

@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

Ман бояд бо истифода аз 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);
}

На танҳо сохторҳои муқаррарии маълумот, балки версияҳои транзаксионии онҳоро низ санҷед. Чунин мешавад, ки IMap кор мекунад, аммо TransactionalMap дигар вуҷуд надорад.

JAR-и навро бе вақти бекорӣ ҷойгир кунед

Аввалан, мо тасмим гирифтем, ки объектҳои синфҳои худро дар Hazelcast сабт кунем. Масалан, мо синфи Application дорем, мо мехоҳем онро захира кунем ва хонем. Захира:

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

Мо мехонем:

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

Ҳама чиз кор мекунад. Пас аз он мо тасмим гирифтем, ки дар Hazelcast як индекс созем, то аз рӯи зерин ҷустуҷӯ кунем:

map.addIndex("subscriberId", false);

Ва ҳангоми навиштани як объекти нав, онҳо ба гирифтани ClassNotFoundException оғоз карданд. Ҳазелкаст кӯшиш кард, ки ба индекс илова кунад, аммо дар бораи синфи мо чизе намедонист ва мехост, ки JAR бо ин синф ба он дода шавад. Мо ҳамин тавр кардем, ҳама чиз кор кард, аммо мушкилоти нав пайдо шуд: чӣ гуна JAR-ро бе қатъ кардани кластер навсозӣ кардан мумкин аст? Hazelcast JAR-и навро ҳангоми навсозии гиреҳ ба гиреҳ намегирад. Дар ин лаҳза мо қарор додем, ки мо метавонем бидуни ҷустуҷӯи индекс зиндагӣ кунем. Дар ниҳоят, агар шумо Hazelcast-ро ҳамчун мағозаи арзишманд истифода баред, ҳама чиз кор хоҳад кард? На дарвоқеъ. Дар ин ҷо боз рафтори IMap ва TransactionalMap гуногун аст. Дар ҷое, ки IMap парво надорад, TransactionalMap хато мекунад.

IMap. Мо 5000 объект менависем, онҳоро хонем. Ҳама чиз интизор аст.

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

Аммо он дар транзаксия кор намекунад, мо 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();
        }
    });
}

Дар 3.8, механизми Deployment Class User пайдо шуд. Шумо метавонед як гиреҳи асосӣ таъин кунед ва файли JAR-ро дар он навсозӣ кунед.

Ҳоло мо равиши худро комилан тағир додем: мо онро худамон ба JSON силсиласозӣ мекунем ва онро дар Hazelcast захира мекунем. Ба Hazelcast лозим нест, ки сохтори дарсҳои моро донад ва мо метавонем бидуни бекоркунӣ навсозӣ кунем. Версияи объектҳои доменро барнома идора мекунад. Версияҳои гуногуни барнома метавонанд дар як вақт кор кунанд ва вазъият имконпазир аст, ки замимаи нав объектҳоро бо майдонҳои нав менависад, аммо версияи кӯҳна дар бораи ин майдонҳо ҳанӯз хабар надорад. Ва дар айни замон, замимаи нав объектҳои аз ҷониби замимаи кӯҳна навишташуда, ки майдонҳои нав надоранд, мехонад. Мо чунин ҳолатҳоро дар дохили барнома ҳал мекунем, аммо барои соддагӣ мо майдонҳоро тағир намедиҳем ё нест намекунем, мо танҳо бо илова кардани майдонҳои нав синфҳоро васеъ мекунем.

Чӣ тавр мо иҷрои баландро таъмин мекунем

Чор сафар ба Hazelcast - хуб, ду ба базаи - бад

Гузариш ба кэш барои маълумот ҳамеша беҳтар аз рафтан ба пойгоҳи додаҳо аст, аммо шумо намехоҳед сабтҳои истифоданашударо нигоҳ доред. Мо тасмимро дар бораи кэш карданро то марҳилаи охирини рушд мегузорем. Вақте ки функсияи нав рамзгузорӣ мешавад, мо сабти ҳама дархостҳоро дар PostgreSQL фаъол мекунем (log_min_duration_statement то 0) ва санҷиши сарбориро дар тӯли 20 дақиқа иҷро мекунем.Бо истифода аз гузоришҳои ҷамъшуда, утилитаҳо ба монанди pgFouine ва pgBadger метавонанд ҳисоботҳои таҳлилиро созанд. Дар гузоришҳо мо пеш аз ҳама дархостҳои суст ва зуд-зуд ҷустуҷӯ мекунем. Барои пурсишҳои суст, мо нақшаи иҷроро месозем (изҳор) ва арзёбӣ мекунем, ки оё чунин дархостро суръат бахшидан мумкин аст. Дархостҳои зуд-зуд барои ҳамон як маълумоти воридотӣ ба кэш хуб мувофиқанд. Мо кӯшиш мекунем, ки дархостҳоро "ҳамвор" нигоҳ дорем, як ҷадвал дар як дархост.

Амалиёт

SV ҳамчун хидмати онлайн дар баҳори соли 2017 ба истифода дода шуд ва ҳамчун маҳсулоти алоҳида, SV моҳи ноябри соли 2017 бароварда шуд (дар он вақт дар ҳолати версияи бета).

Дар тӯли зиёда аз як соли фаъолият дар кори хидмати онлайнии CB ягон мушкилоти ҷиддӣ ба вуҷуд наомадааст. Мо хидмати онлайнро тавассути он назорат мекунем Зарифӣ, ҷамъоварӣ ва ҷойгиркунӣ аз Бамбук.

Тақсимоти сервери SV дар шакли бастаҳои маҳаллӣ таъмин карда мешавад: RPM, DEB, MSI. Плюс барои Windows мо як насбкунандаи ягонаро дар шакли як EXE пешниҳод мекунем, ки сервер, Hazelcast ва Elasticsearch-ро дар як мошин насб мекунад. Мо дар аввал ин версияи насбро ҳамчун версияи "демо" номида будем, аммо ҳоло маълум шуд, ки ин маъмултарин варианти густариш аст.

Манбаъ: will.com

Илова Эзоҳ