(Remote Method Invocation)

Propaganda
APLICAÇÕES EM SISTEMAS DISTRIBUÍDOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com
- Aula 5 PROGRAMAÇÃO DISTRIBUÍDA COM RMI1
(Remote Method Invocation)
1. INTRODUÇÃO
Sistemas distribuídos necessitam que aplicações, executando em vários espaços de
endereçamento, normalmente em diferentes computadores, que sejam capazes de se comunicar.
O endereçamento de equipamentos na Internet é baseado em um identificador que
independe da tecnologia de rede envolvida, conhecido como endereço IP (Internet Protocol), cujo
formato é o do exemplo a seguir: 128.32.96.4.
Este formato representa um número de 32 bits que, no modo normal de endereçamento da
Internet, está associado a um único equipamento. Ele identifica a rede e o seu equipamento nela.
Existe outro modo de endereçamento conhecido como multicasting, onde um endereço IP
está associado a um grupo de computadores. O endereço IP permite apenas a localização de um
dado equipamento na Internet. Para a localização de uma aplicação executando em um
equipamento existe outro identificador conhecido como porta (Port). Esta localização é obtida
através da associação da port com um dos protocolos de transporte Transmission Control Protocol
(TCP) ou User Datagram Protocol (UDP). Essa tríade composta por endereço IP, número de port e
protocolo de transporte é conhecida como socket (Cyclades Brasil, 1996).
Apesar do socket ser flexível o suficiente para comunicação em geral, ele requer do cliente
e do servidor o conhecimento dos protocolos para troca de mensagens, isto é, a codificação e
decodificação destas mensagens. O projeto destes protocolos é sempre difícil e susceptível a erros.
Assim, o Java suporta o conceito de invocação de método remoto (Remote Method
Invocation - RMI) permitindo uma abstração maior ao desenvolvedor que não precisa se preocupar
com o mecanismo de comunicação entre cliente e servidor.
2. RMI
Basicamente o RMI é um RPC (Chamada de Procedimentos Remotos), que ao invés de
realizar chamadas a procedimento remotos realiza chamadas a métodos de um objeto remoto.
Um objeto remoto é aquele que se localiza em uma JVM (Java Virtual Machine) diferente
daquela em que se encontra o cliente, potencialmente em outro computador. Um objeto remoto
é descrito por uma ou mais interfaces escritas na própria linguagem de programação
Java. Por se tratar de um objeto remoto estas interfaces são chamadas de interfaces remotas. A
invocação de um método de um objeto remoto tem a mesma sintaxe que a invocação de um
método de um objeto local. O cliente quando invoca um objeto não sabe se esse objeto é
local ou remoto em relação a ele.
O RMI providencia a:
1
RMI nada mais é que a Invocação de Métodos Remotamente, ou seja, permite a execução de chamadas
remotas em aplicações desenvolvidas na linguagem Java.
1
APLICAÇÕES EM SISTEMAS DISTRIBUÍDOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com



Localização (binding) de um método de um objeto remoto.
Comunicação através de uma conexão de rede confiável permitindo a transmissão de
requisições e respostas, funcionando como um canal entre cliente e servidor.
Interface com usuário convertendo uma chamada de método em um bloco de dados
(mensagem) que possa trafegar através da conexão e remontando a mesma chamada de
método no outro extremo (remoto) a partir desta mensagem.
São necessários códigos nos pontos finais da conexão para deixar transparente o
uso do RMI pelo usuário. No lado cliente, um stub tem a mesma assinatura (nome,
argumentos e tipo de retorno) que o método remoto e sua função é empacotar os
argumentos em uma mensagem para ser enviada através do canal de comunicação.
Quando uma mensagem contendo os resultados enviados pelo servidor surgir neste canal, o
stub extrai o valor de retorno antes de passá-lo para o código que chamou o método.
O complemento do stub, localizado no lado do servidor, é chamado de skeleton. Sua função
é converter as mensagens que chegam pelo canal de comunicação em argumentos e
chamar as implementações dos métodos requisitados. Quando o método termina a
execução, o valor de retorno é convertido em uma mensagem que é remetida ao stub do cliente.
A arquitetura em que se baseia o RMI consiste de três camadas:
 Camada stub/skeleton
 Camada de referência remota (remote reference)
 Camada de transporte
Elas são independentes entre si e podem ser substituídas por diferentes implementações sem
que uma afete a outra. Por exemplo, pode-se substituir a camada de transporte implementada em
TCP, usando socket Java, por outra baseada em UDP.
2
APLICAÇÕES EM SISTEMAS DISTRIBUÍDOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com
3. CAMADA STUB/SKELETON
A camada stub/skeleton é a interface entre a aplicação e as outras camadas que
compõem o RMI. Esta camada não trata do transporte em si, mas é responsável por
transmitir os dados para a camada de referência remota como um stream de dados.
Esse stream chamado de marshal stream emprega o mecanismo de serialização de objeto (object
serialization). Este mecanismo permite que numa invocação (local ou remota) objetos Java possam
ser passados como argumentos ou retornados como resultado da execução de métodos. Os
objetos Java, transmitidos através deste sistema de serialização de objetos, são passados por
cópia entre espaços de endereçamento diferentes, isto é, máquinas diferentes. Caso já sejam
objetos remotos, eles serão repassados por referência, onde referência de um objeto remoto é a
referência de uma instância desse objeto. A serialização de objeto é específica da linguagem Java,
assim, tanto clientes quanto servidores devem estar escritos em Java (Albuquerque, 1998).
Quando um cliente invoca um método de um objeto remoto, os parâmetros do método são
convertidos em um bloco de dados (mensagem) pelo stub e esta mensagem é enviada a máquina
remota utilizando o protocolo, por exemplo, TCP/IP. Quando a mensagem chega à máquina
remota, o skeleton transforma esta mensagem em argumentos e chama a implementação do
método convertendo o resultado em uma mensagem que é redirecionada a máquina cliente, cujo
stub é responsável pela extração do valor de retorno.
O stub que se localiza no lado cliente contém todas as interfaces suportadas pela
implementação do objeto remoto, sendo responsável por (Java, 1999):





Iniciar a chamada do objeto remoto (acionando a camada de referência remota).
Fazer o marshaling dos argumentos, utilizando o mecanismo de serialização de objeto, que
será enviado para a camada de referência remota.
Informar à camada de referência remota que a chamada pode ser invocada.
Fazer o unmarshaling do valor de retorno ou exceção obtido.
Informar à camada de referência remota que a chamada foi completada.
O skeleton que se localiza no lado servidor contém um método que envia as chamadas
recebidas do cliente para a implementação do objeto remoto, sendo responsável por (Java, 1999):
 Fazer o unmarshaling dos argumentos recebidos.
 Realizar a chamada da implementação do objeto que executará o serviço requerido pelo
cliente remoto.
 Fazer o marshaling do valor de retorno ou da situação de exceção, caso ocorra, utilizando o
mecanismo de “serialização” de objeto que será enviado para a origem da chamada.
As classes dos stubs e skeletons apropriadas são determinadas em tempo de execução e
carregadas dinamicamente quando necessárias para atender uma requisição do cliente.
4. CAMADA DE REFERÊNCIA REMOTA
A camada de referência remota lida com a interface de transporte de baixo nível por
meio de um protocolo. Esse protocolo é independente do stub do cliente e skeleton do servidor.
3
APLICAÇÕES EM SISTEMAS DISTRIBUÍDOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com
O stub e skeleton desconhecem os diversos tipos de protocolo que um servidor pode utilizar.
Existem vários protocolos que podem ser especificados e executados por esta camada, tais
como (Java, 1999):



