Spring Cloud Gateway使用及配置
发布日期:2021-06-30 21:30:32 浏览次数:3 分类:技术文章

本文共 10408 字,大约阅读时间需要 34 分钟。

引入依赖包

org.springframework.cloud
spring-cloud-starter-gateway
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-starter-netflix-ribbon
org.springframework.boot
spring-boot-starter-data-redis
org.apache.commons
commons-pool2

配置文件

Spring相关配置

#应用配置server:  port: 8808 #应用端口号  servlet:    context-path: /  #应用host名称spring:  gateway:    discovery:      locator:        enabled: false # 根据注册中心自动注册路由,默认false 重启生效        lowerCaseServiceId: false # 将注册表中的服务名转为小写创建路由,默认false,重启生效    httpclient: #http连接设置      pool:        max-connections: 5000 #最大连接数#       max-life-time: 45000 #最大连接时间        acquire-timeout: 15000 #返回时间        max-idle-time: 10000 #最大空闲时间  application:        name: lizz-gateway #应用名称  redis: #redis配置    database: 6 # Redis默认情况下有16个分片,这里配置具体使用的分片,默认是0    host: 10.2.55.7   # Redis服务器地址    port: 6379 # Redis服务器连接端口    password:  # Redis服务器连接密码(默认为空)    max-active: 200 # 连接池最大连接数(使用负值表示没有限制)    max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)    max-idle: 10 # 连接池中的最大空闲连接    min-idle: 0 # 连接池中的最小空闲连接    timeout: 1000 # 连接超时时间(毫秒)#    cluster: 集群#      nodes:#        - 127.0.0.1:6379#        - 127.0.0.1:6380#        - 127.0.0.1:6381#        - 127.0.0.1:6382#eurela注册中心集群地址eureka:  instance:    prefer-ip-address: true #当微服务有使用IP进行注册时,优先使用IP进行访问  client:    service-url:       defaultZone: http://10.2.55.100:31000/eureka/,http://10.2.55.100:32000/eureka/#日志级别logging:  level:    org:      springframework:        cloud:          gateway: TRACE #开启跟踪日志用于测试

路由配置

注:

  • “=”号参数不能有空格,如“StripPrefix=1”不能写成“StripPrefix = 1”。
  • 路由匹配从上往下,优先匹配前面的路由。
