文章目录
[隐藏]

近期要做一个SOA服务治理相关的项目,详细调研了下WSO2的API Manager(简称,APIM)。因为在调研过程中发现,国内研究WSO2的开发者较少,社区中也不是很活跃,可供直接上手的中文文档很少,好在官网提供的用户文档比较详细,认真研读研读,调研推进起来还不算太费劲,不过源码比较庞大,大致了解下框架。本文梳理下所调研的APIM相关知识,希望能给后来的开发学习者提供一点帮助。

一、概述

当企业实现自己的SOA框架时,需要对外以APIs的方式暴露内部系统的一些关键的流程、数据和服务。外部系统可以集成这些开放的APIs构建新的业务的解决方案,这种模式可以以一种去中心化的开发模式快速扩展潜在市场,挖掘潜在客户,带来巨大的经济效益,这就是所谓的“APIs经济”。但以一种协同的方式发挥API的杠杆作用面临着一些挑战:控制管理、可信连接、安全认证等。

WSO2 API Manager是一款可以旨在提供优秀的API管理功能的开源产品,能够实现API的创建、发布、生命周期管理、流量控制、版本控制、治理和安全控制等功能。 已用于WSO2 Enterprise Service Bus、WSO2 Identity Server和WSO2 Governance Registry等产品中。WSO2 API Manager可以为开发团队提供Web页面进行部署、管理和监控API,服务消费者可以进行服务发现、服务订阅以及服务调用。APIM的Key Manager组件默认通信协议是Apache Thrift,另外,APIM可以通过集成WSO2 Analytic平台实现API调用监控及告警。

二、安装部署

2.1 基本配置

单点部署方式:

默认Linux环境:Jdk1.8、关闭防火墙,关闭环境中运行Rabbitmq服务,检查端口是否存在冲突
查看5672端口占用

# netstat -ntlp|grep 5672

解压安装包:wso2am-2.1.0.zip
修改配置文件:

vim wso2am-2.1.0/repository/conf/carbon.xml

取消注释,并将主机名换成本机IP即可
<HostName>192.168.100.87</HostName>
<MgtHostName>192.168.100.87</MgtHostName>
保存退出
启动:
wso2am-2.1.0/bin/wso2server.sh
日志打印到标准输出

相关命令:
–start: Start Carbon using nohup in the background
–stop: Stop the Carbon server process
–restart: Restart the Carbon server process

浏览器访问:

https://192.168.100.87:9443/publisher

https://192.168.100.87:9443/store/

https://192.168.100.87:9443/carbon/

初始管理员密码为admin:admin

2.2 替换后台数据库

参考:https://docs.wso2.com/display/AM210/Changing+the+Default+API-M+Databases

替换默认的后端存储H2为我们熟悉的MySQL数据库。

后端数据列表

序号 数据库 备注 新建数据库名
1 WSO2_CARBON_DB Carbon的注册和用户管理数据库 wso2carbon_87
2 WSO2AM_DB API Manager的API管理数据库  wso2am_87
3 WSO2AM_STATS_DB API Manager的使用统计数据库 wso2stats_87
4 WSO2_MB_STORE_DB 消息代理数据库 wso2mbstore_87

依次创建以上数据库,例如,

导入数据库表,数据库脚本位于安装目录的/dbscripts目录下:

wso2carbon_87 wso2am-2.1.0/dbscripts/mysql.sql
 wso2am_87 wso2am-2.1.0/dbscripts/apimgt/mysql.sql
wso2stats_87 wso2am-analytics-2.1.0/dbscripts/mysql.sql
wso2mbstore_87 wso2am-2.1.0/dbscripts/mb-store/mysql-mb.sql

查看各个数据库中已经存在了数据表。

修改API Manager的数据库,指定以上四个数据库
wso2am-2.1.0/repository/conf/datasources/master-datasources.xml, 修改<url>、<username>、<password>和<driverClassName>选项,如下:

启动wso2server.sh,控制台无报错说明后端数据库切换成功,查看数据库表中也有了相应记录,例如:

注意:数据库中中文乱码的主要原因是库、表及字段的编码都是默认的latin1,需要全部设置为UTF-8才可以。

2.3 集成APIM Analytics

单点上集成Analytics的部署方式:

