Akka TypedActor

Akka 中的有类型 Actor 是 Active Objects 模式的一种实现,将异步的调用执行逻辑封装在一个方法内,在代码层面保证了的顺序执行思维。

Active Objects 设计模式

来自维基百科 Active Objects

该设计模式包含了六种元素:

  • 代理:提供了面向客户端的带有公开方法的接口。
  • 接口:定义了到 active object 的请求方法(业务代码提供)。
  • 来自客户端的一序列等待请求。
  • 调度器:决定接下来执行哪个请求。
  • active object 方法的实现类(业务代码提供)。
  • 一个回调或变量,用以让客户端接收结果。

上述六个元素中,除了标记(业务代码提供)的,其余都是由该模式的实现提供的,在本篇也就是 Akka。

Akka 是通过 JDK 的 java.lang.reflect.Proxy 来自实现 active object 模式的。

继续阅读

我眼中的 性能劣化、优化的曲线

性能劣化

性能劣化的图形

随着代码写得越来越烂,程序运行时 数据库操作更多、IO 阻塞等待跟过、不必要的对象创建、GC 回收更频繁,线程的上下文切换也更多,开销越来越多,所有因素综合起来,程序运行更慢,响应延迟加大。

当到达临界点的时候,压垮骆驼的最后一根稻草出现了,系统直接崩溃。

坏东西、副作用是会累积的。

继续阅读

《Effective Ecterprise Java》 笔记

只有第7章的。

关于安全:它是站在屋子中心的大象,每个人都可以看到它,每个人都认识它,但每个人都拼命地试图对它视而不见,绕开它进行工作。

  • 认证(authentication):是一种校验行为,检查系统中的一个实体是否真的与它声明的身份相符。认证有三种基本形式:根据你所知的、你所有的或你是什么来进行认证。
  • 授权(Authorize):授权行为是确认系统中的一个实体能够做什么。很多时候,成功的认证导致某种授权。

安全是一个过程,而不是产品

如果你以为技术可以解决你的安全问题,那你根本没有理解这个问题,并且你也没有理解这项技术。

安全不是那种我们可以简单地在系统实现的生命周期的某个时刻 “打开” 的特性。安全必须贯穿于系统开发的每次迭代过程的分析、设计、实现和测试中,否则,漏洞就会出现。

“编写安全代码” 应该是程序员的一条指导原则,就像 “编写好的代码”、“编写优雅的代码” 那样。

安全不仅仅是预防

任何安全系统的另外两个部分就是 检测与反应。软件不能仅仅依赖于预防,检测和反应也必须有,预防甚至不是我们首先要考虑的。

建立威胁模型

一个攻击者可以通过多种方式接触系统,要覆盖所有的入侵方式似乎是不现实的,需要准确地确定系统的哪些部分最重要且容易受攻击,优先保护它们。

为了安全性,需要某种针对我们的应用的安全性的宏图,需要知道哪个地方最容易受到攻击,以及如果被攻击会造成怎样的破坏。这些信息反过来可以帮助我们区分哪些弱点是需要关注而哪些是可以忽略的。这些资源一般被称为一个威胁模型。

如果没有威胁模型,想知道需要花多少时间和精力来防范一个指定的企业系统可能面对的某个潜在的安全攻击是不可能的。

做不安全假设

建立安全系统的一个特殊要点:你必须假设每一样东西都是不安全的,包括你正在建立的那些部分,直到你确定系统可被入侵和攻击的安全疑点都被清除了。

两条关于企业级安全性的定律:

  • 假设一个构件是不安全的,除非你能证明;
  • 一个构建永远不能被证明是安全的。

总是假设每件东西都是不安全的,假设人们会通过其中一些构件攻破系统。

现实世界中的安全系统都使用深度防御策略。它们假设在每个层次上,防御都会被攻破,因此需要另一种防御来以防万一。

我们不能阻止一个攻击者,预防本身永远不能保证提供一个安全的系统,目标是拖延攻击者,以使入侵检测系统和警报管理员可以检测并采取合适的反应措施。

