响应式编程
- I/O 阻塞限制了并行性
- 同步交互限制了并行性
- 轮询减少了使用更少资源的机会
- 一个节点会拖慢所有的其他的节点 需要隔离错误
- 系统的部署能够弹性
建立实例
目标 | 传统部署 | Akka方法 |
---|---|---|
扩展性 | 混合使用线程池 共享数据库的互斥状态,和RPC网络服务进行扩展 | Actor 发送和接收信息 |
提供交互信息 | 对信息进行轮训 | 当时间发生的时候进行推送 |
在网络上进行扩展 | 同步RPC | 异步消息.完成的时候会通过ask和tell方法进行结果的推送 |
错误处理 | 处理所有的异常, 只有一切正常才能继续 | 隔离错误, 通过上级的监督 对出错的信息做处理 |
传统扩展
传统扩展和持久性 一切移入数据库
对象的状态不再是简单的驻留在web服务器的内存中了, 操纵对象的状态不能是简单的getter/setter 而是数据库的DDL,DML. 对于数据库的操作而不是内存的操作会遇到两个问题
- 操作数据库可能会失败. 网络 数据库宕机
- 要通过数据库的锁来保证数据的正确, 无论是关系型数据库的MMVC, 还是Redis的乐观锁, 这时候就没有用到内存锁的机制
- 对程序做测试需要做数据的隔离. @Test(transaction=rollback)
传统扩展和交互应用 轮询
每个数据库的变化需要JDBC做DML才知道变化, 程序不会被主动告知
传统扩展和交互应用 web
在一个controller中我们可能会调用其他的web服务, 网络是不可靠的, 对方的服务也不一定可靠.如果远程的服务调用失败,则程序中同一流程中的其他部分也会失败.
Akka进行扩展
目标 | 传统方式 | Akka方式 |
---|---|---|
保持数据的持久性 | 所有的程序的持久性都由数据库进行维护 | 继续使用内存中的状态所有的状态的改变作为消息发送到日志. 如果应用重新启动, 需要重新读取日志 |
交互 | 对数据库进行轮训 | 把事件推推送到相关的组建 |
最大的挑战是安全的保存数据.
用Akka扩展和持久化
改变保存为事件序列
所有更改都保存为事件序列, 在本例中是MessageAdded事件, Coversation的当前状态可以回放到内容中, Conversation 的状态在内存中进行重建,因此可以在中断的地方继续.这种类型的数据库通常被称为是日志, 这种技术通常为称为事件源.
会话分割
通常采用的使用的技术是 分片 分区
消息推送
事件通过发布订阅的方式进行推送, 而不是组件之间直接通信.
Actor 操作
- 创建
- 发送
- 改变
- 监督