参考:https://docs.wso2.com/display/AM210/Configuring+APIM+Analytics

修改wso2am-2.1.0/repository/conf/api-manager.xml,打开Analytics配置项

关闭wso2server,修改数据源配置WSO2AM_STATS_DB,上面已经制定Mysql数据源(这里进行省略)

修改log4j日志配置wso2am-2.1.0/repository/conf/log4j.properties,增加DAS_AGENT配置,如下

下载并解压wso2am-analytics-2.1.0.zip

修改配置文件:

取消注释,并将主机名换成本机IP即可

修改数据源配置文件wso2am-analytics-2.1.0/repository/conf/datasources/master-datasources.xml,与wso2am-2.1.0/repository/conf/datasources/master-datasources.xml

的WSO2_CARBON_DB配置一致

修改数据源配置文件wso2am-analytics-2.1.0/repository/conf/datasources/stats-datasources.xml,与wso2am-2.1.0/repository/conf/datasources/master-datasources.xml

的WSO2AM_STATS_DB配置一致

拷贝一份mysql-connector-java-5.1.42-bin.jar至wso2am-analytics-2.1.0/repository/components/lib中

启动wso2am-analytics-2.1.0/bin/wso2server.sh,查看有无错误输出

如果没有,可以浏览器访问:

https://192.168.100.87:9444/carbon/ admin:admin

启动wso2am-2.1.0/bin/wso2server.sh,查看有无错误输出

如果没有,浏览器访问:https://192.168.100.87:9443/publisher/

发现之前的Analytics“Not Configured”已经消失,统计分析页面正常显示。

 

三、APIM介绍

3.1 系统架构

3.2 API Gateway

加密、保护、管理和度量API的调用。提供了一个简单的API代理,拦截API请求,并应用限流和安全检测的等功能。它同样作为API使用统计的工具。通过https://<Server Host>:9443/carbon访问。

3.3 API Publisher

具备API信息注册与发布,共享文档,提供API密钥,收集特性、质量和使用的反馈。通过https://<Server Host>:9443/publisher访问。

3.4 API Store

API的消费者,应用系统注册、服务发现和订阅API、评估,并与API Publish进行交互,通过https://<Server Host>:9443/store访问。

3.5 API Manager Analytics

提供统计图表,针对预设的事件和日志分析具备告警机制。

信息页面嵌入到Publisher和Store系统中,分别如下图所示。

3.6 其他组件

Key Manager:处理所有安全和密钥相关的操作,API Gateway连接Key Manager验证订阅
Traffic Manager: 帮助用户调节API流量,使API和应用以不同的服务级别和安全级别被用户获取。Traffic Manager具备动态限流引擎来实时处理限流策略。

3.7 相关概念

(1)用户和角色

创建者:技术角色,理解API的技术层面(接口、文档、版本、如何暴露给网关),使用API publisher发布API给API Store,创建者根据用户反馈使用API Store对API进行评级。创建者可以添加API Store但不能管理他们的声明周期(例如,使他们对外部可见)。
发布者:管理企业或商业的API,控制API的声明周期
消费者:消费者使用API Store发现API,查看文档和论坛,评级和评论API,订阅API并获取API密钥。

(2)API生命周期

被创建:注册到系统中
PROTOTYPED:模拟实现,用户可以不订阅而试用
被发布:API在API Store中可见并且可以订阅
DEPRECATED:API仍被部署在API网关中,但对订阅者不可见了,发布新版本API时自动废弃。
RETIRED:在API网关中不再被发布并从API Store中删除
BLOCKED:API临时不可用,实时调用被停用,API不在API Store中显示。

(3)应用

应用主要用于将API与消费者解耦,允许:

  • 为多个API创建并使用一个简单密钥
  • 以不同的SLA级别多次订阅单一API

(4)流量限制层

与一个API订阅时间相关,可以定义在API层、资源层、订阅层和应用层。它定义了API网关的流量限制次数,例如10TPS(每秒交易数)。可以编辑<API-M_HOME>/repository/conf/api-manager.xml的<TierManagement>进行禁用。

(5)API密钥

支持两个场景的认证:

  • 访问令牌用于识别和认证一整个应用
  • 识别隶属最终用户的应用程序

