Devlime umumiy domeni / Inter-MS domeni uchun namunaviy dizayn

Devlime umumiy domeni / Inter-MS domeni uchun namunaviy dizayn

1. Fon

Scrum'ning AgileProject’i (sprint ijro birligi) haqidagi ma’lumotlarni Devlime’ning Prism tizimida Crewit’ning Project’i (shartnoma va mehnat sarfini boshqarish) bilan birga ko‘rsatish uchun ikki domen o‘rtasida aloqa o‘rnatish talabi yuzaga keldi. Bundan tashqari, ikki domen o‘rtasidagi aloqani o‘rnatish uchun Crewit’ning mehnat sarfi haqidagi ma’lumotlari ekranda ko‘rsatilishi kerak edi.

Shunga ko‘ra, Shared API deb nomlangan yangi qatlam qo‘shildi. Ushbu qatlam ikki MS domenlari o‘rtasidagi aloqalarni belgilash uchun ishlatildi va bir MS domeni boshqa MS tomonidan ham ishlatilishi uchun umumiy domen sifatida loyihalashtirildi.

Ushbu hujjat yuqorida tavsiflangan holat asosida tashkil etilgan umumiy domenlar va MSlar o‘rtasidagi domen havolalarini loyihalash tamoyillari hamda usullarini taqdim etish orqali kelgusidagi umumiy domen dizayni uchun qo‘llanma bo‘lib xizmat qiladi.

2. Dizayn qarorini qabul qilish mezonlari

MSlar o‘rtasidagi domenlarni moslashtirish kerak bo‘lgan holatlar quyida Shared API mavjudligi va Shared API mavjudligihamda unumdorlik muammolari yuzaga kelishiga ko‘ra uch turga ajratiladi va har bir tur turlicha dizayn yondashuvini talab qiladi. Haqiqiy dizaynni boshlashdan oldin, avvalo qaysi holatga tegishli ekanini aniqlang.

Ssenariy

Shartlar

Dizayn yondashuvi

1

Shared API mavjud bo‘lmaganda va ikki MS domeni o‘rtasida moslashtirish talab etilganda

Havola beruvchi MS manba MS domenini entity shaklida bevosita saqlaydi

2

Shared API mavjud bo‘lganda va sezilarli unumdorlik muammolari yuzaga kelmaganda

Havola beruvchi MS faqat manba ID’sini saqlaydi va zarur bo‘lganda Shared API orqali uni ID bo‘yicha qidiradi

3

Shared API mavjud bo‘lganda va unumdorlik muammolari (N+1, takroriy chaqiruvlar va hokazo) yuzaga kelganda

Havola beruvchi MS faqat ko‘rsatish uchun mo‘ljallangan VO’ni saqlaydi va uni paketli qayta ishlash, kechiktirilgan qayta ishlash yoki biznes mantiqi orqali yangilaydi

3. Dizayn tamoyillari

Umumiy domen dizayni

MSlar o‘rtasidagi domen havolalari dizayni

Misol

Shared API’dagi umumiy domen entity’si

scrum AgileProject saqlaydigan crewit Project’iga havola

Joylashuvi

Alohida Shared API servisi ichida

Havola beruvchi servis (scrum) domeni ichida

Mohiyati

Manba MS domenining proyeksiyasi

Manbadan alohida mustaqil obyekt yoki manba MS domenining ID’si

3-1. Umumiy domen dizayni tamoyillari

Umumiy domen — bu boshqa MSlar bilan ulashish maqsadida mavjud bo‘lgan manba MS domenlari orasidagi domen. U quyidagi tamoyillarga amal qiladi.

1. Manba bilan bir xil hayotiy siklga ega bo‘lishi

Manba MS’da ma’lumotlar saqlanganda yoki o‘zgartirilganda, umumiy domen ham event orqali yangilanadi. Boshqacha aytganda, u manba bilan bir xil hayotiy siklga ega. O‘zgarishlarni qo‘llash uchun manba MS’dagi mavjud DataEvent → ProjectionHandler hook’iga trigger o‘rnatiladi.

2. Faqat ulashish uchun zarur maydonlarni o‘z ichiga olishi

Manba maydonlarining barchasini takrorlamang. Manba MS ichidagi ichki boshqaruv uchun ishlatiladigan maydonlarni chiqarib tashlang va faqat boshqa MSlarga amalda kerak bo‘ladigan maydonlarni kiriting.

3. Nomlar uchun manba terminologiyasidan aynanligicha foydalanmaslik

Manba MS entity nomini aynanligicha ko‘chirish uning ma’nosini boshqa MS nuqtayi nazaridan noaniq qilib qo‘yishi mumkin. Nomni obyektning haqiqiy asosiy atributlarini aks ettiradigan tarzda qayta belgilang.

3-2. MSlar o‘rtasidagi domen havolalari tamoyillari

Bu bir MS’dagi domen boshqa MS’dan (yoki umumiy domendan) olingan ma’lumotlarga havola berish orqali aloqani ifodalashi kerak bo‘lganda qo‘llanadi. Muayyan havola berish usuli ssenariyga qarab farq qiladi, shuning uchun ssenariylar quyida alohida tushuntiriladi.

