http抓包分析工具

web开发有时需要用到抓包工具分析请求与返回,通常,firefox的firebug已经够用。但是对于跨页面的请求则不行,如unload事件中的请求。这时可使用httpfox这个插件来监视,它的菜单在tools/web developer中,我开始还找半天。

其余的如果不是监视到本机服务器的请求,可以使用wireshark,但是我发现有时貌似不准,Fiddler更不行了。

它们两个都不好监视对本机服务器的http请求,像rawcap这样的更是不靠谱,输入到文件,用notepad++打开全是乱码。

Continue reading http抓包分析工具

unload事件,刷新,顺序,不靠谱

window的unload事件,用起来不靠谱,为什么呢?

我做个测试来说明,在页面unload事件中做一个同步ajax请求,然后刷新页面,我来比较刷新时unload事件和get新页面请求发生的时间顺序,结果如下:

FF:
16:13:48 445766772 get
16:13:48 445766787 unload

unload在get之后

 

Chrome:
16:36:13 447111240 get
16:36:13 447111274 unload

unload在get之后

 

IE:
16:33:08 446926865 get
16:33:08 446926842 unload

unload在get之前

 

Safari:
16:38:08 447226350 get
16:38:08 447226386 unload

unload在get之后

 

Opera:
16:39:39 447317584 get

没有unload事件

 

结果是FF,Safari,Chrome竟然unload请求在get请求之后。就只IE符合正常逻辑unload完了再get。Opera索性不支持unload事件。

通过HTTP抓包分析FF是先获得新页面的html然后执行上页面的unload事件,然后开始请求新页面的资源。

如果某些处理依赖unload事件而又讲究顺序的话,那就可能对我们的程序造成问题,所以,unload事件还是尽量不用为好,不靠谱啊!

 

beforeubload也存在这个情况。

Continue reading unload事件,刷新,顺序,不靠谱

【转】Google OAUTH + OpenID解决方案

同系列文章,转载自 Google OAUTH + OpenID解决方案, 蓝色字是我加的注解或是着重提示。

 

       在前面已经介绍过OAuth与OpenID,这两种服务,Google都实现了。我们可以通过Google OAuth服务为Google 用户的资源进行授权,如用户通过第三方软件调用Google Open API操作用户的资源时,就需要用户对第三方软件授权;通过Google OpenID服务可以打通Google与其他支持OpenID服务网站之间的用户体系。现在假如有另外一个网站,也想开放自己的Open API服务,但是又不想实现OAuth服务(毕竟实现OAUTH服务还是需要一些成本的),那该怎么办?它可不可以使用Google提供的OAuth服务,授权认证交给Google来处理?可以!但是OAuth授权也是基于用户登录来实现的,Google OAuth用户体系只是Google的用户体系,那又怎么办了?OpenID!对,将网站的用户体系与Google用户体系打通,并且使用Google OAuth服务来实现授权,即Google提出的OpenID + OAUTH的解决方案。

一、 OAUTH与OpenID

前面两篇文章对OAUTH与OpenID均做过介绍,且Google均提供了这两种服务,在此我们先简要的回顾这两种服务,具体介绍请参见相关文章。

OAUTH是一种开放的,基于用户登录的授权认证方式。如当用户使用第三方软件调用Google Open API去操作自己的Google服务资源时,用户就要先对该软件授权。授权过程中,第三方软件会引导用户登录Google,进行用户鉴权,用户通过Google身份鉴权后才能对第三方软件授权。显然,Google OAUTH只能对Google用户进行鉴权,其他用户体系的用户不能直接鉴权。

OpenID是一种开放的,去用户中心的,用于打通各网站之间的用户体系的服务。在支持OpenID的网站间,你可以使用任何一个网站的帐号或者Open ID去登录任何一个网站。OpenID提供了类似单点登录的用户体验,并且用户无需在各个网站上注册就可以使用该网站的资源,将用户从繁重的帐号注册与管理工作中解脱出来。当用户使用OpenID登录没注册的网站过程中,网站会引导用户登录OP(用户OpenID注册的网站),请求OP对用户身份鉴权,用户通过OP鉴权,网站才会容许用户登录。

若将OpenID与Google OAUTH结合,OpenID将第三方网站的用户体系与Google用户体系打通后,第三方网站便可使用Google OAUTH服务,对自己的用户进行授权!交互示意图如下图所示:

二、 Google OAUTH + OpenID解决方案

Google提出了OpenID + OAUTH的解决方案,将两者揉合在一起,具体流程如下图所示:

1. Web应用请求用户登录;

2. 用户选择使用Google OpenID进行登录;

3. Web应用请求发现Google认证服务URL;

4. Google向Web应用返回XRDS信息,其中包含Google认证服务URL;

5. Web应用请求用户登录Google服务,通过请求用户授权;

6. Google引导用户登录;

