性能优化篇

性能调优

背景:最近手里的两个系统相继出现了问题,肝了一个多月,算是告一段落了,总结一下近阶段的问题和解决方案

服务假死问题

Q1: A系统出现的现象如下:Eureka显示注册成功,前端用户访问正常,但是B用Feign方法调用该系统出现Read timeout问题

A: 看服务器发现,在那个时间段CPU爆了,服务处于不可访问状态,服务没有报错信息,之后也再也没有请求信息,仅有定时任务的日志。
方法:打GC日志,关注日志信息发现,内部有大量http请求Lock住了
解决方案:
1 设置三方请求超时时间

    /**
     * 执行post请求获取响应(请求体为JOSN数据)
     *
     * @param url     请求地址
     * @param headers 请求头参数
     * @param json    请求的JSON数据
     * @return 响应内容
     */
    public static String postJson(String url, Map<String, String> headers, String json) {
        HttpPost post = new HttpPost(url);
        post.setHeader("Content-type", "application/json");
        post.setEntity(new StringEntity(json, UTF8));
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000)
                .setConnectionRequestTimeout(5000)
                .setSocketTimeout(5000)
                .build();
        post.setConfig(requestConfig);
        return getRespString(post, headers);
    }

2 设置异步线程

@SneakyThrows
    @Async("asyncPoolTaskExecutor")
    public LxTobOrder pushMessageToLX(LxTobOrder orderResult, int i) {
    }
/**
* 描述:异步配置
* 创建人:HuangTuL
*/
@Slf4j
@Configuration
@EnableAsync    // 可放在启动类上或单独的配置类
public class AsyncConfiguration implements AsyncConfigurer {

   @Bean(name = "asyncPoolTaskExecutor")
   public ThreadPoolTaskExecutor executor() {
       ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
       //核心线程数
       taskExecutor.setCorePoolSize(5);
       //线程池维护线程的最大数量,只有在缓冲队列满了之后才会申请超过核心线程数的线程
       taskExecutor.setMaxPoolSize(10);
       //缓存队列
       taskExecutor.setQueueCapacity(500);
       //设置线程的空闲时间,当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
//        taskExecutor.setKeepAliveSeconds(200);
       //异步方法内部线程名称
       taskExecutor.setThreadNamePrefix("async-");
       /**
        * 当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略
        * 通常有以下四种策略:
        * ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
        * ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
        * ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
        * ThreadPoolExecutor.CallerRunsPolicy:重试添加当前的任务,自动重复调用 execute() 方法,直到成功
        */
       taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
       taskExecutor.initialize();
       return taskExecutor;
   }

   /**
    * 指定默认线程池
    * The {@link Executor} instance to be used when processing async method invocations.
    */
   @Override
   public Executor getAsyncExecutor() {
       return executor();
   }

   /**
    * The {@link AsyncUncaughtExceptionHandler} instance to be used
    * when an exception is thrown during an asynchronous method execution
    * with {@code void} return type.
    */
   @Override
   public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
       return (ex, method, params) -> log.error("线程池执行任务发送未知错误, 执行方法:{}", method.getName(), ex);
   }
}

总结:核心问题是线程数被占满了,http请求没有设置超时时间,异步线程池的线程数未设置。优化后,未发现假死情况,持续观察

Q2 : 数据库死锁

 Insert Batch order_status failed. DeadlockLoserDataAccessException:{}  org.springframework.dao.DeadlockLoserDataAccessException: ### Error updating database. Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction ### The error may exist in 

A: 根据问题

  • 猜想1 业务纠缠导致的死锁。在插入逻辑和更新逻辑造成死锁
    优化:加锁,共用一个分布式锁,可解决死锁问题,但是导致性能下降
  • 猜想2 http请求阻塞时间。由第三方请求导致导致线程占用,长时间没释放数据库资源,导致死锁
    优化:新增kafka topic ,第三方请求作为kafka消费者,解耦超时时间问题
Stopwatch stopwatch = Stopwatch.createStarted();

logger.info("updateOrderStatusToBZ before : cost : {} MS",stopwatch.elapsed(TimeUnit.MILLISECONDS));

总结:问题的核心在于解耦,方法在于监控那个方法那个代码块是耗时部分,针对这部分进行优化

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
《Oracle性能优化之执行计划详解》是一介绍Oracle数据库性能优化中的关键概念和技术的文章。通过深入讲解Oracle执行计划的相关内容,帮助读者更好地理解和优化数据库查询性能。 在Oracle数据库中,执行计划是查询优化器生成的一种执行方案,用于指导数据库在执行SQL语句时的操作步骤和顺序。执行计划会根据表、索引、统计信息等内容,通过优化器的选择逻辑来生成,从而提高查询效率和性能。 《Oracle性能优化之执行计划详解》首先介绍了执行计划的基本组成结构,包括操作、访问方法、操作对象等。然后深入解析了执行计划的生成过程,包括Cost-Based Optimizer(CBO)和Rule-Based Optimizer(RBO)两种优化器的工作原理和区别。 接着,文章详细讲解了执行计划的查看方法和解读技巧。通过使用Oracle提供的多种工具和命令,如EXPLAIN PLAN、AUTOTRACE等,可以获取和分析执行计划,并根据结果进行性能优化。同时,文章还解释了执行计划中的关键指标和信息,如Cost、Cardinality、Bytes等,以及其对性能的影响和解决方法。 除此之外,《Oracle性能优化之执行计划详解》还介绍了一些常见的执行计划优化技术和策略。如索引的优化、统计信息的收集、SQL语句的调整等,通过优化执行计划中的关键因素,可以提高数据库查询效率和性能。 通过阅读《Oracle性能优化之执行计划详解》,读者可以深入了解Oracle数据库性能优化中的执行计划概念和技术,掌握相关工具和方法,从而更好地优化数据库查询性能。该文章对于数据库开发人员、DBA等有着重要的参考价值,帮助他们解决实际问题,提高数据库系统的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巴伦是只猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值