spring:  cloud:    gateway:        filter:            remove-hop-by-hop:              headers:  #默认的移除request中的header                - aaa                - bbb#      httpclient:#        connect-timeout: 1000 # 转发后端服务超时时间#        response-timeout: 3s  # 转发后端服务响应超时时间#      discovery:#        locator:#          enabled: true #开启服务注册和发现#          lower-case-service-id: true #注册名转为小写      routes: #路由配置        - id: route_1 #直接跳转到指定域名下 http://10.2.11.6:8808/gw/1 > http://10.2.11.6:8800/gw/1          uri: http://10.2.11.6:8800 #目标路径          predicates: #谓词匹配            - Path=/gw/** #匹配路径        - id: route_2 #去除前缀跳转 http://10.2.11.6:8808/sp/hi/1 > http://10.2.11.6:8800/hi/1          uri: http://10.2.11.6:8800 #目标路径          predicates: #谓词匹配            - Path=/sp/** #匹配路径            - Method=GET #指定方式          filters:            - StripPrefix=1 #去除第一个级前缀        - id: route_3 # 增加前缀  http://10.2.11.6:8808/pp/1 > http://10.2.11.6:8800/hi/1          uri: http://10.2.11.6:8800  #目标路径          predicates: #谓词匹配            - Path=/pp/** #匹配路径          filters:            - StripPrefix=1 #去除第一个级前缀            - PrefixPath=/hi #        - id: route_4 # 重写前缀  http://10.2.11.6:8808/rp/1 > http://10.2.11.6:8800/hi/1          uri: http://10.2.11.6:8800  #目标路径          predicates: #谓词匹配            - Path=/rp/** #匹配路径          filters:            - RewritePath=/rp, /hi        - id: route_5 # 动态重写前缀  http://10.2.11.6:8808/rp1 > http://10.2.11.6:8800/hi/rp1          uri: http://10.2.11.6:8800  #目标路径          predicates: #谓词匹配            - Path=/rp1/** #匹配路径          filters:            - RewritePath=(?
^/), /hi$\{oldPath} - id: route_6 # 指定跳转路径 http://10.2.11.6:8808/setpath > http://10.2.11.6:8800/hi/1 uri: http://10.2.11.6:8800 #目标路径 predicates: #谓词匹配 - Path=/setpath/** #匹配路径 filters: - SetPath=/hi/1 - id: route_7 # 设置路径,同时使用时,根据前后顺序进行设置,改变顺序结果不同 http://10.2.11.6:8808/allpath > http://10.2.11.6:8800/hi/a uri: http://10.2.11.6:8800 #目标路径 predicates: #谓词匹配 - Path=/allpath/** #匹配路径 filters: - PrefixPath=/b # http://10.2.11.6:8808/allpath > http://10.2.11.6:8800/b/allpath - SetPath=/a # http://10.2.11.6:8800/b/allpath > http://10.2.11.6:8800/a - RewritePath=(?
^/), /hi$\{oldPath} # http://10.2.11.6:8800/b/a > http://10.2.11.6:8800/hi/a - id: route_8 # 通过eureka访问 http://10.2.11.6:8808/eureka/lb/1 > http://10.2.11.6:8800/lb/1 uri: lb://lizz-eureka-provider #目标路径 predicates: #谓词匹配 - Path=/eureka/** #匹配路径# metadata:# connect-timeout: 200 #响应时间 ,当前2.2.0版本暂不支持# response-timeout: 1000 #链接时间,当前2.2.0版本暂不支持 filters: - StripPrefix=1 #去除第一个级前缀 - name : RequestSize args: maxSize: 500000 #限制请求数据大小,byte,比较的长度String contentLength = request.getHeaders().getFirst("content-length"); - name: Retry #重试过滤器,重试调用lizz-eureka-provider的次数 args: retries: 1 #重试次数 默认3次 statuses: BAD_GATEWAY #HttpStatus 什么情况下重试,可以是错误码,如:500,502 series: # HttpStatus.重试系列 默认 SERVER_ERROR-5xx,SUCCESSFUL-2xx ,空为异常补重试,与statuses并行使用 exceptions: #异常重试 默认IOException and TimeoutException,空为异常补重试 methods: GET,POST # HttpMethod 重试的方法 默认 GET GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE; backoff: #延时重试 firstBackoff: 10ms #首次延时次数 maxBackoff: 50ms # 最大延迟后停止 factor: 2 #重试因子 下一次重试延时为firstBackoff*2*n次 basedOnPreviousValue: false #为true, backoff 计算公式为 prevBackoff * factor. - id: route_9 # 流量限制 uri: lb://lizz-eureka-provider #目标路径 predicates: #谓词匹配 - Path=/iprate/** #匹配路径 filters: - StripPrefix=1 #去除第一个级前缀 - name: RequestRateLimiter args: redis-rate-limiter: #过期时间=burstCapacity/replenishRate*2s replenishRate: 3 #每次补充数量 burstCapacity: 1000 #突发容量 requestedTokens: 1 #每次请求消耗几个令牌,可以控制不同频率,默认1 key-resolver: "#{@ipKeyResolver}" # ipKeyResolver 自定义限流柜子# rate-limiter: "#{@myRateLimiter}" # 使用自定义限流规则 - id: route_10 # 修改header uri: lb://lizz-eureka-provider #目标路径 predicates: #谓词匹配 - Path=/userrate/** #匹配路径 filters: - AddRequestHeader=X-Request-Foo,Bar #增加转发请求的header 格式:key,value - AddRequestParameter=foo,bar #增加转发请求的参数 - AddResponseHeader=X-Request-Foo,Bar #增加返回数据的header - RemoveRequestHeader=X-Request-Foo #移除转发请求的header - RemoveResponseHeader=X-Request-Foo #移除返回数据的header

Ribbon相关配置

