如何提升springboot服务吞吐量
背景
生产环境偶尔会有一些慢请求导致系统性能下降,吞吐量下降,下面介绍几种优化建议。
方案
1、undertow替换tomcat
电子商务类型网站大多都是短请求,一般响应时间都在100ms,这时可以将web容器从tomcat替换为undertow,下面介绍下步骤: 1、增加pom配置
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> <exclusions> <exclusion> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-tomcat</artifactid> </exclusion> </exclusions> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-undertow</artifactid> </dependency>
2、增加相关配置
server: undertow: direct-buffers: true io-threads: 4 worker-threads: 160
重新启动可以在控制台看到容器已经切换为undertow了
2、缓存
将部分热点数据或者静态数据放到本地缓存或者redis中,如果有需要可以定时更新缓存数据
3、异步
在代码过程中我们很多代码都不需要等返回结果,也就是部分代码是可以并行执行,这个时候可以使用异步,最简单的方案是使用springboot提供的@Async注解,当然也可以通过线程池来实现,下面简单介绍下异步步骤。 1、pom依赖 一般springboot引入web相关依赖就行
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency>
2、在启动类中增加@EnableAsync注解
@EnableAsync @SpringBootApplication public class AppApplication { public static void main(String[] args) { SpringApplication.run(AppApplication.class, args); } }
3、需要时在指定方法中增加@Async注解,如果是需要等待返回值,则demo如下
@Async public Future<string> doReturn(int i){ try { // 这个方法需要调用500毫秒 Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } // 消息汇总 return new AsyncResult<>("异步调用"); }
4、如果有线程变量或者logback中的mdc,可以增加传递
import org.slf4j.MDC; import org.springframework.context.annotation.Configuration; import org.springframework.core.task.TaskDecorator; import org.springframework.scheduling.annotation.AsyncConfigurerSupport; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.Map; import java.util.concurrent.Executor; /** * @Description: */ @EnableAsync @Configuration public class AsyncConfig extends AsyncConfigurerSupport { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setTaskDecorator(new MdcTaskDecorator()); executor.initialize(); return executor; } } class MdcTaskDecorator implements TaskDecorator { @Override public Runnable decorate(Runnable runnable) { Map<string, string> contextMap = MDC.getCopyOfContextMap(); return () -> { try { MDC.setContextMap(contextMap); runnable.run(); } finally { MDC.clear(); } }; } }
5、有时候异步需要增加阻塞
import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor; @Configuration @Slf4j public class TaskExecutorConfig { @Bean("localDbThreadPoolTaskExecutor") public Executor threadPoolTaskExecutor() { ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); taskExecutor.setCorePoolSize(5); taskExecutor.setMaxPoolSize(200); taskExecutor.setQueueCapacity(200); taskExecutor.setKeepAliveSeconds(100); taskExecutor.setThreadNamePrefix("LocalDbTaskThreadPool"); taskExecutor.setRejectedExecutionHandler((Runnable r, ThreadPoolExecutor executor) -> { if (!executor.isShutdown()) { try { Thread.sleep(300); executor.getQueue().put(r); } catch (InterruptedException e) { log.error(e.toString(), e); Thread.currentThread().interrupt(); } } } ); taskExecutor.initialize(); return taskExecutor; } }
4、业务拆分
可以将比较耗时或者不同的业务拆分出来提供单节点的吞吐量
5、集成消息队列
有很多场景对数据实时性要求不那么强的,或者对业务进行业务容错处理时可以将消息发送到kafka,然后延时消费。举个例子,根据条件查询指定用户发送推送消息,这里可以时按时、按天、按月等等,这时就 </string,></string>
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
为2020年新型网络安全威胁做好准备
我们生活在这样的时代,我们的日常运营日益数字化,同时,新一代人开始拥抱各种新技术,并将其视为生活中自然的部分。随着我们越来越多地连接到网络,我们也开始面临着各种网络安全威胁。并且,敌对政府和恶意攻击者看到更大的破坏潜力,他们只需要付出最小的努力,有时甚至不会留下痕迹。 早期的黑客破解了系统以示抗议,或仅仅是为了吹牛。但是,随着数据成为新的黄金,黑客开始窃取数据或挟持数据以获得利益。首席信息官应特别注意网络安全威胁,因为在2019年,网络罪犯将重点从消费者转移到了企业、医院、美国州立和地方政府以及工业控制系统。这些实体不能容忍停机时间,停机代价非常高,并且他们也有钱支付赎金。网络罪犯期望以更少的努力获得更多的回报,当他们入侵后,他们就可能造成更多的高价值破坏。 目前,我们处于勒索软件时代,安全系统的小漏洞可能造成数百万美元的损失,这不仅是由于勒索赎金所致,停机时间和更换受感染设备的成本甚至更高。例如,针对巴尔的摩政府系统的勒索软件攻击估计花费超过1,820万美元,尽管攻击者只索要大约76,280美元。 本文中,我们研究了网络安全威胁和很多潜在的渗透点,以及我们可以采取的措施。 电子邮件和...
- 下一篇
一种在C语言中用 System V ucontext 实现的协程切换
此文在看了 python 中基于 yield 和 yield from (同步基于 yield 的子生成器/协程)机制的生成器/协程后,就想在C语言中实现类似机制。 在阅读 System V ucontext 手册后,便选择基于他来实现(要是此文自己实现“上下文切换描述”的话,该部分功能所花时间应该会比已有C代码所花时间要多)。所实现功能包括: yield yield from 基于 yield 和 yield from 机制协程的调度器 loop 这些功能皆在 ln_cs.c 中实现,experiences目录下为体验以上功能机制的例子(运行体验可参见 doc 目录下的文档)。 . ├── doc │ ├── A coroutine switching implement ... in C-language.md │ └── An optimization for ... in C-language.md ├── experiences │ ├── make_e │ ├── loop_e │ │ ├── loop_e.c │ │ ├── Makefile │ ├── yield_e ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- MySQL8.0.19开启GTID主从同步CentOS8
- Hadoop3单机部署,实现最简伪集群
- CentOS8编译安装MySQL8.0.19
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Mario游戏-低调大师作品