Մեր բաց կոդով պատմությունը. ինչպես ենք մենք Go-ում վերլուծական ծառայություն ստեղծել և այն հանրությանը հասանելի դարձնել

Ներկայումս աշխարհի գրեթե բոլոր ընկերությունները վիճակագրություն են հավաքում վեբ ռեսուրսի վրա օգտագործողների գործողությունների վերաբերյալ: Մոտիվացիան պարզ է. ընկերությունները ցանկանում են իմանալ, թե ինչպես է օգտագործվում իրենց արտադրանքը/վեբ կայքը և ավելի լավ հասկանալ իրենց օգտատերերին: Իհարկե, այս խնդիրը լուծելու համար շուկայում կան մեծ թվով գործիքներ՝ վերլուծական համակարգերից, որոնք տվյալներ են տրամադրում վահանակների և գրաֆիկների տեսքով (օրինակ. Google AnalyticsՀաճախորդների տվյալների հարթակ, որը թույլ է տալիս հավաքել և համախմբել տվյալներ տարբեր աղբյուրներից ցանկացած պահեստում (օրինակ հատված).

Բայց մենք գտանք մի խնդիր, որը դեռ չի լուծվել։ Այսպես ծնվեց ԻրադարձությունNative — բաց կոդով վերլուծական ծառայություն: Կարդացեք այն մասին, թե ինչու մենք որոշեցինք զարգացնել մեր սեփական ծառայությունը, ինչ տվեց այն մեզ և որն էր վերջնական արդյունքը (կոդերի կտորներով):

Մեր բաց կոդով պատմությունը. ինչպես ենք մենք Go-ում վերլուծական ծառայություն ստեղծել և այն հանրությանը հասանելի դարձնել

Ինչու՞ մենք պետք է զարգացնենք մեր սեփական ծառայությունը:

Իննսունականներն էին, մենք ողջ մնացինք, ինչպես կարող էինք։ 2019 թվականին մենք մշակեցինք API-ի առաջին հաճախորդների տվյալների հարթակը kSense, ինչը հնարավորություն է տվել տարբեր աղբյուրներից (Facebook ads, Stripe, Salesforce, Google play, Google Analytics և այլն) տվյալների համախմբումը ավելի հարմար տվյալների վերլուծության, կախվածությունը բացահայտելու և այլն: Մենք նկատել ենք, որ շատ օգտատերեր օգտագործում են մեր հարթակը տվյալների վերլուծության համար, մասնավորապես՝ Google Analytics (այսուհետ՝ GA): Մենք խոսեցինք որոշ օգտատերերի հետ և պարզեցինք, որ նրանց անհրաժեշտ են իրենց արտադրանքի վերլուծական տվյալները, որոնք նրանք ստանում են GA-ի միջոցով, բայց Google-ը նմուշառում է տվյալներ և շատերի համար GA Օգտվողի միջերեսը հարմարության չափանիշ չէ: Մենք բավականաչափ խոսակցություններ ունեցանք մեր օգտատերերի հետ և հասկացանք, որ շատերն օգտվում են նաև Segment հարթակից (որը, ի դեպ, հենց օրերս էր վաճառվել է 3.2 մլրդ դոլարով).

Նրանք տեղադրեցին Segment javascript պիքսել իրենց վեբ ռեսուրսի վրա, և նրանց օգտատերերի վարքագծի վերաբերյալ տվյալները բեռնվեցին նշված տվյալների բազայում (օրինակ՝ Postgres): Բայց Segment-ն ունի նաև իր բացասական կողմը՝ գինը: Օրինակ, եթե վեբ ռեսուրսն ունի 90,000 MTU (ամսական հետևվող օգտվողներ), ապա դուք պետք է ամսական վճարեք ~ 1,000 $ գանձապահին: Կար նաև երրորդ խնդիր՝ որոշ բրաուզերի ընդլայնումներ (օրինակ՝ AdBlock) արգելափակեցին վերլուծական տվյալների հավաքածուն, քանի որ... http հարցումները զննարկիչից ուղարկվել են GA և Segment տիրույթներ: Ելնելով մեր հաճախորդների ցանկություններից՝ մենք ստեղծել ենք վերլուծական ծառայություն, որը հավաքում է տվյալների ամբողջական փաթեթ (առանց նմուշառման), անվճար է և կարող է աշխատել մեր սեփական ենթակառուցվածքի վրա:

Ինչպես է աշխատում ծառայությունը

Ծառայությունը բաղկացած է երեք մասից՝ javascript պիքսել (որը մենք հետագայում վերաշարադրեցինք տպագրության մեջ), սերվերի մասը ներդրված է GO լեզվով, և նախատեսվում էր օգտագործել Redshift և BigQuery որպես ներքին տվյալների բազա (հետագայում նրանք ավելացրին աջակցություն Postgres, ClickHouse և Snowflake):

Որոշվեց ԳԱ-ի և Սեգմենտի միջոցառումների կառուցվածքը թողնել անփոփոխ։ Ընդամենը անհրաժեշտ էր կրկնօրինակել բոլոր իրադարձությունները վեբ ռեսուրսից, որտեղ պիքսելը տեղադրված է մեր հետնամասում: Ինչպես պարզվում է, դա դժվար չէ անել։ Javascript-ի պիքսելը փոխարինեց GA գրադարանի սկզբնական մեթոդը նորով, որը կրկնօրինակեց իրադարձությունը մեր համակարգում:

//'ga' - стандартное название переменной Google Analytics
if (window.ga) {
    ga(tracker => {
        var originalSendHitTask = tracker.get('sendHitTask');
        tracker.set('sendHitTask', (model) => {
            var payLoad = model.get('hitPayload');
            //отправка оригинального события в GA
            originalSendHitTask(model);
            let jsonPayload = this.parseQuery(payLoad);
            //отправка события в наш сервис
            this.send3p('ga', jsonPayload);
        });
    });
}

Segment pixel-ի հետ ամեն ինչ ավելի պարզ է, այն ունի միջին ծրագրային մեթոդներ, որոնցից մեկը մենք օգտագործել ենք:


//'analytics' - стандартное название переменной Segment
if (window.analytics) {
    if (window.analytics.addSourceMiddleware) {
        window.analytics.addSourceMiddleware(chain => {
            try {
		//дублирование события в наш сервис
                this.send3p('ajs', chain.payload);
            } catch (e) {
                LOG.warn('Failed to send an event', e)
            }
	    //отправка оригинального события в Segment
            chain.next(chain.payload);
        });
    } else {
        LOG.warn("Invalid interceptor state. Analytics js initialized, but not completely");
    }
} else {
    LOG.warn('Analytics.js listener is not set.');
}

Ի հավելումն իրադարձությունների պատճենման, մենք ավելացրել ենք կամայական json ուղարկելու հնարավորությունը՝


//Отправка событий с произвольным json объектом
eventN.track('product_page_view', {
    product_id: '1e48fb70-ef12-4ea9-ab10-fd0b910c49ce',
    product_price: 399.99,
    price_currency: 'USD'
    product_release_start: '2020-09-25T12:38:27.763000Z'
});

Հաջորդը, եկեք խոսենք սերվերի մասի մասին: Backend-ը պետք է ընդունի http հարցումները, լրացնի դրանք լրացուցիչ տեղեկություններով, օրինակ՝ աշխարհագրական տվյալներ (շնորհակալություն maxmind դրա համար) և գրանցել այն տվյալների բազայում: Մենք ցանկանում էինք ծառայությունը հնարավորինս հարմար դարձնել, որպեսզի այն օգտագործվի նվազագույն կոնֆիգուրացիայով: Մենք իրականացրել ենք մուտքային json իրադարձության կառուցվածքի հիման վրա տվյալների սխեմայի որոշման ֆունկցիոնալությունը: Տվյալների տեսակները սահմանվում են արժեքներով: Բնադրված առարկաները քայքայվում և վերածվում են հարթ կառուցվածքի.

//входящий json
{
  "field_1":  {
    "sub_field_1": "text1",
    "sub_field_2": 100
  },
  "field_2": "text2",
  "field_3": {
    "sub_field_1": {
      "sub_sub_field_1": "2020-09-25T12:38:27.763000Z"
    }
  }
}

//результат
{
  "field_1_sub_field_1":  "text1",
  "field_1_sub_field_2":  100,
  "field_2": "text2",
  "field_3_sub_field_1_sub_sub_field_1": "2020-09-25T12:38:27.763000Z"
}

Այնուամենայնիվ, զանգվածները ներկայումս պարզապես վերածվում են տողերի, քանի որ Ոչ բոլոր հարաբերական տվյալների բազաներն են աջակցում կրկնվող դաշտերը: Հնարավոր է նաև փոխել դաշտերի անունները կամ ջնջել դրանք՝ օգտագործելով ընտրովի քարտեզագրման կանոնները: Նրանք թույլ են տալիս անհրաժեշտության դեպքում փոխել տվյալների սխեման կամ փոխարկել տվյալների մի տեսակը մյուսին: Օրինակ, եթե json դաշտը պարունակում է ժամանակի դրոշմով տող (դաշտ_3_ենթադաշտ_1_ենթակետ_դաշտ_1 վերևի օրինակից), այնուհետև տվյալների բազայում ժամանակի դրոշմակնիքի տիպով դաշտ ստեղծելու համար պետք է կազմաձևում գրել քարտեզագրման կանոն: Այլ կերպ ասած, դաշտի տվյալների տեսակը նախ որոշվում է json արժեքով, այնուհետև կիրառվում է տիպի ձուլման կանոնը (եթե կազմաձևված է): Մենք հայտնաբերել ենք տվյալների 4 հիմնական տեսակ՝ STRING, FLOAT64, INT64 և TIMESTAMP: Քարտեզագրման և տիպի ձուլման կանոնները հետևյալն են.

rules:
  - "/field_1/subfield_1 -> " #правило удаления поля
  - "/field_2/subfield_1 -> /field_10/subfield_1" #правило переноса поля
  - "/field_3/subfield_1/subsubfield_1 -> (timestamp) /field_20" #правило переноса поля и приведения типа

Տվյալների տեսակը որոշելու ալգորիթմ.

  • փոխարկել json կառուցվածքը հարթ կառուցվածքի
  • արժեքներով դաշտերի տվյալների տիպի որոշում
  • քարտեզագրման և տիպի ձուլման կանոնների կիրառում

Այնուհետև մուտքային json կառուցվածքից.

{
    "product_id":  "1e48fb70-ef12-4ea9-ab10-fd0b910c49ce",
    "product_price": 399.99,
    "price_currency": "USD",
    "product_type": "supplies",
    "product_release_start": "2020-09-25T12:38:27.763000Z",
    "images": {
      "main": "picture1",
      "sub":  "picture2"
    }
}

տվյալների սխեման կստացվի.

"product_id" character varying,
"product_price" numeric (38,18),
"price_currency" character varying,
"product_type" character varying,
"product_release_start" timestamp,
"images_main" character varying,
"images_sub" character varying

Մենք նաև մտածեցինք, որ օգտատերը պետք է կարողանա կարգավորել բաժանումը կամ տվյալների բազան բաժանել այլ չափանիշների համաձայն և իրականացրեցինք աղյուսակի անվանումը հաստատունով կամ արտահայտություն կոնֆիգուրացիայի մեջ: Ստորև բերված օրինակում իրադարձությունը կպահվի աղյուսակում, որի անունը հաշվարկվում է ապրանքի_տիպի և _ժամանակի դրոշմ դաշտերի արժեքների հիման վրա (օրինակ մատակարարումներ_2020_10):

tableName: '{{.product_type}}_{{._timestamp.Format "2006_01"}}'

Այնուամենայնիվ, մուտքային իրադարձությունների կառուցվածքը կարող է փոխվել գործարկման ժամանակ: Մենք իրականացրել ենք ալգորիթմ՝ ստուգելու գոյություն ունեցող աղյուսակի կառուցվածքի և մուտքային իրադարձության կառուցվածքի տարբերությունը: Եթե ​​տարբերություն հայտնաբերվի, աղյուսակը կթարմացվի նոր դաշտերով: Դա անելու համար օգտագործեք կարկատել SQL հարցումը.

#Пример для Postgres
ALTER TABLE "schema"."table" ADD COLUMN new_column character varying

ճարտարապետություն

Մեր բաց կոդով պատմությունը. ինչպես ենք մենք Go-ում վերլուծական ծառայություն ստեղծել և այն հանրությանը հասանելի դարձնել

Ինչու՞ պետք է իրադարձություններ գրեք ֆայլային համակարգում, և ոչ թե դրանք ուղղակիորեն գրեք տվյալների բազայում: Տվյալների բազաները միշտ չէ, որ լավ են աշխատում, երբ գործ ունենք մեծ թվով ներդիրների հետ (Postgres-ի առաջարկություններ) Դա անելու համար Logger-ը մուտքային իրադարձությունները գրում է ֆայլում և առանձին գորուտինով (թել) File reader-ը կարդում է ֆայլը, այնուհետև տվյալները փոխակերպվում և որոշվում են: Այն բանից հետո, երբ աղյուսակի կառավարիչը համոզվի, որ աղյուսակի սխեման արդիական է, տվյալները մեկ խմբաքանակով կգրվեն տվյալների բազայում: Հետագայում մենք ավելացրինք տվյալների բազայում ուղղակիորեն տվյալներ գրելու հնարավորությունը, բայց մենք օգտագործում ենք այս ռեժիմը իրադարձությունների համար, որոնք բազմաթիվ չեն, օրինակ՝ փոխարկումներ:

Բաց կոդով և ապագայի պլաններ

Ինչ-որ պահի ծառայությունը սկսեց նմանվել լիարժեք արտադրանքի, և մենք որոշեցինք այն թողարկել բաց կոդով: Ներկայումս իրականացվել են ինտեգրումներ Postgres-ի, ClickHouse-ի, BigQuery-ի, Redshift-ի, S3-ի, Snowflake-ի հետ։ Բոլոր ինտեգրացիաներն աջակցում են տվյալների բեռնման և՛ խմբաքանակի, և՛ հոսքային ռեժիմներին: Ավելացվել է API-ի միջոցով հարցումների աջակցություն:

Ներկայիս ինտեգրման սխեման ունի հետևյալ տեսքը.

Մեր բաց կոդով պատմությունը. ինչպես ենք մենք Go-ում վերլուծական ծառայություն ստեղծել և այն հանրությանը հասանելի դարձնել

Չնայած ծառայությունը կարող է օգտագործվել ինքնուրույն (օրինակ՝ օգտագործելով Docker), մենք նույնպես ունենք հյուրընկալված տարբերակը, որտեղ դուք կարող եք ինտեգրվել տվյալների պահեստին, ավելացնել CNAME ձեր տիրույթում և դիտել իրադարձությունների քանակի վիճակագրությունը: Մեր անմիջական ծրագրերն են՝ ավելացնել ոչ միայն վեբ ռեսուրսից վիճակագրություն, այլ նաև տվյալների արտաքին աղբյուրներից ստացված տվյալները և դրանք պահել ձեր ընտրած ցանկացած պահեստում:

→ GitHub
→ Փաստաթղթերով հիմնավորում
→ Անգործություն

Մենք ուրախ կլինենք, եթե EventNative-ն օգնի լուծել ձեր խնդիրները:

Հարցմանը կարող են մասնակցել միայն գրանցված օգտվողները։ Մուտք գործել, խնդրում եմ:

Վիճակագրության հավաքագրման ի՞նչ համակարգ է օգտագործվում ձեր ընկերությունում:

  • 48,0%Google Analytics12

  • 4,0%Հատված 1

  • 16,0%Մեկ այլ (գրեք մեկնաբանություններում)4

  • 32,0%Իրականացրել է ձեր ծառայությունը8

Քվեարկել է 25 օգտատեր։ 6 օգտատեր ձեռնպահ է մնացել։

Source: www.habr.com

Добавить комментарий