
كلمة فارسية تعني "صغيرة" أو "li'l". غالبًا ما يتم استخدامه للإشارة إلى فتاة عند المغازلة ، (بالمعنى ، فتاة li'l)
القاموس الحضري
مرحبًا بكم في Koochooloo : مشروع أنيق وعملي مصمم لتبسيط تطوير تطبيقات Golang. يضم Koochooloo بنية جيدة التنظيم ، يدمج الميزات الحيوية مثل معالجة قواعد البيانات وإدارة التكوين ، مما يمثل أفضل الممارسات في بناء تطبيقات راحة قوية مع GO.
init : يتجنب الكرات وتعقيدات وظائف init للحفاظ على الأمور بسيطة. الاستفادة من fx كإطار حقن التبعية لدينا ، يسلم Koochooloo :
fx في الاختبار بنفس السهولة في الإنتاج.الشروع في رحلة مع Koochooloo وإعادة تعريف نهجك لإنشاء تطبيقات مريحة في GO. سواء كنت تقوم بتوسيع مجموعة المهارات الخاصة بك أو تقوم ببناء أساس متين للتطبيقات المعقدة ، فإن Koochooloo هو شريكك في تصميم برامج فعال ونظيف وقابل للتطوير.
بادئ ذي بدء ، تحتوي حزمة cmd على ثنائيات هذا المشروع باستخدام Cobra. من الجيد أن يكون لديك ثنائيات بسيطة لمهام مثل ترحيل قاعدة البيانات التي يمكن تشغيلها في مرحلة بدء المشروع. كل ثنائي له main.go في حزمةه ويسجل نفسه بوظيفة Register . في root.go من cmd تسمى وظائف Register هذه من الأمراض الفرعية. فيما يلي مثال على وظيفة التسجيل:
// Register server command.
func Register ( root * cobra. Command ) {
root . AddCommand (
& cobra. Command {
Use : "server" ,
Short : "Run server to serve the requests" ,
Run : func ( _ * cobra. Command , _ [] string ) {
fx . New (
fx . Provide ( config . Provide ),
fx . Invoke ( main ),
). Run ()
},
},
)
} مرة أخرى ، يسجل كل أمر علمه بمفرده ، لذلك لدينا انفصال عن الأوامر الأخرى. في بعض الأحيان ، نحتاج إلى مشاركة أعلام بين الأوامر ، فمن الأفضل أن يكون لها تكوين. للحالة الأخيرة ، يمكن أن يساعدنا koanf في الهيكل على النحو التالي:
func Register ( fs * pflag. FlagSet ) {
fs . StringP (
"url" , "u" ,
nats . DefaultURL ,
fmt . Sprintf ( "nats server url(s) e.g. %s" , nats . DefaultURL ),
)
}تقوم هذه الوظيفة بتسجيل الأعلام المشتركة ، ثم نقوم بتحميل التكوين بناءً على الوظيفة التالية:
k := koanf . New ( "." )
if err := k . Load ( posflag . Provider ( fs , "." , k ), nil ); err != nil {
log . Errorf ( "error loading config.yml: %s" , err )
}
if err := k . Unmarshal ( "" , & instance ); err != nil {
log . Fatalf ( "error unmarshalling config: %s" , err )
}الجزء الرئيسي من كل تطبيق هو تكوينه. هناك العديد من الطرق للحصول على التكوين في المشروع من ملف التكوين إلى متغيرات البيئة. Koanf لديه كل منهم في حزمة واحدة جميلة. النقاط الرئيسية هنا هي:
config وسوف تمر إليها في بدايتها.PS Koanf أفضل من Viper لتكوين التكوين. عن طريق التكوين المكتوبة ، أعني أن لديك بنية محددة للتكوين ثم تحميل التكوين من العديد من المصادر فيه.
لتثبيت koanf ، يمكنك استخدام الأوامر التالية:
go get -u github.com/knadh/koanf/v2
go get -u github.com/knadh/koanf/providers/file
go get -u github.com/knadh/koanf/providers/env
go get -u github.com/knadh/koanf/providers/structs
go get -u github.com/knadh/koanf/parsers/toml تستخدم الحزم والخدمات التي يتم تعريفها في حزمة domain فقط حزم أخرى من domain دون استخدام أي حزم طرف ثالثة. تحدد هذه الحزم والخدمات مفاهيم المجال الأساسية.
هناك حزمة db مسؤولة عن الاتصال بقاعدة البيانات. تستخدم هذه الحزمة تكوين قاعدة البيانات المحددة في وحدة config وإنشاء مثيل قاعدة بيانات. إنها لفكرة جيدة أن تتجه إلى قاعدة البيانات الخاصة بك هنا أن تكون واثقًا تمامًا من مثيل قاعدة البيانات الخاص بك قبل المضي قدمًا. أيضًا للحصول على نظرة ثاقبة في Database Health ، يمكنك استدعاء وظيفة Ping هذه بشكل دوري والإبلاغ عن نتائجها مع المقاييس (التي لم أفعلها هنا).
يتم تعريف نماذج المشروع في حزمة model . يتم استخدام هذه النماذج داخليًا ولكن يمكن استخدامها في response أو request . لا يوجد بنية للتواصل مع قاعدة البيانات في هذه الحزمة.
المستودعات هي المسؤولة عن التواصل مع قاعدة البيانات لتخزين أو استرداد النماذج. المستودعات هي interface وهناك تنفيذ ملموس وسخرت لهم. يتم استخدام تنفيذ ملموسة في الكود الرئيسي ويتم استخدام واحد يسخر من الاختبارات. يرجى ملاحظة أن اختبارات المستودعات حساسة وتتم مع قاعدة البيانات الفعلية.
يتم تعريف معالج HTTP في حزمة handler . ECHO هو إطار HTTP رائع يحتوي على كل شيء تحتاجه. لكل معالج هيكله مع طريقة Register تسجل طريقها إلى مجموعة مسار معينة. Route Group هو مفهوم من إطار Echo لتجميع مسارات الوالدين المحددة. كل معالج لديه ما يحتاجه في هيكلها. يتم إنشاء هيكل المعالج في main.go ثم التسجيل على مجموعتهم.
type Healthz struct {}
// Handle shows server is up and running.
func ( h Healthz ) Handle ( c echo. Context ) error {
return c . NoContent ( http . StatusNoContent )
}
// Register registers the routes of healthz handler on given echo group.
func ( h Healthz ) Register ( g * echo. Group ) {
g . GET ( "/healthz" , h . Handle )
} يتم جمع جميع المقاييس باستخدام Prometheus على أساس القياس المفتوح. تحتوي كل حزمة على metric.go . للترحيل من بروميثيوس إلى خدمة أخرى ، تحتاج فقط إلى تغيير telemetry . المقاييس ليست عالمية وأنشأتها لكل حالة بفضل تصميم القياس عن بعد المفتوح. للحصول على وحدة تحكم أفضل على نقطة نهاية المقاييس ، يوجد خادم HTTP آخر يتم تعريفه في حزمة telemetry للمراقبة.
من الجيد أن تكون قد انفصلت عن الحزم للطلبات والاستجابات. تحتوي هذه الحزم أيضًا على منطق التحقق من الصحة. واحدة من pakcages التحقق من الصحة الجيدة في GO هي Ozzo-validator. بعد توفير طريقة التحقق من صحة ، بعد الحصول على الطلب ، يمكنك التحقق من صحة طريقه بسهولة.
تسجيل واحد الجزء الأكثر أهمية من التطبيق. في البداية ، لا توجد حاجة إلى الحصول على شيء أكثر من سجلات STDOUT بسيطة. ولكن في المستقبل ، تحتاج إلى التغلب على تسجيلها وشحنها إلى نظام تجميع لأنه عندما ينمو نظامك في اكتشاف المشكلات من سجلات النص ، سيكون من الممكن أن يكون ذلك ممكنًا.
ZAP هو واحد أفضل مسجل لتسجيل الهيكل. يجبرك zap على تمريرها إلى وحدة طفلك وتسمية Loggers أيضًا Named Method. باستخدام المسجل المسمى ، يمكنك بسهولة العثور على سجلات الوحدة النمطية في مجمع السجل الخاص بك.
يتطلب هذا المشروع MongoDB فقط ، ويمكنك تشغيله بمخطط docker-compose المتوفر.
cd deployments && docker-compose up -d
cd cmd/koochooloo/ && go build && ./koochooloocurl -X POST -d ' {"url": "https://elahe-dastan.github.io"} ' -H ' Content-Type: application/json ' 127.0.0.1:1378/api/urls
curl -L 127.0.0.1:1378/api/CKaniA checks.....................: 99.83% ✓ 2995 ✗ 5
data_received..............: 2.0 MB 64 kB/s
data_sent..................: 521 kB 17 kB/s
group_duration.............: avg=649.18ms min=153.18µs med=265.45ms max=30.95s p(90)=1.61s p(95)=2.06s
http_req_blocked...........: avg=14.12ms min=0s med=3µs max=1.65s p(90)=13µs p(95)=147.04µs
http_req_connecting........: avg=6.23ms min=0s med=0s max=1.36s p(90)=0s p(95)=0s
http_req_duration..........: avg=272.98ms min=0s med=127.99ms max=4.81s p(90)=830.93ms p(95)=1.29s
http_req_receiving.........: avg=125.23µs min=0s med=60µs max=11.21ms p(90)=228µs p(95)=363µs
http_req_sending...........: avg=50.78µs min=0s med=22µs max=7.28ms p(90)=86µs p(95)=138µs
http_req_tls_handshaking...: avg=7.86ms min=0s med=0s max=653.63ms p(90)=0s p(95)=0s
http_req_waiting...........: avg=272.8ms min=0s med=127.71ms max=4.81s p(90)=830.87ms p(95)=1.29s
http_reqs..................: 4000 129.093962/s
iteration_duration.........: avg=1.29s min=142.34ms med=1.04s max=30.97s p(90)=2.18s p(95)=2.64s
iterations.................: 1000 32.273491/s
vus........................: 100 min=100 max=100
vus_max....................: 100 min=100 max=100