渠道
渠道分为接入渠道inbound及接出渠道outbound,inbound和outbound都包括请求的接收和响应,按照消息的接收方式进行区分,inbound用来接收消息,outbound用来向外部访问数据。
channel基础配置
名称 | 说明 |
---|---|
id | 渠道id,同一命名空间内唯一 |
name | 渠道名称 |
started | 初始化时是否开启渠道,如果是false,则此渠道的connector都不会开启 |
protocolType | 渠道接入协议,此属性在connector生效, 用于生成支持对应协议的connector, 如果此channel中的connector配置了不一样的protocolType属性,则以connector配置为准 |
channelType | 渠道类型,inbound,outbound,dynamic_outbound |
contentType | 报文内容类型,此属性在connector生效, 用于生成支持对应协议的connector, 如果此channel中的connector配置了不一样的protocolType属性,则以connector配置为准 |
loadBalance | 负载策略,仅对outbound渠道有效,每种实现都继承ConnectorLoadBalance,目前支持hash,random,round-robin,weight-random,weight-round-robin,custom 对custom类型做特殊说明, 如果负载方式设置成 custom, 则负载策略为 先从channel中获取 connectorRouterExpression字段配置,如果connectorRouterExpression不为Null, 则根据此字段值(该值应为表达式)从当前请求的上下文中获取实际值, 会根据此值作为connector的id获取Connector,如果connectorRouterExpression为null,则会遍历所有的connector, 根据上下文计算每个connector的matcher字段值, 如果值为true,则获取此connector. |
connectorRouterExpression | 一个表达式,用于从上下文中获取connector id , 例如 ${a.b}会从上下文(包括map结构的报文体)中获取key为a/b层级结构的值 |
inMessagePool | 消息接收线程池设置,接收到消息后,交由线程池启动任务处理,如果不设置,则该功能不生效, 详见下面介绍 |
preInMessageFilters | 报文解析前执行的拦截器 |
postInMessageFilters | 报文解析后执行的拦截器 |
preOutMessageFilters | 报文打包前执行的拦截器 |
postOutMessageFilters | 报文打包后执行的拦截器 |
failOverRetryInterval | 当发生传送失败后,将失败的connector加入到失败队列,failOverRetryInterval时间后,对失败队列进行重试,总共重试10,若10次后仍有失败队列,退出重试线程,直到下次收到请求后继续重试,默认探活间隔20000 |
transparent | 是否开启透传 |
persistent | 设置此对象在zk上对应节点的持久性,如果为true,则网关关闭之后,此节点仍然存在,反之就会消失 |
recordTraceEvent | 渠道接收到消息和发送消息时是否触发messageArrived事件 |
stick | 是否使用黏性会话,链接一旦建立后,同一个ip会话向同一个节点进行发送,默认不开启,false |
channelInMessageAvailable | 该channel是否对消息接收是否有效,通过值true或false可直接执行,或使用表达式进行动态判断,当设置无效是,抛出GTW0017异常 |
channelOutMessageAvailable | 该channel是否对消息发送是否有效,通过值true或false可直接执行,或使用表达式进行动态判断,当设置无效是,抛出GTW0017异常 |
inMessageInfoLog | 设置该channel是否对进入channel的消息进行打印,打印消息为经过connector解析后的消息 |
outMessageInfoLog | 设置该channel是否响应的消息进行打印,打印的消息未经过connector打包前的消息 |
渠道线程池配置
- 该线程池的作用为替换netty线程, 接替netty线程执行任务
- 当请求或响应处理链中有比较耗时的阻塞任务执行时, 如在网关的请求处理链阻塞的去调用其他服务, 或操作数据库等场景, 可以应用该功能.
- 如果请求和响应链中几乎没有耗时操作, 比如纯透传场景, 则不需要配置线程池, 减少线程切换损耗.
接入渠道inbound
使用渠道类型channelType=inbound进行区分,一个gateway可以配置多个inbound channel,每个inbound channel包含多个connector,每个connector负责监听一个指定port,connector对报文解码解析后,提交给inbound channel处理线程池进行处理。
处理流程如下如所示:
接出渠道outbound
使用渠道类型channelType=outbound进行区分,一个gateway可以配置多个outbound channel,每个outbound channel包含多个connector,每个负责发起一类请求,connector对报文打包编码后进行发送。 处理流程如下如所示:
连接器及参数说明
连接器,以下使用connector代替,在服务和渠道之间起桥接作用,用来链接真实的服务和渠道,分为inbound的connector和outbound的connector。
inbound连接器会在本地开启指定端口port,监听请求,接收到请求后,由指定的解码器进行解码,同时在请求处理完成后,由特定的编码器进行编码并输出响应。解码器和编码器一般成对出现。
outbound连接器作为访问客户端,用来发送请求消息,同样需要编码器和解码器的参与。
网关支持多种协议报文, 体现在连接器的配置中
- 协议类型: 对应上面配置中的 protocolType 字段
协议类型 | 描述 |
---|---|
http | |
https | |
socket | 基础tcp协议 |
socket-length-field-custom | 通用报文协议 |
socket-ssl-length-field | ssl协议有长度域 |
- 报文类型: 对应上面的 contentType 字段
报文格式 | 描述 |
---|---|
json, json-body | json-body和json使用不同的解析器, 区别是json是字节数组与map之间的转换, json-body是字符串与map之间的转换, 在socket协议时一般使用json-body |
webservice | 当连接器使用webservice协议与外界交互时, 使用该字段, 此时protocolType一定为http |
xml, xml-body | 同json与json-body的区别 |
http-transparent | http协议透传, http的头会被解析, 但http的报文体内容不解析. 在上图中, 报文类型在中间过程中不再是map结构报文, 而是未解析过的字节数组 |
custom-body | 通用报文协议专用 |
connector基本配置
params配置介绍
connector中params主要是一些协议层配置, 使用场景及配置如下:
https协议
| 字段 | 描述 | | ---------------- | ------------------------------- | | keyStorePath | 证书仓库路径, 支持相对路径 | | keyStorePassword | 证书仓库密码 | | twoWay | 是否双向认证, 仅在inbound端配置 |
socket-ssl协议
可能需要长度域相关配置, 以定长报文的长度域配置为例:
| 字段 | 描述 | | -------------------------- | ------------------------------------------------------------ | | keyStorePath | 证书仓库路径, 支持相对路径 | | keyStorePassword | 证书仓库密码 | | twoWay | 是否双向认证, 仅在inbound端配置 | | prependerLengthFieldLength | 在向外发送消息时自动计算长度域长度值以及将该值放入报文头的前几个字节, 如该值为4, 则将长度域值放入报文头的前4个字节 | | lengthFieldLength | 作用范围: 网关收到消息时解析报文, 该字段指定了长度域长度, 如配置为4, 解析报文时按照长度域长度为4进行解析 | | initialBytesToStrip | 作用范围: 网关收到消息时解析报文, 如果不需要解析后的报文包含长度域, 需要配置该字段的值为长度域长度 | | lengthFieldOffset | 作用范围: 网关收到消息时解析报文, 长度域不在报文头需要配置该字段 | | lengthAdjustment | 作用范围: 网关收到消息时解析报文, 如果长度域的值包含报文长度和长度域长度本身, 则需要配置该字段进行修正 |
重组http请求头
如在Outbound端修改某些http请求头以适配服务端的应用服务器, 配置如:
outbound_channel: values: - channelType: outbound available: true protocolType: http id: jsonChannel values: - id: ccc protocolType: http started: true contentType: json type: netty uri: http://localhost:8888 params: headers: #reset字段表示重置整个请求头, 如果只需要重置请求头中某个字段, 不需要配置该项, 注意其中Content-Length 由网关内部自动填充, 不需要关注 reset: true Content-Type: 'application/json' #Host字段比较容易不被应用服务器识别, 会报HTTP Error 400. The request has an invalid header name 或类似错误 Host: '127.0.0.1:6666' name: aa started: true
请求超时及连接空闲超时
- 需注意, 在Inbound connector和outbound connector中都有相同的超时和连接空闲配置
- 他们的区别为Inbound connector的 responseIdleTime字段为读超时, 表示请求进入Inboundconnector后, 开始计时, 如果计时时间达到responseIdleTime字段值还没有收到来自服务端的响应, 则抛超时异常, 响应超时异常报文给客户端.
- Outbound connector的 responseIdleTime字段也为读超时, 表示请求进入Outbound connector后(发送报文数据给服务端后), 开始计时, 如果计时时间达到responseIdleTime字段值还没有收到来自服务端的响应, 则抛超时异常, 响应超时异常报文给客户端.
- idleTime为连接的空闲超时, 如果连接超过该时间未接受或发送过数据, 则认为该连接空闲超时, 直接关闭连接, 没有异常抛出.
outbound_channel#nps: values: - channelType: outbound available: true id: out_nps values: - id: nps01 type: netty started: true protocolType: http contentType: http-transparent #单位秒 params: {responseIdleTime: 60, idleTime: 120, timeUnit: seconds} uri: '%{nps.url}/${path}' name: NPS模块 started: true inbound_channel#ws: values: - channelType: inbound id: inbound_ws_channel protocolType: http contentType: http-transparent values: - port: 9000 id: inbound_ws_connector started: true type: netty params: {responseIdleTime: 70, idleTime: 120, timeUnit: seconds} name: WebService接入渠道 started: true
是否拦截http协议非200响应码值的响应
outbound_channel: values: - channelType: outbound available: true protocolType: http id: jsonChannel values: - id: ccc protocolType: http started: true contentType: json type: netty uri: http://localhost:8888 #该值默认为true, 如果为true, 拦截非200码值的响应, 组装成http异常报文,但组装后的http响应码值为200. #如果为false, 则不转换实际响应码值, 并将其响应给客户端 params: {reportError: true} name: aa started: true
基本json接入接出协议示例
接出协议为ssl
该示例接入报文格式为json, 接出报文格式为xml, 且接出时应用ssl协议, 注意该json报文必须有一个根节点, 才能与xml协议转换, 不然报错
接入接出都为https协议
只允许配置一个keystore, 所以这个keystore要包含信任证书列表和自己的私钥, keystore内容不能是字符串格式
接入webservice, 接出json, wsdl在本地配置
需要注意的事项:
wsdl路径配置在config.properties中,格式为 gateway.wsdlLocation='' 全局有效json服务返回的报文必须符合该wsdl规范, 否则客户端将拿到空报文, 那如何保证每次请求都能获取到对应的wsdl进行解析呢? 我们的规范是按照请求路径匹配到对应的wsdl的, 我们约束wsdl放置的相对路径必须与对应的请求路径一致, 这样就能确定他们的一对一关系了 在outboud端可根据访问路径自动从远端获取wsdl, 可以不用把wsdl配置到本地 比如wsdl放置路径
我们指定wsdl的文件夹路径为 gateway.wsdlLocation=./wsdl , 则请求路径为/rcs入访测试wsdl/RcscustcollloanqueryService 能请求到RcscustcollloanqueryService服务
接入消息时一个端口支持不同报文格式的请求, 如监听9000端口, 可以用http json请求也可以用http xml或者webservice请求,或者透传
注意同一端口不能支持不同协议, 比如http协议和socket协议, 但支持不同报文格式
如下为配置示例
接入时网关需要对Json和webservice请求做区分, 这里依赖本地识别器和匹配表达式确认当前请求的报文格式, 并按照解析出的报文格式对报文做解析
也支持xml格式解析或者透传
透传解析
适用于网关只做报文转发, 不做报文参数转换 , 但是纯粹透传却满足不了路由等需求, 还是需要解析请求报文体的某些字段的情况
该功能可以理解为网关在接入接出报文完全透传情况下, 在此基础上增加的对请求报文做解包的功能, 所以我们的配置也是完全在透传基础上增加了透传解析的配置.
对透传报文进行解析的时间发生在请求刚进入网关时, 解析后的报文信息会统一放入上下文, 所以可以在任何地方获取该解析信息, 解析信息可用于路由, 流控, 并发限制等等.
示例配置如下: