动态插件

之前已经拆解细点逐个介绍了 tcp 、http 代理相关核心点,现在介绍一个让 api gateway 变得很灵活的功能实现: 动态插件。

由于 lua 的动态语言特点,我们可以比较方便做到动态插件机制。

首先我们来了解这一切的基石:lua 模块加载机制。

lua 模块加载机制

一个模块是什么样?

例如: xxxmodule.lua 文件内容

local module = {} -- 注意不要使用全局变量,会造成变量污染,导致无法卸载模块

-- 定义一个函数
function module.func1()
io.write("这是一个公有函数!\n")
end return module

如何加载模块?

Lua提供了一个名为require的函数用来加载模块。要加载一个模块,只需要简单地调用就可以了。例如:

local a = require("xxxmodule")
a.func1() -- "这是一个公有函数!\n"

到底是怎么工作的呢?

require 函数会在模块path列表搜索模块,openresty可以指定如下两种:

lua 库: lua_package_path "./?.lua;/usr/local/openresty/luajit/share/luajit-2.1.0-beta3/?.lua;";

c 库: lua_package_cpath "./?.so;/usr/local/lib/lua/5.1/?.so;";

找到模块文件之后,就会解析执行整个文件的内容(类似函数 loadstring),由于最后是return 模块变量,我们就可以使用这个变量的函数等等一切了

如果开启了 lua_code_cache on, require 函数会将第二步拿到的变量存在 package.loaded 这个table 中,达到缓存效果

那么如何卸载呢?

非常简单,只需一句:

package.loaded['xxxmodule'] = nil

所以基于lua的模块管理,我们就可以非常容易实现插件模块的管理

lua severless function simple demo

所以我们可以基于这样的动态机制,实现 lua severless function 或者动态插件机制,示例如下:

http {
default_type application/json;
lua_code_cache on; lua_package_path "$prefix/deps/share/lua/5.1/?.lua;$prefix/deps/share/lua/5.1/?/init.lua;$prefix/src/?.lua;$prefix/src/?/init.lua;;./?.lua;/usr/local/openresty/luajit/share/luajit-2.1.0-beta3/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/openresty/luajit/share/lua/5.1/?.lua;/usr/local/openresty/luajit/share/lua/5.1/?/init.lua;";
lua_package_cpath "$prefix/deps/lib64/lua/5.1/?.so;$prefix/deps/lib/lua/5.1/?.so;;./?.so;/usr/local/lib/lua/5.1/?.so;/usr/local/openresty/luajit/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall.so;"; # 简单模拟模块
init_by_lua_block {
MockPackages = {}
}
server {
listen 8222;
server_name localhost; location /add { # 比如替换为 request body 去做模块创建,这里为了简单就用写死的代码来模拟
# 内容为通过 loadstring 转换 lua code 字符串为函数
# 并将函数结果 当前时间存在全局变量中
access_by_lua_block {
local lua_src = [[
ngx.update_time()
return tostring(ngx.now())
]]
local f, e = loadstring(lua_src, "module xxxmodule")
MockPackages['xxxmodule'] = f()
ngx.say('add function success')
}
} location /run { # 这里获取缓存结果并输出出来
access_by_lua_block {
if MockPackages['xxxmodule'] then
ngx.say(MockPackages['xxxmodule'])
else
ngx.say('no function')
end
}
}
}
}

启动并测试

mkdir -p logs && /usr/bin/openresty -p ./ -c nginx.conf -g 'daemon off;'

call http://127.0.0.1:8222/run return no function

call http://127.0.0.1:8222/add return add function success

call http://127.0.0.1:8222/run return 1624022896.703

call http://127.0.0.1:8222/add return add function success

call http://127.0.0.1:8222/run return 1624022918.674

可以看到值已经被改变了

这种severless function demo的问题

  • 管理以及定位问题

    实际环境会有很多机器实例,对应的severless function 在哪几台机器哪几个nginx中的哪些worker 进程上加载,加载多久, 需要完整规划方案

  • 资源隔离

    所有的severless function 其实都是在worker内, 所以内存cpu等于是共享,一个特耗性能的代码必然影响其他

  • 安全问题

    由于多个函数会同在一个worker 进程,无论性能和资源都会收到相互影响 别人可以在其中轻松加入恶意代码

所以如果在公用的api gateway中,大家还是不要把它当成云计算中的 severless function 使用,只是当成一个 动态filter function 就好。

目录

