Segurança de informações (Parte II)

Filed Under (Segurança da Informação) by admin on 15-06-2010

Cada vez mais, as organizações e seus sistemas de informação e redes enfrentam ameaças de segurança vindas das mais diversas fontes, incluindo fraudes através de computadores, espionagem, sabotagem, vandalismo, incêndio ou enchentes. Fontes de prejuizos tais como vírus de computador, hackers e ataques de negação de serviços têm se tornado mais comuns, mais ambiciosos e cada vez mais sofisticados.

Devido à dependência de sistemas e serviços de informação, as organizações estão mais vulneráveis às  ameaças contra segurança. A interconexão de redes públicas e privadas e o compartilhamento de recursos de informação aumentam a dificuldade de se conseguir controle de acesso. A tendência ao processaamento distribuído, vem enfraquecendo a efetividade do controle central especializado.

A segurança que pode ser obtida através de meios técnicos é limitada, e deveria ser apoiada por procedimentos e gestão adequados. ;-)

Cálculos para acompanhamento de pacientes que estão sob respiração mecânica

Filed Under (Códigos) by admin on 14-06-2010

Pessoal, estou fazendo um sistema para um amigo, profissional em terapia respiratória. É um sistema p/celular em Java que terá uma parte desktop .NET. E segue abaixo a parte mais complicada que são as fórmulas.

O uso delas  fica por sua conta e risco, pois elas foram feitas com base em vários depoimentos médicos e literatura especializada. E como em toda área  existem divergências, e na medicina não é diferente. O uso delas deve ser OBRIGATORIAMENTE acompanhado por um ou mais profissionais de medicina. Mas serve como base de estudos e pra matar a curiosidade também, já que é uma área de pequena participação do mundo Java.

OBS:  nao consegui identar de forma alguma no tema que escolhi no worpress

/**
*
* todo: Todos os parametros que tiverem sufixo “atual” são da gasometria
*
*
*
*
*/
package com.arnaldo nascimento.formulas;

