CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛

网关硬件方案架构图(不看后悔)网关硬件方案架构设计,刚哥谈架构 (十一) 开源API网关架构分析,

1.网关芯片方案

春未老,风细柳斜斜试上超然台上望,半壕春水一城花烟雨暗千家寒食后,酒醒却咨嗟休对故人思故国,且将新火试新茶诗酒趁年华 苏轼·送《望江南·超然台作》。

2.网关的设计与实现

温哥华的春天来了,上面的图就是我家门口的Marine Gaetway,我今天就在这春色中和大家探讨一下API Gateway。

3.网关产品架构

在微服务的架构下,API网关是一个常见的架构设计模式以下是微服务中常见的问题,需要引入API网关来协助解决微服务提供的API的粒度通常与客户端所需的粒度不同微服务通常提供细粒度的API,这意味着客户端需要与多个服务进行交互。

4.网关总体结构设计图

例如,如上所述,需要产品详细信息的客户需要从众多服务中获取数据不同的客户端需要不同的数据例如,产品详细信息页面桌面的桌面浏览器版本通常比移动版本更为详尽对于不同类型的客户端,网络性能是不同的例如,与非移动网络相比,移动网络通常要慢得多并且具有更高的延迟。

5.网关软件设计

而且,当然,任何WAN都比LAN慢得多这意味着本机移动客户端使用的网络性能与服务器端Web应用程序使用的LAN的性能差异很大服务器端Web应用程序可以向后端服务发出多个请求,而不会影响用户体验,而移动客户端只能提供几个请求。

6.网关控制模块

微服务实例数量及其位置(主机+端口)动态变化服务划分会随着时间的推移而变化,应该对客户端隐藏服务可能会使用多种协议,其中一些协议可能对网络不友好常见的API网关主要提供以下的功能:反向代理和路由 – 大多数项目采用网关的解决方案的最主要的原因。

7.网关技术选型

给出了访问后端API的所有客户端的单一入口,并隐藏内部服务部署的细节负载均衡 – 网关可以将单个传入的请求路由到多个后端目的地身份验证和授权 – 网关应该能够成功进行身份验证并仅允许可信客户端访问API,并且还能够使用类似RBAC等方式来授权。

8.硬件网关设备

IP列表白名单/黑名单 – 允许或阻止某些IP地址通过性能分析 – 提供一种记录与API调用相关的使用和其他有用度量的方法限速和流控 – 控制API调用的能力请求变形 – 在进一步转发之前,能够在转发之前转换请求和响应(包括Header和Body)。

9.网关设计原理

版本控制 – 同时使用不同版本的API选项或可能以金丝雀发布或蓝/绿部署的形式提供慢速推出API断路器 – 微服务架构模式有用,以避免使用中断多协议支持 WebSocket/GRPC缓存 – 减少网络带宽和往返时间消耗,如果可以缓存频繁要求的数据,则可以提高性能和响应时间

10.核心网关协议

API文档 – 如果计划将API暴露给组织以外的开发人员,那么必须考虑使用API文档,例如Swagger或OpenAPI有很多的开源软件可以提供API 网关的支持,下面我们就看看他们各自的架构和功能为了对这些开源网关进行基本功能的验证,我创建了一些代码,使用OpenAPI生成了四个基本的API服务,包含Golang,Nodejs,Python Flask和Java Spring。

API使用了常见的宠物商店的样例,声明如下:openapi: “3.0.0” info: version: 1.0.0 title: Swagger Petstore license: name: MIT servers: – url: http://petstore.swagger.io/v1 paths: /pets: get: summary: List all pets operationId: listPets tags: – pets parameters: – name: limit in: query description: How many items to return at one time (max 100) required: false schema: type: integer format: int32 responses: 200: description: A paged array of pets headers: x-next: description: A link to the next page of responses schema: type: string content: application/json: schema: $ref: “#/components/schemas/Pets” default: description: unexpected error content: application/json: schema: $ref: “#/components/schemas/Error” post: summary: Create a pet operationId: createPets tags: – pets responses: 201: description: Null response default: description: unexpected error content: application/json: schema: $ref: “#/components/schemas/Error” /pets/{petId}: get: summary: Info for a specific pet operationId: showPetById tags: – pets parameters: – name: petId in: path required: true description: The id of the pet to retrieve schema: type: string responses: 200: description: Expected response to a valid request content: application/json: schema: $ref: “#/components/schemas/Pet” default: description: unexpected error content: application/json: schema: $ref: “#/components/schemas/Error” components: schemas: Pet: type: object required: – id – name properties: id: type: integer format: int64 name: type: string tag: type: string Pets: type: array items: $ref: “#/components/schemas/Pet” Error: type: object required: – code – message properties: code: type: integer format: int32 message: type: string

