
Ein persischer Wort, das "klein" oder "li'l" bedeutet. Es wird oft verwendet, um beim Flirten auf ein Mädchen zu beziehen (mit der Bedeutung, li'l Mädchen)
Urban Dictionary
Willkommen bei Koochooloo : Ein elegantes, praktisches Projekt, das die Entwicklung von Golang -Anwendungen rationalisiert. Koochooloo verfügt über eine gut organisierte Architektur und integriert wichtige Funktionen wie Datenbankbehandlungen und Konfigurationsmanagement, um die besten Praktiken beim Erstellen robuster Rastanwendungen mit GO zu veranschaulichen.
init -Funktionen : Vermeiden Sie Globale und die Komplexität von init -Funktionen, um die Dinge einfach zu halten. Nutzung von fx als Abhängigkeitsinjektionsgerüst liefert Koochooloo :
fx bei der gleichen Leichtigkeit wie in der Produktion unterstützt und vereinfacht.Machen Sie eine Reise mit Koochooloo und definieren Sie Ihren Ansatz zur Erstellung erholsamer Anwendungen in Go. Egal, ob Sie Ihre Fähigkeiten erweitern oder eine solide Grundlage für komplexe Anwendungen aufbauen, Koochooloo ist Ihr Partner für effizientes, sauberes und skalierbares Softwaredesign.
Zunächst enthält cmd -Paket die Binärdateien dieses Projekts unter Verwendung von Cobra. Es ist gut, einfache Binärdateien für Aufgaben wie Datenbankmigrationen zu haben, die in der Initiierungsphase des Projekts ausgeführt werden können. Jedes Binary hat sein main.go in seinem Paket und registriert sich mit einer Register . In der root.go von cmd werden diese Register aus Unterbewohnern aufgerufen. Hier ist ein Beispiel für die Registerfunktion:
// 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 ()
},
},
)
} Wieder registriert jeder Befehl seine Flagge selbst, sodass wir von anderen Befehlen getrennt sind. Manchmal müssen wir Flags zwischen Befehlen haben, dann ist es besser, sie in der Konfiguration zu haben. Für den späteren Fall kann koanf uns bei der unten nach unten stehenden Struktur helfen:
func Register ( fs * pflag. FlagSet ) {
fs . StringP (
"url" , "u" ,
nats . DefaultURL ,
fmt . Sprintf ( "nats server url(s) e.g. %s" , nats . DefaultURL ),
)
}Dieses Funktionsregister Shared Flags und dann laden wir die Konfiguration basierend auf ihnen mit der folgenden Funktion:
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 )
}Der Hauptteil jeder Anwendung ist die Konfiguration. Es gibt viele Möglichkeiten, um Konfiguration im Projekt von der Konfigurationsdatei zu Umgebungsvariablen zu haben. Koanf hat sie alle in einem schönen Paket. Die Hauptpunkte hier sind:
config definiert und übergibt es in seiner Initiation an diese.PS KOANF ist viel besser als Viper, wenn es typisierte Konfiguration hat. Mit typisierter Konfiguration meine ich eine definierte Struktur für die Konfiguration und laden Sie dann Konfiguration aus vielen Quellen hinein.
Für die Installation von KOANF können Sie die folgenden Befehle verwenden:
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 Pakete und Dienste, die im domain definiert sind, verwenden nur andere Pakete von domain , ohne dass Pakete von Drittanbietern verwendet werden. Diese Pakete und Dienste geben die Kerndomänenkonzepte an.
Es gibt ein db -Paket, das für die Verbindung mit der Datenbank verantwortlich ist. Dieses Paket verwendet die Datenbankkonfiguration, die im config definiert ist und eine Datenbankinstanz erstellt. Es ist eine gute Idee, Ihre Datenbank hier zu pingen, um Ihre Datenbankinstanz vollständig zuversichtlich zu haben, bevor Sie in Zukunft sind. Auch für einen Einblick in die Datenbankgesundheit können Sie diese Ping -Funktion regelmäßig bezeichnen und sein Ergebnis mit Metriken melden (die ich hier nicht getan habe).
Projektmodelle sind im model definiert. Diese Modelle werden intern verwendet, kann jedoch als response oder request verwendet werden. Es gibt keine Struktur für die Kommunikation mit Datenbank in diesem Paket.
Repositorys sind für die Commnunication mit Datenbank verantwortlich, um Modelle zu speichern oder abzurufen. Repositorys sind interface und es gibt eine konkrete und verspottete Implementierung für sie. Die Betonimplementierung wird im Hauptcode verwendet und für Tests verspottet. Bitte beachten Sie, dass die Tests für Repositories empfindlich sind und mit der tatsächlichen Datenbank durchgeführt werden.
HTTP -Handler sind im handler -Paket definiert. Echo ist ein großartiges HTTP -Framework, das Sie benötigen. Jeder Handler hat seine Struktur mit einer Register , die seine Route in eine bestimmte Routengruppe registriert. Die Routengruppe ist ein Konzept aus dem Echo -Framework für die Gruppierung von Routen unter einem bestimmten übergeordneten Pfad. Jeder Handler hat das, was er braucht in seine Struktur. Die Handlerstruktur wird in main.go erstellt und registriert sich dann in ihrer Gruppe.
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 )
} Alle Metriken werden mit Prometheus gesammelt, die auf offener Telemetrie basieren. Jedes Paket hat seine metric.go , die eine Struktur definiert, enthält die Metriken und verfügt über Methoden, um sie zu ändern. Für die Migration von Prometheus zu einem anderen Service müssen Sie nur telemetry ändern. Metriken sind nicht global und erstellten für jede Instanz separat, dank des offenen Telemetriedesigns. Für einen besseren Controller für den Endpunkt des Metriken gibt es einen weiteren HTTP -Server, der im telemetry zur Überwachung definiert ist.
Es ist gut, Pakete für Anfragen und Antworten getrennt zu haben. Diese Pakete enthalten auch Validierungslogik. Eine der guten Validierungspakagen in Go ist Ozzo-Validator. Nach der Bereitstellung der Validierungsmethode können Sie nach Erhalten von Anforderungen sie mühelos mit seiner Methode validieren.
Protokollieren Sie einen als wichtigsten Teil der Anwendung. Am Anfang müssen Sie nicht mehr als einfache Stdout -Protokolle haben. In Zukunft müssen Sie jedoch eine Strkutierung angeben und in ein Aggregationssystem versenden, da beim Wachstum Ihres Systems das Erkennen von Problemen aus Textprotokollen in Verantwortung sein wird.
Zap ist einer der beste Logger für die Strukturprotokollierung. zap zwingt Sie, es in Ihr Kindermodul zu übergeben, und Sie nennen auch Holzfäller mit Named Methode. Durch die Verwendung des benannten Logger können Sie Ihre Modulprotokolle in Ihrem Protokollaggregator problemlos finden.
Dieses Projekt erfordert nur MongoDB und Sie können es mit angebotenem docker-compose ausführen.
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