开源API网关,到底哪个强?

cpus: ‘1’

memory: 256M

reservations:

memory: 256M

K6 通过 Nginx 网关的测试结果如下:

图片

每秒处理的请求数量是 1093,和不通过网关转发相比非常接近。

从功能上看,Nginx 可以满足用户对于 API 网关的大部分需求,可以通过配置和插件的方式来支持不同的功能,性能非常优秀。

缺点是没有管理的 UI 和管理 API,大部分的工作都需要手工配置 config 文件的方式来进行。商业版本的功能会更加完善。

Kong

====

Kong 是基于 NGINX 和 OpenResty 的开源 API 网关。

Kong 的总体基础结构由三个主要部分组成:NGINX 提供协议实现和工作进程管理,OpenResty 提供 Lua 集成并挂钩到 NGINX 的请求处理阶段。

而 Kong 本身利用这些挂钩来路由和转换请求。数据库支持 Cassandra 或 Postgres 存储所有配置。

图片

Kong 附带各种插件,提供访问控制,安全性,缓存和文档等功能。它还允许使用 Lua 语言编写和使用自定义插件。

Kong 也可以部署为 Kubernetes Ingress 并支持 GRPC 和 WebSockets 代理。

NGINX 提供了强大的 HTTP 服务器基础结构。它处理 HTTP 请求处理,TLS 加密,请求日志记录和操作系统资源分配(例如,侦听和管理客户端连接以及产生新进程)。

NGINX 具有一个声明性配置文件,该文件位于其主机操作系统的文件系统中。

虽然仅通过 NGINX 配置就可以实现某些 Kong 功能(例如,基于请求的 URL 确定上游请求路由),但修改该配置需要一定级别的操作系统访问权限,以编辑配置文件并要求 NGINX 重新加载它们。

而 Kong 允许用户执行以下操作:通过 RESTful HTTP API 更新配置。Kong 的 NGINX 配置是相当基本的:除了配置标准标头,侦听端口和日志路径外,大多数配置都委托给 OpenResty。

在某些情况下,在 Kong 的旁边添加自己的 NGINX 配置非常有用,例如在 API 网关旁边提供静态网站。在这种情况下,您可以修改 Kong 使用的配置模板。

NGINX 处理的请求经过一系列阶段。NGINX 的许多功能(例如,使用 C 语言编写的模块)都提供了进入这些阶段的功能(例如,使用 gzip 压缩的功能)。

虽然可以编写自己的模块,但是每次添加或更新模块时都必须重新编译 NGINX。为了简化添加新功能的过程,Kong 使用了 OpenResty。

OpenResty 是一个软件套件,捆绑了 NGINX,一组模块,LuaJIT 和一组 Lua 库。

其中最主要的是 ngx_http_lua_module一个NGINX 模块,该模块嵌入 Lua 并为大多数 NGINX 请求阶段提供 Lua 等效项。

这有效地允许在 Lua 中开发 NGINX 模块,同时保持高性能(LuaJIT 相当快),并且 Kong 用它来提供其核心配置管理和插件管理基础结构。

Kong 通过其插件体系结构提供了一个框架,可以挂接到上述请求阶段。从上面的示例开始,Key Auth 和 ACL 插件都控制客户端(也称为使用者)是否应该能够发出请求。

每个插件都在其处理程序中定义了自己的访问函数,并且该函数针对通过给定路由或服务启用的每个插件执行 kong.access()。

执行顺序由优先级值决定,如果 Key Auth 的优先级为 1003,ACL 的优先级为 950,则 Kong 将首先执行 Key Auth 的访问功能,如果它不放弃请求,则将执行 ACL,然后再通过将该 ACL 传递给上游 proxy_pass。

由于 Kong 的请求路由和处理配置是通过其 admin API 控制的,因此可以在不编辑底层 NGINX 配置的情况下即时添加和删除插件配置。

因为 Kong 本质上提供了一种在 API 中注入位置块(通过 API 定义)和配置的方法。它们通过将插件,证书等分配给这些 API。

我们使用以下的配置部署 Kong 到容器中(省略四个微服务的部署):

version: ‘3.7’