Quyidagi ikki tamoyil uchala ssenariyning barchasiga umumiy tarzda qo‘llanadi.

1. Uzatilgan ma’lumotlarni manbadan alohida obyekt sifatida ko‘rish

Havola beruvchi tomon saqlaydigan ma’lumotlar (entity yoki VO) manba maydonlarining nusxasi emas; u havola beruvchi domen uchun amalda zarur bo‘lgan atributlarnigina o‘z ichiga olgan, mustaqil ravishda aniqlangan obyekt hisoblanadi.

2. Nomlarni havola beruvchi domen nuqtayi nazaridan qayta belgilash

Uni asl atamani o‘zgarishsiz ishlatish o‘rniga, havola qiluvchi domen nuqtayi nazaridan ushbu ma’lumot aslida nimani anglatishini aks ettiradigan tarzda nomlang.

3-2-1. 1-scenario — Umumiy API mavjud emas: Entityga bevosita egalik qilish

Ikki MS domenini umumiy API hali mavjud bo‘lmagan holatda bog‘lash kerak bo‘lsa, havola qiluvchi MS manba domeni haqidagi ma’lumotlarga o‘z entitysi ichida bevosita egalik qiladi. Amalda, umumiy domen roli havola qiluvchi MS ichida bajariladi.

1. Umumiy domendagi kabi, sourceSystem/sourceKey yordamida kuzatuvchanlikni ta’minlang.

2. Iloji bo‘lsa, manba eventlarini qabul qilib, mos ravishda yangilang; buning iloji bo‘lmasa, qo‘lda/batch orqali yangilash yo‘lini yarating.

3. Havola qiluvchi MSlar soni bittadan oshsa, har biri alohida ravishda shunga o‘xshash nusxani yaratadi va boshqaradi, bu esa boshqaruvni qiyinlashtiradi. Shu paytda umumiy API yarating va uni masshtablanuvchan qilib tuzing.

3-2-2. 2-scenario — Umumiy API mavjud, unumdorlik muammolari yo‘q: ID orqali havola (standart)

Umumiy API mavjud bo‘lsa va takroriy so‘rovlar sababli yuzaga keladigan unumdorlik muammolari aniqlanmagan bo‘lsa, havola qiluvchi MS faqat IDni saqlaydi va ma’lumotlarni olish zarur bo‘lgan har safar umumiy APIga real vaqt rejimida murojaat qiladi.

1. VO maydonlariga ega bo‘lish o‘rniga, havola qilinayotgan domenning havola kaliti (ID)ni o‘z ichiga olgan bitta maydonni saqlang.

2. Ma’lumotni olish vaqtida umumiy APIga real vaqt rejimida murojaat qiling va havola kaliti orqali bog‘langan domenni oling.

3-2-3. 3-scenario — Umumiy API mavjud, unumdorlik muammolari yuzaga keladi: VO (istisno)

Agar 2-scenario asosida ishlash jarayonida takroriy so‘rovlar sababli yuzaga keladigan unumdorlik muammolari amalda tasdiqlansa, havola qiluvchi MS faqat ko‘rsatish uchun mo‘ljallangan VOni saqlaydi va uni batch orqali qayta sinxronlash yoki lazy update yordamida to‘ldiradi.

1. Sinxronlashga urinishlarning o‘zidan saqlaning

Real vaqt rejimida majburiy sinxronlash (manba o‘zgargan har safar darhol yangilash) qo‘llanmaydi.

2. Izchillik muammolarini biznes mantiqi orqali hal qiling

VOdan faqat ko‘rsatish uchun foydalaning. Haqiqiy biznes qarorlarini talab qiladigan mantiqda VO qiymatlariga ishonmang; buning o‘rniga havola kalitidan foydalanib, manbaga (yoki umumiy domenga) qayta so‘rov yuboring.

3. Ma’lumotning yangiligini syncedAt orqali ko‘rinadigan qiling

Yangiligini tekshirish mumkin bo‘lishi uchun ma’lumot bilan birga oxirgi sinxronlash vaqtini ham ko‘rsating.

Yangilash usuli

Usul

Tavsif

Xususiyatlari

Batch orqali qayta sinxronlash

Scheduler VOni yangilash uchun ma’lumotlarni davriy ravishda qayta so‘raydi (masalan, kuniga bir marta).

Qo‘shimcha infratuzilmani minimallashtiradi; izchillikdagi kechikishlar batch intervali davomiyligigacha muntazam yuz berishini odatiy holat sifatida qabul qiladi.

Lazy update

scrum AgileProject bilan ishlaganda (masalan, yaratish yoki o‘zgartirish vaqtida), agar syncedAt eskirgan bo‘lsa, shu paytda uni qayta so‘rang.

Batch infratuzilmasi talab qilinmaydi. Biroq ma’lumotga ma’lum vaqt davomida murojaat qilinmasa, u cheksiz muddat eskirgan holatda qolishi mumkin.

