Archive for agosto \27\-02:00 2011

Postgres Tips: Arquivo de senha – pgpass

Posted on agosto 27, 2011. Filed under: PostgreSQL, Tips |

Alguns dias atrás precisei criar um script automático (shell script) de backup/restore de uma base do postgres. Os comandos que usei foram o pg_dump, para criar o backup, e psql para restaurar backup quando necessário. O banco de dados estava com as permissões de acesso configurado para solicitar senha, até mesmo se logado com o usuário postgres, o quê não acontece normalmente. Normalmente o usuário postgres acessa o banco sem a necessidade de solicitar a senha de acordo com a configuração padrão no pg_hba.conf. Os comandos do postgres, pg_dump, psql, etc.. não permitem especificar a senha através da linha de comando. Se você esta acostumado com o MySQL vai perceber a diferença. O postgres força o usuário à criar um ambiente seguro, não permitindo a especificação da senha na linha de comando como acontece nos comandos do MySQL. (mysqldump, mysql, etc.)

O postgres disponibiliza um mecanismo seguro para que você possa utilizar os comandos sem que eles solicitem a entrada de senha na linha de comando, ideal para scripts automatizados, através do arquivo .pgpass. Crie o arquivo .pgpass no seu diretório home com a permissão 0600:

$ chmod 0600 ~/.pgpass

O formato do arquivo .pgpass é o seguinte:

hostname:port:database:username:password

Exemplo:

localhost:5432:base:foo:mudar123

Agora você pode rodar os comandos do postgres sem necessidade de entrar com a senha no prompt:

$ pg_dump -c -U foo base> ~/base.sql
$ psql -U foo -d base < ~/base.sql
Ler Post Completo | Make a Comment ( 4 so far )

Usando memcached no PHP

Posted on agosto 22, 2011. Filed under: PHP, Tuning |

Memcached utilizando junto com php, permite você aumentar a perfomance de sua aplicação fazendo cache de dados na memória. Usar o memcached para carregar dados, ao invés de carregar de um banco de dados ou do sistema de arquivos, pode ter um grande impacto na perfomance de sua aplicação php.

A regra básica de utilização de cache é simples: Conforme o client (usuário) acessa seu site onde os dados são provenientes de um banco de dados ou qualquer outra fonte de informações, inicialmente esses dados são gravados em um cache, no nosso caso usando o memcached. Nas próximas requisições, ao invés de buscar as informações no banco de dados novamente, iremos primeiro checá-las se existem no cache e caso existindo, são retornadas do cache e não do banco de dados. Em um outro momento, caso essas informações sofrerem atualizações na sua fonte de dados (database, etc..), iremos destruir o cache no memcached e reiniciar o ciclo novamente. Normalmente utilizamos um id único para identificar uma porção de dados gravados ou lidos em um cache.

Somente por curiosidade, o Zend Framework disponibiliza um módulo de Cache que pode ser utilizado juntamente com o memcached. Iremos abordar esse módulo em um post futuro.

Instalando e habilitando memcached no PHP

$ sudo apt-get install memcached
$ sudo apt-get install php5-memcached

O php também disponibiliza a bilioteca memchache, através do pacote php5-memcache, porém aconselho utilizar a biblioteca mancached como citado acima pois é mais atual e implementa o protocolo do memcache de forma mais eficiente.

Verificando se o serviço do memcached esta no ar:

$ ps ax | grep memcached

Reiniciando Apache:

$ sudo service apache2 restart

Exemplos

Segue abaixo um exemplo simples da utilização do memcached com PHP. Os principais pontos aqui são os métodos get, que otem dados do cache usando uma chave para identificação e o método set, utilizado para inserir dados no cache, também utilizando uma chave para identificação.

<?php
// conectando no memcached
$m = new Memcached();
$m->addServer('localhost', 11211);