构建api gateway之 动态插件的更多相关文章

  1. [转载] 构建微服务:使用API Gateway

    原文: http://mp.weixin.qq.com/s?__biz=MzA5OTAyNzQ2OA==&mid=206889381&idx=1&sn=478ccb35294c ...

  2. 0601-Zuul构建API Gateway-API gateway简介、基础使用、路由配置、负载配置

    一.API Gateway简介 参看:http://www.cnblogs.com/bjlhx/p/8794437.html 二.zuul简介[路由器和过滤器:Zuul] 在微服务架构的组成部分进行路 ...

  3. 谈谈微服务中的 API 网关(API Gateway)

    前言 又是很久没写博客了,最近一段时间换了新工作,比较忙,所以没有抽出来太多的时间写给关注我的粉丝写一些干货了,就有人问我怎么最近没有更新博客了,在这里给大家抱歉. 那么,在本篇文章中,我们就一起来探 ...

  4. 微服务中的 API 网关(API Gateway)

    API 网关(API Gateway)提供高性能.高可用的 API 托管服务,帮助用户对外开放其部署在 ECS.容器服务等云产品上的应用,提供完整的 API 发布.管理.维护生命周期管理.用户只需进行 ...

  5. API Gateway微服务

    微服务中的 API 网关(API Gateway)   前言 又是很久没写博客了,最近一段时间换了新工作,比较忙,所以没有抽出来太多的时间写给关注我的粉丝写一些干货了,就有人问我怎么最近没有更新博客了 ...

  6. 服务中的 API 网关(API Gateway)

    我们知道在微服务架构风格中,一个大应用被拆分成为了多个小的服务系统提供出来,这些小的系统他们可以自成体系,也就是说这些小系统可以拥有自己的数据库,框架甚至语言等,这些小系统通常以提供 Rest Api ...

  7. Amazon API Gateway Importer整合过程小结

    (1)需要将swagger json转换成amazon api gateway 所需要的格式(根据Method Request中 Request PathsURL Query String Param ...

  8. Qwiklab'实验-API Gateway, AWS Lambda'

    title: AWS之Qwiklab subtitle: 2. Qwiklab'实验-API Gateway, AWS Lambda' date: 2018-09-20 17:29:20 --- In ...

  9. 几种部署Goku API Gateway的方式,最快一分钟可使用上网关

    本文将介绍几种部署Goku API Gateway的方式,最快一分钟可使用上为网关,详情请看全文. 什么是Goku API Gateway? Goku API Gateway (中文名:悟空 API ...

  10. 详解API Gateway流控实现,揭开ROMA平台高性能秒级流控的技术细节

    摘要:ROMA平台的核心系统ROMA Connect源自华为流程IT的集成平台,在华为内部有超过15年的企业业务集成经验. 本文分享自华为云社区<ROMA集成关键技术(1)-API流控技术详解& ...

随机推荐

  1. 从 WinDbg 角度理解 .NET7 的AOT玩法

    一:背景 1.讲故事 前几天 B 站上有位朋友让我从高级调试的角度来解读下 .NET7 新出来的 AOT,毕竟这东西是新的,所以这一篇我就简单摸索一下. 二:AOT 的几个问题 1. 如何在 .NET ...

  2. Go语言核心36讲30

    你好,我是郝林,今天我继续分享条件变量sync.Cond的内容.我们紧接着上一篇的内容进行知识扩展. 问题 1:条件变量的Wait方法做了什么? 在了解了条件变量的使用方式之后,你可能会有这么几个疑问 ...

  3. rpm环境安装dpkg包管理工具

    rpm环境安装dpkg包管理工具 索引:dpkg-scanpackages.dpkg.dpkg-query.dpkg-source.dpkg-scansource 在centos.redhat.麒麟服 ...

  4. variant conversion error for variable:v8

    oracle 添加表数据报错:variant conversion error for variable:v8. 是数据类型不匹配.

  5. MybatisPlus多表连接查询一对多分页查询数据

    一.序言 在日常一线开发过程中,多表连接查询不可或缺,基于MybatisPlus多表连接查询究竟该如何实现,本文将带你找到答案. 在多表连接查询中,既有查询单条记录的情况,又有列表查询,还有分页查询, ...

  6. 2.9:数据交换-csv、Excel、json、爬虫、Tushare获取数据

    〇.任务 1. 使用Python基础文件读写函数完成CSV文件的处理: 2. 使用标准CSV库完成CSV文件的处理: 3. 使用Excel库完成Excel文件的处理: 4. Python数据结构和Js ...

  7. 推荐一款 在线+离线数据 同步框架 Dotmim.Sync

    移动智能应用可以分为在线模式.纯离线模式与"在线+离线"混合模式.在线模式下系统数据一般存储在服务器端的大中型数据库(如 SQL Server.Oracle.MySQL 等),移动 ...

  8. pycharm 小技巧

    ctrl键 + B 查看定义源代码 alt键 + enter键 查看帮助 ctrl键 + shift键 + -号 所有代码隐藏 ctrl键 + shift键 + +号 所有代码展示 ctrl键 + D ...

  9. Redis——02 学习

    Redis--02 前面了解了 Redis 以及在 Linux 的安装,下面了解一些 Redis 常用的命令. Redis 常用命令: Redis 是 Key-Value 形式,Key 为字符串类型, ...

  10. P1314 聪明的质监员(题解)

    题目 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 \(n\) 个矿石,从 \(1\) 到 \(n\) 逐一编号,每个矿石都有自己的重量 \(w_i\) 以及价值 \(v_i\) ...