本文講述 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