Seria mais fácil se todos os componentes fossem executados no mesmo espaço de heap da mesma máquina virtual Java no mesmo computador, mas na prática muitas vezes não enfrentamos uma situação tão única se o cliente for apenas um dispositivo que pode executar Java. fazer? E se, por motivos de segurança, apenas programas no servidor puderem acessar o banco de dados?
Sabemos que na maioria dos casos as chamadas de métodos ocorrem entre dois objetos no mesmo heap. E se você quiser chamar métodos em objetos em máquinas diferentes?
Normalmente, obtemos informações de um computador para outro através do fluxo de entrada/saída do soquete, abrimos a conexão do soquete do outro computador e, em seguida, obtemos o outputStream para gravar os dados. computador, quais são os métodos dos objetos em outra máquina virtual Java? Claro, podemos definir e projetar nós mesmos o protocolo de comunicação para chamar e depois transmitir os resultados da execução de volta através do Socket, e também pode ser como chamar métodos na máquina local, ou seja, se quisermos chamar objetos remotos (como como outros heaps) ), mas deve ser como uma chamada normal.
É isso que o RMI traz para nós.
O design de chamadas de procedimento remoto
Existem 4 coisas para criar: servidor, cliente, recursos auxiliares do servidor e recursos auxiliares do cliente.
1. Crie aplicativos cliente e servidor O aplicativo servidor é um serviço remoto, um objeto com métodos que o cliente chamará.
2. Crie auxiliares do lado do cliente e do servidor. Eles lidarão com todos os detalhes de entrada/saída da rede subjacente do cliente e do servidor, fazendo com que o cliente e o programa pareçam estar processando chamadas locais.
Tarefas de Recursos Auxiliares Recursos auxiliares são objetos que realmente realizam comunicação. Eles fazem o cliente sentir como se estivesse chamando um objeto local. O objeto cliente parece estar chamando um método remoto, mas na verdade está apenas chamando um método. proxy que lida com detalhes de soquete e streaming localmente No lado do servidor, os recursos auxiliares do servidor conectarão as solicitações dos recursos do cliente por meio do soquete, analisarão as informações empacotadas e, em seguida, chamarão o serviço real, portanto, para o objeto de serviço, isso é Depois. chamando o recurso auxiliar do serviço local, ele obtém o valor de retorno, encapsula-o e o envia de volta (por meio do fluxo de saída do soquete) para o recurso auxiliar do cliente. O recurso auxiliar do cliente descompacta as informações e as transmite ao objeto cliente.
O processo de chamar um método
1. O objeto cliente chama doBigThing() no objeto de recurso auxiliar
2. As instalações auxiliares do cliente empacotam as informações da chamada e as enviam para as instalações auxiliares do servidor através da rede.
3. O recurso auxiliar do lado do servidor decodifica as informações do recurso auxiliar do lado do cliente e as utiliza para chamar o serviço real.
O diagrama que descreve esse processo é o seguinte:
JavaRMI fornece objetos auxiliares do lado do cliente e do lado do servidor
Em Java, o RMI nos ajudou a criar recursos auxiliares do lado do cliente e do lado do servidor. Ele também sabe como fazer com que os recursos auxiliares do lado do cliente pareçam serviços reais. .
Além disso, o RMI fornece toda a infraestrutura necessária para a execução, incluindo consulta de serviços e facilidades auxiliares que permitem aos clientes encontrar e obter clientes (agentes de serviço reais).
Ao usar RMI, não há necessidade de escrever nenhum programa de rede ou de entrada/saída. A chamada do cliente para um método remoto é igual a uma chamada de método na mesma máquina virtual Java.
As chamadas gerais são um pouco diferentes das chamadas RMI. Embora para o cliente esta chamada de método pareça local, mas o recurso auxiliar do cliente fará a chamada através da rede. e o agente irá convertê-lo em um remoto. A forma como as informações intermediárias são enviadas da máquina virtual Java para a máquina virtual Java depende do protocolo usado pelo objeto de recurso auxiliar.
Ao usar RMI, você deve decidir sobre o protocolo: JRMP ou IIOP é o protocolo nativo do RMI. Ele é projetado para chamadas remotas entre Java. Para objetos ou outros tipos de métodos remotos, CORBA geralmente é mais problemático que RMI, porque se ambas as extremidades não forem Java, ocorrerão várias operações terríveis de tradução e conversação.
Nós nos preocupamos apenas com operações Java para Java, então usaremos um RMI bastante simples.
No RMI, os recursos auxiliares do lado do cliente são chamados de stubs, e os recursos auxiliares do lado do servidor são chamados de esqueletos.
Como criar um serviço remoto
1.Criar interface remota
A interface remota define os métodos que o cliente pode chamar remotamente. É uma classe polimórfica como serviço. Tanto o stub quanto o serviço implementarão esta interface.
2. Implemente a interface remota
Esta é a classe de execução real. Ela implementa os métodos definidos na interface. É o objeto que o cliente irá chamar.
3. Use rmic para gerar stub e esqueleto
Tanto o cliente quanto o servidor possuem ajudantes. Não precisamos criar essas classes ou gerar o código fonte dessas classes. Isso será tratado automaticamente ao executar a ferramenta rmic anexada ao JDK.
4. Inicie o RMIregistry (rmiregistry)
rmiregistry é como uma lista telefônica, o usuário obterá o proxy (o objeto stub/helper do cliente) daqui
5. Inicie o serviço remoto
O objeto de serviço deve começar a ser executado. A classe que implementa o serviço iniciará a instância do serviço e a registrará no RMIRegistry. Somente após o registro ele poderá atender o usuário.
Código do servidor
Definir interface
/**
*
*MeuRemoto.java
*
* Função: TODO
* Nome da classe: MyRemote.java
*
* ver. Suporte de personagem atualizado e novo conteúdo.
*──────────────────────────────────────── ────
* V1.00 19/03/2013 Primeira versão do módulo Su Ruo
*
* Copyright (c) 2013 dennisit corporation Todos os direitos reservados.
*
* E-mail:<a href="mailto:[email protected]">Enviar e-mail</a>
*
*
* Remote é uma interface marcada, o que significa que não há métodos. Porém, tem um significado especial para RMI, portanto esta regra deve ser seguida.
* Observe que extends é usado aqui e interfaces podem herdar outras interfaces.
*
*/
interface pública MyRemote estende Remote{
/**
* A interface remota define os métodos que o cliente pode chamar remotamente. É uma classe polimórfica como serviço.
* Mobilize o stub que implementa esta interface e, como esse stub executará trabalhos de rede e de entrada/saída, várias coisas podem acontecer
* Problema, o cliente trata ou declara exceções para reconhecer este tipo de risco. Se o método declarar uma exceção na interface, chame o método.
* Todos os procedimentos devem tratar ou declarar novamente esta exceção.
*
* Os parâmetros e valores de retorno dos métodos remotos devem ser primitivos ou serializáveis.
* O pacote é transmitido pela rede e quando é concluído pela serialização, o valor de retorno é o mesmo, portanto, se for utilizado um tipo customizado.
*, deve ser serializado
* @retornar
* @throws RemoteException
* Todos os métodos da interface devem declarar RemoteException
*/
public String sayHello() lança RemoteException;
}
/**
*
*MyRemoteImpl.java
*
* Função: TODO
* Nome da classe: MyRemoteImpl.java
*
* ver. Suporte de personagem atualizado e novo conteúdo.
*──────────────────────────────────────── ────
* V1.00 19/03/2013 Primeira versão do módulo Su Ruo
*
* Copyright (c) 2013 dennisit corporation Todos os direitos reservados.
*
* E-mail:<a href="mailto:[email protected]">Enviar e-mail</a>
*
* Para se tornar um objeto de serviço remoto, o objeto deve ter funções relacionadas ao controle remoto. O método mais simples é herdar UnicastRemoteObject.
* (de java.rmi.server) para permitir que esta classe pai cuide do trabalho
*
*/
classe pública MyRemoteImpl estende UnicastRemoteObject implementa MyRemote{
/**
* O construtor da classe pai declara uma exceção, então você deve escrever o construtor porque isso significa que seu construtor chamará código de programa arriscado
*
* UnicastRemoteObject tem um pequeno problema, seu construtor lança RemoteException. A única maneira de lidar com isso é.
* Declare um construtor para sua própria implementação para que haja um local para declarar RemoteException Quando a classe for inicializada, a classe pai.
* O construtor será definitivamente chamado. Se o construtor da classe pai lançar uma exceção, o construtor personalizado que devemos declarar também lançará uma exceção.
* @throws RemoteException
*/
protegido MyRemoteImpl() lança RemoteException {
}
/**
* Implemente todos os métodos da interface de saída, mas não precisa declarar RemoteException
*/
@Substituir
public String dizerOlá(){
return "servidor diz, rmi olá mundo!";
}
public static void main(String[] args) {
tentar {
/**
* Já temos um serviço remoto e devemos permitir que usuários remotos o acessem. Isso pode ser feito inicializando-o e adicionando-o ao Registro RMI.
* (Deve estar em execução, caso contrário este programa falhará). Ao registrar um objeto, o sistema RMI adicionará o stub ao registro,
* Porque é isso que o cliente precisa. Use rebind() de java.rmi.Naming para registrar o serviço.
*/
serviço MyRemote = new MyRemoteImpl();
/**
* Crie um objeto remoto e use Naming.rebind() estático para criar uma associação. O nome registrado será fornecido para consulta do cliente.
*/
Naming.rebind("Remoto Olá Mundo", serviço);
} catch (Exceção e) {
e.printStackTrace();
}
}
}
public voidexec(){
tentar {
/**
* O cliente deve obter o objeto stub porque o cliente deve chamar seu método. Isso depende do registro RMI. O cliente consultará o telefone.
* Pesquise no mesmo diretório para encontrar serviços com nomes correspondentes.
* O cliente consulta RMIRegistry e retorna o objeto stub
* Naming.lookup("rmi://127.0.0.1/Remote Olá Mundo");
* Descrição do parâmetro
* rmi://127.0.0.1/Remote Olá Mundo
* 127.0.0.1 representa o nome do host ou endereço IP do host
*O Hello World remoto deve ser igual ao nome registrado
*
*/
Serviço MyRemote = (MyRemote)Naming.lookup("rmi://127.0.0.1/Remote Olá Mundo");
String tmp = service.sayHello();
System.out.println(tmp);
} catch (Exceção e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new MyRemoteClient().exec();
}
}
A ferramenta rmic que acompanha o JDK irá gerar duas classes, stub e esqueleto, com base na implementação do serviço. Ela adicionará _Stub ou _Skeleton após o nome da implementação remota de acordo com as regras de nomenclatura. O rmic tem várias opções, incluindo não gerar esqueletos, observar o código fonte das classes geradas ou usar IIOP como protocolo de comunicação. As classes geradas serão colocadas no diretório atual. Lembre-se que o rmic deve ser capaz de encontrar as classes implementadas. Portanto, pode ser necessário executar rmic a partir do diretório onde a implementação está localizada (na prática, pode ser necessário considerar a estrutura de diretórios do pacote e o nome completo, para simplificar, o pacote não é usado aqui)
Chame a linha de comando para iniciar o rmiregistry. Certifique-se de iniciá-lo a partir de um diretório que possa acessar a classe.
A captura de tela em execução é a seguinte
Perceber:
O cliente usa a interface para chamar o método no stub A máquina virtual Java do cliente deve ter uma classe stub, mas o cliente não fará referência à classe stub no código do programa.
O servidor deve ter stubs e esqueletos, bem como interfaces de serviço e remotas. Requer a classe stub porque o stub será substituído pelo serviço real conectado ao RMIRegistry.
Erros comuns ao usar RMI:
1. Esqueci de iniciar o rmiregistry antes de iniciar o serviço remoto (rmiregistry deve ser iniciado antes de usar Naming.rebind() para registrar o serviço)
2. Esqueci de tornar os parâmetros e tipos de retorno serializáveis (não será detectado durante a compilação e só será descoberto durante a execução)
3. Esquecer de entregar a classe stub ao cliente
O RMI é muito adequado para escrever e executar serviços remotos, mas não usaremos o RMI sozinho para executar serviços de site. Para aplicativos de nível empresarial em grande escala, precisamos de mais e melhores funções, como gerenciamento de transações, processamento simultâneo em grande escala. e segurança e gerenciamento de banco de dados, etc. Isso requer o uso do EnterpriseApplicationServer.
O servidor JavaEE inclui um servidor Web e um servidor Enterprise JavaBeans (EJB). O servidor EJB atua entre as chamadas RMI e a camada de serviço.
Aplicação de RMI no JINI
Jini também usa RMI (embora outros protocolos também possam ser usados), mas possui várias outras funções importantes.
1. Descoberta adaptativa
2. Redes de autocura
O cliente RMI deve primeiro obter o endereço e o nome do serviço remoto. O código do programa de consulta do cliente deve conter o endereço IP ou nome do host do serviço remoto (porque o RMIRegistry está nele) e o nome registrado pelo serviço.
Mas ao usar o JINI, o usuário só precisa saber uma coisa, a interface implementada pelo serviço.
Jini usa lookupservice, que é mais forte e adaptável do que RMIRegistry porque Jini anunciará automaticamente na rede quando o serviço de consulta estiver online, ele usará a tecnologia IP multicast para enviar informações para toda a rede. fica online após a transmissão do serviço de consulta, e o cliente também pode enviar mensagens para toda a rede para consultar.
Quando o serviço estiver online, ele explorará dinamicamente o serviço de consulta JINI na rede e solicitará o registro. Ao registrar-se, o serviço enviará um objeto serializado para o serviço de consulta. Este objeto pode ser o stub do serviço remoto RMI. driver do dispositivo de rede, ou mesmo o próprio serviço que pode ser executado no cliente. E o que está registrado é a interface implementada.
Como funciona a exploração adaptativa
1. O serviço de consulta Jini começa na rede e usa tecnologia IP multicast para se promover
2. Outro serviço Jini que foi iniciado buscará se registrar no serviço de consulta recém-iniciado. Ele registra a função em vez do nome, ou seja, a interface implementada, e então envia o objeto serializado para o serviço de consulta.
3. Os clientes da Internet desejam obter algo para implementar a Calculadora Científica, mas não sabem onde encontrar, então solicitam o serviço de consulta
4. O serviço de consulta responde aos resultados da consulta
Operação de uma rede de autocura
1. Um determinado serviço Jini requer registro e o serviço de consulta concederá um aluguel. Os serviços recém-registrados deverão renovar o aluguel regularmente. Caso contrário, o serviço de consulta assumirá que o serviço está offline. completar o status da rede de serviço disponível.
2. O serviço está offline devido ao encerramento, portanto o arrendamento não é atualizado e o serviço de consulta é iniciado.