Servidores suportam somente invocação ponto-a-ponto, onde um cliente interage com um
único objeto.
Servidores suportam replicação, onde um número de objetos remotos replicados precisam
se manter sincronizados sempre que uma instância é modificada.
Objetos remotos não estão continuamente ativos, sendo somente carregados do disco
quando um cliente invoca um de seus métodos.
Este protocolo pode ser selecionado pelo usuário que escolhe como a camada de referência
será utilizada. Atualmente, a implementação da camada de referência está restrita a invocação
ponto-a-ponto, onde um cliente interage com um único objeto (não replicado) cuja referência é
somente válida quando o processo servidor está executando. A classe que implementa esse
protocolo é a java.rmi.server.UnicastRemoteObject.
5. CAMADA DE TRANSPORTE
A camada de transporte manipula os detalhes da conexão e providencia um canal de
comunicação entre as JVM’s executando o código cliente e código servidor. O lado cliente deve
possuir a interface do objeto remoto para poder referenciá-lo, enquanto o lado servidor possui a
implementação do mesmo. Em geral, esta camada é responsável por (Java, 1999):







Estabelecer conexões entre espaços de endereçamentos remotos, isto é, entre JVM’s
diferentes.
Gerenciar conexões.
Monitorar conexões (se elas existem ou não (liveness)).
Escutar chamadas que estejam sendo recebidas.
Manter uma tabela que contém os objetos remotos residentes num determinado espaço de
endereçamento.
Estabelecer a conexão para as chamadas que estejam sendo recebidas.
Localizar o alvo de uma chamada remota passando a conexão para quem a chamou.
6. APLICAÇÕES UTILIZANDO RMI
O RMI utilizando a facilidade de nomeação (rmiregistry), implementa um objeto servidor
de nomes que mantém registrados todos os objetos localizados num host com os seus
respectivos nomes, tornando acessível a referência desses objetos ao cliente. Uma aplicação
cliente típica para invocar métodos de um objeto remoto deve obter primeiro a referência desse
objeto.
Essa referência é passada ao servidor que localizará a implementação do objeto. O RMI
trata os detalhes de comunicação entre cliente e servidor, assim, o cliente vê a invocação de um
método de um objeto remoto como a de um objeto local.
4
APLICAÇÕES EM SISTEMAS DISTRIBUÍDOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com
Na figura acima um cliente RMI (a) utiliza o sistema de registro para obter a referência de
um objeto remoto, após obtida, invoca os seus métodos (b). Caso seja necessário o RMI pode, se
o cliente autorizar, utilizar o servidor web para localizar e carregar objetos remotos, isto é, classes
Java em bytecodes. Para o carregamento pode-se utilizar qualquer protocolo Uniform Resource
Locator (URL) suportado pelo sistema Java, por exemplo, HTTP, FTP, file, etc. Essas classes
podem ser carregadas para serem executadas no servidor ou no cliente.
Em aplicações que utilizam RMI, o método é executado na máquina onde se encontra o
objeto sobre o qual ele atua. O objeto pode estar tanto em uma máquina diferente daquela onde
se encontra o cliente quanto na mesma máquina.
7. CARREGAMENTO DINÂMICO DE STUB
Em sistemas onde se utiliza o RPC, o código do stub deve ser gerado e linkado junto ao
cliente antes de sua execução. Este código pode ser linkado estaticamente ou linkado
dinamicamente em tempo de execução, utilizando para isso bibliotecas disponíveis localmente ou
na rede. Em ambos os casos, o código que realiza o RPC deve estar disponível, na forma
compilada, na máquina do cliente.
O RMI generaliza essa técnica de carregar o código do stub em tempo de execução. Essa
generalização do carregamento dinâmico do stub (dynamic stub loading) utiliza-se da capacidade
do Java de realizar downloading de código. Tipicamente, o stub é carregado dinamicamente do
sistema de arquivos locais, neste caso, o gerenciador de segurança não apresenta restrições.
Entretanto, quando ele é carregado da rede, suas classes passam pelo gerenciador de segurança,
prevenindo, assim, problemas potenciais de segurança (Java, 1999).
O carregamento do stub, de forma dinâmica, é utilizado somente quando um cliente
necessita de um determinado stub não disponível. Neste esquema, o código do stub (lado cliente)
suporta o mesmo conjunto de interfaces remotas da implementação da classe que o gerou. Esse
código do stub, residente num servidor host ou em qualquer outra localização, será enviado ao
cliente sob demanda (downloaded). Para uma implementação remota, esse código pode ser
5
APLICAÇÕES EM SISTEMAS DISTRIBUÍDOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com
gerado em tempo real (on-the-fly) no lado remoto e enviado para o cliente ou pode ser gerado no
lado cliente através de uma lista de interfaces suportadas pela implementação remota.
O carregamento dinâmico do stub emprega o carregador de classes do Java, o
gerenciador de segurança e a serialização de objeto (Java, 1999). Quando a referência de
um objeto remoto for passada como parâmetro ou como resultado de uma chamada de método, o
marshal stream, que transmite essa referência, incluirá também a informação de onde carregar a
classe do stub para o objeto remoto (o URL, se ele for conhecido). Assim, quando a referência de
objeto remoto for unmarshaled no destino, o marshal stream poderá localizar e carregar o código
do stub (via carregador de classe e verificado pelo gerenciador de segurança) de tal forma que o
cliente tenha disponibilizado o stub correto.
8. COMUNICAÇÃO DE OBJETOS DISTRIBUÍDOS
1.
2.
3.
4.
5.
6.
7.
8.
9.
O objeto A faz a chamada do método desejado no Stub;
O Stub converte a chamada em protocolo RMI e envia pela Rede;
A requisição é enviada pela rede
O Skeleton recebe a requisição em RMI e reconhece qual método deve ser chamado;
Chama o método desejado no Objeto B;
Recebe o retorno do método;
Envia a o objeto de Retorno para o Cliente;
O Stub recebe o retorno;
O Stub repassa o retorno para o Objeto A;
9. PROCEDIMENTOS DE PROGRAMAÇÃO
1.
2.
3.
4.
5.
6.
Escrever Interface remota;
Implementar a Interface;
Implementar Servidor que contém a Implementação da interface remota;
Gerar Stub e Skeleton da Interface;
Registrar Servidor e Disparar Servidor;
Escrever Cliente que utiliza métodos da Interface;
6
APLICAÇÕES EM SISTEMAS DISTRIBUÍDOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com
10. IMPLEMENTAÇÃO
a. Escrevendo a Interface Remota
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello extends java.rmi.Remote {
public String msg() throws RemoteException;
}
b. Implementando a Interface
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class HelloImpl extends UnicastRemoteObject implements Hello {
private String message;
public HelloImpl (String msg) throws java.rmi.RemoteException {
super();
message = msg;
}
public String msg() throws RemoteException {
return message;
}
}
c. Implementando o Servidor que contém a Implementação da interface remota
import java.rmi.*;
public class Server {
public static void main (String[] argv) {
try {
Naming.rebind("Hello", new HelloImpl ("Hello world!"));
System. out.println ("Hello Servidor está funcionando");
}
catch (Exception e) {
System.out.println ("Hello Server failed: " + e);
e.printStackTrace();
}
}
}
d. Gerando Stub e Skeleton da Interface
javac *.java
rmic –v1.1 HelloImpl
7
APLICAÇÕES EM SISTEMAS DISTRIBUÍDOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com
e. Registrando e Disparando o Servidor
rmiregistry (linux)
start rmiregistry (windows) (porta default = 1099)
java Server (executar o servidor)
f. Escrevendo o Cliente que utiliza os métodos da Interface
import java.rmi.*;
public class Cliente {
public static void main(String[] argv) {
try {
Hello hello = (Hello) Naming.lookup("//localhost/Hello");
System.out.println(hello.msg());
}
catch (Exception e) {
System.out.println("HelloClient exception: " + e);
}
}
}
g. Gerando e Executando o Cliente
javac Cliente.java
java Cliente
7. REFERÊNCIAS
Tutorial RMI. <http://java.sun.com/docs/books/tutorial/rmi/index.html>
Andleigh, P. K.; Gretzinger, M. R. Distributed object-oriented data-systems design. New
Jersey: Prentice-Hall, 1992.
Cyclades Brasil. Guia Internet de conectividade. São Paulo, 1996.
DEITEL, H. M.; Deitel, P. J. Java how to program. New Jersey: Prentice-Hall, 2001.
COSTA, Samira Rachid da. Objetos distribuídos: conceitos e padrões. Dissertação de
Mestrado. 2001.
8
Download