首页后端开发其他后端知识SpringCloud Gateway如何实现负载均衡与熔断和限流

SpringCloud Gateway如何实现负载均衡与熔断和限流

时间2024-03-24 21:12:03发布访客分类其他后端知识浏览1238
导读:相信很多人对“SpringCloud Gateway如何实现负载均衡与熔断和限流”都不太了解,下文有实例供大家参考,对大家了解操作过程或相关知识有一定的帮助,而且内容详细,逻辑清晰,接下来小编就为你详细解释一下这个问题。...
相信很多人对“SpringCloud Gateway如何实现负载均衡与熔断和限流”都不太了解,下文有实例供大家参考,对大家了解操作过程或相关知识有一定的帮助,而且内容详细,逻辑清晰,接下来小编就为你详细解释一下这个问题。


环境准备
  • 注册中心Nacos,也可以其他
  • springboot 2.6.8
  • spring-cloud-dependencies 2021.0.3

1.pom依赖

parent包

parent>
    
	groupId>
    org.springframework.boot/groupId>
    
	artifactId>
    spring-boot-starter-parent/artifactId>
    
	version>
    2.6.8/version>
    
/parent>
    

gateway依赖

dependency>
    
	groupId>
    org.springframework.cloud/groupId>
    
	artifactId>
    spring-cloud-starter-gateway/artifactId>
    
/dependency>
    
!--服务注册与发现-->
    
dependency>
    
	groupId>
    com.alibaba.cloud/groupId>
    
	artifactId>
    spring-cloud-starter-alibaba-nacos-discovery/artifactId>
    
	version>
    2021.0.1.0/version>
    
/dependency>
    
!--远程服务路由-->
    
dependency>
    
	groupId>
    org.springframework.cloud/groupId>
    
	artifactId>
    spring-cloud-loadbalancer/artifactId>
    
/dependency>
    

springcloud版本管理

dependencyManagement>
    
	dependencies>
    
		dependency>
    
			groupId>
    org.springframework.cloud/groupId>
    
			artifactId>
    spring-cloud-dependencies/artifactId>
    
			version>
    2021.0.3/version>
    
			type>
    pom/type>
    
			scope>
    import/scope>
    
		/dependency>
    
	/dependencies>
    
/dependencyManagement>

2.yaml配置

spring:
application:
name: gatewayservice
cloud:
#找对应网段的网卡 不配置内部服务就走外网
inetutils:
preferred-networks: 192.168.0
nacos:
discovery:
#nacos注册地址
server-addr: 192.168.0.221:8848
gateway:
routes:
- id: user
#根据服务名转发 只需要名称 不用端口
uri: lb://userservice
#ip的形式转发
# uri: http://127.0.0.1:7540
predicates:
#路由规则
- Path=/user/**
filters:
#1/去掉前缀 0/保持原路径
- StripPrefix=1
#跨域配置
globalcors:
cors-configurations:
'[/**]':
# 允许携带认证信息
allowCredentials: true
# 允许跨域的源(网站域名/ip),设置*为全部
allowedOriginPatterns: "*"
# 允许跨域的method, 默认为GET和OPTIONS,设置*为全部
allowedMethods: "*"
# 允许跨域请求里的head字段,设置*为全部
allowedHeaders: "*"

#本地静态路由配置 jar包依赖不一样
#my-load-balanced-service:
# ribbon:
# listOfServers: http://127.0.0.1:7540,http://127.0.0.1:7541
#轮询
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

3.路由转发和负载均衡测试

启动不同端口的user服务,然后通过gateway调用

user服务暴露接口

访问地址http://127.0.0.1:7500/user/test

@Value("${
server.port}
    ")
String port;

@GetMapping("/test")
public String test() {
    
    return new Date().getTime() + ":" + port;

}

返回结果输出

1657261506117:7540
1657261509785:7541
1657261513874:7540
1657261517464:7541

可以正常路由转发和负载均衡,默认策略是轮询

4.gateway熔断实现

熔断:就是通过在转发过程中失败的,从而采取的降级策略。良好的返回提示给前端。

4.1 熔断代码

@Component
public class FallbackHandler implements ErrorWebExceptionHandler {
    
    @Override
    public MonoVoid>
 handle(ServerWebExchange exchange, Throwable ex) {
    
        String message = "服务正在维护,请稍后再试!";

        byte[] bytes = String.format("{
\"code\":-1,\"message\":\"%s\",\"data\":null}
    ",
                message).getBytes(StandardCharsets.UTF_8);
    
        DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);
    
        exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
    
        return exchange.getResponse().writeWith(Flux.just(buffer));

    }

}

本来是想通过Hystrix直接配置重定向的,奈何spring-cloud-starter-netflix-hystrix已经不更新了,没法兼容。直接采用一刀切算了。

4.2 测试

开启gateway和user服务访问后,然后停掉user。结果如下

{ "code":-1,"message":"服务正在维护,请稍后再试!","data":null}

在这里需要注意的两个点

  • 如果配置的是服务名,gateway先注册转发服务还没注册到Nacos时,访问就不会走熔断,会提示No servers available for service: userservice
  • 如果配置的是http地址,无对应的服务存在时则可以正常走熔断

5.gateway限流

用的是自带的令牌桶算法,例如总共十个令牌,每秒恢复一个,那么一秒内最大只能获取10个令牌,超过的则直接控制掉返回429 Too Many Requests

5.1 需要集成redis

pom依赖如下

dependency>
    
	groupId>
    org.springframework.boot/groupId>
    
	artifactId>
    spring-boot-starter-data-redis-reactive/artifactId>
    
/dependency>

5.2 yaml配置

#引入数据库
redis:
database: 0
host: 192.168.0.100
port: 6379

//限流策略
gateway:
routes:
- id: user
uri: lb://userservice
predicates:
- Path=/user/**
filters:
#名称不可修改
- name: RequestRateLimiter
args:
#限流策略名 通过代码注入到spring容器中去
key-resolver: "#{ @ipKeyResolver} "
#令牌桶每秒填充平均速率
redis‐rate‐limiter.replenishRate: 1
#令牌桶总容量
redis‐rate‐limiter.burstCapacity: 2
# 每次请求获取的令牌数
redis-rate-limiter.requestedTokens: 1

上述配置含义:针对ip限流,总令牌数2,没秒恢复一个,每次获取一个。也就是说一秒内超过2次则会被限流。

注意上述限流配置缺一不可,不然启动也不会报错,也不会生效,重点是转发也不成功了

5.3 注入到spring容器

//针对ip限流
@Primary
@Bean(value = "ipKeyResolver")
public KeyResolver ipKeyResolver() {
    
    return exchange ->
     Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());

}

//针对路径限流
//    @Bean(name = "apiKeyResolver")
public KeyResolver apiKeyResolver() {
    
    return exchange ->
     Mono.just(exchange.getRequest().getPath().value());

}
    

5.4 测试

访问http://127.0.0.1:7500/user/test,一秒内访问三次

redis截图

网页端截图

限流生效!



以上就是关于“SpringCloud Gateway如何实现负载均衡与熔断和限流”的介绍了,感谢各位的阅读,希望文本对大家有所帮助。如果想要了解更多知识,欢迎关注网络,小编每天都会为大家更新不同的知识。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: SpringCloud Gateway如何实现负载均衡与熔断和限流
本文地址: https://pptw.com/jishu/652321.html
修改oracle用户密码的操作是什么? oracle查询慢的问题怎样解决?

游客 回复需填写必要信息