Posts mit dem Label Web Server werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Web Server werden angezeigt. Alle Posts anzeigen

23. Oktober 2015

Galactic Developments ist umgezogen auf einen neuen Server als KVM

Bisher war die Galactic Developments Website ein Apache Virtual Server auf meinem alten Hetzner Rootserver. Den hatte ich vor 6 Jahren bei einer keine-Setupgebühr-Aktion gebucht (und dann 3 Monate lang nicht installiert, was die keine-Setupgebühr-Aktion für mich ad-absurdum geführt hat, für Hetzner nicht). Inzwischen ist das Betriebssystem (Debian Sarge) aber schon aus den Security-Fixes raus gelaufen.

(Ich finde Sicherheitsaktualisierungen für nur 3 Jahre etwas kurz. Naja, ist ja Open Source. Wenn es einem nicht gefällt, dann einfach nicht benutzen oder selbst fixen, wie man so schön sagt, jedenfalls nicht meckern.)

Die Rechner der Rabatt-Aktion waren damals etwas schwach auf der Brust. Das stört nicht, wenn man nicht viel Traffic hat, aber heutzutage will man virtualisieren und mehrere Server gleichzeitig laufen lassen. Dafür ist ein ganzes GB RAM nicht genug. Der neue Server ist wieder bei Hetzner, hat aber 2 TB Platte, 32 GB RAM, 8 CPUs incl. Hyperthreading. Das sollte reichen für ein paar virtuelle.

Ich kann Debian, also weiter Debian-stable, d.h. Jessie 8.2.

Zum Virtualisieren kvm und libvirt drauf. Ein 2 GB Image für das Guest-Template erstellen mit einer Debian-minimal Installation ohne alles außer sshd. Die VMs sind nur über das interne "default" Netzwerk zu erreichen. Alle VMs bekommen statische IP Adressen vom internen DHCP.

Ein VM als Reverse-Proxy, der HTTP-Requests an verschiedene virtuelle Maschinen weiterleitet. Dafür eine iptables-Konfiguration per qemu-Hook, die immer dann die 2 iptables-Regeln setzt/löscht, wenn die VM startet/stoppt. Auf dem Proxy ein nginx, der alle Anfragen für www.galactic-developments.de an die Galactic Developments VM weiterleitet.

Der Galactic Developments Server bekommt eine eigene VM. Hier mit Apache, weil ich Apache schon kann und nicht zu viele Konfiguration ändern muss, dachte ich. Tatsächlich haben sich die Apache Entwickler ein neues Sicherheitskonzept einfallen lassen und erst mal geht gar nichts, bis ich herausfinde, dass man einen neuen Befehl (Require) braucht. Zusätzlich zum Galactic Developments Apache virtual Server gibt es noch einen CatchAll virtual Server, der Adressen wie galactic-developments.de (ohne www.) und *.galactic-developments.com auf den Hauptserver umleitet (401/permanent).

Dateien und Daten der Galactic Developments Website sind in Subversion. Das bleibt erstmal so bis sich die Community mehr beteiligt. Dann will ich git nicht im Wege stehen. Also: Repository auschecken und Apache-config darauf zeigen lassen. Bisher waren SVN Server und Website auf dem gleichen Rechner. Ein Subversion post-commit Hook hat automatisch die Website svn update'd. Poor man's Continuous Delivery. Das geht jetzt nicht mehr, weil es verschiedene Rechner sind und später - wenn der SVN Server auch umgezogen ist - gleicher Rechner, aber getrente VMs. Deshalb muss der post-commit Hook jetzt das Deployment anders triggern. Ich mag Trigger per HTTP-Request. In diesem Fall: ein Einzeiler-PHP in der Galactic Developments Website (Name lang und geheim, quasi das Passwort im Namen, Security by Obscurity), das ein lokales Shellscript startet, das wiederum "svn update" macht. Drei Einzeiler hintereinander. Man muss noch die Benutzer-Grenze überwinden vom wwwdata-User des Apache zum Eigentümer des Repositories. Deshalb wird das Shellscript mit sudo ausgeführt. Dafür eine Zeile in /etc/sudoers. Bei jedem svn commit ruft der post-commit Hook das update PHP-Script in der Zielwebsite per wget ("-O -" nicht vergessen) auf.

Dann noch DNS für www.galactic-developments.de umbiegen von rama.wolfspelz.de auf fred.wolfspelz.de und Galactic Developments ist umgezogen.

