Conteúdo


Desenvolvimento Java 2.0

Utilizando Play com o Amazon RDS

Gerenciamento de dados relacionais como um serviço? Por que não?

Comments

Conteúdos da série:

Esse conteúdo é a parte # de # na série: Desenvolvimento Java 2.0

Fique ligado em conteúdos adicionais dessa série.

Esse conteúdo é parte da série:Desenvolvimento Java 2.0

Fique ligado em conteúdos adicionais dessa série.

Alguns meses atrás, nesta série, eu escrevi uma introdução prática para o Elastic Beanstalk da Amazon, uma platform-as-a-service (PaaS) criada para o desenvolvimento de aplicativos Java. Como eu demonstrei, o Beanstalk é extremamente versátil e permite que desenvolvedores usem praticamente qualquer combinação de ferramentas para realizar seu trabalho. Além de desenvolvimento para a Web rápido com Play, eu pude usar outra PaaS, a MongoHQ, para gerenciar minhas instâncias MongoDB. Ao combinar as duas infraestruturas PaaS, eu não precisaria manipular a maior parte da manutenção do aplicativo, então, poderia focar em desenvolver um ótimo aplicativo de nuvem para dispositivo remoto.

O PaaS MongoHQ funcionou bem para aquele projeto, mas e se eu preferisse armazenar meus dados em um RDBMS tradicional? Afinal, a maioria dos desenvolvedores Java se sente mais confortável criando códigos para um banco de dados relacional. Outro fato é que nem todos os projetos podem dispensar ACID, que é algo exigido por muitos armazenamentos de dados NoSQL.

Neste mês, irei apresentar o Amazon Relational Database Service (RDS), outra excelente e versátil adição à família Amazon Web Services. Usar Amazon RDS é tão fácil quanto executar instâncias MongoDB hospedadas no MongoHQ. Seu aspecto relacional não é tão difícil de gerenciar, mas ele apresenta alguns problemas interessantes de ajuste de escala. É preciso apenas dedicar alguns ciclos para definir um esquema, depois de fazer isso é possível continuar.

Amazon RDS

Amazon Relational Database Service é uma PaaS que oferece instância MySQL on demand, baseada em nuvem e escalável, para desenvolvimento de aplicativos. Se RDS fosse apenas uma instância de MySQL sendo executada na nuvem, eu não estaria escrevendo este artigo. Afinal, eu expliquei como utilizar uma imagem Amazon EC2 executando MySQL em 2009 (consulte Recursos).

A diferença é que RDS é uma PaaS gerenciada e operada pela Amazon que oferece vários serviços e flexibilidades encontrados em Elastic Beanstalk. A Amazon oferece backup, replicação e mesmo correções. Além disso, RDS é totalmente escalável — é possível aumentar a capacidade de armazenamento do aplicativo com alguns cliques. A Amazon também permite replicar RDS em zonas de disponibilidade. Dessa forma, se uma zona ficar inativa ou tiver uma janela de manutenção agendada, ainda é possível entregar dados. É possível até mesmo fornecer instâncias do banco de dados somente de leitura, assegurando maior velocidade de leitura para aplicativos ou períodos de alto volume.

Aplicativos já desenvolvidos para funcionar com MySQL podem aproveitar instantaneamente o RDS, de modo que enquanto o banco de dados estiver na nuvem, nada no aplicativo precisa ser alterado. Por fim, assim como tudo em AWS, RDS é um modelo em que se paga apenas pelo que se usa. Não há custo inicial para hardware ou licenças. Paga-se por capacidade, armazenamento e largura da banda à medida que eles são usados.

Estabelecer e configurar RDS

AWS permite fornecer vários serviços através da linha de comando ou do console de gerenciamento do AWS. Eu costumo usar o console porque ele especifica as opções disponíveis para vários aspectos do RDS. Por isso, começaremos selecionando a guia RDS no console de gerenciamento do AWS e clicando no botão Launch Instance.

Na sua tela, é possível visualizar uma caixa de diálogo que permite especificar detalhes da instância do banco de dados MySQL, como tamanho da máquina, versão do MySQL e quanto armazenamento é alocado à instância do banco de dados. Observe que o AWS possui uma opção para implementar o banco de dados em diversas zonas de disponibilidade. Isso essencialmente cria um cluster, de modo que, se uma zona em particular ficar inativa, outras asseguram a cobertura.

Como mostra a Figura 1, é preciso especificar o nome do esquema, usuário administrador e senha do banco de dados:

Figura 1. Estabelecer a instância do RDS
Estabelecer a instância do RDS
Estabelecer a instância do RDS

Após clicar em Continue, outra caixa de diálogo é exibida para configurar o banco de dados em alto nível — começando com o nome, que é importante na URL do JDBC. Também é possível alterar a porta na qual o MySQL escuta e selecionar a zona de disponibilidade na qual o banco de dados ficará, como na Figura 2:

Figura 2. Configurar a instância RD
Configurar a instância RD
Configurar a instância RD