/**
*
* @author root
*/
public class FormulasCalculos {

public static double getAnionGapCorrigido(double naGasometria, double kGasometria, double albumina, double clGasometria, double hco3, double lactato) {
double res = 0.0;
res = (((naGasometria + kGasometria) - (clGasometria + hco3)) + ((40 - albumina) * 0.25) - lactato);
return res;
}

public static double IMC(double peso, double altura) {
double res = 0.0;
res = peso * (altura * altura);
return res;
}

/**
*
* @param altura
* @param peso
* @param sexo
* @return
*/
public static double getPesoIdeal(double altura, double peso, String sexo) {
double res = 0.0;
if (sexo.equals(”M”)) { //Masculino
res = 22 * (altura * altura);
}
else { //Feminino
res = 20.8 * (altura * altura);
}
return res;
}

/* Outros
Vt = Sara 4 a 6 ml/kg
DPOC*/

public static double getVT( Double sara,
Double outros, Double dpoc,
double altura,
double peso, String sexo) {
double val = 0.0;

//SARA
if (sara != null) {
val = sara.doubleValue();
}

//OUTROS
if (outros != null) {
val = sara.doubleValue();
}

//DPOC
if (dpoc != null) {
val = sara.doubleValue();
}

val = val * FormulasCalculos.getPesoIdeal(altura, peso, sexo);
return val;
}

/**
* FResp ideal = (paCo2atual * FR atual) / PaCOs ideal
* @param paco2Atual
* @param frAtual
* @param idade
* @return
*/
public static double getFrespIdeal(double paco2Atual, double frAtual, double idade) {
double res = 0.0;
res = (paco2Atual * frAtual) / FormulasCalculos.getPaCO2Ideal(null);
return res;
}

/**
* FiO2 ideal = (PaO2 atual x FiO2 atual) / (109 – (0,43 x idade))
* @param pao2Atual
* @param fio2Atual
* @return
*/
public static double getfiO2Ideal(double pao2Atual, double fio2Atual, double idade) {
double res = 0.0;
res = ((pao2Atual * fio2Atual) / FormulasCalculos.getPaO2IdealArterial(idade));
return res;
}

/**
* Cdin = 500/ PPICO - PEEP
* @param pPico
* @param peep
* @return
*/
public static double getCdin(double pPico, double peep) {
double res = 0.0;
res = (500 / (pPico - peep));
return res;
}

/**
* Cest = 500/ PPLATÔ - PEEP
* @param pPlato
* @param peep
* @return
*/
public static double getCest(double pPlato, double peep) {
double res = 0.0;
res = (500 / (pPlato - peep));
return res;
}

/**
* Rsr = ((PPICO - PPLATO) / 30);
* @param pPlato
* @param pPico
* @return
*/
public static double gerRsr(double pPlato, double pPico) {
double res = 0.0;
res = ((pPico - pPlato) / 30);
return res;
}

/**
* PaO2 ideal = 109 – (0,43 x idade)
* @param idade
* @return
*/
public static double getPaO2IdealArterial(double idade) {
return (109 - (0.43 * idade));
}

/**
* TODO: deixa default 40, e liberado pra preenchimento de outros valores
* @return
*/
public static double getPaCO2Ideal(Double val) {
double res = 40;
if (val != null) {
res = val.doubleValue();
}
return res;
}

/**
* FRideal = (FRatual x PaCO2atual) / PaCO2ideal
* @param frAtual
* @param paco2Atual
* @return
*/
public static double getFrIdeal(double frAtual, double paco2Atual) {
double res = (frAtual * paco2Atual) / FormulasCalculos.getPaCO2Ideal(null);
return res;
}

public static double getPAO2Auvelar(double pb, double fiO2Atual, double paCo2Atual) {
double res = 0.0;
res = fiO2Atual * ((pb - 47) - paCo2Atual);
res = res / 0.8;
return res;
}

/**
* @param fiO2Atual
* @param paO2Atual
* @return
*/
public static double getFiO2Ideal(double fiO2Atual, double paO2Atual, double idade, Double pao2Gasometria) {
double res = 0.0;
if (pao2Gasometria != null) {
res = (pao2Gasometria.doubleValue() * fiO2Atual);
} else {
res = (FormulasCalculos.getPaO2IdealArterial(idade) * fiO2Atual);
}

res = res / paO2Atual;
return res;
}

//********** Valores para LIMITES COMPENSATÓRIOS DOS PULMÕES **********//
/**
/* AcidoseMetabolica
* PaCO2 esperada = 1,5 x [HCO3] + 8 (± 2);
*
* @param hco3
* @return
*/
public static double[] getAcidoseMetabolica(double hco3) {
double[] res = new double[]{0.0, 0.0};
double part = (1.5 * hco3) + 8; //(± 2)
res[0] = part + 2;
res[1] = part - 2;
return res;
}

/**
* Alcalose metabólica
* PaCO2 esperada = 0,7 x [HCO3] + 20 (± 5);
* @param hco3
* @return
*/
public static double[] getAlcaloseMetabolica(double hco3) {
double res[] = new double[]{0.0, 0.0};
double part = (0.7 * hco3) + 20; // (± 5);
res[0] = part + 5;
res[0] = part - 5;
return res;
}

/**
* Acidose respiratória  aguda
* [HCO3] esperado = 24 + [( PaCO2 atual – 40 ) / 10]
* @param paco2Atual
* @return
*/
public static double getAcidoseRespiratoriaAguda(double paco2Atual) {
double res = 0.0;
res = 24 + ((paco2Atual - 40) / 10);
return res;
}

/**
* Acidose respiratória crônica
* [HCO3] esperado = 24 + 4 x [( PaCO2 atual – 40 ) / 10]
* @param paco2Atual
* @return
*/
public static double getAcidoseRespiratoriaCronica(double paco2Atual) {
double res = 0.0;
res = 24 + (4 * ((paco2Atual - 40) / 10));
return res;
}

/**
* Alcalose respiratória aguda
* [HCO3] esperado = 24 - 2 x [( 40 - PaCO2 atual ) / 10 ]
* @param paco2Atual
* @return
*/
public static double getAlcaloseRespiratoriaAguda(double paco2Atual) {
double res = 0.0;
res = 24 - (2 * ((40 - paco2Atual) / 10));
return res;
}

/**
* Alcalose respiratória  aguda
* [HCO3] esperado = 24 - 5 x [( 40 - PaCO2 atual ) / 10]
* @param paoc2Atual
* @return
*/
//TODO: renomear funcao
public static double getAlcaloseRespiratoriaAgudaCronica(double paoc2Atual) {
double res = 0.0;
res = 24 - (5 * ((40 - paoc2Atual) / 10));
return res;
}
}

