ESB-企业服务总线,是面向服务架构SOA的基础性组件。SOA 作为一种软件架构思想,出现于上世纪90年代末,它定义了一种基于服务接口的形式实现软件组件复用的方法。
ESB 体现了一种中心化的应用软件组件架构模式,它在数据模型之间进行转换、处理连接、进行报文路由分配、转换通信协议。ESB将这些集成与转换以服务接口的形式被新应用所复用。
ESB 模式要达到最大可能性的生产力,往往以专门设计的集成运行环境和工具形式实现,如 ESB 产品。
当今渐成主流的去中心化、分布式的微服务架构思想,与 SOA 这种中心化的服务架构思想,尽管在“服务化”思想一脉相承,但形式上又截然相反。ESB 还没坐热板凳,微服务已经后来居上。正如 2015年的VR元年还在津津热道,2021就已经被元宇宙元年替代,科技界创新层出不穷、愈演愈烈,图穷后什么匕会“见”呢?
不过对于我等技术人员,了解这些技术发展趋势和核心思想非常重要,“一门学问的开端最好是它的思想史”。
翻译了一段 Apache Synapse 的文档,来了解ESB产品的一些核心内容。
Script Mediator
Synapse 支持各种脚本语言如 JavaScript、Python、Ruby 等实现的中转器。脚本中转器的定义有两种方式:脚本程序语句保存在独立的文件中(可以从本地或者远程两种方式引用);脚本程序语言内嵌到 Synapse 配置中。独立文件配置形式如下:
<script key="string" language="string" [function="script-function-name"]/>
"key" 属性注册要加载的脚本。"language" 属性声明脚本代码的类型(如 "js"
- Javascript, "rb" - Ruby, "groovy" - Groovy, "py" - Python..)。"function" 属性是个可选属性,定义脚本中需要调用的函数名,若不声明该属性则代表按默认函数名'mediate'进行调用。该函数有一个入参,参数类型: Synapse MessageContext;出参为 boolean 类型,若函数无返回值,则系统自动以 true 值返回。内嵌配置形式如下:
<script language="string">...script source code...<script/>
如果脚本中调用了其它脚本中定义的函数,被引用的脚本也应当被包含到脚本中转器配置中 - 用 'include' 子元素。'include' 元素中的 “key” 属性指向被包含的脚本文件,可以是本地或远程。脚本的包含形式定义如下:
<script key="string" language="string" [function="script-function-name"]>
<include key="string"/>
</script>
脚本的执行上下文环境中,可以以名为 'mc' 的变量方式访问预定义的 Synapse MessageContext 对象。比如,一个使用 JavaScript/E4X 引擎的内嵌式脚本中转器,要实现当 SOAP 报文中包含一个值为 “IBM” 的 'symbol' 元素时返回 false 的效果,代码如下:
<script language="js">mc.getPayloadXML()..symbol != "IBM";<script/>
Synapse 的脚本语言支持特性采用的是 Apache
Bean Scripting Framework,即 BSF 所支持的任意一种语言都可以用来实现 Synapse 中转器。
相比于 Synapse 的其它内置类型中转器或者用 Java 实现的自定义类中转器,用脚本语言实现中转器有一些优点。脚本中转器既拥有类中转器的所有灵活性 - 访问 Synapse MessageContext 对象、及 SynapseEnvironment 相关 API,又具有脚本语言的易用性及动态天性 - 可以进行中转器的快速开发与原型实现。另一项益处,有些脚本语言如 JavaScript E4X 或 Ruby REXML,拥有非常简洁优雅的 XML 操纵能力,使得他们极其适用于 Synapse 中转器环境。针对所有类型的脚本中转器定义,传到脚本中的 MessageContext 对象相比于标准的 Synapse MessageContext 对象,带有一些额外的方法,可以在脚本语言中以更自然的方式处理 XML。如使用 JavaScript 时的 E4X XML 对象和使用 Ruby 时的 REXML 文档,带有 getPayloadXML 和 setPayloadXML 方法。
完整的可用方法清单,可参看
ScriptMessageContext Javadoc.
<div class="section">
<div>译注:本文涉及到许多 Web Service 标准中的术语,在国内并无广泛本地化的译法,其中 mediation 译为“中转”,endpoint 译为“服务末端”。</div>
快速入门指南
本文给出两个应用示例,覆盖 Synapse 的两个基础使用场景:报文中转与服务中转,带你从零开始一步步围绕 Synapse 报文模型进行体验。
环境准备
在进行后续内容之前,系统中应该已经安装了下列必备软件:
安装 Synapse
先下载 Apache Synapse。启动一个网页浏览器,转到 Synapse Downloads 页面。下载最新版的二进制分发文件 - 有标准的 zip 格式和 Unix 的 tar 格式.
下载后把压缩文件解压到硬盘上的合适位置即可。解压后会创建一个名为“synapse-版本号”的目录,该目录下包含了Synapse运行时所用到的全部库、配置文件、脚本及其它制品。后文中这个目录会被引用为 “{SYNAPSE_HOME}” ,比如 {SYNAPSE_HOME}/bin 代表 Synapse 安装目录下的 bin 子目录 。
运行 Axis2 Server
本节所描述的示例包含了通过 Synapse ESB 将报文发送给 Web Service 的能力。在真实应用情况下,这些 Web Service 可能被托管在你公司内的Web服务器中或互联网上,此处我们则通过 Synapse 实现一个简单的 Web Service 并将其部署到 Synapse 捆绑的 Axis2 Server 中。
将示例服务部署到 Axis2 Server: 进入 {SYNAPSE_HOME}/samples/axis2Server/src/SimpleStockQuoteService 目录并运行 'ant' 命令,在服务构建和部署的过程中将会看到类似如下输出内容。
user@domain:/opt/synapse-3.0.1/samples/axis2Server/src/SimpleStockQuoteService$ ant
Buildfile: build.xml
clean:
init:
[mkdir] Created dir: /opt/synapse-3.0.1/samples/axis2Server/src/SimpleStockQuoteService/temp
[mkdir] Created dir: /opt/synapse-3.0.1/samples/axis2Server/src/SimpleStockQuoteService/temp/classes
[mkdir] Created dir: /opt/synapse-3.0.1/samples/axis2Server/repository/services
compile-all:
[javac] Compiling 9 source files to /opt/synapse-3.0.1/samples/axis2Server/src/SimpleStockQuoteService/temp/classes
build-service:
[mkdir] Created dir: /opt/synapse-3.0.1/samples/axis2Server/src/SimpleStockQuoteService/temp/SimpleStockQuote
[mkdir] Created dir: /opt/synapse-3.0.1/samples/axis2Server/src/SimpleStockQuoteService/temp/SimpleStockQuote/META-INF
[copy] Copying 1 file to /opt/synapse-3.0.1/samples/axis2Server/src/SimpleStockQuoteService/temp/SimpleStockQuote/META-INF
[copy] Copying 9 files to /opt/synapse-3.0.1/samples/axis2Server/src/SimpleStockQuoteService/temp/SimpleStockQuote
[jar] Building jar: /opt/synapse-3.0.1/samples/axis2Server/repository/services/SimpleStockQuoteService.aar
BUILD SUCCESSFUL
Total time: 1 second
在进入 {SYNAPSE_HOME}/samples/axis2Server 目录,并启动示例服务,命令如下:
Linux / Unix: . axis2server.sh
Windows: axis2server.bat
Axis2 Server 即被启动,HTTP 端口为 9000。打开浏览器,跳转到 URL http://localhost:9000/services/SimpleStockQuoteService?wsdl 就能看到示例服务的 WSDL 描述。
报文中转
现在已经做好了体验第一个 Synapse 场景的全部准备工作。在 {SYNAPSE_HOME}/repository/conf/sample 目录下存在 synapse_sample_0.xml 文件,然后会用该示例配置启动 Synapse。该配置中启用了对所有通过服务总线传过来的报文进行记录的设置:
<definitions xmlns="http://ws.apache.org/ns/synapse">
<sequence name="main">
<log level="full"/>
<send/>
</sequence>
</definitions>
进入 {SYNAPSE_HOME}/bin 目录,执行以下命令启动 ESB:
Linux / Unix: . synapse.sh -sample 0
Windows: synapse.bat -sample 0
在按上述配置启动 Synapse 的过程中,控制台中将会显示如下报文:
Starting Synapse/Java ...
Using SYNAPSE_HOME: /opt/synapse-3.0.1
Using JAVA_HOME: /opt/jdk1.7.0_79
Using SYNAPSE_XML: /opt/synapse-3.0.1/repository/conf/sample/synapse_sample_0.xml
2016-12-28 10:38:00,456 [-] [main] INFO SynapseServer Starting Apache Synapse...
2016-12-28 10:38:00,476 [-] [main] INFO SynapseControllerFactory Using Synapse home : /opt/synapse-3.0.1
2016-12-28 10:38:00,476 [-] [main] INFO SynapseControllerFactory Using Axis2 repository : /opt/synapse-3.0.1/repository
2016-12-28 10:38:00,476 [-] [main] INFO SynapseControllerFactory Using axis2.xml location : /opt/synapse-3.0.1/repository/conf/axis2.xml
2016-12-28 10:38:00,476 [-] [main] INFO SynapseControllerFactory Using synapse.xml location : /opt/synapse-3.0.1/repository/conf/sample/synapse_sample_0.xml
2016-12-28 10:38:00,476 [-] [main] INFO SynapseControllerFactory Using server name : localhost
2016-12-28 10:38:00,493 [-] [main] INFO SynapseControllerFactory The timeout handler will run every : 15s
2016-12-28 10:38:00,566 [-] [main] INFO Axis2SynapseController Initializing Synapse at : Wed Dec 28 10:38:00 IST 2016
2016-12-28 10:38:01,140 [-] [main] INFO PassThroughHttpSSLSender Loading Identity Keystore from : lib/identity.jks
2016-12-28 10:38:01,174 [-] [main] INFO PassThroughHttpSSLSender Loading Trust Keystore from : lib/trust.jks
2016-12-28 10:38:01,242 [-] [main] INFO PassThroughHttpSSLSender Pass-through HTTPS sender started...
2016-12-28 10:38:01,243 [-] [main] INFO PassThroughHttpSender Pass-through HTTP sender started...
2016-12-28 10:38:01,249 [-] [main] INFO JMSSender JMS Sender started
2016-12-28 10:38:01,250 [-] [main] INFO JMSSender JMS Transport Sender initialized...
2016-12-28 10:38:01,251 [-] [main] INFO VFSTransportSender VFS Sender started
2016-12-28 10:38:01,428 [-] [main] INFO PassThroughHttpSSLListener Loading Identity Keystore from : lib/identity.jks
2016-12-28 10:38:01,429 [-] [main] INFO PassThroughHttpSSLListener Loading Trust Keystore from : lib/trust.jks
2016-12-28 10:38:01,443 [-] [main] INFO Axis2SynapseController Loading mediator extensions...
2016-12-28 10:38:01,451 [-] [main] INFO XMLConfigurationBuilder Generating the Synapse configuration model by parsing the XML configuration
2016-12-28 10:38:01,506 [-] [main] INFO SynapseConfigurationBuilder Loaded Synapse configuration from : /opt/synapse-3.0.1/repository/conf/sample/synapse_sample_0.xml
2016-12-28 10:38:01,542 [-] [main] INFO Axis2SynapseController Deploying the Synapse service...
2016-12-28 10:38:01,563 [-] [main] INFO Axis2SynapseController Deploying Proxy services...
2016-12-28 10:38:01,563 [-] [main] INFO Axis2SynapseController Deploying EventSources...
2016-12-28 10:38:01,584 [-] [main] INFO PassThroughHttpSSLListener Starting pass-through HTTPS listener...
2016-12-28 10:38:01,601 [-] [main] INFO PassThroughHttpSSLListener Pass-through HTTPS listener started on port: 8243
2016-12-28 10:38:01,601 [-] [main] INFO PassThroughHttpListener Starting pass-through HTTP listener...
2016-12-28 10:38:01,603 [-] [main] INFO PassThroughHttpListener Pass-through HTTP listener started on port: 8280
2016-12-28 10:38:01,603 [-] [main] INFO Axis2SynapseController Management using JMX available via: service:jmx:rmi:///jndi/rmi://localhost:1099/synapse
2016-12-28 10:38:01,606 [-] [main] INFO TimeoutHandler This engine will expire all callbacks after : 180 seconds, irrespective of the timeout action, after the specified or optional timeout
2016-12-28 10:38:01,607 [-] [main] INFO ServerManager Server ready for processing...
2016-12-28 10:38:01,608 [-] [main] INFO SynapseServer Apache Synapse started successfully
注意:Synapse 监听 HTTP 请求的默认端口为 8280。
执行示例
有了托管在 Axis2 中的 Web Service,以及一个配置成记录和转发报文的 Synapse ESB 实例,接下来向 Synapse 发送请求,就可以见证奇迹发生了。Synapse 捆绑了一个 Web Service 客户端,可用于发送各种类型的请求,进入 {SYNAPSE_HOME}/samples/axis2Client 目录并执行以下命令,向 Synapse 发送请求:
ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280 -Dmode=quote -Dsymbol=IBM
控制台中应该会显示以下输出:
Buildfile: build.xml
init:
[mkdir] Created dir: /opt/synapse-3.0.1/samples/axis2Client/target/classes
compile:
[javac] Compiling 22 source files to /opt/synapse-3.0.1/samples/axis2Client/target/classes
[javac] Note: /opt/synapse-3.0.1/samples/axis2Client/src/samples/userguide/PWCallback.java uses or overrides a deprecated API.
[javac] Note: Recompile with -Xlint:deprecation for details.
[javac] Note: /opt/synapse-3.0.1/samples/axis2Client/src/samples/userguide/LoadbalanceFailoverClient.java uses unchecked or unsafe operations.
[javac] Note: Recompile with -Xlint:unchecked for details.
stockquote:
[java] 2010-11-26 01:35:16,485 [-] [main] INFO MailTransportSender MAILTO Sender started
[java] 2010-11-26 01:35:16,496 [-] [main] INFO JMSSender JMS Sender started
[java] 2010-11-26 01:35:16,497 [-] [main] INFO JMSSender JMS Transport Sender initialized...
[java] Standard :: Stock price = $99.14593325984416
BUILD SUCCESSFUL
Total time: 5 seconds
它代表发送一个股价查询请求,代码为 'IBM'。查询 URL 为 http://localhost:8280 (Synapse) 、 WS-Addressing EPR 设置为 http://localhost:9000/services/SimpleStockQuoteService (Axis2)。Synapse 先记录报文,然后将它转发到给定的 WS-Addressing 头信息中。通过 Synapse WS 客户端 发送的报文,实际内容如下:
看一下运行着 Synapse 的控制台,通过 Synapse 中转传递的 SOAP 报文详情都被记录下来了。如果以调试模式运行 Synapse - 编辑 lib/log4j.properties 文件并将 "log4j.category.org.apache.synapse" 从 INFO 设置为 "DEBUG",重启服务后重新执行上述场景,将能看到更多信息。
2012-09-18 09:46:57,909 [-] [HttpServerWorker-2] DEBUG SynapseMessageReceiver Synapse received a new message for message mediation...
2012-09-18 09:46:57,909 [-] [HttpServerWorker-2] DEBUG SynapseMessageReceiver Received To: http://localhost:9000/services/SimpleStockQuoteService
2012-09-18 09:46:57,909 [-] [HttpServerWorker-2] DEBUG SynapseMessageReceiver SOAPAction: urn:getQuote
2012-09-18 09:46:57,909 [-] [HttpServerWorker-2] DEBUG SynapseMessageReceiver WSA-Action: urn:getQuote
2012-09-18 09:46:57,909 [-] [HttpServerWorker-2] DEBUG Axis2SynapseEnvironment Injecting MessageContext
2012-09-18 09:46:57,909 [-] [HttpServerWorker-2] DEBUG Axis2SynapseEnvironment Using Main Sequence for injected message
2012-09-18 09:46:57,909 [-] [HttpServerWorker-2] DEBUG SequenceMediator Start : Sequence <main>
2012-09-18 09:46:57,909 [-] [HttpServerWorker-2] DEBUG SequenceMediator Sequence <SequenceMediator> :: mediate()
2012-09-18 09:46:57,909 [-] [HttpServerWorker-2] DEBUG LogMediator Start : Log mediator
2012-09-18 09:46:57,910 [-] [HttpServerWorker-2] INFO LogMediator To: http://localhost:9000/services/SimpleStockQuoteService, WSAction: urn:getQuote, SOAPAction: urn:getQuote, ReplyTo: http://www.w3.org/2005/08/addressing/anonymous, MessageID: urn:uuid:754cc296-ff58-4875-a999-3a33ec94c8a1, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsa:To>http://localhost:9000/services/SimpleStockQuoteService</wsa:To><wsa:MessageID>urn:uuid:754cc296-ff58-4875-a999-3a33ec94c8a1</wsa:MessageID><wsa:Action>urn:getQuote</wsa:Action></soapenv:Header><soapenv:Body><m0:getQuote xmlns:m0="http://services.samples"><m0:request><m0:symbol>IBM</m0:symbol></m0:request></m0:getQuote></soapenv:Body></soapenv:Envelope>
2012-09-18 09:46:57,910 [-] [HttpServerWorker-2] DEBUG LogMediator End : Log mediator
2012-09-18 09:46:57,910 [-] [HttpServerWorker-2] DEBUG SendMediator Start : Send mediator
2012-09-18 09:46:57,910 [-] [HttpServerWorker-2] DEBUG SendMediator Sending request message using implicit message properties..
Sending To: http://localhost:9000/services/SimpleStockQuoteService
SOAPAction: urn:getQuote
2012-09-18 09:46:57,910 [-] [HttpServerWorker-2] DEBUG Axis2FlexibleMEPClient Sending [add = false] [sec = false] [rm = false] [to=Address: http://localhost:9000/services/SimpleStockQuoteService]
2012-09-18 09:46:57,910 [-] [HttpServerWorker-2] DEBUG Axis2FlexibleMEPClient Message [Original Request Message ID : urn:uuid:754cc296-ff58-4875-a999-3a33ec94c8a1] [New Cloned Request Message ID : urn:uuid:835c68a7-0645-496d-9acc-1d84a03ccb09]
2012-09-18 09:46:57,911 [-] [HttpServerWorker-2] DEBUG SynapseCallbackReceiver Callback added. Total callbacks waiting for : 1
2012-09-18 09:46:57,912 [-] [HttpServerWorker-2] DEBUG SendMediator End : Send mediator
2012-09-18 09:46:57,912 [-] [HttpServerWorker-2] DEBUG SequenceMediator End : Sequence <main>
2012-09-18 09:46:58,035 [-] [HttpClientWorker-2] DEBUG SynapseCallbackReceiver Callback removed for request message id : urn:uuid:835c68a7-0645-496d-9acc-1d84a03ccb09. Pending callbacks count : 0
2012-09-18 09:46:58,035 [-] [HttpClientWorker-2] DEBUG SynapseCallbackReceiver Synapse received an asynchronous response message
2012-09-18 09:46:58,035 [-] [HttpClientWorker-2] DEBUG SynapseCallbackReceiver Received To: null
2012-09-18 09:46:58,035 [-] [HttpClientWorker-2] DEBUG SynapseCallbackReceiver SOAPAction:
2012-09-18 09:46:58,035 [-] [HttpClientWorker-2] DEBUG SynapseCallbackReceiver WSA-Action:
2012-09-18 09:46:58,036 [-] [HttpClientWorker-2] DEBUG SynapseCallbackReceiver Body :
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns:getQuoteResponse xmlns:ns="http://services.samples"><ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns:GetQuoteResponse"><ns:change>4.158253518011668</ns:change><ns:earnings>13.000214652478554</ns:earnings><ns:high>176.07121446241788</ns:high><ns:last>171.44223855674258</ns:last><ns:lastTradeTimestamp>Tue Sep 18 09:46:57 CEST 2012</ns:lastTradeTimestamp><ns:low>-169.3791832231285</ns:low><ns:marketCap>3.844340450887613E7</ns:marketCap><ns:name>IBM Company</ns:name><ns:open>-167.9098655007073</ns:open><ns:peRatio>-17.815829214870217</ns:peRatio><ns:percentageChange>-2.4400099237243</ns:percentageChange><ns:prevClose>-170.41953303471544</ns:prevClose><ns:symbol>IBM</ns:symbol><ns:volume>16090</ns:volume></ns:return></ns:getQuoteResponse></soapenv:Body></soapenv:Envelope>
2012-09-18 09:46:58,036 [-] [HttpClientWorker-2] DEBUG Axis2SynapseEnvironment Injecting MessageContext
2012-09-18 09:46:58,036 [-] [HttpClientWorker-2] DEBUG Axis2SynapseEnvironment Using Main Sequence for injected message
2012-09-18 09:46:58,036 [-] [HttpClientWorker-2] DEBUG SequenceMediator Start : Sequence <main>
2012-09-18 09:46:58,036 [-] [HttpClientWorker-2] DEBUG SequenceMediator Sequence <SequenceMediator> :: mediate()
2012-09-18 09:46:58,036 [-] [HttpClientWorker-2] DEBUG LogMediator Start : Log mediator
2012-09-18 09:46:58,037 [-] [HttpClientWorker-2] INFO LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , ReplyTo: http://www.w3.org/2005/08/addressing/anonymous, MessageID: urn:uuid:835c68a7-0645-496d-9acc-1d84a03ccb09, Direction: response, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns:getQuoteResponse xmlns:ns="http://services.samples"><ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns:GetQuoteResponse"><ns:change>4.158253518011668</ns:change><ns:earnings>13.000214652478554</ns:earnings><ns:high>176.07121446241788</ns:high><ns:last>171.44223855674258</ns:last><ns:lastTradeTimestamp>Tue Sep 18 09:46:57 CEST 2012</ns:lastTradeTimestamp><ns:low>-169.3791832231285</ns:low><ns:marketCap>3.844340450887613E7</ns:marketCap><ns:name>IBM Company</ns:name><ns:open>-167.9098655007073</ns:open><ns:peRatio>-17.815829214870217</ns:peRatio><ns:percentageChange>-2.4400099237243</ns:percentageChange><ns:prevClose>-170.41953303471544</ns:prevClose><ns:symbol>IBM</ns:symbol><ns:volume>16090</ns:volume></ns:return></ns:getQuoteResponse></soapenv:Body></soapenv:Envelope>
2012-09-18 09:46:58,037 [-] [HttpClientWorker-2] DEBUG LogMediator End : Log mediator
2012-09-18 09:46:58,037 [-] [HttpClientWorker-2] DEBUG SendMediator Start : Send mediator
2012-09-18 09:46:58,037 [-] [HttpClientWorker-2] DEBUG SendMediator Sending response message using implicit message properties..
Sending To: http://www.w3.org/2005/08/addressing/anonymous
SOAPAction:
2012-09-18 09:46:58,038 [-] [HttpClientWorker-2] DEBUG SendMediator End : Send mediator
2012-09-18 09:46:58,038 [-] [HttpClientWorker-2] DEBUG SequenceMediator End : Sequence <main>
过完第一部分内容后,下面我们来看看下一个场景:使用代理服务来实现服务中转。
服务中转(代理服务)
顾名思义,Synapse 托管的代理服务作为一个居间性的服务,通常作为现存服务末端(endpoint) 的前端。请求报文发送给实际的服务末端前,代理服务能够对请求进行居间的调整;类似的,也能在返回给客户端前对服务末端响应的报文进行居间处理。比如将服务末端暴露为不同的Transport、Schema、WSDL或者QoS设置(WS-Security, WS-Reliable Messaging)。
客户端应用直接向 Synapse 发送请求,从客户端的视角,代理服务就是托管在 Synapse 上,在 URL 后面追加 '?wsdl' 后缀可以得到这些虚拟服务的 WSDL。但是在 Synapse 配置中,请求可以按你所需任意处理。最常见的是对报文做些处理再发送给运行在另一台主机上的服务;当然这个过程不是必须的,还可以是执行一组任务来处理接收到的报文,然后直接终止流程或者向客户端返回报文。
本场景依赖前一个示例中用到的股价查询服务,所以确保其已被部署到 Axis2 且 Axis2 Server 在运行中。
接下来启动包含代理服务配置的Synapse。位于 epository/conf/sample 目录下 synapse_sample_150.xml 文件中的配置与本文讨论范围比较匹配。
<definitions xmlns="http://synapse.apache.org/ns/2010/04/configuraiton">
<proxy name="StockQuoteProxy">
<target>
<endpoint>
<address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
</endpoint>
<outSequence>
<send/>
</outSequence>
</target>
<publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/>
</proxy>
</definitions>
上述配置暴露了一个名为 StockQuoteProxy 的代理服务,并声明了endpoint标签(http://localhost:9000/services/SimpleStockQuoteService)作为该代理服务的实际目标(从代理服务过来的报文将会转向该地址)。outSequence 标签定义该代理服务响应报文的出序-如何将将报文返回给客户端。publishWSDL 标签声明该代理服务对外发布的WSDL。在 {SYNAPSE_HOME}/bin 目录下运行以下命令启动示例配置的Synapse:
Linux / Unix: . synapse.sh -sample 150
Windows: synapse.bat -sample 150
Synapse 会像前一个示例一样显示启动过程中的那些报文。在运行该客户端之前,要观察代理服务的另一个特性-显示已发布的WSDL。打开网页浏览器,转到 URL http://localhost:8280/services/StockQuoteProxy?wsdl ,将会看到配置中所声明的 sample_proxy_1.wsdl 内容,并包含了该服务通过 HTTP/S 访问的正确 EPR。
执行示例
从 Axis2 客户端发送请求,调用该代理服务。进入 {SYNAPSE_HOME}/samples/axis2Client 目录,运行以下命令:
ant stockquote -Dtrpurl=http://localhost:8280/services/StockQuoteProxy -Dmode=quote -Dsymbol=IBM
以上命令直接发送“股价查询”请求给对外暴露的服务末端(位于 http://localhost:8280/services/StockQuoteProxy)。代理服务将报文转发给 Axis2 Server(运行股价查询服务所在),并将其响应报文返回给客户端。在控制台可以看到服务端响应的报文:
Standard :: Stock price = $165.32687331383468
关于代理服务的更多内容
代理服务是 Apache Synapse 中最强大的功能性组件,可用于执行传输切换、报文格式切换及更多任务。本文仅覆盖了代理服务的简单用例,可以参考 Synapse 示例目录中编号 #150 及以上的示例,深入了解更高级的用例。