Java 代码重试实现方式

Java 代码重试实现方式

  • 一.方法内直接自动重试
  • 二.静态代理方式
    • 1.启动类
    • 2.接口
    • 3.实现
    • 4.静态代理
    • 5.单元测试类
  • 三.JDK 动态代理
    • 1.代理类
    • 2.单元测试
  • 四.CGLIB 动态代理
    • 1.动态代理类
    • 2.单元测试
  • 五.手动 AOP
    • 1.自定义注解
    • 2.重试注解切面
    • 3.测试类
    • 4.单元测试方法
  • 六.Spring Retry
    • 1.测试类
    • 2.单元测试类
    • 3.单元测试方法
  • 七.Guava Retry
    • 1.测试类
    • 2.单元测试

依赖包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>learn-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>20</maven.compiler.source>
        <maven.compiler.target>20</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>3.1.2</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.28</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.32</version>
        </dependency>

			 <dependency>
			     <groupId>org.aspectj</groupId>
			     <artifactId>aspectjweaver</artifactId>
			     <version>1.9.19</version>
			 </dependency>
			 <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>6.0.11</version>
        </dependency>

    </dependencies>

</project>

一.方法内直接自动重试

    public static void main(String[] args) {
        autoRetry(3);
    }

    /**
     * 自动重试(执行总次数包含于重试次数内)
     * 优点:实现简单
     * 缺点:复用性差,代码侵入
     * @param retryTimes
     */
    public static void autoRetry(int retryTimes){
        int times = 0;
        do {
            try {
                int i = 3/0;
            } catch (Exception e) {
                times++;
                System.out.println("第" + times + "次失败");
            }
        } while (times < retryTimes);
    }

二.静态代理方式

1.启动类

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author Administrator
 */
@SpringBootApplication
public class LearnApp {

    public static void main(String[] args) {
        SpringApplication.run(LearnApp.class,args);
    }
}

2.接口

package org.example.service;

/**
 * @description
 * @author zhuwd && moon
 * @version 1.0
 */
public interface LearnService {

    /**
     * 自动重试
     */
    void autoRetry();
}

3.实现

package org.example.service.impl;

import org.example.service.LearnService;
import org.springframework.stereotype.Service;

/**
 * @author zhuwd && moon
 * @Description
 * @create 2023-08-08 1:05
 */
@Service
public class LearnServiceImpl implements LearnService {
    @Override
    public void autoRetry() {
        throw new RuntimeException();
    }
}

4.静态代理

package org.example.service.impl;

import org.example.service.LearnService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author zhuwd && moon
 * @Description
 * @create 2023-08-08 1:06
 */
@Service
public class LearnServiceProxyImpl implements LearnService {

    @Autowired
    private LearnServiceImpl learnService;

    private static final int RETRY_TIMES = 3;

    @Override
    public void autoRetry() {
        int times = 0;
        do {
            try {
                learnService.autoRetry();
            } catch (Exception e) {
                times++;
                System.out.println("第" + times + "次失败");
            }
        } while (times < RETRY_TIMES);
    }
}

5.单元测试类

import org.example.LearnApp;
import org.example.service.impl.LearnServiceProxyImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @author zhuwd && moon
 * @Description
 * @create 2023-08-08 1:11
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = LearnApp.class)
public class LearnTest {

    @Autowired
    LearnServiceProxyImpl learnServiceProxy;

    @Test
    public void test(){
        learnServiceProxy.autoRetry();
    }

}

在这里插入图片描述

三.JDK 动态代理

1.代理类

package org.example.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @author zhuwd && moon
 * @Description 实现方式较优雅,但是被代理的类必须实现某个接口才能操作
 * @create 2023-08-08 21:14
 */
public class RetryInvocationHandler implements InvocationHandler {

    private static final int RETRY_TIMES = 3;

    /**
     * 目标对象
     */
    private final Object target;

    /**
     * 有参构造
     * @param target
     */
    public RetryInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        int times = 0;
        do {
            try {
                return method.invoke(target,args);
            } catch (Exception e) {
                times++;
                System.out.println("第" + times + "次失败");
            }
        } while (times < RETRY_TIMES);
        return null;
    }
}