Segurança de informações (Parte I)

Filed Under (Segurança da Informação) by admin on 09-06-2010

Tagged Under :

Informações são ativos que, como qualquer outro ativo importante para os negócios,
possuem valor para uma organização e consequentemete precisam ser protegidos adequadamente.

As informações podem existir sob muitas formas. Podem ser impressas ou escritas em papel, armazenadas eletronicamente,
enviadas pelo correio eletronico,ou usando meios e eletrônicos, mostradas em filmes, ou faladas em conversas.
Qualquer forma que seja que as informações assumam, ou os meios, pelos quais sejam compartilhadas ou armazenadas,
elas devem ser sempre protegidas adequadamente.

A segurança de informações protege as informações contra uma ampla gama de ameaças, para assegurar a continuidade dos negócios,
minimizar prejuízos e maximizar o retorno de investimentos e oportunidades comerciais.

Características

A segurança de informações é caracterizada como a preservação de:

  • confidencialidade: garantir que as informações sejam acessíveis apenas àqueles autorizados a terem acesso;
  • integridade: salvaguardar a exatidão e intereireza das informações e métodos de processamento;
  • disponibilidade: garantir que os usuários autorizados tenham acesso às infomações e ativos associados quando necessário.

Conclusão

A segurança das informações é obtida através da implantação de um conjunto adequado de controles, que podem ser políticas,
práticas, procedimentos, estruturas organizacionais e funções e funções de software.
Esses controles precisam ser estabelecidos para assegurar que os objetivos de segurança
específicos da organização sejam alcançados.

Requisitos para instalação do IBM BPM Suite no Red Hat

Filed Under (BPM, Clustering) by admin on 13-11-2009

Estou trabalhando em um projeto de clusterização de várias ferramentas da IBM, entre elas está a suite de BPM. O sistema operacional definido foi o Red Hat Enterprise Linux (RHEL) 5.0 Server/Advanced (Update 1). Então pra quem for fazer uma instalação parecida, aí vai a pequena lista de bibliotecas necessárias para a execução desta tarefa:

compat-libstdc++-33-3.2.3-61
compat-db-4.2.52-5.1
libXp-1.0.0-8
libXmu-1.0.2-5
libXtst-1.0.1-3.1
pam-0.99.6.2-3.26.el5
rpm-build-4.4.2-37.architecture.el5 or later
elfutils-0.125-3.el5
elfutils-libs-0.125-3.el5

So sad :-)

Cache de objetos com o Memcache

Filed Under (Performance) by admin on 23-09-2009

Tagged Under : , , , ,

O Memcached foi desenvolvido pela Danga Interactive para
atender ao livejournal.com um
site com mais de 20 milhões de acessos dinâmicos por dia.
Hoje ele é distribuido sob a permissive free software license e pode
ser baixado em http://danga.com/memcached/dist/

Pre-requisito

