మేము Yandex.Cloudలో 10 ఈవెంట్‌లను అంగీకరిస్తాము. 000 వ భాగము

అందరికీ నమస్కారం, మిత్రులారా!

* ఈ కథనం REBRAIN & Yandex.Cloud ఓపెన్ వర్క్‌షాప్ ఆధారంగా రూపొందించబడింది, మీరు వీడియోను చూడాలనుకుంటే, మీరు దానిని ఈ లింక్‌లో కనుగొనవచ్చు - https://youtu.be/cZLezUm0ekE

Yandex.Cloud ప్రత్యక్ష ప్రసారాన్ని ప్రయత్నించడానికి మాకు ఇటీవల అవకాశం లభించింది. మేము సుదీర్ఘంగా మరియు గట్టిగా పరిశోధించాలనుకుంటున్నాము కాబట్టి, క్లౌడ్ బేస్‌తో సరళమైన WordPress బ్లాగును ప్రారంభించాలనే ఆలోచనను మేము వెంటనే విరమించుకున్నాము - ఇది చాలా బోరింగ్. కొంత ఆలోచించిన తర్వాత, సమీప రియల్ టైమ్ మోడ్‌లో ఈవెంట్‌లను స్వీకరించడం మరియు విశ్లేషించడం కోసం ప్రొడక్షన్ సర్వీస్ ఆర్కిటెక్చర్‌కు సమానమైనదాన్ని అమలు చేయాలని మేము నిర్ణయించుకున్నాము.

ఆన్‌లైన్ (మరియు మాత్రమే కాదు) వ్యాపారాలలో ఎక్కువ భాగం తమ వినియోగదారులు మరియు వారి చర్యల గురించి ఏదో ఒకవిధంగా పర్వతారోహణ సమాచారాన్ని సేకరిస్తారని నేను ఖచ్చితంగా అనుకుంటున్నాను. కనిష్టంగా, నిర్దిష్ట నిర్ణయాలు తీసుకోవడానికి ఇది అవసరం - ఉదాహరణకు, మీరు ఆన్‌లైన్ గేమ్‌ను నిర్వహించినట్లయితే, వినియోగదారులు ఏ స్థాయిలో తరచుగా చిక్కుకుపోతారో మరియు మీ బొమ్మను తొలగించే గణాంకాలను మీరు చూడవచ్చు. లేదా వినియోగదారులు దేనినీ కొనుగోలు చేయకుండానే మీ సైట్‌ను ఎందుకు వదిలేస్తున్నారు (హలో, Yandex.Metrica).

కాబట్టి, మా కథనం: మేము గోలాంగ్‌లో అప్లికేషన్‌ను ఎలా వ్రాసాము, కాఫ్కా vs రాబిట్‌ఎమ్‌క్యూ vs yqs పరీక్షించాము, క్లిక్‌హౌస్ క్లస్టర్‌లో డేటా స్ట్రీమింగ్‌ను వ్రాసాము మరియు యాండెక్స్ డేటాలెన్స్‌ని ఉపయోగించి డేటాను దృశ్యమానం చేసాము. సహజంగానే, ఇవన్నీ డాకర్, టెర్రాఫార్మ్, గిట్‌లాబ్ సిఐ మరియు ప్రోమేథియస్ రూపంలో మౌలిక సదుపాయాలతో ఆనందాన్ని పొందాయి. వెళ్దాం!

మేము ఒక సిట్టింగ్‌లో ప్రతిదీ కాన్ఫిగర్ చేయలేమని నేను వెంటనే రిజర్వేషన్ చేయాలనుకుంటున్నాను - దీని కోసం మనకు సిరీస్‌లో అనేక కథనాలు అవసరం. నిర్మాణం గురించి కొంచెం:

పార్ట్ 1 (మీరు చదువుతున్నారు). మేము పరిష్కారం యొక్క లక్షణాలు మరియు నిర్మాణాన్ని నిర్ణయిస్తాము మరియు గోలాంగ్‌లో అప్లికేషన్‌ను కూడా వ్రాస్తాము.
పార్ట్ 2. మేము మా అప్లికేషన్‌ను ఉత్పత్తికి విడుదల చేస్తాము, దానిని కొలవగలిగేలా చేస్తాము మరియు లోడ్‌ను పరీక్షిస్తాము.
పార్ట్ 3. మనం సందేశాలను ఫైల్‌లలో కాకుండా బఫర్‌లో ఎందుకు నిల్వ చేయాలి మరియు కాఫ్కా, రాబిట్‌ఎమ్‌క్యూ మరియు యాండెక్స్ క్యూ సేవను సరిపోల్చడానికి ఎందుకు ప్రయత్నిద్దాం.
పార్ట్ 4 మేము క్లిక్‌హౌస్ క్లస్టర్‌ని అమలు చేస్తాము, అక్కడ ఉన్న బఫర్ నుండి డేటాను బదిలీ చేయడానికి స్ట్రీమింగ్ సేవను వ్రాస్తాము మరియు డేటాలెన్స్‌లో విజువలైజేషన్‌ని సెటప్ చేస్తాము.
పార్ట్ 5 మొత్తం ఇన్‌ఫ్రాస్ట్రక్చర్‌ను సరైన ఆకృతిలోకి తీసుకువద్దాం - గిట్‌లాబ్ సిఐని ఉపయోగించి సిఐ/సిడిని సెటప్ చేయండి, ప్రోమేథియస్ మరియు కాన్సుల్‌ని ఉపయోగించి మానిటరింగ్ మరియు సర్వీస్ డిస్కవరీని కనెక్ట్ చేయండి.

TK

