Browse Source

新增限流规则

chenweida 6 years ago
parent
commit
f65dd14fde

+ 32 - 0
common-router-starter/src/main/java/com/yihu/base/router/RouteEndPoint.java

@ -1,7 +1,9 @@
package com.yihu.base.router;
import com.alibaba.fastjson.JSON;
import com.yihu.base.router.model.Ratelimit;
import com.yihu.base.router.model.RuleRoute;
import com.yihu.base.router.ratelimit.storage.IRateLimitStorage;
import com.yihu.base.router.rule.storage.IRuleStorage;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
@ -25,6 +27,8 @@ public class RouteEndPoint {
    @Autowired
    private IRuleStorage ruleStorage;
    @Autowired
    private IRateLimitStorage rateLimitStorage;
    @Autowired
    private RefreshRouteService refreshRouteService;
    @PostMapping(value = "/rule/save")
@ -124,4 +128,32 @@ public class RouteEndPoint {
            return e.getMessage();
        }
    }
    @PostMapping(value = "/ratelimit/save")
    @ApiOperation(value = "新增路由规则", notes = "")
    public String saveRule(
            @ApiParam(name = "id", value = "主键", required = true) @RequestParam(required = true, name = "id") String id,
            @ApiParam(name = "ip", value = "ip地址", required = true) @RequestParam(required = true, name = "ip") String ip,
            @ApiParam(name = "path", value = "限制访问的路径", required = false) @RequestParam(required = false, name = "path") String path,
            @ApiParam(name = "accessCount", value = "次数", required = false) @RequestParam(required = false, name = "accessCount",defaultValue = "0") Integer accessCount,
            @ApiParam(name = "accessUnit", value = "访问的次数限制单位 默认是分钟  1秒 2 分钟 3小时 4天 结合accessCount使用 ", required = false) @RequestParam(required = false, name = "accessUnit") String accessUnit
    ) {
        Ratelimit ratelimit=new Ratelimit();
        ratelimit.setId(id);
        ratelimit.setAccessCount(accessCount);
        ratelimit.setAccessUnit(accessUnit);
        ratelimit.setIp(ip);
        ratelimit.setPath(path);
        rateLimitStorage.saveRateLimit(ratelimit);
        return "成功";
    }
    @PostMapping(value = "/ratelimit/delete")
    @ApiOperation(value = "删除路由规则", notes = "")
    public String deleteRule(
            @ApiParam(name = "id", value = "主键", required = true) @RequestParam(required = true, name = "id") String id
      ) {
        rateLimitStorage.deleteRateLimitById(id);
        return "成功";
    }
}

+ 37 - 1
common-router-starter/src/main/java/com/yihu/base/router/RouterAutoConfig.java

@ -1,5 +1,12 @@
package com.yihu.base.router;
import com.yihu.base.router.ratelimit.IPRateLimiter;
import com.yihu.base.router.ratelimit.IRatelimiter;
import com.yihu.base.router.ratelimit.filter.RateLimitFilter;
import com.yihu.base.router.ratelimit.manage.SimpleRateLimitManager;
import com.yihu.base.router.ratelimit.storage.AbstractRateLimitStorage;
import com.yihu.base.router.ratelimit.storage.IRateLimitStorage;
import com.yihu.base.router.ratelimit.storage.RedisRateLimitStorage;
import com.yihu.base.router.route.SimplerRouter;
import com.yihu.base.router.rule.manager.SimpleRuleManager;
import com.yihu.base.router.rule.storage.AbstractRuleStorage;
@ -14,6 +21,8 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.Set;
/**
 * Created by chenweida on 2018/4/27 0027.
 */
