简介:WSO2 Enterprise Integrator 6.6.0 使用手册是一份面向企业集成开发与运维人员的操作指南,核心围绕 WSO2 ESB++ 的集成场景,涵盖 REST 代理与路由转发、REST 与 WebService 互相转换、TCP 转 WebService 等常见需求,并介绍了 WSO2 旗下 API Manager、Enterprise Integrator、Identity Server 三款产品的关系与定位。其中 API Manager 负责 API 全生命周期管理,Identity Server 提供单点登录与访问控制,与 EI 协同构成完整的集成生态。
整份手册为 1 个 doc 文档,容量约 1.43MB,内容组织紧凑,已有 2041 人在 CSDN 学习使用,常被作为快速上手 WSO2 EI 的参考资料。
手册重点解释了 ESB 配置文件与业务流程配置文件的差异,以及短期无状态集成流、长期有状态业务流程的架构区分;同时结合消息传递管道、中介框架、BPEL 与 BPMN 运行机制,帮助读者理解消息如何在传输层、中介层与目标端点间流转。
按章节实践,读者可以清晰掌握 REST/WebService/TCP 协议间的转换与路由思路,并理解不同集成场景的配置要点,提升实际排错与项目落地能力。
1. WSO2-ESB 与 WSO2 Enterprise Integrator 6.6.0:这份手册帮你把老接口改造成新服务
做系统集成最耗时间的往往不是写转换代码,而是搞不清中间件把消息送到哪里去了。手头这份 WSO2-ESB、WSO2 Enterprise Integrator 6.6.0 使用手册,不是官网文档的简单搬运,而是把 WSO2 三款产品、ESB 概要文件的消息血缘、核心组件和 REST/SOAP/TCP 互转案例整理成了一条能照着做的学习路径。WSO2 ESB 本身基于 Apache Synapse 和 Axis2 构建,EI 6.6.0 则是把 ESB、消息代理、业务流程引擎和流处理器打包在一起的 ESB++ 方案。
如果你之前只接触过 Spring Cloud 或 Nginx,这套东西第一眼会像黑匣子:要理解 transport、mediator、sequence、registry 这些术语才能配置一个可用的代理服务。这份手册适合两类人:一是准备把老 SOAP 服务改造成 REST 接口的集成开发,二是已经用 WSO2 但每次配置都靠翻官网、想系统补一遍 ESB 概念的运维。看完你会比官方文档多一个收获:知道哪个参数会带来哪些坑。
2. EI 6.6.0 架构先立住:ESB 配置文件内部的消息流转
2.1 WSO2 三款产品各管一段:API Manager、EI、Identity Server
在拆 ESB 之前要把产品边界划清,不然查文档会找错方向。WSO2 有三款开源产品:API Manager 管 API 全生命周期,从创建、发布到监控和版本控制,还包含访问权限、访问流量、API 调用监控;Enterprise Integrator 也就是本文的主角 EI,负责系统间集成,提供数据集成、流程集成和 B2B 集成能力,是集中式集成中间件;Identity Server 管身份,支持单点登录/注销(SSO)、身份联合、强身份验证、细粒度访问控制、API 安全和审计。集成项目里最常见的组合是一个用 Identity Server 做的 SSO 网关,后面挂 EI 的代理服务,再转发到老 SOAP 服务。把边界搞清楚,去看官网文档时才知道该进哪个产品目录。
三款产品都基于 Carbon 平台构建,Carbon 本身是 OSGi 框架,所以 EI 的功能组件可以按需增删。这也是为什么同一套 EI 6.6.0,有人只跑 ESB 概要文件做消息路由,有人跑业务流程概要文件做订单审批流。产品边界理解了,后面看组件配置才不会一脸懵。
2.2 短期无状态集成流:transport 接收后如何走中介框架
EI 6.6.0 里负责消息转换和路由的核心是 ESB 概要文件。它的事件驱动、基于标准的消息引擎(总线)继承自 WSO2 ESB,底层是 Apache Synapse 和 Axis2。一条请求的完整路径是这样的:应用(客户端)先向 ESB 概要文件发消息;transport 把消息拾取后,推进消息管道处理服务质量(QoS)方面的问题,比如安全、可靠消息传输,管道内部实际是 Axis2 引擎的流入流出;然后消息进入中介框架,这一步是消息转换和路由的统一单元,由 Synapse 实现,转换和路由之间没有明确分隔,有些转换发生在路由决策之前,有些发生在路由决策之后;最后消息根据目标注入到单独的管道,再次确定 QoS 后,由 transport 层完成协议转换并发给接收方应用。
有一点容易被忽略:ESB 概要文件有两种运行模式。一种是纯调解(Mediating Messages),使用单个管道;另一种是代理服务(Proxy Services),使用将传输连接到不同代理服务的单独管道。两种模式的区别在于有没有显式的代理服务边界,这直接决定了你要在 Integration Studio 里建一个 Sequence 还是建一个 Proxy Service。另外,ESB 任务和事件这些模块不会出现在消息流图里,但它们负责定时任务和事件触发,生产环境下任务调度的排错往往要回头看这里。
2.3 长期有状态流程:BPEL、BPMN、人工任务三个运行时
与 ESB 概要文件相对的是业务流程概要文件。如果你要跑需要持久化状态的长时间业务流程,比如订单审批超过 90 秒,就不能用无状态的 ESB 调解,而要部署业务流程概要文件。它用 BPMN 2.0、WS-BPEL 2.0、BPEL4People 标准和 WS-Human Tasks 子集开发,BPMN 引擎是 Activiti 5.21.0,BPEL 引擎是 Apache ODE。这条路径上的消息分发要分三种情况看:BPEL 定义的流程和人工任务以 SOAP 服务暴露,走 Axis2 传输层(HTTP、HTTPS、JMS 都能收),消息到达 ODE 引擎前会经过 Axis2 处理 WS-Addressing、WS-Security 等 QoS 要求;BPMN 定义的流程作为 REST API 暴露,部署在嵌入式 Tomcat 里,收到 REST 请求后对已部署的 BPMN 流程执行相关操作;人工任务运行时则把人工交互集成到业务流程工作流中,执行成功会创建任务实例并把实例数据持久化到数据库。数据访问对象层负责与数据库交互,持久化 BPEL 流程定义、实例数据和人工任务实例数据。
这就是为什么 EI 6.xx 被称为 ESB ++:它不只是短时消息路由,还能直接承载有状态的长业务流程,不需要再单独挂一套 BPM 引擎。
2.4 ESB 概要文件之外:Analytics 与 Message Broker 的角色
ESB 概要文件不是 EI 的全部。EI 6.6.0 是 WSO2 EI 6.xx 系列的最新版本,汇集了 ESB、Message Broker(MB)、业务流程服务器(BPS)、流处理器(SP)四块功能。Analytics 概要文件专门做 ESB 统计信息监控和所有消息跟踪活动,生产环境排查慢接口时,EI-Analytics 的追踪数据比看日志更快定位到是哪个 mediator 耗时。Message Broker 概要文件处理可靠消息传递,适合要求不丢消息的异步集成场景。实际操作中,下载完整发行版后 bin 目录里会有多个启动脚本,micro-integrator 指的是纯 ESB 运行时的轻量形态,完整 EI 则包含上述全部概要文件。手册里给的官方下载入口是 Zip Archive,我一般建议先跑 micro-integrator 验证案例,再决定要不要启动完整版,省内存也少踩坑。
3. ESB 核心组件拆开看:Endpoint、Proxy、Mediator、Sequence 与 Registry
3.1 Transports:Message Builders 与 Message Formatters 的分工
WSO2 ESB 支持所有主流传输协议:HTTP、HTTPS、POP、IMAP、SMTP、JMS、AMQP、FIX、TCP、UDP、FTP、FTPS、SFTP、CIFS、MLLP、SMS。每个 transport 背后由一对组件支撑:Message Builders 根据内容类型识别消息并转成 XML,每一种内容类型都有对应的 builder;Message Formatters 则相反,把 XML 格式的消息转成传输前的格式。这一点是很多新手的盲区——你改了 transport 监听端口但没配 builder/formatter,消息进来直接被丢弃。新增传输协议通常走 Axis2 传输框架,把新 transport 的 receiver、sender、builder、formatter 注册进 axis2.xml 即可。理解了这个对称结构,后面配置 TCP 传输时就不会只加 receiver 不加 sender。
3.2 Endpoint 与 format 参数:一个地址背后有四种消息格式
Endpoint 代表一个后台服务,ESB 调用的每个后台服务都要定义 endpoint。Endpoint 可以被指定为 address endpoint、WSDL endpoint、load balancing endpoint,且独立于传输协议,同一个 endpoint 可以用多种协议访问。配置 sequence 或 proxy service 处理 incoming 消息时,必须指定所用 transport 和消息送达的 endpoint。最需要注意的是 format 参数,它决定消息格式转换行为。手册里给的示例配置如下:
<endpoint> <address uri="http://localhost:9000/services/SimpleStockQuoteService" format="soap11"/> </endpoint>这里把 format 指定为 soap11,ESB 送到后台服务前会把消息强制转为 SOAP 1.1。可用的 format 值有 soap11、soap12、pox、get,另外还有 Leave As-Is 选项表示消息不转换。背景服务是 SOAP 服务时用 soap11 或 soap12,是 REST 风格服务时用 pox,需要把消息转成 HTTP GET 请求时用 get。如果不确定后台吃哪种格式,Leave As-Is 最安全,但它不会修正 Content-Type,后台可能 415 报错。Endpoints 不会单独生效,必须配置在 sequence 或 proxy service 里,这是配置 ESB 的第一个结构认知。
3.3 Proxy Service:虚拟服务如何做协议适配
代理服务是 ESB 上的虚拟服务,可以实现多个实际服务的无缝集成。收到消息在送达给定 endpoint 前可以有选择地处理,不改变现有服务就能做转换或增加额外功能。代理服务接收和发送消息可以使用任何传输协议,默认情况下用 HTTP 和 HTTPS。一个代理服务有两个主要消息流:InSequence 代表消息进入 ESB、发送到 endpoint 前对流程进行编排的阶段;OutSequence 处理 endpoint 响应返回给客户端的过程。如果出现错误,fault sequence 被调用。
从 WSO2 ESB 4.x 起引入了 receiving sequence 概念,用户可以指定外部请求从 ESB 处理得到响应的序列,通过 send mediator 指定 receiving sequence,而不是默认走 outSequence。这个特性在做异步回调场景时非常实用。还有一个启动期的行为要记住:ESB 启动时会启动所有代理服务,并获取代理服务关联的 WSDL,如果启动时找不到这些 WSDL,ESB 会忽略该服务并继续启动。所以代理服务「消失」不一定是代码错了,先查启动日志里的 WSDL 加载失败记录。
3.4 Mediators 与 Sequences:消息流的积木与搭积木的方式
Mediator 是 WSO2 ESB 中进行消息处理的基本组件,ESB 中所有消息流都由一系列 mediator 组成。一个 mediator 包含一个输入消息、一个输出消息还有配置,根据配置做输入消息的转换、替换等操作形成输出消息。WSO2 ESB 提供完整的 mediator 库,也可以用 Java、scripting 和 Spring 自行扩展。Sequence 则是由一系列 mediator 组成的复合结构,分配到 sequence 的消息按顺序流经每一个 mediator 并做相应改变。
实际使用里最常用的几个:Property Mediator 设变量和上下文,Enrich Mediator 改消息内容,Send Mediator 指定 endpoint,Log Mediator 打印调试信息。第 4 章的所有案例都会落在这几个组件上。要注意的是 Mediator 的执行顺序就是 sequence 里写的顺序,没有隐式优先级,这也是新手最容易搞翻车的地方——想先改 header 再路由,结果 send 写在了 property 前面。
3.5 Registry:内建配置仓库与三个 repository 的取舍
Registry 是存储各种配置和组件的地方,sequence、endpoint、services、wsdl、配置文件都通过一个 key 引用,类似 UNIX 文件路径。ESB 配置里可以通过 registry provider 接入。常见配置如下:
<registry provider="org.wso2.carbon.mediation.registry.WSO2Registry"> <parameter name="cachableDuration">15000</parameter> </registry>cachableDuration 控制缓存数据的生命周期,单位是毫秒。当消息通过 ESB 且引用了 registry 资源时,ESB 从 registry 获取信息并缓存,缓存改善了消息处理性能,但资源发生变化时,缓存数据不会立刻反映。增大 cachableDuration 可以提升消息处理速度,减小则能确保 registry 资源及时更新。
Carbon 为每个产品提供的 registry 空间分三部分:Local repository 存储本地配置和运行时数据,不允许多个服务器共享,在 /_system/local 目录下;Configuration repository 存储指定产品配置和数据,允许相同产品的多个实例共享,例如 ESB 集群共享 ESB 配置,在 /_system/config 目录下;Governance repository 存储整个平台可共享的配置和数据,包括 service、endpoint、datasources 等,在 /_system/governance 目录下。集成新注册表时必须实现 org.apache.synapse.registry.Registry 接口。生产环境的典型误用是把集群共享的 sequence 放进了 local repository,结果只有一台节点生效。
4. 从表达式到四个案例:把手册里的功能变成可跑的配置
4.1 表达式速查与选型:json-eval、get-property、XPath、fn:concat
WSO2 ESB 里取值表达式有四种常见形态:JSON 取值用 json-eval($.name);Property 取值用 get-property('name') 或者 $ctx:name;XPath 取值用 //getCustomer、//getCustomer/id;字符串拼接用 fn:concat('Routing to ', get-property('Hospital'))。这四种表达式贯穿所有案例,直接决定了 mediator 从哪取数。
| 表达式形态 | 适合场景 | 典型写法 |
|---|---|---|
| json-eval | 请求体是 JSON | json-eval($.orderId) |
| get-property | 读取上下文属性 | get-property('Hospital') |
| XPath | 读取 XML/SOAP 内容 | //getCustomer/id |
| fn:concat | 拼接字符串生成动态内容 | fn:concat('Routing to ', get-property('Hospital')) |
选型上有个经验:JSON 请求不要用 XPath 去取,解析容易翻车;XML/SOAP 请求也别用 json-eval,会取不到值。Property Mediator 配合 get-property 是跨协议传值的通用手段,比如从 InSequence 提取参数,到 OutSequence 再读取拼响应。
4.2 案例一:REST 代理与基于内容的路由转发
官网案例「Sending a Simple Message to a Service」是 REST 代理的入门操作。用 Integration Studio 新建一个 Proxy Service,默认暴露 HTTP 端点,InSequence 直接 send 到 address endpoint 即可。核心配置如下:
<proxy name="RestProxy" startOnLoad="true" transports="http"> <target> <inSequence> <send> <endpoint name="BackendEP"> <address uri="http://localhost:9000/services/SimpleStockQuoteService" format="pox"/> </endpoint> </send> </inSequence> <outSequence> <send/> </outSequence> </target> </proxy>inSequence 收到客户端消息后,send mediator 直接转发到名为 BackendEP 的 endpoint,format 指定 pox 表示按 plain XML 送出,适配不需要 SOAP 信封的后台服务;outSequence 收到响应后直接送回客户端。参数上要注意 startOnLoad 决定 ESB 启动时是否加载该代理,transports 限定接收协议。
基于请求内容做服务编排和路由转发是另一个官网案例。逻辑上用 Property Mediator 取报文里的关键字段,再用 Filter Mediator 判断走哪个 endpoint。常见做法是用 fn:concat 拼一段路由日志,再根据属性值分流,这样消息去了哪里可以在日志里一眼看穿。
4.3 案例二:REST2SOAP,把 JSON 请求包装成 SOAP 报文
Integration Studio 的 Getting Started 界面有案例模板,创建后打开就能看到完整实现。核心思路:REST 请求进来后,先把参数从 JSON 里取出来,再构造 SOAP 请求体,最后 send 到 format 为 soap11 的 endpoint。PayloadFactory 是做报文构造最顺手的 mediator。下面是一个把 REST 请求的 name 参数包装成 SOAP getCustomer 报文的片段:
<property name="name" expression="json-eval($.name)" scope="default"/> <payloadFactory media-type="xml"> <format> <getCustomer xmlns="http://service.example.com"> <customerId>$1</customerId> </getCustomer> </format> <args> <arg value="get-property('name')"/> </args> </payloadFactory> <send> <endpoint> <address uri="http://localhost:9764/services/CustomerService" format="soap11"/> </endpoint> </send>第一步用 property mediator 把 JSON 里的 name 存进上下文;payloadFactory 里 $1 是占位符,由 args 里的 get-property('name') 替换成实际值,拼进 SOAP 报文;send 时 endpoint 的 format 指定 soap11,确保 Axis2 按 SOAP 1.1 序列化。注意 namespace 要和后台服务 WSDL 一致,不一致的话后台会报找不到操作。如果你在自己构造报文而不是用模板,最容易漏的就是 namespace 声明,漏了之后 SOAP 服务解析会直接失败。
4.4 案例三:SOAP2REST,把 SOAP 响应转成干净 JSON
SOAP2REST 是手册里作者自定义构造的部分,方向正好反过来。要把 SOAP 响应解开、取出 body 内容、以 JSON 返回客户端。两个最容易踩的坑:一是忘了设置响应 messageType,二是把 SOAP 信封的命名空间带出来了。常见做法是在 outSequence 里设置 messageType,再用 PayloadFactory 构造 JSON 返回。配置片段如下:
<outSequence> <property name="messageType" value="application/json" scope="axis2"/> <payloadFactory media-type="json"> <format>{"status":"success","value":"$1"}</format> <args> <arg expression="//*[local-name()='return']"/> </args> </payloadFactory> <send/> </outSequence>messageType 设成 application/json 后,Axis2 的 formatter 会按 JSON 输出;payloadFactory 用 JSON media-type 构造响应体;XPath 用 local-name() 绕开命名空间问题,取 SOAP body 里任意名为 return 的元素。注意这里 XPath 匹配的是消息正文里 body 的子元素,SOAP 信封本身不会被带进 JSON。响应体里的 messageType 属性要放在 outSequence 的开头,放在 send 后面就失效了,这个顺序坑我遇到过不止一次。
4.5 案例四:TCP2SOAP,轴 axis2.xml 加传输协议
官网案例在 TCP Transport 页面。TCP 是底层传输协议,EI 的 axis2.xml 里默认只有 HTTP/HTTPS 的 transport receiver,没加 TCP 前端口都不会监听。手册原文强调:需要修改 Runtime 中的 axis2.xml 文件添加 TCP 传输支持,JMS 传输也需要改 axis2.xml,具体协议参考官网文档。WSO2 接受 TCP 三种类型消息:字节、字符、字符串,并且以指定分隔符或者定长字节来区分是否为一个 TCP 请求。
常见做法是在 axis2.xml 的 transportReceiver 区域加 TCP 配置,指定监听端口和报文 contentType:
<transportReceiver name="tcp" class="org.apache.synapse.transport.tcp.SynapseTCPServer"> <parameter name="port">8463</parameter> <parameter name="contentType">text/plain</parameter> </transportReceiver>同时要在 transportSender 里配置对应的发送器和 message builder/formatter。分隔符场景下需要设置报文分隔符,定长报文则要指定固定字节数。这里的关键是改动任何参数后必须重启 EI 运行时,轴 Axis2 传输框架只在启动时加载一次。TCP 场景下粘包和半包问题会比较难排查,建议先用简单的字节消息验证链路通断,再逐渐上复杂报文,不要一上来就调定长解析。
5. WSO2 ESB 高频翻车点:五个避坑与排查记录
5.1 axis2.xml 改了不生效,TCP/JMS 端口没有监听
现象:按官网加了 transportReceiver 和 transportSender,启动日志里看不到 TCP 端口监听,客户端连接直接超时。
原因:改错了文件,或者改完没有完全重启。EI 6.6.0 运行时里 axis2.xml 不是只有一份,Integration Studio 自带的本地运行时和正式 EI 发行版各加载各自的配置。很多人改了 Integration Studio 工作区里的配置,部署到正式环境自然不生效。
解决:先用 grep 确认实际加载的是哪个 axis2.xml,检查配置里有 transportReceiver name="tcp",然后完全停止进程再启动。TCP 和 JMS 传输都不会热部署生效,重复启动或热加载只会让问题更隐蔽。启动后用 netstat 或 lsof 验证端口监听状态,端口起来了再谈报文格式问题。
5.2 代理服务启动时直接消失
现象:服务列表里找不到某个代理服务,或启动日志中该服务被跳过,客户端 404。
原因:代理服务启动时会获取关联的 WSDL。如果 ESB 在启动时找不到这些 WSDL,它会忽略该服务并继续启动,不会报致命错误。这个问题在代理服务引用了远端 WSDL 且网络不可达时尤其常见。
解决:检查代理服务配置里的 WSDL 地址是本地文件还是远端 URL,确认可达性。如果后端服务的 WSDL 不稳定,就下载到本地或手写一个最小描述文件。启动日志里 grep WSDL 相关的 warn 记录,定位具体是哪个服务被跳过。这个行为是设计如此,不是 bug,理解了就不慌。
5.3 Registry 资源改了不生效,序列还是旧的
现象:修改了 registry 里引用的 sequence 或 endpoint,客户端调用行为没有变化,要等一段时间才变。
原因:Registry 有缓存机制,cachableDuration 参数控制缓存生命周期,默认 15000 毫秒。在缓存有效期内,ESB 不会感知资源变化。
解决:调整 cachableDuration 参数,改小可以加快资源更新速度,但会牺牲消息处理性能。如果改动很频繁,建议在维护窗口期统一改完再重启,而不是边改边调参。另外要确认改动写进了正确的 repository:local repository 不允许多服务器共享,在集群环境下只改本机是不生效的。
5.4 XPath 在 SOAP 消息里取不到值
现象:Property Mediator 里写 //getCustomer,日志打印出来是空值,路由条件永远不成立。
原因:SOAP 消息 body 里的元素带命名空间,//getCustomer 匹配的是无命名空间的同名元素。SOAP 信封本身就有默认命名空间,直接写不带前缀的 XPath 匹配不到目标节点。
解决:用 local-name() 忽略命名空间,写成 //*[local-name()='getCustomer']/id;或者用完整命名空间声明写 XPath。生产环境建议后者,语义更明确,也不容易误匹配。这个坑在 REST2SOAP 之后取响应内容时最常出现,因为后台返回的 SOAP 响应都是带命名空间的。
5.5 官网样例直接跑不通
现象:跟着官网文档的配置抄下来,本地运行时带不起来,或者启动了但行为不对。
原因:官网大量案例基于 Axis2 服务和 Ant 构建,文档版本和 EI 6.6.0 的 Integration Studio 模板有差异。直接下载官网 XML 配置灌进 EI runtime,缺少配套的 Axis2 服务端和构建依赖,自然跑不通。
解决:先从 Integration Studio 的 Getting Started 模板起项目,模板是配套当前版本的。需要理解案例思路后再搬到自定义代理里,不要直接拿旧版 XML 复制粘贴。手册还提到要会使用 Apache Ant,很多官网案例需要 Ant Build,环境变量里没有 Ant 的话案例工程会直接构建失败。
6. 让调试少走弯路:本地起一个 micro-integrator 再谈上线
6.1 本地运行三步验证
拿到手册里任何一个案例,我建议先做三件事:在 Integration Studio 里把项目部署到本地运行时,启动 micro-integrator,再用 curl 打代理服务验证链路。REST 代理直接用 curl 就能验证,不需要额外工具:
curl -v -X POST http://localhost:8290/services/RestProxy \ -H "Content-Type: application/json" \ -d '{"name":"test"}'本地跑通后再打包 composite application 部署到正式 EI。这一步能挡掉大部分配置低级错误,比如 endpoint 地址写错、format 设错、sequence 忘挂。
6.2 我常用的链路调试组合拳
在 InSequence 开头插一个 log mediator,打印 transport headers 和关键参数;在 outSequence 再插一个 log 打印响应。这个习惯配合 EI 的 mediation 日志,能把多数「消息不知道去哪了」的问题找回来。log mediator 的典型写法如下:
<log level="custom"> <property name="direction" value="in"/> <property name="payload" expression="json-eval($.name)"/> </log>level 为 custom 时只输出手动指定的属性,expression 支持 json-eval 和 XPath,输出进 logs/mediator.log。调试完成后记得删掉或注释掉这些 log,避免生产环境日志爆炸。手册里提到的 EI-Analytics 可以做更完整的消息追踪,但日常开发调试用 log 最省事。
从那以后,我每次接 WSO2 的集成需求,都会先花一刻钟把 axis2.xml 的传输协议清单、registry 的缓存周期、代理服务的 WSDL 来源各过一遍,再动手写 sequence。这套习惯帮我避开了至少一半的半夜紧急修复。希望帮到你。
本文还有配套的精品资源,点击获取