lua-web快速开发指南6-CacheDB介绍

"数据库"与"缓存"的基本概念数据库与缓存是服务端开发人员的必学知识点. 数据库"数据库"是一种信息记录、存取的虚拟标记地点的集合统称. 比如现实生活中, 我们经常会用到文件柜、书桌等等数据存取容器. 在对容器进行数据存取的时候, 我们会为每一层打上一个标签表示一种分类项. 而这种在数据库中划分子分类形成了表的概念. 这就是我们通常所说的结构化数据库. 由于通常数据表之间可能会存在依赖关系, 某一(或者多)层通常可能会用于同一种用途. 这种用途将一层划分为索引表, 二层划分为分类表, 三层划分为数据表. 实现这种功能与依赖关系的数据库, 我们称之为: 关系型数据库. 它可以定义一套规范并且建立数据存取模型, 这样方便维护一整套结构化的数据信息. 每当我们需要对数据进行结构化操作(查询、增加、删除、修改)的时候, 需要在计算机中用一种通俗易懂的语言表达方式来进行助记. 这种结构化查询语言称之为SQL. 缓存我们通常将数据存储完毕后, 能通过指定或特定的一(多)种方式对数据进行操作. 在项目开发的初期, 这并没有太大的问题. 但是随着数据量的不断增大, 在数据库的内存中已经放不下这么多数据. 我们的数据逐渐无法被加载到内存中: 只会在使用的时候才会进行(随机)读取. 而这会加大磁盘I/O. 我们知道通常磁盘的读写速度基本上会比内存读写慢几个数量级(即使是SSD), 大量请求可能瞬间将磁盘IO占满并出现数据库的CPU利用率低、内存频繁进行修改/置换等问题. 为了解决这些问题, 出现了很多解决方案: 读、写分离、分表分库等等. 虽然有了这些方案, 但是也同样回引来新的问题: 主从同步、分布式事务等问题. "缓存"则是近十年兴起的概念, 它的本质是一份数据结构化存储在内存中的副本. 高级的缓存我们也可以将其称之为内存数据库或NOSQL(非关系型)数据库. "缓存"也是一种"另类"解决数据库问题点一种手段! 它通过丰富的数据结构扩展了数据模型的组合能力, 通过简单的使用方法与高效的连接方式提供更好数据操作方式. "缓存"将查询、更新较为频繁的热数据组成一个集合加载进内存中, 较少使用的冷数据序列化到磁盘内部. 高效利用内存的同时, 根据变化的情况合理更新、删除缓存. 这样的方式配合数据库都读、写分离与数据分区将数据合理的从一个数据集副本分散到多个数据集副本, 有效的减少性能问题点产生并且提升了整个业务系统的横向扩展能. DB库DB库是cf框架封装自MySQL 4.1协议实现的客户端连接库, 提供MySQL断线重连、SQL重试、连接池等高级特性. CacheCache库是cf封装自Redis 2.0协议实现的客户端连接库, 提供Redis断线重连、命令重试、连接池等高级特性. API学习1. DB API在使用下面的API之前, 请先确保已经导入库: local DB = require "DB". 1.1 DB:new(opts)opts表的参数决定如何连接到MySQL, 表属性如下: ...

June 16, 2019 · 2 min · jiezi

lua-web快速开发指南5-利用template库构建httpd模板引擎