Em seguida, é possível observar as opções de gerenciamento relacionadas a como o AWS deve fazer backup dos dados e quando a manutenção deve ser agendada, como mostra a Figura 3:

Figura 3. Opções de gerenciamento do RDS
Opções de gerenciamento do RDS
Opções de gerenciamento do RDS

Após clicar em Continue e revisar a configuração, inicie a instância do RDS. Isso pode demorar alguns minutos, portanto esse é um bom momento para tomar um café ou entrar no Twitter. Quando o RDS estiver ativo, as coisas serão mais rápidas!

Segurança do RDS

Quando a instância estiver ativa, é preciso fazer mais uma coisa antes de acessá-la com a sua ferramenta de gerenciamento SQL favorita. Se já trabalhou com o AWS antes, você deve saber que, por padrão, as coisas ficam bloqueadas. É preciso permitir o acesso explicitamente.

As restrições de segurança do RDS são muito poderosas, o que permite especificar um IP único ou faixa de IP que possa se comunicar com o RDS. Entretanto, para os fins deste artigo, irei simplificar as coisas e permitir que qualquer IP se comunique com minha instância. Para fazer isso, é preciso acessar a área de janela DB Security do RDS e editar a restrição CIDR/IP para 0.0.0.0/0. Isso faz com que basicamente todos os IPs sejam permitidos. Essa etapa é mostrada na Figura 4:

Figura 4. Configurações de segurança do RDS
Configurações de segurança do RDS
Configurações de segurança do RDS

Após concluir essa etapa, reinicialize sua instância do RDS. (Clique com o botão direito no AWS Management Dashboard e será exibida a opção para reinicializar).

Se você selecionar sua instância RDS em execução, será exibida uma área de janela Description (mostrada na Figura 5) que fornece alguns detalhes importantes. O detalhe mais interessante agora é endpoint, que é a URL que será usada para conectar à instância MySQL.

Figura 5. O painel do RDS
O painel do RDS
O painel do RDS

Agora, é possível usar sua ferramenta favorita de gerenciamento de banco de dados (ou, se preferir, usar a linha de comando) e indicar a instância do RDS. Usarei Sequel Pro, que, como a maioria das ferramentas orientadas para GUI, fornece uma interface legal para visualizar tabelas e dados, e fornece também console de consulta. Para conectar, é preciso saber o nome de usuário, senha e URL de terminal do banco de dados.

Magnus, estilo RDBMS

Se você leu minha introdução a Elastic Beanstalk da Amazon (consulte Recursos), você está familiarizado com Magnus, o aplicativo de transferência de nuvem para dispositivo móvel que eu desenvolvi para aquele artigo. Para Magnus, foram criadas duas coleções no MongoDB: Account e Location. (Observe, no entanto, que eu também poderia ter apenas uma coleção chamada Account com cada documento contendo um documento integrado de Location.) Possuir essas duas coleções permitiu manter os locais das contas. No meu cenário de aplicativo, esses locais estariam localizados em dispositivos móveis em todo o mundo.

Eu irei modelar o mesmo relacionamento na demo do Amazon RDS, mas, desta vez, isso será feito da maneira tradicional. Poderia ser útil alternar um aplicativo como Magnus, com atualizações frequentes de local em todo o mundo, para o RDS. Especialmente considerando que o RDS permite armazenamento em cluster em várias zonas de disponibilidade. Lembre-se que há outras técnicas na área de RDBMS, como sharding, que divide os dados em partições lógicas. Consequentemente, também é possível fazer shards de contas e locais por geografia. De qualquer forma, armazenamento em cluster, replicação e sharding possuem vantagens e desvantagens, que devem ser consideradas atentamente antes de se adotar uma estratégia individual.

Para apresentar o Magnus no ambiente SQL, é preciso primeiro definir as tabelas relacionais, que (previsivelmente) chamarei de account e location. Isso é apresentado na Listagem 1:

Lista 1. Uma tabela account
CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

Na minha tabela location na Listagem 2, eu fornecerei uma chave estrangeira para account. Dessa maneira, é estabelecida uma relação de um para muitos entre accounts e diversas locations.

