说明
- 本文将分析 Apache ShenYu 网关所有插件都用到的选择器和规则参数说明,以及源码分析
参数说明
选择器
- 名称:为你的选择器起一个容易分辨的名字
- 类型:custom flow 是自定义流量。full flow 是全流量。自定义流量就是请求
会走你下面的匹配方式与条件。全流量则不走。 - 匹配方式:and 或者or 是指下面多个条件是按照and 还是or的方式来组合。
- 条件:
- uri:是指你根据uri的方式来筛选流量,match的方式支持模糊匹配(/**)
- header:是指根据请求头里面的字段来筛选流量。
- query:是指根据uri的查询条件来进行筛选流量。
- ip:是指根据你请求的真实ip,来筛选流量。
- host:是指根据你请求的真实host,来筛选流量。
- post:建议不要使用。
- 条件匹配:
- match:模糊匹配,建议和uri条件搭配,支持 restful风格的匹配。(/test/**)
- =:前后值相等,才能匹配。
- regEx:正则匹配,表示前面一个值去匹配后面的正则表达式。
- like:字符串模糊匹配。
- 是否开启:打开才会生效
- 打印日志:打开的时候,当匹配上的时候,会打印匹配日志。
- 执行顺序:当多个选择器的时候,执行顺序小的优先执行。
规则
说明
- 当流量经过选择器匹配成功之后,会进入规则来进行最终的流量匹配。
- 规则是对流量最终执行逻辑的确认。
参数说明
- 名称:为你的规则起一个容易分辨的名字
- 匹配方式:and 或者or 是指下面多个条件是按照and 还是or。
- 条件:
- uri:是指你根据uri的方式来筛选流量,match的方式支持模糊匹配(/**)
- header:是指根据请求头里面的字段来筛选流量。
- query:是指根据uri的查询条件来进行筛选流量。
- ip:是指根据你请求的真实ip,来筛选流量。
- host:是指根据你请求的真实host,来筛选流量。
- post:建议不要使用。
- 条件匹配:
- match : 模糊匹配,建议和uri条件搭配,支持 restful风格的匹配。(/test/**)
- = : 前后值相等,才能匹配。
- regEx : 正则匹配,表示前面一个值去匹配后面的正则表达式。
- like :字符串模糊匹配。
- 是否开启:打开才会生效。
- 打印日志:打开的时候,当匹配上的时候,会打印匹配日志。
- 执行顺序:当多个规则的时候,执行顺序小的优先执行。
- 处理:每个插件的规则处理不一样,具体的差有具体的处理,具体请查看每个对应插件的处理。
源码分析
在请求进入网关后,首先是匹配插件,当匹配上插件后就会对选择器和规则信息就行上次参数说明的匹配处理。
匹配方式 and or
and 是要全部配置,而 or则有任一匹配就行。它的核心源码为:
@Join
public class AndMatchStrategy extends AbstractMatchStrategy implements MatchStrategy {
@Override
public Boolean match(final List<ConditionData> conditionDataList, final ServerWebExchange exchange) {
// 完全匹配,conditionDataList里则是具体的规则集合,比如 like eq gt lt等待比较逻辑,和比较的值
return conditionDataList
.stream()
.allMatch(condition -> OperatorJudgeFactory.judge(condition, buildRealData(condition, exchange)));
}
}
@Join
public class OrMatchStrategy extends AbstractMatchStrategy implements MatchStrategy {
@Override
public Boolean match(final List<ConditionData> conditionDataList, final ServerWebExchange exchange) {
// 任一匹配,conditionDataList里则是具体的规则集合,比如 like eq gt lt等待比较逻辑,和比较的值
return conditionDataList
.stream()
.anyMatch(condition -> OperatorJudgeFactory.judge(condition, buildRealData(condition, exchange)));
}
}
具体规则匹配分析
根据插件的选择器,查处规则相关信息,就会到规则工厂类里去获取具体规则逻辑处理类。这里用到工厂模式,加载工厂类的时候就会初始化具体的规则类,并缓存在工厂类的Map集合中,后面的所有请求都从这里面取:
public class OperatorJudgeFactory {
private static final Map<String, OperatorJudge> OPERATOR_JUDGE_MAP = Maps.newHashMapWithExpectedSize(4);
//通过静态代码块初始化规则验证类
static {
//完全匹配
OPERATOR_JUDGE_MAP.put(OperatorEnum.EQ.getAlias(), new EqOperatorJudge());
//根据url匹配
OPERATOR_JUDGE_MAP.put(OperatorEnum.MATCH.getAlias(), new MatchOperatorJudge());
//模糊匹配
OPERATOR_JUDGE_MAP.put(OperatorEnum.LIKE.getAlias(), new LikeOperatorJudge());
//正则匹配
OPERATOR_JUDGE_MAP.put(OperatorEnum.REGEX.getAlias(), new RegExOperatorJudge());
}
public static Boolean judge(final ConditionData conditionData, final String realData) {
//获取规则验证对象并验证规则
return OPERATOR_JUDGE_MAP.get(conditionData.getOperator()).judge(conditionData, realData);
}