Scala实例教程:Kestrel

开发 后端
本文通过Kestrel进行Scala的实例教程。对于没有 Python, Ruby 等语言基础的Java工程师来说,学习Scala是一件比较痛苦的事情,所以通过实例学习是最好的方法了。

要学习一门新语言,***的方法之一莫过于从代码实例学习。现在Scala对于很多人来说还是一门新语言,所以有机会通过Scala实例教程多看多学都是很有帮助的。

Scala实例教程:走读Kestrel,了解Scala

Scala的一些语言特性是很令人着迷的,尤其对于那些厌倦了异常处理和冗长的类型转换的Java工程师来说,Scala可以把代码写的更加地简洁。但是对于Scala来说,尤其是没有 Python, Ruby 等语言基础的Java工程师来说,学习Scala是一件比较痛苦的事情,而将Scala的优势发挥出来,则需要更多的努力。

为了让这个事情变得不那么困难,我们可以从优秀的一个Scala代码的实例来开始——Kestrel。我们可以从新闻中了解到,作为Twitter核心的消息转发机制,使用了Kestrel。也许是因为Kestrel的集群架构实现简单——Kestrel的说明中提到,只要运行多个独立的Kestrel,随机set和get这些实例就能做到集群了(其实牺牲了消息队列的时序)。

Kestrel的原型是来自于Ruby的Starling。一个兼容memcached接口的消息队列,把这个消息队列看成是一个基础的service。客户端可以通过queueName,向队列添加或者获取消息队列中的消息,依次处理。Kestrel项目中,使用Apache Mina项目来实现Socket的链接管理。

同时,Kestrel还支持当消息队列过多的时候,把消息队列存放到本地硬盘上的策略。以提高整体的稳定性。当然,***的情况,还是能够及时将队列中的消息处理完毕。在测试的过程中,会发生OutOfMemory的情况,这是因为在配置中,允许驻留在内存中的消息数量,超过了JVM开启的时候,所能够申请的数量,这在实际的使用中,是需要考虑清楚的。

另外,还需要注意的是Kestrel只能在Java 1.6的环境下使用。

不过还是主要通过走读Kestrel代码,来了解Scala。也能从中学到一些对Scala非常好的使用方法。等到对代码有一定认识之后,在回来看Scala的语法手册,可能会有更多的新发现。

下载编译不多说,注意要用Java 1.6就可以了。我们先从简单的开始,我们在Kestrel的官方网站上看到一个压力测试的用例。如下文所示:

  1. $ ant -f tests.xml put-many-1 -Ditems=5000000 

先从测试案例开始,然后再看核心代码,入门会比较容易。在测试案例里面,我们比较容易猜出来,整个程序大概做了一些什么,通过test.xml所述,我们找到了net.lag.kestrel.load.PutMany,在src/test/net/lang/kestrel/load里面可以找到这个程序,PutMany.scala,相对来说ManyClients.scala的功能可能更全面一些,我们就拿它作为例子吧:

  1. package net.lag.kestrel.load  
  2.  
  3. import _root_.java.net._  
  4. import _root_.java.nio._  
  5. import _root_.java.nio.channels._  
  6. import _root_.java.util.concurrent.atomic._  
  7. import _root_.net.lag.extensions._  

