云计算API网关遇上容器服务

Posted 阿里云云栖号

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了云计算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网关的功能不止这些,如果想了解更详细的信息,请移步官网。


定义后端服务



为了简单起见,我们的应用利用实现,运行在上。


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"





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


创建API


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



在这个分组中创建API:





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



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



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


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


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



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



进入AppKey页面,记录下AppKey和AppSecret



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



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


访问API的应用示例


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



本文我们使用Java语言创建应用,生成的最终示例在github上:,大家有兴趣可以参考。


在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。


本文的示例代码在此:,供大家参考。


小  节


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

大流量&高并发

互联网应用实践在线峰会

【云计算】API网关遇上容器服务 
9月20-21日
 
20:00-21:30,线上共聚首
峰会议程

应对超大流量、超高并发的绝密实践,最适合技术开发者的夜间技术交流、每场1.5小时互动分享、素材第一时间公开、全开放注册,我们希望通过在线峰会这样的新模式,广聚开发者,共建技术分享的生态。


[ 09月20日 ] 云数据库超大流量峰值保障最佳实践
09月20日 ] 淘宝开放平台海量订单实时同步与处理实践
09月20日 ] 大规模计算平台研究与实战 
09月20日 ] 御膳房:探索大数据开放处理平台之路  
09月20日 ] 阿里无线开放生态 
[ 09月21日 ] 支撑海量用户的阿里中间件技术    
09月21日 ] 千牛开放从云到端  

[ 09月21日 ] 阿里聚石塔电商云容器服务应用和实践

[ 09月21日 ] 如何打造应对超大流量的负载均衡

[ 09月21日 ] 聚星台:客户运营核心大数据与算法技术


 扫码直入报名页:


以上是关于云计算API网关遇上容器服务的主要内容,如果未能解决你的问题,请参考以下文章

在容器云平台部署微服务,API网关应如何选择?

如何用阿里云函数计算结合API网关构建自己的serverless服务

阿里云API网关

我们为什么建议使用 API 网关实现微服务治理

阿里API网关使用总结

当云原生遇上边缘计算,会擦出什么样的火花?