Java中提升接口性能的一些方法

这篇具有很好参考价值的文章主要介绍了Java中提升接口性能的一些方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.使用线程池并行执行

假如有一个接口的逻辑如下:

Java中提升接口性能的一些方法

接口的整体耗时大约在1s左右,那么如果我们使用并行处理,类似木桶效应,接口的响应时间就不再是所有模块的耗时相加,而是取决于耗时最长的模块(600ms)了。

Java中提升接口性能的一些方法

2.数据库优化

我们可以通过JVM参数调整、应用节点数扩容来增加系统的吞吐量,但是用户的请求最终都会落到数据库上,如果数据库的性能不高的话,就会成为整个链路的性能瓶颈。主要有以下几种数据库的优化方案:

2.1 小表关联大表

生产环境的数据库中的数据量一般都会非常的大,联表查询是一件非常耗时、吃内存的操作,操作不当的话可能会导致服务被拖垮。

所以我们在联表查询时,一般先查询小表,然后再用小表的查询结果作为条件去筛选大表的数据。

2.2 反三大范式操作

一般不会改变的字段,可以在表当中冗余一下,这样可以减少我们的关联查询次数,提升接口响应速度。

比如常见的:用户姓名字段。

2.3 增加索引

比如我们建表时所使用的主键是默认添加索引的,对于经常关联查询的字段也需要添加索引。

当然有一些特殊的查询方式会导致索引失效,我们需要注意一下:

Java中提升接口性能的一些方法

2.4 减小事务粒度

我们在数据库操作的时候,为了保证数据的一致性,经常会需要使用到数据库的事务。

其实,我们在程序中使用数据库事务的时候,稍稍注意一下也可以提升我们接口的性能。

比如这个方法上面就加了一个 @Transactional 注解来开启事务。

@Transactional
public Boolean bigTransaction() {
    Object a = queryDataFromA();
    Object b = queryDataFromB();
    handleData(a, b);
    insertDataA(a);
    updateDataB(b);
}

那么,其实这里需要保证事务的地方也就只有最后两行 insert 和 update,没有必要将整个方法都放到事务当中。

Java中提升接口性能的一些方法

最直接的,我们可能会想把这两个事务抽出来,单独用一个带有 @Transactional 注解修饰的方法来执行。

@Transactional
public void handleABTransaction(Object a, Object b)
	insertDataA(a);
    updateDataB(b);
}

但是由于 @Transactional 注解底层是使用 AOP 来实现的,直接在类内部进行方法的调用,事务是不生效的。这里我们可以采用编程式事务来代替声明式事务:

import org.springframework.transaction.support.TransactionTemplate;

@Autowired
private TransactionTemplate transactionTemplate;

public Boolean bigTransaction() {
    Object a = queryDataFromA();
    Object b = queryDataFromB();
    handleData(a, b);
    
    // 编程式事务
    transactionTemplate.execute(() -> {
    	insertDataA(a);
    	updateDataB(b);
    });
}

2.5 读写分离、分库分表

随着业务的发展,数据库中的数据量会越来越多,这个时候就需要进行读写分离、分库分表的技术。尤其是现在微服务高可用的大环境下,不同业务使用不同的数据库已经成为了一种主流的设计。

具体分库分表的逻辑比较复杂,这里可以使用 ShardingJDBC 来实现。

3.拥抱缓存

3.1 Redis

Redis 相信大家都再熟悉不过了,它可以用来做缓存、分布式锁,甚至可以直接用来做数据库。

我们可以把变动不是很频繁,但是访问却非常频繁的数据放到 redis 里面,比如配置数据、热点数据等等。

3.2 内存缓存

我们常用的内存缓存有 Guava Cache,还有现在非常火的,性能非常高的 Caffeine Cache