这段一点都不难懂,嗯……我们可以大胆地猜的 _ 在这里的涵义等同于 Java 里面的 *。事实上就是这样的,在后来,你会发现 _ 不仅仅代表的是 * ,它会出其不意地出现在很多地方,而在Scala中,它的涵义接近于default。

  1. object ManyClients {  
  2.   private val SLEEP = System.getProperty("sleep""100").toInt  
  3.   private val COUNT = System.getProperty("count""100").toInt  
  4.   ……  

类定义也很清楚,object 等同于 Java 中的 class。变量声明中Scala的格式和Java有点不同,需要说明一下的是var表示变量,而val表示常量,在声明的时候必须被赋值,不过这个常量是在创建的时候执行的结果。就好像例子中写的那样。注意toInt,这是一个Scala的特点,通过推断的方式来确定变量的类型,所有在有些时候,变量的类型声明就可以被省略了。

这种对变量类型的省略是Scala的核心理念——”Type Less, Do more”,有些事情编译器直到就好啦。

函数来了:

  1. def put(socket: SocketChannel, queueName: String, n: Int) = {  
  2.     ……  

def 表示一个方法,每个Scala的函数都有返回,这是Scala对”=”的理解,返回的结果就是 {} 中***一条指令执行的返回值,所以,Scala没有return函数。返回值类型和参数的类型说明都是用 name : type 的格式来体现的,如果我们制定了 put 的返回是一种特殊的类型,比如Unit,那么我们的定义就是 def put ( a : Int) : Unit = …… 。这样的表达是可以理解的,但是对于Java工程师来说,看起来很别扭,尤其是 = 后面的 {} 被省略掉之后。

接下来我们就阅读到了main函数,是的,它和Java的main函数作用是完全相同的,但是其中有一段比较难以理解的代码,而这段代码体现了Scala易用性的特点:

  1. var threadList: List[Thread] = Nil  
  2. ……  
  3. for (i <- 0 until clientCount) {  
  4.   val t = new Thread {  
  5.     override def run = {  
  6.       val socket = SocketChannel.open(new InetSocketAddress("localhost"22133))  
  7.       getStuff(socket, "spam")  
  8.     }  
  9.   }  
  10.   threadList = t :: threadList  
  11.   t.start  
  12. }  
  13. ……  
  14. for (t <- threadList) {  
  15.   t.join  
  16. }  
  17.  

先解释一下对List的操作。var threadList : List[Thread],比较好理解,就是声明一个List,每个成员都是Thread,类似于Java声明ArrayList。使用var而不使用val,因为前面提到过var是会被改变的,val是常量。而 threadList = t :: threadList 是一个对List的操作,把t放在threadList的表头……是不是很形象呢?

再解释一下for循环的一个语法 for (t <- threadList) {} 就是遍历所有的threadList都执行一遍,等同于Java中的iterator,是否看起来很简洁呢?而另一个语法 for (t <- 0 until clientCount) {} 就不用解释了。

Scala的精彩部分之一,隆重登场了:

  1. val t = new Thread {  
  2.     override def run = {  
  3.       val socket = SocketChannel.open(new InetSocketAddress("localhost"22133))  
  4.       getStuff(socket, "spam")  
  5.     }  
  6.   } 

首先,t 是一个Thread类,因为 val t = new Thread ….。

然后我们发现这个Thread的run函数被重载了。这就是为什么def 后面那个 = 的深意,函数是可以被赋值的。然后繁琐的创建线程的语句,被简化成了简单的几行代码。非常直观。

哦,其实Javascript也有这样的语法,这也是这一代语言的发展趋势。在这一代语言里面,语言不再是少林寺的武功,需要从摆架子开始,而更象金庸笔下的凌波微步,走得更加轻巧。其实多生成一个类,增加一个对象,对系统资源的耗损并没有想象中的那么大,所以在这里,类的重载,以及Scala的匿名函数等语法上的特性,更加鼓励程序员,用简洁和优美的方式来描述数据处理的方式。

看了这个Scala实例教程,希望能够更好的帮助你了解Scala语言。

【编辑推荐】

  1. 从Scala看canEqual与正确的的equals实现
  2. Java:所有的equals方法实现都是错误的?
  3. Java语言中深入研究Java equals方法
  4. Java是平台而非产品:可添加型概念需改变
  5. Scala编程语言
责任编辑:yangsai 来源: dingsding
相关推荐

2009-09-28 11:42:21

KestrelScala

2009-09-28 10:26:12

Scala代码实例Kestrel

2014-08-26 11:46:46

QtAndroid实例教程

2009-09-22 10:15:42

PersistentQScala

2019-06-17 15:25:17

expandunexpandLinux

2010-08-17 11:02:45

DIV CSS实例教程

2009-09-22 09:59:40

QueueCollecScala

2013-01-04 16:17:33

Android开发图像特效图像处理

2009-09-08 14:18:35

NFS服务器

2011-07-25 16:03:47

XCode 编译

2009-09-28 11:25:17

PersistentQKestrelScala

2010-08-25 17:08:18

实例教程

2009-07-30 14:18:02

ASP.NET实例教程

2013-01-14 17:05:55

UCUI设计菜单栏

2009-09-28 11:37:03

Journal.scaKestrel

2013-07-25 14:44:48

sqlite实例教程iOS开发学习sqlite打造词典

2013-08-15 09:14:55

2010-06-18 15:55:47

UML建模

2009-09-22 09:42:24

Scala的核心

2011-07-21 17:00:59

iPhone UIWebView Status Cod
点赞
收藏

51CTO技术栈公众号