分类目录归档:开发语言

使用C语言的7个步骤

  1. 定义程序的目标
  2. 设计程序
  3. 编写代码
  4. 编译
  5. 运行程序
  6. 测试和调试程序
  7. 维护和修改程序

openResty中ngx.shared.DICT的用法

ngx_lua 提供了一系列共享内存相关的 API (ngx.shared.DICT),可以很方便地通过设置过期时间来使得缓存被动过期,值得一提的是,当缓存的容量超过预先申请的内存池大小的时候,ngx.shared.DICT.set 方法则会尝试以 LRU 的形式淘汰一部分内容。

继续阅读

openResty中cosocket的控制

cosocket 是 OpenResty 世界中技术、实用价值最高的部分。让我们可以用非常低廉的成本,优雅的姿势,比传统 socket 编程效率高好几倍的方式进行网络编程。无论资源占用、执行效率、并发数等都非常出色。

cosocket = coroutine + socket
coroutine:协同程序(后面简称:协程)
socket:网络套接字

继续阅读

openResty中获取请求 body

在 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中正则表达式的使用

在 OpenResty 中,同时存在两套正则表达式规范:Lua 语言的规范和 Nginx 的规范;即使您对 Lua 语言中的规范非常熟悉,我们仍不建议使用 Lua 中的正则表达式。

  1. 因为 Lua 中正则表达式的性能并不如 Nginx 中的正则表达式优秀;
  2. Lua 中的正则表达式并不符合 POSIX 规范,而 Nginx 中实现的是标准的 POSIX 规范,后者明显更具备通用性。

继续阅读

openResty中的ngx.location.capture和ngx.location.capture_multi的使用

在openResty中,ngx.location.capture_multi是一个非常强大的功能。可以应用于并发多个相互之间没有依赖的请求。在现代的应用架构中经常使用微服务,提供低粒度的接口;但在客户端(例如:app、网页服务)经常需要请求多个微服务接口,才能完整显示页面内容。

例如:打开一个商品详情页,需要请求:

  1. banner广告接口;
  2. 商品详情;
  3. 商品评论等。

那么ngx.location.capture_multi就派上大用场了,当然使用ngx.location.capture_multi不是唯一的办法,呵呵~。下面就来看看这个东东的用法;

继续阅读

openResty中ngx_lua模块提供的API

ngx_lua模块的原理:

  1. 每个worker(工作进程)创建一个Lua VM,worker内所有协程共享VM;
  2. 将Nginx I/O原语封装后注入 Lua VM,允许Lua代码直接访问;
  3. 每个外部请求都由一个Lua协程处理,协程之间数据隔离;
  4. Lua代码调用I/O操作等异步接口时,会挂起当前协程(并保护上下文数据),而不阻塞worker;
  5. I/O等异步操作完成时还原相关协程上下文数据,并继续运行

系列文章:
指令:openResty中ngx_lua模块提供的指令
常量:openResty中ngx_lua模块提供的常量
API:openResty中ngx_lua模块提供的API

继续阅读

openResty中ngx_lua模块提供的常量

ngx_lua模块的原理:

  1. 每个worker(工作进程)创建一个Lua VM,worker内所有协程共享VM;
  2. 将Nginx I/O原语封装后注入 Lua VM,允许Lua代码直接访问;
  3. 每个外部请求都由一个Lua协程处理,协程之间数据隔离;
  4. Lua代码调用I/O操作等异步接口时,会挂起当前协程(并保护上下文数据),而不阻塞worker;
  5. I/O等异步操作完成时还原相关协程上下文数据,并继续运行

系列文章:
指令:openResty中ngx_lua模块提供的指令
常量:openResty中ngx_lua模块提供的常量
API:openResty中ngx_lua模块提供的API

继续阅读

openResty中ngx_lua模块提供的指令