// checando dados no cache e carregando em $rows
if (!($rows = $m->get('lista_usuarios'))) {
    if ($m->getResultCode() == Memcached::RES_NOTFOUND) {
        // dados não encontrados no cache. 
        // inserir no cache dados obtidos no banco
        // obter lista de usuarios do banco de dados
        // $rows = obter_lista_usuarios_db();
        $rows = array('joao', 'jose', 'maria');

        // inserindo dados
        $m->set('lista_usuarios', $rows);
    }
}

// acessando dados
var_dump($rows);

PS: No método set é possível especificar o tempo de expiração em segundos em que irá durar o cache. Caso seja omitido, é por tempo indeterminado. (nunca irá expirar).

Caso os dados do banco de dados forem modificados ou de alguma forma for determinado que o cache precisa ser atualizado existe a possibilidade de forçar a limpeza do cache através do método delete:

<?php
$m = new Memcached();
$m->addServer('localhost', 11211);

// verifica se houve modificacao na fonte de dados que esta em cache
// $dados_modificados = houve_atualizacao_dados();

$dados_modificados = true; // somente para este exemplo funcionar
if($dados_modificados) {
        $m->delete('lista_usuarios');
}

Somente lembrando que se você reiniciar o serviço do memcached, por padrão, os dados em cache serão perdidos.

Usando o memcached para armazenar dados da sessão

O memcached pode ser utilizado para outros propósitos no PHP, como por exemplo, no armazenamento de sessões. É útil no caso de estar utilizando load-balancing com o php. Ao invés de armazenar os dados de sessão em disco, todos servidores php que estão no balanceamento podem armazenar os dados de sessão em lugar centralizado, no caso, um servidor memcached. Dessa forma, caso o usuário que logou em um servidor, ao ser redirecionado para outro servidor durante o acesso no site, ele não perderá a sessão iniciada anteriormente, devido ao mecanismo de sessão estar centralizado no memcached.

Para habilitar o armazenamento da sessão no memcached, configure o php.ini dessa forma:

session.save_handler = memcached
session.save_path = "127.0.0.1:11211"

É isso ae, espero que tenham gostado. Sintam-se à vontade para postar comentários. Abraços!

Ler Post Completo | Make a Comment ( 2 so far )

Java Tips: Executando comandos externos

Posted on agosto 6, 2011. Filed under: Java, Tips |

Nesta dica vamos abordar como executar comandos externos (shell, comando dos, etc.) no java. É útil quando precisamos executar algum shell script ou, no caso do Windows, um arquivo bat.

O código abaixo executa um shell script chamado gera-backup.sh e aguarda a execução desse script terminar antes de continuar com a execuação do programa java. Isso é possível devido à utilização do método waitFor().

 
import java.io.IOException;

public class ComandoExterno {
  
