今天在google reader上无意中看到了twitter开源出来的RPC框架Finagle项目。简单看了介绍,立刻引起了我的兴趣,一是Finagle提供了RPC服务器端和客户端所需的众多成熟的功能,另外则是Finagle是用我所喜欢的scala语言写的。
Finagle基于Netty,支持众多rpc调用方式,包括request-response, streaming 和 pipelining;同时也提供对于保持状态的支持。
客户端特性
- Connection Pooling
- Load Balancing
- Failure Detection
- Failover/Retry
- Distributed Tracing (a la Dapper)
- Service Discovery (e.g., via Zookeeper)
- Rich Statistics
- Native OpenSSL bindings
- Sharding
服务器端特性
- Backpressure (to defend against abusive clients)
- Service Registration (e.g., via Zookeeper)
- Native OpenSSL bindings
支持的协议
- HTTP
- Streaming HTTP (Comet)
- Thrift
- Memcached/Kestrel
起了个名叫做segcala, 地址 http://segcala.googlecode.com。
这几天对Scala比较感兴趣,看了一些资料,不过语言这东西光看不练还是没感觉,就写了这样一个分词程序。使用了Chih-Hao Tsai的mmseg分词算法。做为依赖注入的粉丝,程序里使用了google guice做为依赖注入容器。
Scala在JVM上的运行效率可以达到和Java差不多的程度。做为同时支持面向对象和函数式编程思想的语言,其强大的表达能力则是Java所忘尘莫及。
以mmseg算法中求一个chunk的自由语素度的代码为例,看看Scala如何使程序变得更加简捷和清晰:
Scala版:
def largestSumMorphemicFreedomDegreeRule(chunks: List[Chunk]): List[Chunk] = {
val c = chunks.reduceLeft((c1, c2) => {if (c1.degreeOfMorphemicFreedom > c2.degreeOfMorphemicFreedom) c1 else c2})
chunks.filter(chunk => (chunk.degreeOfMorphemicFreedom == c.degreeOfMorphemicFreedom))
}
再看看Java版(取自solo L的mmseg库):
public class LSDMFOCWRule implements IRule {/* (non-Javadoc)
* @see org.solol.mmseg.core.IRule#invoke()
*/
public final IChunk[] invoke(final IChunk[] chunks) {
LSDMFOCWRuleComparator[] orderedChunks = new LSDMFOCWRuleComparator[chunks.length];
for (int i = 0; i < chunks.length; i++) {
orderedChunks[i] = new LSDMFOCWRuleComparator(chunks[i]);
}
Arrays.sort(orderedChunks);
int index = 0;
double degreeOfMorphemicFreedom = orderedChunks[index].getChunk().getDegreeOfMorphemicFreedom();
List list = new ArrayList(1);
list.add(orderedChunks[index].getChunk());
index++;
while (index < orderedChunks.length) {
if (orderedChunks[index].getChunk().getDegreeOfMorphemicFreedom() == degreeOfMorphemicFreedom) {
list.add(orderedChunks[index].getChunk());
} else {
break;
}
index++;
}
IChunk[] degreeOfMorphemicFreedomChunks = new IChunk[list.size()];
list.toArray(degreeOfMorphemicFreedomChunks);
return degreeOfMorphemicFreedomChunks;
}
static class LSDMFOCWRuleComparator implements Comparable {
private IChunk chunk;
public LSDMFOCWRuleComparator(IChunk chunk) {
this.chunk = chunk;
}
public IChunk getChunk() {
return chunk;
}
public int compareTo(Object obj) {
IChunk another = ((LSDMFOCWRuleComparator) obj).getChunk();
double temp = another.getDegreeOfMorphemicFreedom()
- chunk.getDegreeOfMorphemicFreedom();
if (temp > 0D) {
return 1;
} else if (temp < 0D) {
return -1;
} else {
return 0;
}
}
}