Faqat yuqoridagi ikkita usuldan foydalanish majburiy emas. Agar izchillik muammolarini hal qilishning biznesga asoslangan boshqa usuli mavjud bo‘lsa, undan foydalanish mumkin.

4. Dizayn namunasi (2-scenario)

① Manba (crewit Project)

public class Project extends StageEntity {
    ...
    private String code;                        // 코드
    private LangStrings langNames;               // 이름
    private LangStrings langDescription;         // 설명
    private LangStrings langCustomers;           // 고객사
    private LangStrings langLocations;           // 위치
    private Member manager;                      // PM
    private ProjectStatus projectStatus;         // 프로젝트상태
    private ProjectPeriod projectPeriod;         // 프로젝트기간
    private String skillSet;                     // 기술세트
    private LangStrings langVendors;              // 협력업체
    private LangStrings langRiskNotes;            // 리스크
    private double budget;                        // 예산, ex, 21억5천만원
    private int totalEffort;                      // 총공수, 230 M/M
    private boolean active;
    transient List<ProjectManMonthPlan> projectManMonthPlans;   // 구성원별
    transient List<ProjectMonthPlan> projectMonthPlans;         // 월별
    transient List<ManOutput> manOutputs;
    transient List<ManRatio> manRatios;
    transient List<ManOutputMonthSum> manOutputMonthSums;
    transient List<ManRatioMonthSum> manRatioMonthSums;
    ...
}

② Umumiy domen (umumiy APIning Staffing Projecti — Projectning Projectioni)

public class StaffingProject extends StageEntity {
    ...
    private String id;                    // PK
    private String sourceSystem;          // 원본 MS 또는 도메인 추적용
    private String sourceKey;             // crewit Project의 Id
    private String code;                  // 코드
    private LangStrings name;             // 이름
    private LangStrings description;      // 설명
    private LangStrings customerNames;    // 고객사
    private ProjectStatus status;         // 프로젝트상태
    private ProjectPeriod projectPeriod;  // 프로젝트기간
    private Member manager;               // 담당자
    private double budget;                // 예산, ex, 21억5천만원
    private int totalEffort;              // 총공수, 230 M/M
    private boolean active;
    private LocalDateTime syncedAt;       // 마지막 동기화 시각
    ...
}
  • crewit Project saqlanganda yoki o‘zgartirilganda DataEvent/ProjectionHandler hook + event orqali yangilang (manba bilan bir xil lifecycle).

  • skillSet/budget/langVendors kabi ichki boshqariladigan maydonlarni chiqarib tashlang.

  • Muhokamaga asosan StaffingProject deb nomlangan, bunda asosiy atribut shartnoma ma’lumotlari emas, balki mehnat sarfi haqidagi ma’lumot hisoblanadi.

  • Oxirgi sinxronlash vaqtini syncedAt orqali boshqaring (kuzatuv maqsadida saqlanadi, chunki hatto umumiy domen ham real vaqt rejimida to‘liq aks ettirishni kafolatlamaydi).

③ Havola qiluvchi servis (scrum AgileProjecti)

public class AgileProject extends StageEntity {
    ...
    private String staffingProjectId;   // StaffingProject 참조키. ID만 보유.
    ...
}
  • AgileProject o‘z maydonlarida crewit/umumiy domen ma’lumotlarini saqlamaydi — u faqat bitta IDga havola qiladi.

  • Ekran ko‘rsatilganda har safar umumiy APIga murojaat qiling va ma’lumotlarni oling.

5. Havola (3-scenario) — Unumdorlik muammolariga tayyorgarlik

Agar kelajakda so‘rovlar chastotasi oshib, unumdorlik muammolari tasdiqlansa, quyida ko‘rsatilganidek, faqat ko‘rsatish uchun mo‘ljallangan VOni o‘z ichiga olgan usulga o‘tishni ko‘rib chiqing. Hozircha u qo‘llanmaydi va faqat ma’lumot uchun taqdim etilgan.

public class StaffingProject implements ValueObject {
    ...
    private String staffingProjectId;    // staffing project id
    private LangStrings name;            // 이름
    private LangStrings customerNames;   // 고객사
    private ProjectStatus status;        // 프로젝트상태
    private ProjectPeriod projectPeriod; // 프로젝트기간
    private Member manager;              // 담당자
    private double budget;               // 예산, ex, 21억5천만원
    private int totalEffort;             // 총공수, 230 M/M
    private LocalDateTime syncedAt;      // 마지막 동기화 시각
    ...
}
  • Uni AgileProject tarkibiga kiriting va munosabatni belgilang.

  • Uni crewit nusxasi sifatida emas, scrumga tegishli alohida va mustaqil obyekt sifatida boshqaring.

  • Manbani real vaqt rejimida aks ettirmang; uni batch orqali qayta sinxronlash, lazy update (yoki boshqa biznes mantiqi) orqali to‘ldiring.

  • O‘tish nuqtasini faqat amaldagi so‘rovlar namunalarida unumdorlik muammolari tasdiqlangandan keyin bilan cheklang.

Bignow

Site footer