API网关遇上容器服务

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 本文通过利用阿里云的容器服务和API网关,构建一个完整的基于Docker的具有API管理功能的服务。

在API经济和微服务的背景下,如何对服务的API进行管理是大家都很感兴趣的话题。本文通过利用阿里云的容器服务和API网关,构建一个完整的基于Docker的具有API管理功能的服务。

API管理

假定我们需要这么一个经典的后端服务,访问如下API接口的时候返回Hello World:

$ curl http://apisvc.hostxx/api
<p>Hello World</p>

这个服务推出后广受欢迎,但是烦恼总是伴随幸福不期而至:

  • 对API进行计费怎么做?
  • 外界访问API的流量太高了,如何进行流量控制?
  • 外界访问API的并发连接太多了,能不能把这许多连接合成一个长连接访问服务?
  • 如何对API进行保护,让只有授权的应用才能访问API?
  • ... ...

这实际上涉及到了API管理的内容,并且很多和业务逻辑无关。是否可以利用云上的PaaS服务来完成呢?

答案是,可以。利用阿里云的API网关就可以完成上面所有任务。当然,API网关的功能不止这些,如果想了解更详细的信息,请移步官网API网关

定义后端服务

为了简单起见,我们的应用利用openresty实现,运行在阿里云容器服务上。

Openresty应用

Openresty是基于NGINX和LuaJIT的Web应用框架。实现我们的这个经典服务只需要nginx.conf配置文件做如下声明即可:

http {
    server {
        listen 8080;
        location /api {
            default_type text/html;
            content_by_lua '
                ngx.say("<p>hello, world</p>")
            ';
        }
    }
}

在本地启动openresty后访问:

$ /usr/local/openresty/bin/openresty -p . -c conf/nginx.conf
$ curl http://localhost:8080/api
<p>hello, world</p>

后端服务就成了。

构建Docker镜像

构建Docker镜像的Dockerfile内容如下:

FROM openresty/openresty:latest
RUN mkdir -p /work/conf work/logs
COPY nginx.conf /work/conf
WORKDIR /work
ENTRYPOINT ["/usr/local/openresty/bin/openresty", "-g", "daemon off;","-p","/work/","-c","/work/conf/nginx.conf"]

容器启动时为其增加了daemon off设置,这让nginx进程一直在前台运行,保证容器不退出。

部署到阿里云容器服务

部署到阿里云容器服务需要定义docker-compose.yml,这个文件和标准的docker compose部署模版文件完全兼容,只不过增加了一些阿里云特有的label。比如:

aliyun.lb.port_8080: http://${slbname}:8080

这个label的意思是把openresty应用对外通过负载均衡8080端口暴露出来。

version: '2'
services:
  hello:
    image: registry.cn-hangzhou.aliyuncs.com/jingshanlb/openresty-helloworld
    restart: always
    ports:
      - 8080:8080
    labels:
      aliyun.lb.port_8080: http://${slbname}:8080
      aliyun.scale: "2"

我们的测试集群是运行在经典网络中,开通一个内网阿里云负载均衡,并添加http 8080到8080的监听器。上面的部署文件讲hello服务通过这个负载均衡对外提供服务,访问端点为负载均衡的阿里云内网地址,如下图:

slb_ip

这个地址会用来配置API网关中对后端的访问,请记好。

在API网关中定义对后端的访问

创建API

我们首先要在API网关中定义API,并绑定和后端的映射关系。进入API网关控制台,首先创建一个API分组:

apigw_1

在这个分组中创建API:

apigw_2

对后端的访问地址为如下形式:

http://<负载均衡IP地址>:8080/api

API对外路径定义为/api,如下图所示:

apigw_3_classic

把API发布成功后可以进入调试API进行测试:

apigw_4

庆祝一下,我们的服务对外提供API了。

在应用程序能够访问我们的API之前,我们还需要在API网关控制台上生成应用访问所需要的token。