API密钥是一个简单的字符串,通过HTTP header传输(例如”Authorization: Bearer NtBQkXoKElu0H1a1fQ0DWfo6IX4a,”)在SOAP和REST调用中同样起作用。
OAuth2用作API密钥管理。

在应用级别上,Application访问令牌对所有的API都有效。这些Token具备确定的过期时间。默认60分钟,可以设置更长时间(修改<API-M_HOME>/repository/conf/identity.xml的<ApplicationAccessTokenDefaultValidityPeriod>,如果设置负值,意味着永远有效),甚至几周。消费者可以通过API Store直接重新生成token。

在应用用户级别上,可以按需生成访问令牌,为避免令牌过期,可以使用Token API进行更新。同样应用用户访问令牌也有确切的过期时间。默认60分钟,编辑<API-M_HOME>/repository/conf/identity/identity.xml中的<AccessTokenDefaultValidityPeriod>可以进行设置。

(6)API资源

API由一个或多个资源组成,每个资源处理一中特殊的请求,类似与一个大的API中方法。API资源接受以下可选属性:

  • 动作verbs:GET, POST, PUT, DELETE, PATCH, HEAD和OPTIONS
  • uri-template:定义参考http://tools.ietf.org/html/rfc6570
  • url-mapping:作为每个servlet规范,扩展映射、路径映射、精准映射
  • Throttling tiers:一段时间内请求资源次数限制
  • Auth-Type:None、Application和Application User。

四、使用说明

4.1 用户及权限管理

在API GateWay中,进行用户创建、修改、删除,以及权限角色的相关管理,如下:

4.2 发布API

在API Publisher中进行API的设计、实现及管理,这里采用用户文档中所给的一个示例,外部Web Service服务可以提供查询指定电话号码的验证的服务。

首先进行发布API的设计,设计时需要设置名称、HTTP动作及其参数、Url-mapping、可见性等信息,如下:

实现阶段,需要设置API所对对应服务提供者的Endpoint,具备生产环境和测试环境的URL信息,如下

管理阶段可以设置是否为默认版本,协议类型,订阅可见性以及流量控制信息,如下:

完成配置后,可以选择保存或发布,发布后在设置可见的订阅用户可以在API Store中发现服务,并可以进行订阅调用。

4.3 订阅API

在API Store中进行应用系统注册、API订阅、调用测试。

首先,注册一个应用系统,名称为Applicaton001,如下:

然后给应用程序生成用于验证的Key,在后面调用API时需要用到,这里可以指定Key的声明周期,如下:

切换到API Tab上,选择需要订阅的PhoneVerification,点击进入,在订阅栏中选择那些应用系统可以订阅,这里选择刚才创建的应用Application001,如下:

在API Console中测试服务调用,选择应用为已经订阅的Application001,输入一个电话号码,点击尝试调用,如下:

正常情况下,调用会有正确返回,如果这里服务URL识别的不对(这里就不对主机识别成了10.10.10.231,这个IP是主机上另外一个网卡所对应的IP,外网可访问的IP应该是192.168.100.87),我们根据它所提供的curl调用测试方法,手动测试下服务是否可用,如下:

正确返回了结果,如下:

不难发现,应用系统能够调用API是需要OAuth安全验证,验证方式是通过追加Access_Token到Http Header的方式进行,也就是说客户端调用,需要通过Http Header指定授权的key才能进行调用。例如,我们在浏览器中直接访问服务,会返回后台需要进行OAuth 认证,请求参数缺少认证所需的Http Header。

这里加上HTTP Header的内容就可以通过验证,得到正确结果。增加Header方式,可以客户端工具指定。例如利用Chrome插件或测试工具中指定,如下:

 

Java客户端Demo源码,如下:

请求返回结果:

4.4 其他一些应用场景

五、源码研究

5.1 源码编译

下载源码,直接利用Maven进行Build:

注意事项:

  • 注意匹配pom.xml中依赖版本,不要直接编译master分支;
  • 最好放可联网的服务器上编译,PC上编译过程较慢;
  • 多次编译(生成依赖组件)、可忽略测试

2.1.0版本所依赖的源码:

5.2 源码框架