这一条的结论是采用 最低权限原则。

总是验证用户输入

如何处理用户输入是建立一个安全系统的关键,任何一个系统接受的用户输入都是攻击者进入系统的通道。

必须假设客户端验证逻辑没有被执行,对于每个用户输入的提交,都要严格地进行一序列的验证校验以保证用户输入中的所有基于输入的攻击都被过滤了。

(数据与代码分离)


欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。

计算 一个点 附近的地方

问题

随着地理位置的应用普及,越来越多类似计算 一个点 附近的酒店的需求。比如,显示当前位置2000米范围内的 7 天酒店。

一般来说,在系统里都有一张表,存储了每个 7 天酒店的位置信息,表结构可以简化为三个字段 tb_location(ID, lng, lat),其中 lng:表示经度;lat:表示纬度,这两个字段都是数值类型的,且建了索引。

现在要把 2 公里范围内的 7 天酒店找出来,有的人写的 SQL 语句大概是这样的:
select id from tb_location where calc_distance(lng, lat, curLng, curLat) < 2000

这个语句的问题是没法利用索引,需要全表扫描,计算每一条记录与当前位置的距离,效率很低。

优化

用一张图来说明优化策略:
附近地点计算优化

继续阅读

关于 RESTful 的一点思考

RESTful 是什么?

来自《Spring 实战》:

REST 组成:表述性、状态、转移。

REST 是将资源的状态以最合适的形式从服务器转移到客户端。

RESTless

RESTless 是面向行为的,而不是面向资源的。比如:
http://host:port/servletContext/showUser.action?id=123

在这个 URL 里,servletContext 是 servlet 上下文路径;showUser.action 是控制器 URL 模式,其中 show 是动词,是一种行为;id=123 是标识符。

RESTful URL

比如:http://host:port/servletContext/users/123

在这个 URL 里,users 是资源类型(名词),123 是特定的 user。

这个 URL 并不做任何事情,只是标识了一个资源,而对这个资源做什么是由 HTTP 请求的方法决定的。

RESTful URL 的一些特性:

  • 不仅定位资源,还可以唯一标识这个资源;
  • 有层次,从左到右读时,是一个从抽象到具体的过程;
  • 对于服务器端应用,路径是参数化的。

继续阅读

Akka Actor 生命周期

本文主要展示 Akka Actor 的生命周期管理和默认的监管策略。基于 Akka 2.3.4,Scala 2.11。

Akka Actor 生命周期钩子

Actor 实例化后就由 Actor 运行时调度执行。

Akka Actor 定义了下列的生命周期回调钩子:

  • preStart:在 actor 实例化后执行,重启时不会执行。
  • postStop:在 actor 正常终止后执行,异常重启时不会执行。
  • preRestart:在 actor 异常重启前保存当前状态。
  • postRestart:在 actor 异常重启后恢复重启前保存的状态。

继续阅读

Scala Trait 堆叠特性

以一个简单的例子展示 Scala Trait 线性堆叠的特性:

package net.coderbee.scala

trait BaseTrait {
    def action
}

trait Trait0 extends BaseTrait {
    abstract override def action {
        println("action at Trait0")
        super.action
    }
}

trait Trait1 extends BaseTrait {
    abstract override def action() {
        println("action at trait1")
        super.action // 如果某个Trait不调用父类的方法,则会中断Trait的调用栈,这可用以实现过滤
        println("rollback at action at trait1")
    }
}

trait Trait2 extends BaseTrait {
    abstract override def action() {
        println("action at trait2")
        super.action
    }
}

trait BreakTrait extends BaseTrait {
    abstract override def action {
        println("i am break trait, end here ")
    }
}

class ClassWithTrait extends BaseTrait {
    def action() {
        println("action at ClassWithTrait")
    }
}

object StackTrait {

