工作上的几个tip

1、如果用java6的ScriptEngineManager来调用JRuby,并且脚本使用到了Ruby的标准库(比如我用到了YAML库),如果没有正确设置,是会找不到标准库的。通过打印$:变量可以看到文件的加载路径,比如在某台机器上的打印的结果:
   puts $:
   输出:
.
/root/.jruby/lib/ruby/site_ruby/1.8
/root/.jruby/lib/ruby/site_ruby
/root/.jruby/lib/ruby/1.8
/root/.jruby/lib/ruby/1.8/java
lib/ruby/1.8
......略

显然,默认会到当前用户的主目录下寻找.jruby隐藏目录,将此目录作为Ruby的安装目录,因此,可以在~user/.jruby放置一个jruby实现,一劳永逸地解决问题,不然就要自己手工添加完整的路径到$:变量中。

2、nio的临时selector的使用,了解grizzly的都知道,Grizzly框架有一个比较与众不同的地方在于使用临时selector注册channel进行读或者写。这个带来什么好处呢?一个是,通常我们可能将read派发到其他线程中去,如果一次没有读完,那么就得继续注册OP_READ到主selector上;注意,nio在一些平台上有个问题,就是SelectionKey.interestOps方法跟Selector.select方法会有并发冲突,产生奇怪的现象,因此,你会看到大多数的nio框架都会保证SelectionKey.interestOps跟Selector.select的调用在同一个线程;在没有读完继续注册这个场景下,免不了线程间的context switch,如果采用一个临时selector注册并读取,就可以避免这个切换开销。另外,对于write调用,通常你可能这样写:
while  (byteBuffer.hasRemaining()) {
  
int  len  =  socketChannel.write(byteBuffer);
  
if  (len  <   0 ){
   
throw   new  EOFException(); 
  }
}


   在负载比较高的时候,write返回0的次数会越来越多,while循环将空耗多次导致CPU占用偏高,这个问题在win32上比较严重,同样可以采用临时selector的解决(Cindy2.x是留在队列,等待下次写)。下例是采用临时Selector进行读的例子:

                 Selector readSelector  =  SelectorFactory.getSelector();
                SelectionKey tmpKey 
=  sc.register(readSelector,
                        SelectionKey.OP_READ);
                tmpKey.interestOps(tmpKey.interestOps() 
|  SelectionKey.OP_READ);
                
int  code  =  readSelector.select( 1000 );
                tmpKey.interestOps(tmpKey.interestOps()
                        
&  ( ~ SelectionKey.OP_READ));
                
if  (code  >   0 ) {
                    
do  {
                        n 
=  sc.read(in);
                    } 
while  (n  >   0   &&  in.hasRemaining());
                    in.flip();
                    decode();
                    in.compact();
                }
                SelectorFactory.returnSelector(readSelector);
    这样的方式,某种意义上可以认为是non-blocking模式下的阻塞读,在网络条件稳定的情况下(比如内网),能带来比较高的效率。

3、 spymemcached,是另一个memcached的java client实现,采用nio。最近遇到的问题是它跟原来的 MemcachedClient的兼容问题,用它去操作MemcachedClient存储的数据。spymemcached是通过Transcoder来实现序列化,Transcoder的WhalinTranscoder实现类兼容了Greg Whalin的MemcachedClient:
private  Transcoder whalinTranscoder  =   new  WhalinTranscoder();


Future
< Object >  f  =  memcachedClient.asyncGet(id, whalinTranscoder);

   各个方法都有重载的版本用以指定Transcoder。

你可能感兴趣的:(工作上的几个tip)