2.单元测试

import org.example.LearnApp;
import org.example.proxy.RetryInvocationHandler;
import org.example.service.LearnService;
import org.example.service.impl.LearnServiceImpl;
import org.example.service.impl.LearnServiceProxyImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
 * @author zhuwd && moon
 * @Description
 * @create 2023-08-08 1:11
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = LearnApp.class)
public class LearnTest {

    @Autowired
    LearnServiceImpl learnService;

    @Test
    public void testJdk(){
        InvocationHandler handler = new RetryInvocationHandler(learnService);
        LearnService service = (LearnService) Proxy.newProxyInstance(handler.getClass().getClassLoader(), learnService.getClass().getInterfaces(),handler);
        service.autoRetry();
    }
}

在这里插入图片描述

四.CGLIB 动态代理

注意依赖选择 cglib 包下的,不要用 spring 下的

1.动态代理类

package org.example.proxy;


import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;


/**
 * @author zhuwd && moon
 * @Description
 * @create 2023-08-08 21:25
 */
public class CGLibRetryProxyHandler implements MethodInterceptor {

    private static final int RETRY_TIMES = 3;
    private Object target;

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        int times = 0;
        do {
            try {
                return method.invoke(target,objects);
            } catch (Exception e) {
                times++;
                System.out.println("第" + times + "次失败");
            }
        } while (times < RETRY_TIMES);
        return null;
    }

    /**
     * 生产代理类
     * @param target
     * @return
     */
    public Object getProxy(Object target){
        this.target = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        enhancer.setCallback(this);
        enhancer.setClassLoader(this.target.getClass().getClassLoader());
        Object proxy = enhancer.create();
        return proxy;
    }

}

2.单元测试

import org.example.LearnApp;
import org.example.proxy.CGLibRetryProxyHandler;
import org.example.service.LearnService;
import org.example.service.impl.LearnServiceImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @author zhuwd && moon
 * @Description
 * @create 2023-08-08 1:11
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = LearnApp.class)
public class LearnTest {

    @Autowired
    LearnServiceImpl learnService;

    @Test
    public void testCglib(){
        CGLibRetryProxyHandler handler = new CGLibRetryProxyHandler();
        LearnService service = (LearnService) handler.getProxy(learnService);
        service.autoRetry();
    }
}

如果是JDK17及以上版本,用IDEA调试需要增加VM配置:--add-opens java.base/java.lang=ALL-UNNAMED

在这里插入图片描述

在这里插入图片描述

五.手动 AOP

利用自定义注解实现重试AOP逻辑

1.自定义注解

package org.example.anno;

import java.lang.annotation.*;

/**
 * @author zhuwd && moon
 * @Description
 * @create 2023-08-08 22:50
 */
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RetryAnno {

    /**
     * 重试次数
     * @return
     */
    int retryTimes() default 3;

    /**
     * 重试间隔(s)
     * @return
     */
    int retryInterval() default 3;

}

2.重试注解切面

package org.example.config;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.example.anno.RetryAnno;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @author zhuwd && moon
 * @Description
 * @create 2023-08-08 22:52
 */
@Aspect
@Component
public class RetryAspect {

    @Pointcut("@annotation(org.example.anno.RetryAnno)")
    private void retryCall(){};

    @Around("retryCall()")
    public Object retry(ProceedingJoinPoint joinPoint) throws Throwable{
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        RetryAnno retryAnno = signature.getMethod().getAnnotation(RetryAnno.class);
        int retryTimes = retryAnno.retryTimes();
        int retryInterval = retryAnno.retryInterval();
        int times = 0;
        do {
            try {
                return joinPoint.proceed();
            } catch (Exception e) {
                times++;
                System.out.println(System.currentTimeMillis() + "  第" + times + "次失败");
                TimeUnit.SECONDS.sleep(retryInterval);
            }
        } while (times < retryTimes);
        return null;
    }

}

3.测试类

package org.example.config;

import org.example.anno.RetryAnno;
import org.springframework.stereotype.Component;

/**
 * @author zhuwd && moon
 * @Description
 * @create 2023-08-08 23:02
 */
@Component
public class LearnRetry {