WSO2产品套件非常全面,API Manager仅仅是产品之一,其他产品像Enterprise Integrator 、Identity  Server、Enterprise Service Bus、Analytics、IoT Server等都非常庞大。所有的产品都基于一个公共的组件就是Carbon Kernel,Carbon Kernel是一个模块化、轻量级、基于OSGi的服务器开发框架,其他的产品都有OSGi插件的形式集成到Carbon Server上,包括这里的Carbon-apimgt和Analytics-apim都开发了服务端的OSGi Bundles集成到Carbon Server中,启动Carbon时自动解析加载、注册装和启动。像在这种庞大的项目中,采用OSGi框架的是明智的,不仅开发出可以重用的组件,而且能够实现强鲁棒性的系统,对于线上运行要求较高的系统,能够做到不停机的增加或禁止某项服务,借助OSGi的组件热插拔属性做到线上服务的动态修补。

对于API Manager这样的一个开源组件,我们比较关心的问题是如何二次开发,如何调用后端服务?定制它的前端界面?其实Carbon-apimgt后端会以SOAP和REST的方式提供API管理的Web Service,对于前端,我们比较感兴趣是API Gateway、API Publisher和API Store这三个主要系统的界面如何定制开发,通过查看代码可以发现,Portal开发其实是采用不同的两种方式,API Gateway是在Carbon-apimgt中撰写Jsp代码来完成的(界面感觉有点丑),可以推测其他ESB、Analytics等产品的Gateway后端管理界面和API Gateway都是一样的,而另外一种前端框架是采用WSO2自研所谓的Jaggery全功能框架,我们所熟悉的API Publisher和API Store(界面渲染的比较鲜艳)都是拿它来做的。Jaggery其实是拿JavaScript在前端和后端之间封装了一层服务层,前端可以利用封装好的require()函数,调用后端服务,返回结果传给JS,然后动态转成Html,然后完成页面渲染。

5.3 Carbon-Kernel

基于OSGi框架,负责Carbon Server(standalone)的启动、配置变量和运行环境的检验、OSGi Bundles的注册及类加载、日志功能等功能,入口主函数程序:org.wso2.carbon.bootstrap.Bootstrap。

OSGi(Open Service Gateway Initiative)该规范和核心部分是一个框架,其中定义了应用程序的生命周期模式和服务注册。基于这个框架定义了大量的OSGi服务:日志、配置管理、偏好,HTTP(运行servlet)、XML分析、设备访问、软件包管理、许可管理、评级、用户管理、IO连接、连线管理、Jini和UPnP。这个框架实现了一个优雅、完整和动态的组件模型。应用程序(称为bundle)无需重新引导可以被远程安装、启动、升级和卸载(其中Java包/类的管理被详细定义)。API中还定义了运行远程下载管理政策的生命周期管理。服务注册允许bundles去检测新服务和取消的服务,然后相应配合。

未来版本:
解析多个组件启动顺序,不需要利用OSGi现有的启动顺序,通过启动顺序解析器来解决组件内依赖和组件间依赖的问题。

Carbon Server的启动:

入口程序为org.wso2.carbon.bootstrap.Bootstrap,源码位置:

主要作用:

OSGi Bundles:

QpidBundleActivator:

http://svn.wso2.org/repos/wso2/tags/stratos/1.5.1/orbit/qpid/0.11.wso2v2/src/main/java/org/apache/qpid/wso2/internal/QpidBundleActivator.java

CarbonCoreActivator:

https://github.com/Buddhima/carbon4-kernel/blob/master/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/internal/CarbonCoreActivator.java

CarbonCoreActivator.start()中,CarbonCoreDataHolder(单例) setBundleContext(context)、PrivilegedCarbonContext,进行启动

BootupValidationActivator:

调用ConfigValidationXMLProcessor进行系统配置检验SystemValidator,检验部署节点的CPU、Mem、Swap、是否windows环境、认证primary keystore(wso2carbon.jks),

启动时打印日志:

5.4 Carbon-apimgt

  • 用于构建API Manager产品所依赖的OSGi功能组件、配置文件、静态资源等;
  • 组件功能主要包括Publisher、Store、流量控制、Key Manager、GateWay等功能模块的API、Webservice服务;
  • 生成的组件位于安装目录的wso2am-2.1.0\repository\components中。

5.5 Analytics-apim

与APIM同等部署,修改相同配置,提供监控统计服务。

5.6  Jaggery