7. 用户输入用户名密码进行登录,同时确认是否对第三方软件授权;

8. Google认证中心返回用户ID与授权的Request Token给Web应用;

9. 用户可以访问受保护的资源,同时可以继续第七部中Oauth认证余下的环节;

从上面的流程第五步可以看出,Google解决方案中,将OAUTH与OpenID的登录操作合并在一起、并且在登录的同时向Google发送Oauth请求,请求用户授权。这样一来,在第五步中,用户登录Google(OpenID中Google对用户鉴权),同时请求对用户授权(OAUTH中对用户授权,同时无需再次登陆,因为前面OpenID已经登录过了)。

三、Google OAUTH+OpenID Demo

Google提供了OAUTH + OpenID的DEMO,Demo演示地址如下:http://googlecodesamples.com/hybrid/

刚开始,用户既没OpenID登录也没OAUTH授权,如下图所示:

接着,点击上图中login按钮请求以Google提供的OpenID登录,如下图所示:

输入用户名与密码登录后,Google提醒您即将登陆到外部网站,外部网站申请对您的资源进行授权,您是否同意,如下图所示:

点击继续登录后,登录成功,并且返回授权的Token,如下图所示:

 

参见:

http://kazge.com/archives/765.html

http://kazge.com/archives/496.html

Continue reading 【转】Google OAUTH + OpenID解决方案

【转】OAUTH协议简介

好文,忍不住转载了,转自http://blog.csdn.net/hereweare2009/article/details/3968582 ,蓝色字是我加的注解或是着重提示。

 摘要:OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAUTH是安全的。同时,任何第三方都可以使用OAUTH认证服务,任何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间,因而OAUTH是简易的。目前互联网很多服务如Open API,很多大头公司如Google,Yahoo,Microsoft等都提供了OAUTH认证服务,这些都足以说明OAUTH标准逐渐成为开放资源授权的标准。

一、OAUTH产生的背景

    典型案例:如果一个用户拥有两项服务:一项服务是图片在线存储服务A,另一个是图片在线打印服务B。如下图所示。由于服务A与服务B是由两家不同的服务提供商提供的,所以用户在这两家服务提供商的网站上各自注册了两个用户,假设这两个用户名各不相同,密码也各不相同。当用户要使用服务B打印存储在服务A上的图片时,用户该如何处理?法一:用户可能先将待打印的图片从服务A上下载下来并上传到服务B上打印,这种方式安全但处理比较繁琐,效率低下;法二:用户将在服务A上注册的用户名与密码提供给服务B,服务B使用用户的帐号再去服务A处下载待打印的图片,这种方式效率是提高了,但是安全性大大降低了,服务B可以使用用户的用户名与密码去服务A上查看甚至篡改用户的资源。

    很多公司和个人都尝试解决这类问题,包括Google、Yahoo、Microsoft,这也促使OAUTH项目组的产生。OAuth是由Blaine Cook、Chris Messina、Larry Halff 及David Recordon共同发起的,目的在于为API访问授权提供一个开放的标准。OAuth规范的1.0版于2007年12月4日发布。通过官方网址:http://oauth.net可以阅读更多的相关信息。

二、OAUTH简介

    在官方网站的首页,可以看到下面这段简介:

    An open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.

    大概意思是说OAUTH是一种开放的协议,为桌面程序或者基于BS的web应用提供了一种简单的,标准的方式去访问需要用户授权的API服务。OAUTH类似于Flickr Auth、Google's AuthSub、Yahoo's BBAuth、 Facebook Auth等。OAUTH认证授权具有以下特点:

1. 简单:不管是OAUTH服务提供者还是应用开发者,都很容易于理解与使用;

2. 安全:没有涉及到用户密钥等信息,更安全更灵活;

3. 开放:任何服务提供商都可以实现OAUTH,任何软件开发商都可以使用OAUTH;

 三、OAUTH相关术语

    在弄清楚OAUTH流程之前,我们先了解下OAUTH的一些术语的定义:

  • OAUTH相关的三个URL
    • Request Token URL: 获取未授权的Request Token服务地址;
    • User Authorization URL: 获取用户授权的Request Token服务地址;
    • Access Token URL: 用授权的Request Token换取Access Token的服务地址;

  • OAUTH相关的参数定义:
    • oauth_consumer_key: 使用者的ID,OAUTH服务的直接使用者是开发者开发出来的应用。所以该参数值的获取一般是要去OAUTH服务提供商处注册一个应用,再获取该应用的oauth_consumer_key。如Yahoo该值的注册地址为:https://developer.yahoo.com/dashboard/
    • oauth_consumer_secret:oauth_consumer_key对应的密钥。
    • oauth_signature_method: 请求串的签名方法,应用每次向OAUTH三个服务地址发送请求时,必须对请求进行签名。签名的方法有:HMAC-SHA1、RSA-SHA1与PLAINTEXT等三种。
    • oauth_signature: 用上面的签名方法对请求的签名。
    • oauth_timestamp: 发起请求的时间戳,其值是距1970 00:00:00 GMT的秒数,必须是大于0的整数。本次请求的时间戳必须大于或者等于上次的时间戳。
    • oauth_nonce: 随机生成的字符串,用于防止请求的重放,防止外界的非法攻击。
    • oauth_version: OAUTH的版本号,可选,其值必须为1.0。

  OAUTH HTTP响应代码:

  • HTTP 400 Bad Request 请求错误
    • Unsupported parameter 参数错误
    • Unsupported signature method 签名方法错误
    • Missing required parameter 参数丢失
    • Duplicated OAuth Protocol Parameter 参数重复
  • HTTP 401 Unauthorized 未授权
    • Invalid Consumer Key 非法key
    • Invalid / expired Token 失效或者非法的token
    • Invalid signature 签名非法
    • Invalid / used nonce 非法的nonce