O Memcached utiliza a libevent, e caso seu sistma não possua esta biblioteca
você poderá baixa-la em http://www.monkey.org/~provos/libevent-1.4.8-stable.tar.gz
e seguir os passos:

tar xfz libevent-1.4.8-stable.tar.gz
./configure && make && sudo make install
sudo ln -s /usr/local/lib/libevent-1.4.so.2 /usr/lib
Instalando o Memcached

wget http://danga.com/memcached/dist/memcached-1.2.6.tar.gz
tar xfz memcached-1.2.6.tar.gz
cd memcached-1.2.6
./configure && make && sudo make install

OBS: O utilitário apt-get faz a instalação do memcached e da dependência libevent.
O comando é o sudo apt-get install memcached

Agora vamos roda-lo:
# (d = daemon, m = memory, u = user, l = IP to listen to, p = port)
memcached -d -m 1024 -u root -l 127.0.0.1 -p 11211
verifique se ele está ouvindo na porta definida acima:
netstat -a | grep 11211

Suporte a linguagens

O memcached possui clients-api para:

- C/C++
- Erlang
- PHP
- Perl
- Java
- Phyton
- Ruby
- .NET
- MySQL
e outras http://code.google.com/p/memcached/wiki/Clients

Escolhi como exemplo o Ruby e o PHP e em ambos clients-api a “serialização” dos objetos é automática.

Memcached & PHP

apt-get install php5-memcache

verifique se a linha
extension=memcache.so não está comentada no arquivo /etc/php5/conf.d/memcache.ini

agora é só reiniciar o apache
/etc/init.d/apache2 restart

Fiz um código simples para acessar uma base de dados e retornar uma coleção da classe Pessoa:

teste.php

<?php

require “persistence/Entity.class.php”;

class Pessoa extends Entity {
 public $nome;
 public $endereco;
 public function to_string() {
  echo $this->nome.” - “.$this->endereco;
 }
}

$memcache=new Memcache;
$memcache->connect(’localhost’, 11211) or die(’Oops!’);

$pessoas = $memcache->get(’key’);

if (!$pessoas) {
 $pessoas = Pessoa::findAll(”nome”);
 $memcache->set(’key’,$pessoas,false,60);
}

print_r($pessoas);

?>

 
Ruby

sudo gem install Ruby-MemCache

Este exemplo em Ruby exibe outros recursos do Memcache como compressão de dados, debug e restrição de escrita.

teste.rb

require “rubygems”
require “memcache”
require “persistence.rb”

class Pessoa
 attr_accessor :nome, :endereco
 def to_s
  puts “#{nome} - #{endereco}”
 end
end

memcache_options = {
   :compression => true,
   :debug => false,
   :namespace => “mem-teste”,
   :readonly => false,
   :urlencode => false
}

memcache_servers = [ '127.0.0.1:11211' ]

CACHE = MemCache::new(memcache_options)
CACHE.servers = memcache_servers

pessoas = CACHE["key"]

if !pessoas
 pessoas = Persistence::findAll(”pessoas”, “nome”)
 CACHE["key"] = pessoas
end

puts pessoas

Das ist! um poderoso cache em minutos. ;-)

Monitoramento e gerência de processos no servidor

Filed Under (Failover) by admin on 11-09-2009

Vários são os serviços disponibilizados por um servidor: e-mail, http, database…. e todos sujeitos a falhas ou a um mal funcionamento que pode comprometer outros sistemas e na pior hipótese toda máquina.
É preciso então que estes sistemas sejam monitorados e em caso de falha ou mal funcionamento que os
administradores sejam notificados.
Neste post vou apresentar como isso pode ser facilmente configurado através do Monit.

O Monit é um utilitário UNIX de monitoração e gerência de processos. Ele é capaz de
 identificar que um processo (serviço, sistema…) caiu ou se está consumindo memória ou cpu excessivamente.
