Internalização da tecnologia cliente/servidor na Celepar
Autor: Vidal Martins – GPT
A Celepar está internalizando a tecnologia cliente/servidor através do desenvolvimento e implantação de uma aplicação pioneira para o DETRAN. Devido a este trabalho, freqüentemente nos solicitam informações e esclarecimentos sobre essa tecnologia. Acreditamos que a maioria dos desenvolvedores de sistemas ainda não domina os conceitos referentes a essa área, bem como métodos para a implantação dessa tecnologia. Sendo assim, produzimos este artigo com o objetivo de contribuir para o crescimento de todos os interessados em arquitetura cliente/servidor, que ainda não tiveram a oportunidade de se aprofundar no assunto.
Primeiramente, vamos apresentar um conceito: numa arquitetura cliente/ servidor o processamento é dividido entre duas entidades, um cliente e um servidor, sendo que essas duas entidades estão fisicamente conectadas através de uma rede. Esse conceito é trivial, mas já permite levantar algumas questões, tais como: O que deve ser processado pelo cliente? O que deve ser processado pelo servidor? Quais produtos devem ser instalados na rede para permitir a interoperabilidade entre o cliente e o servidor? As respostas para essas perguntas não são tão simples, cada caso é um caso.
A tabela 1 mostra o progresso da computação, desde a arquitetura tradicional de mainframes até a arquitetura cliente/servidor.
Tabela 1: O progresso da computação desde mainframes até cliente/servidor.
Para compreender melhor os limites entre arquitetura de mainframe, arquitetura file-server e a variedade de arquiteturas cliente/servidor, vamos nos basear em um artigo produzido por Herb Edelstein, fundador da Euclid Associates, uma empresa de consultoria em banco de dados sediada em Potomac, Maryland. Segundo Edelstein, podemos dividir uma aplicação em seis componentes:
Serviços de apresentação: são fornecidos por um dispositivo que aceita as entradas do usuário e mostra tudo o que a lógica de apresentação mandar.
Lógica de apresentação: controla a interação entre o usuário e o computador, ou seja, especifica o que acontece quando o usuário seleciona uma opção de menu, quando aciona um botão, ou quando escolhe um item de uma list box.
Lógica do negócio, ou lógica da aplicação: é um conjunto de decisões, cálculos e operações que a aplicação deve executar, tal como o cálculo do salário de um empregado, a análise da melhor forma de aplicar um recurso financeiro, ou os procedimentos necessários para transferir fundos de uma conta bancária para outra.
Lógica de dados: é a especificação das operações que devem ser executadas no banco de dados para cumprir os requisitos da lógica do negócio. Para um banco de dados relacionaI, essa especificação nada mais é do que um conjunto de declarações SQL, tais como SELECT, UPDATE e INSERT.
Serviços de dados: são as ações que o sistema gerenciador de banco de dados executa para que se cumpra a lógica dos dados. Isto inclui a definição de dados, a manipulação de dados, commit e rollback de transação, etc.
Serviços de arquivos: normalmente são funções do sistema operacional de leitura e gravação de dados.
Agora que você já conhece os componentes de uma aplicação responda: onde se localiza a garantia de integridade referencial? Na lógica de dados, no serviço de dados, ou na lógica do negócio? Dependendo da sua interpretação, qualquer uma dessas categorias poderia ser apropriada. Na realidade, a questão mais importante é: a quais dispositivos devemos atribuir as partes de uma aplicação? Para tentar responder essa questão, vamos analisar a tabela 1 comparando as qualidades e as deficiências de cada arquitetura.
Observe que nos ambientes de mainframe o terminal fornece os serviços de apresentação, enquanto o host fornece o restante das funções. Isto causa basicamente dois problemas sérios. Primeiro, a interface com o usuário fica limitada a um terminal, ou seja, é difícil, se não impossível, fornecer uma interface GUI (Graphical User Interface) eficiente quando todos os processamentos residem na máquina central. Segundo, cada aplicação ou usuário adicional causa uma carga substancial ao mainframe. Isto causa uma perda de escalabilidade. A própria carga da rede é maior do que a necessária, uma vez que o host, além de enviar os dados para o terminal , tem que transmitir instruções para a formatação da tela.
A arquitetura file-server coloca os serviços de arquivos no servidor e todas as demais funções ficam alocadas na máquina cliente. O servidor de arquivos apenas recupera os arquivos necessários e os transmite para a estação cliente. Assim sendo, podemos afirmar que a arquitetura file-server resolve os problemas da arquitetura baseada em mainframe porém cria novas dificuldades. Resolve os problemas na medida em que permite a criação de interface gráfica eficiente e acrescenta pequena carga de trabalho à CPU toda vez que se aumenta o número de usuários ou de aplicações na rede. Em compensação, cria os seguintes inconvenientes: a demanda na estação cliente torna-se muito alta e aumenta consideravelmente o tráfego na rede.
A arquitetura cliente/servidor foi projetada para resolver esses problemas, separando os componentes de uma aplicação e colocando cada um deles no local onde é mais eficiente. Uma vez que existem diversas formas de distribuir esses componentes, é importante compreender as diferentes arquiteturas cliente/servidor e para que tipo de aplicações cada uma é adequada.
A maioria das configurações cliente/servidor hoje utiliza um modelo two-tiered (duas-camadas), na qual um cliente solicita serviços a um servidor. É possível que um servidor funcione como cliente de outro servidor formando uma espécie de arquitetura cliente/servidor hierárquica. Neste caso, trata-se ainda de uma abordagem two-tiered, porém, encadeada.
No mínimo, uma arquitetura cliente/servidor pressupõe que os serviços de apresentação e a lógica de apresentação residam no cliente. Isto resolve os inconvenientes de uma interface tipo terminal fornecendo um gerenciador de interface gráfica local. Mas, para onde vão os demais componentes da aplicação?
A primeira possibilidade é colocar os serviços de dados e de arquivos no servidor, e a lógica do negócio e a lógica de dados no cliente. Esta abordagem pode ser chamada de "SGBD remoto". A maioria das definições superficiais de computação cliente/servidor emprega este modelo: a aplicação está no cliente e o SGBD no servidor. Uma vez que este modelo coloca a menor demanda no servidor ele é o que prove a melhor escalabilidade. No entanto, para aplicações complexas que envolvem uma grande interação com banco de dados, ele pode ocasionar sobrecarga na estação cliente e na rede. Outra desvantagem desse modelo diz respeito ao gerenciamento da aplicação, pois uma cópia completa do código executável reside em cada estação cliente. Quando você, muda o código, você tem que substituí-lo em todas as estações.
Você pode reduzir a carga do cliente e da rede transferindo parte da lógica do negócio para o servidor. Este modelo cliente/servidor é chamado de split-logic, que em português significa aproximadamente lógica distribuída.
O próximo passo para minimizar o impacto da aplicação sobre as estações cliente é transferir toda a lógica do negócio para o servidor, deixando apenas a lógica e os serviços de apresentação no cliente. Este modelo é chamado de apresentação remota.
O mecanismo mais comumente utilizado para implementar a lógica do negócio nos servidores são as stored procedures. Uma vez que elas são compiladas, o uso sensato de stored procedures pode melhorar a performance e reduzir a carga do servidor, se comparado ao uso de SQL dinâmico (comando SQL não compilado emitido pela estação cliente). Para compreender porque isto ocorre temos que entender os dois passos do processo de compilação. Primeiro a SQL é processada, o que significa checar nomes de tabelas e colunas, direitos de acesso do usuário que está acionando o procedimento e otimizar a SQL. Otimização é o processo através do qual o SGBD determina o melhor caminho de acesso aos dados. O segundo passo é compilar a parte procedural do código. Observe que se não utilizarmos stored procedures todas essas tarefas serão executadas em tempo real, durante o processamento da transação. Outro aspecto importante quanto à performance é que uma stored procedure pode ser armazenada em um cache de procedimentos, reduzindo assim o número de I/Os da aplicação.
As arquiteturas two-tiered (SGBD remoto, lógica distribuída e apresentação remota) também apresentam alguns problemas, se considerarmos aplicações complexas, com muitos clientes, lógica intrincada, bases de dados heterogêneas e entradas de dados heterogêneas para as bases de dados.
O primeiro problema é definir onde colocar a lógica do negócio. Colocar no cliente implica muito esforço no momento de uma alteração ou de um upgrade, pois o software terá que ser alterado, instalado e testado em todas as estações.
O segundo problema diz respeito ao uso de stored procedures para implementar lógica complexa. Infelizmente, as linguagens procedurais utilizadas nas stored procedures não têm capacidade equivalente às linguagens convencionais. Além disso, possuem um ambiente de desenvolvimento precário no que diz respeito a testes, depuração, controle de versão e gerenciamento de bibliotecas. Pior que isso é o fato de todas as implementações de stored procedures utilizarem uma linguagem proprietária associada a um SGBD específico. Atualmente, as stored procedures não são portáveis entre os SGBDs. Isto significa que se mudarmos o SGBD temos que reescrever toda a aplicação. Significa também que, se possuímos bases de dados heterogêneas, temos que escrever procedimentos customizados para cada SGBD.
Outro aspecto a ser considerado é que o uso de stored procedure para implementar a lógica do negócio acarreta a perda de escalabilidade, um dos principais benefícios da computação cliente/servidor. Isto ocorre porque cada novo cliente usará o servidor para executar sua aplicação. Portanto, as stored procedures aumentam a utilidade e a escala dos modelos two-tiered através da melhoria de performance, mas, em compensação, grandes quantidades de código procedural rodando no servidor causam, em última análise, uma redução no número de usuários que o sistema é capaz de comportar.
A arquitetura three-tiered propõe-se a solucionar os problemas apresentados pela computação cliente/servidor no modelo two-tiered. Nessa arquitetura, o cliente fica dedicado à lógica e aos serviços de apresentação, e tem uma API para chamar a aplicação que reside em uma camada intermediária. O servidor de banco de dados fica dedicado aos serviços de dados e de arquivos, que podem ser otimizados sem o risco de usar stored procedures. A camada intermediária é um servidor de aplicação no qual executamos a lógica do negócio e solicitamos serviços de dados, através da lógica de dados. O servidor de aplicação pode controlar transações e garantir integridade em bancos de dados distribuídos através do gerenciamento de two-phase commit heterogêneo.
Os limites entre lógica de apresentação, lógica do negócio e lógica dos dados são confusos. Por essa razão, a lógica do negócio pode aparecer em todas as três camadas. Você deveria determinar o local de uma função específica usando critérios como facilidade de desenvolvimento e teste, facilidade de administração, escalabilidade dos servidores e performance, incluindo carga da rede e de processamento. Estes critérios freqüentemente serão conflitantes entre si.
Outro benefício das arquiteturas three-tiered é que o desenvolvimento de boas interfaces requer habilidade e treinamento. Nem todo profissional que programa bem a lógica do negócio é capaz de escrever um bom código de apresentação.
O projeto através do qual a Celepar está internalizando a tecnologia cliente/servidor está sendo desenvolvido segundo o modelo de lógica distribuída, sendo que a maior parte da lógica do negócio reside no servidor, e é acionada pelas estações cliente através de RPC (Remote Procedure Call).
O sistema gerenciador de banco de dados usado nesse projeto inicialmente é o Adabas, e os procedimentos remotos estão sendo codificados em Natural. A grande vantagem dessa arquitetura é que a camada cliente é totalmente independente da camada residente no servidor, ou seja, quando a Celepar migrar a base de dados para um SGBD relacional a camada de software residente nas estações cliente não sofrerá alteração. O único trabalho será converter os procedimentos escritos em Natural para stored procedures, mantendo seus nomes e parâmetros.
A Celepar está internalizando a tecnologia cliente/servidor através do desenvolvimento e implantação de uma aplicação pioneira para o DETRAN. Devido a este trabalho, freqüentemente nos solicitam informações e esclarecimentos sobre essa tecnologia. Acreditamos que a maioria dos desenvolvedores de sistemas ainda não domina os conceitos referentes a essa área, bem como métodos para a implantação dessa tecnologia. Sendo assim, produzimos este artigo com o objetivo de contribuir para o crescimento de todos os interessados em arquitetura cliente/servidor, que ainda não tiveram a oportunidade de se aprofundar no assunto.
Primeiramente, vamos apresentar um conceito: numa arquitetura cliente/ servidor o processamento é dividido entre duas entidades, um cliente e um servidor, sendo que essas duas entidades estão fisicamente conectadas através de uma rede. Esse conceito é trivial, mas já permite levantar algumas questões, tais como: O que deve ser processado pelo cliente? O que deve ser processado pelo servidor? Quais produtos devem ser instalados na rede para permitir a interoperabilidade entre o cliente e o servidor? As respostas para essas perguntas não são tão simples, cada caso é um caso.
A tabela 1 mostra o progresso da computação, desde a arquitetura tradicional de mainframes até a arquitetura cliente/servidor.
Mainframe | Desktop | Host | |
Serviços de Apresentação | Lógica de Apresentação | ||
Lógica do Negócio | |||
Lógica de Dados | |||
Serviços de Dados | |||
Serviços de Arquivos | |||
File-Server | Desktop | Host | |
Serviços de Apresentação | Serviços de Arquivos | ||
Lógica de Apresentação | |||
Lógica do Negócio | |||
Lógica de Dados | |||
Serviços de Dados | |||
SGBD Remoto | Desktop | Host | |
Serviços de Apresentação | Serviços de Dados | ||
Lógica de Apresentação | Serviços de Arquivos | ||
Lógica do Negócio | |||
Lógica de Dados | |||
Apresentação Remota | Desktop | Host | |
Serviços de Apresentação | Lógica do Negócio | ||
Lógica de Apresentação | Lógica de Dados | ||
Serviços de Dados | |||
Serviços de Arquivos | |||
Lógica Distribuída | Desktop | Host | |
Serviços de Apresentação | Lógica do Negócio | ||
Lógica de Apresentação | Lógica de Dados | ||
Lógica do Negócio | Serviços de Dados | ||
Lógica de Dados | Serviços de Arquivos | ||
Three-Tiered | Desktop | Servidor de Aplicação | Servidor de Banco de Dados |
Serviços de Apresentação | Lógica do Negócio | Servidor de Dados | |
Lógica de Apresentação | Lógica de Dados | Serviços de Arquivos |
Tabela 1: O progresso da computação desde mainframes até cliente/servidor.
Para compreender melhor os limites entre arquitetura de mainframe, arquitetura file-server e a variedade de arquiteturas cliente/servidor, vamos nos basear em um artigo produzido por Herb Edelstein, fundador da Euclid Associates, uma empresa de consultoria em banco de dados sediada em Potomac, Maryland. Segundo Edelstein, podemos dividir uma aplicação em seis componentes:
Serviços de apresentação: são fornecidos por um dispositivo que aceita as entradas do usuário e mostra tudo o que a lógica de apresentação mandar.
Lógica de apresentação: controla a interação entre o usuário e o computador, ou seja, especifica o que acontece quando o usuário seleciona uma opção de menu, quando aciona um botão, ou quando escolhe um item de uma list box.
Lógica do negócio, ou lógica da aplicação: é um conjunto de decisões, cálculos e operações que a aplicação deve executar, tal como o cálculo do salário de um empregado, a análise da melhor forma de aplicar um recurso financeiro, ou os procedimentos necessários para transferir fundos de uma conta bancária para outra.
Lógica de dados: é a especificação das operações que devem ser executadas no banco de dados para cumprir os requisitos da lógica do negócio. Para um banco de dados relacionaI, essa especificação nada mais é do que um conjunto de declarações SQL, tais como SELECT, UPDATE e INSERT.
Serviços de dados: são as ações que o sistema gerenciador de banco de dados executa para que se cumpra a lógica dos dados. Isto inclui a definição de dados, a manipulação de dados, commit e rollback de transação, etc.
Serviços de arquivos: normalmente são funções do sistema operacional de leitura e gravação de dados.
Agora que você já conhece os componentes de uma aplicação responda: onde se localiza a garantia de integridade referencial? Na lógica de dados, no serviço de dados, ou na lógica do negócio? Dependendo da sua interpretação, qualquer uma dessas categorias poderia ser apropriada. Na realidade, a questão mais importante é: a quais dispositivos devemos atribuir as partes de uma aplicação? Para tentar responder essa questão, vamos analisar a tabela 1 comparando as qualidades e as deficiências de cada arquitetura.
Observe que nos ambientes de mainframe o terminal fornece os serviços de apresentação, enquanto o host fornece o restante das funções. Isto causa basicamente dois problemas sérios. Primeiro, a interface com o usuário fica limitada a um terminal, ou seja, é difícil, se não impossível, fornecer uma interface GUI (Graphical User Interface) eficiente quando todos os processamentos residem na máquina central. Segundo, cada aplicação ou usuário adicional causa uma carga substancial ao mainframe. Isto causa uma perda de escalabilidade. A própria carga da rede é maior do que a necessária, uma vez que o host, além de enviar os dados para o terminal , tem que transmitir instruções para a formatação da tela.
A arquitetura file-server coloca os serviços de arquivos no servidor e todas as demais funções ficam alocadas na máquina cliente. O servidor de arquivos apenas recupera os arquivos necessários e os transmite para a estação cliente. Assim sendo, podemos afirmar que a arquitetura file-server resolve os problemas da arquitetura baseada em mainframe porém cria novas dificuldades. Resolve os problemas na medida em que permite a criação de interface gráfica eficiente e acrescenta pequena carga de trabalho à CPU toda vez que se aumenta o número de usuários ou de aplicações na rede. Em compensação, cria os seguintes inconvenientes: a demanda na estação cliente torna-se muito alta e aumenta consideravelmente o tráfego na rede.
A arquitetura cliente/servidor foi projetada para resolver esses problemas, separando os componentes de uma aplicação e colocando cada um deles no local onde é mais eficiente. Uma vez que existem diversas formas de distribuir esses componentes, é importante compreender as diferentes arquiteturas cliente/servidor e para que tipo de aplicações cada uma é adequada.
A maioria das configurações cliente/servidor hoje utiliza um modelo two-tiered (duas-camadas), na qual um cliente solicita serviços a um servidor. É possível que um servidor funcione como cliente de outro servidor formando uma espécie de arquitetura cliente/servidor hierárquica. Neste caso, trata-se ainda de uma abordagem two-tiered, porém, encadeada.
No mínimo, uma arquitetura cliente/servidor pressupõe que os serviços de apresentação e a lógica de apresentação residam no cliente. Isto resolve os inconvenientes de uma interface tipo terminal fornecendo um gerenciador de interface gráfica local. Mas, para onde vão os demais componentes da aplicação?
A primeira possibilidade é colocar os serviços de dados e de arquivos no servidor, e a lógica do negócio e a lógica de dados no cliente. Esta abordagem pode ser chamada de "SGBD remoto". A maioria das definições superficiais de computação cliente/servidor emprega este modelo: a aplicação está no cliente e o SGBD no servidor. Uma vez que este modelo coloca a menor demanda no servidor ele é o que prove a melhor escalabilidade. No entanto, para aplicações complexas que envolvem uma grande interação com banco de dados, ele pode ocasionar sobrecarga na estação cliente e na rede. Outra desvantagem desse modelo diz respeito ao gerenciamento da aplicação, pois uma cópia completa do código executável reside em cada estação cliente. Quando você, muda o código, você tem que substituí-lo em todas as estações.
Você pode reduzir a carga do cliente e da rede transferindo parte da lógica do negócio para o servidor. Este modelo cliente/servidor é chamado de split-logic, que em português significa aproximadamente lógica distribuída.
O próximo passo para minimizar o impacto da aplicação sobre as estações cliente é transferir toda a lógica do negócio para o servidor, deixando apenas a lógica e os serviços de apresentação no cliente. Este modelo é chamado de apresentação remota.
O mecanismo mais comumente utilizado para implementar a lógica do negócio nos servidores são as stored procedures. Uma vez que elas são compiladas, o uso sensato de stored procedures pode melhorar a performance e reduzir a carga do servidor, se comparado ao uso de SQL dinâmico (comando SQL não compilado emitido pela estação cliente). Para compreender porque isto ocorre temos que entender os dois passos do processo de compilação. Primeiro a SQL é processada, o que significa checar nomes de tabelas e colunas, direitos de acesso do usuário que está acionando o procedimento e otimizar a SQL. Otimização é o processo através do qual o SGBD determina o melhor caminho de acesso aos dados. O segundo passo é compilar a parte procedural do código. Observe que se não utilizarmos stored procedures todas essas tarefas serão executadas em tempo real, durante o processamento da transação. Outro aspecto importante quanto à performance é que uma stored procedure pode ser armazenada em um cache de procedimentos, reduzindo assim o número de I/Os da aplicação.
As arquiteturas two-tiered (SGBD remoto, lógica distribuída e apresentação remota) também apresentam alguns problemas, se considerarmos aplicações complexas, com muitos clientes, lógica intrincada, bases de dados heterogêneas e entradas de dados heterogêneas para as bases de dados.
O primeiro problema é definir onde colocar a lógica do negócio. Colocar no cliente implica muito esforço no momento de uma alteração ou de um upgrade, pois o software terá que ser alterado, instalado e testado em todas as estações.
O segundo problema diz respeito ao uso de stored procedures para implementar lógica complexa. Infelizmente, as linguagens procedurais utilizadas nas stored procedures não têm capacidade equivalente às linguagens convencionais. Além disso, possuem um ambiente de desenvolvimento precário no que diz respeito a testes, depuração, controle de versão e gerenciamento de bibliotecas. Pior que isso é o fato de todas as implementações de stored procedures utilizarem uma linguagem proprietária associada a um SGBD específico. Atualmente, as stored procedures não são portáveis entre os SGBDs. Isto significa que se mudarmos o SGBD temos que reescrever toda a aplicação. Significa também que, se possuímos bases de dados heterogêneas, temos que escrever procedimentos customizados para cada SGBD.
Outro aspecto a ser considerado é que o uso de stored procedure para implementar a lógica do negócio acarreta a perda de escalabilidade, um dos principais benefícios da computação cliente/servidor. Isto ocorre porque cada novo cliente usará o servidor para executar sua aplicação. Portanto, as stored procedures aumentam a utilidade e a escala dos modelos two-tiered através da melhoria de performance, mas, em compensação, grandes quantidades de código procedural rodando no servidor causam, em última análise, uma redução no número de usuários que o sistema é capaz de comportar.
A arquitetura three-tiered propõe-se a solucionar os problemas apresentados pela computação cliente/servidor no modelo two-tiered. Nessa arquitetura, o cliente fica dedicado à lógica e aos serviços de apresentação, e tem uma API para chamar a aplicação que reside em uma camada intermediária. O servidor de banco de dados fica dedicado aos serviços de dados e de arquivos, que podem ser otimizados sem o risco de usar stored procedures. A camada intermediária é um servidor de aplicação no qual executamos a lógica do negócio e solicitamos serviços de dados, através da lógica de dados. O servidor de aplicação pode controlar transações e garantir integridade em bancos de dados distribuídos através do gerenciamento de two-phase commit heterogêneo.
Os limites entre lógica de apresentação, lógica do negócio e lógica dos dados são confusos. Por essa razão, a lógica do negócio pode aparecer em todas as três camadas. Você deveria determinar o local de uma função específica usando critérios como facilidade de desenvolvimento e teste, facilidade de administração, escalabilidade dos servidores e performance, incluindo carga da rede e de processamento. Estes critérios freqüentemente serão conflitantes entre si.
Outro benefício das arquiteturas three-tiered é que o desenvolvimento de boas interfaces requer habilidade e treinamento. Nem todo profissional que programa bem a lógica do negócio é capaz de escrever um bom código de apresentação.
O projeto através do qual a Celepar está internalizando a tecnologia cliente/servidor está sendo desenvolvido segundo o modelo de lógica distribuída, sendo que a maior parte da lógica do negócio reside no servidor, e é acionada pelas estações cliente através de RPC (Remote Procedure Call).
O sistema gerenciador de banco de dados usado nesse projeto inicialmente é o Adabas, e os procedimentos remotos estão sendo codificados em Natural. A grande vantagem dessa arquitetura é que a camada cliente é totalmente independente da camada residente no servidor, ou seja, quando a Celepar migrar a base de dados para um SGBD relacional a camada de software residente nas estações cliente não sofrerá alteração. O único trabalho será converter os procedimentos escritos em Natural para stored procedures, mantendo seus nomes e parâmetros.