package com.atguigu.gulimall.gateway.filter; import com.alibaba.cloud.commons.lang.StringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.support.atomic.RedisAtomicLong; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import java.net.InetAddress; import java.net.UnknownHostException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.concurrent.TimeUnit; @Slf4j @Configuration public class AuthFilter implements GlobalFilter, Ordered { @Autowired StringRedisTemplate redisTemplate; @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String countIp = "countIp_"+sdf.format(new Date()); // 请求 ServerHttpRequest request = exchange.getRequest(); // 获取 IP 地址 String ip = getIP(request); String ipRedis = redisTemplate.opsForValue().get(ip); //判断获取redis中今天Ip是否存在, if (!StringUtils.isNotBlank(ipRedis)){ long seconds= (getMiol() - System.currentTimeMillis())/1000; //获取当天剩余时间 incr(countIp, seconds);//加一操作 putTime(ip,ip);//判断本天Ip地址是否存在 } log.info("========= 请求的IP地址:{},当天请求数量:{} " ,ip,redisTemplate.opsForValue().get(countIp)); return chain.filter(exchange); } public Long incr(String key, long liveTime) { RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); Long increment = entityIdCounter.getAndIncrement(); if ((null == increment || increment.longValue() == 0) && liveTime > 0) {//初始设置过期时间 entityIdCounter.expire(liveTime, TimeUnit.SECONDS); } return increment; } public void putTime(String key, String value) { long seconds= ((getMiol() - System.currentTimeMillis())/1000) < 0?1:(getMiol() - System.currentTimeMillis())/1000; //获取剩余时间 System.out.println(seconds); redisTemplate.opsForValue().set(key, value, seconds, TimeUnit.SECONDS); } public static Long getMiol() { Calendar ca = Calendar.getInstance(); //失效的时间 ca.set(Calendar.HOUR_OF_DAY, 23); ca.set(Calendar.MINUTE, 59); ca.set(Calendar.SECOND, 59); long fl = ca.getTimeInMillis(); return fl; } // 多次反向代理后会有多个ip值 的分割符 private final static String IP_UTILS_FLAG = ","; // 未知IP private final static String UNKNOWN = "unknown"; // 本地 IP private final static String LOCALHOST_IP = "0:0:0:0:0:0:0:1"; private final static String LOCALHOST_IP1 = "127.0.0.1"; private static String getIP(ServerHttpRequest request){ // 根据 HttpHeaders 获取 请求 IP地址 String ip = request.getHeaders().getFirst("X-Forwarded-For"); if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeaders().getFirst("x-forwarded-for"); if (ip != null && ip.length() != 0 && !UNKNOWN.equalsIgnoreCase(ip)) { // 多次反向代理后会有多个ip值,第一个ip才是真实ip if (ip.contains(IP_UTILS_FLAG)) { ip = ip.split(IP_UTILS_FLAG)[0]; } } } if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeaders().getFirst("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeaders().getFirst("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeaders().getFirst("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeaders().getFirst("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeaders().getFirst("X-Real-IP"); } //兼容k8s集群获取ip if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getRemoteAddress().getAddress().getHostAddress(); if (LOCALHOST_IP1.equalsIgnoreCase(ip) || LOCALHOST_IP.equalsIgnoreCase(ip)) { //根据网卡取本机配置的IP InetAddress iNet = null; try { iNet = InetAddress.getLocalHost(); } catch (UnknownHostException e) { log.error("getClientIp error: ", e); } ip = iNet.getHostAddress(); } } return ip; } @Override public int getOrder() { return -10; } }
springboot根据IP地址获取当天请求访问量
最新推荐文章于 2023-05-12 21:21:37 发布