使用redis,实现了项目的一些功能:完成网关层请求,一分钟请求数不超过20次,
两次重复点击不允许,分布式锁。通过用户id ,获取用户信息。
一:完成网关层请求,一分钟请求不超过20次
首先添加maven依赖
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
application.propertie
#server.port=2001
Redis服务器连接端口
#spring.redis.port=6379
Redis服务器地址
#spring.redis.host=127.0.0.1
Redis数据库索引(默认为0)
#spring.redis.database=0
Redis服务器连接密码(默认为空)
#spring.redis.password=125259
连接池最大连接数(使用负值表示没有限制)
#spring.redis.jedis.pool.max-active=200
连接池中的最大空闲连接
#spring.redis.jedis.pool.max-idle=60
连接池中的最小空闲连接
#spring.redis.jedis.pool.min-idle=30
连接池最大阻塞等待时间(使用负值表示没有限制)
#spring.redis.jedis.pool.max-wait=60000ms
连接超时时间(毫秒)
#spring.redis.timeout=5000ms 然后配置redisConfig
然后,redisconfig 主要是json序列化
("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setValueSerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
再新建一个IPCheckFilter,通过这个过滤器去实现网关层请求限流
("${spring.gateway.limit.num}")
private int limit;
("${server.port}")
private String port ;
private RedisTemplate redisTemplate;
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
InetAddress inetAddress = InetAddress.getLocalHost();
String ipAddress = inetAddress.getHostAddress();
String key = "gateway:" + ipAddress+ ":" + port;
long count = redisTemplate.opsForValue().increment(key, 1);
if (count == 1) {
redisTemplate.expire(key, 60, TimeUnit.SECONDS);
}
if (count > limit) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
response.getHeaders().add("X-Rate-Limit-Remaining", "0");
response.getHeaders().setContentType(MediaType.TEXT_PLAIN);
byte[] messageBytes = "当前ip一分钟内请求超过限制,请稍后重试".getBytes(StandardCharsets.UTF_8);
return response.writeWith(Mono.just(response.bufferFactory().wrap(messageBytes)));
}
return chain.filter(exchange);
}
}
测试结果,一分钟内超过20次,不再返回请求结果,而是“当前ip一分钟内请求超过限制,请稍后重试”,需求完成。
-----未完待续------