Quando identifica uma situação anormal o Monit notifica os administradores e restaura o processo.
Existem também recursos de monitoramento de arquivos, diretórios e sistema de arquivos que não serão abordados neste post,
mas que são muito úteis.

O site do Monit é o http://mmonit.com/monit/

Instalação

Neste exemplo vamos monitorar o funcionamento do apache (obs: o Monit pode ser configurado para monitorar vários processos)

Faça o download do arquivo e descompacte-o:

 tar zxvf monit-x.y.z.tar.gz
 cd monit-x.y.z

Execute o ./configure e verifique se todas as dependências estão instaladas no seu Linux.

Se estiver tudo ok entao: make && make install

O Monit é instalado no /usr/local/bin e o arquivo de configuração monitrc eu criarei no /etc
Configuração
extraído do original http://mmonit.com/monit/documentation/monit.pdf

(1) # Monit control file
(2)
(3) set daemon 60
(4) set logfile syslog facility LOG_daemon
(5) set mailserver mail.meuserver.com
(6) set alert sysadm@meuserver.com
(7) set httpd port 2812 address localhost
(8) allow localhost
(9) allow admin:monit
(10)
(11) check process apache with pidfile “/var/run/apache2.pid”
(12) start = “/etc/init.d/apache2 start”
(13) stop = “/etc/init.d/apache2 stop”
(14) if failed port 80 and protocol http
(15) and request “/index.html” then restart
(16) if cpu usage is greater than 60 percent for 2 cycles then alert
(17) if cpu usage > 98% for 5 cycles then restart
(18) if 2 restarts within 3 cycles then timeout
(19) alert foo@meuserver.com
A linha é apenas um comentário. Na linha 3, o monit é configurado para iniciar no modo dæmon e verificar cada serviço em
ciclos de 1 minuto (valor em segundos). na linha 4 , o monit informa que o  log de erros e as mensagens de status utilizarao o  syslog.
O Monit precisa de um servidor SMTP server para enviar as mensagens de alerta, e na linha 5 especificamos
o endereço do SMTP server que o monit deve usar. A linha 6 define o e-mail que receberá os alertas sysadm@meuserver.com
A linha 7 inicia o servidor http próprio do monit. Este servidor HTTP será acessado para visualizar a interface de monitoramento e gerência (fig. 1 e fig. 2)
A linha 8 define que o servidor http dele poderá ser acessado apenas de localhost
e a linha 9 adiciona um usuário/senha para que o o servidor http do monit possa ser acessado via
HTTP Basic Authentication

Informações sobre o processo a ser monitorado

A linha 11 informa qual processo vamos monitorar, ela contém um identificador para o processo e o caminho para o pidfile dele.
Se desejamos que o monit inicie, pare ou reinicie um processo devemos configurar os comandos start e stop.
As linhas 12-13 definem os comandos para parar e iniciar o apache.
Na linha 4 configuramos o monit para estabelecer uma conexao com o servidor apache e solicitar o arquivo index.html
Se este teste falhar, monit irá reiniciar o processo do apache.
Nas linhas 16-17 o processo é testado quanto ao uso dos recursos de cpu da máquina e executa as tarefas necessárias de alerta ou reiniciar.
Finalizando o e-mail para onde o monit enviará e-mails caso o serviço configurado falhe.
O ideal é que o monit inicie junto com o linux, mas para testar você pode iniciá-lo simplesmente chamndo: monit e para para-lo: monit quit
É prudente antes de iniciá-lo executar monit -t para verificar se não existem erros na configuração do monitrc.

Até apróxima ;-)

Whippet CodGen for PHP

Filed Under (Whippet CodGen for PHP) by admin on 04-09-2009

Tagged Under : , ,

Iniciei um projeto de geração de código PHP e no momento estou trabalhando na interface de geração. No source forge já postei o framework de persistência.Mas, o projeto ainda não tem um release  e está em desenvolvimento.

