
คำเปอร์เซียซึ่งหมายถึง "เล็ก" หรือ "li'l" มันมักจะถูกใช้เพื่ออ้างถึงผู้หญิงเมื่อเจ้าชู้ (ด้วยความหมาย Li'l Girl)
พจนานุกรมเมือง
ยินดีต้อนรับสู่ Koochooloo : โครงการที่สง่างามและมีประโยชน์ที่สร้างขึ้นเพื่อปรับปรุงการพัฒนาแอพพลิเคชั่น Golang ด้วยสถาปัตยกรรมที่จัดระเบียบอย่างดี Koochooloo ได้รวมคุณสมบัติที่สำคัญเช่นการจัดการฐานข้อมูลและการจัดการการกำหนดค่าเป็นตัวอย่างของแนวทางปฏิบัติที่ดีที่สุดในการสร้างแอพพลิเคชั่นพักผ่อนที่แข็งแกร่งด้วย GO
init : eschews globals และความซับซ้อนของฟังก์ชั่น init เพื่อให้สิ่งต่าง ๆ ง่าย ใช้ประโยชน์จาก fx เป็นกรอบการฉีดพึ่งพาของเรา Koochooloo ส่งมอบ:
fx ง่ายขึ้นในการทดสอบได้อย่างง่ายดายเช่นเดียวกับในการผลิตเริ่มต้นการเดินทางด้วย Koochooloo และกำหนดวิธีการของคุณในการสร้างแอพพลิเคชั่นที่พักผ่อนใน GO ไม่ว่าคุณจะขยายชุดทักษะหรือสร้างรากฐานที่แข็งแกร่งสำหรับแอพพลิเคชั่นที่ซับซ้อน Koochooloo เป็นคู่ค้าของคุณในการออกแบบซอฟต์แวร์ที่มีประสิทธิภาพสะอาดและปรับขนาดได้
ก่อนอื่นแพ็คเกจ cmd มีไบนารีของโครงการนี้ด้วยการใช้งูเห่า เป็นการดีที่จะมีไบนารีง่ายๆสำหรับงานเช่นการย้ายฐานข้อมูลที่สามารถทำงานได้ในขั้นตอนการเริ่มต้นของโครงการ ไบนารีแต่ละตัวมี 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 และสร้างอินสแตนซ์ฐานข้อมูล เป็นความคิดที่ดีที่จะ ping ฐานข้อมูลของคุณที่นี่เพื่อให้มั่นใจอย่างเต็มที่กับอินสแตนซ์ฐานข้อมูลของคุณก่อนที่จะก้าวไปข้างหน้า นอกจากนี้สำหรับการมีข้อมูลเชิงลึกที่ฐานข้อมูลสุขภาพคุณสามารถเรียกฟังก์ชั่น ping นี้เป็นระยะและรายงานผลลัพธ์ด้วยตัวชี้วัด (ซึ่งฉันไม่ได้ทำที่นี่)
โมเดลโครงการถูกกำหนดไว้ในแพ็คเกจ model แบบจำลองเหล่านี้ใช้ภายใน แต่สามารถใช้ใน response หรือ request แพ็คเกจ ไม่มีโครงสร้างสำหรับการสื่อสารกับฐานข้อมูลในแพ็คเกจนี้
ที่เก็บมีหน้าที่รับผิดชอบในการสื่อสารกับฐานข้อมูลเพื่อจัดเก็บหรือดึงโมเดล ที่เก็บเป็น interface และมีการใช้งานที่เป็นรูปธรรมและล้อเลียนสำหรับพวกเขา การใช้งานคอนกรีตใช้ในรหัสหลักและใช้การเยาะเย้ยสำหรับการทดสอบ โปรดทราบว่าการทดสอบสำหรับที่เก็บนั้นมีความสุขและทำด้วยฐานข้อมูลจริง
HTTP Handler ถูกกำหนดไว้ในแพ็คเกจ handler Echo เป็นกรอบ HTTP ที่ยอดเยี่ยมที่คุณต้องการ ตัวจัดการแต่ละตัวมีโครงสร้างด้วยวิธี Register ที่ลงทะเบียนเส้นทางของมันไปยังกลุ่มเส้นทางที่กำหนด Route Group เป็นแนวคิดจาก Framework 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 ตาม telemetry แต่ละแพ็คเกจมี metric.go ที่กำหนดโครงสร้างที่มีตัวชี้วัดและมีวิธีการเปลี่ยน สำหรับการย้ายจากโพรไปเป็นบริการอื่นคุณเพียงแค่ต้องเปลี่ยน telemetry ตัวชี้วัดไม่ใช่ระดับโลกและพวกเขาสร้างขึ้นสำหรับแต่ละอินสแตนซ์แยกจากกันด้วยการออกแบบ telemetry แบบเปิด สำหรับการมีคอนโทรลเลอร์ที่ดีขึ้นบนจุดสิ้นสุดตัวชี้วัดมีเซิร์ฟเวอร์ HTTP อื่นที่กำหนดไว้ในแพ็คเกจ telemetry สำหรับการตรวจสอบ
เป็นการดีที่จะมีแพ็คเกจแยกสำหรับคำขอและการตอบกลับ แพ็คเกจเหล่านี้ยังมีตรรกะการตรวจสอบความถูกต้อง หนึ่งในการตรวจสอบที่ดี pakcages ใน GO คือ Ozzo-Validator หลังจากให้วิธีการตรวจสอบความถูกต้องหลังจากได้รับการร้องขอคุณสามารถตรวจสอบได้ด้วยวิธีการของมันได้อย่างง่ายดาย
การบันทึกหนึ่งส่วนที่สำคัญที่สุดของแอปพลิเคชัน ในตอนแรกไม่จำเป็นต้องมีอะไรมากกว่าบันทึก STDOUT อย่างง่าย แต่ในอนาคตคุณต้องใช้งานของคุณเข้าสู่ระบบและจัดส่งไปยังระบบการรวมเพราะเมื่อระบบของคุณเริ่มตรวจจับปัญหาจากบันทึกข้อความจะเป็นไปไม่ได้
ZAP เป็นหนึ่งในตัวบันทึกที่ดีที่สุดสำหรับการบันทึกโครงสร้าง zap บังคับให้คุณส่งผ่านไปยังโมดูลลูกของคุณและคุณยังตั้งชื่อคนบันทึกด้วยวิธีการ Named ด้วยการใช้ Logger ที่มีชื่อคุณสามารถค้นหาบันทึกโมดูลของคุณได้อย่างง่ายดายในการรวบรวมบันทึกของคุณ
โครงการนี้ต้องใช้ 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