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 :=))
Projektstruktur für Micro-Services
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.
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.
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.__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.
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
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:
Eine Component ist definiert als:
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.
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:
"deployed separately" hier meint z.B. separate Docker Container.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.
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.
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
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