    @RetryAnno(retryTimes = 3,retryInterval = 3)
    public void retry(){
        throw new RuntimeException();
    }

}

4.单元测试方法

import org.example.LearnApp;
import org.example.config.LearnRetry;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @author zhuwd && moon
 * @Description
 * @create 2023-08-08 1:11
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = LearnApp.class)
public class LearnTest {

    @Autowired
    LearnRetry learnRetry;

    @Test
    public void testAopRetry(){
        learnRetry.retry();
    }
}

在这里插入图片描述

六.Spring Retry

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>2.0.2</version>
</dependency>

1.测试类

package org.example.config;

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;

/**
 * @author zhuwd && moon
 * @Description
 * @create 2023-08-08 23:10
 */
@Component
@EnableRetry
public class SpringRetry {

    /**
     * maxAttempts 最大重试次数
     * backoff.delay 重试延迟
     * backoff.multiplier 延迟倍数,即第一次间隔 2S 第二次将间隔 4秒
     */
    @Retryable(maxAttempts = 3,backoff = @Backoff(delay = 2000,multiplier = 2))
    public void retry(){
        System.out.println(System.currentTimeMillis() + "  重试 ...");
        throw new RuntimeException();
    }

    /**
     * @Recover 注解必须和 @Retryable 在同一个类;且返回值一致不能抛出额外异常
     *
     * @param e
     */
    @Recover
    public void recover(RuntimeException e){
        System.out.println("已达最大重试次数");
    }

}

2.单元测试类

import org.example.LearnApp;
import org.example.config.SpringRetry;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @author zhuwd && moon
 * @Description
 * @create 2023-08-08 1:11
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = LearnApp.class)
public class LearnTest {


    @Autowired
    SpringRetry springRetry;

    @Test
    public void testSpringRetry(){
        springRetry.retry();
    }
}

在这里插入图片描述

3.单元测试方法

import org.example.LearnApp;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.retry.backoff.FixedBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.HashMap;
import java.util.Map;

/**
 * @author zhuwd && moon
 * @Description
 * @create 2023-08-08 1:11
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = LearnApp.class)
public class LearnTest {

    public void retry(){
        System.out.println(System.currentTimeMillis() + "  重试 ...");
        throw new RuntimeException();
    }

    @Test
    public void testSpringRetryMethod(){

        RetryTemplate template = new RetryTemplate();

        /**
         * 重试策略
         */
        Map<Class<? extends Throwable>,Boolean> map = new HashMap<>();
        map.put(RuntimeException.class,true);
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(3,map);

        /**
         * 重试回退策略
         */
        FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
        backOffPolicy.setBackOffPeriod(2000);

        template.setRetryPolicy(retryPolicy);
        template.setBackOffPolicy(backOffPolicy);

        Boolean execute = template.execute(retryContext -> {
            retry();
            return true;
        },retryContext -> {
            System.out.println("已达最大重试次数");
            return false;
        });

        System.out.println("调用结果 " + execute);
    }
}

在这里插入图片描述

七.Guava Retry

<dependency>
    <groupId>com.github.rholder</groupId>
    <artifactId>guava-retrying</artifactId>
    <version>2.0.0</version>
</dependency>

1.测试类

package org.example.config;

import org.springframework.stereotype.Component;

/**
 * @author zhuwd && moon
 * @Description 10S 后返回正确值
 * @create 2023-08-08 23:49
 */
@Component
public class GuavaRetry {

    private static long init_time = System.currentTimeMillis() + 1000 * 10;

    public int retry(){
        if (System.currentTimeMillis() > init_time){
            return 0;
        }
        return -1;
    }


}

2.单元测试

import com.github.rholder.retry.*;
import org.example.LearnApp;
import org.example.config.GuavaRetry;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author zhuwd && moon
 * @Description
 * @create 2023-08-08 1:11
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = LearnApp.class)
public class LearnTest {

    @Autowired
    GuavaRetry guavaRetry;

