Apache Modulu mod_unique_id

Göndərildi: 08.09.2021
Məqalənin müəllifi Adəm Quliyev

Bu modul, çox spesifik şərtlər altında "bütün" sorğular arasında unikal olmasına zəmanət verilən hər bir istək üçün sehrli bir mö'cüzə təqdim edir. Unikal identifikator, düzgün qurulmuş bir maşın qrupunda birdən çox maşın arasında unikaldır. UNIQUE_ID mühit dəyişənliyi hər bir sorğu üçün identifikatora təyin edilir. Unikal identifikatorlar bu sənədin əhatə dairəsinə daxil olmayan müxtəlif səbəblərə görə faydalıdır.

Mövzular

  • Nəzəriyyə

Direktivlər

Bu modul heç bir direktiv təqdim etmir.

Bugfix yoxlama siyahısı

Həmçinin bax

Nəzəriyyə

Əvvəlcə Apache serverinin Unix maşınlarında necə işlədiyinə dair qısa məlumat. Bu xüsusiyyət hazırda Windows NT -də dəstəklənmir. Unix maşınlarında Apache bir neçə uşaq yaradır, uşaqlar bir anda istəkləri yerinə yetirirlər. Hər bir uşaq ömrü boyu bir neçə sorğuya xidmət edə bilər. Bu müzakirə məqsədi ilə uşaqlar bir -biri ilə heç bir məlumat paylaşmırlar. Uşaqlara müraciət edəcəyik.

Veb saytınızda inzibati nəzarət altında bir və ya daha çox maşın var, birlikdə onlara maşın dəstəsi deyəcəyik. Hər bir maşın, ehtimal ki, birdən çox Apache nümunəsini işlədə bilər. Bunların hamısı birlikdə "kainat" hesab olunur və müəyyən fərziyyələrlə bu kainatda, hər bir istək üçün, qrupdakı maşınlar arasında geniş əlaqə olmadan, unikal identifikatorlar yarada biləcəyimizi göstərəcəyik.

Klasterinizdəki maşınlar bu tələblərə cavab verməlidir. (Yalnız bir maşınınız olsa belə, saatını NTP ilə sinxronizasiya etməlisiniz.)

  • Maşınların vaxtları NTP və ya digər şəbəkə vaxtı protokolu ilə sinxronlaşdırılır.
  • Maşınların host adlarının hamısı fərqlidir, belə ki, modul host adında bir host adı axtarışı edə bilər və klasterdəki hər bir maşın üçün fərqli bir IP ünvanı ala bilər.

Əməliyyat sistemi fərziyyələrinə gəldikdə, pidlərin (proses idlərinin) 32 bitə uyğun olduğunu düşünürük. Əməliyyat sistemi bir pid üçün 32 bitdən çox istifadə edərsə, düzəliş əhəmiyyətsizdir, ancaq kodda yerinə yetirilməlidir.

Bu fərziyyələri nəzərə alaraq, bir anda, bütün digər httpd proseslərindən çoxluqdakı hər hansı bir maşında hər hansı bir httpd prosesini müəyyən edə bilərik. Bunun üçün maşının IP ünvanı və httpd prosesinin pidləri kifayətdir. Çox yivli bir MPM istifadə edirsinizsə, httpd prosesi eyni vaxtda birdən çox sorğunu həll edə bilər. Mövzuları müəyyən etmək üçün, Apache httpd -nin daxildə istifadə etdiyi bir mövzu indeksindən istifadə edirik. Beləliklə, istəklər üçün unikal identifikatorlar yaratmaq üçün yalnız zamanla fərqli nöqtələri ayırmaq lazımdır.

Vaxtı ayırmaq üçün Unix zaman damgasını (1 Yanvar 1970 UTC-dən sonra saniyə) və 16 bitlik sayğacdan istifadə edəcəyik. Zaman damgası yalnız bir saniyəlik hissəciklərə malikdir, buna görə sayğac bir saniyə ərzində 65536 -dək dəyəri təmsil etmək üçün istifadə olunur. Dörd (ip_addr, pid, time_stamp, counter) httpd prosesi hər saniyədə 65536 sorğu sadalamaq kifayətdir. Zaman keçdikcə pidlərin təkrar istifadəsi ilə bağlı problemlər var və sayğac bu problemi həll etmək üçün istifadə olunur.

When an httpd child is created, the counter is initialized with ( current microseconds divided by 10 ) modulo 65536 (this formula was chosen to eliminate some variance problems with the low order bits of the microsecond timers on some systems). When a unique identifier is generated, the time stamp used is the time the request arrived at the web server. The counter is incremented every time an identifier is generated (and allowed to roll over).

Nüvə hər bir proses üçün bir pid əmələ gətirir və prosesin davam etməsinə icazə verilir və pidlərin yuvarlanmasına icazə verilir (onlar bir çox Unix-də 16 bitdir, lakin daha yeni sistemlər 32 bitə qədər genişlənmişdir). Vaxt keçdikcə eyni pid yenidən istifadə olunacaq. Eyni saniyədə təkrar istifadə edilmədiyi təqdirdə, dördlüyümüzün bənzərsizliyini pozmaz. Yəni, sistemin bir saniyədə 65536 proses yaratmadığını güman edirik (hətta bəzi Unixesdə 32768 proses ola bilər, amma belə olmayacaq).