Das hört sich alles locker flockig an, hat mich aber mehrere Tage gekostet. Es gibt fast keine Anleitungen für libvirt/kvm OHNE lokales Display und ohne VNC. Auch virt-manager usw. alles nett gemeint, aber ich will kein Desktop auf meinem Server nur zum Installieren. (Wer bis hier gelesen bekommt von mir ein nagelneues Notebook). Genauso das Netzwerk: entweder es wird nicht erwähnt, was blöd ist, wenn man die VM vom Netzwerk installieren will oder es wird bridge-Networking vorgeschlagen, was bei mir einfach nicht wollte. Dabei geht das "default" Netzwerk super. Man muss es nur anschalten. Das könnte mal irgendwo stehen. Ein qemu-Hook statt bridge-Netz sehe ich nicht als Hack an, im Gegenteil.

PS: rama.wolfspelz.de war keine Frühstücksmargerine, sondern ein 50 km langes Alien-Raumschiff.

_happy_migrating()

29. Oktober 2014

Microservices bei Weblin

Und wieder einmal bekommt ein Prinzip, das wir bei Weblin entwickelt und benutzt haben, einen Namen: Microservices.

"Microservices is a software architecture design pattern, in which complex applications are composed of small, independent processes communicating with each other using language-agnostic APIs"

Wir haben es natürlich nicht erfunden. Viele andere gute Softwareingenieure haben zur gleichen Zeit das gleiche gemacht und inzwischen ist das Prinzip (=architecture design pattern) im Mainstream angekommen und hat einen Namen und es gibt viele Artikel und Vorträge.

Es geht darum, dass man nicht eine fette Anwendung macht, sondern mehrere (viele) von einander logisch getrennte Web-Services, die jeweils eine Funktionalität des Gesamtsystems bereitstellen und untereinander kommunizieren. Das betrifft sowohl Client/Server Kommunikation, als auch Server-Frontend/Backend und innerhalb vom Backend. Microservices können in verschiedenen Sprachen geschrieben sein und haben typischerweise jeweils eigene Datenbanken (wenn auch oft auf dem gleichen Datenbankserver). Microservices können horizontal oder vertikal skalieren,d.h. alle können auf der gleichen Server Farm laufen oder man ordnet einzelnen Microservices dedizierte Server zu.

Welches Web-Service Protokoll man wählt spielt eine untergeordnete Rolle. Eigentlich kann man Transportprotokoll und Datenformat beliebig kombinieren. REST/JSON ist dafür momentan das Mittel der Wahl. Aber SOAP geht auch. XMLRPC war mal sehr verbreitet. Bei Weblin hatten wir oft Key/Value/LF als Datenformat (auch liebevoll SRPC genannt), weil das meistens völlig ausreicht. Es geht aber auch anspruchsvoller, z.B. mit Protocol Buffers als Datenformat. Als Transportprotokoll bietet sich HTTP an. Aber es geht auch plain TCP oder ein Message-Bus.

Bei Weblin hatten wir Microservices für:

  • Userdaten (Identity), vom Frontend bespielt, vom Client benutzt
  • User created content upload (der berühmte File-Service: files.zweitgeist.com)
  • Download-Server
  • Wallet-Service und Punktekonto
  • Topsites-Service
  • XMPP-Server Management Service
  • Unit-Test (System-Runtime-Test) als Web-Service
  • GeoIP Auflösung als Web-Service
  • Kontaktlistenverwaltung
  • Wuscheln, Publisher (alles, was der Client wollte, ich sage nur "srpc.php")
  • VPI-Server
  • Compute-Service (Avatar-Generator)
  • Locatr
  • Ad-Server
_happy_eigenlobing()

29. Juli 2010

IBM recommends XMPP for Realtime Web Apps


There is a new tutorial from IBM about how to build modern realtime web apps. In the tutorial IBM suggests using XMPP, BOSH from JavaScript. It is worth reading.

http://www.ibm.com/developerworks/xml/tutorials/x-realtimeXMPPtut/index.html

This is exactly how weblin.lite was built 2 years. Even including the HTTP proxy to circumvent the JavaScript security limitation, tunneling XMPP through HTTP with BOSH, using a real XMPP server for message routing and a JavaScript XMPP client library to communicate. Also: jQuery, Ajaj, XML, JSON, WebServices, mysql. Basically, all the cool web-tech stuff we like.

Congrats to the weblin dev team. The best dev team I've ever had.

_happy_boshing()

