Freitag, 1. Dezember 2017

Software Zuverlässigkeit, Verfügbarkeit und Six Sigma

Alle nicht-funktionalen Anforderungen (NFA) an Software zahlen auf die Verfügbarkeit der Software ein. Aber welche Verfügbarkeit soll man anstreben?

Zu erst nach dieser Formel wird die Verfügbarkeit berechnet:

Verfügbarkeit [%] = (Gesamtzeit - Zeit mit Fehlern) * 100 / Gesamtzeit

Bei klassischen Industrieprodukten nimmt man eine Zeitspanne die auf der durchschnittlichen Lebenszeit der Produkte basiert (MTBF). Aber bei Software gibt es keine MTBF, weil die Ausfälle von Software weder auf Verschleiss wie bei mechanischen Produkten oder dem Zufall wie bei elektronischen Bauteilen beruhen. Deshalb wird bei Server-Diensten wie E-Commerz Lösungen oft die letzten 365 Tage als Betrachtungszeitraum genommen. Aber was bedeutet ein Verfügbarkeitswert von 99.9%, ist das gut? Die Antwort ist ... ein bisschen komplizierter. Zuerst mal ein kleine Übersicht was solche Prozentwerte eigentlich an Zeit bedeuten:



D.h. bei einer Verfügbarkeit von 99.9% habe ich mehr als 8h Ausfall im Jahr. Das ist sicher mehr als man bei einer hohen Zahl wie 99.9% erwartet hätte. Aber welche Werte sollte man für die Verfügbarkeit anstreben? Im Gegensatz zu mechanischen oder elektronischen Systemen kann man sich bei Software auf noch keinen Standards oder Normen abstützen. Aber es gibt als universelles Qualitätsmanagementsystem Six Sigma. Man kann jetzt versuchen Six Sigma auf Softwarezuverlässigkeit anzuwenden. Als Grenzwert bzw. anzustrebender Wert bietet sich Level 6 von Six Sigma an mit einer Wert von 99,99966% Fehlerfreiheit an. Setzt man diese Zuverlässigkeit zu Grunde, dann hat man nur noch 1,8 Minuten Ausfall im Jahr.

Nachdem das Ziel klar ist, stellt sich jetzt die Frage, ist dieses Ziel realistisch und wie kommt man dahin?

Mittwoch, 29. November 2017

Warum wir Robustness Test brauchen.

Es gibt einen sehr einfachen Grund für Robustness Tests, Robustness Tests helfen dabei die Verfügbarkeit von Softwaresystemen zu steigern. Es gibt drei wesentliche Einflussfaktoren die zu einer Reduzierung der Softwarezuverlässigkeit führen:

  1. Anzahl bzw. Frequenz von Störfällen (Incidents)
  2. Dauer von Störfällen (Duration of Incidents)
  3. Auswirkung oder Umfang von Störfällen (Impact of Incidents)
Robustness Test wirken sich positiv auf alle drei Faktoren aus.
  1. Robustness Test ermöglichen es ein Softwarearchitektur zu wählen bei denen ein Störfall auf das betroffene System beschränkt bleibt und es zu keiner Fehlerkaskade kommt. So wird im Falle eines Störfalls der Umfang begrenzt.
  2. Durch die Reduktion des Umfangs des Störfalls auf eine Einzelsystem wird für die Wiederherstellung des Betriebs weniger Zeit benötigt. Es sind keine Aufwendigen Startprozeduren notwendig wie z.B. starte als erstes Db Server, dann die App Server, warte auf App Server für 3 Minuten bis sie voll funktionsfähig sind, 3. wäre Cache vor, ...
  3. Und als drittes führen Robustness Test zum frühzeitigen Aufdecken von noch unbekannten Problemen die in der Zukunft zu Störfällen geworden wären.
  4. Und als letztes verhindern Robustness Test das Wiederauftreten bekannter Störfälle in dem man bekannt Störfallszenarien als Robustness Test umsetzt und regelmässig testet. Auch so wird die Anzahl der Störfälle reduziert. Für diesen Fall kann man auch eine Testabdeckung berechnen, d.h. wieviele bekannt Störfälle werden regelmässig durch Robustness Test abgedeckt, bzw. simuliert.