    public static void main(String[] args) {
        
        Process p;
        try {
            //executar rotina de backup
            p = Runtime.getRuntime().exec("/opt/gera-backup.sh"); 
            p.waitFor(); // espera pelo processo terminar
            
            // ....
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

Abaixo temos uma variação do programa acima, porém agora nosso programa java guarda a saída do comando ls -la, lendo a saída padrão e a saída de erro em variáveis. Após isso as variáveis são impressas:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ComandoExterno {

    public static void main(String[] args) {

        Process p;
        String stdIn = "", stdErr = "", s;
        try {
            //executar  ls -la no diretório corrente
            p = Runtime.getRuntime().exec("ls -la");

            BufferedReader stdInput = new BufferedReader(new
                 InputStreamReader(p.getInputStream()));

            BufferedReader stdError = new BufferedReader(new
                 InputStreamReader(p.getErrorStream()));

            // lê o conteudo da saída padrão do comando e guarda em variável
            while ((s = stdInput.readLine()) != null) {
                stdIn += s + "\n";
            }

            // lê o conteudo da saída de erro do comando e guarda em variável
            while ((s = stdError.readLine()) != null) {
                stdErr += s + "\n";
            }

            // Exibir a saída padrão e de erro na tela
            System.out.println("Saida Padrao: \n" + stdIn);
            System.out.println("Saida Erro: \n" + stdErr);

        }
        catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

Saída do nosso programa acima:

root@ubuntu:~/java# java ComandoExterno
Saida Padrao:
total 16
drwxr-xr-x 2 root root 4096 2011-08-05 11:15 .
drwx------ 6 root root 4096 2011-08-05 11:15 ..
-rw-r--r-- 1 root root 1456 2011-08-05 11:15 ComandoExterno.class
-rw-r--r-- 1 root root 1249 2011-08-05 11:15 ComandoExterno.java

SaidaErro:

root@ubuntu:~/java#
Ler Post Completo | Make a Comment ( 8 so far )

Erro ao tentar instalar PHP oci8 no Ubuntu: /usr/bin/ld: cannot find -lclntsh

Posted on agosto 5, 2011. Filed under: Linux, Oracle, PHP |

Utilizei o link abaixo para configurar o php para acessar Oracle, somente modo client, no Ubuntu Server:
https://help.ubuntu.com/community/PHPOracle

Porém na hora de instalar o módulo oci8 para php, obtinha o erro abaixo:

$ sudo pecl install oci8
...
libtool: link: cc -shared  .libs/oci8.o .libs/oci8_lob.o .libs/oci8_statement.o .libs/oci8_collection.o .libs/oci8_interface.o   -L/usr/local/lib/instantclient_11_2 -lclntsh  -Wl,-rpath -Wl,/usr/local/lib/instantclient_11_2   -Wl,-soname -Wl,oci8.so -o .libs/oci8.so
/usr/bin/ld: skipping incompatible /usr/local/lib/instantclient_11_2/libclntsh.so when searching for -lclntsh
/usr/bin/ld: cannot find -lclntsh
collect2: ld returned 1 exit status
make: *** [oci8.la] Error 1

Para resolver o problema é simples: Como estava seguindo o link do HowTo baixei o instantclient para Linux versão x86, porém meu servidor é 64bits, portanto deve ser instalado o pacote do instantclient para Linux x86-64 e problema resolvido.

http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html

Ler Post Completo | Make a Comment ( None so far )

Java Tips: Download de Arquivo Binário (HttpClient)

Posted on agosto 1, 2011. Filed under: Java, Tips |

Estreando no blog as seção tips tem como objetivo divugar dicas práticas de programação, banco de dados e configuração de servidores. São dicas rápidas e práticas de utilização imediata. Para começar, estou disponibilizando um simples e útil código java que realiza download de um arquivo binário, como imagens, pdf, zip, etc. a partir de uma URL.

A execução abaixo irá realizar o download da imagem localizada na URL http://hc.apache.org/images/logos/httpcomponents.png no diretório /root.

O programa utiliza a lib apache commons e precisa ser instalada antes de compiliar.

import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.params.HttpMethodParams;

import java.io.*;

public class HttpClientDownload {

  private static String url = "http://hc.apache.org/images/logos/httpcomponents.png";
  private static String arquivoLocal = "/root/java/httpcomponents.png";

  public static void main(String[] args) {
    // Instância do HttpClient
    HttpClient client = new HttpClient();

    // Método GET
    GetMethod method = new GetMethod(url);

    try {
      // Realiza a reqiusição GET
      int statusCode = client.executeMethod(method);

      if (statusCode != HttpStatus.SC_OK) {
            System.err.println("Falha na requisição GET: " + method.getStatusLine());
      }

      // Ler o conteúdo da resposta.
      byte[] responseBody = method.getResponseBody();

      // gravar o conteúdo da resposta em arquivo, permitnido dados binários
      DataOutputStream os = new DataOutputStream(new FileOutputStream(arquivoLocal));
      os.write(responseBody);
      os.close();

    } catch (HttpException e) {
          System.err.println("Fatal protocol violation: " + e.getMessage());
          e.printStackTrace();
    } catch (IOException e) {
          System.err.println("Fatal transport error: " + e.getMessage());
          e.printStackTrace();
    } finally {
          // Libera a conexão.
          method.releaseConnection();
    }
  }
}
Ler Post Completo | Make a Comment ( None so far )

Liked it here?
Why not try sites on the blogroll...

%d blogueiros gostam disto: