开源分布式网络应用开发利器EJOE详解(基本应用)

 

 
EJOE
一、             概论
EJOE是一个轻量级的Java 客户端/服务器框架,其创建目的就是通过可插拔的序列化机制来实现对象传输。它提供了一种高效、简单、清晰的对象请求代理。并且,其服务器端和客户端组件都很容易和你的C/S应用集成。它是一个基于java.nio包的高度可扩展的“请求-处理-反馈”模式。
 
EJOE主要提供以下三种功能:
1、一个多线程、可扩展、高效的网络IO服务组件和一个相应的客户端组件。
2、自动对客户端发送的请求对象和服务器端商业逻辑反馈的对象进行序列化。
3、可以用一种简单、清晰、惟一的接口来创建网络应用程序或者很方便地集成一个对象请求代理到你的应用程序中。
 
除了以上功能外,它还支持:
1、可选的远程类加载功能可以避免多余的类路径入口。
2、多种线程机制。
3、可调整的线程池大小。
4、可选的多种压缩机制。
5、在阻塞和非阻塞方式之间的自由切换。
6、在防火墙环境下对HTTP协议的有限支持。
7、远程发射机制
8、多种可选的序列化策略
9、CRISPY支持
10、             WSIF支持
 
下图就是EJOE在集成应用中的大体框架图:
二、             前提预备
在开始以下的内容之前,我们假设 你已在 http://sourceforge.net/projects/ejoe/ 上下载了EJOE的最新版本,并且已经将
  • ejoe_xx.jar,
  • xstream-1.x.jar und
  • xpp3_min-1.1.3.x.x.jar
这三个Jar包包含到你的系统的classpath中了。
 
三、             服务器端组件
EJServer是一个完整的基于TCP/IP的网络服务,它可以被用来创建一个新的C/S应用或者被已存在的应用所集成。目前,它能提供以下支持:
l         Java 非阻塞IO(java.nio)
l         Java 流导向IO(java.io)
l         持久和非持久连接
l         可选的数据压缩
l         弹性的多线程机制
l         Usage of all processor cores on multiprocessor systems
l         HTTP协议(部分)
l         partial reading/writing of data without process blocking
l         自动监控I/O操作,并恢复/重启“濒死”进程。
 
创建一个EJServer可以有以下方法:
l              EJServer() 
          使用默认的“ejserver.properties”配置文件
l              EJServer(Properties properties)
         基于其它的配置文件(或手工构建Properties)
l              EJServer(String pathToConfigFile)
基于一个已知的配置文件的路径来构建服务
l              EJServer(ServerHandler handler)
通过已经构造好的ServerHandler来构建服务
l              EJServer(ServerHandler handler,int port)
在上面的基础上,再指定监听的端口(如果不指定,其默认端口是 12577)
l              EJServer(ServerHandler handler,String bindAddr)
指定地址
l              EJServer(ServerHandler handler,String bindAddr ,int port)
              同时指定地址、端口
 
Ø        什么是ServerHandler
一个ServerHandler主要用来代理客户端的请求,在外部应用程序对这些请求做进一步的请求之前。它是EJOE和在其上发布远程服务的应用程序之间的接口。
目前在EJOE中,已支持的ServerHandler有以下三种:
1、RemotingHandler:通过放射机制来处理客户端的请求。
2、Custom ServerHandler:必须实现de.netseeker.ejoe.handler.ServerHandler接口
3、de.netseeker.ejoe.handler.ClassHandler :一个特殊的,内置使用的ServerHandler,被EJOE的RemoteClassloader所使用。
 
在将EJOE集成倒放我们的应用环境中,将集中面对一个问题:是使用RemotingHandlers,还是自己来实现Custom ServerHandler接口?
       下面,我们分别介绍这两种机制。
RemotingHandler
EJOE目前已经包含了适用的remotingHandlers,它们的使用使得自定义ServerHandlers变得多余了。老实说,并不推荐自己去定义ServerHandlers。
       当在服务器端使用RemotingHandler,客户端必须使用特定的“RemotingRequest”容器来压缩请求,以下给出一段示例代码:
import de.netseeker.ejoe.EJClient;
import de.netseeker.ejoe.handler.RemotingRequest;
...
{
       EJClient ejClient = new EJClient( "192.168.1.21", 80 );
       List result = null;
       try
       {
              RemotingRequest request = new RemotingRequest( "com.who.AddressManagement",             
                     "listAddressesByName", new Object[]{ "Mustermann" } );
              result = (List)ejClient.execute(request );
       }
       catch(RemoteException re)
       {
              //EJServer did return an Error
       }
       catch(IOException e)
       {
              //connection or serialization issues maybe?
       }
       ...
}
随之而来的是安全问题:理论上来说,RemotingHandler是一件非常危险的事情,想想看,客户端可以通过RemotingRequest来接触到所有可能的服务器端方法。 EJOE 默认情况下拒绝所有的远程放射调用请求,并通过一个注册文件来登记那些允许被执行的类。
       EJOE 在类路径上寻找“ejoe-reflectionconf.properties ”这个文件,如果其存在,则在其中列表登记的所有类和包都将被允许远程反射调用。如果其不存在,EJOE 将从"META-INF/ejoe-reflection-conf.properties"中加载一个非常受限的配置,其文件如下:
#######################################################################
# This is the default configuration for remote reflection in EJOE.
# EJOE handles received reflection requests by clients VERY restrictive:
# Only packages/classes which are listed in this file
# can be used for remote reflection.
# To overwrite the reflection settings, provide a customized
# ejoe-reflection-conf.properties on the classpath.
##########################################################################
de.netseeker.ejoe.test.*
 
 
可以用通配符“*”来表示所有的子包及其下的所有类都允许被执行,如:
        package.path.*
     也可以通过指定明确的类路径来明确限制要执行的类:
        package.path.MyClass
 
