微服务启动慢,看我如何消灭这些憨憨怪!

2024-04-29 23:36
文章标签 服务 启动 消灭

本文主要是介绍微服务启动慢,看我如何消灭这些憨憨怪!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Hello,我是大都督周瑜,最近在公司做微服务启动速度的优化,我们有些微服务启动要花5-6分钟(就问你夸不夸张),直接导致打工人们有了更多的划水时间,领导表示不开心,要求我将微服务的启动速度控制在30秒以内,而那些特殊的微服务控制在1分钟以内,怎么办,请看我的表演。

第一步,肉眼看启动日志,先看启动时哪些类型的日志长时间频繁打印,经过我的火眼金睛,找到了以下几个憨憨怪。

第一个,Shardingsphere

我们用的Shardingsphere 5.x的版本,在微服务启动时,ShardingShpere需要获取数据库中的每张表的元数据信息,比如字段信息、索引信息,这些查询日志在启动时会频繁打印,比如以下日志会频繁打印:
image.png
因此,表越多,这个步骤消耗的时间就越多,好在我们开发环境的表不多,只有2000多张,是的,2000多张表!!! 当然啦,毕竟是开发库,没怎么做过清理,并且我们有业务是动态创建表的,所以表很多,BUT,就算删掉那些没用的表,也还有600多张,而且是一个库下面有600多张表,我都不好意思说我们是微服务架构了。

咋搞,我的办法是多线程+多数据连接,通过自定义Shardingsphere的元数据加载器MetaDataLoader,改造为内部通过线程池异步开启多个数据库连接来获取表的元数据信息,伪代码如下:

for (List<String> each : Lists.partition(tables, tables.size() / 4)) {// 创建连接Connection connection = 获取数据库连接;// 获取元数据futures.add(EXECUTOR_SERVICE.submit(() -> loadColumnMetaDataMap(connection, each)));}for (Future<Map<String, Collection<ColumnMetaData>>> each : futures) {columnMetaDataMap.putAll(each.get());
}

欢迎关注我的公众号:IT周瑜。获取更多技术干货、免费经典面试资料

第二个,还是ShardingShpere

前面Shardingsphere只是在查询表的元数据,可恶的是,它查出来之后还会存到H2数据库中(我们用的单机模式),我是怎么发现的呢?是因为上面查询元数据的日志频繁打印后,会突然暂停,控制台突然就不打印任何日志了,最开始,我还以为是应用启动结束了,后来才发现这只是中场休息,两分钟后就开始继续打印其他日志了。

为什么会中场休息?经过看源码发现,是Shardingsphere需要将查到的元数据信息存到H2数据库中,所以,如果表越多,表的元数据就越多,存H2的时间就越久(尽管是存内存中),关键是这个过程Shardingsphere还不打info日志,所以不研究一下就不知道应用在干嘛。

那么解决思路是一样的,多线程并发将元数据存入H2数据库,只不过这就得改Shardingsphere的源码了,不过我们本来就改了Shardingsphere的源码了,将错就错,直接在现有的源码的基础上,通过线程池并发将元数据存入H2数据库。

别说,经过以上两个措施优化之后,成功将启动时间从5-6分钟缩短到了2分钟左右,效果很不错,领导很满意(领导们别光看,记得点赞三连哦),但是距离1分钟的目标还差1分钟,怎么办?

欢迎关注我的公众号:IT周瑜。获取更多技术干货、免费经典面试资料

第三个,Bean扫描

我相信大部分SpringBoot应用的启动类都是这么写的:


/*** 大都督周瑜(微信: dadudu6789)*/
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

这么写,SpringBoot会扫描Application类所在的包路径,假如包路径为com.zhouyu,那么SpringBoot启动时就会扫描com.zhouyu这个包下的所有类,因为Spring需要去判断每个类是不是Bean,比如一个类加了@Component注解就是Bean,没加就不是Bean,但是不管怎样都需要去解析类,因此,如果com.zhouyu包下的类特别特别多,就会很影响扫描的速度,从而影响应用的启动速度,解决办法就是:

@SpringBootApplication(scanBasePackages = {"com.zhouyu.controller", "com.zhouyu.service",...})

通过@SpringBootApplication注解的scanBasePackages属性明确指定那些真正定义了Bean的包路径,这样SpringBoot启动时就只会扫描指定的包路径,这样Bean扫描的效率就会高很多,从而提高应用的启动速度,经过我测试,应用的启动速度又缩短了50秒左右,现在距离目标1分钟只有10秒左右了,开心。另外告诉大家一个秘密,我测试的这个微服务中总共有2000多个Bean对象,300个多@Service,200个@RestController~~~~

欢迎关注我的公众号:IT周瑜。获取更多技术干货、免费经典面试资料

第四个,日志打印

通过观察日志发现,启动过程中,Spring Fox会打印1000条日志,这是因为我们Controller接口比较多,Spring Fox会对大部分Controller接口中的@RequestMapping都打印一条日志,这种日志其实没有太大的意义,一条日志打印需要几百毫秒,那么所有1000条日志加起来也是一比不少的开销,所以就直接关掉,同样还找了一些其他没有太大作用的日志,通过SpringBoot的配置文件都关掉了,比如:

