hessian序列化协议+memcached的缓存存取

dapeng00 2015-04-09

大名鼎鼎的memcached恐怕没人不知道吧!hessian是一种远程调用的机制 ,类似于web service,不过它是使用自己的序列化协议。 
  那么,为什么要把hessian的序列化协议和memcached结合起来实现缓存 的读取呢? 
  有过使用memcached的经验的人会了解到,php+memcached的性能 是最好的,java+memcached的性能比较差,其主要原因就是在于java本身的序列化机制很慢。 
  我做了个简单的测试 , 一个UserData类,有一个字符串属性,一个日期属性,一个double属性,分别用java,hessian来序列化一百万次,结果让人吃惊,不止 是hessian序列化的速度要比java的快上一倍,而且hessian序列化后的字节数也要比java的少一倍。因为我在测试的时候只是做了序列化这 部分的工作,并没有把序列化后的结果放到网络上传 输,所以,实际中的性能hessian应该会更好! 
  既然hessian的序列化协议要比java本身的好,而memcached客户端的性能又在很大程度上依赖与对象的序列化。所以,我就决定把我的cache实现中序列化这部分的工作改成用hessian来实现了。 
  我用的memcached客户端是用的danga。MemCached包,主要是改动了MemCachedClient的get方法及set方法,在set方法中改为调用hessian的序列化: 
  ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
  //修改以前的序列化代码: 
  //(new ObjectOutputStream( bos )).writeObject( value ); 
  //修改后的序列化代码: 




serializeByHessian(bos, value);
  val = bos.toByteArray();
  serializeByHessian方法如下:
  protected void serializeByHessian(OutputStream os, Object object) throws IOException {
  AbstractHessianOutput out = new Hessian2Output(os);;
  SerializerFactory serializerFactory = getSerializerFactory();
  out.setSerializerFactory(serializerFactory);
  out.startReply();
  out.writeObject(object);
  out.completeReply();
  out.flush();
  } 
  在get方法中主要是修改了这个方法调用的类ContextObjectInputStream的readObject方法: 
  在ContextObjectInputStream中覆盖了readObjectOverride方法: 




 protected Object readObjectOverride() throws IOException, ClassNotFoundException {
  ByteArrayInputStream is = new ByteArrayInputStream(bytes);
  ClHessian2Input in = new ClHessian2Input(is, this.mLoader);
  in.setSerializerFactory(getSerializerFactory());
  int code = in.read();//"r"
  int major = in.read();//%26gt;=2
  int minor = in.read();//0
  Object value = in.readObject();
  is.close();
  return value;
  } 
  因为我的框架 是 基于osgi的,所以我重载了Hessian2Input,把classloader作为参数传进去,否则hessian在反序列化的时候会找不到类。如 果你没有用osgi框架的话, ClHessian2Input in = new ClHessian2Input(is, this。mLoader);这行代码就可以直接用: Hessian2Input in = new Hessian2Input(is); 
  这样修改就基本完成了。 
  我把memcached client的序列化协议改为hessian也有另外一个系统架构 的 原因,那就是因为我的服务层逻辑都是用java+spring+osgi的方式实现,而web层则是用php实现,两者之间通讯已经是采用hessian 的远程调用。所以,部分缓存数据在服务层通过java设置到memcached服务器中,在php中一样可以用memcached php client读取出来。

相关推荐

Iamlonely / 0评论 2013-01-23