ribbon:  eureka:    enabled: true #默认开启ribbon,关闭faslespring:  cloud:    loadbalancer:      retry:        enabled: true #开启VEHICLE-CUSTOMER-SERVICE: #对应lb的微服务名称  ribbon:    #BestAvailableRule:选择一个最小的并发请求的server    #AvailabilityFilteringRule:过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)    #WeightedResponseTimeRule:根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低。    #RetryRule:对选定的负载均衡策略机上重试机制。    #RoundRobinRule:roundRobin方式轮询选择server    #RandomRule:随机选择一个server    #ZoneAvoidanceRule:复合判断server所在区域的性能和server的可用性选择server#    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #负载策略,默认RoundRobinRule轮训策略    NFLoadBalancerRuleClassName: com.gateway.loadbalancer.MatchRule #自定义负载策略    #listOfServers: localhost:8090,localhost:9092,localhost:9999 #自定义服务列表,不使用eureka,需要ribbon.eureka.enabled设置为false    #ServerListRefreshInterval: 10000 #listOfServers列表刷新时间,单位ms#    ReadTimeout: 1 # 请求处理的超时时间#    ConnectTimeout: 1 # 请求连接的超时时间#    OkToRetryOnAllOperations: false # 对所有操作请求都进行重试,默认 false#    MaxAutoRetriesNextServer: 1 #切换重试次数#    MaxAutoRetries: 3 #对当前实例的重试次数

限流规则代码

方法名与配置文件中的key-resolver参数对应

@Configurationpublic class RateResolver {    @Value("")    /**     * 必须有一个主键方法     * 根据ip进行限流     * @return     */    @Primary    @Bean    public KeyResolver ipKeyResolver() {        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());    }    /**     * 根据用户限流     * 根据参数中的userId值进行限流     * @return     */    @Bean    public KeyResolver userKeyResolver() {        return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));    }    /**     * 根据api限流     * 根据请求path进行限流     * @return     */    @Bean    KeyResolver apiKeyResolver() {        return exchange -> Mono.just(exchange.getRequest().getPath().value());    }    /**     * 根据自定义key限流     * @return     */    @Bean    public KeyResolver otherKeyResolver() {        return exchange -> Mono.just(getOtherKey(exchange));    }    /**     * 自定义限流key,根据需要生产key     * @param exchange     * @return     */    private String getOtherKey(ServerWebExchange exchange){        String key;        String userId = exchange.getRequest().getQueryParams().getFirst("uid");        Map aa = exchange.getAttributes();        key = userId + aa.get("group");        return key;    }}

限流原理

执行限流过程时,Gateway会通过在request_rate_limiter.lua脚本在redis中创建两个key:

  • request_rate_limiter.{$key}.timestamp:最近获取令牌时间
  • request_rate_limiter.{$key}.tokens:可用令牌数量

注:key的存活时间为路由配置中的 burstCapacity/replenishRate*2s

当burstCapacity:100,replenishRate:2,100/2*2s=100s

当burstCapacity:200,replenishRate:100,200/100*2s=4s

正常情况几秒内就会消失,需要查看key值可以将差值调大查看。

自定义过滤器

公用过滤器

实现GlobalFilter和Ordered即可。

/** * @Description: 自定义拦截器 * @Auther: lizz * @Date: 2019/12/26 17:32 */@Componentpublic class JWTFilter implements GlobalFilter, Ordered {    private static final Logger logger = LoggerFactory.getLogger(JWTFilter.class);    @Override    public Mono
filter(ServerWebExchange exchange, GatewayFilterChain chain) { logger.info(" JWTFilter 过滤"); //获取请求信息进行过滤// exchange.getApplicationContext();// exchange.getAttribute("uid");// exchange.getAttributes();// exchange.getFormData();// exchange.getRequest().getQueryParams();// exchange.getSession(); //拦截请求 //return exchange.getResponse().setComplete(); //执行下一个拦截器 return chain.filter(exchange); } @Override public int getOrder() { //拦截器优先级,0位最先执行 return 0; }}

 

转载地址:https://lizz6.blog.csdn.net/article/details/103697453 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Spring Cloud Gateway压测(wrk、k8s、nginx)
下一篇:Apollo配置中心使用及热更新

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月11日 09时03分45秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章