volumes:

kong_data: {}

networks:

kong-net:

external: false

services:

kong:

image: “${KONG_DOCKER_TAG:-kong:latest}”

user: “${KONG_USER:-kong}”

depends_on:

- db

environment:

KONG_ADMIN_ACCESS_LOG: /dev/stdout

KONG_ADMIN_ERROR_LOG: /dev/stderr

KONG_ADMIN_LISTEN: ‘0.0.0.0:8001’

KONG_CASSANDRA_CONTACT_POINTS: db

KONG_DATABASE: postgres

KONG_PG_DATABASE: ${KONG_PG_DATABASE:-kong}

KONG_PG_HOST: db

KONG_PG_USER: ${KONG_PG_USER:-kong}

KONG_PROXY_ACCESS_LOG: /dev/stdout

KONG_PROXY_ERROR_LOG: /dev/stderr

KONG_PG_PASSWORD_FILE: /run/secrets/kong_postgres_password

secrets:

- kong_postgres_password

networks:

- kong-net

ports:

- “8080:8000/tcp”

- “127.0.0.1:8001:8001/tcp”

- “8443:8443/tcp”

- “127.0.0.1:8444:8444/tcp”

healthcheck:

test: [“CMD”, “kong”, “health”]

interval: 10s

timeout: 10s

retries: 10

restart: on-failure

deploy:

restart_policy:

condition: on-failure

db:

image: postgres:9.5

environment:

POSTGRES_DB: ${KONG_PG_DATABASE:-kong}

POSTGRES_USER: ${KONG_PG_USER:-kong}

POSTGRES_PASSWORD_FILE: /run/secrets/kong_postgres_password

secrets:

- kong_postgres_password

healthcheck:

test: [“CMD”, “pg_isready”, “-U”, “${KONG_PG_USER:-kong}”]

interval: 30s

timeout: 30s

retries: 3

restart: on-failure

deploy:

restart_policy:

condition: on-failure

stdin_open: true

tty: true

networks:

- kong-net

volumes:

- kong_data:/var/lib/postgresql/data

secrets:

kong_postgres_password:

file: ./POSTGRES_PASSWORD

数据库选择了 PostgreSQL,开源版本没有 Dashboard,我们使用 RestAPI 创建所有的网关路由:

curl -i -X POST http://localhost:8001/services \

–data name=goapi \

–data url=‘http://goapi:8080’

curl -i -X POST http://localhost:8001/services/goapi/routes \

–data ‘paths[]=/goapi’ \

–data name=goapi

需要先创建一个 service,然后在该 service 下创建一条路由。

使用 K6 压力测试的结果如下:

每秒请求数 705 要明显弱于 Nginx,所以所有的功能都是有成本的。

APISIX

======

Apache APISIX 是一个动态、实时、高性能的 API 网关, 提供负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。

APISIX 于 2019 年 4 月由中国的支流科技创建,于 6 月开源,并于同年 10 月进入 Apache 孵化器。

支流科技对应的商业化产品的名字叫 API7 。APISIX 旨在处理大量请求,并具有较低的二次开发门槛。

APISIX 的主要功能和特点有:

  • 云原生设计,轻巧且易于容器化。

  • 集成了统计和监视组件,例如 Prometheus,Apache Skywalking 和 Zipkin。

  • 支持 gRPC,Dubbo,WebSocket,MQTT 等代理协议,以及从 HTTP 到 gRPC 的协议转码,以适应各种情况。

  • 担当 OpenID 依赖方的角色,与 Auth0,Okta 和其他身份验证提供程序的服务连接。

  • 通过在运行时动态执行用户功能来支持无服务器,从而使网关的边缘节点更加灵活。

  • 支持插件热加载。

  • 不锁定用户,支持混合云部署架构。

  • 网关节点无状态,可以灵活扩展。

从这个角度来看,API 网关可以替代 Nginx 来处理南北流量,也可以扮演 Istio 控制平面和 Envoy 数据平面的角色来处理东西向流量。

APISIX 的架构如下图所示:

图片

APISIX 包含一个数据平面,用于动态控制请求流量;一个用于存储和同步网关数据配置的控制平面,一个用于协调插件的 AI 平面,以及对请求流量的实时分析和处理。