Yes, we have been there. Now it is so much a standard, that IBM recommends the technology. It will be picked up by many others and we are already the experts. So much for certain ignorant investors and business angels, who do not recognize technology in their portfolio, even if it jumps into their face. We will be there without you.

3. November 2009

mod_mono Control Panel Extension

Just added a list of URLs to the mod_mono Control Panel (CP).

The Apache module mod_mono has a small control panel. The CP has some (actually very few) control features. You can see how many requests are currently processed, how many are waiting and you can restart the server process (the mono worker process, not the web server).

It can be enabled by

  1. <Location /mono>
  2. SetHandler mono-ctrl
  3. </Location>
Then go to http://your.host/mono. Unfortunately, it only shows how many requests are in work. I was missing information which requests are processed and waiting. I need the URLs. I want to know which ones take much time and which are blocking the server under high load.

So, I extended the CP to show a simple list of currently processed and waiting URLs.
  • First column is the request serial number.
  • The second colum is the processing time in seconds.
  • The third column is the URL with query.
Waiting requests are also listed. This happens only if the max processing limit is exceeded and requests wait (not in the screenshot). The waiting list shows the wait time instead of the processing time.

All data is stored in a shared memory segment.

BTW: mod_mono is programmed in C with not too much structure. No offense guys. I am very thankful for it. Great work. I know, it's open source. I should not complain, but improve it (which I did).

Why did I extend it? 2 reasons:
  1. I believe that an operator of a real service needs more information about what is going on than just the number of requests. We used apache server-status heavily. This is the same for mono.
  2. Flooding the server with dozens of integration tests, which spawn 200 backend requests each, stalled the server. I was afraid, that mon_mono has a problem under high load.
Once I knew the URLs, I could clearly see, that mod_mono is fine. It was just a normal deadlock situation where an frontend request tried to make a backend call via HTTP and could not get a free slot. Processing slots are limited by the thread pool. It can be increased, but there must be a hard limit. Allowing unlimited threads would make the server unusable under load, whereas deadlock situations can be avoided.

All slots are occupied by requests which wait for completion of backend requests, which do not find a free slot. Not a mod_mono issue. The situation has been resolved by splitting frontend and backend into separate mono applications. This is the normal configuration of a real multi-tier system, anyway.

The patch:

  1. % cd mod_mono-2.4.2/src
  2. % wget http://wolfspelz.de/download/mod_mono-2.4.2.patch
  3. % patch < mod_mono-2.4.2.patch
_happy_patching()

Update: the patch has been integrated into mono 2.6

17. August 2008

Big and Bigger Systems

I started to compile a list of guidelines for developing big systems. So, what is a big system?

  • "Big" means 5k - 100k concurrent users.
Of course, there are even bigger systems. There is also
  • "Massive" 50k up to 1 Mio. concurrent and
  • "Mainstream" 500k up to 10 Mio. concurrent and beyond.
The guidelines are for the smallest one the of 3 noteworty categories: "Big". This is the category I am experienced with. 10 or 20k concurrent is significantly different from normal/sparetime/hobby systems. But it is still conventional technology (e.g. on standard LAMP). I can imagine what needs to be done to get a massive system up and keep it running. ButI have never done it, yet. I can only dream of a mainstream scale system, especially a unique and not sharded one (see below).

Examples:
  • "Big": Xing, major online newspapers, Wikipedia, many browser games,
  • "Massive": Second Life, EVE-Online (barely), Runescape (I guess), Habbo, Facebook,
  • "Mainstream": WoW (barely), major IM networks (QQ, ICQ, MSN), Google search, mobile networks.
In other words:
  • "Big" ranges from "substantially over the top of your single server" to "the complete cluster would appear in the Top 500 Supercomputers list". EVE-Online is at the top of "Big" by sheer numbers, but it is on the brink to "Massive" because of its complexity. Xing: more than 10k click around on the web site at any time, sometimes twice as much.
  • "Massive" is really large. Think about thousands or ten times more servers. That's a decent farm. Second Life is at the lower end. Their server numbers are a bit high for the user count, because of their architecture. Facebook is somwhere in the middle with 50 TB cache memory alone. This number is already 20,000 times more than your PC and growing. We are talking about the large web services, companies with 10 B market capitalization. These are "Massive". The big guys.
  • "Mainstream" is unthinkable. Can you imagine half a million servers? If you stack them, they scratch the International Space Station. If you plan a system like this for everyone, then better avoid the hazzle and make it distributed like the Web. It's made for 10% of the world population (registered users not concurrent). There are few such systems on the planet. Few people managed to build in this order of magnitude. I am sure they grew into it with the system. Nothing that you can buy.