http://sourceforge.net/projects/whippetcodgen/

Balanceamento de Carga com PHP - Parte II

Filed Under (Clustering, PHP) by admin on 19-08-2009

Esse tipo de cluster tem como função controlar a distribuição equilibrada do processamento.
Requer um monitoramento constante na sua comunicação e em seus mecanismos de redundância,
pois se ocorrer alguma falha haverá uma interrupção no seu funcionamento.
Wikipédia

Vou assumir que já temos duas máquinas rodando a aplicação criada no passo I e devidamente configuradas para gravar
as sessões em um terceiro servidor, o banco de dados.
Estas máquinas podem ser configuradas com qualquer sistema operacional que suporte um servidor web com PHP
Para o servidor responsável pelo balanceamento de carga eu utilizo o Linux, e neste exemplo o Ubuntu Linux.

Bom, selecionei duas formas de balanceamento para exemplificar: por DNS e por Proxy.
Para o DNS vamos usar o software BIND9 e para o Proxy o Apache + mod_proxy_balancer
A tarefa destes softwares é receber as requisições e dividi-las entre os dois servidores PHP utilizando o algorítimo
mais simples de balancemento: o Round Robin.
Round Robin divide as requisições de forma igual, uma para o servidor A - outra pro servidor B,
sem levar em consideração se A já está executando muitas tarefas ou se B está com consumo muito alto de CPU e etc…
Existe vários tipos de algorítimos e o melhor deve ser escolhido após um estudo aprofundado que leve em consideração
o número de máquinas disponíveis para balanceamento e suas configurações de memória, CPU, link de rede, número de sistemas instalados…

Balanceamento por DNS

Para instalar o BIND9 no Ubuntu basta digitar a linha abaixo
sudo apt-get install bind9

Após a instalação, o servidor já está configurado para ser um servidor de DNS e ouvindo na porta 53.
O próximo passo é configurá-lo de forma que as requisições para o domínio www.exemplo.com.br
sejam redirecionadas para as máquinas com o PHP.

Criaremos então o arquivo /etc/bind/db.exemplo

$TTL 0
IN SOA dns1.exemplo.com.br. email.exemplo.com.br. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
IN MX 10 mail

mail IN A 192.168.56.107

www IN A 192.168.56.101
IN A 192.168.56.103

Note que em www eu adicionei os IPs dos servidores que vão rodar a aplicação PHP, isso já faz com que o BIND use o Round Robin
para balancear as requisições.

E agora adicionamos uma referência ao db.exemplo no arquivo /etc/bind/named.conf

zone “localhost” {
type master;
file “/etc/bind/db.local”;
};

zone “127.in-addr.arpa” {
type master;
file “/etc/bind/db.127″;
};

zone “0.in-addr.arpa” {
type master;
file “/etc/bind/db.0″;
};

zone “255.in-addr.arpa” {
type master;
file “/etc/bind/db.255″;
};

zone “exemplo.com.br” {
type master;
file “/etc/bind/db.exemplo”;
};

include “/etc/bind/named.conf.local”;

Reinicie o serviço com a linha abaixo:
sudo /etc/init.d/bin9 restart

É interessante neste momento alterar uma linha do arquivo teste.php para melhor visualização do balanceamento:

Servidor A: $_SESSION['server']= “server 1″;

Servidor B: $_SESSION['server']= “server 2″;

Hora de testar: abra a URL http://www.exemplo.com.br/teste.php com o browser e veja o resultado do balanceamento.

Balanceamento via Proxy

O Apache2 possui um módulo chamado mod_proxy_balancer. Ele é uma extensão do mod_proxy, que portanto também deve estar presente
na configuração do balanceamento de carga. O proxy balancer suporta os protocolos HTTP, FTP e AJ13.

Para quem não possui o apache2 instalado pode instalar a partir da linha abaixo:
sudo apt-get install apache2

