Projektstruktur für Micro-Services

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
robin_
User
Beiträge: 48
Registriert: Montag 3. August 2020, 17:59

Hallo zusammen,

Ich bin mir bzg. der Projektstruktur unsicher. Bisher liegt alles in einer Repo:

/webserver/
/data_worker/
schemas.py

Der Webserver (FastAPI, SQLAlchemy + SQLite) und der data_worker sind beides Docker Container.

schemas.py definiert mehrere Pydantic BaseModel-Klassen, die für die Datenvalidierung in beiden "Micro-Services" gebraucht wird.
Wie sollte man das ganze strukturieren? Relativer Import aus den beiden Packages heraus klappt ja nicht und ich will die Datei logischer Weise auch nicht mehrmals kopieren.

Sollte ich eine eigene Git Repo für die Klassendefinitionen anlegen, nur um diese dann in /webserver und /data_worker zu clonen?
Grundsätzlich brauchen alle Services die gleiche Klassendefinition...

Bin mir gerade unschlüssig, wie das am besten auszusehen hat.

Vielen Dank euch :=))
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sinn und Zweck von Microservices ist es doch gerade *nicht* solche Dinge zu teilen. Wenn man die ueber solchen Code aneinander bindet, kann man genauso gut einfach einen modularen Monolithen bauen - wo sowas einfach nur ein Modul wird. Oder sogar ueberfluessig.

Allgemein gilt: die wenigsten Organisationen brauchen uServices. Hyper-Scaler wie Amazon & Co profitieren davon, aber fuer die meisten anderen Shops ist das einfach nur ein follow-the-hype Thema.

Den YT Kanal finde ich zu dem Thema (und allgemein zu Entwicklungspraktiken) ganz gut: https://www.youtube.com/watch?v=zzMLg3Ys5vI - weiss nicht mehr genau, ob das genau das Video war, in dem meine Aussagen oben zu finden ist. Aber irgendwo bei ihm waren die.
robin_
User
Beiträge: 48
Registriert: Montag 3. August 2020, 17:59

__deets__ hat geschrieben: Dienstag 18. Oktober 2022, 15:21 Sinn und Zweck von Microservices ist es doch gerade *nicht* solche Dinge zu teilen. Wenn man die ueber solchen Code aneinander bindet, kann man genauso gut einfach einen modularen Monolithen bauen - wo sowas einfach nur ein Modul wird. Oder sogar ueberfluessig.
Also ich bin kein Experte bei Software-Architekturen. Du hast recht, man könnte das ganze auch in einem Container haben. Ich hatte Docker so verstanden, dass man genau einen Task ausführen lässt, daher die Idee das ganze zu splitten, einmal in das Skript für den Webserver und einmal eben in eins für die Aggregation der Daten.

Dazu kommt, dass ich Selenium fürs Webscraping verwende, das ist thematisch schon eher weit weg von Speicherung der Daten/ Webserver, daher empfand ich das irgendwie sinnvoll so.

Danke für den Link, werde mir den Kanal anschauen, folge schon ähnlichen YTern :)
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Microservices lösen kein technisches sondern ein organisatorisches. Wenn du nur eine Anwendung hast musst du dich mit allen die daran arbeiten verständigen, ob man den Code ändert, bei Deployments, usw. Diese Koordination wird schwieriger je mehr Leute und Teams involviert sind und irgendwann wird dies zu einem Bottleneck. Gerade wenn man in was DORA den High Cluster nennt, was heisst dass du in der Lage sein möchtest mehrmals pro Tag Deployments zu machen.

Microservices lösen dieses Problem dadurch dass die Architektur an die Organisationsstruktur (und andersherum) zu einem gewissen grad angepasst wird, so dass Teams unabhängig voneinander arbeiten können, weniger koordinieren müssen und damit bleibt mehr Zeit für andere Dinge übrig.

Microservices bringen aber auch selbst ganz viele Probleme mit sich, die sich zwar lösen lassen aber nur mit sehr viel Aufwand. Damit sich die Investition lohnt muss man also schon ein recht großes Problem haben (oder davor sein ein solches Problem zu haben). Das ist in der Regel erst bei ziemlich großen Unternehmen der Fall.

Bei uns im Unternehmen definieren wir Microservice übrigens so:
An application [read: microservice] can represent any meaningful set of software components providing a common purpose and business value.

Eine Component ist definiert als:
A component typically represent a unit of deployment, e.g. an application might have backend, frontend, and data store components which are deployed separately. A component does not have to be a deployable service, a component can also be a CronJob, a data pipeline, or some managed cloud service.
"deployed separately" hier meint z.B. separate Docker Container.

In deinem Fall würden wir sagen dass das eine Anwendung ist mit mehreren Komponenten (Web Server, Worker, Datenbank, ...). Zumindest in meinem Team wäre dass auch alles ein Python Package und ein Docker Image, dem man dann einfach unterschiedliche Argumente übergibt. Sentry macht dass z.b. auch so und ist praktischerweise Open Source, da kann man sich also einiges abschauen.
robin_
User
Beiträge: 48
Registriert: Montag 3. August 2020, 17:59

OK, also ein Image das mehrfach läuft und nur andere Skripte ausführt... klingt genau nach dem, was ich brauche :)

Merci!
robin_
User
Beiträge: 48
Registriert: Montag 3. August 2020, 17:59

Hm, bin leider noch nicht so richtig weiter.

Also, ich würde hinterher am liebsten verschiedene Container ausführen können. Der Grund ist, dass der Webserver durch das Dockerfile ja durchgehend läuft und so keine requests an apis gesendet werden können.

So ist nun die Struktur:
/webserver
/data_worker
/common

in common.schemas.py ist nun die Model-Definition von Pydantic drinne.
Wie mach ich es nun mit Docker am besten? Bisher existieren die Dockerfiles:
/webserver/Dockerfile
und
/data_worker/Dockerfile

Problem: Da der Context jeweils innerhalb der packages ist, wird common nicht mit kopiert.

Wie wäre die beste Konfiguration?
Danke
Antworten