Appearance
双中心路由过滤器
此过滤器作用是在双中心模式下,根据业务后台数据库中间件libra
的分片键和分片算法,计算出某一个请求过来的应该路由到哪一个库中去,而这些库对应了一个中心,从而找到了中心信息,该请求就可以执行通过负载转发到这个中心的服务中去,从而提升接口效率,如果匹配不到则该笔请求在本中心或者其余的中心进行处理。
1.1 使用方法
如果网关已运行,需要先停止网关,修改一些配置参数,之后在重启网关此功能才可正常使用,以下步骤默认为网关没有运行进行的操作,以下所用到的环境配置文件均为application-sit.yml文件。
(1)在网关配置文件中添加comet框架中使用mq的配置和libra数据源Hint配置。核心业务目前使用的是rocketmq,下面写的时rocketmq配置。
yaml
comet:
mq:
type: rocketmq
###mq消费者配置
consumer:
#消息组 需要和生产者的groupName配置一样
groupName: mqproducer
#mq的nameserver地址,多个用分号隔开
namesrvAddr: 10.7.19.39:9876
#默认值是64
consumeThreadMax: 512
#默认值是24
consumeThreadMin: 64
#默认值是1
consumeMessageBatchMaxSize: 128
hint:
type: com.dcits.comet.gateway.comet.dbsharding.galaxy.libra.HintLibraManager #libra数据源Hint配置
此配置是在核心做交易时将使用的分片键值(clientNo,传输的报文中没有此值)、与clientNo对应的唯一的报文中会包含的值,按照格式推送到rocketmq中。网关消费此数据存放到数据库中,以此作为报文中传输分片键的路由映射。
业务推送到mq的数据格式是:
json
{
"clientNo:100001001": {
"baseAcctNo": "35110225003000804",
"cardNo": "",
"phoneNo": "13111111111"
},
"clientNo:100001002": {
"baseAcctNo": "35110225003000804",
"cardNo": "",
"phoneNo": "13111111111"
}
}
(2)修改如下配置,加载双中心负载Bean
yaml
#双中心路由配置
jupiter:
multi-center:
enabled: ${ribbon.dcRoute} #是否使用双中心路由负载均衡配置
(3)修改网关的数据库连接使用libra中间件配置:
在database.xml
文件中配置好所有的数据库dataNode
,此时所添加的dataNode
的名称和数量与在服务中添加的双中心路由过滤器中所配置的dataNode保持一致,同时为dataNode
添加 dataCenter
属性,说明数据库在哪个中心。
xml
<!DOCTYPE libra:database SYSTEM "database.dtd">
<libra:database xmlns:libra="http://www.dcits.com/libra/">
<dataNode name="dn1" dataHost="localhost1" database="jupiter" dataCenter="dc01"/>
<dataNode name="dn2" dataHost="localhost1" database="jupiter" dataCenter="dc01"/>
<dataNode name="dn3" dataHost="localhost1" database="jupiter" dataCenter="dc02"/>
<dataNode name="dn4" dataHost="localhost1" database="jupiter" dataCenter="dc02"/>
<dataHost balance="0" maxCon="500" minCon="10" name="localhost1" switchType="1">
<heartbeat>select 1 from dual</heartbeat>
<writeHost host="hostM5" url="jdbc:oracle:thin:@192.168.161.17:1521/DCITS" password="ENS_GATEWAY"
user="ENS_GATEWAY" dbDriver="druid" settings="druid"/>
</dataHost>
<sourceSettings name="druid">
<property name="druid.maxWait">5000</property>
<property name="druid.defaultAutoCommit">false</property>
<property name="druid.testWhileIdle">false</property>
<property name="druid.testOnBorrow">false</property>
<property name="druid.testOnReturn">false</property>
<property name="druid.initialSize">10</property>
<property name="druid.timeBetweenEvictionRunsMillis">60000</property>
<property name="druid.poolPreparedStatements">true</property>
<property name="druid.maxPoolPreparedStatementPerConnectionSize">1000</property>
<property name="druid.filters">stat</property>
</sourceSettings>
</libra:database>
在rule.xml
配置libra分片算法,此算法应该与业务中使用libra的算法配置一致。
xml
<!DOCTYPE libra:rule SYSTEM "rule.dtd">
<libra:rule xmlns:libra="http://www.dcits.com/libra/">
<tableRule name="t_order">
<rule>
<columns>id</columns>
<algorithm>mod</algorithm>
</rule>
</tableRule>
<function name="mod" class="com.actiontech.dble.route.function.PartitionByLong">
<property name="partitionCount">4</property>
<property name="partitionLength">1</property>
</function>
</libra:rule>
(4)启动网关:
shell
./start.sh -p xxx
(5)网关启动成功之后,登录运维平台,进入服务治理模块,打开网关拓扑图菜单,选择要使用双中心路由的服务,修改服务的负载均衡策略为双中心负载均衡并为其添加双中心路由过滤器。()
点击拓扑中的服务修改负载均衡策略:
点击拓扑图中服务和网关之间的连线(默认路由已添加,若路由没有设置,可参数《OMS配置手册》中《服务治理》模块的路由设置进行操作),添加双中心路由过滤器。
yaml
routerKeyName:指的是该请求所使用的的libra的分片键
dataNodes: 指的在业务服务中libra所使用的的数据库节点配置
partitionName:指的是目前libra所使用的的分片算法
(6)在服务治理中进入取值规则菜单,添加对应接口的取值字段和取值表达式(数据库中的表是GLOBAL_ROUTER_FIELD_RULE)。
yaml
目标url指的是:所要使用该过滤器服务路由的URL拼接上请求接口的uri eg:lb://ensemble-cif-service/cif/inq/client/single
字段名称:指的是所要该请求中所要使用的分片键的名称 eg:branchId
取值表达式:使用spring的spel表达式从请求报文获取分片键的值 eg:[sysHead][branchId]
1.2 原理流程
网关接收到业务的交易请求后,双中心路由过滤器com.dcits.comet.gateway.filter.DCRouterGatewayFilterFactory
会根据配置的取值规则获取到报文中的值,然后对比双中心路由过滤器中配置的分片键。若取值规则中配置的字段和过滤器中配置的分片键字段相同,则会根据配置的分片算法计算出该值应该是在哪一个数据库中。此时就能从网关的libra配置中获取到该数据库是在哪个中心的,拿到中心信息直接在负载中根据获取的中心信息负载到对应中心去。若双中心路由过滤器中配置的分片键和取值规则中的字段名称不相同,则会将从报文中按照取值规则取得的值作为条件去路由映射关系表(GLOBAL_ROUTER_KEY_MAPPING)中查找,如果有与之对应的值则会使用其作为中心的计算,如果没有则默认路由到当前中心去。
text
eg:
索引建: branchId:351002 路由键: clientNo:351001
当匹配到请求报文中的branchId的值为351002时,就会用clientNo去做路由分片,值为351001
如果匹配不到,则会直接路由到本中心,并将为匹配到的索引键值添加到未命中路由中去