Para instalar o mod_proxy_balance devemos copiar os arquivos do diretório /etc/apache2/mods-available

proxy_balancer.load
proxy.load
proxy.conf
proxy_http.load

para o diretório:
/etc/apache2/mods-enabled

Vamos agora configurar o módulo para operar no modo reverse proxy (ou gateway). Neste modo a requisição chega ao servidor proxy que decide quem a atenderá, e retorna o resultado ao cliente origem.
Para isso alteramos no arquivo proxy.conf  a diretiva ProxyRequests para o valor off.

Segue abaixo um exemplo de como deve ficar o  arquivo proxy.load

<IfModule mod_proxy.c>
         ProxyRequests Off

        <Proxy *>
                AddDefaultCharset off
                Order deny,allow
           Allow from all #Isso é apenas um exemplo, configure seu proxy com segurança!!!!
        </Proxy>

 <Proxy balancer://meucluster>
  BalancerMember http://192.168.56.103:80 #Servidor PHP A
  BalancerMember http://192.168.56.102:80 #Servidor PHP B
 </Proxy>
 ProxyPass /teste balancer://meucluster
</IfModule>

 

Reinicie o Apache:
sudo /etc/init.d/apache2 restart

Neste exemplo meu servidor proxy atende pela URL www.appteste.com.br e redireciona para os IPs 192.168.56.103 e 192.168.56.102 que estão rodando a aplicação de teste.
Hora de testar: abra a URL http://www.appteste.com.br/teste/teste.php com o browser e veja o resultado do balanceamento.

Bom, acho que consegui passar uma visão de como podemos configurar um balanceamento com PHP. O assunto, claro,
não para por aqui. Existem inúmeras outras situações, configurações, problemas, soluções, algorítimos… Mas, um problema que fica claro na solução acima é o fato do load balancer se tornar mais um ponto de falha na arquitetura. Basta imaginar que se ele cair, todo trabalho está perdido e será um assunto que quero tratar nos próximos posts.
Valeu!

Balanceamento de Carga com PHP - Parte I

Filed Under (Clustering, PHP) by admin on 18-08-2009

Empresas que possuem um número alto de requisições em seus servidores ou que precisam de alta-disponibilidade em seus sistemas, adotam soluções de cluster adaptadas as sua realidade. Dos três tipos conhecidos (Alto Desempenho, Alta Disponibilidade e Balanceamento de Carga) vou tentar passar as configurações básicas para o Balanceamento de Carga para PHP.
As configurações que vou apresentar podem ser aplicadas em máquinas físicas ou em um ambiente virtualizado.

O primeiro problema a ser resolvido é o das sessões. O PHP por padrão salva os dados de sessões em arquivos dentro
de um diretório local. Em um cluster configurado para balanceamento de carga o PHP então não saberia encontrar os dados da sessão de um usuário ou qual foi o ID criado para ele e etc… Pois, cada máquina, teria seu próprio gerenciador de sessões.
Existem algumas soluções para este problema e a que vou apresentar aqui é a persistência de sessões em banco de dados. Um ponto único de gravação e leitura de sessões com o suporte  da transação gerenciada pelo banco.
O banco de dados utilizado aqui será o MySQL, mas o código PHP necessário para o gerenciamento
de sessões pode ser facilmente migrado para qualquer outro banco. Uma boa prática é usar o PDO como camada de
acesso ao banco.

Vamos ao código, o PHP permite alterar o gerenciamento de sessões através da função session_set_save_handler .
Esta função espera seis funções de callback como parâmetro que são:

open
close
read
write
destroy
gc

Então o primeiro passo é definir a classe session que implementará estes métodos:

session.class.php

<?php

class session {
    var $life_time;
    var $connection;
   