ముందుగా, రిఫరెన్స్ నిబంధనలను రూపొందిద్దాం - ఫలితంగా మనం సరిగ్గా ఏమి పొందాలనుకుంటున్నాము.

  1. మేము ఈవెంట్స్.
  2. ఈవెంట్‌లు వంటి సాధారణ json: {“ఈవెంట్”: “వ్యూ”, “os”: “linux”, “browser”: “chrome”}. చివరి దశలో మేము కొంచెం ఎక్కువ ఫీల్డ్‌లను జోడిస్తాము, కానీ ఇది పెద్ద పాత్ర పోషించదు. మీరు కోరుకుంటే, మీరు ప్రోటోబఫ్‌కి మారవచ్చు.
  3. సేవ తప్పనిసరిగా సెకనుకు 10 ఈవెంట్‌లను ప్రాసెస్ చేయగలగాలి.
  4. మా పరిష్కారానికి కొత్త ఉదాహరణలను జోడించడం ద్వారా క్షితిజ సమాంతరంగా స్కేల్ చేయడం సాధ్యమవుతుంది. క్లయింట్ అభ్యర్థనల కోసం జాప్యాన్ని తగ్గించడానికి మేము ముందు భాగాన్ని వేర్వేరు జియోలొకేషన్‌లకు తరలించగలిగితే బాగుంటుంది.
  5. తప్పు సహనం. పరిష్కారం తగినంత స్థిరంగా ఉండాలి మరియు ఏదైనా భాగాల పతనం (నిర్దిష్ట సంఖ్య వరకు, వాస్తవానికి) మనుగడ సాగించగలగాలి.

నిర్మాణం

సాధారణంగా, ఈ రకమైన పని కోసం, సమర్థవంతమైన స్కేలింగ్‌ను అనుమతించే శాస్త్రీయ నిర్మాణాలు చాలా కాలంగా కనుగొనబడ్డాయి. ఫిగర్ మా పరిష్కారం యొక్క ఉదాహరణను చూపుతుంది.

మేము Yandex.Cloudలో 10 ఈవెంట్‌లను అంగీకరిస్తాము. 000 వ భాగము

కాబట్టి మన దగ్గర ఉన్నది:

1. ఎడమవైపున వివిధ ఈవెంట్‌లను రూపొందించే మా పరికరాలు ఉన్నాయి, అది ప్లేయర్‌లు స్మార్ట్‌ఫోన్‌లో బొమ్మలో స్థాయిని పూర్తి చేయడం లేదా సాధారణ బ్రౌజర్ ద్వారా ఆన్‌లైన్ స్టోర్‌లో ఆర్డర్‌ను సృష్టించడం. ఒక ఈవెంట్, స్పెసిఫికేషన్‌లో పేర్కొన్న విధంగా, మా ఎండ్‌పాయింట్‌కి పంపబడే సాధారణ json - events.kis.im.

2. మొదటి రెండు సర్వర్లు సాధారణ బ్యాలెన్సర్‌లు, వాటి ప్రధాన పనులు:

  • నిరంతరం అందుబాటులో ఉండండి. దీన్ని చేయడానికి, మీరు ఉదాహరణకు కీపాలివ్‌ని ఉపయోగించవచ్చు, ఇది సమస్యల విషయంలో నోడ్‌ల మధ్య వర్చువల్ IPని మారుస్తుంది.
  • TLSని ముగించండి. అవును, మేము వాటిపై TLSని రద్దు చేస్తాము. ముందుగా, మా పరిష్కారం సాంకేతిక నిర్దేశాలకు అనుగుణంగా ఉంటుంది మరియు రెండవది, మా బ్యాకెండ్ సర్వర్‌ల నుండి ఎన్‌క్రిప్టెడ్ కనెక్షన్‌ని స్థాపించే భారం నుండి ఉపశమనం పొందడం కోసం.
  • అందుబాటులో ఉన్న బ్యాకెండ్ సర్వర్‌లకు ఇన్‌కమింగ్ అభ్యర్థనలను బ్యాలెన్స్ చేయండి. ఇక్కడ కీలక పదం అందుబాటులో ఉంది. దీని ఆధారంగా, లోడ్ బ్యాలెన్సర్‌లు తప్పనిసరిగా మా సర్వర్‌లను అప్లికేషన్‌లతో పర్యవేక్షించగలరని మరియు విఫలమైన నోడ్‌లకు ట్రాఫిక్‌ను బ్యాలెన్స్ చేయడాన్ని ఆపగలరని మేము అర్థం చేసుకున్నాము.

3. బ్యాలెన్సర్‌ల తర్వాత, మా వద్ద అప్లికేషన్ సర్వర్‌లు చాలా సరళమైన అప్లికేషన్‌ను అమలు చేస్తున్నాయి. ఇది HTTP ద్వారా ఇన్‌కమింగ్ అభ్యర్థనలను ఆమోదించగలగాలి, పంపిన jsonని ధృవీకరించాలి మరియు డేటాను బఫర్‌లో ఉంచాలి.

4. రేఖాచిత్రం కాఫ్కాను బఫర్‌గా చూపిస్తుంది, అయితే, ఇతర సారూప్య సేవలను ఈ స్థాయిలో ఉపయోగించవచ్చు. మేము మూడవ వ్యాసంలో కాఫ్కా, rabbitmq మరియు yqలను పోల్చి చూస్తాము.

5. మా ఆర్కిటెక్చర్ యొక్క చివరి పాయింట్ క్లిక్‌హౌస్ - ఇది పెద్ద మొత్తంలో డేటాను నిల్వ చేయడానికి మరియు ప్రాసెస్ చేయడానికి మిమ్మల్ని అనుమతించే కాలమ్ డేటాబేస్. ఈ స్థాయిలో, మేము బఫర్ నుండి స్టోరేజ్ సిస్టమ్‌కు డేటాను బదిలీ చేయాలి (దీనిపై మరింత వ్యాసం 4లో).

ఈ డిజైన్ ప్రతి పొరను స్వతంత్రంగా అడ్డంగా స్కేల్ చేయడానికి అనుమతిస్తుంది. బ్యాకెండ్ సర్వర్‌లు తట్టుకోలేవు - ఇంకొక విషయాన్ని జోడిద్దాం - అన్నింటికంటే, అవి స్థితిలేని అప్లికేషన్‌లు మరియు అందువల్ల, ఇది స్వయంచాలకంగా కూడా చేయవచ్చు. కాఫ్కా-శైలి బఫర్ పని చేయదు-మరిన్ని సర్వర్‌లను జోడించి, మా అంశంలోని కొన్ని విభజనలను వాటికి బదిలీ చేద్దాం. క్లిక్‌హౌస్ దీన్ని నిర్వహించదు - ఇది అసాధ్యం :) వాస్తవానికి, మేము సర్వర్‌లను కూడా కనెక్ట్ చేస్తాము మరియు డేటాను ముక్కలు చేస్తాము.