Custom ServerHandler
如果反射太慢,不安全,或仅仅只是不适当,那么一个自定义的ServerHandler则就成为合适的解决方案了。
在EJOE中使用自定义的ServerHandler只有两个要求:
1、ServerHandlers必须实现 de.netseeker.ejoe.handler.ServerHandler 接口
2、Serverhandlers必须是线程安全的
EJOE 以单例(singletons )的形式来使用ServerHandlers 。也就是说,在 EJOE 中只存在一个 ServerHandler 的实例。一个ServerHandlers将不能使用synchronization(特别是在方法范围内),因为这将严重影响EJOE的多线程性。
以下是 EJOE ServerHandler 的接口描述:
package de.netseeker.ejoe.handler;
/**
* Simple interface defining the entry point for all server handlers.
* Server handlers are the working horses which the caller must implement.
* Server handlers take the transported input objects send by the client
* application and return none, one or more return values.
*
* @author netseeker aka Michael Manske
* @since 0.3.0
*/
public interface ServerHandler
{
          /**
          * Handles a client request
          *
          * @param obj The input object transported by EJOE
          * @return null or a valid return value. If you want return custom datatypes,
          * eg. Your own beans and do not want (or not be able) to deploy the classes of
          * these datatypes on the client, you can turn on EJOEs remote classloading feature.
          */
          public Object handle( Object obj ) throws Exception;
}
 
 
线程池
EJServer 使用两种不同的线程池来管理服务端任务:
1、 一个线程池用来容纳读取和处理客户端请求。默认是 4
2、 另一个线程池用来分发服务器端的反馈。默认是 2 个。
以上的比例应该说是一个比较合适的比例。但是如果现实要求我们调整怎么办能,以下给出了一段实例代码:
import de.netseeker.ejoe.EJServer;
...
{
        EJServer server = new EJServer( ... ); 
        //expected server load?
        //available hardware resources? 
        //how many read/process-threads are required? 
        server.setMaxReadProcessors( number of read/process-threads );
        //how many write-threads are required? 
         server.setMaxWriteProcessors( number of write-threads );   
        //start the server
        server.start();
        ...
}
 
       到处为止,服务器端组件已经大体介绍完毕,接下来就着重介绍客户端组件了。
四、            客户端组件
n        EJClient 是一个基于 TCP/IP 的网络客户端,是与 EJServer 进行通信的专有工具。其提供如下功能:
n        系列化和反系列化请求(Requests
n        HTTP/1.0 协议封装请求(Requests
n        可选的压缩模式( 必须与服务器端一致)
n        动态远程类加载
n        持久化和非持久化连接( 必须与服务器端一致)
n        可调整的连接超时设置
n        系列化处理的多种策略
另外, EJClient 本身也可以被系列化并存储到 HTTPSession 容器中
可以通过以下方法来创建一个 EJClient 的实例,不在一一描述,可以参考 EJServer 的创建:
        EJClient()—利用默认的“ejoe.properties”配置文件。
        EJClient(Properties properties)
        EJClient(String pathToConfigFile)
        EJClient(String host, int port)
        EJClient(String host, int port, SerializeAdapter adapter)
 
       EJClient(String host, int port, SerializeAdapter adapter, boolean isPersistent, boolean isHttp, boolean useCompression)------
其监听端口是“host:port”,使用指定的系列化适配器,
如果isPersistent=true,那么EJClient将使用持久连接到相应的EJServer.
如果isHttp=true,那么EJClient将使用HTTP请求协议来封装requests
如果useCompression=true,EJClient将使用GZIP格式来压缩请求的数据
 
下面是一个请求的实例:
import de.netseeker.ejoe.EJClient; 
...
{ 
        Integer myIntegerRequest = new Integer(1); 
        String myStringRequest = "Hallo EJServer";
        Map myMapRequest = new HashMap();
        SomeBean myBeanRequest = new SomeBean(); 
        ... 
        EClient client = new EJClient(...);
        try 
        { 
                 client.execute( myIntegerRequest); 
                 client.execute( myStringRequest ); 
                 client.execute( myMapRequest ); 
                 client.execute( myBeanRequest );
                 ...
        } 
        catch(RemoteException re) 
        { 
                 //EJServer did return an Error
        }
        catch(IOException e) 
        { 
                 //connection or serialization issues maybe? 
        } 
        ...
}
 
系列化适配器-为什么系列化这么重要
    对象,即使是最简单的对象也是一个很复杂的构造。为了在媒介上传递对象,必须将对象转换为可传输的格式。
    Java already offers two mechanisms for serialization: object serialization and Long Term Persistence for Java Beans. Both make strict demands against the objects which should be transformed. To fulfill these demands is everything but not easy in most cases. Exemplarily it may be stated here that even many classes of the java library do not fulfill the requirements.
Furthermore nearly completely any support for modern forms of data modelling and data binding is missing to the two mechanisms mentioned.
Among other things one goal behind EJOE is to offer as much as possible kinds of serialization mechanisms out of the box. Developers should not have to modify their POJOs, beans or whatever they are using just to be able to transmit their business objects over network!
Here the so-called SerializeAdapter comes into the play:
They are the interface between EJOE and many mechanisms and frameworks for serialization.
如果适配器不被指定,EJClient默认使用缺省的适配器:
Ø       XstreamAdapter,如果Xstream的jar包存在于类路径上
Ø       其次采用ObjectStreamAdapter
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值