工作的几个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。

你可能感兴趣的:(框架,工作,memcached,Ruby,jruby)