Beim letzten mal war die versuchte Nutzung von Cloudhosting mit Heroku ein Reinfall. Relativ viel Arbeit für ein Scheitern an der Performance. Doch es gibt Alternativen zu Heroku, und AppFog ist eine, die mir sehr gut gefällt.
Auch AppFog unterstützt einen kostenlosen Account, bietet aber wesentlich mehr als Heroku: 2 GB statt 512 MB Ram, 8 Instanzen statt einem Worker und 8 mögliche sogenannte Services, darunter verschiedene Datenbanken. Es gibt auch Einschränkungen, die bei Heroku nicht erwähnt werden: 5 GB Traffic im Monat und ein Maximum von 100 Requests pro Sekunde. Unterschiedlich sind die Datenbanklimits und das Accountmodell: 100 MB bei AppFog gegen 10k Reihen bei Heroku, und AppFogs Ressourcen gelten accountweit, Herokus pro Anwendung. Völlig entfällt die ziemlich kritische Beschränkung, keine Hintergrundthreads laufen lassen zu können.
Wie gesagt, ich halte das AppFog-Angebot für wesentlich besser.
Instanz einrichten
Doch nicht nur das Hosting selbst ist besser, auch die Dokumentation drumrum gefiel mir besser. Sie ist auch schnell zusammengefasst. Statt direkt mit git wird mit einem Tool namens af gearbeitet:
gem install af
af login
Vom Kontrollzentrum kann die Beispielanwendung als .zip heruntergeladen werden. Mit ihr wird auch schnell klar, was sonst noch zu tun ist. Wieder muss eine Gemfile angelegt werden. Meine:
source :rubygems
gem "sinatra"
gem "thin"
gem 'pg'
gem 'json'
gem 'nokogiri'
gem 'rest-client'
gem 'haml
Ein
bundle install
später kann die Anwendung per
af update APPFOG-SERVERNAME
hochgeladen werden. Die app.rb kann mit jeder anderen Datei ersetzt werden, welche Datei ausgeführt werden muss, wird durch das require 'sinatra'
erkannt - sehr nett!
Datenbank aktivieren
Da die Anwendung vom letzten mal schon für PostgresSQL angepasst war, blieb das natürlich als Datenbank gesetzt. Die Datenbank kann im Kontrollzentrum als Service aktiviert und dort benannt werden. Dann werden die Einloggdaten als Umgebungsvariable der Anwendung gegeben, und diesmal gibt es tatsächlich ordentlichen Beispielcode (mit dem kleinen Fehler, dass dort im Original :username statt :user steht):
services = JSON.parse(ENV['VCAP_SERVICES'])
postgresql_key = services.keys.select { |svc| svc =~ /postgresql/i }.first
postgresql = services[postgresql_key].first['credentials']
postgresql_conn = {:host => postgresql['hostname'], :port => postgresql['port'], :user => postgresql['user'], :password => postgresql['password'], :dbname => postgresql['name']}
@db = PG.connect(postgresql_conn)
Ansonsten gelten natürlich die gleichen Hinweise wie bei Heroku, wenn von sqlite aus umgestellt werden muss.
Gut funktionierte bei Heroku der Zugriff auf die Datenbank von außen. Auch bei AppFog ist das gut gelöst, wobei ich die Lösung erst finden musste. Das Stichwort ist Tunnelling:
gem install caldecott
af services
af tunnel DATENBANKNAME
Fazit
AppFog hatte natürlich den Vorteil, dass durch den vorherigen Versuch mit Heroku mir ziemlich klar war, wie das alles funktionieren müsste - reduzierte Verwirrung führt schnell zu einem besseren Eindruck. Aber auch ohne diesen Vorteil ist AppFog meiner Meinung nach klar die bessere Wahl:
- Wesentlich umfangreicheres kostenloses Angebot...
- ...mit tatsächlich deutlich besserer Performance.
- Klarer strukturierte Dokumentation, inklusive Beispielcode für die Datenbankanbindung (wie kann sowas fehlen?).
Aber der wichtigste Vorteil von AppFog ist, dass meine Anwendung hier funktionierte und auf Heroku nicht. Und das lag höchstwahrscheinlich am Serverstack und damit an Heroku, nicht an der Anwendung selbst (wie erwähnt konnte ich Herokus Analysetool nicht testen). Rsspusher trägt sich bei verschiedenen PuSH- bzw rssCloud-Hubs als Abonnent ein, und dieses Eintragen muss bei beiden Protokollen jedes mal bestätigt werden, indem von dem Hub ein GET an rsspusher geschickt wird, wobei die so gesendete Challenge zurückgegeben werden muss. Das war auf dem Entwicklungsrechner kein Problem, das war auf AppFog kein Problem, aber unter Heroku lief das jedes mal in ein das Zeitlmit von 2 bzw 3 Sekunden, weil die Anfrage laut Log im Heroku-Stack alleine solange hängen blieb. Ich weiß nicht, ob das an dem einzelnen Worker hing (eigentlich ist das kein Grund, ein Worker kann mehrere Anfragen parallel bearbeiten), aber das war definitiv kein guter Eindruck.