四、OAUTH认证授权流程

    在弄清楚了OAUTH的术语后,我们可以对OAUTH认证授权的流程进行初步认识。其实,简单的来说,OAUTH认证授权就三个步骤,三句话可以概括:

1. 获取未授权的Request Token

2. 获取用户授权的Request Token

3. 用授权的Request Token换取Access Token

    当应用拿到Access Token后,就可以有权访问用户授权的资源了。大家肯能看出来了,这三个步骤不就是对应OAUTH的三个URL服务地址嘛。一点没错,上面的三个步骤中,每个步骤分别请求一个URL,并且收到相关信息,并且拿到上步的相关信息去请求接下来的URL直到拿到Access Token。具体的步骤如下图所示:

 

具体每步执行信息如下:

A. 使用者(第三方软件)向OAUTH服务提供商请求未授权的Request Token。向Request Token URL发起请求,请求需要带上的参数见上图。

B. OAUTH服务提供商同意使用者的请求,并向其颁发未经用户授权的oauth_token与对应的oauth_token_secret,并返回给使用者。

C. 使用者向OAUTH服务提供商请求用户授权的Request Token。向User Authorization URL发起请求,请求带上上步拿到的未授权的token与其密钥。

D. OAUTH服务提供商将引导用户授权。该过程可能会提示用户,你想将哪些受保护的资源授权给该应用。此步可能会返回授权的Request Token也可能不返回。如Yahoo OAUTH就不会返回任何信息给使用者。

E. Request Token 授权后,使用者将向Access Token URL发起请求,将上步授权的Request Token换取成Access Token。请求的参数见上图,这个比第一步A多了一个参数就是Request Token。

F. OAUTH服务提供商同意使用者的请求,并向其颁发Access Token与对应的密钥,并返回给使用者。

G. 使用者以后就可以使用上步返回的Access Token访问用户授权的资源。

    从上面的步骤可以看出,用户始终没有将其用户名与密码等信息提供给使用者(第三方软件),从而更安全。用OAUTH实现背景一节中的典型案例:当服务B(打印服务)要访问用户的服务A(图片服务)时,通过OAUTH机制,服务B向服务A请求未经用户授权的Request Token后,服务A将引导用户在服务A的网站上登录,并询问用户是否将图片服务授权给服务B。用户同意后,服务B就可以访问用户在服务A上的图片服务。整个过程服务B没有触及到用户在服务A的帐号信息。如下图所示,图中的字母对应OAUTH流程中的字母:

 

五、OAUTH服务提供商

    OAUTH标准提出到现在不到两年,但取得了很大成功。不仅提供了各种语言的版本库,甚至Google,Yahoo,Microsoft等等互联网大头都实现了OAUTH协议。由于OAUTH的client包有很多,所以我们就没有必要在去自己写,避免重复造轮子,直接拿过来用就行了。我使用了这些库去访问Yahoo OAUTH服务,很不错哦!下面就贴出一些图片跟大家一起分享下!

    下图是OAUTH服务提供商引导用户登录(若用户开始没有登录)

  

    下图是提示用户将要授权给第三方应用,是否同意授权的页面

 

    下图提示用户已授权成功的信息

 

    一些服务提供商不仅仅仅实现了OAUTH协议上的功能,还提供了一些更友好的服务,比如管理第三方软件的授权服务。下图就是YAHOO管理软件授权的页面,用户可以取消都某些应用的授权。

参见:

http://kazge.com/archives/765.html

http://kazge.com/archives/496.html

Continue reading 【转】OAUTH协议简介

【转】memcache在大型网站的应用策略

style="width: 858px; height: 64px" />

转自 http://blog.sina.com.cn/s/blog_5f53615f0100qdxc.html ,原文不知出处。

蓝色字是我的加重或是注解。

今天看完了日本人mixi写的“memcached全面剖析”的系列文章,结合我在项目中使用memcache的经验,再谈谈memcache在大型网站中的应用策略。