Vaxtın nədənsə təkrarlandığını düşünək. Yəni sistemin saatı bərbad vəziyyətdədir və keçmişi yenidən nəzərdən keçirir (və ya çox irəlidədir, düzgün sıfırlanır və sonra gələcək vaxtı yenidən nəzərdən keçirir). Bu vəziyyətdə, pid və vaxt möhürünün təkrar istifadəsini əldə edə biləcəyimizi asanlıqla göstərə bilərik. Tezgah üçün başlanğıc seçimi, bunun məğlub edilməsinə kömək etmək məqsədi daşıyır. Diqqət yetirin ki, sayğacı işə salmaq üçün təsadüfi bir rəqəm istəyərik, lakin əksər sistemlərdə hazır nömrələr yoxdur ( yəni , rand () istifadə edə bilməzsiniz, çünki generatoru əkmək lazımdır və onu əkə bilməzsiniz. zamanla, çünki vaxt, ən azı bir saniyəlik qətnamə özünü təkrarladı). Bu mükəmməl müdafiə deyil.

Nə yaxşı müdafiədir? Fərz edin ki, maşınlarınızdan biri saniyədə ən çox 500 sorğuya xidmət edir (bu yazıda çox ağlabatan bir sərhəddir, çünki sistemlər ümumiyyətlə statik faylları çıxarmaqla kifayətlənmir). Bunu etmək üçün, eyni vaxtda müştərilərinizin sayından asılı olaraq bir neçə uşaq lazımdır. Ancaq bədbin olacağıq və fərz edək ki, tək bir uşaq saniyədə 500 sorğuya xidmət edə bilər. 500 mümkün iki ardıcıllıqla üst -üstə düşən 1000 mümkün başlanğıc sayğac dəyəri var. Beləliklə, vaxt (bir saniyədə) özünü təkrar edərsə, bu uşaq bir sayğac dəyərini təkrarlayacaq və unikallıq pozulacaq. Bu çox bədbin bir nümunə idi və real dünya dəyərləri ilə daha az ehtimal olunur. Sisteminiz hələ də baş vermə ehtimalı yüksəkdirsə,sonra bəlkə də saytı 32 bit etməlisiniz (kodu düzəldərək).

Yaz gün işığına qənaət edərkən saatın "geriyə" qoyulması sizi narahat edə bilər. Ancaq bu problem deyil, çünki burada istifadə olunan vaxtlar "həmişə" irəli gedən UTC -dir. Unutmayın ki, x86 əsaslı Unixes bunun doğru olması üçün müvafiq konfiqurasiyaya ehtiyac duya bilər - anakart saatının UTC -də olduğunu və uyğun şəkildə kompensasiya ediləcəyini düşünmək üçün konfiqurasiya edilməlidir. Ancaq yenə də, NTP ilə işləsəniz, yenidən başladıqdan qısa müddət sonra UTC vaxtınız düzgün olacaq.

UNIQUE_ID mühit dəyişəni 144 bitlik (32 bit IP ünvanı, 32 bit pid, 32 bit vaxt möhürü, 16 bit sayğac, 32 bit mövzu indeksi) əlifbadan istifadə edərək [A-Za-z0-9@ -] 24 simvol istehsal edən MIME base64 kodlaşdırmasına bənzər bir şəkildə. MIME base64 əlifbası əslində [A-Za-z0-9 + /] olsa da + və / URL-lərdə xüsusi olaraq kodlanmalıdır ki, bu da onları daha az arzuolunandır. Bütün dəyərlər şəbəkə bayt sıralamasında kodlanır, beləliklə kodlaşdırma fərqli bayt sifarişinin memarlıqları arasında müqayisə edilə bilər. Kodlamanın həqiqi sifarişi: vaxt möhürü, IP ünvanı, pid, sayğac. Bu sifarişin bir məqsədi var, ancaq tətbiqlərin kodlamanı parçalamaması lazım olduğunu vurğulamaq lazımdır. Tətbiqlər bütün kodlanmış UNIQUE_ID -ə qeyri -şəffaf bir işarə kimi baxmalıdır,yalnız bərabərlik üçün digər UNIQUE_ID -lərlə müqayisə edilə bilər.

Sifariş, UNIQUE_ID -lərin mövcud verilənlər bazası ilə toqquşmadan narahat olmayaraq gələcəkdə kodlaşdırmanı dəyişdirmək mümkün olacaq şəkildə seçildi. Yeni kodlaşdırmalar da zaman möhürünü ilk element olaraq saxlamalı və əks halda eyni əlifbadan və bit uzunluğundan istifadə edə bilər. Zaman damgaları əslində artan bir ardıcıllıq olduğundan , çoxluqdakı bütün maşınların hər hansı bir istəyi yerinə yetirməyi dayandırması və köhnə kodlaşdırma formatını istifadə etməməsi üçün bir bayrağa sahib olmaq kifayətdir . Daha sonra sorğuları davam etdirə və yeni kodlamaların verilməsinə başlaya bilərlər.

Bu problemin nisbətən portativ bir həll olduğuna inanırıq. Yaradılan identifikatorlar əslində sonsuz bir həyat müddətinə malikdir, çünki gələcək identifikatorlar tələb olunduğu kimi daha uzun müddətə edilə bilər. Əslində, çoxluqdakı maşınlar arasında heç bir əlaqə tələb olunmur (yalnız NTP sinxronizasiyası tələb olunur, bu da aşağıdır) və httpd prosesləri arasında heç bir əlaqə tələb olunmur (ünsiyyət nüvənin təyin etdiyi pid dəyərində gizlidir). Çox spesifik vəziyyətlərdə identifikator qısaldıla bilər, lakin daha çox məlumatın qəbul edilməsinə ehtiyac var (məsələn, 32 bitlik IP ünvanı hər hansı bir sayt üçün həddindən artıqdır, lakin onun üçün portativ daha qısa bir əvəz yoxdur).