hessian序列化協(xié)議+memcached的緩存存取
大名鼎鼎的memcached恐怕沒人不知道吧!hessian是一種遠(yuǎn)程調(diào)用的機(jī)制,類似與web service,不過它是使用自己的序列化協(xié)議.
那么,為什么要把hessian的序列化協(xié)議和memcached結(jié)合起來實(shí)現(xiàn)緩存的讀取呢?
有過使用memcached的經(jīng)驗(yàn)的人會(huì)了解到,php+memcached的性能是最好的,java+memcached的性能比較差,其主要原因就是在于java本身的序列化機(jī)制很慢.
我做了個(gè)簡單的測試,一個(gè)UserData類,有一個(gè)字符串屬性,一個(gè)日期屬性,一個(gè)double屬性,分別用java,hessian來序列化一百萬次,結(jié)果讓人吃驚,不止是hessian序列化的速度要比java的快上一倍,而且hessian序列化后的字節(jié)數(shù)也要比java的少一倍.因?yàn)槲以跍y試的時(shí)候只是做了序列化這部分的工作,并沒有把序列化后的結(jié)果放到網(wǎng)絡(luò)上傳輸,所以,實(shí)際中的性能hessian應(yīng)該會(huì)更好!
既然hessian的序列化協(xié)議要比java本身的好,而memcached客戶端的性能又在很大程度上依賴與對(duì)象的序列化.所以,我就決定把我的cache實(shí)現(xiàn)中序列化這部分的工作改成用hessian來實(shí)現(xiàn)了.
我用的memcached客戶端是用的danga.MemCached包,主要是改動(dòng)了MemCachedClient的get方法及set方法,在set方法中改為調(diào)用hessian的序列化:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//修改以前的序列化代碼:
//(new ObjectOutputStream( bos )).writeObject( value );
//修改后的序列化代碼:
serializeByHessian(bos, value);
val = bos.toByteArray();
serializeByHessian方法如下:
AbstractHessianOutput out = new Hessian2Output(os);;
SerializerFactory serializerFactory = getSerializerFactory();
out.setSerializerFactory(serializerFactory);
out.startReply();
out.writeObject(object);
out.completeReply();
out.flush();
}
在get方法中主要是修改了這個(gè)方法調(diào)用的類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();//>=2
int minor = in.read();//0
Object value = in.readObject();
is.close();
return value;
}
因?yàn)槲业目蚣苁腔趏sgi的,所以我重載了Hessian2Input,把classloader作為參數(shù)傳進(jìn)去,否則hessian在反序列化的時(shí)候會(huì)找不到類.如果你沒有用osgi框架的話, ClHessian2Input in = new ClHessian2Input(is, this.mLoader);這行代碼就可以直接用: Hessian2Input in = new Hessian2Input(is);
這樣修改就基本完成了.
我把memcached client的序列化協(xié)議改為hessian也有另外一個(gè)系統(tǒng)架構(gòu)的原因,那就是因?yàn)槲业姆?wù)層邏輯都是用java+spring+osgi的方式實(shí)現(xiàn),而web層則是用php實(shí)現(xiàn),兩者之間通訊已經(jīng)是采用hessian的遠(yuǎn)程調(diào)用.所以,部分緩存數(shù)據(jù)在服務(wù)層通過java設(shè)置到memcached服務(wù)器中,在php中一樣可以用memcached php client讀取出來.(php的memcached client我用的是memcached-client.php,而不是php擴(kuò)展,所以一樣可以修改memcached-client.php的序列化機(jī)制)
posted on 2008-06-18 10:04 pony 閱讀(7882) 評(píng)論(11) 編輯 收藏 所屬分類: Java