ActiveRecord 也属于 ORM(对象关系映射)层,由 Rails
最早提出,遵循标准的 ORM
模型:表映射到记录,记录映射到对象,字段映射到对象属性。配合遵循的命名和配置惯例,能够很大程度的快速实现模型的操作,而且简洁易懂。
ActiveRecord 的主要思想是:
每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表的一行记录;通常表的每个字段在类中都有相应的
Field;
ActiveRecord 同时负责把自己持久化,在 ActiveRecord
中封装了对数据库的访问,即 CURD;;
ActiveRecord 是一种领域模型(Domain Model),封装了部分业务逻辑;
ActiveRecord 比较适用于:
业务逻辑比较简单,当你的类基本上和数据库中的表一一对应时,
ActiveRecord 是非常方便的,即你的业务逻辑大多数是对单表操作;
当发生跨表的操作时, 往往会配合使用事务脚本(Transaction
Script),把跨表事务提升到事务脚本中;
ActiveRecord 最大优点是简单, 直观。
一个类就包括了数据访问和业务逻辑. ...
Neo4j 简介
Neo4j 是一个高性能的 NOSQL
图形数据库,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的
Java
持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。Neo4j
也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。程序员工作在一个面向对象的、灵活的网络结构下,而不是严格、静态的表中。但是他们可以享受到具备完全的事务特性、企业级的数据库的所有好处。Neo4j
因其嵌入式、高性能、轻量级等优势,越来越受到关注。
现实中很多数据都是用图来表达的,比如社交网络中人与人的关系、地图数据、或是基因信息等等。RDBMS
并不适合表达这类数据,而且由于海量数据的存在,让其显得捉襟见肘。NoSQL
数据库的兴起,很好地解决了海量数据的存放问题,图数据库也是 NoSQL
的一个分支,相比于 NoSQL
中的其他分支,它很适合用来原生表达图结构的数据。
通常来说,一个图数据库存储的结构就如同数据结构中的图,由顶点和边组成。
Neo4j 是图数据库中一个主要代表,其开源,且用 Java 实现(需安装
J ...
提到
SaaS,很多人都会立刻想到节约成本、按需付费、即租即用等等这些概念,这说明大部分人对
SaaS 已经有了普遍认知,且开始主动应用 SaaS
软件。然而这只是一些浅层概念。很多人对于一些 SaaS
技术问题还是知之甚少,例如企业在进行 SaaS
企业管理软件选型时,仍不了解“多租户”与“单租户”是什么意思,二者之间的区别更是一头雾水。企业管理者需要明白这两种
SaaS
架构的特点,才能更多地从未来的功能需求、数据安全等方面进行考虑,从而选出适合企业应用的
SaaS 软件。
本文将通过举例,形象深刻解释“SaaS 多租户和单租户有什么分别”。
一、多租户 SaaS 架构
小 A、小 B、小 C
大学毕业后,一起同租了一套三室两厅的房子。三个人都拥有自己独立的房间,且每个房间都有配有一把钥匙,保证三个人独立的空间私密性。如果其他人要进入别人的房间,就需要拥有配套房间的钥匙进行开锁。而客厅、餐厅、厨房等属于公共区域,三人共同享有这些资源。
这里小 A、小 B、小 C 就属于应用 SaaS
多租户解决方案的企业实体。应用运行在同一个或同一组服务商(即三个人同租一套房子,厨房、餐厅、客厅 ...
背景
随着互联网、大数据、云计算、人工智能、物联网、区块链等一系列技术创新与行业服务的加速融合,行业产品创新能力正在不断提升,数字化、智能化不断催生新兴的服务模式和新产品,已成为企业数字化转型升级的新方向。
企业用户采购 API
网关作为企业自身数字化转型的一环,为后续持续转型和升级做铺垫,逐步向“全面云化”、“分布式化”、“智能化”、“开放化”的新技术体系演进。云原生
API 网关 Apache APISIX,可以完美的助力企业完成 API
管理和微服务架构转型。此外基于开源 APISIX 还有 k8s Ingress Controller 和
Service Mesh 产品,企业用户后续升级到 Kubernetes
和服务网格,提供统一、顺滑的过渡方案。底层技术栈的统一,极大降低学习、管理维护成本。
同时,在云原生架构下,开源 +
购买商业支持的方式是首选,这不仅仅保证企业自身不被具体商业公司锁定,更重要的是,可以让企业保持快速的技术升级,以便让技术满足产品的迭代,
最终在竞争中取得优势。
APISIX 是 Apache
基金会的顶级项目,同时也在云原生软件基金会(CNCF)的全景 ...
wrk 是一个非常棒的 HTTP 压力测试工具,构建在 Redis、NGINX、Node.js 和
LuaJIT 这几个开源项目的基础之上,充分利用了他们在事件驱动、HTTP
解析、高性能和灵活性方面的优点,并且可以自己写 Lua
脚本来生成测试请求。
虽然 wrk
没有测试案例,并且作者大概一年现身一次来合并代码,但这些并不妨碍我们把
wrk 作为性能测试和 fuzz 测试的首选工具。如果你还在使用多线程的
ab,那么非常值得尝试下 wrk。
下面是 wrk 结果中的延时分布统计部分:
123456789Latency Distribution 50% 1.20ms 75% 595.78ms 90% 899.11ms 99% 1.00s
这个示例是指,50% 的请求在 1.2ms 内完成,90% 的请求在 899 ms
内完成,99% 的请求在 1s 内完成。
我们在使用 wrk 压力测试自己产品的时候,发现 wrk
统计的延时结果中,大部分请求都是几毫秒内完成,但有一小部分请求的延时会超过
100 毫秒。 对于用 OpenResty
构建的系统,出现 ...
Apache APISIX 和 Kong 都是开源的微服务 API
网关,那么在这两者之间,如何去做比较和选择呢?
这两个项目都有完善的文档和测试来覆盖,也有不少的生产用户在使用,所以不用去担心稳定性和它们的可持续发展,本文会从功能和性能这两个最直接和可验证的角度去做下对比。
功能
从 API 网关核心功能点来看,两者均已覆盖:
功能
Apache APISIX
KONG
动态上游
支持
支持
动态路由
支持
支持
健康检查和熔断器
支持
支持
动态 SSL 证书
支持
支持
七层和四层代理
支持
支持
分布式追踪
支持
支持
自定义插件
支持
支持
REST API
支持
支持
CLI
支持
支持
更详细的比较:
功能
Apache APISIX
KONG
项目归属
Apache 软件基金会
Kong Inc.
技术架构
Nginx + etcd
Nginx + postgres
交流渠道
微信群、QQ 群、邮件列表、GitHub、meetup
GitHub、论坛、freenode
单核 QPS (开启限流和 prometheus 插件)
18000
1700
平均延迟
0.2 毫 ...
Apache APISIX 是一个很年轻的项目,2019 年 6 月份开源,7 月份加入到
CNCF 全景图,10 月份进入 Apache 孵化器,所以我会和大家分享一下 APISIX
是如何从 0 到 1,进入 Apache 孵化器的。
Apache APISIX 现在有 17 个 committer,分别来自 16
家不同的公司,是一个非常社区化的项目。每个 committer
有一票,决定版本的发布、选举新的 committer 和 PPMC
等比较重大的事情。
Apache Way
Apache Way 是大家都比较熟悉的概念:社区大于代码。烂代码可以改,Apache
的导师并不会指导你怎么写出更高水平的代码,他们更关心的是社区是否在健康的发展,只要有一个好的社区,烂代码一定会有更高水平的人进行重构,变成更好的代码。所以只要社区在,那这个项目就能够一直存活下去,这在
Apache 是最重要的。
邮件列表优先是另一个重要的点,没有在邮件列表中出现过的,就当做不存在。这在中国其实是一个非常大的挑战,大家在文化上和习惯上都不太喜欢用邮件:第一是时间不够及时,可能发一封邮件后隔
1-2 ...
wctype.h
wctype.h 提供 ctype.h 里面函数的宽字符版本。
宽字符类型判断函数
下面函数判断宽字符的类型。
iswalnum() 测试宽字符是否为字母数字
iswalpha() 测试宽字符是否为字母
iswblank() 测试这是否是一个宽空白字符
iswcntrl() 测试这是否是一个宽控制字符。
iswdigit() 测试这个宽字符是否是数字
iswgraph() 测试宽字符是否是可打印的非空格字符
iswlower() 测试宽字符是否为小写
iswprint() 测试宽字符是否可打印
iswpunct() 测试宽字符是否为标点符号
iswspace() 测试宽字符是否为空格
iswupper() 测试宽字符是否为大写
iswxdigit() 测试宽字符是否为十六进制数字
wctype(),iswctype()
iswctype()是上一节各种宽字符类型判断函数的通用版本,必须与wctype()配合使用。
1int iswctype(wint_t wc, wctype_t desc);
iswctype()接受两个参数,第一个参数是一个需要判断类型的宽字 ...
wchar.h
宽字符使用两个或四个字节表示一个字符,导致 C
语言常规的字符处理函数都会失效。wchar.h
定义了许多宽字符专用的处理函数。
类型别名和宏
wchar.h 定义了一个类型别名 wint_t,表示宽字符对应整数值。
wchar.h 还定义了一个宏 WEOF,表示文件结束字符 EOF 的宽字符版。
btowc(),wctob()
btowc()将单字节字符转换为宽字符,wctob()将宽字符转换为单字节字符。
12wint_t btowc(int c);int wctob(wint_t c);
btowc()返回一个宽字符。如果参数是
EOF,或转换失败,则返回 WEOF。
wctob()返回一个单字节字符。如果参数是
WEOF,或者参数宽字符无法对应单个的单字节字符,则返回 EOF。
下面是用法示例。
123456789wint_t wc = btowc('B'); // 输出宽字符 Bwprintf(L"Wide character: %lc\n", wc);unsigned char c = wctob(wc);// 输出 ...
time.h
time_t
time_t 是一个表示时间的类型别名,可以视为国际标准时
UTC。它可能是浮点数,也可能是整数,Unix 系统一般是整数。
许多系统上,time_t 表示自时间纪元(time epoch)以来的秒数。Unix
的时间纪元是国际标准时 UTC 的1970年1月1日的零分零秒。time_t
如果为负数,则表示时间纪元之前的时间。
time_t
一般是32位或64位整数类型的别名,具体类型取决于当前系统。如果是32位带符号整数,time_t
可以表示的时间到 2038年1月19日03:14:07 UTC
为止;如果是32位无符号整数,则表示到2106年。如果是64位带符号整数,可以表示-2930亿年到+2930亿年的时间范围。
struct tm
struct tm
是一个数据结构,用来保存时间的各个组成部分,比如小时、分钟、秒、日、月、年等。下面是它的结构。
1234567891011struct tm { int tm_sec; // 秒数 [0, 60] int tm_min; // 分钟 [0, 59] int tm_hour ...