本文讲述 OpenResty api网关设计,主要涉及api网关介绍、openresty api网关 请求路由(路由判断、路由重写、服务判断、限流)、受权验证(统一认证)、动态Upstream 以及这三部分理论简单实现的Api网关和Api网关admin。html
一、什么是api网关nginx
在这个微服务这么火的时代,随之api网关经常被提到。咱们知道在微服务架构风格中,一个大应用被拆分红为了多个小的服务并提供 Rest Api 风格的接口来被 H5, Android, IOS 应用调用,由api网统一关管理这些接口的方方面面,那么什么才是api网关?git
百度上针对于 API 网关有以下介绍: github
API网关是一个服务器,是系统的惟一入口。从面向对象设计的角度看,它与外观模式相似。API网关封装了系统内部架构,为每一个客户端提供一个定制的API。它可能还具备其它职责,如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理。 API网关方式的核心要点是,全部的客户端和消费端都经过统一的网关接入微服务,在网关层处理全部的非业务功能。一般,网关也是提供REST/HTTP的访问API。服务端经过API-GW注册和管理服务。json
二、OpenResty api网关api
OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建可以处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
缓存
OpenResty 经过汇聚各类设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可使用 Lua 脚本语言调动 Nginx 支持的各类 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发链接的高性能 Web 应用系统。
服务器
开发api网关使用到的 OpenResty 一个重要知识:OpenResty 对于一个请求的处理流程。Nginx 把一个请求分为不一样的阶段,从而让第三方模块经过挂载行为在不一样的阶段来定制本身的行为;OpenResty 拥有一样的特性,不过在不一样阶段挂载的是 Lua 脚本。restful
在不一样的阶段直接完成大部分典型处理了。架构
set_by_lua: 流程分之处理判断变量初始化
rewrite_by_lua: 转发、重定向、缓存等功能(例如特定请求代理到外网)
access_by_lua: IP准入、接口权限等状况集中处理(例如配合iptable完成简单防火墙)
content_by_lua: 内容生成
header_filter_by_lua: 应答HTTP过滤处理(例如添加头部信息)
body_filter_by_lua: 应答BODY过滤处理(例如完成应答内容统一成大写)
log_by_lua: 回话完成后本地异步完成日志记录(日志能够记录在本地,还能够同步到其余机器)
那么咱们能够开始的api网关设计了:
init_by_lua_block 加载路由信息、服务信息到lua_shared_dict。
init_worker_by_lua_block 持久化经过apiadmin新增或者修改的路由、服务信息到磁盘、服务健康检查。
rewrite_by_lua_block 根据url规则匹配路由信息和服务信息并赋值到ngx上下文
access_by_lua_block 进行统一受权
opengate_upstream 经过ngx上下文的url服务信息经过ngx_balancer.set_current_peer对服务进行转发。
adminapi 提供路由、服务信息管理restful接口
示例代码以下:
lua_shared_dict url_dict 5m; lua_shared_dict balancer_dict 5m; init_by_lua_block { opengate = require 'opengate.openpoint' opengate.init() } init_worker_by_lua_block{ opengate.cofigsync() opengate.heathcheck() } upstream opengate_upstream { server 0.0.0.1; balancer_by_lua_block { opengate.balancer() } keepalive 60; } server { listen 443 http2 ssl default_server; server_name _; ssl on; ssl_certificate server.crt; ssl_certificate_key server.key; location / { default_type application/json; rewrite_by_lua_block { opengate.rewrite() } access_by_lua_block { opengate.access() } proxy_pass http://opengate_upstream; proxy_intercept_errors on; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } error_page 404 /404.html; location = /404.html { root html; } } server { listen 8800; server_name _; location / { default_type application/json; content_by_lua_block { opengate.adminapi() } } location /robots.txt { return 200 'User-agent: *\nDisallow: /'; } }
经过如上咱们就实现一个简单的api网关。
最后推荐下github上一个开源的openresty大做 https://github.com/Kong/kong