    def main(args: Array[String]) {
        val tr012 = new ClassWithTrait with Trait2 with Trait1 with Trait0
        tr012.action // 从右往左调用 trait 的抽象实现,最后调用本类的。如果中间某个抽象方法没有调用超类的  super 方法,则不会调用到本类

        println
        val tr02 = new ClassWithTrait with Trait2 with Trait0
        tr02.action

        println
        val trBreak = new ClassWithTrait with Trait2 with BreakTrait with Trait1 with Trait0
        trBreak.action
    }
}

输出结果:

继续阅读

Akka Actor 4个核心操作

来自:http://markusjura.github.io/akka-intro-slides/ 的笔记

  1. create:创建新的Actor。
    每个 Actor 表示为一个 ActorRef;
    没法访问 Actor 实例;
    一个Actor引用允许你发送消息到一个 Actor。

  2. send:发送消息到其他 Actor。
    需要一个 Actor 引用;
    异步和非阻塞(fire-and-forget);
    注意:消息必须是不可变的。
    最佳实践:
    使用 object 和/或 case 类;
    在 actor的伴生对象里定义消息协议。

  3. Become:为处理下一个消息改变行为。
    动态定义Actor的行为;
    通过接收消息触发;
    将对它接收到的消息作出不同的反应。

    用途:
    实现有限状态机;
    让高度竞争的Actor自适应地转换他自己为 Actor 池或路由Router;
    实现优雅的降级;
    派生出通用的工作者Actor,成为管理者当前需要的。

  4. Supervise:管理其他 Actor 的失败。
    监管策略:

      每个Actor有一个默认的监管策略:
           ActorInitializationException → Stop
           ActorKilledException → Stop
           Exception → Restart
           Throwable → Escalate
           Otherwise → Escalate
    
      策略可以被覆写;
    

欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。

Java 对象内存布局

本文来自:http://www.ibm.com/developerworks/cn/java/j-codetoheap/

寻址能力与用户空间

进程能够处理的位数取决于处理器能寻址的内存范围,处理器的寻址能力取决于处理器的位数,比如 32 位能寻址 2^32,也就是 4G。

处理器提供的部分可寻址范围由 OS 本身用,供操作系统内核以及 C 运行时。OS 和 C 运行时占用的内存数量取决于所用的 OS,比如 Windows 默认占用 2GB。剩余的可寻址空间是供运行的实际进程使用的内存(用户空间)。

对于 Java 应用程序,用户空间是 Java 进程占用的内存,实际上包含两个池:Java 堆和本机(非 Java)堆。Java 堆的大小由 JVM 的 Java 堆设置控制:-Xms 和 -Xmx 分别设置最小和最大 Java 堆。在按照最大的大小设置分配了 Java 堆之后,剩下的用户空间就是本机堆。
32bit JVM

可寻址范围总共有 4GB,OS 和 C 运行时大约占用了其中的 1GB,Java 堆占用了将近 2GB,本机堆占用了其他部分。请注意,JVM 本身也要占用内存,就像 OS 内核和 C 运行时一样,而 JVM 占用的内存是本机堆的子集。

继续阅读

一周随记之 2014-07. 21-27

2014-07. 21-27

7.21-23

另一个项目组在搞动静分离,所有的静态资料由 Nginx 处理,动态资料由 JBoss 处理,域名不同,产生跨域问题(跨域请求和跨域 Cookie 传送)。其实访问量不大,没必要这么折腾,由 Nginx 做代理和处理静态资源完全够了。

域是浏览器的安全策略,可以说跟服务器端无关。可参考:

7.24

早上到办公室后,想从手机里拷点资料到电脑来看,发现了一个已被遗忘的好东西:《阿里巴巴集团web安全标准Ver1.4》,开发必备,码农普及安全编程的良药。

顺便推荐《白帽子讲web安全》,这本书买之前还犹豫值不值,看完第一章就觉得已经值回书价了。这个经历也改变了我对买书的看法:如果一本书能带来一点改变、甚至一点感触或启发就值回书价了。

继续阅读