Alexander (HH): Großes Projekt und viele Fragen

Beitrag lesen

Moin Moin!

Da ich seit ungefähr einem Jahr an einem vergleichbaren Projekt arbeite, kann ich Svens Ausführungen nur bestätigen.

Ein paar Ergänzungen noch:

Den Server kriegst du beim Hosting-Anbieter deines Vertrauens in jeder gewünschten Konfiguration.

Ich würde für's erste trotz Extra-Kosten einen Server mit RAID-1 (in Software) nehmen, das sorgt bei einem (gar nicht so seltenen) Festplattenausfall für eine wesentlich entspanntere Stimmung, weil der Provider einfach nur die tote Platte austauschen muß, ohne dass der Server tagelang tot ist. Eine gewisse Downtime wird es in aller Regel geben, weil die meisten günstigen Root-Server eben nicht komplett Hot-Plug-fähig sind. Aber die beschränkt sich dann auf eine Stunde oder so, die der Techniker braucht, um den Server runterzufahren, die Platte zu tauschen, und den Server wieder zu starten. Danach kann man im laufenden Betrieb fdisk laufen lassen und das RAID wieder aufbauen lassen.

Ein virtueller Root-Server auf einem dicken Server hat solche Probleme natürlich nicht, dafür muß man sich mit wahrscheinlich mit Resourcen fressenden Nachbarn rumschlagen und ist bei entsprechendem Erfolg der Plattform bald zum Umzug auf einen dedizierten Server genötigt.

2.) Welche Linux Distribution sollte man am besten nehmen? Ich dachte an Debian.

Du nimmst die Distri, die du am besten kennst. Oder halt die, die dein Hoster hat.

Schalte *ALLE* Services ab, die nicht benötigt werden. X11 hat auf einem Webserver genauso wenig verloren wie Samba oder Avahi. Idealerweise installierst Du die entsprechenden Pakete gar nicht erst, bzw. deinstallierst Du sie.

Auf "meinem" Server laufen exakt zwei von außen erreichbare Dienste: sshd und httpd. Außerdem laufen noch ntpd und postgresql, beide sind jedoch von außen nicht erreichbar, weil sie entweder gar keinen Server-Socket öffnen (ntpd) oder ausschließlich via localhost erreichbar sind (postgresql).

Vermeide frei zugängliche oder nur per Passwort geschützte Konfigurationssoftware. Setze SSH v2 mit Public-Keys statt Passworten ein, schalte Password-Authentication im sshd aus. Erlaube kein root-Login, verwende ausschließlich sudo.

Ich sehe auf "meinem" Server täglich Routine-Scans auf den SSH-Server, die mit Wörterbüchern vergeblich versuchen, funktionierende Kombinationen von Usernamen und Passworten zu finden. Ebenso gibt es reichlich Routine-Scans nach phpadmin, Wikis, Web-Mailern, Frontpage-Umgebungen, und einiger anderer Web-Software.

ssh ersetzt FTP in Form von scp und sftp vollständig und sicher. rsync über ssh reduziert außerdem das administrative Datenvolumen. Es ist also absolut unnötig, einen FTP-Server laufen zu lassen.

Die Datenbank sollte von außen nicht zu erreichen sein, d.h. die Anwendung connectet sich über Unix Domain Sockets oder eine Loopback-Adresse (127.0.0.0/255.0.0.0, z.B. 127.0.0.1) auf die Datenbank. Für Wartungsarbeiten kann man mit einem auf dem Server installierten DB-Kommandozeilen-Client arbeiten oder per SSH einen lokalen Port auf den DB-Server-Port auf der Loopback-Adresse tunneln und auf dem lokalen Rechner mit entsprechenden Mausschubser-Tools arbeiten.

4.) Letztendlich wollte ich 3 Server nehmen. Einen für die Datenbank, einen für die Userbilder und einen Für die PHP Files.

Overkill. Du wirst im ersten und sehr wahrscheinlich auch im zweiten Jahr genügend Arbeit haben, für Auslastung eines Servers durch entsprechende Userzahlen zu sorgen.

Plane so, dass Du diese Trennung im Erfolgsfall vornehmen kannst, aber lasse alle drei Aufgaben zunächst auf einem Server laufen. Überlege auch, dass Du bei getrennten Servern die Datenbank von außen erreichbar machst. Ein VPN oder eine dedizierte, von außen nicht erreichbare Verbindung (sprich: zwei Netzwerkkarten und ein Patchkabel) schaft da Abhilfe.

