花椒直播Kong應用實踐

什麼是Kong

Kong 是面向現代架構(混合雲,混合組織)的下一代 API 網關平臺,具備雲原生、高性能,易用、可擴展等特性。nginx

適用於 Api Gateway, Kubernetes Ingress, Service Mesh Sidecar 等場景。sql

主要特性有:數據庫

  • 雲原生: 與平臺無關,Kong 能夠從裸機運行到 Kubernetes
  • 高性能 : 背靠非阻塞通訊的 nginx,性能自不用說
  • 插件機制 : 提供衆多開箱即用的插件,且有易於擴展的自定義插件接口,用戶可使用 Lua 自行開發插件
  • 熔斷:能夠經過插件實現熔斷,避免系統雪崩
  • 日誌: 能夠記錄經過 Kong 的 HTTP,TCP,UDP 請求和響應。
  • 鑑權: 權限控制,IP 黑白名單,一樣是 OpenResty 的特性
  • SSL: Setup a Specific SSL Certificate for an underlying service or API.
  • 監控: Kong 提供了實時監控插件
  • 認證: 如數支持 HMAC, JWT, Basic, OAuth 2.0 等經常使用協議
  • 限流:能夠經過插件實現單個服務某些接口的限流,避免服務過載致使不可用
  • REST API: 經過 Rest API 進行配置管理,從繁瑣的配置文件中解放
  • 健康檢查:自動檢查,被動檢查;節點不可用同步到全部的kong節點須要 1 - 2 秒
  • 動態路由:Kong 的背後是 OpenResty+Lua,因此從 OpenResty 繼承了動態路由的特性

爲何使用Kong

目前咱們須要解決的問題api

  1. 統一入口: 服務端微服務框架中,接口權限驗證,ip限制,限流等在各個服務中都單獨實現。沒有統一入口,不方便統一管理。
  2. 易用性,擴展性: 服務端技術棧主要是LNMP開發,目前在逐步轉型到基於Spring Boot、Spring Clound 微服務技術棧上開發。這是一個灰度遷移的過程,咱們須要Proxy能操做簡單,管理方便。
  3. 持續集成發佈: 互聯網 2C 產品,用戶無時不刻不在使用服務,同時產品還在不斷的迭代,服務每時每刻均可以發佈,因此必需要熱部署能力,而且是自動化的。可是基於Spring Boot的服務啓動 15 -30 秒,咱們須要 Kong 的藍綠髮布功能。

Kong 能夠完美的解決以上問題,解決方案以下:緩存

  1. 統一入口: 能夠做爲微服務統一入口,將限流,權限驗證,日誌,ip 限制等統一實現

avatar

  1. 易用性,擴展性: 提供了Restful操做方式,而且有dashboard管理工具bash

    # 建立一個名稱 hello 的 upstream
    curl -X POST http://localhost:8001/upstreams --data "name=hello"
    
    # 爲 hello 添加兩個負載均衡節點
    curl -X POST http://localhost:8001/upstreams/hello/targets --data "target=localhost:8080" --data "weight=100"
    
    curl -X POST http://localhost:8001/upstreams/hello/targets --data "target=localhost:8081" --data "weight=100"
    
    # 配置一個service
    curl -X POST http://localhost:8001/services --data "name=hello" --data "host=hello"
    
    # 爲service 配置路由
    curl -X POST http://localhost:8001/routes --data "paths[]=/hello" --data "service.id={$service.id 配置上面service返回的}"
    複製代碼

    dashboard工具截圖架構

    avatar

  2. 持續集成發佈: 與 GitLab CI/CD 配合,代碼提交代碼庫後,自動打包,運行測試用例,藍綠部署。 app

    avatar

咱們如何使用Kong

當前使用 Kong 架構圖 負載均衡

avatar

Kong集羣
  1. 全部節點鏈接到數據中心框架

    • 使用 Postgresql 主從機制,保證數據庫高可用,注意使用9.6以上版本
  2. 全部節點將週期性執行任務,同步數據最終一致

    • 配置選項:db_update_frequency (默認: 5 秒)
    • 每 db_update_frequency 秒,全部節點將從數據庫中拉取全部更新,若是有同步到更新變化,將清理本地相關緩存。
    • 若是 Postgresql 數據庫異常,節點使用原有數據還能夠提供服務
  3. 節點有本地緩存,能夠設置緩存過時時間

    • 配置選項:db_cache_ttl (default: 0s)
    • 當數據中心異常,依賴本地緩存依舊能夠提供服務
  4. 支持動態擴容,參考上方架構圖,Kong集羣在Lvs後面

    • 新增節點,同步其餘節點配置後,驗證正常,加到到Lvs的RS裏便可,就提供服務了
    • 刪除節點,直接將 Lvs 的 RS 刪除便可,他就不提供服務了
    • 修改節點配置,先從 Lvs 後摘除kong RS, 修改完成後重啓,驗證正常,放回到 Lvs 的 RS 裏面
  5. 支持 gRPC

    # /etc/kong/kong.conf
    proxy_listen = 0.0.0.0:8000, 0.0.0.0:8443 ssl, 0.0.0.0:9080 http2
    複製代碼
  6. 服務監控

    • 使用prometheus,grafana和Kong自然配合
      avatar