作为减少或消除不同web应用层和API开发不匹配场景,提供一个完全的Javascript方法来编写Web应用程序和服务的所有部分。
通过允许同时创建应用程序和api从而减少Web应用程序与Web服务之间的差距。

Jaggery应用程序所在目录:
wso2am-2.1.0/repository/deployment/server/jaggeryapps

Publisher和Store的汉化方案:直接修改Jaggery程序中的本地化文件即可,国际化配置文件为每个Jaggery程序目录下的/site/conf/locales/jaggery/locale_default.json。

http://jaggeryjs.org/quickstart.jag

https://docs.wso2.com/display/DVS380/Creating+Jaggery+Artifacts

六、开发指南

6.1 Java Doc

http://product-dist.wso2.com/javadocs/api-manager/2.1.0/

6.2 Carbon-kernel DeveloperTools

https://github.com/wso2/carbon-kernel/tree/master/docs/DeveloperTools

6.3 OSGi Bundles

打开OSGi管理控制台:

待系统启动后多次回车进入osgi控制台,

执行ss/install/start/stop等控制命令进行组件的列表查询、安装、启动、停止等操作。这里所依赖的OSGi Bundles共有694个条目。

创建通用osgi-bundle

https://github.com/wso2/carbon-kernel/blob/master/docs/DeveloperTools/UsingMavenArchetypes.md#creating-a-generic-osgi-bundle-in-one-step

将JARs转为OSGi Bundles

https://github.com/wso2/carbon-kernel/blob/master/docs/DeveloperTools/ConvertingJARsToOSGiBundles.md

使用OSGi声明服务的注解

https://github.com/wso2/carbon-kernel/blob/master/docs/DeveloperTools/UsingAnnotationswithOSGiDeclarativeServices.md

6.4 Admin Services

内部系统所使用SOAP的Web Service,底层有OSGi服务组件提供服务、上层通过UI组件为用户提供服务、通过Service stub来提供WSDL服务。

查看服务列表:

首先打开显示服务的配置项,修改wso2am-2.1.0/repository/conf/carbon.xml,将<HideAdminServiceWSDLs>配置项置为False,然后在osgi管理控制台上输入listAdminServices命令,可以查询到所有的后台SOAP服务,共有119个条目。

选中需要调用的服务URL,直接在浏览器中添加?wsdl即可获得服务,例如这里我们访问API声明周期的服务https://192.168.100.84:9443/services/LifeCycleManagementService?wsdl,结果如下:

6.5 WSO2 APIs

提供API管理的相关REST APIs。

https://docs.wso2.com/display/AM210/apidocs/store/#guide

https://docs.wso2.com/display/AM210/apidocs/publisher/#guide

七、选型考量

考虑到服务集成、服务治理、ESB系统与其他应用的系统耦合度较高,这对需求产品的可靠性、稳定性、可控性等具有较高的要求。API Manager及其他开源产品选型时可进行以下方面的考虑。

如果API Manager现有功能可以满足要求,只想定制前端页面,可以采用以下方案:

  • 只改造前端,研究Jaggery框架,修改Publisher和Store页面
  • 调用后台Web Service服务,自行设计业务逻辑,封装开发SDK,利用熟悉前端框架构建Portal

如果API Manager现有的后端服务不能满足需求,需要更深层次的开发,可采用以下方案:

  • 借助现有的开发资源,研究底层源码
  • 熟悉OSGi开发框架,开发功能扩展的OSGi模块
  • 必要时写Mail与开发者请教交流

产品上线前的一些测试

  • 并发性能测试
  • 稳定性测试
  • 流量控制机制的有效性

API Manager运维的一些考量

  • 部署架构的演进:分布式部署、HA部署、LB部署
  • 故障排查的策略
  • 应急处理的策略

八、相关参考

Mail-list:http://wso2.com/mail/

用户文档:https://docs.wso2.com/display/AM210

Eclipse调试Web Service: http://wso2.com/library/225/

Stackoverflow问答:https://stackoverflow.com/questions/tagged/wso2

社区:https://devhub.io/repos/wso2-product-apim

https://gitter.im/wso2/product-apim?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge

多租户场景介绍:http://wso2.com/library/articles/2015/10/article-multitenant-api-management-with-wso2-api-manager/