统计接口调用耗时_黑白名单配置

黑名单配置

  • 黑名单就是那些被禁止访问的URL
  • 创建自定义过滤器 BlackListUrlFilter,并配置黑名单地址列表blacklistUrl
  • 如果有其他需求,还可以实现自定义规则的过滤器来满足特定的过滤要求
/**
 * 黑名单过滤器
 *
 * @author canghe
 */
@Component
public class BlackListUrlFilter extends AbstractGatewayFilterFactory<BlackListUrlFilter.Config>
{
    @Override
    public GatewayFilter apply(Config config)
    {
        return (exchange, chain) -> {

            String url = exchange.getRequest().getURI().getPath();
            if (config.matchBlacklist(url))
            {
                return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求地址不允许访问");
            }

            return chain.filter(exchange);
        };
    }

    public BlackListUrlFilter()
    {
        super(Config.class);
    }

    public static class Config
    {
        private List<String> blacklistUrl;

        private List<Pattern> blacklistUrlPattern = new ArrayList<>();

        public boolean matchBlacklist(String url)
        {
            return !blacklistUrlPattern.isEmpty() && blacklistUrlPattern.stream().anyMatch(p -> p.matcher(url).find());
        }

        public List<String> getBlacklistUrl()
        {
            return blacklistUrl;
        }

        public void setBlacklistUrl(List<String> blacklistUrl)
        {
            this.blacklistUrl = blacklistUrl;
            this.blacklistUrlPattern.clear();
            this.blacklistUrl.forEach(url -> {
                this.blacklistUrlPattern.add(Pattern.compile(url.replaceAll("\\*\\*", "(.*?)"), Pattern.CASE_INSENSITIVE));
            });
        }
    }

}
  • 在Nacos的pmhub-gateway-dev.yml 中配置需要拉黑的请求路径

image.png

  • **拦截之后结果如下 : **

image.png

白名单配置

  • 白名单就是允许访问的地址。且无需登录就能访问
  • 比如登录、注册接口,以及其他的不需要网关做鉴权的接口
  • 在全局过滤器**AuthFilter**第一步就校验是否为白名单

```java // 跳过不需要验证的路径 if (StringUtils.matches(url, ignoreWhite.getWhites())) { return chain.filter(exchange); } ``` ![image.png](https://img-blog.csdnimg.cn/img_convert/039bd801d452b9b721ff2d031f1c0812.png)
  • **在 ****ignore**中设置 **whites**,表示允许匿名访问

image.png

统计接口调用耗时

  • 在全局过滤器处理完其他操作之后再记录时间
  • 全局过滤器: 1.白名单过滤 2.Token鉴权 3.设置用户信息到请求 4. 接口调用耗时

image.png

  • 计算接口调用总耗时

return chain.filter(exchange).then(Mono.fromRunnable(()->{
    Long beginVisitTime = exchange.getAttribute(BEGIN_VISIT_TIME);
    if (beginVisitTime != null){
        log.info("访问接口主机: " + exchange.getRequest().getURI().getHost());
        log.info("访问接口端口: " + exchange.getRequest().getURI().getPort());
        log.info("访问接口URL: " + exchange.getRequest().getURI().getPath());
        log.info("访问接口URL参数: " + exchange.getRequest().getURI().getRawQuery());
        log.info("访问接口时长: " + (System.currentTimeMillis() - beginVisitTime) + "ms");
        log.info("我是美丽分割线: ###################################################");
        System.out.println();
    }
}));
  • 感觉还是自带的计时工具好用一些, 不过不支持异步
/**
 * 统计耗时工具类, 这个只支持同步的耗时打印,不支持异步的场景
 *
 * @author YiHui
 * @date 2023/11/10
 */
public class StopWatchUtil {
    private StopWatch stopWatch;

    private StopWatchUtil(String task) {
        stopWatch = task == null ? new StopWatch() : new StopWatch(task);
    }

    /**
     * 初始化
     *
     * @param task
     * @return
     */
    public static StopWatchUtil init(String... task) {
        return new StopWatchUtil(task.length > 0 ? task[0] : null);
    }

    /**
     * 同步耗时计时
     *
     * @param task 任务名
     * @param call 执行业务逻辑
     * @param <T>  返回类型
     * @return 返回结果
     */
    public <T> T record(String task, Callable<T> call) {
        stopWatch.start(task);
        try {
            return call.call();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            stopWatch.stop();
        }
    }

    /**
     * 同步耗时计时
     *
     * @param task 任务名
     * @param run  执行业务逻辑
     */
    public void record(String task, Runnable run) {
        stopWatch.start(task);
        try {
            run.run();
        } finally {
            stopWatch.stop();
        }
    }


    /**
     * 计时信息输出
     *
     * @return
     */
    public String prettyPrint() {
        return stopWatch.prettyPrint();
    }
}
  • 下面是一个使用**StopWatchUtil**的例子
  • 先初始化**StopWatchUtil stopWatchUtil = StopWatchUtil.init("图片上传");**
  • 再stopWatchUtil.record(“流转字节”, () -> StreamUtils.copyToByteArray(finalInput));
  • 最后**log.info("图片上传耗时: {}", stopWatchUtil.prettyPrint());**
@Override
    public String upload(InputStream input, String fileType) {
        // 记录耗时分布
        StopWatchUtil stopWatchUtil = StopWatchUtil.init("图片上传");
        try {
            if (fileType == null) {
                // 根据魔数判断文件类型
                InputStream finalInput = input;
                byte[] bytes = stopWatchUtil.record("流转字节", () -> StreamUtils.copyToByteArray(finalInput));
                input = new ByteArrayInputStream(bytes);
                fileType = getFileType((ByteArrayInputStream) input, fileType);
            }

            String path = imageProperties.getAbsTmpPath() + imageProperties.getWebImgPath();
            String fileName = genTmpFileName();

            InputStream finalInput = input;
            String finalFileType = fileType;
            FileWriteUtil.FileInfo file = stopWatchUtil.record("存储", () -> FileWriteUtil.saveFileByStream(finalInput, path, fileName, finalFileType));
            return imageProperties.buildImgUrl(imageProperties.getWebImgPath() + file.getFilename() + "." + file.getFileType());
        } catch (Exception e) {
            log.error("Parse img from httpRequest to BufferedImage error! e:", e);
            throw ExceptionUtil.of(StatusEnum.UPLOAD_PIC_FAILED);
        } finally {
            log.info("图片上传耗时: {}", stopWatchUtil.prettyPrint());
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值