Mein System ist (aus Erfahrung mit "zu" erfolgreichen Systemen) sogar noch weiter auftrennbar: Ich könnte mehrere identisch konfigurierte Webserver parallel hinter einem Loadbalancer laufen lassen und -- wie schon von Dir angedacht -- statische Resourcen von getrennten Webservern ausliefern lassen, bei Bedarf auch nochmal über Loadbalancer. Auch aus der Datenbank könnte ich einen Cluster machen, um so die DB-Last auf mehrere Server zu verteilen. Das ist im Moment aber noch unsere geringste Sorge, noch stemmt der Root-Server unsere User-Anzahl locker als "Maschinchen für alles".

Ich will anfangs nicht mehr als 120€/Monat investieren - geht sowas?

Nicht mit so "größenwahnsinnigen" Plänen. Nimm den kleinsten Root-Server, der zwei Platten hat. Suche Dir einen Hoster, bei dem Du nicht Kunde 25.893.382 bist. "Mein" Hoster wirbt mit "Menschlich. Einfach. Besser", und den kann ich nur weiter empfehlen -- schnell, kompetent und freundlich. Und die Kundennummer ist nur vierstellig. ;-)

Du hast am Anfang keinerlei Performanceprobleme. Also reicht im Prinzip auch "Webspace" irgendwo. Welche Performanceprobleme auftreten, wirst du nur kennenlernen, wenn deine Community tatsächlich so wächst, dass du mehr als einen Server benötigst. Bzw. erst dann findest du einen zum Problem exakt passende Lösung, so dass die Performanceprobleme optimal bearbeitet werden.

Wenn die Community so groß wird, dass der Server Dauerlast hat, sollte auch genügend Geld reinströmen, um einen zweiten, notfalls einen dritten Server anzuschaffen und sich ggf. auch mal ein paar Tage externe Beratung zu kaufen.

Und es ist ja ganz offensichtlich (oder?), dass Webserver *UND* Datenbank-Server genau in dem Moment beide viel CPU, viel RAM und viel Festplatte haben wollen, in dem ein Request abgearbeitet wird. Es bietet sich also an, als ersten Schritt im Falle des Erfolges Webserver und Datenbank auf zwei getrennte Maschinen zu packen. Meistens hat die DB etwas weniger Last und kann auf der schwächeren (alten) Maschine bleiben, während man den Webserver auf die aktuellere Hardware umzieht. Damit sich DB-Traffic und HTTP-Traffic nicht ins Gehege kommen, ist ein DB-Netz (und sei es nur ein Crossover-Kabel und zwei 100er-LAN-Karten) empfehlenswert.

Ich habe noch nie gehört, dass die Wahl der Datenbank sich aufgrund der Zahl der Datenbankeinträge entscheidet. Da wären immer andere Faktoren entscheidender. Allen voran: Mit welcher DB kennst du dich am besten aus? Denn es ist abzusehen, dass du das gesamte Featureangebot der DB benötigen wirst. Zweitens: Bietet diese Datenbank all das, was du an DB-Features benötigst?

Drittens: Stehen Dir Sonderfall-Optimierungen (wie z.B. sehr gehäuft in MySQL) und andere exotische Dinge im Weg oder nützen sie Dir sogar?

Ich kam für mein Projekt zu dem Ergebnis, dass *mir* MySQL mehr im Weg stehen würde als PostgreSQL, und das PostgreSQL gegenüber (dem allen ernstes von einem selbsternannten Experten vorgeschlagenen) Oracle einen "geringfügigen" Kosten- und Dokumentationsvorteil hat.

Deine limitierte Ressource heißt am Anfang "Entwickler", nicht "Performance". Wenn das Projekt Erfolg haben soll (was ich angesichts der langjährig existierenden Konkurrenz bezweifle), dann muß es sich durch absolut gute Qualität und interessante Features hervorheben.

Exakt.

Außerdem ein paar Dinge, die man im Laufe der Zeit entweder lernt oder an denen man kläglich scheitert:

* Arbeite nicht ohne schriftlichen Vertrag, egal ob selbständig oder angestellt. Eine "Hallo Welt, hier ist Hein Meier"-Seite für den Nachbarn kann man für zwei Scheine auch mal ohne Vertrag machen, aber ein Projekt, das Wochen bis Jahre dauert, sollte auf einem Vertrag basieren.