    @Test
    public void testGuavaRetry(){
        Retryer<Integer> retryer = RetryerBuilder.<Integer>newBuilder()
                //根据异常重试
                .retryIfException()
                //根据结果重试
                .retryIfResult(result-> !Objects.equals(result,0))
                //重试策略
                .withWaitStrategy(WaitStrategies.fixedWait(2, TimeUnit.SECONDS))
                //停止策略
                .withStopStrategy(StopStrategies.stopAfterAttempt(300))
                //监听重试进度
                .withRetryListener(new RetryListener() {
                    @Override
                    public <V> void onRetry(Attempt<V> attempt) {
                        System.out.println(System.currentTimeMillis() + "  第" + attempt.getAttemptNumber() + "次失败");
                    }
                })
                .build();

        try {
            int result = retryer.call(()->guavaRetry.retry());
            System.out.println("调用结果:" + result);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } catch (RetryException e) {
            throw new RuntimeException(e);
        }
    }

}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/65478.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

虚拟机centos7配置网络

虚拟机centos7配置网络 centos7克隆之后需要配置网络才能联网。 实验环境&#xff1a; VMware Workstation Pro 16CentOS 7系统虚拟机主机Windows 11系统 1.VMware网络模式设置为NAT模式 虚拟机–设置–网络适配器– ​​ ‍ 2.查看虚拟机 子网IP和网关IP 编辑–虚拟网…

pytorch Stream 多流处理

CUD Stream https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#c-language-extensions 中指出在kenel的调用函数中最后一个可选参数表示该核函数处在哪个流之中。 - 参数Dg用于定义整个grid的维度和尺寸&#xff0c;即一个grid有多少个block。为dim3类型。…

Openlayers实战:利用turf获取两个多边形的交集、差集、并集