【部署策略】

基于memcached的slab和dump的内存管理方式,它产生的内存碎片比较少,不需要OS去做繁杂的内存回收,所以它对CPU的占用率那是相当的低。所以建议将它跟占用CPU较高的WEB服务器一起使用来节省成本。当然如果你有大量的廉价PC,那用来专门做memcached服务器也不错。由于32位操作系统中,每个进程最多只能使用2GB内存,所以如果你有大内存的话,可以以daemon的方式启动两个以上的memcached服务,或者干脆用64位的CPU和OS。

【服务监控】

memcached支持分布式机制,php通过memcache::addserver来实现该机制,它实现了如果服务器列表中的一台down掉的时候在参数retry_interval指定的时间就不会再连接该服务器的机制。所以只要你在该时间段内重启或者修复了该服务器,则不会对前端造成太大的影响。当然了,如果你一直不去重启该服务器的话,我测试过addserver再次连接一台down掉的服务器的时间将比平时延长了1秒的时间。可以通过addserver的最后一个参数failure_callback定义一个回调函数来实现邮件通知或者短信通知管理员的功能。

如果是手工重启,我建议将该值设置为20分钟。不过对于memcached进程死掉的服务器,只要重新启动memcached,就可以正常运行,所以采用了监视memcached进程并自动启动的方法的效果最好。mixi推荐的工具:nagios,daemontool

【应用策略】

memcached主要的作用是为减轻大访问量对数据库的冲击,所以一般的逻辑是首先从memcached中读取数据,如果没有就从数据库中读取数据写入到memcache中,等下一次读取的时候就可以从memcached中读取了。但在项目中的具体应用策略(也就是哪些数据应该缓存?怎么样缓存?过期策略?)就是个问题了。它的一个总原则是将经常需要从数据库读取的数据缓存在memcached中。这些数据也分为几类:

一、经常被读取并且实时性要求不强可以等到自动过期的数据。例如网站首页最新文章列表、某某排行等数据。也就是虽然新数据产生了,但对用户体验不会产生任何影响的场景。

这类数据就使用典型的缓存策略,设置一过合理的过期时间,当数据过期以后再从数据库中读取。当然你得制定一个缓存清除策略,便于编辑或者其它人员能马上看到效果。

二、经常被读取并且实时性要求强的数据。比如用户的好友列表,用户文章列表,用户阅读记录等。

这类数据首先被载入到memcached中,当发生更改(添加、修改、删除)时就清除缓存。在缓存的时候,我将查询的SQL语句md5()得到它的hash值作为key,结果数组作为值写入memcached,并且将该SQL涉及的table_name以及hash值配对存入memcached中。当更改了这个表时,我就将与此表相配对的key的缓存全部删除。

三、统计类缓存,比如文章浏览数、网站PV等

此类缓存是将在数据库的中来累加的数据放在memcached来累加。获取也通过memcached来获取。但这样就产生了一个问题,如果memcached服务器down掉的话这些数据就有可能丢失,所以一般使用memcached的永固性存储,这方面我们新浪使用memcachedb。[PS:这是nosql的地盘了]

四、活跃用户的基本信息或者某篇热门文章。

此类数据的一个特点就是数据都是一行,也就是一个一维数组,当数据被update时(比如修改昵称、文章的评论数),在更改数据库数据的同时,使用Memcache::replace替换掉缓存里的数据。这样就有效了避免了再次查询数据库。

[PS:第五点哪去了?]

六、session数据

使用memcached来存储session的效率是最高的。memcached本身也是非常稳定的,不太用担心它会突然down掉引起session数据的丢失,即使丢失就重新登录了,也没啥。见[多服务器session共享之memcache共享]

【总结】

通过以上的策略数据库的压力将会被大大减轻。检验你使用memcached是否得当的方法是查看memcached的命中率。有些策略好的网站的命中率可以到达到90%以上。

【后记】

一、memcached暂时还不支持故障转移,希望在以后的版本中能支持该功能。当然你可以使用日本人平林幹雄的Tokyo Tyrant 来代替memcached,它支持memcached协议,支持永固性存储和故障转移[这个似乎并不是memcached本身语义该做的事情吧]。但我没有在生产环境中使用过,也没有相关的性能测试数据。以后会试用一下这个东东。

二、memcached不支持检索的功能,在实际使用中比如我们想把一个IP表放在memcached中,来检索某一个IP属于那个地区的话,有了检索功能就方便多了。希望他在以后的版本中能提供该功能。暂时可以通过排序存储和二分法在客户端实现。

三、memcached1.2.2版本确实有不稳定的情况,有时候会出现DOWN机,强烈建议升级至1.2.6的版本。见官方说明:Version 1.2.6 released. Major crash fixes, DTrace support, minor updates. If you have stability issues with any previous release, please upgrade to this one.