@ -28,9 +37,30 @@ public class RouterAutoConfig {
    ZuulProperties zuulProperties;
    @Autowired
    ServerProperties server;
    //--------------------------限制规则相关配置 start---------------------------
    //--------------------------限制规则相关配置 start---------------------------
    @Bean
    @ConditionalOnMissingBean
    public IRateLimitStorage redisRateLimitStorage() {
        RedisRateLimitStorage redisRateLimitStorage = new RedisRateLimitStorage();
        redisRateLimitStorage.setRedisTemplate(redisTemplate);
        return redisRateLimitStorage;
    }
    @Bean
    @ConditionalOnMissingBean
    public SimpleRateLimitManager simpleRateLimitManager(Set<IRatelimiter> ratelimiters) {
        SimpleRateLimitManager simpleRateLimitManager = new SimpleRateLimitManager();
        simpleRateLimitManager.setRatelimiters(ratelimiters);
        return simpleRateLimitManager;
    }
    @Bean
    public IPRateLimiter ipRateLimiter(){
        IPRateLimiter rateLimiter= new IPRateLimiter();
        rateLimiter.setRateLimitStorage(redisRateLimitStorage());
        return rateLimiter;
    }
    //--------------------------限制规则相关配置 end---------------------------
@ -61,5 +91,11 @@ public class RouterAutoConfig {
        return simplerRouter;
    }
    //--------------------------路由规则相关配置 end---------------------------
    @Bean
    public RateLimitFilter rateLimitFilter(Set<IRatelimiter> ratelimiters) {
        RateLimitFilter rateLimitFilter = new RateLimitFilter();
        rateLimitFilter.setRateLimitManager(simpleRateLimitManager(ratelimiters));
        return rateLimitFilter;
    }
}

+ 34 - 0
common-router-starter/src/main/java/com/yihu/base/router/model/RateLimitCount.java

@ -0,0 +1,34 @@
package com.yihu.base.router.model;
/**
 * Created by chenweida on 2018/4/27 0027.
 */
public class RateLimitCount {
    private Integer count;//访问次数
    private String startTime;//开始时间  yyyy-MM-dd HH:mm:ss
    private String endTime;//结束时间 yyyy-MM-dd HH:mm:ss
    public Integer getCount() {
        return count;
    }
    public void setCount(Integer count) {
        this.count = count;
    }
    public String getStartTime() {
        return startTime;
    }
    public void setStartTime(String startTime) {
        this.startTime = startTime;
    }
    public String getEndTime() {
        return endTime;
    }
    public void setEndTime(String endTime) {
        this.endTime = endTime;
    }
}

+ 77 - 0
common-router-starter/src/main/java/com/yihu/base/router/model/Ratelimit.java

@ -0,0 +1,77 @@
package com.yihu.base.router.model;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
/**
 * Created by chenweida on 2018/4/27 0027.
 */
