Spring-Cloud-Gateway基于服务发现的动态路由源码分析-1

Spring-Cloud-Gateway源码系列学习

版本 v2.2.6.RELEASE

demo搭建

Nacos下载地址:https://github.com/alibaba/nacos/releases/tag/2.0.0-BETA

解压进入bin目录

单机运行Nacos:

  • windows系统:startup.cmd -m standalone
  • linux/mac:startup.sh -m standalone

打开Nacos管理界面:

  • 链接:http://localhost:8848/nacos
  • 账号:nacos
  • 密码:nacos

示例代码对应仓库():

示例代码由芋道源码提供,嘿嘿~

运行上面两个Spring-Boot程序

验证基于服务发现的动态路由:

http://localhost:8888/user-service/user/get?id=1

DiscoveryLocatorProperties源码分析

DiscoveryLocatorProperties是Spring-Cloud-Gateway discovery配置类,示例配置如下:

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          url-expression: "'lb://' + serviceId"

下面通过 GatewayDiscoveryClientAutoConfiguration 类分析 ,DiscoveryLocatorProperties在装配时默认添加的predicate和filter

public class GatewayDiscoveryClientAutoConfiguration{

	@Bean
	public DiscoveryLocatorProperties discoveryLocatorProperties() {
		DiscoveryLocatorProperties properties = new DiscoveryLocatorProperties();
        //设置了默认的predicate
		properties.setPredicates(initPredicates());
        //设置了默认的filter
		properties.setFilters(initFilters());
		return properties;
	}
	
    //默认predicate:-Path = "'/'+serviceId+'/**'"
	public static List<PredicateDefinition> initPredicates() {
		ArrayList<PredicateDefinition> definitions = new ArrayList<>();
		// TODO: add a predicate that matches the url at /serviceId?

		// add a predicate that matches the url at /serviceId/**
        //new一个PredicateDefinition
		PredicateDefinition predicate = new PredicateDefinition();
        //生产AsyncPredicate时是根据name来匹配PredicateFactory的
		predicate.setName(normalizeRoutePredicateName(PathRoutePredicateFactory.class));
		//设置predicate配置,等于 -Path = "'/'+serviceId+'/**'"
        predicate.addArg(PATTERN_KEY, "'/'+serviceId+'/**'");
		definitions.add(predicate);
		return definitions;
	}

    //默认filter:- RewritePath="'/' + serviceId + '/(?<remaining>.*)'", "'/${remaining}'"
	public static List<FilterDefinition> initFilters() {
		ArrayList<FilterDefinition> definitions = new ArrayList<>();

		// add a filter that removes /serviceId by default
		FilterDefinition filter = new FilterDefinition();
		filter.setName(normalizeFilterFactoryName(RewritePathGatewayFilterFactory.class));
		String regex = "'/' + serviceId + '/(?<remaining>.*)'";
		String replacement = "'/${remaining}'";
		filter.addArg(REGEXP_KEY, regex);
		filter.addArg(REPLACEMENT_KEY, replacement);
		definitions.add(filter);

		return definitions;
	}	
}

下面接着分析DiscoveryLocatorProperties的源码

public class DiscoveryLocatorProperties {

	/** Flag that enables DiscoveryClient gateway integration. */
	private boolean enabled = false;

	/**
	 * The prefix for the routeId, defaults to discoveryClient.getClass().getSimpleName()
	 * + "_". Service Id will be appended to create the routeId.
	 */
    //路由id前缀
	private String routeIdPrefix;

	/**
	 * SpEL expression that will evaluate whether to include a service in gateway
	 * integration or not, defaults to: true.
	 */
    //是否使用SpEL表达式
	private String includeExpression = "true";

	/**
	 * SpEL expression that create the uri for each route, defaults to: 'lb://'+serviceId.
	 */
    //创建路由使用的SpEL表达式
	private String urlExpression = "'lb://'+serviceId";

	/**
	 * Option to lower case serviceId in predicates and filters, defaults to false. Useful
	 * with eureka when it automatically uppercases serviceId. so MYSERIVCE, would match
	 * /myservice/**
	 */
    //是否开启大写转小写
	private boolean lowerCaseServiceId = false;

    //作用于每个服务发现路由的Predicate
	private List<PredicateDefinition> predicates = new ArrayList<>();

    //作用于每个服务发现路由的Filter
	private List<FilterDefinition> filters = new ArrayList<>();
}

DiscoveryClientRouteDefinitionLocator源码分析

通过DiscoveryClient提供的Flux<List> serviceInstances 和 DiscoveryLocatorProperties properties来创建RouteDefinition

//TODO
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值