使用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

相关文章
相关标签/搜索