当我们在使用一些内存缓存框架的时候,我们一定要了解的一点就是内存数据是跟随GVM进程同时存在的。所以当我们重启应用,缓存就会有一段时间的真空期,也就是我们常说的缓存击穿。所以我们需要考虑一下数据预热,或者是选择低谷的时候重启应用。

Caffeine 框架有一个非常好的功能就是它可以自动去刷新缓存,这样就可以保证我们缓存里面一直有数据,而且大概率是最新的数据。

private final LoadingCache<CountryCacheKey, String> appSettingCache = CaffeineCacheUtils
    .createLoadingCache(1000, Duration.ofHours(2), Duration.ofDays(1),
                       "app-setting-thread", // threadName
                       new CacheLoader<CountryCacheKey, String>() {
                           @Nullable
                           @Override
                           public String load(CountryCacheKey key) throws Exception {
                               String k = key.getKey(String.class);
                               String setting = settingApi.getAppSettingByName(k);
                               return setting;
                           }
                       });

4.锁和异步

4.1 减小锁的粒度

这里其实和上面说到的数据库事务是一个道理,我们可以使用 Lock 类来控制锁的范围。它比 synchronized 关键字更为灵活。

Java中提升接口性能的一些方法

现在我们的系统都是向微服务的演进,一个业务可能涉及多个服务,所以在锁定资源或者做互斥操作的时候,我们需要考虑用到分布式锁。

4.2 分布式锁

常用的分布式锁的解决方案会用到 Redis,上层是用 Redisson 的框架来提供 java 锁的 API。当我们在使用这些框架的时候,需要注意:

  • 获取锁要加一个等待时间,不能让程序一直自旋,一直在获取锁。
  • 对于获取到的锁要添加一个失效时间,如果不添加失效时间的话。拿 Redisson 举例,里面有一个看门狗机制,会不断进行锁的续期,这样就会增加锁的持有时间。
  • 代码中,一定要在 final 代码块中释放锁,否则因为程序 Bug 导致锁没有释放,导致请求就会卡住,当请求的线程占满以后,整个服务就不可用了。

除了锁的粒度意外呢,我们还可以采用异步的方式去提升服务的性能。比如配合使用 @EnableAsync@Async 来异步地处理日志记录等操作。这样就算日志记录异常也不会影响主流程的流转,接口的响应时间也会下降,性能也会得到明显的提升。

另外,系统间交互我们会用到 MQ。MQ 是一个异步处理的方式。消息的生产者制造消息,然后把消息放到消息队列,比如说 RabbitMQ。接下来消费者只需要去监听这个消息队列,有新的消息会自动去触发和处理,如果消费者处理失败了,消息队列还会进行重发。比之前 A 系统同步调用 B 系统,等 B 系统处理之后才能做接下来的事情相比,性能提升了不少。

Java中提升接口性能的一些方法

整理完毕,完结撒花~ 🌻





参考地址:

1.用4个方法,提升接口性能 | 多线程 | 数据库优化 | 缓存 | 异步与MQ,https://www.bilibili.com/video/BV1QG4y1g7QJ文章来源地址https://www.toymoban.com/news/detail-431648.html