ngx_lua模块的原理:

  1. 每个worker(工作进程)创建一个Lua VM,worker内所有协程共享VM;
  2. 将Nginx I/O原语封装后注入 Lua VM,允许Lua代码直接访问;
  3. 每个外部请求都由一个Lua协程处理,协程之间数据隔离;
  4. Lua代码调用I/O操作等异步接口时,会挂起当前协程(并保护上下文数据),而不阻塞worker;
  5. I/O等异步操作完成时还原相关协程上下文数据,并继续运行

系列文章:
指令:openResty中ngx_lua模块提供的指令
常量:openResty中ngx_lua模块提供的常量
API:openResty中ngx_lua模块提供的API

继续阅读

openResty学习中的知识点(一)

1、变量申明后,默认的值是nil;将 nil 赋给变量后,相当于删除变量。注意nil 和 ngx.null的区别。

2、在 lua中只有 false和 nil 值为 false ,其他值都为 true ,包括0,””等

3、lua中的数字(一切数字)都是 number类型。

4、table 的下标从 1 开始。

5、逻辑运算法 and 、or 、not的用法。

继续阅读

微信小程序的app.json配置

app.json文件用来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。下面对app.json文件进行逐个分析:

Tips : 该文件时一个json文件,故不支持注释

继续阅读

Go中的net/url包学习笔记

GO中的net/url包,实现对URL的处理。

1、对URL进行编码和解码

func QueryEscape(s string) string
QueryEscape函数对s进行转码使之可以安全的用在URL查询里。

func QueryUnescape(s string) (string, error)
QueryUnescape函数用于将QueryEscape转码的字符串还原。它会把%AB改为字节0xAB,将’+’改为’ ‘。如果有某个%后面未跟两个十六进制数字,本函数会返回错误。

继续阅读

Go中net包中的方法

本文章是学习Go中net包的一篇笔记,记录 net 包的一些方法的使用。

 1、func SplitHostPort(hostport string) (host, port string, err error)

函数将格式为”host:port”、”[host]:port”或”[ipv6-host%zone]:port”的网络地址分割为host或ipv6-host%zone和port两个部分。

继续阅读

如何优雅地关闭Go channel

几天前,我写了一篇文章来说明golang中channel的使用规范。在reddit和HN,那篇文章收到了很多赞同,但是我也收到了下面几个关于Go channel设计和规范的批评:

  1. 在不能更改channel状态的情况下,没有简单普遍的方式来检查channel是否已经关闭了
  2. 关闭已经关闭的channel会导致panic,所以在closer(关闭者)不知道channel是否已经关闭的情况下去关闭channel是很危险的
  3. 发送值到已经关闭的channel会导致panic,所以如果sender(发送者)在不知道channel是否已经关闭的情况下去向channel发送值是很危险的

继续阅读

Goroutine和channel的详细理解(二)

  • Go语言的并发和并行

不知道你有没有注意到一个现象,还是这段代码,如果我跑在两个goroutines里面的话:

var quit chan int = make(chan int)
func loop() {
    for i := 0; i < 10; i++ {
        fmt.Printf("%d ", i)
    }
    quit <- 0
}
func main() {
    go loop()   // 开两个goroutine跑函数loop, loop函数负责打印10个数
    go loop()
    for i := 0; i < 2; i++ {
        <- quit
    }
}

继续阅读

Goroutine和channel的详细理解(一)

如果不是我对真正并行的线程的追求,就不会认识到Go有多么的迷人。

Go语言从语言层面上就支持了并发,这与其他语言大不一样,不像以前我们要用Thread库 来新建线程,还要用线程安全的队列库来共享数据。

以下是我入门的学习笔记。

继续阅读

Go新建文件权限与设置不符

问题:

fileName := "/Users/my/tests/perm_file"
f, _ := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
f.Close()

上述代码是打开一个文件,如果文件不存在则创建一个新文件,同时权限设置为0666(-rw-rw-rw-),但实际生成的文件权限可能与你认为的不一致:

继续阅读