简介:这是一份面向 WSO2 Enterprise Integrator 6.6.0 的中文使用手册,定位为 WSO2 ESB 升级版的企业集成实操指南,适合中间件工程师、架构师以及正在选型或落地 WSO2 产品的团队阅读。文档先介绍 WSO2 三款开源产品(API Manager、Enterprise Integrator、Identity Server)的定位与分工,再深入 ESB 配置文件的消息流架构,梳理请求从传输层、Axis2 管道、中介框架到目标端点的完整路径,说明短期无状态集成流与长期有状态业务流程(BPEL、BPMN、人工任务)的实现方式。同时覆盖 REST 代理、路由转发、REST 与 WebService 双向转换、TCP 转 WebService 等高频场景,帮助读者理解中介框架下的消息转换与路由机制,以及 ESB、业务流程、Analytics 等多配置文件的适用条件。资源为单个 doc 文档,体积仅 1.43MB,内容组织紧凑,可直接按章节查阅协议配置与集成示例,也适合作为实施过程中的速查手册。目前已有 2041 人学习,对初次接触 WSO2 EI 的开发者或需要快速搭建企业集成方案的工程师具有实用参考价值。
1. 拿到 EI 6.6.0 手动搭建集成网关:资历老、资料散、坑也实在
做系统集成的这些年,不少人第一次接触 WSO2 Enterprise Integrator 都是被同一个问题逼来的:手头有旧系统要接新服务,协议五花八门——REST 的要转成 SOAP 发给老平台,TCP 报文要塞进 WebService,还要带鉴权和路由。某个开发者当时在模拟项目X里就是这么被卡的,翻遍官网文档发现资料虽全但太散,中文实操笔记更是各说各话。这份 WSO2-EI 6.6.0 使用手册解决的就是这个痛点:它把 ESB 概要文件的两类消息流讲明白了,还内置 REST2SOAP、SOAP2REST、TCP2SOAP 三个可照着做的案例。适合刚接手集成中间件、被协议转换折腾的开发者,也适合需要快速评估 EI 和 ESB 差异的技术负责人。
2. EI 6.6.0 到底整合了什么:从 ESB++ 到三大配置文件的边界理清
2.1 产品家族不是三选一,是按场景分工
WSO2 生态里常被拿出来说的三件套——API Manager、Enterprise Integrator、Identity Server——各管一段。API Manager 管 API 全生命周期,从创建发布到流量控制和版本管理都在它手里;Identity Server 管身份与访问,单点登录、身份联合、细粒度访问控制是它的主场。真正干集成活儿的是 Enterprise Integrator,它把原本分散的 ESB、消息代理、业务流程服务器和流处理器收进了一个运行时。
选型时容易踩的误区是:以为上了 EI 就得把 AM 和 IS 也一起部署。实际不是这样,EI 6.6.0 自带注册表和安全管理能力,单机就能撑起一条完整的集成链路。只有当你要对外大规模发布 API 或者做跨系统统一身份认证时,才需要把另外两个产品拉进来。从手册里给的产品生态图来看,三者是互补关系而不是依赖关系。
2.2 ESB 概要文件:短期无状态集成流的默认入口
手册花了大篇幅讲 ESB 概要文件的七步消息流转,这套机制值得记熟,因为它决定了后续所有代理服务和序列的调试思路。流程大致是:客户端发消息进 ESB,传输层按协议接收;消息经过管道时先做 QoS 处理,比如安全校验;接着进入中介框架完成转换和路由,注意转换和路由不是严格分先后,而是交织在一起由 Synapse 实现;最后再经过一条出口管道,由传输层做协议转换并送达目标端点。响应处理完全反过来走这条链。
很多人把 ESB 和消息队列搞混。ESB 不负责消息的持久化和可靠投递,它侧重的是格式转换、内容路由和服务编排。EI 6.6.0 里如果要做可靠消息,需要启用 Message Broker 配置文件(MB),这套东西在集成方案里负责消息的存储转发。两者搭配使用是常见设计,ESB 做接入和转换,Broker 做缓冲和解耦。
2.3 业务流程概要文件:BPEL、BPMN 和人工任务的差异化实现
长期运行的有状态流程走的是另一条路,手册里拆成三条分支讲得很清楚。BPEL 流程和人工任务以 SOAP 服务形式暴露,走 Axis2 Web 服务通道;BPMN 流程则以 REST API 暴露,部署在嵌入式 Tomcat 上。这三者的传输入口不一样,进入后分别交给 ODE BPEL 引擎、Activiti BPMN 引擎和人工任务运行时去处理,流程实例数据统一通过数据访问对象层持久化到数据库。
实际项目里,短期接口转换用 ESB 概要文件就够了;一旦涉及审批流、多步人工确认这类长事务,再去启用业务流程概要文件。手册里点名了 Activiti 5.21.0 和 Apache ODE 引擎,这意味着你的 BPMN 文件版本兼容性要按这套引擎来核,BPMN 2.0 标准虽然通用,但某些扩展元素在不同引擎上表现不一样,批次升级时容易翻车。
2.4 EI 6.6.0 的组件清单:ESB、MB、BPS、SP 一次收齐
版本 6.6.0 是 EI 6.xx 系列的最新版,它把四个产品的功能封进了同一个发行包:ESB 做中介和路由,MB 做可靠消息,BPS 跑业务流程,SP 做流处理。单从架构上看,这套设计能在同一个 Carbon 平台上统一管理,省去了多套中间件之间的对接成本。
成本的一面是包体变大。下载 Zip Archive 解压后,目录里有多个配置文件目录对应不同配置文件。启动哪个取决于你跑什么场景,不需要的概要文件完全可以不启动,避免 JVM 内存被无谓占用。这是 EI 和单独装 ESB 的一个重要区别:灵活性和资源消耗成正比。
3. ESB 核心概念落地:从 Transport 到 Registry 的配置要点
3.1 Transports 和 Message Builders/Formatters 的配对逻辑
WSO2 ESB 支持的传输协议列表很长,HTTP、HTTPS、JMS、TCP、FIX、SFTP 等一大串。每种传输进来后,消息要被转成统一的 XML 表示,靠的是 Message Builders;从 XML 再转回原始格式发出去,靠的是 Message Formatters。这俩是成对出现的,按内容类型匹配。
实际调试中最常见的翻车点是:新增了一个协议但没配对应的 builder/formatter,消息进来直接报错或者变成乱码。手册里提到 TCP 传输的三种消息类型——字节、字符、字符串——以定界符或者定长字节判断请求边界,这个配置细节在 axis2.xml 里折腾过的人都有印象。HTTP 相关的 builder/formatter 基本默认可用,但 TCP、FIX 这类冷门协议必须手工改配置文件才能让传输层正确解析。
3.2 Endpoints 三种定义方式和 format 参数取舍
Endpoint 代表后台服务地址,配一个 endpoint 才能让 ESB 知道消息往哪送。手册给出了一个典型的 address endpoint 配置:
<endpoint> <address uri="http://localhost:9000/services/SimpleStockQuoteService" format="soap11"/> </endpoint>这里 format 决定消息在发送端的最终形态,合法的取值有soap11、soap12、pox和get。选soap11意味着 ESB 会把当前消息转换成 SOAP 1.1 信封再发出去;选pox就是纯 XML 不带 SOAP 包装;get会把消息转成 HTTP GET 请求参数。所谓 Leave As-Is,是保留消息原样不做格式转换。
三种 endpoint 类型之间,address 是最直接的,指定 uri 就行;WSDL endpoint 是从 WSDL 里提取地址,适用于服务地址经常变的环境;load balancing endpoint 则是把同一个服务的一组地址配进来,让 ESB 在多个实例间分发流量。负载均衡的权重和会话亲和性都在 endpoint 配置里调整,不需要额外部署 LB 组件。
3.3 Proxy Service 的 InSequence、OutSequence 与 Fault Sequence
代理服务是 ESB 的虚拟服务,不真正执行业务逻辑,业务在外部端点完成。每次消息进入代理服务时会经过 InSequence,在这个阶段你可以做校验、改写、路由决定;外部服务响应后,响应消息从 OutSequence 回来,由这里做最后的加工再还给客户端。出错时走 Fault Sequence,这个 sequence 常被新手忽略,导致线上报错时连个日志都看不见。
配置代理服务时最值得留意的参数是receiving sequence机制。从 4.x 版本开始,你可以在 send mediator 里显式指定一个 sequence 来接收响应,而不是默认回到 OutSequence。这在异步场景下非常有用,同一个代理服务可以并发处理多个请求,每个请求的响应回到各自指定的接收序列,而不是一股脑全挤回 OutSequence。
3.4 Mediators 和 Sequences:消息流的积木与流水线
Mediator 是消息处理的最小单元,输入一个消息,经过转换或路由,输出一个消息。ESB 预置了几十个 mediator,从发消息的 send、改属性的 property、调日志的 log,到做分支判断的 filter、做内容增强的 enrich,都有现成的。而 Sequence 就是把一堆 mediator 按顺序串起来,形成一条可复用的流水线。
写 sequence 时有个好习惯:把常用的路由和转换逻辑拆成独立 sequence 存到 Registry,用 key 引用,而不是每个代理服务里复制粘贴。这样改一处全局生效,不用逐个代理服务去翻。ESB 的 xpath 表达式在 filter mediator 里的取值逻辑是基于 Synapse 的,和标准 XPath 有细微差别,判断节点的写法不对会直接走 else 分支,排查时要能想到这一层。
3.5 Registry 两级缓存和 cachableDuration 参数
注册表是 ESB 存放配置和资源的中央仓库,sequence、endpoint、WSDL、数据源定义都按路径存在里面。内置注册表按作用域分为本地仓库、配置仓库和治理仓库三部分:本地仓库存各节点私有数据,不参与共享;配置仓库在同类产品实例间共享,ESB 集群就靠它同步配置;治理仓库跨产品共享,存服务描述、endpoint、数据源这类全平台通用资产。
<registry provider="org.wso2.carbon.mediation.registry.WSO2Registry"> <parameter name="cachableDuration">15000</parameter> </registry>这个cachableDuration的单位是毫秒,控制注册表资源的缓存刷新周期。ESB 在消息流里引用注册表资源后会放到缓存里,缓存期间资源内容变了也不会重新加载,必须等缓存过期。把值调大能提升消息处理速度——查注册表的次数少,调小则让配置更新能更快生效。折中方案是开发环境设 5000,生产环境按变更频率设 15000 或更高,保存配置后等待一个缓存周期再做验证,不然会误以为发布失效。
4. 基于 Integration Studio 复现三个典型案例:REST2SOAP、SOAP2REST、TCP2SOAP
4.1 开发环境搭建:EI 运行时和 Integration Studio 的分工
手册明确推荐用 Integration Studio 做可视化开发,它基于 Eclipse,支持拖拽式编排,适合不习惯手写 XML 的人。而 EI 6.6.0 本身是运行时,负责把开发好的配置跑起来。两者的版本要匹配,EI 6.6.0 对应配套的 Integration Studio 版本,混用容易出现打包部署不兼容。
搭建时先下载 EI 6.6.0 的 Zip Archive,解压后设置JAVA_HOME,然后跑bin/integrator.sh或bin/integrator.bat启动运行时。Integration Studio 这边,创建一个新的 Integration Project,在项目里建 Proxy Service 或 Sequence。开发完成后导出 CAR 文件(Carbon Archive),部署到 EI 运行时的repository/deployment/server/carbonapps目录,运行时热部署自动加载。手册项目目录里那些案例截图对应的也就是这套工程结构。
4.2 REST2SOAP:代理服务接入 REST 请求再转发 SOAP 服务
这个案例是最典型的协议转换场景:客户端只发 REST 请求,后台服务是 SOAP 接口。在 Integration Studio 中新建一个 Proxy Service,传输协议选 HTTP/HTTPS,InSequence 里加一个 payload factory mediator,把 REST 请求的 JSON 或表单参数拼装成 SOAP 信封,再通过 send mediator 发往目标 SOAP endpoint。
<proxy name="RestToSoapProxy" transports="http https" startOnLoad="true"> <target> <inSequence> <payloadFactory media-type="xml"> <format> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.example.com"> <soapenv:Body> <ser:getCustomer> <ser:id>$1</ser:id> </ser:getCustomer> </soapenv:Body> </soapenv:Envelope> </format> <args> <arg xmlns:m="http://schemas.xmlsoap.org/soap/envelope/" evaluator="xml" expression="$trp:customerId"/> </args> </payloadFactory> <send> <endpoint> <address uri="http://localhost:9080/customerService" format="soap11"/> </endpoint> </send> </inSequence> <outSequence> <send/> </outSequence> </target> </proxy>代码里$trp:customerId是传输属性取值,对应 HTTP 请求参数里的 customerId;payloadFactory 的$1引用第一个 arg 的值做占位替换。format="soap11"保证 send 发出去的是标准 SOAP 1.1 信封。OutSequence 里的send不带 endpoint 会把响应直接送回客户端,此时响应默认还是 SOAP 格式,如果客户端要 REST 形式,需要在 OutSequence 里再做一次 payloadFactory 把 SOAP 响应转成 JSON,很多人在这里漏掉反向转换导致联调失败。
4.3 SOAP2REST:反向转换的自定义实现要点
SOAP2REST 场景在手册里标记为自定义构造,没有直接给模板,但实现逻辑和 REST2SOAP 是镜像的。代理服务接收 SOAP 请求,解析 SOAP Body 里的业务参数,用 payloadFactory 构造 REST 格式的消息,再通过 HTTP endpoint 以 POST 或 GET 方式发出去。
关键点在两处:一是 endpoint 的 format 参数必须选pox或get,不能是soap11,否则 ESB 会把消息重新包成 SOAP 信封发给 REST 服务。二是 OutSequence 里同样要把 REST 回来的 JSON 还原成 SOAP 结构返回客户端。整个过程中 property mediator 常被用来暂存 SOAP 请求里的字段值,等 REST 响应回来再从属性里取出来拼装。JSON 和 XML 之间的字段映射容易出差错,建议在开发环境用 SoapUI 同时起两个客户端分别模拟 REST 方和 SOAP 方,这样两端格式问题能第一时间定位到。
4.4 TCP2SOAP:修改 axis2.xml 启用 TCP 传输的完整路径
TCP 传输需要动配置文件,这是手册里明确点名的步骤。找到 EI 运行时目录下的conf/axis2/axis2.xml,在 transport receiver 和 transport sender 区域分别添加 TCP 相关的配置。配置好后重启运行时才会生效,不能热加载。
<transportReceiver name="tcp" class="org.apache.synapse.transport.nhttp.NhttpTransportListener"> <parameter name="port">6060</parameter> </transportReceiver>TCP 入站消息在 ESB 里靠分隔符或定长字段切分请求边界,常用的是在<parameter name="requestStreaming">或消息类型相关配置里指定分隔符值。收到完整 TCP 报文后,接下来要做的处理同 REST2SOAP 一样:用 payloadFactory 把原始字节或字符串拼装成 SOAP Body,然后 send 到 SOAP endpoint。手册提醒 JMS 传输也要走同样的配置修改流程,不能指望默认配置就能直接用。
4.5 SampleService 和内容路由的实操笔记
手册里附带的 SampleService 案例是官网最简单的入门版,只做了一件事:接收 REST 请求直接转发到后台服务,不做任何转换。先跑通这个案例能确认环境没问题,再去碰路由案例。路由案例基于消息内容做判断,常见实现是 filter mediator 按 XPath 或 JSONPath 分流到不同 endpoint。
<filter source="json-eval($.hospitalType)" regex="General"> <then> <send><endpoint key="GeneralHospitalEP"/></send> </then> <else> <send><endpoint key="SpecialHospitalEP"/></send> </else> </filter>json-eval($.hospitalType)从 JSON 消息体里取 hospitalType 字段,匹配 General 则走综合医院端点,否则走专科端点。这里要注意 filter source 的表达式解析基于 Synapse,JSON 路径表达式的语法与标准 JSONPath 有细节差异,写完后最好在管理控制台的尝试工具里先验证再部署。
5. 避坑与常见问题:axis2.xml、WSDL、缓存、协议四类典型故障排查
5.1 代理服务启动后接口 404:WSDL 获取失败但不影响启动
现象:代理服务部署后控制台显示运行中,但调用接口返回 404。
原因:启动时 ESB 尝试获取代理服务关联的 WSDL,若 WSDL 不可达,ESB 记录错误并继续启动该服务——手册明确写了这一点——但服务对外暴露的元数据不完整,导致路由不到正确处理器。另有一种可能:代理服务配置里wsdlEndpoint指向的外部地址在启动瞬间不可用,影响的是服务描述而非消息处理。
解决:确认 WSDL 地址可访问;临时方案是把 WSDL 文件拷到本地用wsdlURI指向文件路径。更常见的做法是手动编写代理服务的 WSDL 或复用已有服务的 WSDL,而不是依赖启动时动态拉取。每次修改 WSDL 相关配置后必须重启运行时,代理服务不会感知外部 WSDL 的变更。
5.2 新协议配置了但请求进不来:axis2.xml 热加载是假象
现象:在 Integration Studio 里改了 axis2.xml 里的 TCP 配置并保存,运行时日志看不到 TCP 监听端口。
原因:axis2.xml 是运行时启动时加载的全局配置,在线修改不会触发重载,需要重启 EI 进程。
解决:改完配置后完整停掉 integrator 进程再启动,启动日志里确认对应 transport listener 的端口已打开。对 TCP 这类非默认协议,建议在修改前先备份 axis2.xml,改坏后可以快速回滚,不要手动改完就完事,拿启动日志核对一遍是最稳妥的验证方式。
5.3 注册表配置改了不生效:cachableDuration 过期前用的是旧缓存
现象:更新了某个 sequence 定义,但代理服务调用时还是旧逻辑,持续很久才变过来。
原因:注册表资源被 ESB 缓存,cachableDuration设置 15000 毫秒,意味着资源变更最长要等 15 秒才会被重新加载。集群环境下各节点独立缓存,更新不是即时同步的。
解决:要么把发布变更的验证窗口拉长到超过缓存周期,要么开发环境把cachableDuration临时调小到 1000 毫秒缩短等待。生产环境不建议系统性地调小缓存,会拖累消息吞吐。发布配置后该做的验证等一个缓存周期再执行,别刚保存完就去试并发。
5.4 路由到错误端点:filter 表达式解析和预期不一致
现象:filter mediator 明明写了等于判断,但消息走了 else 分支。
原因:表达式写法不匹配实际消息内容。XPath 在 Synapse 里和标准 XPath 对命名空间的处理有差异,json-eval对 JSON 数组和嵌套对象的下标是从 0 还是从 1 开始也要实测。另一个隐蔽点:表达式取到的值带前后空格或换行,导致字符串比较失败。
解决:在 filter 前加一个 log mediator 把属性和消息体打出来,确认表达式的实际取值。排查工具方面,Integration Studio 里有消息跟踪视图,EI 管理控制台也提供调试接口。比翻日志更快的方式是先在控制台尝试工具里手动跑一遍表达式,确认取值正确再部署。条件比较上尽量用正则而非全等匹配,给数据留点余量。
5.5 协议转换响应冲突:REST 转发后返回的却是 SOAP 信封
现象:REST2SOAP 案例联调时,客户端发 REST 请求,后台 SOAP 服务确实收到了,但返回给客户端的响应是 SOAP XML,不是预期的 JSON。
原因:OutSequence 直接用了不带参数的send,响应消息维持 SOAP 格式原样返回。ESB 只处理入站转换,出站方向如果不显式转换,消息就以 SOAP 信封的形态回到客户端。
解决:在 OutSequence 里显式加 payloadFactory 把响应 Body 内容抽取出来转成 JSON 结构,或者用一个property name="messageType" value="application/json"强制设置响应消息的内容类型。注意 JSON 结构要从 SOAP Body 的命名空间里解析出来,别把 envelope 包装一起输出。这类问题的隐蔽之处在于本地直接用 SoapUI 调代理服务时看不到问题,因为 SoapUI 能解析 SOAP,要到真实 REST 客户端联调时才会暴露。
6. 把手册收成一张速查表:常用 Mediator 和表达式的实战用法
Property Mediator 是最常被用到的存储和读取工具。写入时用set-property,读取时用get-property('name')或者简写$ctx:name。它存的值可以是消息上下文里的临时变量,也可以覆盖传输属性。跨 sequence 传参时我习惯用 property 承载临时值,而不是在消息体里拼来拼去。
Enrich Mediator 用于从源内容提取数据并合并到当前消息的指定位置。写作格式复合场景比 payloadFactory 更灵活,它不用手工拼整个信封,只需指定源表达式和目标位置。搭配json-eval($.name)或 XPath 表达式,在处理动态响应时比写死模板省力得多。
表达式速查:
| 表达式 | 示例 | 适用场景 |
|---|---|---|
| JSONPath | json-eval($.customer.name) | 提取 JSON 消息体字段 |
| Property | get-property('hospitalType')/$ctx:name | 访问或复用消息属性 |
| XPath | //getCustomer/id | 在 XML/SOAP 信封里定位节点 |
| Concat | fn:concat('Routing to ', get-property('Hospital')) | 拼接日志或动态创建路由目标 |
手册里这四种表达式的选取逻辑:消息体是 JSON 用json-eval,消息体是 XML 用 XPath,跨消息流传参用 property,需要拼接字符串去构造日志或者动态 URL 用fn:concat。实际项目里一条消息流往往要混合用,先 property 取到 ID,再 concat 拼出服务地址,最后 XPath 从响应里抽取结果。
将手册收成速查表之后,日常写代理服务时的习惯变成了固定套路:先是 log 打印入站消息,接下来 property 抽取关键字段,payloadFactory 或 enrich 重组消息体,filter 按字段值分支,send 发往 endpoint——这套流程覆盖了大部分 REST 和 SOAP 协议转换需求。从那以后每次部署新的代理服务,都强制走一遍先在控制台尝试工具里验证表达式、再导出 CAR 包、最后用独立客户端联调的正向流程,协议转换的返工率降了不止一半,希望这份梳理也能帮你少走几步弯路。
本文还有配套的精品资源,点击获取