Zusammenfassend kann man festhalten Robustness Test sind sie Art von Test die man zum prüfen von nicht-funktionalen Anforderungen (NFA) benötigt.

Montag, 26. Juni 2017

Nicht-funktionale Anforderungen: Seamless Deployment

Ein System soll unter Last deployed werden können ohne das es negative Auswirkungen auf den Kunden hat, das bezeichnet man als Seamless Deployment. Vor allem ist diese Anforderung wichtig, weil durch das Heute übliche Continuouse Deployment (CD) permanent neue Softwareversionen released werden. Dieser Test muss unter üblichen Lasten d.h. Volllast durchgeführt werden.

Montag, 12. Juni 2017

Bad Code: Multiple Exit Point Problem

Lange war mir nicht klar warum multiple Exit Points ein Problem sein sollen. Sei sind eine einfache Möglichkeit schlanken und einfachen Code zu schreiben. Bis jetzt.

Ich muss gerade bestehenden Code für Monitoring instrumentalisieren, das mache ich auf sehr einfache und verständliche Art mittels System.currentTimeMillis().  Das Hauptproblem sind multiple Exit Points:

  1. Exit Points können übersehen werden. Das passiert bei langen Methoden manchmal nicht sehr schnell. 
  2. Das Code auf Try Blöcken entfernt werden (Premature Optimization) und ich Code umkopieren muss um die Logik zu erhalten. Oder anders ausgedrückt: Code der eigentlich zum Try gehört aber sich nicht im Try Block befindet. Er steht nach dem letzten Catch, welche return Anweisungen enthalten. Dieser Code muss wieder in den Try Block eingefügt werden.


Fazit:

  1. Multiple Exit Points sind keine gut Idee, 
  2. Ausser die Methode ist ein 5-Zeiler.
  3. Unit-Test sind die Basis des erfolgreichen Refactorings.



Zurück auf den alten Stand mit Git

Wenn man z.B. den Master oder einen wichtigen Branch zerstört hat und auf einen funktionierenden Softwarestand zurückkehren möchte muss man folgende zwei Schritte durchführen:

1) Den HEAD auf den entsprechenden funktionierenden Commit zurücksetzen und diese Änderung auf den Master pushen:
git revert --no-commit 14y6c335..HEAD
git commit
git push
Jetzt funktioniert der Master und Head wieder.


2) Lokal sind noch die alten, also die defekten Daten vorhanden, die kann man jetzt ggf editieren oder einen neuen Branch erzeugen oder einfach zurücksetzen. Dann ist die lokale Kopie wieder identisch mit dem Master und Head.
git reset HEAD --hard

Mittwoch, 26. April 2017

Docker: Oracles Java auf einem Ubuntu Image

Das geht ganz einfach, bei den meisten gängigen Images bekommt man OpenJDK oder die Images sind nicht gewartet. Also hier eine relativ einfache, mögliche Lösung:

FROM ubuntu:latest
MAINTAINER mirko.ebert@g****.com

RUN apt-get update; apt-get -y upgrade
RUN apt-get -y  install software-properties-common
RUN add-apt-repository ppa:webupd8team/java
RUN apt-get update
RUN echo debconf shared/accepted-oracle-license-v1-1 select true |  debconf-set-selections
RUN echo debconf shared/accepted-oracle-license-v1-1 seen   true |  debconf-set-selections
RUN apt-get -y  install  oracle-java8-installer


RUN apt-get clean

Donnerstag, 6. April 2017

R Package Helper: Finden aller benötigten R Pakete

So kann man alle R Pakete in einem Projekt finden und in eine Datei schreiben.

grep -r -h library src | tr -d '()' | tr '"' ' ' | awk '{print $2}' > DEPENDENCIES.txt

Später kann man diese Datei im Dockerfile verwenden um im Docker alle benutzen R Pakete zu installieren:

COPY DEPENDENCIES.txt /DEPENDENCIES.txt
RUN cat /DEPENDENCIES.txt \

    | xargs -i Rscript -e 'install.packages("{}", repos="http://cran.us.r-project.org")'