它构建在 Nginx 反向代理服务器和键值存储 etcd 的之上,以提供轻量级的网关。

它主要用 Lua 编写,Lua 是类似于 Python 的编程语言。它使用 Radix 树进行路由,并使用前缀树进行 IP 匹配。

使用 etcd 而不是关系数据库来存储配置可以使它更接近云原生,但是即使在任何服务器宕机的情况下,也可以确保整个网关系统的可用性。

所有组件都是作为插件编写的,因此其模块化设计意味着功能开发人员只需要关心自己的项目即可。

内置的插件包括流控和速度限制,身份认证,请求重写,URI 重定向,开放式跟踪和无服务器。

APISIX 支持 OpenResty 和 Tengine 运行环境,并且可以在 Kubernetes 的裸机上运行。它同时支持 X86 和 ARM64。

我们同样使用 Docker Compose 来部署 APISIX:

version: “3.7”

services:

apisix-dashboard:

image: apache/apisix-dashboard:2.4

restart: always

volumes:

- ./dashboard_conf/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml

ports:

- “9000:9000”

networks:

apisix:

ipv4_address: 172.18.5.18

apisix:

image: apache/apisix:2.3-alpine

restart: always

volumes:

- ./apisix_log:/usr/local/apisix/logs

- ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro

depends_on:

- etcd

##network_mode: host

ports:

- “8080:9080/tcp”

- “9443:9443/tcp”

networks:

apisix:

ipv4_address: 172.18.5.11

deploy:

resources:

limits:

cpus: ‘1’

memory: 256M

reservations:

memory: 256M

etcd:

image: bitnami/etcd:3.4.9

user: root

restart: always

volumes:

- ./etcd_data:/etcd_data

environment:

ETCD_DATA_DIR: /etcd_data

ETCD_ENABLE_V2: “true”

ALLOW_NONE_AUTHENTICATION: “yes”

ETCD_ADVERTISE_CLIENT_URLS: “http://0.0.0.0:2379”

ETCD_LISTEN_CLIENT_URLS: “http://0.0.0.0:2379”

ports:

- “2379:2379/tcp”

networks:

apisix:

ipv4_address: 172.18.5.10

networks:

apisix:

driver: bridge

ipam:

config:

- subnet: 172.18.0.0/16

开源的 APISIX 支持 Dashboard 的方式来管理路由,而不是像 KONG 把仪表盘功能限制在商业版本中。

但是 APISIX 的仪表盘不支持对路由 URI 进行改写,所以我们只好使用 RestAPI 来创建路由。

创建一个服务的路由的命令如下:

curl --location --request PUT ‘http://127.0.0.1:8080/apisix/admin/routes/1’ \

–header ‘X-API-KEY: edd1c9f034335f136f87ad84b625c8f1’ \

–header ‘Content-Type: text/plain’ \

–data-raw '{