Of course there are differences in complexity between a static web site and an MMOG. A static web site, e.g. a newspaper may need much less resources for 10k concurrent readers, than a vitual world for 10k concurrent players. Comunication in an IM network is very different from a MMOG. MMOGs enter the "Massive" category earlier than browser games.

But there are also factors, which make the complexity similar or at least in the same order of magnitude.
  • As an example, 10k HTTP/HTML readers make more network connections (easily 10k conns per sec.) than 10k players (100 conns per sec. when people log in).
  • The data delivered may be in the same order of magnitude. Lets face it: a web site consists of min 100 items and active readers fetch 0,1 pages per second. This makes 10k x 0,1 x 100 = 100k items/sec. I doubt, that MMOGs deliver more than 100 items/sec to clients. This is 10 times more than what the web server does, but most MMOG items are just IDs of data pre-installed at the client. The web-items are all completely transferred. This reduces the difference. SecondLife transfers really many items by data. For a virtual world it is still an exception and it shows in the bad performance when discovering new areas.
  • Then, there is a stupid reason, why web servers may feel the same load as MMOG servers: average web server technology is much worse, especially if they use scripting languages. Nobody would make MMOG servers in PHP. They are compiled code, C++, C#, compiled Java, compiled Python. But many "Big" web sites run on (uncompiled) byte code. Better than the script, but still byte code.
  • Also, apart from good and bad technologies, there is good and not so good (=stupid) code. This happens to all types of systems and can make an MMOG more responsive than a web site at the same number of users.
  • Across all types of services, some are sharded, some are unique worlds. EVE-Online is unique, which means everyone can play with everyone. WoW is sharded into 1,000 (?) servers of up to 3,000 (?) concurrent players. Your friend is on a different server? you do not even chat to him. Sharding largely reduces communication and DB load. If shard=host then communication overhead disappears. A DB per shard allows for 100 or 1000 times less DB load per instance. This helps a lot.
  • After all, each category covers an order of magnitude. There is much room for "small" or "large" inside a category.
All in all, the classification into "Big", "Massive", "Mainstream" works.

Distributed systems do not really count here. This is about operating the resources required to support concurrent users. E.g. the Web is not operated by a single entity (though you could count the DNS). The Skype network has a (cool) architecture, that lets Skype, the company manage the network without the need to provide all required resources. Skype is also not an issue here. But most systems are operated by someone with a server farm and this is about what these people do.

So, these lessons are for "Big" systems. Actually primarily for web servers but also some messaging issues and general remarks. Some lessons are obvious, some are obvious in hindsight, some are not so obvious, some may be interesting even if you are one of the few (thousand) architects of big systems worldwide. Read the (far from complete but growing) list of lessons here.

6. August 2008

Neuer Server

Endlich mal abends Zeit gefunden den Server aufzusetzten. Der übliche Hetzner minimal-bootstrap, mit RAID1, dann:
- firewall
- apache
- php, memcache, apc
- minimales Hardening
- SSL Zertifikat
- default Virtual Server nur über https
- mysql, phpmyadmin
- ejabberd
und Domain Umzug im DNS.

29. Juni 2008

Trennung von Memcache und Web Server

Memcache (memcached) nimmt meiner Datenbank fantastisch viel Arbeit ab. Alle Objekte sind im Memcache, kein Code greift direkt auf die Datenbank zu. Die Datenbank wird dadurch um eine Größenordung entlastet. Was die Datenbank leisten müsste sieht man dann, wenn der Cache leer ist. Dann geht alles direkt auf die DB bis der Cache wieder gefüllt (warm) ist.

Der Memcache ist ein verteilter Speicher. Er ist verteilt über mehrere Rechner. Will man keine Rechner extra für den Memcache abstellen, dann verwendet man traditionell die Webserver auch als Memcache-Server. Das heißt nicht, dass es schneller wird, weil die meisten Zugriffe nicht lokal sind, aber billiger weil man keine extra Rechner braucht. Die Webserver hat man ja sowieso. Die Standardvorgehensweise ist also: 10 Webserver hinter einem Loadbalancer. Auf jedem Webserver ein memcached. Das wird deshalb empfohlen, weil Webserver vor allem CPU brauchen (CPU bound) und der Memcache vor allem Speicher (memory bound). Man kann also die jeweils "andere" Ressource auch noch nutzen.

