使用Kong做爲APIGateway

爲何須要 API 網關

Kong與舊架構對比

在微服務架構之下,服務被拆的很是零散,下降了耦合度的同時也給服務的統一管理增長了難度。如上圖左所示,在舊的服務治理體系之下,鑑權,限流,日誌,監控等通用功能須要在每一個服務中單獨實現,這使得系統維護者沒有一個全局的視圖來統一管理這些功能。API 網關致力於解決的問題即是爲微服務納管這些通用的功能,在此基礎上提升系統的可擴展性。如右圖所示,微服務搭配上 API 網關,可使得服務自己更專一於本身的領域,很好地對服務調用者和服務提供者作了隔離。nginx

爲何是 Kong

Kong 的插件機制是其高可擴展性的根源,Kong 能夠很方便地爲路由和服務提供各類插件,網關所須要的基本特性,Kong 都如數支持:git

  • Cloud-Native 雲原生: 與平臺無關,Kong能夠從裸機運行到Kubernetes
  • Dynamic Load Balancing 動態路由:Kong 的背後是 OpenResty+Lua,因此從 OpenResty 繼承了動態路由的特性
  • Circuit-Breaker 熔斷
  • Health Checks 健康檢查
  • Logging 日誌: 能夠記錄經過 Kong 的 HTTP,TCP,UDP 請求和響應。
  • Security 鑑權: 權限控制,IP 黑白名單,一樣是 OpenResty 的特性
  • SSL: Setup a Specific SSL Certificate for an underlying service or API.
  • 監控: Kong 提供了實時監控插件
  • 認證: 如數支持 HMAC, JWT, Basic, OAuth2.0 等經常使用協議
  • Rate-limiting限流:Block and throttle requests based on many variables.
  • REST API: 經過 Rest API 進行配置管理,從繁瑣的配置文件中解放
  • 可用性: 自然支持分佈式
  • 高性能: 背靠非阻塞通訊的 nginx,性能自不用說
  • Plugins 插件機制: 提供衆多開箱即用的插件,且有易於擴展的自定義插件接口,用戶可使用 Lua 自行開發插件

上面這些特性中,反覆說起了 Kong 背後的 OpenResty,實際上,使用 Kong 以後,Nginx 能夠徹底摒棄,Kong 的功能是 Nginx 的父集。github

Kong 的架構

Version 0.14.1數據庫

|– kong
  |– api [admin管理接口的代碼]
    |– …
  |– cluster_events [集羣事件的數據訪問層代碼]
    |– …
  |– cmd [kong命令行的代碼]
    |– …
  |– dao [數據庫訪問層代碼]
    |– …
  |– plugins [插件的代碼]
    |– …
  |– templates [nginx配置文件模板]
    |– …
  |– tools [工具類代碼]
    |– …
  |– vendor [這裏提供了用於lua面向對象編程的基類]
    |– …
  |– cache.lua [緩存實現類,封裝了mlcache]
  |– cluster_events.lua [集羣事件同步代碼]
  |– conf_loader.lua [配置加載]
  |– constants.lua [常量定義]
  |– init.lua [kong的入口,能夠從這裏開始閱讀代碼]
  |– meta.lua [定義版本號之類]
  |– singletons.lua [單例模式,存放公共對象]
複製代碼

執行入口

/templates/nginx_kong.lua 中提供了一份示例配置:編程

init_by_lua_block {
    Kong = require 'kong'
    Kong.init()
}
init_worker_by_lua_block {
    Kong.init_worker()
}
upstream kong_upstream {
    server 0.0.0.1;
    balancer_by_lua_block {
        Kong.balancer()
    }
    keepalive 60;
}
server {
    server_name kong;
    listen 0.0.0.0:8000;
    error_page 400 404 408 411 412 413 414 417 494 /kong_error_handler;
    error_page 500 502 503 504 /kong_error_handler;
    ssl_certificate_by_lua_block {
        Kong.ssl_certificate()
    }
    location / {     
        rewrite_by_lua_block {
            kong.rewrite()
        }
        access_by_lua_block {
            kong.access()
        }
        header_filter_by_lua_block {
            kong.header_filter()
        }
        body_filter_by_lua_block {
            kong.body_filter()
        }
        log_by_lua_block {
            kong.log()
        }
    }

    location = /kong_error_handler {
        content_by_lua_block {
            Kong.handle_error()
        }
        header_filter_by_lua_block {
            Kong.header_filter()
        }
        body_filter_by_lua_block {
            Kong.body_filter()
        }
        log_by_lua_block {
            Kong.log()
        }
    }
}
複製代碼

ngx_lua 的 11 個用戶可介入階段

ngx_lua 的 11 個用戶可介入階段

Kong 入口

init.luaapi

local Kong = {}

-- init_by_lua_block
-- 用來完成耗時長的模塊加載
-- 或者初始化一些全局常量
function Kong.init()
end

-- init_worker_by_lua_block
-- 用於定時拉取配置/數據(啓動一些定時任務)
-- 有幾個Nginx工做進程就有幾個定時任務
function Kong.init_worker()
end

-- ssl_certificate_by_lua_block
-- 在Nginx和下游服務開始一個SSL握手時處理
function Kong.ssl_certificate()
end

-- balancer_by_lua_block
-- 上游服務器中的負載均衡器
function Kong.balancer()
end

-- rewrite_by_lua_block
-- 內部URL重寫或者外部重定向
function Kong.rewrite()
end

-- access_by_lua_block
-- 訪問控制
function Kong.access()
end

-- header_filter_by_lua_block
-- 設置響應頭
function Kong.header_filter()
end

-- body_filter_by_lua_block
-- 對響應數據進行過濾
function Kong.body_filter()
end

-- log_by_lua_block
-- 使用Lua處理日誌
function Kong.log()
end

-- content_by_lua_block
function Kong.handle_error()
end

-- content_by_lua_block
function Kong.serve_admin_api(options)
end

return Kong
複製代碼

推薦閱讀

Kong源碼導讀--拍拍貸團隊緩存

有贊API網關實踐--有贊網關bash

相關文章
相關標籤/搜索