public class Ratelimit {
    private String id;//主键
    private String ip;//ip地址
    private String path;// 限制访问的路径
    private Integer accessCount = 0;//次数 默认是0 表示没有限制
    private String accessUnit = "2";//访问的次数限制单位 默认是分钟  1秒 2 分钟 3小时 4天 结合accessCount使用
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }
    public String getPath() {
        return path;
    }
    public void setPath(String path) {
        this.path = path;
    }
    public Integer getAccessCount() {
        return accessCount;
    }
    public void setAccessCount(Integer accessCount) {
        this.accessCount = accessCount;
    }
    public String getAccessUnit() {
        return accessUnit;
    }
    public void setAccessUnit(String accessUnit) {
        this.accessUnit = accessUnit;
    }
    public String getEndTime() {
        switch (accessUnit) {
            case "1": {
                return LocalDateTime.now().minusSeconds(-1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
            case "2": {
                return LocalDateTime.now().minusMinutes(-1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"+":00"));
            }
            case "3": {
                return LocalDateTime.now().minusHours(-1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH"+":00:00"));
            }
            case "4": {
                return LocalDateTime.now().minusDays(-1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"+" 00:00:00"));
            }
        }
        return null;
    }
}

+ 12 - 0
common-router-starter/src/main/java/com/yihu/base/router/model/RuleRoute.java

@ -98,4 +98,16 @@ public class RuleRoute {
    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }
    @Override
    public String toString() {
        return "RuleRoute{" +
                "id='" + id + '\'' +
                ", path='" + path + '\'' +
                ", serviceId='" + serviceId + '\'' +
                ", url='" + url + '\'' +
                ", retryable=" + retryable +
                ", enabled=" + enabled +
                '}';
    }
}

+ 61 - 2
common-router-starter/src/main/java/com/yihu/base/router/ratelimit/IPRateLimiter.java

@ -1,11 +1,16 @@
package com.yihu.base.router.ratelimit;
import com.yihu.base.router.model.Ratelimit;
import com.yihu.base.router.model.RuleRoute;
import com.yihu.base.router.ratelimit.storage.IRateLimitStorage;
import com.yihu.base.router.util.NetworkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
 * Created by chenweida on 2018/4/27 0027.
@ -14,18 +19,72 @@ import javax.servlet.http.HttpServletRequest;
public class IPRateLimiter implements IRatelimiter {
    private Logger logger = LoggerFactory.getLogger(IPRateLimiter.class);
    private IRateLimitStorage rateLimitStorage;
    private AntPathMatcher antPathMatcher = new AntPathMatcher();
    @Override
    public Boolean rateLimit(HttpServletRequest request) {
        try {
            logger.info("path:" + request.getRequestURI());
            //这边可以根据数据库的配置去判断当前的路径是否是限制的
            //获取请求的的链接
            String path = request.getRequestURI();
            logger.info("path:" + path);
            //获取ip
            String requestIP = NetworkUtil.getIpAddress(request);
            logger.info("ip:" + requestIP);
            //获取数据库规则
            List<Ratelimit> ratelimitList = rateLimitStorage.findAllRatelimit();
            //便利判断
            if (ratelimitList != null && ratelimitList.size() > 0) {
                for (int i = 0; i < ratelimitList.size(); i++) {
                    Ratelimit ratelimit = ratelimitList.get(i);
                    if (StringUtils.isEmpty(ratelimit.getIp())) {
                        //如果数据是空跳过
                        logger.error("ratelimitId:" + ratelimit.getId() + " ip is null");
                        continue;
                    } else {
                        //1.验证当前请求是否符合规则
                        if (!antPathMatcher.match(ratelimit.getPath(), path)) {
                            continue;
                        }
                        //2.判断当前请求的ip是不是可以通过的ip
                        if (requestIP.equals(ratelimit.getIp())) {
                            //3 判断是否有次数限制
                            //默认是0 表示没有限制
                            if (ratelimit.getAccessCount() == 0) {
                                return true;
                            }
                            //如果没有超过次数限制
                            if (!rateLimitStorage.isUpperLimit(ratelimit.getId())) {
                                if (!rateLimitStorage.countDec(ratelimit.getId())) {
                                    return false;
                                }
                                return true;
                            } else {
                                return false;
                            }
                        } else {
                            return false;
                        }
                    }
                }
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            return false;
        }
    }
    public IRateLimitStorage getRateLimitStorage() {
        return rateLimitStorage;
    }
    public void setRateLimitStorage(IRateLimitStorage rateLimitStorage) {
        this.rateLimitStorage = rateLimitStorage;
    }
}

+ 12 - 6
common-router-starter/src/main/java/com/yihu/base/router/ratelimit/filter/RateLimitFilter.java

@ -34,17 +34,23 @@ public class RateLimitFilter extends ZuulFilter {
    @Override
    public boolean shouldFilter() {
        //返回一个boolean值来判断该过滤器是否要执行,true表示执行,false表示不执行。
        HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
        logger.info("path:"+request.getRequestURI());
        logger.info("这边可以根据数据库的配置去判断当前的路径是否是限制的");
        //这边可以根据数据库的配置去判断当前的路径是否是限制的
        //to do....................................
        return true;
    }
    @Override
    public Object run() {
        logger.info("进入zuul过滤器");
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        //这边可以根据数据库的配置去判断当前的路径是否是限制的
        Boolean flag = rateLimitManager.dofilter(request);
        if (flag) {
            ctx.setSendZuulResponse(true);
            ctx.setResponseStatusCode(200);
        } else {
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            ctx.setResponseBody("{\"result\":\"no authority !\"}");
        }
        return null;
    }

+ 8 - 0
common-router-starter/src/main/java/com/yihu/base/router/ratelimit/manage/SimpleRateLimitManager.java

@ -23,4 +23,12 @@ public class SimpleRateLimitManager extends AbstractRateLimitManager {
        }
        return true;
    }
    public Set<IRatelimiter> getRatelimiters() {
        return ratelimiters;
    }
    public void setRatelimiters(Set<IRatelimiter> ratelimiters) {
        this.ratelimiters = ratelimiters;
    }
}

+ 46 - 0
common-router-starter/src/main/java/com/yihu/base/router/ratelimit/storage/AbstractRateLimitStorage.java

@ -1,7 +1,53 @@
package com.yihu.base.router.ratelimit.storage;
import com.yihu.base.router.model.Ratelimit;
import java.util.List;
/**
 * Created by chenweida on 2018/4/27 0027.
 */
public class AbstractRateLimitStorage implements IRateLimitStorage {
    @Override
    public Boolean saveRateLimit(Ratelimit ratelimit) {
        return null;
    }
    @Override
    public Boolean updateRateLimit(Ratelimit ratelimit) {
        return null;
    }
    @Override
    public Boolean deleteRateLimitById(String id) {
        return null;
    }
    @Override
    public Ratelimit findRateLimitById(String id) {
        return null;
    }
    @Override
    public List<Ratelimit> findAllRatelimit( ) {
        return null;
    }
    @Override
    public Boolean countDec(String id) {
        return null;
    }
    @Override
    public Integer getCount(String id) {
        return null;
    }
    @Override
    public Boolean isUpperLimit(String id) {
        return null;
    }
}

+ 57 - 0
common-router-starter/src/main/java/com/yihu/base/router/ratelimit/storage/IRateLimitStorage.java

@ -1,7 +1,64 @@
package com.yihu.base.router.ratelimit.storage;
import com.yihu.base.router.model.Ratelimit;
import java.util.List;
/**
 * Created by chenweida on 2018/4/27 0027.
 */
public interface IRateLimitStorage {
    /**
     * 新增限制规则
     * @param ratelimit
     * @return
     */
    Boolean saveRateLimit(Ratelimit ratelimit);
    /**
     * 修改限制规则
     * @param ratelimit
     * @return
     */
    Boolean updateRateLimit(Ratelimit ratelimit);
    /**
     * 根据id删除限制规则
     * @param id
     * @return
     */
    Boolean deleteRateLimitById(String id);
    /**
     * 根据id查找限制规则
     * @param id
     * @return
     */
    Ratelimit findRateLimitById(String id);
    /**
     * 获取全部的限制规则
     * @return
     */
    List<Ratelimit> findAllRatelimit();
    /**
     * 总数-1
     * @param id
     * @return
     */
    Boolean countDec(String id);
    /**
     * 获取次数
     * @param id
     * @return
     */
    Integer getCount(String id);
    /**
     * 判断是否超过次数
     * @param id
     * @return
     */
    Boolean isUpperLimit(String id);
}

+ 199 - 0
common-router-starter/src/main/java/com/yihu/base/router/ratelimit/storage/RedisRateLimitStorage.java

@ -1,9 +1,208 @@
package com.yihu.base.router.ratelimit.storage;
import com.alibaba.fastjson.JSON;
import com.yihu.base.router.model.RateLimitCount;
import com.yihu.base.router.model.Ratelimit;
import com.yihu.base.router.model.RuleRoute;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
 * Created by chenweida on 2018/4/27 0027.
 */
public class RedisRateLimitStorage extends AbstractRateLimitStorage {
    private Logger logger = LoggerFactory.getLogger(RedisRateLimitStorage.class);
    private static String redisPre = "router:rateLimit:";
    private static String redisPreCount = "router:rateLimitCount:";
    private StringRedisTemplate redisTemplate;
    @Override
    public Boolean saveRateLimit(Ratelimit ratelimit) {
        try {
            if (StringUtils.isEmpty(ratelimit.getId())) {
                logger.error("Ratelimit id is null");
                return false;
            }
            String key = id(ratelimit.getId());
            Object value = redisTemplate.opsForValue().get(key.toString());
            if (!StringUtils.isEmpty(value)) {
                logger.error("Ratelimit id is exists ");
                return false;
            }
            redisTemplate.opsForValue().set(key.toString(), JSON.toJSON(ratelimit).toString());
            return true;
        } catch (Exception e) {
            logger.error(e.getMessage());
            return false;
        }
    }
    @Override
    public Boolean updateRateLimit(Ratelimit ratelimit) {
        try {
            if (StringUtils.isEmpty(ratelimit.getId())) {
                logger.error("Ratelimit id is null");
                return false;
            }
            String key = id(ratelimit.getId());
            redisTemplate.opsForValue().set(key.toString(), JSON.toJSON(ratelimit).toString());
            return true;
        } catch (Exception e) {
            logger.error(e.getMessage());
            return false;
        }
    }
    @Override
    public Boolean deleteRateLimitById(String id) {
        try {
            redisTemplate.delete(id(id));
            return true;
        } catch (Exception e) {
            logger.error(e.getMessage());
            return false;
        }
    }
    @Override
    public List<Ratelimit> findAllRatelimit() {
        Set<String> keys = redisTemplate.keys(redisPre + "*");
        List<String> values = redisTemplate.opsForValue().multiGet(keys);
        List<Ratelimit> ratelimits = new ArrayList<>();
        for (int i = 0; i < values.size(); i++) {
            ratelimits.add(JSON.parseObject(values.get(i), Ratelimit.class));
        }
        return ratelimits;
    }
    @Override
    public Ratelimit findRateLimitById(String id) {
        String json = redisTemplate.opsForValue().get(id(id));
        return JSON.parseObject(json, Ratelimit.class);
    }
    @Override
    public Boolean countDec(String id) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            String key = redisPreCount + id;
            if (redisTemplate.hasKey(key)) {
                redisTemplate.watch(key);
                String value = redisTemplate.opsForValue().get(key);
                RateLimitCount rateLimitCount = JSON.parseObject(value, RateLimitCount.class);
                logger.info("当前剩余访问数目:" + rateLimitCount.getCount());
                if (rateLimitCount.getCount() > 0) {
                    SessionCallback<Boolean> sessionCallback = new SessionCallback<Boolean>() {
                        @Override
                        public Boolean execute(RedisOperations operations) throws DataAccessException {
                            //开启事务
                            operations.multi();
                            rateLimitCount.setCount(rateLimitCount.getCount() - 1);
                            redisTemplate.opsForValue().set(key, JSON.toJSONString(rateLimitCount));
                            try {
                                Date endTime = simpleDateFormat.parse(rateLimitCount.getEndTime());
                                if (new Date().after(endTime)) {
                                    redisTemplate.delete(key);
                                }else{
                                    redisTemplate.expireAt(key, endTime);
                                }
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                            //执行事务
                            List<Object> list = operations.exec();
                            if (list != null) {
                                return true;
                            } else {
                                return false;
                            }
                        }
                    };
                    return redisTemplate.execute(sessionCallback);
                } else {
                    return false;
                }
            } else {
                Ratelimit ratelimit = findRateLimitById(id);
                //如果没有key说明上一次到期了redis自动消除了 在重新新增一个
                RateLimitCount rateLimitCount = new RateLimitCount();
                rateLimitCount.setStartTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                String endTime = ratelimit.getEndTime();
                rateLimitCount.setEndTime(endTime);
                rateLimitCount.setCount(ratelimit.getAccessCount() - 1);
                redisTemplate.opsForValue().set(key, JSON.toJSONString(rateLimitCount));
                redisTemplate.expireAt(key, simpleDateFormat.parse(endTime));
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    @Override
    public Integer getCount(String id) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String key = redisPreCount + id;
        String value = redisTemplate.opsForValue().get(key);
        RateLimitCount rateLimitCount = JSON.parseObject(value, RateLimitCount.class);
        try {
            Date endTime = simpleDateFormat.parse(rateLimitCount.getEndTime());
            if (new Date().after(endTime)) {
                redisTemplate.delete(key);
            }else{
                redisTemplate.expireAt(key, endTime);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return rateLimitCount.getCount();
    }
    /**
     * @param id
     * @return true 返回时已经达到上限 false表示没有
     */
    @Override
    public Boolean isUpperLimit(String id) {
        //不存在key的时候默认是可以的
        String key = redisPreCount + id;
        if (!redisTemplate.hasKey(key)) {
            return false;
        }
        return getCount(id) == 0 ? true : false;
    }
    public StringRedisTemplate getRedisTemplate() {
        return redisTemplate;
    }
    public void setRedisTemplate(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    private String id(String id) {
        return new StringBuffer(redisPre + id).toString();
    }
}

+ 1 - 0
common-router-starter/src/main/java/com/yihu/base/router/route/SimplerRouter.java

@ -89,6 +89,7 @@ public class SimplerRouter extends SimpleRouteLocator implements RefreshableRout
            } catch (Exception e) {
                logger.error("=============从数据库加载Zuul配置失败==============", e);
            }
            logger.info(result.toString());
            routes.put(zuulRoute.getPath(), zuulRoute);
        }
        return routes;

+ 9 - 6
common-router-starter/src/main/java/com/yihu/base/router/util/NetworkUtil.java

@ -27,38 +27,38 @@ public final class NetworkUtil {
        String ip = request.getHeader("X-Forwarded-For");
        if (logger.isInfoEnabled()) {
            logger.info("getIpAddress(HttpServletRequest) - X-Forwarded-For - String ip=" + ip);
           // logger.info("getIpAddress(HttpServletRequest) - X-Forwarded-For - String ip=" + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
                if (logger.isInfoEnabled()) {
                    logger.info("getIpAddress(HttpServletRequest) - Proxy-Client-IP - String ip=" + ip);
                 //   logger.info("getIpAddress(HttpServletRequest) - Proxy-Client-IP - String ip=" + ip);
                }
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
                if (logger.isInfoEnabled()) {
                    logger.info("getIpAddress(HttpServletRequest) - WL-Proxy-Client-IP - String ip=" + ip);
                   // logger.info("getIpAddress(HttpServletRequest) - WL-Proxy-Client-IP - String ip=" + ip);
                }
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
                if (logger.isInfoEnabled()) {
                    logger.info("getIpAddress(HttpServletRequest) - HTTP_CLIENT_IP - String ip=" + ip);
                  //  logger.info("getIpAddress(HttpServletRequest) - HTTP_CLIENT_IP - String ip=" + ip);
                }
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
                if (logger.isInfoEnabled()) {
                    logger.info("getIpAddress(HttpServletRequest) - HTTP_X_FORWARDED_FOR - String ip=" + ip);
                  //  logger.info("getIpAddress(HttpServletRequest) - HTTP_X_FORWARDED_FOR - String ip=" + ip);
                }
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
                if (logger.isInfoEnabled()) {
                    logger.info("getIpAddress(HttpServletRequest) - getRemoteAddr - String ip=" + ip);
                   // logger.info("getIpAddress(HttpServletRequest) - getRemoteAddr - String ip=" + ip);
                }
            }
        } else if (ip.length() > 15) {
@ -71,6 +71,9 @@ public final class NetworkUtil {
                }
            }
        }
        if("0:0:0:0:0:0:0:1".equals(ip)){
            ip="127.0.0.1";
        }
        return ip;
    }
}