logging:level:springfox.documentation.spring.web.readers.operation.CachingOperationNameGenerator: OFF

这样,又节省了一些启动时间,最终成功达到了领导预期的目标,可以开心过五一了。

其实这个过程中,除开通过肉眼观察日志,还利用了一些工具,比如开源项目spring-startup-analyzer,它可以分析启动过程中每个Bean的创建时间,还有IntelliJ Profiler,它可以分析启动过程中某个线程或某个方法的执行时间,都是非常有用的,感谢这些工具和背后的大佬。

欢迎关注我的公众号:IT周瑜。获取更多技术干货、免费经典面试资料

这篇关于微服务启动慢,看我如何消灭这些憨憨怪!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/947442

相关文章

springboot家政服务管理平台 LW +PPT+源码+讲解

3系统的可行性研究及需求分析 3.1可行性研究 3.1.1技术可行性分析 经过大学四年的学习,已经掌握了JAVA、Mysql数据库等方面的编程技巧和方法,对于这些技术该有的软硬件配置也是齐全的,能够满足开发的需要。 本家政服务管理平台采用的是Mysql作为数据库,可以绝对地保证用户数据的安全;可以与Mysql数据库进行无缝连接。 所以,家政服务管理平台在技术上是可以实施的。 3.1

Docker启动异常

报错信息: failed to start daemon: Error initializing network controller: error creating default "bridge" network: cannot create network b8fd8c684f0ba865d4a13d36e5282fd694bbd37b243c7ec6c9cd29416db98d4b (d

微服务中RPC的强类型检查与HTTP的弱类型对比

在微服务架构中,服务间的通信是一个至关重要的环节。其中,远程过程调用(RPC)和HTTP是两种最常见的通信方式。虽然它们都能实现服务间的数据交换,但在类型检查方面,RPC的强类型检查和HTTP的弱类型之间有着显著的差异。本文将深入探讨这两种通信方式在类型检查方面的优缺点,以及它们对微服务架构的影响。 一、RPC的强类型检查 RPC的强类型检查是其核心优势之一。在RPC通信中,客户端和服务端都使

中国341城市生态系统服务价值数据集(2000-2020年)

生态系统服务反映了人类直接或者间接从自然生态系统中获得的各种惠益,对支撑和维持人类生存和福祉起着重要基础作用。目前针对全国城市尺度的生态系统服务价值的长期评估还相对较少。我们在Xie等(2017)的静态生态系统服务当量因子表基础上,选取净初级生产力,降水量,生物迁移阻力,土壤侵蚀度和道路密度五个变量,对生态系统供给服务、调节服务、支持服务和文化服务共4大类和11小类的当量因子进行了时空调整,计算了

SpringCloud - 微服务

1、微服务介绍         参考: 微服务百度百科 1.1 概念         微服务(或称微服务架构)是一种云原生架构方法,在单个应用中包含众多松散耦合且可单独部署的小型组件或服务。 这些服务通常拥有自己的技术栈,包括数据库和数据管理模型;通过一个REST API、事件流和消息代理组合彼此通信;以及按照业务能力进行组织,具有通常称为有界上下文的服务分隔线。         微服务特

小车启动底盘功能包

传感器与小车底盘的集成 新建功能包 catkin_create_pkg mycar_start roscpp rospy std_msgs ros_arduino_python usb_cam ydlidar_ros_driver 功能包下创建launch文件夹,launch文件夹中新建launch文件,文件名start.launch。 内容如下 <!-- 机器人启动文件:1.启动底盘2

Web容器启动时加载Spring分析

在应用程序web.xml中做了以下配置信息时,当启动Web容器时就会自动加载Spring容器。 [java]  view plain copy print ? <listener>          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

微服务(服务治理)

服务远程调用时存在的问题 注册中心原理 服务治理中的三个角色分别是什么? 服务提供者:暴露服务接口,供其它服务调用服务消费者:调用其它服务提供的接口注册中心:记录并监控微服务各实例状态,推送服务变更信息 消费者如何知道提供者的地址? 服务提供者会在启动时注册自己信息到注册中心,消费者可以从注册中心订阅和拉取服务信息 消费者如何得知服务状态变更? 服务提供者通过心

Linux开机自动启动ORACLE设置

Redhat init简介: Linux启动时,会运行一个init程序,然后由init来启动后面的任务,包括多用户环境(inittab中设定)和网络等。运行级就是当前程序运行的功能级别,这个级别从1到6,具有不同的功能。这些级别在/etc/inittab(其他发行版这个文件位置不同)中指定,该文件就是init程序寻找的主要文件。最先运行的服务放在/etc/rc.d目录下。

Mac 本地启动 Dify

本地启动 dify 拉取 dify 文件 git clone https://github.com/langgenius/dify.git 启动底层服务 cd dify/dockerdocker-compose -f docker-compose.middleware.yaml -p dify up -d 启动后端 API 安装 poetry brew install poet