读Spring-Cloud-Gateway源码收获
当初始化类的成员变量时,如果操作比较复杂,可以这样写。通过一个private函数来返回你想要的东西
1
2
3
4
5
6
7
8
9
10
11
12/**
* List of filter definitions that are applied to every route.
*/
private List<FilterDefinition> defaultFilters = loadDefaults();
private ArrayList<FilterDefinition> loadDefaults() {
ArrayList<FilterDefinition> defaults = new ArrayList<>();
FilterDefinition definition = new FilterDefinition();
definition.setName(normalizeFilterName(RemoveNonProxyHeadersGatewayFilterFactory.class));
defaults.add(definition);
return defaults;
}Spring-Cloud-Gateway中为什么要用响应式编程?
通过配置来生成一个东西的时候,可以用这种方式。比如这里的RouteDefinition => Route ,前者是管理配置route的,后者是实现的route。而且可以抽象出一个接口,然后实现具体的类实现接口,比如从文件获取配置、从mysql数据库获取配置,从zookeeper、etcd获取配置。
接口为什么可以多继承?因为接口全都是抽象方法继承谁都无所谓,所以接口可以继承多个接口。注意:类实现接口的时候一定要写明public,要不默认的protected,相当于缩小了方法的使用范围。接口中如果返回类型不是void,则实现类一定要有return。
synchronizedMap(new LinkedHashMap<String, RouteDefinition>()); LHM不是线程安全的哦!
什么时候用对象,什么时候new就好,就像这个亚子
1
2
3
4
5RouteDefinition routeDefinition = new RouteDefinition();
// 设置 ID
routeDefinition.setId(this.routeIdPrefix + serviceId);
// 设置 URI
routeDefinition.setUri(URI.create("lb://" + serviceId));如果想创建一个东西,可以通过静态内部类builder的方式,比如这里的build route
当实现方法变换多端时,可以通过一个委托模式来收集,这样能提供一个统一的入口。比如org.springframework.cloud.gateway.route.CompositeRouteLocator ,组合多种 RouteLocator 的实现类,为 RoutePredicateHandlerMapping 提供统一入口访问路由。
1
2
3
4
5
6
7
8
9
10
11
12
13public class CompositeRouteLocator implements RouteLocator {
private final Flux<RouteLocator> delegates;
public CompositeRouteLocator(Flux<RouteLocator> delegates) {
this.delegates = delegates;
}
public Flux<Route> getRoutes() {
return this.delegates.flatMap(RouteLocator::getRoutes);
}
}AtomicReference无锁的对象引用
1
2
3
4/**
* 路由缓存
*/
private final AtomicReference<List<Route>> cachedRoutes = new AtomicReference<>();
这里为什么需要用无锁的对象引用呢?
java里没有tuple,在spring库里实现了一个,https://docs.spring.io/spring-xd/docs/0.1.x-SNAPSHOT/reference/html/_tuples.html
有关HTTP Security headers的一篇文章
https://blog.appcanary.com/2017/http-security-headers.html搭建一个 WebSocket 服务可以使用wscat。
npm install -g wscat
Hystrix 基于 RxJava ,而SpringCloudGateWay中的 GatewayFilter 基于 Reactor 。未来,Hystrix也会基于Reactor。
限流算法
漏桶算法
有一个漏水的桶,肯定是以一定不变的速度漏水吧,当水桶满了,水就溢出去了,可以看出漏桶算法能强行限制数据的传输速率。这里的“桶”是用来buffer请求的。令牌桶算法
对于很多应用场景来说,除了要求能够限制数据的平均传输速率外,还要求允许某种程度的突发传输。这时候漏桶算法可能就不合适了,令牌桶算法更为适合。这个是以一定的速度往桶里放令牌,那我取令牌的速度快一点就可以应对这种突发传输的情况。而令牌桶里的“桶”来计量可用资源数量(令牌)的。虽然我们并不会创建令牌实体,但是仍然可以假想,这个桶内每隔X时间就会新增一定数量的令牌,如果没有请求申请令牌,那么这个令牌桶是会溢出的。
令牌桶成了buffer,如果请求密度低,或者处于冷却状态,那么令牌桶就会溢满,此后如果流量突发,则过去积累的结余资源则可以直接被“借用”。
https://juejin.im/post/5d1c978d51882555433429e6
基于令牌桶算法的限流的特点:让流量平稳,而不是瞬间流量。1000 QPS 相对平均的分摊在这一秒内,而不是第 1 ms 999 请求,后面 999 ms 0 请求。
可以通过Redis Lua 脚本,实现基于令牌桶算法实现限流。不会有并发问题吗?不会,因为redis是单线程的啊。