到了这里,关于Java中提升接口性能的一些方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • CSS 提高性能的方法,并提供一些实用的技巧和代码示例

    CSS 是前端开发中不可或缺的一部分,它负责网页的样式和布局。随着网站规模和复杂度的增加,CSS 的性能也变得越来越重要。本文将介绍 CSS 提高性能的方法,并提供一些实用的技巧和代码示例。 使用压缩后的 CSS 文件 压缩 CSS 文件可以减小文件大小,加快加载速度。常见的

    2024年02月06日
    浏览(39)
  • 强强联合,性能提升数倍!Alibaba Dragonwell11+VectorAPI 助力 Java 高性能新时代

    Alibaba Dragonwell 作为 OpenJDK 的下游版本,是阿里巴巴针对 10万+ 服务器上运行的在线电商、金融、物流应用优化的 OpenJDK 实现。 阿里巴巴和 OpenJDK 社区紧密合作,将尽可能多的 Alibaba Dragonwell 定制功能带到上游。Dragonwell 是 OpenAnolis 的默认 JDK,Alibaba 的众多 Java 应用,正在逐步

    2024年02月06日
    浏览(34)
  • 要利用Java编程提升人们对安全教育的兴趣,可以开发一些互动性强、内容生动有趣的教育软件或游戏

    要利用Java编程提升人们对安全教育的兴趣,可以开发一些互动性强、内容生动有趣的教育软件或游戏。以下是一些建议: 开发安全教育游戏:使用Java编程语言,可以开发一些有关于安全教育的小游戏,如模拟火灾逃生、地震自救等场景,让玩家在游戏中学习到安全知识。

    2024年04月27日
    浏览(42)
  • 【银行测试】金融项目+测试方法范围分析,功能/接口/性能/安全...

    1、金融行业软件特征分析 金融行业软件系统具有集中度高、规模庞大、数量多、系统之间关联性强、业务复杂、需求变化快等特点,如何有效可行的实现软件测试和软件质量控制,是对金融行业软件测试人员提出的基本要求。 1)金融行业软件的业务特点 以金融行业软件的

    2024年02月04日
    浏览(43)
  • 一种提升深度多视角行人检测的泛化性能的方法 Bringing Generalization to Deep Multi-View Pedestrian Detection

    论文url : https://openaccess.thecvf.com/content/WACV2023W/RWS/html/Vora_Bringing_Generalization_to_Deep_Multi-View_Pedestrian_Detection_WACVW_2023_paper.html 论文提出了一种用于多视角行人检测的深度学习模型,旨在提高模型在不同摄像机数量、不同摄像机配置和新场景下的泛化能力。 $ {N} $ 个校准的RGB摄像

    2024年04月10日
    浏览(33)
  • 问,由于java存在性能上,以及部分功能上的缺点,请问如何正确使用C,C++,Go,这三个语言,提升Java Web项目的性能?

    拓展阅读:版本任你发,我用java8 我明白Java虽然在许多方面表现出色,但在某些特定场景下可能会遇到性能瓶颈或功能限制。为了提升Java Web项目的性能,可以考虑将C、C++和Go这三种语言用于特定的组件或服务。以下是如何正确使用这些语言来提升性能的一些建议: 1. **性能

    2024年04月23日
    浏览(28)
  • String类中的一些常用方法(JAVA)

    目录 字符串比较方法: boolean equals(Object anObject):  int compareTo(String s): int compareToIgnoreCase(String str) 字符串查找方法: char charAt(int index): int indexOf(int ch):  int indexOf(int ch, int fromIndex): int indexOf(String str): int indexOf(String str, int fromIndex): int lastIndexOf(int ch): int lastIndexOf(in

    2024年02月07日
    浏览(34)
  • 1.UnityProfiler性能分析提升性能

    1.main thread 主线程 业务逻辑都在这里,我们调用Unity API都在这里;例如设置transform位置,main thread里面处理 2.render thread,渲染线程,负责渲染图像、执行渲染循环、处理GPU命令、帧同步。 3.  这个则表示当前负载最多可以绘制多少次(当前帧数) 4.Batches :批次,绘制场景,

    2024年01月25日
    浏览(48)
  • 【Java】泛型类,接口,方法

    泛型的作用:约束元素的类型 集合 泛型的符号: T:type E:element K:Key V:value 泛型符号是个占位符,给引用类型占位置 在使用的时候名称没有任何要求,ABCDEFG无所谓,个数也不要求 反省符号应用: 泛型类 在本类中,可以把泛型符号当成已知类型来用 泛型的具体类型在创

    2024年02月14日
    浏览(31)
  • Java 9 - 私有接口方法

    Java 9 - 私有接口方法

    2024年02月16日
    浏览(21)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包