近期要做一个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调用监控及告警。
单点部署方式:
默认Linux环境:Jdk1.8、关闭防火墙,关闭环境中运行Rabbitmq服务,检查端口是否存在冲突
查看5672端口占用
# netstat -ntlp|grep 5672
解压安装包:wso2am-2.1.0.zip
修改配置文件:
vim wso2am-2.1.0/repository/conf/carbon.xml
取消注释,并将主机名换成本机IP即可
保存退出
启动:
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
参考: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 |
依次创建以上数据库,例如,
1
|
# mysql -uroot -pXXXXXX -h 192.168.100.87 -e "create database wso2carbon_87 character set utf8; GRANT ALL ON wso2carbon_87.* TO wso2@'%' IDENTIFIED BY 'XXXXXX'; FLUSH PRIVILEGES;"
|
导入数据库表,数据库脚本位于安装目录的/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, 修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
|
启动wso2server.sh,控制台无报错说明后端数据库切换成功,查看数据库表中也有了相应记录,例如:
1
|
SELECT *
FROM
wso2carbon_87
.
UM_USER
;
|
注意:数据库中中文乱码的主要原因是库、表及字段的编码都是默认的latin1,需要全部设置为UTF-8才可以。
单点上集成Analytics的部署方式:
参考:https://docs.wso2.com/display/AM210/Configuring+APIM+Analytics
修改wso2am-2.1.0/repository/conf/api-manager.xml,打开Analytics配置项
1
|
<
Enabled
>
true
<
/
Enabled
>
|
关闭wso2server,修改数据源配置WSO2AM_STATS_DB,上面已经制定Mysql数据源(这里进行省略)
修改log4j日志配置wso2am-2.1.0/repository/conf/log4j.properties,增加DAS_AGENT配置,如下
1
|
log4j
.
rootLogger
=
<
other
loggers
>
,
DAS_AGENT
|
下载并解压wso2am-analytics-2.1.0.zip
修改配置文件:
1
|
# vim wso2am-analytics-2.1.0/repository/conf/carbon.xml
|
取消注释,并将主机名换成本机IP即可
1
2
|
<
HostName
>
192.168.100.87
<
/
HostName
>
<
MgtHostName
>
192.168.100.87
<
/
MgtHostName
>
|
修改数据源配置文件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”已经消失,统计分析页面正常显示。
加密、保护、管理和度量API的调用。提供了一个简单的API代理,拦截API请求,并应用限流和安全检测的等功能。它同样作为API使用统计的工具。通过https://
具备API信息注册与发布,共享文档,提供API密钥,收集特性、质量和使用的反馈。通过https://
API的消费者,应用系统注册、服务发现和订阅API、评估,并与API Publish进行交互,通过https://
提供统计图表,针对预设的事件和日志分析具备告警机制。
信息页面嵌入到Publisher和Store系统中,分别如下图所示。
Key Manager:处理所有安全和密钥相关的操作,API Gateway连接Key Manager验证订阅
Traffic Manager: 帮助用户调节API流量,使API和应用以不同的服务级别和安全级别被用户获取。Traffic Manager具备动态限流引擎来实时处理限流策略。
(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与消费者解耦,允许:
(4)流量限制层
与一个API订阅时间相关,可以定义在API层、资源层、订阅层和应用层。它定义了API网关的流量限制次数,例如10TPS(每秒交易数)。可以编辑
(5)API密钥
支持两个场景的认证:
API密钥是一个简单的字符串,通过HTTP header传输(例如”Authorization: Bearer NtBQkXoKElu0H1a1fQ0DWfo6IX4a,”)在SOAP和REST调用中同样起作用。
OAuth2用作API密钥管理。
在应用级别上,Application访问令牌对所有的API都有效。这些Token具备确定的过期时间。默认60分钟,可以设置更长时间(修改
在应用用户级别上,可以按需生成访问令牌,为避免令牌过期,可以使用Token API进行更新。同样应用用户访问令牌也有确切的过期时间。默认60分钟,编辑
(6)API资源
API由一个或多个资源组成,每个资源处理一中特殊的请求,类似与一个大的API中方法。API资源接受以下可选属性:
在API GateWay中,进行用户创建、修改、删除,以及权限角色的相关管理,如下:
在API Publisher中进行API的设计、实现及管理,这里采用用户文档中所给的一个示例,外部Web Service服务可以提供查询指定电话号码的验证的服务。
首先进行发布API的设计,设计时需要设置名称、HTTP动作及其参数、Url-mapping、可见性等信息,如下:
实现阶段,需要设置API所对对应服务提供者的Endpoint,具备生产环境和测试环境的URL信息,如下
管理阶段可以设置是否为默认版本,协议类型,订阅可见性以及流量控制信息,如下:
完成配置后,可以选择保存或发布,发布后在设置可见的订阅用户可以在API Store中发现服务,并可以进行订阅调用。
在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调用测试方法,手动测试下服务是否可用,如下:
1
|
# curl -k -X GET --header 'Accept: application/xml' --header 'Authorization: Bearer 6ca32c4f-80c7-32d2-bdc4-59c61defdd42' 'https://192.168.100.87:8243/phoneverify/2.0.0/CheckPhoneNumber?Phonenumber=13235678906&Licensekey=0'
|
正确返回了结果,如下:
不难发现,应用系统能够调用API是需要OAuth安全验证,验证方式是通过追加Access_Token到Http Header的方式进行,也就是说客户端调用,需要通过Http Header指定授权的key才能进行调用。例如,我们在浏览器中直接访问服务,会返回后台需要进行OAuth 认证,请求参数缺少认证所需的Http Header。
这里加上HTTP Header的内容就可以通过验证,得到正确结果。增加Header方式,可以客户端工具指定。例如利用Chrome插件或测试工具中指定,如下:
Java客户端Demo源码,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
import
java
.
io
.
IOException
;
import
org
.
apache
.
http
.
HttpResponse
;
import
org
.
apache
.
http
.
client
.
ClientProtocolException
;
import
org
.
apache
.
http
.
client
.
HttpClient
;
import
org
.
apache
.
http
.
client
.
methods
.
HttpGet
;
import
org
.
apache
.
http
.
impl
.
client
.
DefaultHttpClient
;
public
class
APIInvokeClient
{
public
static
void
main
(
String
[
]
args
)
{
String
serviceUrl
=
"http://192.168.100.87:8280/phoneverify"
+
"/CheckPhoneNumber?Phonenumber=13235678906&Licensekey=0"
;
String
accessToken
=
"Bearer 6ca32c4f-80c7-32d2-bdc4-59c61defdd42"
;
HttpClient
httpClient
=
new
DefaultHttpClient
(
)
;
HttpGet
httpGet
=
new
HttpGet
(
serviceUrl
)
;
httpGet
.
setHeader
(
"Authorization:"
,
accessToken
)
;
HttpResponse
response
=
null
;
try
{
response
=
httpClient
.
execute
(
httpGet
)
;
String
result
=
EntityUtils
.
toString
(
response
.
getEntity
(
)
,
"UTF-8"
)
;
System
.
out
.
println
(
result
)
;
}
catch
(
ClientProtocolException
e
)
{
e
.
printStackTrace
(
)
;
}
catch
(
IOException
e
)
{
e
.
printStackTrace
(
)
;
}
}
}
|
请求返回结果:
下载源码,直接利用Maven进行Build:
1
|
# mvn clean install -Dmaven.test.skip=true
|
注意事项:
2.1.0版本所依赖的源码:
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,然后完成页面渲染。
基于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),
启动时打印日志:
与APIM同等部署,修改相同配置,提供监控统计服务。
作为减少或消除不同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
http://product-dist.wso2.com/javadocs/api-manager/2.1.0/
https://github.com/wso2/carbon-kernel/tree/master/docs/DeveloperTools
打开OSGi管理控制台:
1
|
# wso2am-2.1.0/bin/wso2server.sh -DosgiConsole
|
待系统启动后多次回车进入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
内部系统所使用SOAP的Web Service,底层有OSGi服务组件提供服务、上层通过UI组件为用户提供服务、通过Service stub来提供WSDL服务。
查看服务列表:
首先打开显示服务的配置项,修改wso2am-2.1.0/repository/conf/carbon.xml,将
选中需要调用的服务URL,直接在浏览器中添加?wsdl即可获得服务,例如这里我们访问API声明周期的服务https://192.168.100.84:9443/services/LifeCycleManagementService?wsdl,结果如下:
提供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现有功能可以满足要求,只想定制前端页面,可以采用以下方案:
如果API Manager现有的后端服务不能满足需求,需要更深层次的开发,可采用以下方案:
产品上线前的一些测试
API Manager运维的一些考量
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/