构建好的Web服务通过Docker Compose来进行容器化的部署version: “3.7” services: goapi: container_name: goapi image: naughtytao/goapi:0.1 ports: – “18000:8080” deploy: resources: limits: cpus: 1 memory: 256M reservations: memory: 256M nodeapi: container_name: nodeapi image: naughtytao/nodeapi:0.1 ports: – “18001:8080” deploy: resources: limits: cpus: 1 memory: 256M reservations: memory: 256M flaskapi: container_name: flaskapi image: naughtytao/flaskapi:0.1 ports: – “18002:8080” deploy: resources: limits: cpus: 1 memory: 256M reservations: memory: 256M springapi: container_name: springapi image: naughtytao/springapi:0.1 ports: – “18003:8080” deploy: resources: limits: cpus: 1 memory: 256M reservations: memory: 256M。

我们在学习这些开源网关架构的同时,也会对其最基本的路由转发功能作出验证这里用户发送的请求http://server/service_name/v1/pets会发送给API网关,网关通过service name来路由到不同的后端服务。

我们使用K6用100个并发跑1000次测试的结果如上图,我们看到直连的综合响应,每秒可以处理的请求数量大概是 1100+NginxNginx是异步框架的网页服务器,也可以用作反向代理、负载平衡器和HTTP缓存。

该软件由伊戈尔·赛索耶夫创建并于2004年首次公开发布2011年成立同名公司以提供支持2019年3月11日,Nginx公司被F5 Networks以6.7亿美元收购Nginx有以下的特点由C编写,占用的资源和内存低,性能高。

单进程多线程,当启动nginx服务器,会生成一个master进程,master进程会fork出多个worker进程,由worker线程处理客户端的请求支持反向代理,支持7层负载均衡(拓展负载均衡的好处)。

高并发,nginx是异步非阻塞型处理请求,采用的epollandqueue模式处理静态文件速度快高度模块化,配置简单。社区活跃,各种高性能模块出品迅速。

如上图所示,Nginx主要由Master,Worker和Proxy Cache三个部分组成Master 主控:NGINX遵循主从架构它将根据客户的要求为Worker分配工作将工作分配给Worker后,Master将寻找客户的下一个请求,因为它不会等待Worker的响应。

一旦响应来自Worker,Master就会将响应发送给客户端Worker 工作单元:Worker是NGINX架构中的Slave每个工作单元可以单线程方式一次处理1000个以上的请求一旦处理完成,响应将被发送到主服务器。

单线程将通过在相同的内存空间而不是不同的内存空间上工作来节省RAM和ROM的大小多线程将在不同的内存空间上工作Cache 缓存:Nginx缓存用于通过从缓存而不是从服务器获取来非常快速地呈现页面在第一个页面请求时,页面将被存储在高速缓存中。

