问题的起源:在电商等业务中,系统一般由多个独立的服务组成,如何解决分布式调用时候数据的一致性?
具体业务场景如下,比如一个业务操作,如果同时调用服务 A、B、C,需要满足要么同时成功;要么同时失败。 A、B、C 可能是多个不同部门开发、部署在不同服务器上的远程服务。
在分布式系统来说,如果不想牺牲一致性,CAP 理论告诉我们只能放弃可用性,这显然不能接受。为了便于讨论问题,先简单介绍下数据一致性的基础理论。
问题的起源:在电商等业务中,系统一般由多个独立的服务组成,如何解决分布式调用时候数据的一致性?
具体业务场景如下,比如一个业务操作,如果同时调用服务 A、B、C,需要满足要么同时成功;要么同时失败。 A、B、C 可能是多个不同部门开发、部署在不同服务器上的远程服务。
在分布式系统来说,如果不想牺牲一致性,CAP 理论告诉我们只能放弃可用性,这显然不能接受。为了便于讨论问题,先简单介绍下数据一致性的基础理论。
这里主要介绍几种常见的架构设计理论和原则,常见于大中型互联系统架构设计。
著名的CAP理论是由Brewer提出的,所谓CAP,即一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)。
在传统的RDBMS中,事务具有ACID4个属性,即原子性(Atomicity),一致性(Consistency),隔离性(Isolation)和持久性(Durable)。
如何针对当前需求,选择合适的应用架构,如何面向未来,保证架构平滑过渡,这个是软件开发者,特别是架构师,都需要深入思考的问题。
无架构,不系统,架构是大型系统的关键。从形上看,架构是系统的骨架,支撑和链接各个部分;从神上看,架构是系统的灵魂,深刻体现业务本质。
架构可细分为业务架构、应用架构、技术架构,业务架构是战略,应用架构是战术,技术架构是装备。其中应用架构承上启下,一方面承接业务架构的落地,另一方面影响技术选型。
float 和 double 的范围是由指数的位数来决定的。
float 的指数位有8位,而 double 的指数位有11位,分布如下:
float:
1bit(符号位) | 8bits(指数位) | 23bits(尾数位) |
double:
1bit(符号位) | 11bits(指数位) | 52bits(尾数位) |
ngx_lua 提供了一系列共享内存相关的 API (ngx.shared.DICT),可以很方便地通过设置过期时间来使得缓存被动过期,值得一提的是,当缓存的容量超过预先申请的内存池大小的时候,ngx.shared.DICT.set 方法则会尝试以 LRU 的形式淘汰一部分内容。
cosocket 是 OpenResty 世界中技术、实用价值最高的部分。让我们可以用非常低廉的成本,优雅的姿势,比传统 socket 编程效率高好几倍的方式进行网络编程。无论资源占用、执行效率、并发数等都非常出色。
cosocket = coroutine + socket coroutine:协同程序(后面简称:协程) socket:网络套接字
在 Nginx 的典型应用场景中,几乎都是只读取 HTTP 头即可,例如负载均衡、正反向代理等场景。但是对于 API Server 或者 Web Application ,对 body 可以说就比较敏感了。
由于 OpenResty 基于 Nginx ,所以天然的对请求 body 的读取细节与其他成熟 Web 框架有些不同。在lua代码中使用 ngx.req.read_body 函数 (或打开 lua_need_request_body 选项强制本模块读取请求体,此方法不推荐)才可以获取到请求 body。究其原因,主要是 Nginx 诞生之初主要是为了解决负载均衡情况,而这种情况,是不需要读取 body 就可以决定负载策略的。
由于 Nginx 是为了解决负载均衡场景诞生的,所以它默认是不读取 body 的行为,会对 API Server 和 Web Application 场景造成一些影响。根据需要正确读取、丢弃 body 对 OpenResty 开发是至关重要的。
在 OpenResty 中,同时存在两套正则表达式规范:Lua 语言的规范和 Nginx 的规范;即使您对 Lua 语言中的规范非常熟悉,我们仍不建议使用 Lua 中的正则表达式。
在openResty中,ngx.location.capture_multi是一个非常强大的功能。可以应用于并发多个相互之间没有依赖的请求。在现代的应用架构中经常使用微服务,提供低粒度的接口;但在客户端(例如:app、网页服务)经常需要请求多个微服务接口,才能完整显示页面内容。
例如:打开一个商品详情页,需要请求:
那么ngx.location.capture_multi就派上大用场了,当然使用ngx.location.capture_multi不是唯一的办法,呵呵~。下面就来看看这个东东的用法;
ngx_lua模块的原理:
系列文章:
指令:openResty中ngx_lua模块提供的指令
常量:openResty中ngx_lua模块提供的常量
API:openResty中ngx_lua模块提供的API
ngx_lua模块的原理:
系列文章:
指令:openResty中ngx_lua模块提供的指令
常量:openResty中ngx_lua模块提供的常量
API:openResty中ngx_lua模块提供的API
ngx_lua模块的原理:
系列文章:
指令:openResty中ngx_lua模块提供的指令
常量:openResty中ngx_lua模块提供的常量
API:openResty中ngx_lua模块提供的API
1、变量申明后,默认的值是nil;将 nil 赋给变量后,相当于删除变量。注意nil 和 ngx.null的区别。
2、在 lua中只有 false和 nil 值为 false ,其他值都为 true ,包括0,””等
3、lua中的数字(一切数字)都是 number类型。
4、table 的下标从 1 开始。
5、逻辑运算法 and 、or 、not的用法。
openResty是nginx的luaJit的扩展,所在在安装openResty的过程中,安装的选项配置包括openResty的自有配置和继承的nginx配置。
openResty的安装参考:openResty的安装、启动、停止与重启
在解压openResty的源码安装包后,使用 ./configure –help 即可看到所有的安装配置选项,如下:
官方源码:https://github.com/kr/beanstalkd
中文协议:https://github.com/kr/beanstalkd/blob/master/doc/protocol.zh-CN.md
如果要使用Beanstalkd,请务必熟读《中文协议》,并注意一些细节。
Beanstalk协议使用ASCII编码,运行在TCP协议之上。客户端负责主动建立连接,发送命令和数据,等待响应以及关闭连接。对于每个连接,服务端以接收请求的顺序串行地处理命令,并按相同的顺序发送响应。协议中所有的数字都是十进制并且非负的(除非有明确说明)。
协议中的名字都是ASCII字符串。名字可以包含字母(A-Z和a-z)、 数字(0-9)、连字符(”-“)、 加(”+”)、 斜线(”/”)、 分号(”;”)、 点(”.”)、 美元符号(”$”)、下划线(”_”)和括号(“(”和”)”),但是不能以连字符开头。名字以空格或换行结束。每个名字至少要有一个字符的长度。