apisix源码分析-减少对对象的访问 ctx 缓存(9)

apisix源码分析-减少对对象的访问 ctx 缓存(9)

ctx

apisix/core/ctx

用来缓存 ngx.var 的信息。

  1. set_vars_meta(ctx)

    创建了一个名为 ctx_var 的 tablepool

    包含了两个 table 对象 
    
    • _cache
    • _request 这里 request 缓存了 resty.ngxvar.request 的对象

    ctx.var = var

  2. release_var(ctx)

    释放 ctx_var 对象

用到了库 resty.ngxvar 利用 ffi 的方式实现了取 ngx.var 的值,相比直接去值性能提高了5倍。

导出了两个函数

1
2
local get_var      = require("resty.ngxvar").fetch   
local get_request = require("resty.ngxvar").request

request 是 local get_request = require("resty.core.base").get_request

看看 fetch 的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function _M.fetch(name, request)
-- 从 vars 获取值,var 实现了 ffi 获取 uri host remote_addr request_time scheme upstream_response_time 等
local method = vars[name]

-- 未实现的直接从 ngx_var 取值
if not var_patched or not method then
if num_type[name] then
return tonumber(ngx_var[name])
elseif ups_num_type[name] then
return sum_upstream_num(ngx_var[name])
end

return ngx_var[name]
end

return method(request)
end
  1. local mt 的 __index 重写了去值方式。

    直接取值,如果_cache (也就是第一步里面创建的_cache)存在,直接返回。

    这里 key 做了一些预定义

    • cookie 开头的,返回 cookie
    • arg 开头的返回 request.get_uri_args 的值
    • post_arg 返回 request.get_post_args 的值
    • http 开头返回 ngx.var 的值。
    • graphql 开头返回 graphql 的值。
    • 否则 返回 ngx.ctx.api_ctx 的值 或者 ngx.var 的值

    _newinex 设置缓存。

高性能的原因

1. 使用 ffi 的方式优化去值性能  


2. 通过维护缓存,减少多次取值。 

apisix源码分析-减少对对象的访问 ctx 缓存(9)

https://beixiu.net/apisix-source-9/

作者

张巍

发布于

2023-08-24

更新于

2023-08-24

许可协议

评论