Continue reading 【转】memcache在大型网站的应用策略

eclipse outline视图对于javascript的bug

现在我一个javascript文件里面写的代码一般就有一千多行,原因主要是用闭包啊,不想搞太多的变量空间引用麻烦。一般来说eclipse的outline视图很好用,将所有函数都列出来了,但是有几次原本好好地outline结构什么都没有了,让我切换函数非常麻烦,查找一下原因,原来对于函数中return 一个json对象的写法造成outline失效了:

function a(){
    return {}; //这里会造成outline问题
}

解决办法:

/>

function a(){
var o = {};
return o;

}

这个问题对EXTJS的源码很头疼,因为里面一堆的return  {};

估计他们不是用eclipse开发的吧,也许牛人既不需要outline视图,LOL.

Continue reading eclipse outline视图对于javascript的bug

【转】Memcached Java Client API详解

转自 http://blog.csdn.net/qqiabc521/article/details/6438429 ,蓝色字是我加的加重或是注解

Memcached Java Client API详解

针对Memcached官方网站提供的java_memcached-release_2.0.1版本进行阅读分析,Memcached Java客户端lib库主要提供的调用类是SockIOPool和MemCachedClient?,关键类及方法整理说明如下。

SockIOPool

这个类用来创建管理客户端和服务器通讯连接池,客户端主要的工作包括数据通讯、服务器定位、hash码生成等都是由这个类完成的。

  • public static SockIOPool getInstance()
    • 获得连接池的单态方法。这个方法有一个重载方法getInstance( String poolName ),每个poolName只构造一个SockIOPool实例。缺省构造的poolName是default。
    • 如果在客户端配置多个memcached服务,一定要显式声明poolName。
  • public void setServers( String[] servers )
    • 设置连接池可用的cache服务器列表,server的构成形式是IP:PORT(如:127.0.0.1:11211)
  • public void setWeights( Integer[] weights )
    • 设置连接池可用cache服务器的权重,和server数组的位置一一对应
    • 其实现方法是通过根据每个权重在连接池的bucket中放置同样数目的server(如下代码所示),因此所有权重的最大公约数应该是1,不然会引起bucket资源的浪费。
