异步数据存储声明
在过去的几年里,NoSQL数据存储的工作让我对应用程序的方向有了一些见解,因为NoSQL成为了主流的数据存储和检索方法,至少对网络和基于云的程序来说是这样的(企业级应用最终也会这样,但这需要花费较长的时间)。多年来,我学会了相信自己的直觉,我的直觉告诉我,这种方法很有价值,应该有人去探索——即使我个人没有时间来写这个系统。
异步访问
我认为整个方法的核心是对数据的非阻塞异步访问。一般来说,如果我们希望在程序中使用异步消息传递,就必须获得消息代理的帮助,消息代理的唯一目的就是异步地路由消息。毫无疑问,我最喜欢的就是RabbitMQ。但是,为了扩展RabbitMQ的一些关键功能和抓住特别棘手的部分,我认为通过利用一个更加轻量级的异步库,可以更快地实现更多的进展,这个库不是一个具体的协议,类似RabbitMQ之于AMQP。
在我看来,Node.js已经改变了Web程序开发的形式。虽然真正的异步程序比较难以构建(因此,在一般民众中还没有那么受欢迎。),但在云环境中,用户可能需要大量相对较小的虚拟机实例,这些虚拟机可以相互协作,因此在云环境中,它的可扩展性更强,性能也更好。
我们当然可以在这里使用便利的消息代理,添加一些消费者,在我们的Web程序中写几个生产者,然后说写的不错。
但我不会满足于此。
数据是国王
如果我们将程序剥离为最纯粹的形式,那么我们唯一关心的就只有数据。我可能会选择我最喜欢的NoSQL数据存储和Riak,因为它们既可以扩展我的数据,我又可以在我的数据上执行分布式的Map / Reduce。但是,首先,数据才是程序的全部原因。无论我在程序内部做什么都是在有数据的环境中完成的。如果我使用消息代理,那么消息就是数据。如果我建立一个网络表单,我将接收数据。如果我生成报告,我将报告数据。
没有什么比数据更重要。
但是消息代理不关心数据,它仅仅是一个指挥,消息存储并不关心这个指挥。但事实并非如此。
因为我认为在代码中,也许有一个例子可以说明我的观点。
想象一下,我需要将上传的图像转换成缩略图。要做到这一点,我写了一个简单的程序,使用ImageMagick缩放,裁剪,并将图像转换为JPEG。我还创建了一个Web窗体,允许用户上传他们的图像。在这个异步的数据存储世界中,我的图像转换器逻辑应该能够监听数据存储中的INSERT或UPDATE事件并将其转换传入数据,自动存储上传图像的缩略图。
图像转换器伪代码:
def db = asyncdb.connect("tcp://localhost:5555")
def img = request.get_upload_data("image")
def metadata = [ content_type: "image/jpg" ]
db.push("imagebucket", img.name, img.data, metadata, { event, data ->
if(event.type == SUCCESS) {
db.push("profilebucket", "$user.profile", [ avatar: data.key + ".thumbnail" ])
}
})
这是什么:
- 连接到数据存储的节点。
- 通过传递可以调用的Closure来订阅数据存储事件,返回true | false并在过滤器Closure返回true时传递Closure来调用。
- 被调用时,会自动更新缩略图,并将原始图像的版本存储在特定的键下。
在我的Web程序控制器中,我通过使用异步数据存储访问客户端插入上传的图像。
def db = asyncdb.connect("tcp://localhost:5555", [ name: "image.converter",
description: "Image thumbnailing listener" ])
这是什么:
- 连接到数据存储的节点。
- 构建新的数据存储条目,包括可以触发缩略图侦听器的元数据。
- 异步地将图像数据“推入”数据存储区并注册一个事件处理程序,以便在监听程序成功缩略图像时调用客户机的回调函数。
- 当缩略图成功创建后,用户的配置文件将通过向其中添加新的数据进行更新,该数据引用了新转换的缩略图。
注意,这一切都是以非阻塞和异步的方式完成的。数据完整性保持不变,因为直到缩略图创建完成后才会更新配置文件。这个系统也是无国界的。每个节点彼此都知道,所以负载平衡器可以将请求的第一部分发送到一个服务器,将请求的第二部分发送到另一个服务器,但是没有一个是重要的,因为一个操作依赖于另一个等待被释放的特定事件。
消息和数据处理的混合
这种数据访问形式对我来说很有意义。虽然它可能混合了一些传统上没有一起使用过的程序(异步消息传递和数据存储),但它可以创造出非常简洁和易于理解的应用程序。
数据存储应该提供一个Web UI,以便开发人员可以询问系统的内部,看看事件是否正在等待交付。在理想情况下,客户端方法也应该接收Web UI向开发人员展示的任意元数据,以便他们可以很容易地看到报告监听器实际上做了什么。如下所示:
def db = asyncdb.connect("tcp://localhost:5555", [ name: "image.converter",
description: "Image thumbnailing listener" ])
目前没有任何数据存储支持这些类型的东西。可能是我是唯一真正喜欢这种东西的人。但是随着数据访问渐渐走向有更多异步和NoSQL的世界,我们的应用程序开发模式将发生变化。我可以向你保证。唯一的问题是“它会改变什么?”
- 机器学习黑客系列:模型比较与选择
- asp.net :使用jquery 的ajax +WebService+json 实现无刷新去后台值
- 用A标签实现页面内容定位 点击链接跳到具体位置
- Seq2seq模型的一个变种网络:Pointer Network的简单介绍
- 框架设计原则和规范(三)
- 微信推广功能支持图片广告和投放外链广告
- PHP 高级编程之多线程
- 框架设计原则和规范(四)
- python 函数参数的传递(参数带星号的说明)
- 微信公众平台增加更多统计项 让你更了解运营数据
- 用OpenCV计算道路交通流量的一个直观教程
- WPF Button TextBox 圆角
- 设置WPF窗体全屏显示:
- winform 、WPF传值方式详解
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【Java8新特性】02 函数式接口和Lambda表达式实战练习:环绕执行模式使行为参数化
- Go语言入门(三)数组和切片
- 一天一大 leet(回文数)难度:简单 DAY-10
- 如何使用docker搭建PHP环境
- Go语言入门(四)Map&函数
- 一天一大 leet(每日温度)难度:中等 DAY-11
- Go语言入门(五)结构体&练习
- 利用hexo和github或coding 搭免费个人博客
- window 指令之 tree
- Go语言入门(六)结构体后续&指针
- 一天一大 leet(二叉树的序列化与反序列化)难度:困难 DAY-16
- 一天一大 leet(三数之和)难度:中等 DAY-12
- MongoDB Docker版本:基础入门和复制集
- Django连接MySql使用models处理数据
- 一天一大 leet(爬楼梯)难度:简单 DAY-13