% $Id$ % Mise au point \documentclass[a4,landscape,article]{seminar} % Impression réelle %\documentclass[a4,landscape,slidesonly]{seminar} \usepackage[latin1]{inputenc} \usepackage{fancybox} \usepackage{eepic} \usepackage{latexsym} \usepackage{bortzmeyer-utils} \newpagestyle{MH}% {\thepage} {echoping\hfil} \slidepagestyle{MH} \pagestyle{empty} \title{echoping, mesurer les applications} \author{Stéphane Bortzmeyer\\ AFNIC\\ \url{} } \date{4 octobre 2004} \begin{document} \begin{slide} \maketitle \addtocounter{slide}{-1} \slidepagestyle{empty} \end{slide} \begin{slide} \heading{Mesurer les applications} \begin{itemize} \item On mesure souvent le temps de réponse du réseau (RTT) avec ping \item Mais celui des applications peut être très différent \begin{enumerate} \item Unix : traitement par le noyau ou par une application qui \foreign{swappe} \item Délais spécifiques à l'application (contacter la base de données\ldots) \item Coupe-feux qui bloquent ICMP \item \foreign{Layer-4 or Layer-7 switches} qui traitent différemment ICMP et TCP \end{enumerate} \end{itemize} \end{slide} \begin{slide} \heading{Limite des outils classiques} Certains outils n'ont pas de mesure du RTT : on les emballe avec \computer{time}. Inconvénients : \begin{enumerate} \item On mesure le temps de résolution DNS, \item On mesure le temps de lancement du programme (s'il est en Perl, cela fausse tout)\ldots \end{enumerate} Certains outils ont la mesure de RTT (\computer{dig}). Mais pas de possibilité de répéter le test donc, il faut utiliser \computer{awk} si on veut des statistiques. \end{slide} Exemple avec dig, le script qtest, qui détermine le serveur le plus rapide (BIND utilise un algorithme analogue pour savoir quel serveur d'un domaine interroger). \begin{info} #!/bin/sh # # From: Joe Abley query=$1; shift # [ -z "$*" ] && echo "Syntax: $0 query server..." && exit 1 # for i in 0 1 2; do for server in $*; do dig @${server} ${query}; done done | \ awk '/^;; Query time:/ { query_time = $4; } \ /^;; SERVER: / { sum[$3] += query_time; num[$3]++; } \ END { for (server in sum) { print int(sum[server]/num[server]), server; } }' | \ sort -n | head -1 \end{info} \begin{slide} \heading{echoping} \url{http://echoping.sourceforge.net/} 9 ans d'utilisation aujourd'hui. A surtout décollé dans le cadre du projet Renater-Cache (mesurer le temps de réponse du cache national, par exemple avant et après un réglage). Mesurer le RTT d'une requête applicative. Le chrono est lancé \emph{après} la résolution DNS. Tourne sur tout Unix, en ligne de commandes, pour utilisation par des scripts (mon, Nagios, MRTG, Smokeping). Smokeping (\url{http://www.smokeping.org/}) est de loin le plus gros utilisateur d'echoping. \end{slide} \begin{slide} \heading{Protocoles utilisés} \begin{enumerate} \item Au début, echo, discard et chargen \item Puis HTTP (Renater-Cache), toujours le plus utilisé \item Demain, DNS, whois, PostgreSQL, LDAP\ldots \end{enumerate} \end{slide} \begin{slide} \heading{Répétition des tests} Comme ping, on peut répéter les tests et avoir des statistiques. \begin{info} % echoping -h 10 -h / webmail.nic.af ... Minimum time: 1.799637 seconds (142 bytes per sec.) Maximum time: 16.494219 seconds (16 bytes per sec.) Average time: 3.356738 seconds (76 bytes per sec.) Standard deviation: 3.730219 Median time: 2.003397 seconds (128 bytes per sec.) \end{info} \end{slide} \begin{slide} \heading{Moyenne et médiane} Sur l'Internet, ou sur un serveur chargé, la moyenne est peu significative : un seul test très lent la change beaucoup. La médiane est en général plus informative. \begin{info} Elapsed time: 3.030966 seconds Elapsed time: 122.533918 seconds Elapsed time: 2.394198 seconds Elapsed time: 2.012312 seconds Elapsed time: 1.432407 seconds ... --- Minimum time: 1.432407 seconds (179 bytes per sec.) Maximum time: 122.533918 seconds (2 bytes per sec.) Average time: 11.393709 seconds (22 bytes per sec.) Standard deviation: 26.072556 Median time: 2.712582 seconds (94 bytes per sec.) \end{info} \end{slide} %\begin{slide} % \heading{Les temps de réponse et leur variation} %\input{whois-ripe.epic} %\end{slide} \begin{slide} \heading{Les greffons} Beaucoup d'utilisateurs réclamaient le support de tel ou tel protocole. Souvent, ils envoyaient le \foreign{patch}. Le code devenait de plus en plus complexe. Et dépendant de bibliothèques extérieures. echoping 6 introduira donc les greffons (\foreign{plug-ins}), écrits à part et chargés dynamiquement. \end{slide} \begin{slide} \heading{Utiliser le greffon DNS} \begin{info} % echoping -v -m dns ns2.nic.fr -t NS nic.fr This is echoping, version 6.0-BETA. Running start() for the plugin dns.so... Trying to call plugin dns.so for internet address 192.134.0.4 53... Elapsed time: 0.001717 seconds \end{info} \end{slide} \begin{slide} \heading{Utiliser le greffon PostgreSQL} \begin{info} % echoping -v -m postgresql localhost -c 'dbname=essais' \ 'SELECT * FROM Foobar' This is echoping, version 6.0-BETA. Running start() for the plugin postgresql.so... Trying to call plugin postgresql.so... 3 tuples returned Elapsed time: 0.058392 seconds \end{info} \end{slide} \begin{slide} \heading{API des greffons} Les greffons se programment en C \begin{itemize} \item \computer{char * init (const int argc, const char **argv, const echoping\_options options)} Initialise \item \computer{void start (struct addrinfo *res)} Se connecte \item \computer{int execute ()} Le chronomètre est lancé juste avant \item \computer{void terminate ()} \end{itemize} \end{slide} Exemple avec le greffon whois, le plus simple vue la simplicité du protocole (\rfc{3912}) : \begin{info} char * init (const int argc, const char **argv, echoping_options global_options) { /* Analyse les arguments */ return "nicname"; } void start (struct addrinfo *res) { whois_server = *res; } int execute () { int nr = 0; char recvline[MAX_LINE + 1]; char complete_request[MAX_REQUEST]; if ((sockfd = socket (whois_server.ai_family, whois_server.ai_socktype, whois_server.ai_protocol)) < 0) err_sys ("Can't open socket"); if (connect (sockfd, whois_server.ai_addr, whois_server.ai_addrlen) < 0) err_sys ("Can't connect to server"); if ((files = fdopen (sockfd, "r")) == NULL) err_sys ("Cannot fdopen"); sprintf (complete_request, "%s\r\n", request); n = strlen (complete_request); if (writen (sockfd, complete_request, n) != n) err_sys ("writen error on socket"); /* Read from the server */ while ((nr = readline (files, recvline, MAX_LINE, 0)) > 0) if (dump) printf ("%s", recvline); if (dump) printf ("\n"); close (sockfd); return 1; } void terminate () { } \end{info} \end{document}