为了实现API的路由转发,需要只需要对Nginx作出如下的配置:server { listen 80 default_server; location /goapi { rewrite ^/goapi(.*) $1 break; proxy_pass http://goapi:8080; } location /nodeapi { rewrite ^/nodeapi(.*) $1 break; proxy_pass http://nodeapi:8080; } location /flaskapi { rewrite ^/flaskapi(.*) $1 break; proxy_pass http://flaskapi:8080; } location /springapi { rewrite ^/springapi(.*) $1 break; proxy_pass http://springapi:8080; } }

我们基于不同的服务goapi,nodeapi,flaskapi和springapi,分别配置一条路由,在转发之前,需要利用rewrite来去掉服务名,并发送给对应的服务使用容器把ngnix和后端的四个服务部署在同一个网络下,通过网关连接路由转发的。

Nginx的部署如下:version: “3.7” services: web: container_name: nginx image: nginx volumes: – ./templates:/etc/nginx/templates – ./conf/default.conf:/etc/nginx/conf.d/default.conf ports: – “8080:80” environment: – NGINX_HOST=localhost – NGINX_PORT=80 deploy: resources: limits: cpus: 1 memory: 256M reservations: memory: 256M

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

每秒处理的请求数量是1093,和不通过网关转发相比非常接近从功能上看,Nginx可以满足用户对于API网关的大部分需求,可以通过配置和插件的方式来支持不同的功能,性能非常优秀,缺点是没有管理的UI和管理API,大部分的工作都需要手工配置config文件的方式来进行。

商业版本的功能会更加完善KongKong是基于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使用了OpenRestyOpenResty是一个软件套件,捆绑了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,所以所有的功能都是有成本的APISIXApache 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来部署APISIXversion: “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的好成绩,表现出接近不经过网关的性能,可能缓存起到了很好的效果TykTyk是一款基于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接近。ZuulZuul是Netflix开源的基于Java的API网关组件。

Zuul包含多个组件:zuul-core:该库包含编译和执行过滤器的核心功能zuul-simple-webapp:该Webapp展示了一个简单的示例,说明如何使用zuul-core构建应用程序zuul-netflix:将其他NetflixOSS组件添加到Zuul的库-例如,使用Ribbon路由请求。

zuul-netflix-webapp: 将zuul-core和zuul-netflix打包到一个易于使用的程序包中的webappZuul提供了灵活性和弹性,部分是通过利用其他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如下: 4.0.0 naughtytao.apigateway demo 0.0.1-SNAPSHOT org.springframework.boot spring-boot-starter-parent 1.4.7.RELEASE UTF-8 UTF-8 1.8 Camden.SR7 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; @SpringBootApplication @EnableAutoConfiguration(exclude = { RabbitAutoConfiguration.class }) @EnableZuulProxy @ComponentScan(“naughtytao.apigateway.demo”) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }

Docker 构建文件如下:FROM maven:3.6.3-openjdk-11 WORKDIR /usr/src/app COPY src ./src COPY pom.xml ./ RUN mvn -f ./pom.xml clean package -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dmaven.wagon.http.ssl.ignore.validity.dates=true EXPOSE 8080 ENTRYPOINT [“java”,”-jar”,”/usr/src/app/target/demo-0.0.1-SNAPSHOT.jar”]

路由的配置写在application.properties中#Zuul routes. zuul.routes.goapi.url=http://goapi:8080 zuul.routes.nodeapi.url=http://nodeapi:8080 zuul.routes.flaskapi.url=http://flaskapi:8080 zuul.routes.springapi.url=http://springapi:8080 ribbon.eureka.enabled=false server.port=8080

我们同样使用Docker Compose运行Zuul的网关来进行验证:version: 3.7 services: gateway: image: naughtytao/zuulgateway:0.1 ports: – 8080:8080 volumes: – ./config/application.properties:/usr/src/app/config/application.properties deploy: resources: limits: cpus: 1 memory: 256M reservations: memory: 256M

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

在相同的配置条件下(单核,256M),Zuul的压测结果要明显差于其它几个,只有200左右。

在分配更多资源的情况下,4核 2G,Zuul的性能提升到600-800,所以Zuul对于资源的需求还是比较明显的另外需要提及的是,我们使用的是Zuul1,Netflix已经推出了Zuul2Zuul2对架构做出了较大的改进。

Zuul1本质上就是一个同步Servlet,采用多线程阻塞模型Zuul2的基于Netty实现了异步非阻塞编程模型同步的方式,比较容易调试,但是多线程本身需要消耗CPU和内存资源,所以它的性能要差一些而采用非阻塞模式的Zuul,因为线程开销小,所支持的链接数量要更多,也更节省资源。

GraviteeGravitee是http://Gravitee.io开源的,基于Java的,简单易用,性能高,且具成本效益的开源API平台,可帮助组织保护,发布和分析您的API。

Gravitee可以通过设计工作室和路径的两种方式来创建和管理API

Gravity提供网关,API门户和API管理,其中网关和管理API部分是开源的,门户需要注册许可证来使用。

后台使用MongoDB作为存储,支持ES接入我们同样使用Docker Compose来部署整个Gravitee的栈# # Copyright (C) 2015 The Gravitee team (http://gravitee.io) # # Licensed under the Apache License, Version 2.0 (the “License”); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an “AS IS” BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # version: 3.7 networks: frontend: name: frontend storage: name: storage volumes: data-elasticsearch: data-mongo: services: mongodb: image: mongo:${MONGODB_VERSION:-3.6} container_name: gio_apim_mongodb restart: always volumes: – data-mongo:/data/db – ./logs/apim-mongodb:/var/log/mongodb networks: – storage elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-7.7.0} container_name: gio_apim_elasticsearch restart: always volumes: – data-elasticsearch:/usr/share/elasticsearch/data environment: – http.host=0.0.0.0 – transport.host=0.0.0.0 – xpack.security.enabled=false – xpack.monitoring.enabled=false – cluster.name=elasticsearch – bootstrap.memory_lock=true – discovery.type=single-node – “ES_JAVA_OPTS=-Xms512m -Xmx512m” ulimits: memlock: soft: -1 hard: -1 nofile: 65536 networks: – storage gateway: image: graviteeio/apim-gateway:${APIM_VERSION:-3} container_name: gio_apim_gateway restart: always ports: – “8082:8082” depends_on: – mongodb – elasticsearch volumes: – ./logs/apim-gateway:/opt/graviteeio-gateway/logs environment: – gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 – gravitee_ratelimit_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 – gravitee_reporters_elasticsearch_endpoints_0=http://elasticsearch:9200 networks: – storage – frontend deploy: resources: limits: cpus: 1 memory: 256M reservations: memory: 256M management_api: image: graviteeio/apim-management-api:${APIM_VERSION:-3} container_name: gio_apim_management_api restart: always ports: – “8083:8083” links: – mongodb – elasticsearch depends_on: – mongodb – elasticsearch volumes: – ./logs/apim-management-api:/opt/graviteeio-management-api/logs environment: – gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 – gravitee_analytics_elasticsearch_endpoints_0=http://elasticsearch:9200 networks: – storage – frontend management_ui: image: graviteeio/apim-management-ui:${APIM_VERSION:-3} container_name: gio_apim_management_ui restart: always ports: – “8084:8080” depends_on: – management_api environment: – MGMT_API_URL=http://localhost:8083/management/organizations/DEFAULT/environments/DEFAULT/ volumes: – ./logs/apim-management-ui:/var/log/nginx networks: – frontend portal_ui: image: graviteeio/apim-portal-ui:${APIM_VERSION:-3} container_name: gio_apim_portal_ui restart: always ports: – “8085:8080” depends_on: – management_api environment: – PORTAL_API_URL=http://localhost:8083/portal/environments/DEFAULT volumes: – ./logs/apim-portal-ui:/var/log/nginx networks: – frontend。

我们使用管理UI来创建四个对应的API来进行网关的路由,也可以用API的方式,Gravitee是这个开源网关中,唯一管理UI也开源的产品。

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

和同样采用Java的Zuul类似,Gravitee的响应只能达到200左右,而且还出现了一些错误。我们只好再一次提高网关的资源分配到4核2G。

提高资源分配后的性能来到了500-700,稍微好于Zuul总结本文分析了几种开源API网关的架构和基本功能,为大家在架构选型的时候提供一些基本的参考信息,本文做作的测试数据比较简单,场景也比较单一,不能作为实际选型的依据。

NginxNginx基于C开发的高性能API网关,拥有众多的插件,如果你的API管理的需求比较简单,接受手工配置路由,Nginx是个不错的选择KongKong是基于Nginx的API网关,使用OpenResty和Lua扩展,后台使用PostgreSQL,功能众多,社区的热度很高,但是性能上看比起Nginx有相当的损失。

如果你对功能和扩展性有要求,可以考虑KongAPISIXAPISIX和Kong的架构类似,但是采用了云原生的设计,使用ETCD作为后台,性能上比起Kong有相当的优势,适合对性能要求高的云原生部署的场景。

特别提一下,APISIX支持MQTT协议,对于构建IOT应用非常友好TykTyk使用Golang开发,后台使用Redis,性能不错,如果你喜欢Golang,可以考虑一下要注意的是Tyk的开源协议是MPL,是属于修改代码后不能闭源,对于商业化应用不是很友好。

ZuulZuul是Netflix开源的基于Java的API网关组件,他并不是一款开箱即用的API网关,需要和你的Java应用一起构建,所有的功能都是通过集成其它组件的方式来使用,适合对于Java比较熟悉,用Java构建的应用的场景,缺点是性能其他的开源产品要差一些,同样的性能条件下,对于资源的要求会更多。

GraviteeGravitee是http://Gravitee.io开源的基于Java的API管理平台,它能对API的生命周期进行管理,即使是开源版本,也有很好的UI支持但是因为采用了Java构建,性能同样是短板,适合对于API管理有强烈需求的场景。

本文所有的代码可以从这里获得https://github.com/gangtao/api-gateway

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
相关推荐
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容