Akka in Scala Part 5 - 监护与错误恢复

引言

在分布式系统中,由于集群规模庞大,系统环境复杂,出错是常态,容错是一个非常重要的内容。

传统的异常处理,通常是捕获某种类型的异常并调用相应的异常处理函数,但是在分布式系统中,由于环境的复杂性,通常无法预料错误的类型并进行有效的处理,传统的异常处理方式并不适用。

Akka沿袭了Erlanglet it crash哲学,当actor内部发生异常时,并不试图捕捉异常并处理,而是重建一个新的actor, 使得整个系统在错误发生的时候可以自动恢复。

Read More

Akka in Scala Part 4 - 测试

引言

按测试驱动开发(TDD, Test Driven Development)的理念,测试代码应先于产品代码被编写,这样不仅保证了产品代码的测试覆盖率,并且可以强制开发者在设计之初就考虑代码将如何被使用,如何才能易于测试。

Akka基于ScalaTest框架,提供了akka-testkit模块来支持单元测试和集成测试的编写。

Read More

Akka in Scala Part 2 - Akka 并发之道

初识Akka

并发,是计算机世界与生俱来的命题,从CPU的分时处理,到web网站响应多用户请求,无处不彰显着并发的力量。

概言之,并发模型可分为两种,共享可变状态模型和消息传递模型。

多线程是共享可变状态模型的经典例子,上一篇我们已经简要解释了这种模型的问题。

消息传递模型有两种经典的实现,一种是CSP(Communicating Sequential Processes), 例如Golang中的Goroutine和Channel, 另一种是Actor, 例如Erlang的OTP和Scala的Akka。相对于CSP,Actor更加适应分布式环境。

Read More

Akka in Scala Part 1 - Java dosen't work

Java 之殇

我无意挑起编程宗教间的争论,仅仅想阐述一个简单的事实 – Java doesn’t work.

你从最优秀的Java书籍中学到了解耦接口与实现,于是开始热衷于设计出各种各样的接口,然而这些接口要么支持的方法太少,沦为几乎无用的鸡肋,要么需要实现方法太多,给子类造成沉重的负担。Java还慷慨地给了你额外的’奖励’ – 同样的方法声明在各个子类中需要一遍又一遍地重复,如同遭受了计算机世界中恶灵的诅咒。

你从最优秀的Java博客中掌握了设计模式,开始实现各种各样的单件类,如同发现新大陆一般对访问权限控制,枚举变量之类的奇技淫巧兴奋不已。然而所有的设计模式,背后都对应着现实中的高频需求,在Java的内在世界,这些需求却被无情地置于荒漠之中。

Java最大的魅力在于,这门语言总在试图表达正确的概念,却总能展现丑陋的实现,这一点在并发编程领域,体现得淋漓尽致。

Read More

Mesos 札记

引言

基于云平台的应用如雨后春笋般涌出,任务处理应用如Hadoop,Spark,Storm,服务调度应用Marathon, Aurora, Chronos, 数据库Redis, Cassandra, Mongodb, 搜索引擎ElasticSearch, 消息系统kafka。面对如此纷繁的应用,需要一个操作系统,在应用之间分配集群资源,在此背景之下,云世界的操作系统——mesos, 应运而生。

本文是Mesos的学习笔记,主要基于Mesos white paper, 和Mesos系列博客

Read More

Rails源码管窥7 - autoload 机制

引言

在开发大型web应用时,一个普遍的痛点是在每个源代码文件的开头,都需要一长串的import来引入所需的类,使得源代码变得冗长并且容易出错。
Rails通过ActiveSupport::Autoload模块,免去了手动加载类或者模块的烦恼。Rails的autoload机制主要提供给了两大功能:

  • 自动加载类和模块的定义

    当rails看到未定义的常量时,会根据名字猜测其所处的路径,然后加载其定义。这里又一次体现了rails convention over configuration哲学的强大力量。

    Rails采用缓式(lazy)加载的策略,在常量名首次出现时试图尝试其定义。缓式加载使得rails server在开发模式启动时,只需加载少量的类及模块定义,整个启动过程可在较短时间内完成。

  • 文件修改后自动重新加载

    当处于开发模式时,如果开发者修改了controller, model等目录下的源码文件,无需重启服务器,下一次请求rails会自动读取最新的定义,后面我们会一起探索这样的魔法是如何实现的。

Read More

Rails源码管窥6 - 数据验证

引言

在web开发的过程中,经常需要对数据的有效性进行验证,以保证数据符合我们的需求。

数据验证可以在以下几处完成:

  1. 在前端通过JavaScript进行验证。Javascript最初被创造的目的就是为了对表单进行数据验证,使用JS验证的优点是简单,响应迅速,缺点在于无法对涉及后端逻辑的数据进行验证。

  2. 在Model层进行验证。当数据验证需要在后端完成时,这是推荐的做法。

  3. 在Controller层进行验证。这种做法的主要缺点在于会使controller的代码膨胀,并且增加与model层的耦合度,不利于代码的阅读和维护。

  4. 在数据库层面进行验证。数据库也提供了constraints功能来对保证数据的正确性,但是缺点主要在于提供的验证方式有限,并且直到数据最终存储到数据库前,才能发现错误。

Rails通过ActiveModel模块提供了一系列预定义的类来辅助验证,用户也可以根据自己的需求来自定义验证逻辑。

Read More

Rails源码管窥5 - 添加属性方法

引言

这一节我们研究rails MVC 架构中的model部分,rails 中有三种model相关的类型:ActiveModel, ActiveRecord 和 ActiveResource

ActiveModel实现了和model相关的许多功能,比如validation,ActiveRecordActiveModel的基础上,提供了和数据库相关的ORM支持,ActiveResourceActiveModel的基础上,提供了对WebService API的支持。本节我们关注ActiveModel相关的模块。

Read More

Rails源码管窥4 - 模板缓存

引言

通过上一节的研究,我们理解了Rails模板查找机制。
但复杂的查找逻辑也意味着昂贵的时间开销,那么如何提高模板查找的效率呢?聪明的你一定已经想到了——缓存查找结果。

我们该如何实现rails的模板缓存系统呢?
最简单的办法是使用一个hash ,但是查找结果由name, prefix, partial, details这些参数共同决定, 那么hash key该如设计呢?

让我们一起到Rails源码中寻找答案吧。

Read More