注意事項

  1. kong/templates/nginx_kong.lua 模板文件統一
  2. 對於kong日誌要作好切割,咱們使用 logrotate
Kong插件
  • kong的插件功能不少其內置了不少包括認證,限流,日誌等相關插件,固然也能夠自定義插件,加載成功後就能夠在這個界面進行添加使用

avatar

  • 不一樣的插件有不一樣的參數,須要進行設定,設定完成後就會啓用

    例如:這是內置的 key-auth 插件,做用是進行api認證,設定 key 以後只有認證經過的才能訪問

  • 自定義開發和部署,根據業務須要開發插件

    基本流程

    1. 下載模板

    base簡單版

    simple-plugin
    ├── handler.lua
    └── schema.lua
    複製代碼

    advanced高級版

    complete-plugin
    ├── api.lua
    ├── daos.lua
    ├── handler.lua
    ├── migrations
    │   ├── cassandra.lua
    │   └── postgres.lua
    └── schema.lua
    複製代碼

    必要文件就是 handler.lua 和 schema.lua

    1. 修改 handler.lua 文件,有不少函數,自定義邏輯就是在這些函數中寫

      kong會在一些特定階段調用對應的函數

    local BasePlugin = require "kong.plugins.base_plugin"
    
    -- The actual logic is implemented in those modules
    local access = require "kong.plugins.my-custom-plugin.access"
    local body_filter = require "kong.plugins.my-custom-plugin.body_filter"
    
    local CustomHandler = BasePlugin:extend()
    
    function CustomHandler:new()
        CustomHandler.super.new(self, "my-custom-plugin")
    end
    
    function CustomHandler:access(config)
        CustomHandler.super.access(self)
    
        -- Execute any function from the module loaded in `access`,
        -- for example, `execute()` and passing it the plugin's configuration. access.execute(config) end function CustomHandler:body_filter(config) CustomHandler.super.body_filter(self) -- Execute any function from the module loaded in `body_filter`, -- for example, `execute()` and passing it the plugin's configuration.
        body_filter.execute(config)
    end
    
    return CustomHandler
    
    複製代碼
    1. 修改 schema.lua 文件,主要是配置一些參數,以及參數檢查
    return {
        no_consumer = true, -- this plugin will only be applied to Services or Routes,
        fields = {
            -- Describe your plugin's configuration's schema here.
        },
        self_check = function(schema, plugin_t, dao, is_updating)
            -- perform any custom verification
            return true
        end
    }
    複製代碼
    1. 配置部署

      插件文件在

      /data/kong/plugins/simple-plugin/
      複製代碼

      則配置kong.conf

      lua_package_path = /data/?.lua;($default);
      plugins = bundled,simple-plugin
      複製代碼

      而後從新reload kong 若是lua插件沒有錯誤,就能夠在後臺看到加載出來了

線上碰到問題
  1. 返回的內容太大,須要加大 buffer(upstream response cache error) 修改配置

    nginx_proxy_proxy_buffer_size=128k
    nginx_proxy_proxy_buffers=4 256k
    nginx_proxy_proxy_busy_buffers_size=256k
    複製代碼
  2. 須要注意配置屬性

    • strip_path 屬性
    若是設置爲 true, paths 設置有值,那麼請求將會被替換掉
    { "paths": ["/service"], "strip_path": true, "service": { "id": "..." }}
    請求:GET /service/path/to/resource HTTP/1.1Host: …
    Proxy: GET /path/to/resource HTTP/1.1
    
    { "paths": ["/version/\d+/service"], "strip_path": true, "service": { "id": "..." }
    請求:GET /version/1/service/path/to/resource HTTP/1.1
    Proxy: GET /path/to/resource HTTP/1.1
    複製代碼
    • preserve_host屬性
    若是設置爲 true,代理後仍然保留 header 請求 host
    請求:GET / HTTP/1.1Host: service.com
    Proxy: GET / HTTP/1.1Host: service.com
    
    設置爲false,將不保留header host
    GET / HTTP/1.1Host: service.com
    GET / HTTP/1.1Host: <my-service-host.com>
    複製代碼

總結

Kong 是行業內較爲成熟的網關開源產品,不管是性能,易用,擴展方面都表現不錯。

Kong 就是服務治理的翅膀,能夠更優雅,更便捷,更智能的實現服務降級,熔斷,流量調度等工做。

讓咱們在自建 Kunernetes 私有云,Hulk雲,阿里雲等複雜的架構中任意翱翔。

相關文章
相關標籤/搜索