在数据统计方面,通常会涉及到图形间的交集、并集、差集等。在Openlayers的实战中,我们显示两个多边形的交集、并集、差集的表现。通过turf的方式,可以快速的实现我们的数据处理,具体的请参考源代码。 效果图 源代码 /* * @Author: 大剑师兰特(xiaozhuanlan),还是大剑师…

MySQL 事务原理:事务概述、隔离级别、MVCC

文章目录 一、事务1.1 事务概述1.2 事务控制语句1.3 ACID特性 二、隔离级别2.1 隔离级别的分类2.1.1 读未提交&#xff08;RU&#xff09;2.1.2 读已提交&#xff08;RC&#xff09;2.1.3 可重复读&#xff08;RR&#xff09;2.1.4 串行化 2.2 命令2.3 并发读异常2.3.1 脏读2.3…

Redis实战案例25-附近商铺功能

1. GEO数据结构 Redis中Geohash功能应用 添加地理坐标 求两点之间距离 搜索天安门附近10km的火车站&#xff0c;按升序 2. 导入店铺数据到GEO Redis中存储店铺的信息&#xff0c;将店铺的id和经纬度坐标存到GEO数据类型中去&#xff0c;其中member存id&#xff0c;经纬度对应…

Docker实战-操作Docker容器实战(二)

导语   上篇分享中,我们介绍了关于如何创建容器、如何启动容器、如何停止容器。这篇我们来分享一下如何操作容器。 如何进入容器 可以通过使用-d参数启动容器后会进入后台运行,用户无法查看容器中的信息,无法对容器中的信息进行操作。 这个时候如果我们需要进入容器对容器…

C语言经典小游戏之扫雷(超详解释+源码)

“少年气&#xff0c;是历尽千帆举重若轻的沉淀&#xff0c;也是乐观淡然笑对生活的豁达&#xff01;” 今天我们学习一下扫雷游戏怎么用C语言来实现&#xff01; 扫雷小游戏 1.游戏介绍2.游戏准备3.游戏实现3.1生成菜单3.2游戏的具体实现3.2.1初始化棋盘3.2打印棋盘3.3布置雷…

黑马头条项目学习--Day1: 环境搭建、SpringCloud微服务(注册发现、网关)

Nacos注册发现、网关 a. 项目介绍b. app登录1) 需求分析2) 表结构分析3) 手动加密&#xff08;md5随机字符串&#xff09;4) 用户端微服务搭建5) 功能实现6) app网关7) 网关校验jwt8) 前端集成, 配置nginx a. 项目介绍 业务说明 技术栈说明 [外链图片转存失败,源站可能有防盗…

Spring Boot多级缓存实现方案

1.背景 缓存&#xff0c;就是让数据更接近使用者&#xff0c;让访问速度加快&#xff0c;从而提升系统性能。工作机制大概是先从缓存中加载数据&#xff0c;如果没有&#xff0c;再从慢速设备(eg:数据库)中加载数据并同步到缓存中。 所谓多级缓存&#xff0c;是指在整个系统架…

SpringBoot之logback-spring.xml详细配置

《logback官网》 各种指导文件&#xff0c;有空自己去看&#xff0c;比如&#xff1a;我们需要调整的是布局&#xff0c;直接看Layouts。 pom.xml <!-- 环境配置 --><profiles><profile><id>dev</id><properties><spring.profiles.a…

前端例程20230806:彩色灯珠装饰

演示 这里页面四周的彩色灯珠是会随着页面调整自动调整位置的。 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta na…

【数据结构与算法——TypeScript】哈希表

【数据结构与算法——TypeScript】 哈希表(HashTable) 哈希表介绍和特性 哈希表是一种非常重要的数据结构&#xff0c;但是很多学习编程的人一直搞不懂哈希表到底是如何实现的。 在这一章节中&#xff0c;我门就一点点来实现一个自己的哈希表。通过实现来理解哈希表背后的原理…

2022年03月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 已知a“161”&#xff0c;b“16”&#xff0c;c“8”,执行语句da>b and a>c&#xff0c;变量d的值为是&#xff1f; A&#xff1a;0 B&#xff1a;1 C&#xff1a;True D&am…

探究使用HTTP爬虫ip后无法访问网站的原因与解决方案

在今天的文章中&#xff0c;我们要一起来解决一个常见问题&#xff1a;使用HTTP爬虫ip后无法访问网站的原因是什么&#xff0c;以及如何解决这个问题。我们将提供一些实际的例子和操作经验&#xff0c;帮助大家解决HTTP爬虫ip无法访问网站的困扰。 1、代理服务器不可用 使用HT…

【SpringBoot笔记】定时任务(cron)

定时任务就是在固定的时间执行某个程序&#xff0c;闹钟的作用。 1.在启动类上添加注解 EnableScheduling 2.创建定时任务类 在这个类里面使用表达式设置什么时候执行 cron 表达式&#xff08;也叫七子表达式&#xff09;&#xff0c;设置执行规则 package com.Lijibai.s…

面试常问:tcp的三次握手和四次挥手你了解吗?

三次握手和四次挥手是各个公司常见的考点&#xff0c;一个简单的问题&#xff0c;却能看出面试者对网络协议的掌握程度&#xff0c;对问题分析与解决能力&#xff0c;以及数据流管理理解和异常情况应对能力。所以回答好一个tcp的三次握手和四次挥手的问题对于我们的面试成功与否…

(vue)获取对象的键遍历,同时循环el-tab页展示key及内容

(vue)获取对象的键遍历&#xff0c;同时循环el-tab页展示key及内容 效果&#xff1a; 数据结构&#xff1a; "statusData": {"订购广度": [ {"id": 11, "ztName": "广", …

C++笔记之两个类的实例之间传递参数的各种方法

C笔记之两个类的实例之间传递参数的各种方法 code review! 文章目录 C笔记之两个类的实例之间传递参数的各种方法1.构造函数参数传递2.成员函数参数传递3.友元函数4.友元类5.传递指针或引用6.静态成员变量7.静态成员函数8.全局变量或命名空间9.回调函数和函数指针10.观察者模…

pg实现月累计

获取每月累计数据&#xff1a; ​​​ SELECT a.month, SUM(b.total) AS total FROM ( SELECT month, SUM(sum) AS total FROM ( SELECT to_char(date("Joinin"),YYYY-MM) AS month , COUNT(*) AS sum FROM "APP_HR_Staff_Basic_Info" GROUP BY month ) …

做接口测试如何上次文件

在日常工作中&#xff0c;经常有上传文件功能的测试场景&#xff0c;因此&#xff0c;本文介绍两种主流编写上传文件接口测试脚本的方法。 首先&#xff0c;要知道文件上传的一般原理&#xff1a;客户端根据文件路径读取文件内容&#xff0c;将文件内容转换成二进制文件流的格式…