Soweit die Standardvorgehensweise. Tatsache ist aber, dass bei PHP/Apache basierten Webservern (LAMP!) Webserver meistens auch memory bound sind. Apache und PHP werden nämlich normalerweise im Prefork-Modus verwendet. Also viele Apache Prozesse, jeder mit einer eigenen PHP-Runtime. Bei einer großen Applikation braucht ein so ein Apache/PHP Prozess schnell mal 16 MB Speicher. Der geteilte Speicher der verwendeten DLLs fällt kaum ins Gewicht. Das sind fast alles Daten. Ein Standardserver vom letzen Jahr hat 2 GB Speicher, 2 Cores. Will man 100 Apache Prozesse laufen lassen, bekommt man 16 MB x 100 = 1,6 GB. Da bleibt nicht mehr viel für den Memcache, der auch sein 1 GB pro Rechner haben sollte. Schließlich sind ja 1 Mio. User und zig Millionen Objekte im Cache. Dieses Jahr sind es 4 GB und 4 Cores, aber man erwartet auch 200 Prozesse pro Rechner, also auch nicht besser. Apache und Memcache konkurrieren um den Speicher.

Und es wird noch schlimmer. Apache und Memcache haben in der Standardkonfiguration unterschiedliche Verfügbarkeitsanforderungen. Webserver hinter dem Loadbalancer können ab und zu mal ausfallen. Der Loadbalancer merkt das schnell und nimmt sie aus dem Lastverteilungsverbund. Alle Daten, alle Sessions sind im Memcache und damit stets transferierbar. Aber: vom Memcache-Verbund darf kein einziger Rechner ausfallen. Selbst wenn man das schnell merkt und ihn aus dem Verbund nimmt, bedeutet der Ausfall eines einzigen Memcache-Servers einen 50% Cache-Flush. Memcache-Clients berechnen aus dem Key und den verfügbaren Memcache-Servern auf welchem Server die gefragten Daten liegen und holen sie direkt dort. Fällt ein Server aus, dann ändert sich die Zuordnung der Keys zu den Memcache-Servern. Die Daten bleiben dort gespeichert, aber die Clients finden sie nicht mehr und nehmen an, dass sie nicht da sind. Es gibt alternative Zuordnungsalgorithmen, die verhindern, dass sich alle Keys umsortieren. Das ist bitter nötig in großen Memcache-Clustern (Facebook: man spricht von 800 Rechnern mit viel Speicher). Denn dann fällt immer einer aus oder es kommt einer dazu.

Aber trotzdem reicht das nicht, denn Webserver sind manchmal überlastet und fallen für den Loadbalancer effektiv aus. Wenn auf dem gleichen Rechner ein memcached läuft und der auch nicht mehr antworten kann, dann fällt ein Teil (20% oder 10%) des Caches aus. Das treibt die Datenbank sofort zu Höchstleistungen und propagiert das Überlastproblem vom Frontend-Rechner zur DB. Das kann schnell die Performance des Gesamtsystems zerstören. Denn braucht die DB 1 h bei leerem Cache um den Cache zu füllen, dann führt der Ausfall von 1 aus 5 Memcaches immerhin zu 1h / 5 = 12 Minuten Überlast auf der DB. Das hört sich nicht gut an, denn eigentlich ist es das Ziel überhaupt keine Spannungssituationen zu erzeugen bloß weil ein Webserver ausfällt.

Webserver arbeiten viel mit der Festplatte. Das ist im high-performance Bereich auch zu vermeiden, aber ist trotzdem Standard im Medium-Segment. Geht die Festplatte kaputt steht der Webserver. Memcache arbeitet nur mit Speicher, überhaupt nicht auf der Platte. Steht die Platte kann er weiterarbeiten. Es ist unsinnig den Memcache von der Festplatte des Webservers abhängen zu lassen. Eigentlich sollte der Memcache-Server vom Netz booten und ohne Platte arbeiten. Ein Teil weniger was kaputt gehen kann, und zwar das häufigste.

Webserver und Memcache haben sehr unterschiedliche Profile und sollten deshalb nicht die Rechner teilen. Webserver (sollen nicht, aber) dürfen ausfallen, deshalb Software RAID-1. Memcaches (tun es, aber) dürfen nicht ausfallen, deshalb entweder RAID-Controller, damit die Platte im Betrieb getauscht werden kann oder gar keine Platte. Webserver so bemessen, damit sie CPU und Speicher Last tragen können. Separate Memcache-Server bemessen, so dass alle zusammen alle Daten der Applikation speichern können, die innerhalb der TTL der Cache-Items anfallen.

happy_coding()