Lista 2. Uma tabela location
CREATE TABLE `location` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `account_id` int(11) DEFAULT NULL,
  `latitude` double DEFAULT NULL,
  `longitude` double DEFAULT NULL,
  `date_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `name` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `account_id` (`account_id`),
  FOREIGN KEY (`account_id`) REFERENCES `account` (`id`)
)

Após a definição das tabelas, é preciso criá-las na minha instância do RDS. Criar tabelas em uma instância RDS é igual a criá-las em uma instância MySQL executada na máquina local. Basta abrir um terminal e indicar sua GUI favorita para o terminal do RDS e criar as tabelas. Isso é muito simples.

Configurando Play

A estrutura de aplicativo da Web Play (consulte Recursos) funciona tão bem no Amazon RDS quando em Elastic Beanstalk, portanto irei usá-la para desenvolver meu aplicativo. Play facilita a alternância entre vários armazenamentos de dados e suporta JPA nativamente. Alternar uma implementação MongoHQ e uma que usa o Amazon RDS requer apenas algumas alterações no meu modelo. Primeiramente, o suporte integrado a JPA do Play significa que é preciso alterar o arquivo application.conf do Magnus e indicar a minha instância do RDS, como mostra a Listagem 3:

Lista 3. Uma tabela location
db.url=jdbc:mysql://magnus.cp3pl5vineyp.us-east-1.rds.amazonaws.com/magnus_locations
db.driver=com.mysql.jdbc.Driver
db.user=admin
db.pass=g3tf0kl

Não há nada de diferente aqui, — a Listagem 3 é 100% JDBC!

Modelando relacionamentos

Assim como todas as bibliotecas ORM de RDBMS, irei modelar minhas tabelas em um relacionamento um para um com objetos Java de nível superior: um tipo Account e um tipo Location. Meu Location será vinculado com Account.

Estender a partir do tipo de Modelo do Play oferece alguns benefícios. Por exemplo, os métodos finder-like, bem como os métodos CRUD típicos save e delete.

Minha classe Account utiliza duas anotações JPA. A anotação Table mostrada na Listagem 4 é necessária para indicar minha tabela account renomeada (em minúsculas).

Lista 4. Tipo Account
package models;

import play.db.jpa.Model;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name = "account") //required otherwise table is Account
public class Account extends Model {
 public String name;
}

Meu POJO Location, a seguir na Listagem 5, é um pouco mais complexo. É preciso adicionar mais duas anotações a ele e criar um relacionamento de muitos para um entre Locations e Accounts.

Lista 5. Uma classe Location definida com JPA
package models;

import play.db.jpa.Model;
import javax.persistence.*;
import java.math.BigDecimal;
import java.sql.Timestamp;

@Entity
@Table(name = "location")
public class Location extends Model {

 public BigDecimal latitude;
 public BigDecimal longitude;
 public String name;
 @Column(name = "date_time")
 public Timestamp timestamp;

 @ManyToOne
 @JoinColumn(name="account_id", nullable = false)
 public Account account;

}

Por fim, na Listagem 6, o método saveLocation foi atualizado a partir do meu controlador Application. (Lembre-se que, na implementação Magnus anterior, foi feito o roteamento de todos os PUTs de HTTP para /location/ para esse método.) saveLocation apenas cria um novo objeto Location (e, portanto, um registro correspondente) e liga essa instância Location a uma Account existente. Como o objeto Model do Play foi estendido anteriormente, também existe um método ActiveRecord útil.

Lista 6. Atualizações baseadas em locais com RDS
public static void saveLocation(String id, JsonObject body) throws Exception {
 String eventname = body.getAsJsonPrimitive("name").getAsString();
 double latitude = body.getAsJsonPrimitive("latitude").getAsDouble();
 double longitude = body.getAsJsonPrimitive("longitude").getAsDouble();

 Location loc = new Location();
 loc.longitude = new BigDecimal(longitude);
 loc.latitude = new BigDecimal(latitude);
 loc.name = eventname;
 loc.account = Account.findById(new Long(id));

 loc.save();

 renderJSON(getSuccessMessage());
}

Testes com RESTClient

É possível usar RESTClient para descobrir se o serviço de local atualizado está funcionando. Assim como foi feito com o Magnus, serão criados alguns documentos JSON e eles serão enviados.

Figura 6. Testes com RESTClient
Testes com RESTClient

Quando o método mantém, com sucesso, um novo registro Location, uma resposta JSON é enviada de volta indicando que a operação foi bem-sucedida. Como minha GUI avançada permite visualizar os dados em um RDBMS, eu apenas verifico a tabela location. Nessa verificação eu vejo novos registros Magnus na nuvem via RDS!

Figura 7. Aqui você pode visualizar todas as po0ssibilidades!
Aqui você pode visualizar todas as po0ssibilidades!
Aqui você pode visualizar todas as po0ssibilidades!

Conclusão

PaaS ajuda equipes de desenvolvimento de software que desejam desenvolver e implementar aplicativos da Web rapidamente. Neste artigo, eu apresentei Amazon RDS, uma solução PaaS que coloca o banco de dados relacional (neste caso, MySQL, mas RDS também oferece suporte ao Oracle Database) na nuvem. O fornecimento do Amazon RDS é muito fácil e ele funciona da mesma maneira que vários sistemas RDBMS que você provavelmente já desenvolveu ao longo dos anos. A principal diferença é que a Amazon cuida da manutenção para você.


Recursos para download


Temas relacionados


Comentários

Acesse ou registre-se para adicionar e acompanhar os comentários.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Cloud computing, Tecnologia Java
ArticleID=749672
ArticleTitle=Desenvolvimento Java 2.0: Utilizando Play com o Amazon RDS
publish-date=08022011