మార్గం ద్వారా, మీరు వివిధ జియోలొకేషన్లలో మా సాంకేతిక లక్షణాలు మరియు స్కేల్ యొక్క ఐచ్ఛిక భాగాన్ని అమలు చేయాలనుకుంటే, అంతకన్నా సరళమైనది ఏదీ లేదు:

మేము Yandex.Cloudలో 10 ఈవెంట్‌లను అంగీకరిస్తాము. 000 వ భాగము

ప్రతి జియోలొకేషన్‌లో మేము అప్లికేషన్ మరియు కాఫ్కాతో లోడ్ బ్యాలెన్సర్‌ని అమలు చేస్తాము. సాధారణంగా, 2 అప్లికేషన్ సర్వర్లు, 3 కాఫ్కా నోడ్‌లు మరియు క్లౌడ్ బ్యాలెన్సర్, ఉదాహరణకు, క్లౌడ్‌ఫ్లేర్ సరిపోతాయి, ఇది క్లయింట్ యొక్క సోర్స్ IP చిరునామా ఆధారంగా జియోలొకేషన్ ద్వారా అప్లికేషన్ నోడ్‌లు మరియు బ్యాలెన్స్ అభ్యర్థనల లభ్యతను తనిఖీ చేస్తుంది. అందువలన, ఒక అమెరికన్ క్లయింట్ పంపిన డేటా అమెరికన్ సర్వర్‌లపైకి వస్తుంది. మరియు ఆఫ్రికా నుండి డేటా ఆఫ్రికన్‌లో ఉంది.

అప్పుడు ప్రతిదీ చాలా సులభం - మేము కాఫ్కా సెట్ నుండి మిర్రర్ సాధనాన్ని ఉపయోగిస్తాము మరియు రష్యాలో ఉన్న మా సెంట్రల్ డేటా సెంటర్‌కు అన్ని స్థానాల నుండి మొత్తం డేటాను కాపీ చేస్తాము. అంతర్గతంగా, మేము డేటాను అన్వయించి, తదుపరి విజువలైజేషన్ కోసం క్లిక్‌హౌస్‌లో రికార్డ్ చేస్తాము.

కాబట్టి, మేము నిర్మాణాన్ని క్రమబద్ధీకరించాము - Yandex.Cloudని షేక్ చేయడం ప్రారంభిద్దాం!

అప్లికేషన్ రాయడం

క్లౌడ్‌కు ముందు, ఇన్‌కమింగ్ ఈవెంట్‌లను ప్రాసెస్ చేయడానికి మీరు ఇంకా కొంచెం ఓపికగా ఉండాలి మరియు చాలా సులభమైన సేవను వ్రాయాలి. మేము గోలాంగ్‌ని ఉపయోగిస్తాము ఎందుకంటే ఇది నెట్‌వర్క్ అప్లికేషన్‌లను వ్రాయడానికి ఒక భాషగా బాగా నిరూపించబడింది.

ఒక గంట గడిపిన తర్వాత (బహుశా కొన్ని గంటలు), మేము ఇలాంటివి పొందుతాము: https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/main.go.

నేను ఇక్కడ గమనించదలిచిన ప్రధాన అంశాలు ఏమిటి:

1. అప్లికేషన్‌ను ప్రారంభించేటప్పుడు, మీరు రెండు ఫ్లాగ్‌లను పేర్కొనవచ్చు. మేము ఇన్‌కమింగ్ http అభ్యర్థనలను (-addr) వినే పోర్ట్‌కు ఒకరు బాధ్యత వహిస్తారు. రెండవది కాఫ్కా సర్వర్ చిరునామాకు సంబంధించినది, ఇక్కడ మేము మా ఈవెంట్‌లను రికార్డ్ చేస్తాము (-కాఫ్కా):

addr     = flag.String("addr", ":8080", "TCP address to listen to")
kafka    = flag.String("kafka", "127.0.0.1:9092", "Kafka endpoints”)

2. అప్లికేషన్ సరమ లైబ్రరీని ఉపయోగిస్తుంది ([] github.com/Shopify/saram) కాఫ్కా క్లస్టర్‌కు సందేశాలను పంపడానికి. మేము వెంటనే గరిష్ట ప్రాసెసింగ్ వేగంతో సెట్టింగులను సెట్ చేసాము:

config := sarama.NewConfig()
config.Producer.RequiredAcks = sarama.WaitForLocal
config.Producer.Compression = sarama.CompressionSnappy
config.Producer.Return.Successes = true

3. మా అప్లికేషన్‌లో అంతర్నిర్మిత ప్రోమేథియస్ క్లయింట్ కూడా ఉంది, ఇది వివిధ మెట్రిక్‌లను సేకరిస్తుంది, అవి:

  • మా దరఖాస్తుకు అభ్యర్థనల సంఖ్య;
  • అభ్యర్థనను అమలు చేస్తున్నప్పుడు లోపాల సంఖ్య (పోస్ట్ అభ్యర్థనను చదవడం అసాధ్యం, విరిగిన json, కాఫ్కాకు వ్రాయడం అసాధ్యం);
  • క్లయింట్ నుండి ఒక అభ్యర్థన కోసం ప్రాసెసింగ్ సమయం, కాఫ్కాకు సందేశం వ్రాసే సమయంతో సహా.

4. మా అప్లికేషన్ ప్రాసెస్ చేసే మూడు ముగింపు పాయింట్లు:

  • / స్థితి - మనం సజీవంగా ఉన్నామని చూపించడానికి సరే అని తిరిగి ఇవ్వండి. మీరు కాఫ్కా క్లస్టర్ లభ్యత వంటి కొన్ని తనిఖీలను జోడించవచ్చు.
  • /మెట్రిక్స్ - ఈ url ప్రకారం, ప్రోమేథియస్ క్లయింట్ తాను సేకరించిన కొలమానాలను తిరిగి ఇస్తుంది.
  • /post అనేది json లోపల ఉన్న POST అభ్యర్థనలు పంపబడే ప్రధాన ముగింపు స్థానం. మా అప్లికేషన్ చెల్లుబాటు కోసం jsonని తనిఖీ చేస్తుంది మరియు ప్రతిదీ సరిగ్గా ఉంటే, అది కాఫ్కా క్లస్టర్‌కు డేటాను వ్రాస్తుంది.

కోడ్ పరిపూర్ణంగా లేదని నేను రిజర్వేషన్ చేస్తాను - అది పూర్తి చేయగలదు (మరియు తప్పక!). ఉదాహరణకు, మీరు అంతర్నిర్మిత నెట్/httpని ఉపయోగించడం ఆపివేసి, వేగవంతమైన fasthttpకి మారవచ్చు. లేదా మీరు json చెల్లుబాటు తనిఖీని తదుపరి దశకు తరలించడం ద్వారా ప్రాసెసింగ్ సమయం మరియు cpu వనరులను పొందవచ్చు - డేటా బఫర్ నుండి క్లిక్‌హౌస్ క్లస్టర్‌కు బదిలీ చేయబడినప్పుడు.

సమస్య యొక్క అభివృద్ధి వైపు పాటు, మేము వెంటనే మా భవిష్యత్తు మౌలిక సదుపాయాల గురించి ఆలోచించాము మరియు డాకర్ ద్వారా మా అప్లికేషన్‌ను అమలు చేయాలని నిర్ణయించుకున్నాము. అప్లికేషన్‌ను రూపొందించడానికి చివరి డాకర్‌ఫైల్ https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/Dockerfile. సాధారణంగా, ఇది చాలా సులభం, నేను శ్రద్ధ వహించాలనుకుంటున్న ఏకైక అంశం మల్టీస్టేజ్ అసెంబ్లీ, ఇది మా కంటైనర్ యొక్క తుది చిత్రాన్ని తగ్గించడానికి అనుమతిస్తుంది.

క్లౌడ్‌లో మొదటి అడుగులు

అన్నింటిలో మొదటిది, నమోదు చేసుకోండి cloud.yandex.ru. అవసరమైన అన్ని ఫీల్డ్‌లను పూరించిన తర్వాత, మాకు ఖాతా సృష్టించబడుతుంది మరియు క్లౌడ్ సేవలను పరీక్షించడానికి ఉపయోగించే కొంత మొత్తంలో డబ్బు కోసం గ్రాంట్ ఇవ్వబడుతుంది. మీరు మా కథనం నుండి అన్ని దశలను పునరావృతం చేయాలనుకుంటే, ఈ మంజూరు మీకు సరిపోతుంది.

నమోదు చేసిన తర్వాత, మీ కోసం ప్రత్యేక క్లౌడ్ మరియు డిఫాల్ట్ డైరెక్టరీ సృష్టించబడతాయి, దీనిలో మీరు క్లౌడ్ వనరులను సృష్టించడం ప్రారంభించవచ్చు. సాధారణంగా, Yandex.Cloudలో, వనరుల సంబంధం ఇలా కనిపిస్తుంది:

మేము Yandex.Cloudలో 10 ఈవెంట్‌లను అంగీకరిస్తాము. 000 వ భాగము

మీరు ఒక ఖాతా కోసం అనేక క్లౌడ్‌లను సృష్టించవచ్చు. మరియు క్లౌడ్ లోపల, వివిధ కంపెనీ ప్రాజెక్ట్‌ల కోసం వేర్వేరు డైరెక్టరీలను తయారు చేయండి. మీరు దీని గురించి డాక్యుమెంటేషన్‌లో మరింత చదువుకోవచ్చు - https://cloud.yandex.ru/docs/resource-manager/concepts/resources-hierarchy. మార్గం ద్వారా, నేను తరచుగా దానిని టెక్స్ట్‌లో క్రింద సూచిస్తాను. నేను మొదటి నుండి మొత్తం అవస్థాపనను సెటప్ చేసినప్పుడు, డాక్యుమెంటేషన్ నాకు ఒకటి కంటే ఎక్కువసార్లు సహాయపడింది, కాబట్టి దానిని అధ్యయనం చేయమని నేను మీకు సలహా ఇస్తున్నాను.

క్లౌడ్‌ను నిర్వహించడానికి, మీరు వెబ్ ఇంటర్‌ఫేస్ మరియు కన్సోల్ యుటిలిటీ - yc రెండింటినీ ఉపయోగించవచ్చు. ఇన్‌స్టాలేషన్ ఒక ఆదేశంతో నిర్వహించబడుతుంది (Linux మరియు Mac Os కోసం):

curl https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash

మీ అంతర్గత భద్రతా నిపుణుడు ఇంటర్నెట్ నుండి స్క్రిప్ట్‌లను అమలు చేయడం గురించి ఆవేశంగా ఉంటే, మొదట, మీరు స్క్రిప్ట్‌ను తెరిచి చదవవచ్చు మరియు రెండవది, మేము దానిని మా వినియోగదారు కింద - రూట్ హక్కులు లేకుండా అమలు చేస్తాము.

మీరు Windows కోసం క్లయింట్‌ను ఇన్‌స్టాల్ చేయాలనుకుంటే, మీరు సూచనలను ఉపయోగించవచ్చు ఇక్కడ ఆపై అమలు చేయండి yc initదీన్ని పూర్తిగా అనుకూలీకరించడానికి:

vozerov@mba:~ $ yc init
Welcome! This command will take you through the configuration process.
Please go to https://oauth.yandex.ru/authorize?response_type=token&client_id= in order to obtain OAuth token.

Please enter OAuth token:
Please select cloud to use:
 [1] cloud-b1gv67ihgfu3bp (id = b1gv67ihgfu3bpt24o0q)
 [2] fevlake-cloud (id = b1g6bvup3toribomnh30)
Please enter your numeric choice: 2
Your current cloud has been set to 'fevlake-cloud' (id = b1g6bvup3toribomnh30).
Please choose folder to use:
 [1] default (id = b1g5r6h11knotfr8vjp7)
 [2] Create a new folder
Please enter your numeric choice: 1
Your current folder has been set to 'default' (id = b1g5r6h11knotfr8vjp7).
Do you want to configure a default Compute zone? [Y/n]
Which zone do you want to use as a profile default?
 [1] ru-central1-a
 [2] ru-central1-b
 [3] ru-central1-c
 [4] Don't set default zone
Please enter your numeric choice: 1
Your profile default Compute zone has been set to 'ru-central1-a'.
vozerov@mba:~ $

సూత్రప్రాయంగా, ప్రక్రియ చాలా సులభం - ముందుగా మీరు క్లౌడ్‌ను నిర్వహించడానికి ప్రమాణ టోకెన్‌ను పొందాలి, క్లౌడ్ మరియు మీరు ఉపయోగించే ఫోల్డర్‌ను ఎంచుకోండి.

మీరు ఒకే క్లౌడ్‌లో అనేక ఖాతాలు లేదా ఫోల్డర్‌లను కలిగి ఉంటే, మీరు yc config ప్రొఫైల్ సృష్టించి వాటి మధ్య మారడం ద్వారా ప్రత్యేక సెట్టింగ్‌లతో అదనపు ప్రొఫైల్‌లను సృష్టించవచ్చు.

పై పద్ధతులతో పాటు, Yandex.Cloud బృందం చాలా బాగా రాసింది టెర్రాఫార్మ్ కోసం ప్లగిన్ క్లౌడ్ వనరుల నిర్వహణ కోసం. నా వంతుగా, నేను ఒక git రిపోజిటరీని సిద్ధం చేసాను, ఇక్కడ నేను వ్యాసంలో భాగంగా సృష్టించబడే అన్ని వనరులను వివరించాను - https://github.com/rebrainme/yandex-cloud-events/. మాకు మాస్టర్ బ్రాంచ్ పట్ల ఆసక్తి ఉంది, దానిని స్థానికంగా క్లోన్ చేద్దాం:


vozerov@mba:~ $ git clone https://github.com/rebrainme/yandex-cloud-events/ events
Cloning into 'events'...
remote: Enumerating objects: 100, done.
remote: Counting objects: 100% (100/100), done.
remote: Compressing objects: 100% (68/68), done.
remote: Total 100 (delta 37), reused 89 (delta 26), pack-reused 0
Receiving objects: 100% (100/100), 25.65 KiB | 168.00 KiB/s, done.
Resolving deltas: 100% (37/37), done.
vozerov@mba:~ $ cd events/terraform/

టెర్రాఫార్మ్‌లో ఉపయోగించే అన్ని ప్రధాన వేరియబుల్స్ main.tf ఫైల్‌లో వ్రాయబడ్డాయి. ప్రారంభించడానికి, టెరాఫార్మ్ ఫోల్డర్‌లో ప్రైవేట్.auto.tfvars ఫైల్‌ను కింది కంటెంట్‌తో సృష్టించండి:

# Yandex Cloud Oauth token
yc_token = ""
# Yandex Cloud ID
yc_cloud_id = ""
# Yandex Cloud folder ID
yc_folder_id = ""
# Default Yandex Cloud Region
yc_region = "ru-central1-a"
# Cloudflare email
cf_email = ""
# Cloudflare token
cf_token = ""
# Cloudflare zone id
cf_zone_id = ""

మేము ఇప్పటికే కన్సోల్ యుటిలిటీని కాన్ఫిగర్ చేసాము కాబట్టి అన్ని వేరియబుల్స్ yc config జాబితా నుండి తీసుకోవచ్చు. అనుకోకుండా ప్రైవేట్ డేటాను ప్రచురించకుండా ఉండేందుకు, వెంటనే .gitignoreకి private.auto.tfvarsని జోడించమని నేను మీకు సలహా ఇస్తున్నాను.

private.auto.tfvarsలో మేము Cloudflare నుండి డేటాను కూడా పేర్కొన్నాము - DNS రికార్డ్‌లను సృష్టించడానికి మరియు మా సర్వర్‌లకు ఈవెంట్స్.kis.im అనే ప్రధాన డొమైన్‌ను ప్రాక్సీ చేయడానికి. మీరు cloudflareని ఉపయోగించకూడదనుకుంటే, main.tfలో cloudflare ప్రొవైడర్ యొక్క ప్రారంభీకరణను మరియు అవసరమైన dns రికార్డ్‌లను రూపొందించడానికి బాధ్యత వహించే dns.tf ఫైల్‌ను తీసివేయండి.

మా పనిలో మేము మూడు పద్ధతులను మిళితం చేస్తాము - వెబ్ ఇంటర్‌ఫేస్, కన్సోల్ యుటిలిటీ మరియు టెర్రాఫార్మ్.

వర్చువల్ నెట్‌వర్క్‌లు

నిజం చెప్పాలంటే, మీరు ఈ దశను దాటవేయవచ్చు, ఎందుకంటే మీరు కొత్త క్లౌడ్‌ను సృష్టించినప్పుడు, మీరు స్వయంచాలకంగా ప్రత్యేక నెట్‌వర్క్‌ని కలిగి ఉంటారు మరియు 3 సబ్‌నెట్‌లు సృష్టించబడతాయి - ప్రతి లభ్యత జోన్‌కు ఒకటి. కానీ మేము ఇప్పటికీ మా ప్రాజెక్ట్ కోసం దాని స్వంత చిరునామాతో ప్రత్యేక నెట్‌వర్క్‌ను తయారు చేయాలనుకుంటున్నాము. Yandex.Cloudలో నెట్‌వర్క్ ఎలా పనిచేస్తుందనే సాధారణ రేఖాచిత్రం క్రింది చిత్రంలో చూపబడింది (నిజాయితీగా తీసుకోబడింది https://cloud.yandex.ru/docs/vpc/concepts/)

మేము Yandex.Cloudలో 10 ఈవెంట్‌లను అంగీకరిస్తాము. 000 వ భాగము

కాబట్టి, మీరు వనరులు ఒకదానితో ఒకటి సంభాషించుకునే ఉమ్మడి నెట్‌వర్క్‌ను సృష్టించుకోండి. ప్రతి లభ్యత జోన్ కోసం, సబ్‌నెట్ దాని స్వంత చిరునామాతో సృష్టించబడుతుంది మరియు సాధారణ నెట్‌వర్క్‌కు కనెక్ట్ చేయబడింది. ఫలితంగా, దానిలోని అన్ని క్లౌడ్ వనరులు వేర్వేరు లభ్యత జోన్‌లలో ఉన్నప్పటికీ, కమ్యూనికేట్ చేయగలవు. విభిన్న క్లౌడ్ నెట్‌వర్క్‌లకు కనెక్ట్ చేయబడిన వనరులు బాహ్య చిరునామాల ద్వారా మాత్రమే ఒకదానికొకటి చూడగలవు. మార్గం ద్వారా, ఈ మేజిక్ లోపల ఎలా పని చేస్తుంది, హబ్రేలో బాగా వివరించబడింది.

నెట్‌వర్క్ సృష్టి రిపోజిటరీ నుండి network.tf ఫైల్‌లో వివరించబడింది. అక్కడ మేము అంతర్గతంగా ఒక సాధారణ ప్రైవేట్ నెట్‌వర్క్‌ని సృష్టిస్తాము మరియు దానికి మూడు సబ్‌నెట్‌లను వివిధ లభ్యత జోన్‌లలో కనెక్ట్ చేస్తాము - ఇంటర్నల్-ఎ (172.16.1.0/24), ఇంటర్నల్-బి (172.16.2.0/24), ఇంటర్నల్-సి (172.16.3.0/24). )

టెర్రాఫారమ్‌ను ప్రారంభించండి మరియు నెట్‌వర్క్‌లను సృష్టించండి:

vozerov@mba:~/events/terraform (master) $ terraform init
... skipped ..

vozerov@mba:~/events/terraform (master) $ terraform apply -target yandex_vpc_subnet.internal-a -target yandex_vpc_subnet.internal-b -target yandex_vpc_subnet.internal-c

... skipped ...

Plan: 4 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

yandex_vpc_network.internal: Creating...
yandex_vpc_network.internal: Creation complete after 3s [id=enp2g2rhile7gbqlbrkr]
yandex_vpc_subnet.internal-a: Creating...
yandex_vpc_subnet.internal-b: Creating...
yandex_vpc_subnet.internal-c: Creating...
yandex_vpc_subnet.internal-a: Creation complete after 6s [id=e9b1dad6mgoj2v4funog]
yandex_vpc_subnet.internal-b: Creation complete after 7s [id=e2liv5i4amu52p64ac9p]
yandex_vpc_subnet.internal-c: Still creating... [10s elapsed]
yandex_vpc_subnet.internal-c: Creation complete after 10s [id=b0c2qhsj2vranoc9vhcq]

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

గొప్ప! మేము మా నెట్‌వర్క్‌ని సృష్టించాము మరియు ఇప్పుడు మా అంతర్గత సేవలను సృష్టించడానికి సిద్ధంగా ఉన్నాము.

వర్చువల్ మిషన్లను సృష్టిస్తోంది

అప్లికేషన్‌ను పరీక్షించడానికి, మేము రెండు వర్చువల్ మిషన్‌లను మాత్రమే సృష్టించాలి - అప్లికేషన్‌ను రూపొందించడానికి మరియు అమలు చేయడానికి మాకు మొదటిది అవసరం, రెండవది కాఫ్కాను అమలు చేయడానికి, మేము ఇన్‌కమింగ్ సందేశాలను నిల్వ చేయడానికి ఉపయోగిస్తాము. మరియు మేము అప్లికేషన్‌ను పర్యవేక్షించడానికి ప్రోమేథియస్‌ని కాన్ఫిగర్ చేసే మరొక యంత్రాన్ని సృష్టిస్తాము.

వర్చువల్ మెషీన్‌లు యాన్సిబుల్‌ని ఉపయోగించి కాన్ఫిగర్ చేయబడతాయి, కాబట్టి టెర్రాఫార్మ్‌ను ప్రారంభించే ముందు, మీ వద్ద అన్సిబుల్ యొక్క తాజా వెర్షన్‌లు ఒకటి ఉన్నాయని నిర్ధారించుకోండి. మరియు ఆన్సిబుల్ గెలాక్సీతో అవసరమైన పాత్రలను ఇన్‌స్టాల్ చేయండి:

vozerov@mba:~/events/terraform (master) $ cd ../ansible/
vozerov@mba:~/events/ansible (master) $ ansible-galaxy install -r requirements.yml
- cloudalchemy-prometheus (master) is already installed, skipping.
- cloudalchemy-grafana (master) is already installed, skipping.
- sansible.kafka (master) is already installed, skipping.
- sansible.zookeeper (master) is already installed, skipping.
- geerlingguy.docker (master) is already installed, skipping.
vozerov@mba:~/events/ansible (master) $

ansible ఫోల్డర్ లోపల నేను ఉపయోగించే ఒక ఉదాహరణ .ansible.cfg కాన్ఫిగరేషన్ ఫైల్ ఉంది. ఇది ఉపయోగపడవచ్చు.

వర్చువల్ మిషన్‌లను సృష్టించే ముందు, మీరు ssh-agent నడుస్తున్నట్లు మరియు ssh కీ జోడించబడిందని నిర్ధారించుకోండి, లేకుంటే టెరాఫార్మ్ సృష్టించిన మెషీన్‌లకు కనెక్ట్ చేయబడదు. నేను, వాస్తవానికి, os xలో బగ్‌ని చూశాను: https://github.com/ansible/ansible/issues/32499#issuecomment-341578864. ఇది మళ్లీ జరగకుండా నిరోధించడానికి, Terraformని ప్రారంభించే ముందు envకి చిన్న వేరియబుల్‌ని జోడించండి:

vozerov@mba:~/events/terraform (master) $ export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES

టెర్రాఫార్మ్‌తో కూడిన ఫోల్డర్‌లో మేము అవసరమైన వనరులను సృష్టిస్తాము:

vozerov@mba:~/events/terraform (master) $ terraform apply -target yandex_compute_instance.build -target yandex_compute_instance.monitoring -target yandex_compute_instance.kafka
yandex_vpc_network.internal: Refreshing state... [id=enp2g2rhile7gbqlbrkr]
data.yandex_compute_image.ubuntu_image: Refreshing state...
yandex_vpc_subnet.internal-a: Refreshing state... [id=e9b1dad6mgoj2v4funog]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

... skipped ...

Plan: 3 to add, 0 to change, 0 to destroy.

... skipped ...

ప్రతిదీ విజయవంతంగా ముగిసినట్లయితే (మరియు అది ఉండాలి), అప్పుడు మనకు మూడు వర్చువల్ మిషన్లు ఉంటాయి:

  1. బిల్డ్ - అప్లికేషన్‌ను పరీక్షించడానికి మరియు నిర్మించడానికి ఒక యంత్రం. Ansible ద్వారా డాకర్ ఆటోమేటిక్‌గా ఇన్‌స్టాల్ చేయబడింది.
  2. పర్యవేక్షణ - పర్యవేక్షణ యంత్రం - ప్రోమేథియస్ & గ్రాఫానా దానిపై వ్యవస్థాపించబడింది. లాగిన్ / పాస్‌వర్డ్ ప్రమాణం: అడ్మిన్ / అడ్మిన్
  3. కాఫ్కా అనేది కాఫ్కా ఇన్‌స్టాల్ చేయబడిన చిన్న యంత్రం, పోర్ట్ 9092లో అందుబాటులో ఉంటుంది.

అవన్నీ స్థానంలో ఉన్నాయని నిర్ధారించుకుందాం:

vozerov@mba:~/events (master) $ yc compute instance list
+----------------------+------------+---------------+---------+---------------+-------------+
|          ID          |    NAME    |    ZONE ID    | STATUS  |  EXTERNAL IP  | INTERNAL IP |
+----------------------+------------+---------------+---------+---------------+-------------+
| fhm081u8bkbqf1pa5kgj | monitoring | ru-central1-a | RUNNING | 84.201.159.71 | 172.16.1.35 |
| fhmf37k03oobgu9jmd7p | kafka      | ru-central1-a | RUNNING | 84.201.173.41 | 172.16.1.31 |
| fhmt9pl1i8sf7ga6flgp | build      | ru-central1-a | RUNNING | 84.201.132.3  | 172.16.1.26 |
+----------------------+------------+---------------+---------+---------------+-------------+

వనరులు స్థానంలో ఉన్నాయి మరియు ఇక్కడ నుండి మేము వారి IP చిరునామాలను పొందవచ్చు. కింది వాటిలో నేను ssh ద్వారా కనెక్ట్ చేయడానికి మరియు అప్లికేషన్‌ను పరీక్షించడానికి IP చిరునామాలను ఉపయోగిస్తాను. మీరు టెర్రాఫార్మ్‌కి కనెక్ట్ చేయబడిన క్లౌడ్‌ఫ్లేర్ ఖాతాను కలిగి ఉంటే, తాజాగా సృష్టించిన DNS పేర్లను ఉపయోగించడానికి సంకోచించకండి.
మార్గం ద్వారా, వర్చువల్ మెషీన్‌ను సృష్టించేటప్పుడు, అంతర్గత IP మరియు అంతర్గత DNS పేరు ఇవ్వబడతాయి, కాబట్టి మీరు నెట్‌వర్క్‌లోని సర్వర్‌లను పేరు ద్వారా యాక్సెస్ చేయవచ్చు:

ubuntu@build:~$ ping kafka.ru-central1.internal
PING kafka.ru-central1.internal (172.16.1.31) 56(84) bytes of data.
64 bytes from kafka.ru-central1.internal (172.16.1.31): icmp_seq=1 ttl=63 time=1.23 ms
64 bytes from kafka.ru-central1.internal (172.16.1.31): icmp_seq=2 ttl=63 time=0.625 ms
^C
--- kafka.ru-central1.internal ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.625/0.931/1.238/0.308 ms

అప్లికేషన్‌కు kafkతో ముగింపు బిందువును సూచించడానికి ఇది మాకు ఉపయోగపడుతుంది.

అప్లికేషన్ అసెంబ్లింగ్

చాలా బాగుంది, సర్వర్లు ఉన్నాయి, ఒక అప్లికేషన్ ఉంది - దానిని సమీకరించడం మరియు ప్రచురించడం మాత్రమే మిగిలి ఉంది. బిల్డ్ కోసం మేము సాధారణ డాకర్ బిల్డ్‌ని ఉపయోగిస్తాము, కానీ ఇమేజ్ స్టోరేజ్‌గా మేము Yandex - కంటైనర్ రిజిస్ట్రీ నుండి సేవను ఉపయోగిస్తాము. కానీ మొదటి విషయాలు మొదటి.

మేము అప్లికేషన్‌ను బిల్డ్ మెషీన్‌కు కాపీ చేస్తాము, ssh ద్వారా లాగిన్ చేసి, చిత్రాన్ని సమీకరించండి:

vozerov@mba:~/events/terraform (master) $ cd ..
vozerov@mba:~/events (master) $ rsync -av app/ [email protected]:app/

... skipped ...

sent 3849 bytes  received 70 bytes  7838.00 bytes/sec
total size is 3644  speedup is 0.93

vozerov@mba:~/events (master) $ ssh 84.201.132.3 -l ubuntu
ubuntu@build:~$ cd app
ubuntu@build:~/app$ sudo docker build -t app .
Sending build context to Docker daemon  6.144kB
Step 1/9 : FROM golang:latest AS build
... skipped ...

Successfully built 9760afd8ef65
Successfully tagged app:latest

సగం యుద్ధం పూర్తయింది - ఇప్పుడు మేము మా అప్లికేషన్‌ను ప్రారంభించడం మరియు కాఫ్కాకు పంపడం ద్వారా దాని కార్యాచరణను తనిఖీ చేయవచ్చు:

ubuntu@build:~/app$ sudo docker run --name app -d -p 8080:8080 app /app/app -kafka=kafka.ru-central1.internal:9092</code>

С локальной машинки можно отправить тестовый event и посмотреть на ответ:

<code>vozerov@mba:~/events (master) $ curl -D - -s -X POST -d '{"key1":"data1"}' http://84.201.132.3:8080/post
HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 13 Apr 2020 13:53:54 GMT
Content-Length: 41

{"status":"ok","partition":0,"Offset":0}
vozerov@mba:~/events (master) $

అప్లికేషన్ రికార్డింగ్ విజయవంతం కావడంతో ప్రతిస్పందించింది మరియు సందేశం చేర్చబడిన విభజన మరియు ఆఫ్‌సెట్ యొక్క ఐడిని సూచిస్తుంది. Yandex.Cloudలో రిజిస్ట్రీని సృష్టించడం మరియు అక్కడ మా చిత్రాన్ని అప్‌లోడ్ చేయడం మాత్రమే మిగిలి ఉంది (మూడు లైన్లను ఉపయోగించి దీన్ని ఎలా చేయాలో registry.tf ఫైల్‌లో వివరించబడింది). నిల్వను సృష్టించండి:

vozerov@mba:~/events/terraform (master) $ terraform apply -target yandex_container_registry.events

... skipped ...

Plan: 1 to add, 0 to change, 0 to destroy.

... skipped ...

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

కంటైనర్ రిజిస్ట్రీలో ప్రమాణీకరించడానికి అనేక మార్గాలు ఉన్నాయి - ఓయూత్ టోకెన్, ఐయామ్ టోకెన్ లేదా సర్వీస్ అకౌంట్ కీని ఉపయోగించడం. ఈ పద్ధతుల గురించి మరిన్ని వివరాలను డాక్యుమెంటేషన్‌లో చూడవచ్చు. https://cloud.yandex.ru/docs/container-registry/operations/authentication. మేము సేవా ఖాతా కీని ఉపయోగిస్తాము, కాబట్టి మేము ఖాతాను సృష్టిస్తాము:

vozerov@mba:~/events/terraform (master) $ terraform apply -target yandex_iam_service_account.docker -target yandex_resourcemanager_folder_iam_binding.puller -target yandex_resourcemanager_folder_iam_binding.pusher

... skipped ...

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

ఇప్పుడు దాని కోసం కీని తయారు చేయడం మాత్రమే మిగిలి ఉంది:

vozerov@mba:~/events/terraform (master) $ yc iam key create --service-account-name docker -o key.json
id: ajej8a06kdfbehbrh91p
service_account_id: ajep6d38k895srp9osij
created_at: "2020-04-13T14:00:30Z"
key_algorithm: RSA_2048

మేము మా నిల్వ ఐడి గురించి సమాచారాన్ని అందుకుంటాము, కీని బదిలీ చేసి లాగిన్ చేయండి:

vozerov@mba:~/events/terraform (master) $ scp key.json [email protected]:
key.json                                                                                                                    100% 2392   215.1KB/s   00:00

vozerov@mba:~/events/terraform (master) $ ssh 84.201.132.3 -l ubuntu

ubuntu@build:~$ cat key.json | sudo docker login --username json_key --password-stdin cr.yandex
WARNING! Your password will be stored unencrypted in /home/ubuntu/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
ubuntu@build:~$

చిత్రాన్ని రిజిస్ట్రీకి అప్‌లోడ్ చేయడానికి, మాకు కంటైనర్ రిజిస్ట్రీ ID అవసరం, మేము దానిని yc యుటిలిటీ నుండి తీసుకుంటాము:

vozerov@mba:~ $ yc container registry get events
id: crpdgj6c9umdhgaqjfmm
folder_id:
name: events
status: ACTIVE
created_at: "2020-04-13T13:56:41.914Z"

ఆ తర్వాత, మేము మా చిత్రాన్ని కొత్త పేరుతో ట్యాగ్ చేసి అప్‌లోడ్ చేస్తాము:

ubuntu@build:~$ sudo docker tag app cr.yandex/crpdgj6c9umdhgaqjfmm/events:v1
ubuntu@build:~$ sudo docker push cr.yandex/crpdgj6c9umdhgaqjfmm/events:v1
The push refers to repository [cr.yandex/crpdgj6c9umdhgaqjfmm/events]
8c286e154c6e: Pushed
477c318b05cb: Pushed
beee9f30bc1f: Pushed
v1: digest: sha256:1dd5aaa9dbdde2f60d833be0bed1c352724be3ea3158bcac3cdee41d47c5e380 size: 946

చిత్రం విజయవంతంగా లోడ్ చేయబడిందని మేము ధృవీకరించవచ్చు:

vozerov@mba:~/events/terraform (master) $ yc container repository list
+----------------------+-----------------------------+
|          ID          |            NAME             |
+----------------------+-----------------------------+
| crpe8mqtrgmuq07accvn | crpdgj6c9umdhgaqjfmm/events |
+----------------------+-----------------------------+

మార్గం ద్వారా, మీరు Linux మెషీన్‌లో yc యుటిలిటీని ఇన్‌స్టాల్ చేస్తే, మీరు ఆదేశాన్ని ఉపయోగించవచ్చు

yc container registry configure-docker

డాకర్‌ను కాన్ఫిగర్ చేయడానికి.

తీర్మానం

మేము చాలా కష్టపడి పని చేసాము మరియు ఫలితంగా:

  1. మేము మా భవిష్యత్ సేవ యొక్క నిర్మాణంతో ముందుకు వచ్చాము.
  2. మేము మా వ్యాపార తర్కాన్ని అమలు చేసే అప్లికేషన్‌ను గోలాంగ్‌లో వ్రాసాము.
  3. మేము దానిని సేకరించి ప్రైవేట్ కంటైనర్ రిజిస్ట్రీలో కురిపించాము.

తదుపరి భాగంలో, మేము ఆసక్తికరమైన అంశాలకు వెళ్తాము - మేము మా అప్లికేషన్‌ను ఉత్పత్తికి విడుదల చేస్తాము మరియు చివరకు దానిపై లోడ్‌ను ప్రారంభిస్తాము. మారవద్దు!

ఈ విషయం ఓపెన్ వర్క్‌షాప్ REBRAIN & Yandex.Cloud యొక్క వీడియో రికార్డింగ్‌లో ఉంది: మేము Yandex క్లౌడ్‌లో సెకనుకు 10 అభ్యర్థనలను అంగీకరిస్తాము - https://youtu.be/cZLezUm0ekE

మీరు ఆన్‌లైన్‌లో ఇటువంటి ఈవెంట్‌లకు హాజరు కావడానికి మరియు నిజ సమయంలో ప్రశ్నలు అడగడానికి ఆసక్తి కలిగి ఉంటే, కనెక్ట్ చేయండి REBRAIN ఛానెల్ ద్వారా DevOps.

అటువంటి ఈవెంట్‌ను హోస్ట్ చేసే అవకాశం ఇచ్చినందుకు Yandex.Cloudకి మేము ప్రత్యేక ధన్యవాదాలు చెప్పాలనుకుంటున్నాము. వాటికి లింక్ - https://cloud.yandex.ru/prices

మీరు క్లౌడ్‌కి వెళ్లాలనుకుంటే లేదా మీ మౌలిక సదుపాయాల గురించి ఏవైనా ప్రశ్నలు ఉంటే, అభ్యర్థనను సమర్పించడానికి సంకోచించకండి.

PS మాకు నెలకు 2 ఉచిత ఆడిట్‌లు ఉన్నాయి, బహుశా మీ ప్రాజెక్ట్ వాటిలో ఒకటి కావచ్చు.

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి