【虎年大吉,祝大家日入百万】SpringBoot 如何实现异步编程,让业务接口快到飞起

【虎年大吉,祝大家日入百万】SpringBoot 如何实现异步编程,让业务接口快到飞起,第1张

【虎年大吉,祝大家日入百万】SpringBoot 如何实现异步编程,让业务接口快到飞起

新年新征程
新年新气象
元旦节快乐
虎年大吉,家人们。
祝大家日入百万,心想事成。


为啥使用异步??
异步方法可以让业务接口快到飞起

异步方法适用于逻辑与逻辑之间可以相互分割互不影响的业务中, 如生成验证码和发送验证码组成的业务, 其实无需等到真正发送成功验证码才对客户端进行响应, 可以让短信发送这一耗时 *** 作转为异步执行, 解耦耗时 *** 作和核心业务

异步:

注解说明:

@EnableAsync // 使用异步方法时需要提前开启(在启动类上或配置类上)
@Async // 被async注解修饰的方法由SpringBoot默认线程池(SimpleAsyncTaskExecutor)执行

看代码结构:

异步配置
@EnableAsync
@Configuration
public class SyncConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //设置核心线程数
        executor.setCorePoolSize(8);
        // 设置最大线程数
        executor.setMaxPoolSize(20);
        // 设置队列大小
        executor.setQueueCapacity(Integer.MAX_VALUE);
        // 设置线程活跃时间(秒)
        executor.setKeepAliveSeconds(60);
        // 设置线程名前缀+分组名称
        executor.setThreadNamePrefix("AsyncOperationThread-");
        executor.setThreadGroupName("AsyncOperationGroup");
        // 所有任务结束后关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 初始化
        executor.initialize();
        return executor;
    }
    //异步异常打印
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new CustomAsyncExceptionHandler();
    }
}

异步异常打印
@Slf4j
public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
    @Override
    public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
        log.error("异常捕获------------");
        log.error("Exception message 异常信息 {}", throwable.getMessage() );
        log.error("Method name 方法名称: {}", method.getName());
    
        for (Object param : objects) {
            System.out.println("Parameter value - " + param);
        }
        
    }
}

发短信 业务层
@Slf4j
@Service
public class MsgService {
    //定义生成策略
    public static final String CODE_id = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    
    
    public String createCode() {
        
        StringBuilder sb=new StringBuilder(4);
        for(int i=0;i<4;i++)
        {
            char ch=CODE_id.charAt(new Random().nextInt(CODE_id.length()));
            sb.append(ch);
        }
        return sb.toString();
    }
    
    
    @Async
    public void sendCode(String code) throws InterruptedException {
        TimeUnit.SECONDS.sleep(10);
//        throw new RuntimeException("故意异常");
        log.info("发生给用户:");
        log.info("【SteveCode】验证码:{},您正在使用SteveCode,需要进行验证,请勿向任何人提供您收到的短信验证码。", code);
    }
}

测试异步方法调用
@RestController
@RequestMapping("sync")
public class TestSyncWeb {
    @Resource
    private MsgService msgService;
    
    @SneakyThrows
    @GetMapping("send")
    public String userSendCode() {
        String code = msgService.createCode();
        msgService.sendCode(code);
        return "短信已发送,请注意查收";
    }
}
异步方法 带来的问题吧!
  1. 异步方法执行失败后对Controller前半部分的非异步 *** 作无影响, 因此说异步方法在整个业务逻辑中不是100%可靠的,
  2. 对于强一致性的业务来说不适用 还是消息中间件更为强大, RabbitMQ, Kafka…
  3. 异步方法只能声明在Service方法中在Controller直接调用才会生效, 异步方法被同级Service方法调用不会生效
效果图

页面先打印信息:

10秒–后台才会把具体的信息发送给给用户。【为什么10s, TimeUnit.SECONDS.sleep(10)】

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5691552.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存