* Arbeite nicht ohne Plan. Schreibe einen Plan für das Projekt, und einen weiteren Plan für jeden Aspekt. Fang mit den wichtigsten Aspekten an, plane Optionales später detailiert. Auch ein Schmierzettel mit zwei Skizzen und 10 Stichworten kann ein Plan (für einen sehr kleinen Aspekt) sein.

* Leite aus den Plänen einen Zeitplan ab. Vergiß beim Schätzen des Aufwands nicht, dass Du Zeit für Tests, Debugging, Pannen, weitere Pläne, Administratives und die eine oder andere unangenehme Überraschung brauchst. Bauchgefühl + 100% + großzügig Aufrunden funktioniert bei mir ganz gut. Ohne Bauchgefühl mußt Du einfach ins Blaue hinein Codezeilen und darauf basierend Zeit raten, während der Umsetzung zählen und messen, und den Fehler beim nächsten Rateversuch mit einberechnen. Dann zählst und mißt Du wieder und nimmst den neuen Fehler mit in die dritte Schätzung, und so weiter. Irgendwann entwickelst Du Dein persönliches Bauchgefühl und Deinen persönlichen Korrekturfaktor.

* Sammle Feedback von Deinen Nutzern, so viel wie möglich. Berücksichtige das Feedback bei der weiteren Planung. Wir haben so herausgefunden, dass ein von uns für völlig unwichtig erachtetes Feature für unsere User quasi lebensnotwendig ist, und diesem Feature entsprechend Priorität bei der Entwicklung eingeräumt.

* Stelle 100% sicher, dass Du für Entwicklungsserver, Entwicklungs-Workstation *UND* Produktivserver zu jeder Zeit ein verifiziertes Backup hast, von dem Du die betreffene Maschine jederzeit ab "bare metal" wiederherstellen kannst.

* Benutze eine Quelltextverwaltung (Subversion, GIT, ...), committe jeden kleinen, getesteten Arbeitsschritt und kommentiere diesen Arbeitsschritt in der Quelltextverwaltung (nicht "was geändert", sondern "warum geändert" -- "was geändert" liefert Dir "svn diff" vollautomatisch)

* Benutze eine Fehler- bzw. Anforderungsverwaltung, wie z.B. Bugzilla, und trage JEDEN Fehler und JEDE neue Anforderung dort ein.

* Automatisiere alle Routine-Arbeitsschritte durch Makefiles oder Shell-Scripte. Halte diese ebenfalls in der Quelltextverwaltung. So reicht dann ein "make update-testserver" oder "make update-liveserver" aus, um den aktuellen Stand auf den Server zu bringen, *OHNE* dass Du jedes mal wieder darüber nachdenken mußt, was Du alles berücksichtigen mußt. rsync und Make (auch auf dem Server) sind dabei extrem hilfreich.

* Teste und entwickle nicht auf dem Produktivsystem.

* Vertraue keinem einzigen Wert, der nicht aus deinem Programm kommt. Mißtraue allen Benutzereingaben, allen URL-Parametern, allen Cookies, allen Daten, die per GET oder POST hereinkommen. Behandle all dieses als gezielten Angriff eines hoch motivierten, exzellent ausgestatteten und exzellent ausgebildeten Bösewichts auf Deine Software, bis durch eine gründliche Validierung das Gegenteil bewiesen ist. Erst dann beginne mit der Verarbeitung der Eingaben.

* Überwache alle (relevanten) Logfiles des Produktivsystems.

* Oftmals reicht erstmal aus, eine Lösung zu finden, die für 80% der User ausreicht. Erst recht, wenn die restlichen 20% einen astronomischen Aufwand erfordern.

* Wenn Du als Selbständiger oder mit einer Mini-Firma das Projekt als einzige Einnahmequelle durchziehst, geh davon aus, dass das Geld irgendwann aufgebraucht ist, und Du fremdes Geld benötigst. Wenn Du nicht gerade auf einem sehr großen Sack Geld sitzt, wird das vor Fertigstellung des Projekts sein.

* Wenn Du als Angestellter arbeitest, oder spätestens wenn Du einen Investor brauchst, sieh zu, dass Du jederzeit IRGENDETWAS vorführen kanst, und sei es noch so häßlich und zickig. Sei in jeder Minute bereit vorzuführen, dass die Entwicklung voranschreitet.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".