在控制台创建一个新的应用:

apigw_6

授权该应用可以访问我们的经典服务:

apigw_9

进入AppKey页面,记录下AppKeyAppSecret

apigw_7

进入分组管理页面,记录下API对外的二级域名:

apigw_8

这三个信息是应用程序访问API所需的端点和认证信息,我们马上要把它们填入到程序中。

访问API的应用示例

下面我们可以构建一个访问API的应用示例。访问SDK下载页面,可以看到很多语言的示例。

apigw_5

本文我们使用Java语言创建应用,生成的最终示例在github上:https://github.com/binblee/apigateway-docker-demo/tree/master/client,大家有兴趣可以参考。

在DemoClient的主程序中声明3个变量表示前面拿到的三个信息:AppKey,AppSecret和分组二级域名(API_HOST)。

public class DemoClient {
    //APP KEY
    private String APP_KEY;
    // APP密钥
    private String APP_SECRET;
    //API域名
    private String API_HOST;
...

把三个参数代入到HTTP请求中:


//请求URL
String url = "/api";

Map<String, String> headers = new HashMap<String, String>();
headers.put(HttpHeader.HTTP_HEADER_ACCEPT, ContentType.CONTENT_TYPE_TEXT);

Request request = new Request(Method.GET, HttpSchema.HTTP + API_HOST + url, APP_KEY, APP_SECRET, Constants.DEFAULT_TIMEOUT);
request.setHeaders(headers);
request.setSignHeaderPrefixList(CUSTOM_HEADERS_TO_SIGN_PREFIX);

//调用服务端
HttpResponse response = Client.execute(request);

为了不把ApiKey和ApiSecret等敏感信息硬编码到程序里,我们采用在环境变量中指定的方式:

Map<String, String> env = System.getenv();
APP_KEY = env.get("APP_KEY");
if(APP_KEY == null || APP_KEY.length() == 0){
    System.err.println("Please specify APP_KEY environment variable.");
    return false;
}

构建并运行 Demo Client

为了方便示例程序的构建,我们使用Gradle。

dependencies {
    compile('org.springframework.boot:spring-boot-starter')
    compile('org.apache.httpcomponents:httpclient:4.2.1')
    compile('org.apache.httpcomponents:httpcore:4.2.1')
    compile('commons-lang:commons-lang:2.6')
    compile('org.eclipse.jetty:jetty-util:9.3.7.v20160115')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

运行如下命令可以构建一个包含所有依赖的Uber Jar:

./gradle build -x test

这个命令的意思是构建Jar包,但不执行测试。我们的示例Client的测试代码都需要填写ApiKey和ApiSecret等信息,没有的话测试会失败。为了不影响构建Jar包,我们编译的时候忽略测试。

构建成功后,执行如下命令运行Demo Client:

export APP_KEY=<placeholder>
export APP_SECRET=<placeholder>
export API_HOST=<placeholder>
java -jar build/libs/apidemoclient-0.0.1-SNAPSHOT.jar

把前面得到的信息分别填入,可以看到如下执行结果:

...
17:23:47.329 [main] DEBUG org.apache.http.impl.conn.BasicClientConnectionManager - Releasing connection org.apache.http.impl.conn.ManagedClientConnectionImpl@2b05039f
17:23:47.329 [main] DEBUG org.apache.http.impl.conn.BasicClientConnectionManager - Connection can be kept alive indefinitely
200
Tengine
Mon, 12 Sep 2016 09:23:41 GMT
text/html;charset=UTF-8
chunked
keep-alive
Accept-Encoding
Accept-Encoding
*
POST, GET, OPTIONS
X-Requested-With, X-Sequence, _aop_secret, _aop_signature
172800
717E9CD3-320A-49F0-8F4E-82C3C6CA913E
CONTAINERID=; Expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/
<p>hello, world</p>

BINGO,访问应用成功调用了云上的API。

本文的示例代码在此:https://github.com/binblee/apigateway-docker-demo,供大家参考。

小节

本文演示了如何利用阿里云的API网关管理后台Docker应用API,和读者探讨了如何利用API网关和CaaS的能力为服务提供API管理功能。

相关实践学习
Docker镜像管理快速入门
本教程将介绍如何使用Docker构建镜像,并通过阿里云镜像服务分发到ECS服务器,运行该镜像。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
API
阿里云微服务引擎及 API 网关 2024 年 2 月产品动态
阿里云微服务引擎及 API 网关 2024 年 2 月产品动态
|
3月前
|
Prometheus 网络协议 JavaScript
api 网关 kong 数据库记录请求响应报文
Kong的tcp-log-with-body插件是一个高效的工具,它能够转发Kong处理的请求和响应。这个插件非常适用于需要详细记录API请求和响应信息的情景,尤其是在调试和排查问题时。
50 0
api 网关 kong 数据库记录请求响应报文
|
3月前
|
监控 应用服务中间件 API
API 网关的功能用途及实现方式
API 网关的功能用途及实现方式
|
6月前
|
Java API Maven
淘东电商项目(05) - Swagger及网关统一管理API
淘东电商项目(05) - Swagger及网关统一管理API
75 0
|
7月前
|
缓存 负载均衡 监控
每日一博 - 反向代理、API 网关、负载均衡
每日一博 - 反向代理、API 网关、负载均衡
89 0
|
6月前
|
Kubernetes API Docker
k8s教程(pod篇)-容器获取pod信息(Downward API)
k8s教程(pod篇)-容器获取pod信息(Downward API)
311 0
|
3月前
|
缓存 安全 API
【亿级数据专题】「高并发架构」盘点本年度探索对外服务的百万请求量的API网关设计实现
公司对外开放的OpenAPI-Server服务,作为核心内部系统与外部系统之间的重要通讯枢纽,每天处理数百万次的API调用、亿级别的消息推送以及TB/PB级别的数据同步。经过多年流量的持续增长,该服务体系依然稳固可靠,展现出强大的负载能力。
71 9
【亿级数据专题】「高并发架构」盘点本年度探索对外服务的百万请求量的API网关设计实现
|
5天前
|
负载均衡 Java API
构建高效微服务架构:API网关与服务熔断策略
【5月更文挑战第2天】 在微服务架构中,确保系统的高可用性与灵活性是至关重要的。本文将深入探讨如何通过实施有效的API网关和设计合理的服务熔断机制来提升分布式系统的鲁棒性。我们将分析API网关的核心职责,包括请求路由、负载均衡、认证授权以及限流控制,并讨论如何利用熔断器模式防止故障传播,维护系统的整体稳定性。文章还将介绍一些实用的技术和工具,如Netflix Zuul、Spring Cloud Gateway以及Hystrix,以帮助开发者构建一个可靠且高效的微服务环境。
|
21天前
|
API
阿里云微服务引擎及 API 网关 2024 年 3 月产品动态
阿里云微服务引擎及 API 网关 2024 年 3 月产品动态。
|
2月前
|
运维 Cloud Native 应用服务中间件
阿里云微服务引擎 MSE 及 API 网关 2024 年 02 月产品动态
阿里云微服务引擎 MSE 面向业界主流开源微服务项目, 提供注册配置中心和分布式协调(原生支持 Nacos/ZooKeeper/Eureka )、云原生网关(原生支持Higress/Nginx/Envoy,遵循Ingress标准)、微服务治理(原生支持 Spring Cloud/Dubbo/Sentinel,遵循 OpenSergo 服务治理规范)能力。API 网关 (API Gateway),提供 APl 托管服务,覆盖设计、开发、测试、发布、售卖、运维监测、安全管控、下线等 API 生命周期阶段。帮助您快速构建以 API 为核心的系统架构.满足新技术引入、系统集成、业务中台等诸多场景需要。