“uri”: “/goapi/*”,

“plugins”: {

“proxy-rewrite”: {

“regex_uri”: [“^/goapi(.*)$”,“$1”]

}

},

“upstream”: {

“type”: “roundrobin”,

“nodes”: {

“goapi:8080”: 1

}

}

}’

使用 K6 压力测试的结果如下:

图片

APISix 取得了 1155 的好成绩,表现出接近不经过网关的性能,可能缓存起到了很好的效果。

Tyk

===

Tyk 是一款基于 Golang 和 Redis 构建的开源 API 网关。它于 2014 年创建,比 AWS 的 API 网关即服务功能早。Tyk 用 Golang 编写,并使用 Golang 自己的 HTTP 服务器。

Tyk 支持不同的运行方式:云,混合(在自己的基础架构中为 GW)和本地。

图片

Tyk 由 3 个组件组成:

  • 网关: 处理所有应用流量的代理。

  • 仪表板: 可以从中管理 Tyk,显示指标和组织 API 的界面。

  • Pump: 负责持久保存指标数据,并将其导出到 MongoDB(内置),ElasticSearch 或 InfluxDB 等。

我们同样使用 Docker Compose 来创建 Tyk 网关来进行功能验证。

version: ‘3.7’

services:

tyk-gateway:

image: tykio/tyk-gateway:v3.1.1

ports:

- 8080:8080

volumes:

- ./tyk.standalone.conf:/opt/tyk-gateway/tyk.conf

- ./apps:/opt/tyk-gateway/apps

- ./middleware:/opt/tyk-gateway/middleware

- ./certs:/opt/tyk-gateway/certs

environment:

- TYK_GW_SECRET=foo

depends_on:

- tyk-redis

tyk-redis:

image: redis:5.0-alpine

ports:

- 6379:6379

Tyk 的 Dashboard 也是属于商业版本的范畴,所我们又一次需要借助 API 来创建路由,Tyk 是通过 app 的概念来创建和管理路由的,你也可以直接写 app 文件。

curl --location --request POST ‘http://localhost:8080/tyk/apis/’ \

–header ‘x-tyk-authorization: foo’ \

–header ‘Content-Type: application/json’ \

–data-raw '{

“name”: “GO API”,

“slug”: “go-api”,

“api_id”: “goapi”,

“org_id”: “goapi”,

“use_keyless”: true,

“auth”: {

“auth_header_name”: “Authorization”

},

“definition”: {

“location”: “header”,

“key”: “x-api-version”

},

“version_data”: {

“not_versioned”: true,

“versions”: {

“Default”: {

“name”: “Default”,

“use_extended_paths”: true

}

}

},

“proxy”: {

“listen_path”: “/goapi/”,

“target_url”: “http://host.docker.internal:18000/”,

“strip_listen_path”: true

},

“active”: true

}’

使用 K6 压力测试的结果如下:

图片

Tyk 的结果在 400-600 左右,性能上和 KONG 接近。

Zuul

====

Zuul 是 Netflix 开源的基于 Java 的 API 网关组件。

图片

Zuul 包含多个组件:

  • zuul-core: 该库包含编译和执行过滤器的核心功能。

  • zuul-simple-webapp: 该 Webapp 展示了一个简单的示例,说明如何使用 zuul-core 构建应用程序。

  • zuul-netflix: 将其他 NetflixOSS 组件添加到 Zuul 的库,例如,使用 Ribbon 路由请求。

  • zuul-netflix-webapp: 将 zuul-core 和 zuul-netflix 打包到一个易于使用的程序包中的 webapp。

Zuul 提供了灵活性和弹性,部分是通过利用其他 Netflix OSS 组件进行的:

  • Hystrix 用于流控。包装对始发地的呼叫,这使我们可以在发生问题时丢弃流量并确定流量的优先级。

  • Ribbon 是来自 Zuul 的所有出站请求的客户,它提供有关网络性能和错误的详细信息,并处理软件负载平衡以实现均匀的负载分配。

  • Turbine 实时汇总细粒度的指标,以便我们可以快速观察问题并做出反应。

  • Archaius 处理配置并提供动态更改属性的能力。

Zuul 的核心是一系列过滤器,它们能够在路由 HTTP 请求和响应期间执行一系列操作。

以下是 Zuul 过滤器的主要特征:

  • 类型: 通常定义路由流程中应用过滤器的阶段。(尽管它可以是任何自定义字符串)

  • 执行顺序: 在类型中应用,定义跨多个过滤器的执行顺序。

  • 准则: 执行过滤器所需的条件。

  • 动作: 如果符合条件,则要执行的动作。

class DeviceDelayFilter extends ZuulFilter {

def static Random rand = new Random()

@Override

String filterType() {

return ‘pre’

}

@Override

int filterOrder() {

return 5

}

@Override

boolean shouldFilter() {

return  RequestContext.getRequest().

getParameter(“deviceType”)?equals(“BrokenDevice”):false

}

@Override

Object run() {

sleep(rand.nextInt(20000)) // Sleep for a random number of

// seconds between [0-20]

}

}

Zuul 提供了一个框架来动态读取,编译和运行这些过滤器。过滤器不直接相互通信。

而是通过每个请求唯一的 RequestContext 共享状态。过滤器使用 Groovy 编写。

图片

有几种与请求的典型生命周期相对应的标准过滤器类型:

  • Pre 过滤器在路由到原点之前执行。示例包括请求身份验证,选择原始服务器以及记录调试信息。

  • Route 路由过滤器处理将请求路由到源。这是使用 Apache HttpClient 或 Netflix Ribbon 构建和发送原始 HTTP 请求的地方。

  • 在将请求路由到源之后,将执行 Post 过滤器。示例包括将标准 HTTP 标头添加到响应,收集统计信息和指标以及将响应从源流传输到客户端。

  • 在其他阶段之一发生错误时,将执行 Error 过滤器。

Spring Cloud 创建了一个嵌入式 Zuul 代理,以简化一个非常常见的用例的开发,在该用例中,UI 应用程序希望代理对一个或多个后端服务的调用。

此功能对于用户界面代理所需的后端服务很有用,从而避免了为所有后端独立管理 CORS 和身份验证问题的需求 。

要启用它,请使用 @EnableZuulProxy 注解一个 Spring Boot 主类,这会将本地调用转发到适当的服务。

Zuul 是 Java 的一个库,他并不是一款开箱即用的 API 网关,所以需要用 Zuul 开发一个应用来对其功能进行测试。

对应的 Java 的 POM 如下:

<project

xmlns=“http://maven.apache.org/POM/4.0.0”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>

4.0.0

naughtytao.apigateway

demo

0.0.1-SNAPSHOT

  

org.springframework.boot

spring-boot-starter-parent

1.4.7.RELEASE

           

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<java.version>1.8</java.version>

  

<spring-cloud.version>Camden.SR7</spring-cloud.version>

           

org.springframework.cloud

spring-cloud-dependencies

${spring-cloud.version}

pom

import

              

org.springframework.cloud

spring-cloud-starter-zuul

     

org.springframework.boot

spring-boot-starter-actuator

     

org.springframework.boot

spring-boot-starter-logging

           

org.springframework.boot

spring-boot-starter-log4j2

           

org.springframework.boot

spring-boot-starter-web

        

jakarta.xml.bind

jakarta.xml.bind-api

2.3.2

        

org.glassfish.jaxb

jaxb-runtime

2.3.2

     

org.springframework.boot

spring-boot-starter-test

test

     

org.junit.jupiter

junit-jupiter-api

5.0.0-M5

test

              

org.springframework.boot

spring-boot-maven-plugin

     

org.apache.maven.plugins

maven-compiler-plugin

3.3

   1.8  

1.8

              

主要应用代码如下:

package naughtytao.apigateway.demo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;

import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Bean;

import naughtytao.apigateway.demo.filters.ErrorFilter;

import naughtytao.apigateway.demo.filters.PostFilter;

import naughtytao.apigateway.demo.filters.PreFilter;

import naughtytao.apigateway.demo.filters.RouteFilter;  
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

面试是跳槽涨薪最直接有效的方式,马上金九银十来了,各位做好面试造飞机,工作拧螺丝的准备了吗?

掌握了这些知识点,面试时在候选人中又可以夺目不少,暴击9999点。机会都是留给有准备的人,只有充足的准备,才可能让自己可以在候选人中脱颖而出。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
amework.context.annotation.Bean;

import naughtytao.apigateway.demo.filters.ErrorFilter;

import naughtytao.apigateway.demo.filters.PostFilter;

import naughtytao.apigateway.demo.filters.PreFilter;

import naughtytao.apigateway.demo.filters.RouteFilter;  
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-G7FlxYY1-1712919486848)]

[外链图片转存中…(img-UznyYmOG-1712919486848)]

[外链图片转存中…(img-Xun0DYfN-1712919486848)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

面试是跳槽涨薪最直接有效的方式,马上金九银十来了,各位做好面试造飞机,工作拧螺丝的准备了吗?

掌握了这些知识点,面试时在候选人中又可以夺目不少,暴击9999点。机会都是留给有准备的人,只有充足的准备,才可能让自己可以在候选人中脱颖而出。

[外链图片转存中…(img-OCTSLCG3-1712919486849)]

[外链图片转存中…(img-EazmUtkp-1712919486849)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值