Heute stand wieder mal eine Server-Migration an. Die Weblins wurden vom Ein-Server-Testbetrieb zum aktuellen Produktiv-Cluster migriert. Das war meine bisher schönste Migration:
- Server installieren,
- Konfigurationsdaten anpassen,
- Daten migrieren,
- Integrationstests checken,
- DNS umschalten,
- fertig.
Zugegeben, langsam bekomme ich Übung. Angefangen hat alles mit einem Entwicklungsserver. Dann kam das erste Produktiv-System aus 2 Hetzner-Servern. Darauf folgte ziemlich schnell das erste echte Rechenzentrum aus 10 Servern, genannt: der Proton-Cluster. Der wurde dann ausgebaut bis zu 60 Hosts. Vor 2 Monaten habe ich alles auf einem Server installiert als Testbetrieb mit einem simulierten Cluster (genannt Delta). Zwischendurch gab es noch eine Installation des gesamten Systems auf einer VMware. Heute dann die bisher letzte Installation (genannt Atlas) auf mehreren Servern, die sich die ca. 8 Rollen teilen.
Weblin ist ein komplexes System. Viele Subsysteme, zusätzlich zur Website auch noch ein Client und das Instant Message-System. Trotzdem ist es gut handhabbar, läuft stabil und ist flexibel, wie die unterschiedlichen Setups zeigen. Wäre es nicht so gut in Schuss, dann hätte ich es nicht wieder zum Laufen bekommen.
An Weblin Client und Portal haben viele Leute gearbeitet. Bei denen möchte ich mich hier für mich und im Namen der User bedanken: Entwickler im T-Team und iTeam, Research-Team und Praktikanten, Operating und Code-Review, Design und Content, Partner-Integration und Community-Management. Und nicht zuletzt die, die in letzter Zeit mit Rat (=Consulting) und Tat (=Twincoding) geholfen haben.
Ein paar meiner "Learnings":
- Viele gut ausgeprägte Server-Rollen helfen dabei groß (und klein) zu skalieren.
- Konfiguration zentralisieren und das dann durchhalten, wenn viele Rollen und Subsysteme dazukommen.
- Konsequentes Durchziehen einer verteilten Architektur hilft, auch wenn es manchmal mehr Arbeit macht.
- Ausführliche Integrationstests helfen Konfigurationsprobleme aufzuspüren.
- Refactoring hält jung.
- Technische Lösungen nicht ausreizen. Immer noch eine Optimierung in petto haben.
- Ich kann programmieren, deshalb funktionieren für mich eigene Lösungen, z.B. beim Backup (scp, rsync, tar) und beim Setup (svn und Shellskripte). Und das ist auch gut so.
Jetzt sind wir richtig online.
Weblin is back.
Und das ist erst der Anfang.
_happy_migrating()
13. November 2011
Server Migration
Labels: weblin
5. November 2011
Throttling Bandwidth with Linux Tools
The problem: Backup interferes with normal operation
Backup is running at the same time as the normal operation of the production system and the system is already quite busy. Copy and transfer tools take as many resources as they can get from CPU, DMA and network. This usually interferes with the normal server operations and can even bring down the server (thank you DMA).
The solution: Throttling
Many of the tools have a throttling option, which can limit the bandwidth in network transfers and file system operations.
scp:
- Option -l limits the used bandwidth, specified in Kbit/s.
- Example for max 5 MByte/sec: scp -l 40000 myfile $user@$host:
- Option --bwlimit limits I/O bandwidth in KBytes per second.
- Example for max 5 MByte/sec: rsync --bwlimit 5000 myfile destfolder
- Setting "net:limit-rate" limits transfer rate on data connection in bytes per second.
- Example for max. 5 MByte/sec: echo "set net:limit-rate 5000000; put myfile" | lftp -u $user,$password $host
- cstream can limit throughput of pipes with option -t in bytes per second.
- Example for max 5 MByte/sec: tar cf - myfolder | cstream -t -5000k > myfolder.tar
- Use "-5000k" instead of "5000k" to never exceed the max. Otherwise cstream saves throughput it could not use for later, which may be more bursty.
Labels: Linux
1. Oktober 2011
KLab geht an die Börse
Die Firma KLab ist in Tokio erfolgreich an die Börse gegangen. Die Aktien wurden für 1700 Yen ausgegeben. Der Handel begann dann mit 3970 und 3 Tage später stehen sie bei 3500. Also kein schlechter Start. Das ist der erste Börsengang einer Social-Network / Casual-Game Firma in Japan. Vielleicht sogar weltweit. Der Buzz sagt: "Zynga of Japan". KLab ist eine Nummer kleiner als Zynga, aber ziemlich erfolgreich mit Social Games und virtuellen Gütern.
Wichtiges Projekt im Börsenprospekt einer Firma mit US$ 200 Mio. Marktkapitalisierung. Coole Sache das.
Labels: Financial, Japan, virtual presence
17. September 2011
Im VMware Player vom ISO Image installieren
Für Noob-Admins wie mich: Debian in VMware Player vom ISO-Image installieren
ide1:0.autodetect = "TRUE"ide1:0.deviceType = "cdrom-image"ide1:0.fileName = "C:\debian-6.0.2.1-i386-netinst.iso"ide1:0.present = "TRUE"
ide1:0.fileName = ""ide1:0.present = "FALSE"
Labels: Linux
31. August 2011
28. August 2011
Galaxy Tab wiederbeleben - ein Wunder
Heute mal ein (weniger tiefschürfender, aber doch bewegender) Microblog:
14. August 2011
Zweitgeist Kündigung aufgehoben
Labels: Persönlich, Realwelt
4. August 2011
Adwords Test gesponsort von Google
Google hat mir vor einiger Zeit einen 100 € Adwords Gutschein geschickt. Anscheinend gräbt Google inzwischen auch Registergerichte durch nach neuen Firmen. Mir solls recht sein. Besser als noch ein Büromaterial-Katalog.
Das - dachte ich mir - ist doch eine gute Gelegenheit, mal kostenlos mit Adwords zu experimentieren. Die Kampagne von Google wendet sich an alle möglichen IT-Firmen. Also - dachte ich mir - muss man nicht unbedingt SEO/Adwords Experte sein, um das Angebot zu nutzen. Adwords - dachte ich mir - wird schon so einfach sein, dass ich es auch verstehe. Schliesslich - dachte ich mir - wollen sie ja, dass die kostenlose Adwords Kampagne so gut gefällt, dass man noch etwas mehr investiert. Falsch gedacht.
Adwords ist nicht für Dummies und nicht für Handbuch-Ignorierer, wie mich. Die Kampage ist zwar einfach aufgesetzt, funktioniert aber leider nicht. Ich bekomme keine Klicks. Die Ads werden gar nicht angezeigt, weil angeblich die Keyword-Relevanz zu schlecht ist.
Am Inhalt kann es nicht liegen. Der Inhalt besteht aus Massen an selbstgeschriebenen Text zu einem bestimmten Thema. Die Seiten sind reichhaltig, fokussiert, originär: www.galactic-developments.de. Daran kann es nicht liegen. Die Keywords stammen aus dem Text und jedes Keyword linkt auf die Seite aus der es stammt. Trotzdem werden die Keywords nicht angezeigt. Selbst wenn ich wollte, könnte ich nichts investieren, um die Website zu pushen, denn Google will mein Geld nicht.
Mögliche Schwachstellen meiner Kampagne:
- Die Website hat keine META-Keywords.
- Die Landing Pages haben nicht das Keyword im Title.
- Die Kampagne hat nur ein Ad. Man könnte für jeses Keyword ein Ad machen.
- Die Keywords kommen nicht im Ad-Text vor.
- Die Website ist nicht SEO-optimiert.
- Ich habe nichts zu verkaufen. Adwords ist für Shops gemacht, die immer direkt auf ein Produkt linken.
14. Juni 2011
An HTML based Chat Window with WebKit, jQuery, and tricks
Over the weekend I was working on the OVW chat window. The chat window is very similar to the avatar display and also very different. The similarities are:
- both are display modules
- both use WebKit
#ChatOut .cNickname { font-weight:bold; }
- chat is a dialog where the Chat.html code is in an IFRAME
- avatar display paints directly, has no dialog frame
function ContentEval(sCode)
{
return document.getElementById('Content').contentWindow.EvalJS(sCode);
}
7. Juni 2011
More OVW Progress
Another week of evenings and weekend worth of progress on the next weblin generation (OVW). I am now working on browser tracking, support for multiple tabs and the multiple views for the same scene.
1. Juni 2011
Open Virtual World Progress
The Open Virtual World project makes significant progress. I am now using WebKit for all user interface components. WebKit is the HTML rendering engine that drives Google Chrome, Safari, and many mobile browsers, because it is easy to integrate and has a good open source license. WebKit is a C++ library and it has a brand new transparency feature. WebKit with transparency is perfect to paint avatars over browser windows.
$(this).animate( { bottom: '0px' }, 800 );
Labels: Avatar, C++, Code, Javascript, virtual presence
20. Mai 2011
Technologie und idiotische Investoren
Gerade komme ich wieder mal von einem Barcamp/Conference/Unconference zurück. Da gab es wieder allerlei interessante Vorträge über Technologien und Arbeitsmethoden. Dabei haben wir (ehemalige Mitarbeiter von Weblin) festgestellt, dass das was wir vor 3-5 Jahren gemacht haben, jetzt für die Masse der Entwickler interessant ist. Wir haben damals Probleme erkannt und gelöst, die immer noch aktuell sind und inzwischen wenigstens von den meisten anderen Teams auch angegangen werden.
- MVC Frameworks,
- PHP Accelerator,
- Memcache mit strukturiertem, versioniertem Caching,
- Cache-All-Strategie,
- Monitoring,
- Unit-Tests, Integration-Tests,
- SCRUM,
- vertikal integrierte Teams,
- öffentliche live Dashboards,
- Cloud,
- Service Oriented Architecture,
- Load Balancing ohne Session-Binding,
- Zero-Bug Policy
Technologie zählt. Alle Firmen, die Erfolg haben, haben super Teams im Hintergrund. Werft das Technik-Team weg und ihr habt nichts. Facebook, Zynga, Bigpoint kaufen Firmen nur, um an die Technik-Teams zu kommen. Für alle, die es noch nicht gemerkt haben: die Zeiten ändern sich.
8. März 2011
Simple Dependency Injection
Dependency injection (DI) is very useful for isolated tests. In short:
Assumed you have a user table in the database. Assumed, that the user table is accessed through a class UserDatabase. Your application wants to cache users for quicker access. This means, that there is at least a list of users in memory. Usually you would wrap this list into a class UserManager. The typical code of UserManager will instantiate a UserDatabase, like:
class UserManager {
UserDatabase DB = new UserDatabase();
UserManager() {}
public UserId CreateUser() {
return DB.CreateUser();
}
...
}
If you want to test UserManager.CreateUser(), then the method needs a UserDatabase instance which will access the real database. This is not what you want, because it is not isolated. You want to test UserManager without activating UserDatabase. It rather would be cool if the UserManager would use a dummy database class which just simulates the behaviour of UserDatabase without actually writing to the real database.
So, we want to equip the UserManager for the test with a MockDatabase, but for the real operation it should use the real UserDatabase. We want to decide which database class the UserManager will be using under which circumstances. Means: we make the proper database and hand it to the UserManager. We inject it. Example:
class UserManager {
UserDatabase DB;
UserManager() { // real constructor
DB = new UserDatabase();
}
UserManager(UserDatabase db) { // test constructor
DB = db;
}
public UserId CreateUser() {
return DB.CreateUser();
}
...
}
The test code will create a new MockDatabase() and use UserManager(UserDatabase db) to inject it. The real code will use the default constructor, which makes its own normal UserDatabase. Not pretty, but possible. If there are more dependencies, then things get nasty with large contructors which are only used for tests and have different code from the real constructor. Not pretty.
There are better ways. For example DI frameworks, which provide sophisticated methods for injecting dependencies without bloating constructors. They use extensive configuration, if you like. I used StructureMap. It works, but I do not like, that I have to learn it. I spend a few hours reading, learning, trying, and even a few hours on it's unexpected limitations. Now I can use StructureMap, but I do not recommend it, if you do not already know it.
Dependency injection can be simpler. Here is my take: we want, that UserManager uses either MockDatabase or a UserDatabase. Why not just tell the UserManager to Use() either database:
class UserManager {
UserDatabase DB { get; set; }
UserManager Use(UserDatabase db) { DB = db; return this; }
public UserId CreateUser() {
return DB.CreateUser();
}
...
}
The test code will then look like:
var um = new UserManager().Use(new MockDatabase());
The production code will be very similar:
var um = new UserManager().Use(new UserDatabase());
The return this; part in Use() takes care, that the configuration can be written in a single line. If there are multiple dependencies, then I can do:
var um = new UserManager()
.Use(new MockDatabase())
.Use(new DummyWebService())
.Use(new TestController());
...because all the different Use() Methods have different parameters types and automatically know what to do. That's it. Use() is my DI framework.
And here comes my favorite single line of dependency injected configuration for a unit test. An ItemCore which uses a RezMockConnection and an ItemRepository which itself uses a MemoryItemStorage.Factory:
var rep = new ItemCore().Use(new ItemRepository().Use(MemoryItemStorage.Factory)).Use(new RezMockConnection()).Repository;
_happy_using()
Labels: Code
27. Februar 2011
A Busy Spaceport in Earth Orbit
- 2 russian soyuz crew vehicles
- 1 russian progress transporter
- a japanese HTV transporter
- a european ATV transporter
- an american space shuttle
2 x Soyuz TMA-20 & TMA-01M Russia | Progress M-09M Russia | HTV-II Kounotori 2 Japan | ATV-2 Johannes Kepler Europe | Space Shuttle Discovery USA |
Skylab | Salyut | ISS |
2. Februar 2011
2 1/2 Zi. Wohnung in Freiburg zu vermieten ab 1.4.2011
Anzeige:
Labels: Realwelt
2. Januar 2011
OAuth for TwiX
I finally added OAuth to TwiX, the Twitter-XMPP gateway.
Since August 2010 Twitter requires OAuth for API access. This is extremely stupid for background daemons like TwiX which do not have a user interface and especially no browser based UI.
TwiX is my C# playground. So, I needed an OAuth library for C#. TwiX runs on mono and .NET. I am running my instance of TwiX on a Linux server. Luckily almost all .NET libraries run without modification on mono.
A quick research returned several OAuth libraries, some are for ASP.NET, which I do not use, because TwiX is a faceless server daemon, not a Web application. I zeroed in on Shannon Whitley's implementation which comes with a handy sample project.
This example project has
- an OAuth core implementation
- a Twitter OAuth adapter
- a sample desktop app with embedded browser
= cool thing
I used the 2 OAuth classes in TwiX and converted the sample desktop app into a Twitter OAuth token generator tool (see screen shot). 1 hour of work, thanks Shannon.
This is a general Twitter token generator. It is not just for TwiX. The OAuthTwitterDesktopTool generates a twitter token and token secret for every Twitter app, if you know the app's consumer key and consumer secret. The OAuthTwitterDesktopTool is part of the TwiX distribution.
You can find TwiX with OAuth and the token generator on the TwiX homepage.
_happy_authorizing()