介绍template模板引擎是为了使用户界面与业务数据(内容)分离而产生的, 其本身并不是一种深奥的技术. template模板引擎首先会将合法的模板编译为lua函数, 然后将模板文件和数据通过模板引擎生成一份HTML代码. cf的admin库整使使用了template来构建服务端渲染页面, 并利用单页面+iframe模式快速完成lua后台开发. 1. template基础语法在真正使用之前, 我们先来学习一下template常见的一些基本语法: {{ lua expression }} - lua expression是一段lua表达式; 作用为输出表达式的结果, 一些特殊符号将会被转义;{* lua expression *} - lua expression是一段lua表达式; 作用为输出表达式的结果, 不会转义任何符号;{% lua code %} - 执行一段lua代码, 如: {% for i = x, y do %} ... {% end %};{# comments #}- comments仅作为注释, 不会包含在输出字符串内. 这段语法的作用类似lua内的--与--[[]];{(template)} - 导入其它模板文件; 同时支持传参: {(file.html, { message = "Hello, World" })};2. 转义字符& 将会转义为 &amp;< 将会转义为 &lt;> 将会转义为 &gt;" 将会转义为 &quot;' 将会转义为 &#39;/ 将会转义为 &#47;3. APItemplate.compile(html)参数html为字符串类型, 可以是:模板文件路径、 ...

June 14, 2019 · 2 min · jiezi

lua-web快速开发指南4-详细了解httpd库的作用

httpd库是基于HTTP 1.1协议实现而来, 内置了高性能的http协议解析器与urldecode解析库. httpd库默认情况下就能工作的很好, 但是在一些需求较为极端的场景还是需要微调一下参数. httpd常用的内置方法介绍1. httpd:timeout(number)设置每个连接到最大空闲(idle)连接等待时间, 超过这个数值httpd将主动断开连接. (默认值为:30秒) 2. httpd:max_path_size(number)设置Path的最大长度, 超过这个值httpd将会返回414. (默认值为: 1024) 3. httpd:max_header_size(number)设置Header最大长度, 超过这个值httpd将会返回431. (默认值为: 65535) 4. httpd:max_body_size(number)设置Body的最大长度, 超过这个值将会返回413. (默认为 1024 * 1024) 5. httpd:before(function)before方法决定API与USE路由回调在触发之前的行为, 默认情况下允许所有路由通过. before方法一般用来设置与修改用户验证路由行为(例如头部验证), 这提供了开发者基于before函数设计中间件的机会. 当开发者设置了function后(即是是一个空函数), 需要利用http库来决定行为. 6. httpd:group(type, prefix, handles)group方法提供了一种批量注册路由的方式, 为一组同一组路由提供简单便方便在注册方法. 第一个参数type为需要批量注册的路由类型; 初始化httpd对象后, 使用app.USE或app.API进行传值; 第二个参数prefix为string类型的头部; 例如:/api、/admin; 第三个参数为一组路由处理函数或处理类数组; 类型为: {route = '/login', class = class}; 注意: 此方法仅支持批量注册API与USE路由, 不可同时注册不同类型路由; 7. httpd:static(folder, ttl)listen方法用于告诉httpd对象监听指定端口. 第一个参数ip暂未被httpd使用(但是必须设置), 默认监听所有网卡的'0.0.0.0'地址与指定的端口号; backlog为用户最大连接等待队列, 合理的设置能减少连接被重置的情况(默认值为128). 8. httpd:run()在httpd库所有参数与路由设置完毕之后, 调用run方法开启监听模式. httpd的请求日志日志格式为: [年/月/日 时:分:秒] - [ip] - [x-real-ip] - [path] - [method] - [http code] - [request handle timeline] ...

June 14, 2019 · 1 min · jiezi

lua-web快速开发指南3-初识httpd库路由

本章假设您已经知道httpd server如何快速搭建, 并且知道cf的启动流程与运行流程, 知晓httpd如何创建与启动. 回顾上一章节-- script/main.lualocal httpd = require "httpd"local app = httpd:new("app")app:static("static", 30)app:listen("0.0.0.0", 8080)app:run()我们利用httpd内置库快速实现了一套httpd静态文件server, 其中包括静态文件目录指定与端口设置. 并且在启动server后可以在看到测试页面. 什么是"路由"与"路由表"?Web路由用于描述资源到处理函数之间的一个映射关系. Web路由表用于描述当前作用域下所有路由的一个集合. 如下所示: /userlogin -> function userlogin(content) ... end/userinfo -> function userinfo(content) ... end对于一个服务端开发者来说! 当接受到客户端的HTTP请求时, 服务端会将请求URL中的PATH进行分割, 然后开始寻找的PATH映射对应的回调处理函数. 当URL映射的回调处理函数被找到时, 将会为其注入整个http上下文并且根据处理函数的行为将返回值展现给资源访问者. 这就是基本的路由雏形. cf中的各种路由cf的httpd库利用这种机制, 为开发者提供了一整套完整的路由注册方法, 其中包括: 静态文件路由、API接口路由、USE页面路由、WebSocket路由. 静态文件路由我们在上一章节已经看到过, 其本质是根据需要读取指定文件而存在的. 这种路由一般有库编写者或者框架编写者实现. 而API接口路由、USE页面路由、Websocket路由则一般由开发自行指定, 这些路由一般都用来处理对应的业务逻辑. 下面我们就开始学习如何在cf中注册路由. 注册API与USE路由1. API路由API接口路由用于快速构建前、后端分离的web开发场景. 它提供了基于http协议提供了基础的前、后端通讯的解决方案, 是目前位置Web领域最为常见的开发模式. 而作为前、后端数据沟通的桥梁自然需要指定指定数据交互类型. 目前为止, API路由的content-type为"application/json", 数据交互格式仅支持: json. httpd库为开发者提供了app:api方法用来注册API路由, 第一个参数是一个字符串类型的资源路径, 第二个参数则是回调处理方法; 现在让我们在main.lua中, 添加我们刚刚学习到的api路由: -- main.lualocal json = require "json"app:api('/userinfo', function(content) return json.encode({ code = 200, user = { name = "CandyMi", age = 29, sex = "男", } })end)然后打开浏览器, 输入http://localhost:8080/userinfo. 我们就可以看到我们输出的接口数据了. ...

June 14, 2019 · 1 min · jiezi