sábado, 28 de fevereiro de 2009

Programa livre para teste de servidores Web

Na busca de uma ferramenta para testar uma aplicação que rodava em um servidor web, além do tradicional Jmeter, encontrei um utilitário da apache para linux chamado ab.

O ab (Apache HTTP server benchmarking tool), é uma ferramenta para benchmarking de servidores web da apache (HTTP). Com essa ferramenta possibilita medir o desempenho de sua versão atual do servidor, mostra especialmente quantas requisições por segundo o servidor é capaz de responder.

Para instalar o ab, utilize a seguinte linha de comando:


sudo apt-get install apache2-utils



Um exemplo de utilização:


sudo ab -n 1000 -c 10 -X 192.168.1.114:3128 -e result.csv http://localhost:8080/minhaAplicacao/index.jsp



Segue abaixo a descrição dos parâmetros utilizados no teste:

Parâmetros utilizados:

-n : número de requisições do teste
-c : concorrência, representa o número de usuários simultâneos por requisição
-X : endereço IP do servidor proxy (só utilize esse opção se usar um proxy)
-e : escreve um arquivo .CSV (valores separados por vírgula) contendo a cada porcentagem (1%-100%) o tempo gasto pelo servidor para responder as requisições


Resultado da execução do teste:



This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost [through 192.168.1.114:3128] (be patient)
Completed 100 requests
Completed 200 requests
...
Completed 900 requests
Finished 1000 requests


Server Software: squid/2.6.STABLE16
Server Hostname: localhost
Server Port: 8080

Document Path: /minhaAplicacao/index.jsp
Document Length: 1087 bytes

Concurrency Level: 10
Time taken for tests: 10.509680 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Non-2xx responses: 1000
Total transferred: 1503000 bytes
HTML transferred: 1087000 bytes
Requests per second: 95.15 [#/sec] (mean)
Time per request: 105.097 [ms] (mean)
Time per request: 10.510 [ms] (mean, across all concurrent requests)
Transfer rate: 139.59 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.3 0 1
Processing: 101 103 1.6 104 110
Waiting: 101 103 1.4 104 109
Total: 101 103 1.7 104 110

Percentage of the requests served within a certain time (ms)
50% 104
66% 105
75% 105
80% 105
90% 105
95% 106
98% 106
99% 106
100% 110 (longest request)



Nesse teste, fiz 1000 requisições com 10 usuários acessando a página simultaneamente por requisição, obtive um tempo médio por requisição de 105ms e verifiquei também que meu servidor (Tomcat 5.5) conseguiu responder em média 95.15 requisições/segundo.

Essa ferramenta é simples de ser utilizada, pode ser usada para medir desempenho de servidores HTTP.

Referência:
http://httpd.apache.org/docs/2.0/programs/ab.html

domingo, 15 de fevereiro de 2009

JAVA: Converter Imagem para Escala de Cinza

Um exemplo básico de processamento de imagens em JAVA é a conversão de uma imagem colorida para escala de cinza.

Esse exemplo (MainClass) mostra como efetuar a leitura dos pixels de uma imagem, converter seus valores para RGBA (red, green, blue, alpha), modificar os pixels e gravar uma nova imagem.




import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class MainClass {

// converte pixels da imagem para tons de cinza
public static int[] imageToGray(int image[]) {
int grayimage[] = new int[image.length];

for (int i = 0; i < image.length; i++) {
// extrai a informação RGBA do valor inteiro
int alpha = (image[i] >> 24) & 0xff;
int red = (image[i] >> 16) & 0xff;
int green = (image[i] >> 8) & 0xff;
int blue = (image[i]) & 0xff;

// média dos valores RGB para tranformar para
// escala de cinza
int mean = (red + green + blue) / 3;

// converte a informação de rgb para inteiro
int gray = ((0 << 24) & 0xFF000000) | ((mean << 16) & 0x00FF0000) | ((mean << 8) & 0x0000FF00) | (mean & 0x000000FF);

// seta o pixel modificado na imagem
grayimage[i] = gray;
}

return grayimage;
}

public static void main(String[] args) throws IOException {

File inputFile = new File("/tmp/tux-ubuntu.jpg");
BufferedImage buffImage = ImageIO.read(inputFile);

int w = buffImage.getWidth();
int h = buffImage.getHeight();

int rgba[] = new int[w * h];
// obtem pixels do bufferedImage
buffImage.getRGB(0, 0, w, h, rgba, 0, w);

// converte para tons de cinza
int gray[] = imageToGray(rgba);
// escreve no bufferedImage
buffImage.setRGB(0, 0, w, h, gray, 0, w);

// escreve nova imagem no disco
ImageIO.write(buffImage, "JPG", new File("/tmp/tux-gray.jpg"));
}
}




O exemplo de utilização da classe:

terça-feira, 3 de fevereiro de 2009

JAVA: Varargs

Uma característica muito legal das linguagens orientadas à objetos, em especial do JAVA é o overloading de métodos, onde um mesmo método pode ser invocado usando assinaturas diferentes. Por exemplo, um método com o mesmo nome, mas com uma variável quantidade de argumentos aceitáveis.
Um exemplo poderia ser:



Calc c = new Calc();

c.calcula(10, 35, 34);

c.calcula(3.4, 12);

c.calcula("Triângulo", 56, 23, 21);



No exemplo acima, foi instanciada uma classe chamada Calc, que efetua algum tipo de cálculo qualquer. O objeto c possui um método chamado calcula(), que pode ser chamado de três formas diferentes, onde o nome do método não muda, somente seus argumentos.

O Varargs (Variable Arguments), permite especificar que o método terá múltiplos argumentos do mesmo tipo, sem que haja necessidade de pre-determinar o número exato de argumentos(em tempo de compilação e/ou execução).

Para utilizar o varargs, fazemos uso da elipse (...), onde os três pontos são a chave (keyword) pra varargs. Vejamos e exemplo da classe VargsExample, esta por sua vez é composta de métodos que calculam a média de valores passados com o argumentos. Temos mean(float num1, float num2), que calcula a média de 2 argumentos, um overload do método anterior: mean(float num1, float num2, float num3, float num4); que calcula a média entre quatro argumentos, e por ultimo, temos a utilização de varargs: mean(float... numbers), que permite o cálculo da média para um número indefinido de argumentos, incluindo a passagem de parâmetro como um array primitivo do tipo float.



public class VargsExample {

// método que calcula a média
public float mean(float num1, float num2) {
return (num1 + num2) / 2.0f;
}

// overloading do método que calcula a média
public float mean(float num1, float num2, float num3, float num4) {
return (num1 + num2 + num3 + num4) / 4.0f;
}

// calculo da média usando varargs
public float mean(float... numbers) {
float sum = 0;

for (float n : numbers)
sum += n;

return sum / (float) numbers.length;
}

public static void main(String[] args) {

VargsExample calc = new VargsExample();
// Exemplos de chamadas de métodos

// método de calculo de média
calc.mean(10, 23);

// overloading
calc.mean(10, 20, 30, 40);

// usando varargs que recebe número indeterminado de argumentos
calc.mean(12);
calc.mean(new float[] {12, 45, 78, 34, 21, 34, 54, 8, 9, 12, 87});
calc.mean(0, 2, 1);
calc.mean(9, 5, 7, 10, 4);
}
}




O exemplo apresentado, mostra a flexibilidade que se consegue com o emprego de varargs em determinados métodos. Esse recurso foi introduzido na versão Tiger do JAVA: 1.5.