    function session($connection) {
        $this->connection = $connection;
        $this->life_time = get_cfg_var(”session.gc_maxlifetime”);
        //Olha session_set_save_handler aqui!!!
        session_set_save_handler(
            array( &$this, “open” ),
            array( &$this, “close” ),
            array( &$this, “read” ),
            array( &$this, “write”),
            array( &$this, “destroy”),
            array( &$this, “gc” )
        );
    }

    function open( $save_path, $session_name ) {
        global $sess_save_path;
        $sess_save_path = $save_path;     
        return true;
    }

    function close() {
        return true;
    }

    function read( $id ) {
        $num_rows = 0;
        $data = ”;
        $time = time();
        $newid = mysql_real_escape_string($id); //prefira PDO e bindParams ao mysql_real_escape_string
        $result =mysql_query(”SELECT `session_data` FROM `sessions` WHERE `session_id` = “.$newid.” AND `expires` > “.$time, $this->connection);
        if ($result) {
            $num_rows = mysql_num_rows($result,$this->connection);

            if($num_rows  > 0) {
                $row = mysql_fetch_array($result);
                $data = $row['session_data'];
            }
        }
        return $data;
    }
    function write( $id, $data ) {    
        $time = time() + $this->life_time;
        $newid = mysql_real_escape_string($id);     //prefira PDO e bindParams ao mysql_real_escape_string
        $newdata = mysql_real_escape_string($data);
        $sql = “REPLACE `sessions` (`session_id`,`session_data`,`expires`) VALUES(’$newid’, ‘$newdata’, $time)”;
        $rs = mysql_query($sql,$this->connection);
        return true;
    }

    function destroy( $id ) {     
        $newid = mysql_real_escape_string($id);
        $sql = “DELETE FROM `sessions` WHERE `session_id` = ‘$newid’”;
         mysql_query($sql, $this->connection);
        return true;
    }

    function gc() {
        $sql = ‘DELETE FROM `sessions` WHERE `expires` < UNIX_TIMESTAMP();’;
        mysql_query($sql,$this->connection);     
        return true; //Sempre retorna true
    }
}
?>

Agora vamos criar uma página para testes:

teste.php

<?php

require_once(”session.class.php”);

$connection = mysql_connect(”192.168.56.1″,”root”,”");
mysql_select_db(”sessions”, $connection) or die( “Erro ao selecionar a base de dados”);

$session = new session($connection);

session_start();
$_SESSION['time']= date(”H:i:s”);
$_SESSION['server']= “server 1″;
print_r($_SESSION);

?>
E por fim a tabela que irá armazenar os dados das sessões:

CREATE TABLE IF NOT EXISTS `sessions` (
  `session_id` varchar(100) NOT NULL DEFAULT ”,
  `session_data` text NOT NULL,
  `expires` int(11) NOT NULL DEFAULT ‘0′,
  PRIMARY KEY (`session_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Rode a aplicação e veja o resultado gravado na tabela.
E agora que já temos toda parte de sessão resolvida vamos para a segunda parte: as configurações de balanceamento.

Instalando WebSphere 6.1 no Ubuntu

Filed Under (Application Server) by admin on 16-07-2009

Tagged Under : ,

Minha primeira tentativa de instalar o WAS 6.1 no Ubuntu Linux foi desastrosa. Mas, após pesquisar eu identifiquei que o /bin/sh no Ubuntu é um link para o dash e o instalador só funcionará corretamente se apontar para bash. Isso pode ser resolvido com o comando sudo unlink /bin/sh seguido do sudo ln -s /bin/bash /bin/sh

Agora baixe/atualize as bibliotecas abaixo:

apt-get -y install libstdc++5
apt-get -y install mc
apt-get -y install unzip

O próximo passo é verificar no arquivo WAS/responsefile.base.txt se o parâmetro -OPT installLocation é um diretório válido no Linux. Por padrão a distribuição que baixei vem com o valor “c:\IBM\WebSphere\AppServ”

Agora é só executar o instalador: sudo WAS/install -options responsefile.base.txt e é isso ae ;-)