Apache Synapse ESB

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.

译注:本文涉及到许多 Web Service 标准中的术语,在国内并无广泛本地化的译法,其中 mediation 译为“中转”,endpoint 译为“服务末端”。

快速入门指南

本文给出两个应用示例,覆盖 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 客户端 发送的报文,实际内容如下:

POST / HTTP/1.1
Content-Type: text/xml; charset=UTF-8
SOAPAction: &quot;urn:getQuote&quot;
User-Agent: Axis2
Host: 127.0.0.1
Transfer-Encoding: chunked

218
<?xml version='1.0' encoding='UTF-8'?>
   <soapenv:Envelope xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
      <soapenv:Header>
         <wsa:To>http://localhost:9000/services/SimpleStockQuoteService</wsa:To>
         <wsa:MessageID>urn:uuid:D538B21E30B32BB8291177589283717</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>0

看一下运行着 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 &lt;main&gt;
2012-09-18 09:46:57,909 [-] [HttpServerWorker-2] DEBUG SequenceMediator Sequence &lt;SequenceMediator&gt; :: 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: &lt;?xml version='1.0' encoding='utf-8'?&gt;&lt;soapenv:Envelope xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;&lt;soapenv:Header xmlns:wsa=&quot;http://www.w3.org/2005/08/addressing&quot;&gt;&lt;wsa:To&gt;http://localhost:9000/services/SimpleStockQuoteService&lt;/wsa:To&gt;&lt;wsa:MessageID&gt;urn:uuid:754cc296-ff58-4875-a999-3a33ec94c8a1&lt;/wsa:MessageID&gt;&lt;wsa:Action&gt;urn:getQuote&lt;/wsa:Action&gt;&lt;/soapenv:Header&gt;&lt;soapenv:Body&gt;&lt;m0:getQuote xmlns:m0=&quot;http://services.samples&quot;&gt;&lt;m0:request&gt;&lt;m0:symbol&gt;IBM&lt;/m0:symbol&gt;&lt;/m0:request&gt;&lt;/m0:getQuote&gt;&lt;/soapenv:Body&gt;&lt;/soapenv:Envelope&gt;
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 &lt;main&gt;
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 &lt;main&gt;
2012-09-18 09:46:58,036 [-] [HttpClientWorker-2] DEBUG SequenceMediator Sequence &lt;SequenceMediator&gt; :: 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 &lt;main&gt;

过完第一部分内容后,下面我们来看看下一个场景:使用代理服务来实现服务中转。

服务中转(代理服务)

顾名思义,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 及以上的示例,深入了解更高级的用例。

总结

这份快速入门指南到此结束,也是时候更深入一步去探索Synapse的高级特性了。可以浏览感兴趣的各组示例。若遇到任何问题,随时可以在 Synapse 用户邮件列表交流 (http://synapse.apache.org/mail-lists.html)。

posted @ 2022-07-01 22:10  x3d  阅读(282)  评论(0编辑  收藏  举报