言简意赅的讲解Kong解决的痛点
在微服务和API网关盛行的时代,对HTTP请求的路由、负载均衡、代理和服务发现的需求愈加明显。Nginx作为高性能HTTP服务器和反向代理服务器已久负盛名,而Kong则是基于Nginx(和OpenResty)构建的API网关解决方案,通过插件系统和Admin API为开发者提供了更灵活、易扩展的方式。之前给大家讲解了Nginx和如何实现域名解析,今天来说说Kong与Nginx的对比。
本文将从多方面对比Kong和Nginx,以帮助你在项目中进行技术选型时做出更明智的决定。
核心区别概览
特性 | Nginx | Kong |
---|---|---|
核心定位 | 高性能HTTP服务器、反向代理、负载均衡 | API网关、服务治理、可观测性、身份认证和权限控制 |
配置方式 | 通过静态配置文件(nginx.conf)或Lua脚本 | 提供RESTful Admin API、数据库(Postgres、Cassandra)存储配置、插件配置 |
可扩展性 | 通过Lua脚本(需OpenResty)、第三方模块或编译 | 丰富插件系统,可通过Admin API在线热更新配置与插件,无需重启 |
学习曲线 | 简单(但高级功能需要了解配置指令与Lua脚本) | 相对复杂(需理解API网关模式、插件机制、数据库schema) |
生态支持 | 社区广泛、成熟稳定、运维经验丰富 | 官方提供大量插件(认证、速率限制、日志、指标收集)、Kong Enterprise有企业支持 |
性能对比 | 原生Nginx性能极高 | 性能接近Nginx,但会因插件处理和数据库交互略有开销 |
部署灵活性 | 传统安装、Docker、Kubernetes Ingress Controller | 原生支持Kubernetes、提供Helm chart和Operator、Docker下易集成Admin与DB |
管理方式 | 修改配置文件后reload | 通过Admin API动态管理,无需重启服务 |
Kong 安装部署成功
使用场景差异
-
传统反向代理与静态文件服务:
如果你的场景主要是静态文件托管、基础的反向代理和负载均衡,那么Nginx简洁且性能优越,无需额外数据库和插件系统复杂度。 -
复杂的API网关场景:
如果你需要对API请求进行认证、访问控制、速率限制、JWT鉴权、SSL终止、请求变更、日志与指标收集、A/B测试、金丝雀发布等高级治理场景,那么Kong自带的插件系统和Admin API配置显然是更合适的选择。
配置方式示例对比
Nginx 配置示例
Nginx主要通过nginx.conf
配置文件定义虚拟主机、上下文、反向代理规则。以下是一个简单的Nginx反向代理配置示例:
# nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
upstream backend_servers {
server backend1:8080;
server backend2:8080;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
上例中,当配置或后端服务器更新时,你需要对Nginx进行nginx -s reload
重载。没有内置的在线API来动态管理配置。
Kong 配置示例
Kong的配置则可以通过Admin API实时更新。例如,在运行Kong的容器中,你可以直接通过HTTP请求添加服务和路由,而无需修改静态配置文件和重载。
# 添加一个服务
curl -X POST http://localhost:8001/services \
--data name=my_service \
--data url='http://backend1:8080'
# 为服务添加路由
curl -X POST http://localhost:8001/services/my_service/routes \
--data paths[]=/ \
--data hosts[]=example.com
# 添加一个插件(例如限速插件)
curl -X POST http://localhost:8001/services/my_service/plugins \
--data name=rate-limiting \
--data config.minute=100 \
--data config.policy=local
这些更改会立即生效,无需重启Kong。
Docker-Compose 样例环境
下面是一个使用docker-compose
快速搭建Kong和Nginx环境的示例。该环境包含:
- 一个Postgres数据库(为Kong存储配置使用)
- Kong本身
- Kong Admin API(通过8001端口访问)
- Kong代理网关(通过8000端口访问)
- 一个示例后端服务(简单的Node.js Express应用或者Nginx容器)
- 一个独立的Nginx作为对照服务
docker-compose.yml 示例
version: '3.8'
services:
postgres:
image: postgres:13
environment:
POSTGRES_USER: kong
POSTGRES_PASSWORD: kong
POSTGRES_DB: kong
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U kong -d kong"]
interval: 5s
timeout: 5s
retries: 5
kong-migrations:
image: kong:3.3
command: kong migrations bootstrap
depends_on:
- postgres
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: postgres
KONG_PG_USER: kong
KONG_PG_PASSWORD: kong
KONG_CASSANDRA_CONTACT_POINTS: postgres
restart: on-failure
kong:
image: kong:3.3
depends_on:
- postgres
- kong-migrations
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: postgres
KONG_PG_USER: kong
KONG_PG_PASSWORD: kong
KONG_PROXY_LISTEN: "0.0.0.0:8000"
KONG_ADMIN_LISTEN: "0.0.0.0:8001"
ports:
- "8000:8000"
- "8001:8001"
# 示例后端服务,这里用一个简单的Nginx作为后端
backend1:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./backend-html:/usr/share/nginx/html:ro
# 独立的Nginx作为对照
standalone-nginx:
image: nginx:alpine
ports:
- "8081:80"
volumes:
- ./standalone-html:/usr/share/nginx/html:ro
在上述docker-compose.yml
中:
postgres
用于存储Kong的配置数据。kong-migrations
用于初始化Kong的数据库schema。kong
容器运行了Kong本身。backend1
是一个简单的Nginx后端,Kong将会代理到它。standalone-nginx
是一个独立Nginx实例用于对照测试。
后端示例文件结构
./backend-html/
index.html # 用于backend1的简单测试页面
./standalone-html/
index.html # standalone Nginx使用的静态页面
启动:
docker-compose up -d
然后通过Kong Admin API配置路由:
# 创建Service指向backend1
curl -X POST http://localhost:8001/services --data name=backend_service --data url='http://backend1:80'
curl -X POST http://localhost:8001/services/backend_service/routes --data paths[]=/backend
# 测试访问
curl http://localhost:8000/backend
如上,访问http://localhost:8000/backend
时,Kong将请求转发到backend1
,无需修改Kong配置文件,只需HTTP调用Admin API即可完成动态配置。
可扩展性与插件系统示例
-
Nginx的Lua扩展:
如果你需要在Nginx中增加一些自定义逻辑,需要借助OpenResty(将Nginx打包成可编写Lua脚本的发行版)。如下是一个Nginx Lua脚本的示例:# nginx.conf (with OpenResty) http { server { listen 80; location /lua { content_by_lua_block { ngx.say("Hello from Lua!") } } } }
要修改逻辑,需要编辑nginx.conf或相关Lua文件,然后reload Nginx。
-
Kong的插件:
Kong可以使用现有官方或社区插件,也可以使用自定义插件(Lua代码)。例如,你可以轻松加载一个身份验证插件:# 给service启用key-auth插件 curl -X POST http://localhost:8001/services/backend_service/plugins \ --data name=key-auth # 添加consumer curl -X POST http://localhost:8001/consumers \ --data username=demo_user # 为consumer创建认证凭证 curl -X POST http://localhost:8001/consumers/demo_user/key-auth \ --data key=my-api-key
通过为请求携带
apikey
进行访问验证:curl -X GET http://localhost:8000/backend -H "apikey: my-api-key"
上述逻辑全部通过API动态实现,无需重启或更改静态配置文件。
性能与监控
- Nginx:性能优秀,广泛用于CDN、边缘代理等场景。Nginx的监控可通过
stub_status
模块或第三方工具实现。 - Kong:相对Nginx,Kong的性能接近但有额外的插件处理开销。Kong内置Prometheus插件、Zipkin插件等用于指标和分布式追踪,提供更完整的服务网格监控方案。
Kong启用Prometheus插件示例:
# 为全局启用Prometheus插件
curl -X POST http://localhost:8001/plugins \
--data name=prometheus
# 现在可访问 http://localhost:8001/metrics 获取Kong指标
总结
- Nginx:适合用于静态文件服务、反向代理、负载均衡等传统场景,配置方式简单直观,但动态更新和扩展灵活性稍弱,需要reload配置文件,插件化能力(Lua)需借助OpenResty。
- Kong:适合需要快速迭代、动态更新配置、需要丰富认证和限流等网关功能的API场景,提供完善的插件系统和Admin API,无需重启即可更新配置,适合构建API管理平台和服务治理体系。
在你的应用场景中,如果你更关注性能和简单,那么Nginx或许足够;如果你需要更复杂的API管理和可扩展性,那么Kong将是更好的选择。
通过上述内容,你就已经基本理解了这个方法,基础用法我也都有展示。如果你能融会贯通,我相信你会很强
Best
Wenhao (楠博万)