for ( int i = 0; i < servers.length; i+/+ ) { if ( this.weights /!= null &&this.weights.length > i ) { for ( int k = 0; k < this.weights[i].intValue(); k+/+ ) { this.buckets.add( servers[i] ); if ( log.isDebugEnabled() ) log.debug("++++ added " + servers[i] + " to server bucket" ); } }

这个文档上举例:

Lets say you have 3 servers.  Server 1 and server 2 have 3GB of space

and server 3 has 2GB of space for cache.  Here is how I would set up

my client.

如果有三个server,分别有3GB,3GB,2GB的缓存空间,那么权重对应应该是3:3:2

 

  • public void setInitConn( int initConn )
    • 设置开始时每个cache服务器的可用连接数
  • public void setMinConn( int minConn )
    • 设置每个服务器最少可用连接数
  • public void setMaxConn( int maxConn )
    • 设置每个服务器最大可用连接数
  • public void setMaxIdle( long maxIdle )
    • 设置可用连接池的最长等待时间
  • public void setMaintSleep( long maintSleep )
    • 设置连接池维护线程的睡眠时间
    • 设置为0,维护线程不启动
    • 维护线程主要通过log输出socket的运行状况,监测连接数目及空闲等待时间等参数以控制连接创建和关闭。
  • public void setNagle( boolean nagle )
    • 设置是否使用Nagle算法,因为我们的通讯数据量通常都比较大(相对TCP控制数据)而且要求响应及时,因此该值需要设置为false(默认是true)

Nagle算法是用于对缓冲区内的一定数量的消息进行自动连接。该处理过程(称为Nagling),通过减少必须发送的封包的数量,提高了网络应用程序系统的效率。这个该不该禁用还需的具体分析,

参见http://www.blogjava.net/killme2008/archive/2011/10/25/353441.html 这个也是与memcached相关的经验。

  • ublic void setSocketTO( int socketTO )
    • 设置socket的读取等待超时值
  • public void setSocketConnectTO( int socketConnectTO )
    • 设置socket的连接等待超时值
  • public void setAliveCheck( boolean aliveCheck )
    • 设置连接心跳监测开关。
    • 设为true则每次通信都要进行连接是否有效的监测,造成通信次数倍增,加大网络负载,因此该参数应该在对HA要求比较高的场合设为TRUE,默认状态是false。
  • public void setFailback( boolean failback )
    • 设置连接失败恢复开关
    • 设置为TRUE,当宕机的服务器启动或中断的网络连接后,这个socket连接还可继续使用,否则将不再使用,默认状态是true,建议保持默认。
  • public void setFailover( boolean failover )
    • 设置容错开关
    • 设置为TRUE,当当前socket不可用时,程序会自动查找可用连接并返回,否则返回NULL,默认状态是true,建议保持默认。

      这里我补充一下,当这个设置为true时,写操作会对此server池中所有的server都进行,例如set(‘1’,’abc’);则每个server都存储了1=abc,当设置为false时,则把所有server作为一个整体,那么上一个set操作可能就放置在server1,而下一个set操作可能就放置在server2.

  • public void setHashingAlg( int alg )
    • 设置hash算法
      • alg=0 使用String.hashCode()获得hash code,该方法依赖JDK,可能和其他客户端不兼容,建议不使用
      • alg=1 使用original 兼容hash算法,兼容其他客户端
      • alg=2 使用CRC32兼容hash算法,兼容其他客户端,性能优于original算法
      • alg=3 使用MD5 hash算法
    • 采用前三种hash算法的时候,查找cache服务器使用余数方法。采用最后一种hash算法查找cache服务时使用consistent方法。
  • public void initialize()
    • 设置完pool参数后最后调用该方法,启动pool。

MemCachedClient?

  • public void setCompressEnable( boolean compressEnable )
    • 设定是否压缩放入cache中的数据
    • 默认值是ture
    • 如果设定该值为true,需要设定CompressThreshold?
  • public void setCompressThreshold( long compressThreshold )
    • 设定需要压缩的cache数据的阈值
    • 默认值是30k
  • public void setPrimitiveAsString( boolean primitiveAsString )
    • 设置cache数据的原始类型是String
    • 默认值是false
    • 只有在确定cache的数据类型是string的情况下才设为true,这样可以加快处理速度。
  • public void setDefaultEncoding( String defaultEncoding )
    • 当primitiveAsString为true时使用的编码转化格式
    • 默认值是utf-8
    • 如果确认主要写入数据是中文等非ASCII编码字符,建议采用GBK等更短的编码格式
  • cache数据写入操作方法
    • set方法
      • 将数据保存到cache服务器,如果保存成功则返回true
      • 如果cache服务器存在同样的key,则替换之
      • set有5个重载方法,key和value是必须的参数,还有过期时间,hash码,value是否字符串三个可选参数
    • add方法
      • 将数据添加到cache服务器,如果保存成功则返回true
      • 如果cache服务器存在同样key,则返回false
      • add有4个重载方法,key和value是必须的参数,还有过期时间,hash码两个可选参数
    • replace方法
      • 将数据替换cache服务器中相同的key,如果保存成功则返回true
      • 如果cache服务器不存在同样key,则返回false
      • replace有4个重载方法,key和value是必须的参数,还有过期时间,hash码两个可选参数
    • 建议分析key的规律,如果呈现某种规律有序,则自己构造hash码,提高存储效率
  • cache数据读取操作方法
    • 使用get方法从cache服务器获取一个数据
      • 如果写入时是压缩的或序列化的,则get的返回会自动解压缩及反序列化
      • get方法有3个重载方法,key是必须的参数,hash码和value是否字符串是可选参数
    • 使用getMulti方法从cache服务器获取一组数据
      • get方法的数组实现,输入参数keys是一个key数组
      • 返回是一个map
  • 通过cache使用计数器
    • 使用storeCounter方法初始化一个计数器
    • 使用incr方法对计数器增量操作
    • 使用decr对计数器减量操作

Memcached Client API 优化(草)

实现memcached的遍历操作

有些应用情况下,需要遍历memcached服务器中所有被cache的数据,目前memcached client API不支持遍历操作,需要进行扩展。

实现get时刷新数据过期时间(应用于session,可能需要修改服务器端程序)

当memcached被用作session服务器的时候,需要支持session的access方法,根据最近访问时间刷新过期时间,目前memcached也不支持该操作,需要进行扩展。

Continue reading 【转】Memcached Java Client API详解

Memcached-Java-Client使用

官网是:https://github.com/gwhalin/Memcached-Java-Client/

Memcached-Java-Client是memcahed的java客户端库,依据其源码文档doc/howto.txt 介绍,是meetup网站目前使用的客户端。

可参见 http://developer.51cto.com/art/201106/271749.htm

从各方面参考,这个是目前最靠谱的java client了.参见

http://kazge.com/archives/752.html

http://www.infoq.com/cn/articles/memcached-java

http://lveyo.iteye.com/blog/240146

 http://www.iteye.com/topic/154767

2.5版之后较之前有较大性能提升,所以网上许多怀疑其性能问题的一般都是在2011年之前的文章。

它的doc很简单,在源码目录doc/howto.txt 中,这位仁兄整理了较新的中文版:

http://kazge.com/archives/754.html

其实也可以理解,协议就那几个。

其源码中MemcachedBench是压力测试的例子。

如下是我测试的结果(客户端和服务器不是一台机子,服务端10m缓存空间,其他默认):

100000 sets: 73047ms
100000 gets: 49594ms
100000 getMulti: 30485ms
100000 deletes: 43281ms

10000 sets: 7579ms
10000 gets: 7328ms
10000 getMulti: 4015ms
10000 deletes: 4172ms

1000 sets: 906ms
1000 gets: 781ms
1000 getMulti: 375ms
1000 deletes: 437ms

100 sets: 109ms
100 gets: 109ms
100 getMulti: 47ms
100 deletes: 47ms

这说明不了什么,仅供参考。

Continue reading Memcached-Java-Client使用

【转】JAVA客户端调用memcached比较

style="width: 902px; height: 88px" />

转自http://blog.chinaunix.net/space.php?uid=20787846&do=blog&id=1841943 ,

有趣的是这篇文章测试结果显示上篇转载的ali client性能有问题,那篇文章还说是优化了whalin,结果反而不如它,不知怎么回事!

蓝色字是博主加的加重标记或是注解。

 

1.memcached client for java客户端API:memcached client for java 

网址:http://www.whalin.com/memcached 

最新版本:java_memcached-release_2.0.1 

操作示例: 

Java代码
  1. import com.danga.MemCached.*;  
  2. import org.apache.log4j.*;  
  3. public class TestMemcached {  
  4.     public static void main(String[] args) {  
  5.         /*初始化SockIOPool,管理memcached的连接池*/ 
  6.         String[] servers = { "192.168.1.20:12111" };  
  7.         SockIOPool pool = SockIOPool.getInstance();  
  8.         pool.setServers(servers);  
  9.         pool.setFailover(true);  
  10.         pool.setInitConn(10);  
  11.         pool.setMinConn(5);  
  12.         pool.setMaxConn(250);  
  13.         pool.setMaintSleep(30);  
  14.         pool.setNagle(false);  
  15.         pool.setSocketTO(3000);  
  16.         pool.setAliveCheck(true);  
  17.         pool.initialize();  
  18.         /*建立MemcachedClient实例*/ 
  19.         MemCachedClient memCachedClient = new MemCachedClient();  
  20.         for (int i = 0; i < 10; i++) {  
  21.             /*将对象加入到memcached缓存*/ 
  22.             boolean success = memCachedClient.set("" + i, "Hello!");  
  23.             /*从memcached缓存中按key值取对象*/ 
  24.             String result = (String) memCachedClient.get("" + i);  
  25.             System.out.println(String.format("set( %d ): %s", i, success));  
  26.             System.out.println(String.format("get( %d ): %s", i, result));  
  27.         }  
  28.     }  

2.spymemcached客户端API:spymemcached client 

网址:http://code.google.com/p/spymemcached/ 

最新版本:memcached-2.1.jar 

操作示例: 

用spymemcached将对象存入缓存 

Java代码
  1. import java.net.InetSocketAddress;  
  2. import java.util.concurrent.Future;  
  3.  
  4. import net.spy.memcached.MemcachedClient;  
  5.  
  6. public class MClient {  
  7.       
  8.     public static void main(String[] args){  
  9.         try{  
  10.             /*建立MemcachedClient 实例,并指定memcached服务的IP地址和端口号*/ 
  11.             MemcachedClient mc = new MemcachedClient(new InetSocketAddress("192.168.1.20", 12111));  
  12.             Future<Boolean> b = null;  
  13.             /*将key值,过期时间(秒)和要缓存的对象set到memcached中*/ 
  14.             b = mc.set("neea:testDaF:ksIdno", 900, "someObject");  
  15.             if(b.get().booleanValue()==true){  
  16.                 mc.shutdown();  
  17.             }  
  18.         }  
  19.         catch(Exception ex){  
  20.             ex.printStackTrace();  
  21.         }  
  22.     }  

用spymemcached从缓存中取得对象 

Java代码
  1. import java.net.InetSocketAddress;  
  2. import java.util.concurrent.Future;  
  3.  
  4. import net.spy.memcached.MemcachedClient;  
  5.  
  6. public class MClient {  
  7.       
  8.     public static void main(String[] args){  
  9.         try{  
  10.             /*建立MemcachedClient 实例,并指定memcached服务的IP地址和端口号*/ 
  11.             MemcachedClient mc = new MemcachedClient(new InetSocketAddress("192.168.1.20", 12111));  
  12.             /*按照key值从memcached中查找缓存,不存在则返回null */ 
  13. Object b = mc.get("neea:testDaF:ksIdno ");  
  14.             mc.shutdown();  
  15.         }  
  16.         catch(Exception ex){  
  17.             ex.printStackTrace();  
  18.         }  
  19.     }  
 
3.alisoft-xplatform-asf-cache-2.4
这是国产的memcached client.我花时间测试过,配置简单,使用也简单,有很详细的中文文档和英文文档.

网址:http://code.google.com/p/memcache-client-forjava/

最新版本: alisoft-xplatform-asf-cache-2.5.2.jar

使用例子
memcached.xml
=========================
<?xml version="1.0" encoding="UTF-8"?>

<memcached>

    

    <client name="mclient0" compressEnable="true" defaultEncoding="UTF-8" socketpool="pool0">

        <errorHandler>com.moit.xplatform.asf.cache.memcached.MemcachedErrorHandler</errorHandler>

    </client>

    

    <client name="mclient1" compressEnable="true" defaultEncoding="UTF-8" socketpool="pool1">

        <errorHandler>com.moit.xplatform.asf.cache.memcached.MemcachedErrorHandler</errorHandler>

    </client>

    

    <client name="mclient2" compressEnable="true" defaultEncoding="UTF-8" socketpool="pool2">

        <errorHandler>com.moit.xplatform.asf.cache.memcached.MemcachedErrorHandler</errorHandler>

    </client>

    

    <socketpool name="pool0" failover="true" initConn="5" minConn="5" maxConn="250" maintSleep="0"

        nagle="false" socketTO="3000" aliveCheck="true">

        <servers>192.168.3.251:11211,192.168.3.251:11211</servers>

    </socketpool>

    

    <socketpool name="pool1" failover="true" initConn="5" minConn="5" maxConn="250" maintSleep="0"

        nagle="false" socketTO="3000" aliveCheck="true">

        <servers>192.168.3.251:11211,192.168.3.251:11211</servers>

    </socketpool>

    

    <socketpool name="pool2" failover="true" initConn="5" minConn="5" maxConn="250" maintSleep="0"

        nagle="false" socketTO="3000" aliveCheck="true">

        <servers>192.168.3.251:11211,192.168.3.251:11211</servers>

    </socketpool>

    <cluster name="cluster1">

        <memCachedClients>mclient1,mclient2</memCachedClients>

    </cluster>

</memcached>
 
  //用containsKey方法判断cache服务器按指定的key值是否存在。

  System.out.println("是否包含了key的数据="+cache.containsKey("key"));

  if(cache.containsKey("key"))

  {

    System.out.println("包含了key的数据");

    System.out.println("从cache服务器获得key值");

  }

  else

  {

    System.out.println("没有包含了key的数据");

    System.out.println("cache服务器,没有数据,则去取数据库数据!");

  }

  

  例子:

  static ICacheManager<IMemcachedCache> manager;

 
  /**

   * 测试MemCached

   * @return

   */

  public String memcache()

  { 
    manager = CacheUtil.getCacheManager(IMemcachedCache.class,

    MemcachedCacheManager.class.getName());

    manager.start();

    try

    {

      IMemcachedCache cache = manager.getCache("mclient0");

      //根据key得到缓存数据

      String a =(String)cache.get("key");

      //用containsKey方法判断cache服务器按指定的key值是否存在。

      System.out.println("是否包含了key的数据="+cache.containsKey("key"));

      if(cache.containsKey("key"))

      {

        System.out.println("包含了key的数据");

        System.out.println("从cache服务器获得key值");

      }

      else

      {

        System.out.println("没有包含了key的数据");

        System.out.println("cache服务器,没有数据,则去取数据库数据!");

      }

      //根据key删除服务器上的对应的缓存数据

      cache.remove("key");

      //根据key保存数据到服务器上

      cache.put("key", "你好!"); 
      //设置带有过期时间的例子

      //过30分钟

      Calendar calendar = Calendar.getInstance();//当前日期

        calendar.setTime(new Date());

        calendar.add(Calendar.MINUTE, 30);//

        cache.remove("keytime");

        cache.put("keytime", "30分钟后过期",calendar.getTime());

        System.out.println("30分钟后过期=keytime="+cache.get("keytime"));

        System.out.println("cache服务器getTime="+calendar.getTime());  
  
  }finally{ manager.stop();}

     //jsp 使用请参考test.jsp文件

     return "testmempage";

  }

总结:三种API比较 

memcached client for java:较早推出的memcached JAVA客户端API,应用广泛,运行比较稳定。 [注:这个是meetup正在使用的]

spymemcached:A simple, asynchronous, single-threaded memcached client written in java. 支持异步,单线程的memcached客户端,用到了java1.5版本的concurrent和nio,存取速度会高于前者,但是稳定性不好,测试中常报timeOut等相关异常。

alisoft-xplatform-asf-cache-2.4 我开始采用,后来发现性能很差,尤其是调用频繁时特别容易出问题.我后来还是采用第一个.现在还没发现什么问题.

由于memcached client for java发布了新版本,性能上有所提高,并且运行稳定,所以建议使用memcached client for java。

Continue reading 【转】JAVA客户端调用memcached比较

Pagination


Total views.

© 2013 - 2019. All rights reserved.

Powered by Hydejack v6.6.1