# SpringCloud Gateway 2

img

# 路由

# 使用webflux

	@Bean
	public RouterFunction<ServerResponse> function(){
		
		RouterFunction<ServerResponse> route = RouterFunctions.route(
				
				RequestPredicates.path("/002"),
				req -> ServerResponse.ok().body(BodyInserters.fromValue("xxx"))
				
				);
		
		return route;
		
		
	}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 缓存

# 权重与灰度发布

img

# 随机算法

      routes:
      - id: w1
        predicates:
        - Path=/w/**
        - Weight=service,95
        uri: lb://MDB
        
        filters:
        - StripPrefix=1
        
        
      - id: w2
        predicates:
        - Path=/w/**
        - Weight=service,5
        uri: lb://MDB2
        
        filters:
        - StripPrefix=1        
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 过滤器

SpringCloud Gateway用于拦截用户请求和链式处理,可以实现面向切面编程,在切面中可以实现与应用无关的需求,比如安全、访问超时等

# 有序

order值越小 优先级越高

	@Override
	public int getOrder() {
		// TODO Auto-generated method stub
		return 110;
	}
1
2
3
4
5

# 限流

# 内置令牌桶 + Redis

pom

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
1
2
3
4
      routes:
      - id: w1
        predicates:
        - Path=/w/**
        uri: lb://MDB2
        
        filters:
        - StripPrefix=1
        - name: RequestRateLimiter
          args:
            key-resolver: '#{@userKeyResolver}'
            redis-rate-limiter.replenishRate: 1
            redis-rate-limiter.burstCapacity: 3
1
2
3
4
5
6
7
8
9
10
11
12
13
public class RateLimitConfig {
    KeyResolver userKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
    }
}

1
2
3
4
5
6

# 整合GoogleGuava

DefaultRateLimiter

package com.mashibing.admin;

import java.util.HashMap;
import java.util.Objects;

import javax.validation.constraints.DecimalMin;

import org.springframework.cloud.gateway.filter.ratelimit.AbstractRateLimiter;
import org.springframework.cloud.gateway.support.ConfigurationService;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import com.google.common.util.concurrent.RateLimiter;

import reactor.core.publisher.Mono;

@Component
@Primary
public class DefaultRateLimiter extends AbstractRateLimiter<DefaultRateLimiter.Config> {

    public DefaultRateLimiter() {
    	
        super(Config.class, "default-rate-limit", new ConfigurationService());
    }

	/**
     * 每秒一个请求,每秒发一个令牌
     */
    private final RateLimiter limiter = RateLimiter.create(1);



    @Override
    public Mono<Response> isAllowed(String routeId, String id) {
        Config config = getConfig().get(routeId);
        limiter.setRate(Objects.isNull(config.getPermitsPerSecond()) ? 1 : config.getPermitsPerSecond());

        boolean isAllow = limiter.tryAcquire();

        return Mono.just(new Response(isAllow, new HashMap<>()));
    }

    @Validated
    public static class Config {

        @DecimalMin("0.1")
        private Double permitsPerSecond;


        public Double getPermitsPerSecond() {
            return permitsPerSecond;
        }

        public Config setPermitsPerSecond(Double permitsPerSecond) {
            this.permitsPerSecond = permitsPerSecond;
            return this;
        }
    }

	
	
	
	
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

配置

      routes:
      - id: w1
        predicates:
        - Path=/w/**
        uri: lb://MDB2
        
        filters:
        - StripPrefix=1
        - name: RequestRateLimiter
          args:
            rate-limiter: "#{@defaultRateLimiter}"
            key-resolver: "#{@userKeyResolver}"
            default-rate-limit.permitsPerSecond: 0.5
        
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 权限

写在filter中

# hystrix

项目里讲

# 生命周期

img

Spring Cloud Gateway同zuul类似,有“pre”和“post”两种方式的filter。客户端的请求先经过“pre”类型的filter,然后将请求转发到具体的业务服务,比如上图中的user-service,收到业务服务的响应之后,再经过“post”类型的filter处理,最后返回响应到客户端。