Springboot整合Quartz集群部署以及配置Druid数据源

参考链接:
https://blog.csdn.net/wangmx1993328/article/details/105441308
https://blog.csdn.net/qq_39669058/article/details/90411497

参数配置连接:https://github.com/wangmaoxiong/quartzjdbc/blob/master/src/main/resources/application-cluster.yml

factory.setWaitForJobsToCompleteOnShutdown(true);
确认这个配置集群需要配置吗?
false

开源项目若依定时任务配置

package com.ruoyi.quartz.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import javax.sql.DataSource;
import java.util.Properties;/*** 定时任务配置* * @author ruoyi*/
@Configuration
public class ScheduleConfig
{@Beanpublic SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource){SchedulerFactoryBean factory = new SchedulerFactoryBean();factory.setDataSource(dataSource);// quartz参数Properties prop = new Properties();//实例名称可以自定义prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler");prop.put("org.quartz.scheduler.instanceId", "AUTO");// 线程池配置prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");prop.put("org.quartz.threadPool.threadCount", "20");prop.put("org.quartz.threadPool.threadPriority", "5");// JobStore配置prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");// 集群配置prop.put("org.quartz.jobStore.isClustered", "true");prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "false");// sqlserver 启用prop.put("org.quartz.jobStore.misfireThreshold", "12000");prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");factory.setQuartzProperties(prop);//实例名称可以自定义factory.setSchedulerName("RuoyiScheduler");// 延时启动factory.setStartupDelay(1);factory.setApplicationContextSchedulerContextKey("applicationContextKey");// 可选,QuartzScheduler// 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了factory.setOverwriteExistingJobs(true);factory.setWaitForJobsToCompleteOnShutdown(true);// 设置自动启动,默认为truefactory.setAutoStartup(true);return factory;}
}

一句话概括Quartz:

Quart分布式调度任务是通过数据库实现的,抢占式调度,一个任务只能在一个节点上执行,他的集群也仅仅是解决了单点故障(任务级别),实现了高可用,多个任务在集群中负载均衡调度,并没有解决任务分片的问题,不能实现水平扩展,如果执行大量的短任务,各个节点频繁的竞争数据库锁,节点越多这种情况越严重,性能会很低下。

版本为:SpringBoot 2.x,Quartz 2.3.0,Durid 1.1.9

这里不再使用c3p0数据源,在boot2.x中spring-boot-starter-quartz依赖默认是不依赖c3p0数据源的,如果要使用需要自己单独引用c3p0数据源,在quartz.properties配置下就可以了,这里使用的Druid数据源。

首先引入依赖:

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.43</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.9</version></dependency>

Druid-spring-boot-starter:
https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter

application.yml文件配置,这里面配置的Druid数据源相关的,没有配置其他的,很单纯的

server:port: 8080
spring:application:name: quartzdatasource:url: jdbc:mysql://192.168.184.135:3306/quartzdb?characterEncoding=utf-8&useUnicode=true&useSSL=falsedriver-class-name: com.mysql.jdbc.Driver  # mysql8.0以前使用com.mysql.jdbc.Driverusername: rootpassword: 123456platform: mysql#通过这句配置将druid连接池引入到我们的配置中,spring会尽可能判断类型是什么,然后根据情况去匹配驱动类。type: com.alibaba.druid.pool.DruidDataSourcedruid:initial-size: 5  # 初始化大小min-idle: 5  # 最小max-active: 100  # 最大max-wait: 60000  # 配置获取连接等待超时的时间time-between-eviction-runs-millis: 60000  # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒min-evictable-idle-time-millis: 300000  # 指定一个空闲连接最少空闲多久后可被清除,单位是毫秒validationQuery: select 'x'test-while-idle: true  # 当连接空闲时,是否执行连接测试test-on-borrow: false  # 当从连接池借用连接时,是否测试该连接test-on-return: false  # 在连接归还到连接池时是否测试该连接filters: config,wall,stat  # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙poolPreparedStatements: true # 打开PSCache,并且指定每个连接上PSCache的大小maxPoolPreparedStatementPerConnectionSize: 20maxOpenPreparedStatements: 20# 通过connectProperties属性来打开mergeSql功能;慢SQL记录connectionProperties: druid.stat.slowSqlMillis=200;druid.stat.logSlowSql=true;config.decrypt=false# 合并多个DruidDataSource的监控数据#use-global-data-source-stat: true#WebStatFilter配置,说明请参考Druid Wiki,配置_配置WebStatFilterweb-stat-filter:enabled: true #是否启用StatFilter默认值trueurl-pattern: /*exclusions: /druid/*,*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.icosession-stat-enable: truesession-stat-max-count: 10#StatViewServlet配置,说明请参考Druid Wiki,配置_StatViewServlet配置stat-view-servlet:enabled: true #是否启用StatViewServlet默认值trueurl-pattern: /druid/*reset-enable: truelogin-username: adminlogin-password: admin

quartz.properties配置文件

#调度标识名 集群中每一个实例都必须使用相同的名称
org.quartz.scheduler.instanceName = quartzScheduler
#调度器实例编号自动生成,每个实例不能不能相同
org.quartz.scheduler.instanceId = AUTO
#开启分布式部署,集群
org.quartz.jobStore.isClustered = true
#分布式节点有效性检查时间间隔,单位:毫秒,默认值是15000
org.quartz.jobStore.clusterCheckinInterval = 2000
#远程管理相关的配置,全部关闭
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
#实例化ThreadPool时,使用的线程类为SimpleThreadPool(一般使用SimpleThreadPool即可满足几乎所有用户的需求)
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
##并发个数,指定线程数,至少为1(无默认值)(一般设置为1-100之间的的整数合适)
org.quartz.threadPool.threadCount = 10
##设置线程的优先级(最大为java.lang.Thread.MAX_PRIORITY 10,最小为Thread.MIN_PRIORITY 1,默认为5)
org.quartz.threadPool.threadPriority = 5
#org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
#容许的最大作业延长时间,最大能忍受的触发超时时间,如果超过则认为“失误”,不敢再内存中还是数据中都要配置
org.quartz.jobStore.misfireThreshold = 6000
#持久化方式配置
# 默认存储在内存中,保存job和Trigger的状态信息到内存中的类
#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
#数据库方式
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
#持久化方式配置数据驱动,MySQL数据库
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#quartz相关数据表前缀名
org.quartz.jobStore.tablePrefix = QRTZ_#数据库别名 随便取
#org.quartz.jobStore.dataSource = qzDS
#org.quartz.dataSource.qzDS.driver = com.mysql.jdbc.Driver
#org.quartz.dataSource.qzDS.URL = jdbc:mysql://192.168.184.135:3306/quartzdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8
#org.quartz.dataSource.qzDS.user = root
#org.quartz.dataSource.qzDS.password = 123456
#org.quartz.dataSource.qzDS.maxConnections = 10
#org.quartz.dataSource.qzDS.acquireIncrement=1

///分割一下///

我这里使用的是MySql数据库,想要使用Oracle数据库,导入表(@"/路径/tables_oracle.sql"),不管你怎么导,只要能用就行,在数据源的地方修改下连接信息,修改quartz.properties文件修改为如下,直接启动就行了

org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate

在这里插入图片描述
///分割一下///

案例结构
在这里插入图片描述
模拟任务调度service层的业务逻辑

UserService.java

package com.quartz.service;import java.io.Serializable;public interface UserService extends Serializable {void getUserInfo();void getUserAddr();
}

UserServiceImpl.java

package com.quartz.service.impl;import com.quartz.service.UserService;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {@Overridepublic void getUserInfo() {System.err.println("调度getUserInof成功");}@Overridepublic void getUserAddr() {System.err.println("调度getUserAddr成功");}
}

任务

JobOne.java

package com.quartz.job;import com.quartz.service.UserService;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;@Component
@DisallowConcurrentExecution //保证上一次任务执行完毕再执行下一任务
//@PersistJobDataAfterExecution //上一个任务完成前写入需要被下一个任务获取的变量以及对应的属性值,类似求和累加
public class JobOne extends QuartzJobBean {private UserService userService;@Overrideprotected void executeInternal(JobExecutionContext context) throws JobExecutionException {userService.getUserInfo();}public void setUserService(UserService userService) {this.userService = userService;}
}

JobTwo.java

package com.quartz.job;import com.quartz.service.UserService;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;@Component
@DisallowConcurrentExecution
public class JobTwo extends QuartzJobBean {//不能使用注入的方式,只能使用DateMap方式传入参数private UserService userService;@Overrideprotected void executeInternal(JobExecutionContext context) throws JobExecutionException {userService.getUserAddr();}public void setUserService(UserService userService) {this.userService = userService;}
}

JobConfig.java

package com.quartz.jobconfig;import com.quartz.job.JobOne;
import com.quartz.job.JobTwo;
import com.quartz.service.UserService;
import org.quartz.JobDataMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;@Configuration
public class JobConfig {@Autowiredprivate UserService userService;@Bean("jobOneDetail")public JobDetailFactoryBean jobOneDetailFactoryBean(JobOne jobOne) {JobDetailFactoryBean jobDetailFactoryBean =new JobDetailFactoryBean();jobDetailFactoryBean.setJobClass(jobOne.getClass());//没有绑定触发器仍然保留在Quartz的JobStore中jobDetailFactoryBean.setDurability(true);jobDetailFactoryBean.setName("jobOneDetailName");jobDetailFactoryBean.setGroup("jobOneDetailGroup");JobDataMap jobDataMap = new JobDataMap ();jobDataMap.put ("userService",userService);jobDetailFactoryBean.setJobDataMap(jobDataMap) ;return jobDetailFactoryBean;}@Bean("jobOneTrigger")public CronTriggerFactoryBean cronTriggerOneFactoryBean(@Qualifier("jobOneDetail") JobDetailFactoryBean jobDetailFactoryBean){CronTriggerFactoryBean cronTriggerFactoryBean=new CronTriggerFactoryBean();cronTriggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject());cronTriggerFactoryBean.setCronExpression("*/1 * * * * ?");cronTriggerFactoryBean.setName("jobOneTriggerName");cronTriggerFactoryBean.setGroup("jobOneTriggerGroup");return cronTriggerFactoryBean;}@Bean("jobTwoDetail")public JobDetailFactoryBean jobTwoDetailFactoryBean(JobTwo jobTwo) {JobDetailFactoryBean jobDetailFactoryBean =new JobDetailFactoryBean();jobDetailFactoryBean.setJobClass(jobTwo.getClass());jobDetailFactoryBean.setDurability(true);jobDetailFactoryBean.setName("jobTwoDetailName");jobDetailFactoryBean.setGroup("jobTwoDetailGroup");JobDataMap jobDataMap = new JobDataMap ();jobDataMap.put ("userService",userService);jobDetailFactoryBean.setJobDataMap(jobDataMap) ;return jobDetailFactoryBean;}@Bean("jobTwoTrigger")public CronTriggerFactoryBean cronTriggerTwoFactoryBean(@Qualifier("jobTwoDetail") JobDetailFactoryBean jobDetailFactoryBean){CronTriggerFactoryBean cronTriggerFactoryBean=new CronTriggerFactoryBean();cronTriggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject());cronTriggerFactoryBean.setCronExpression("*/1 * * * * ?");cronTriggerFactoryBean.setName("jobTwoTriggerName");cronTriggerFactoryBean.setGroup("jobTwoTriggerGroup");return cronTriggerFactoryBean;}}

SchedulerConfig.java

package com.quartz.jobconfig;import com.alibaba.druid.pool.DruidDataSource;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;@Configuration
public class SchedulerConfig {//执行任务。有了触发器,我们就可以执行任务了。注册一个SchedulerFactroyBean,然后将触发器一list的方式传入@Beanpublic SchedulerFactoryBean schedulerFactoryBean(DruidDataSource druidDataSource, @Qualifier("jobOneTrigger") Trigger jobOneTrigger, @Qualifier("jobTwoTrigger") Trigger jobTwoTrigger){SchedulerFactoryBean schedulerFactoryBean=new SchedulerFactoryBean();//调度器名称schedulerFactoryBean.setSchedulerName("TestScheduler");//数据源schedulerFactoryBean.setDataSource(druidDataSource);//覆盖已存在的任务,用于Quartz集群,QuartzScheduler启动会更新已存在的JobschedulerFactoryBean.setOverwriteExistingJobs(true);//延时1s启动定时任务,避免系统未完全启动却开始执行定时任务的情况schedulerFactoryBean.setStartupDelay(1);//设置加载的quartz.properties配置文件schedulerFactoryBean.setConfigLocation(new ClassPathResource("/quartz.properties"));//自动启动schedulerFactoryBean.setAutoStartup(true);//注册触发器schedulerFactoryBean.setTriggers(jobOneTrigger,jobTwoTrigger);return schedulerFactoryBean;}
}

启动两个改下端口8080,8081就行了,看到效负载调度。
在这里插入图片描述
节点争抢Job问题

因为Quartz使用了一个随机的负载均衡算法, Job以随机的方式由不同的实例执行。Quartz官网上提到当前,还不存在一个方法来指派(钉住) 一个 Job 到集群中特定的节点。

参考链接:https://blog.csdn.net/qq_39669058/article/details/90411497

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/519345.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我是如何拿到蚂蚁金服实习 offer 的

我是2018年3月入职蚂蚁的应届前端工程师&#xff0c;来自于北京邮电大学。2年前的此刻&#xff0c;我也是实习求职大潮中的一员&#xff0c;在这里&#xff0c;分享一下我从准备面试到实习&#xff0c;再到最终正式入职的经历。 选择蚂蚁 阿里的前端水平在业界有着很高的评价…

java 客户化排序_第八部分_客户化JSP标签

EL语言(减少JSP页面中的Java代码)String password request.getParameter("password");%>username: password: username: ${param.username }password: ${param.password }属性范围->在EL中的名称Page->pageScope&#xff1b;Request->requestScope&…

十大类疫情服务紧缺 阿里广发英雄帖抗疫小程序开发者最高可获50万元奖励

全民积极响应国家抗击新冠肺炎疫情的号召&#xff0c;正催生出越来越多新的互联网服务缺口。基于对用户、政府、企事业单位抗疫服务需求的紧缺情况调查&#xff0c;支付宝今日面向社会各界开发者发布“10大疫情期最急需服务开发清单”&#xff0c;号召更多开发者投入进来开发更…

信用算力基于 RocketMQ 实现金融级数据服务的实践

微服务架构已成为了互联网的热门话题之一&#xff0c;而这也是互联网技术发展的必然阶段。然而&#xff0c;微服务概念的提出者 Martin Fowler 却强调&#xff1a;分布式调用的第一原则就是不要分布式。 纵观微服务实施过程中的弊端&#xff0c;可以推断出作者的意图&#xff…

六年打磨!阿里开源混沌工程工具 ChaosBlade

阿里妹导读&#xff1a;减少故障的最好方法就是让故障经常性的发生。通过不断重复失败过程&#xff0c;持续提升系统的容错和弹性能力。今天&#xff0c;阿里巴巴把六年来在故障演练领域的创意和实践汇浓缩而成的工具进行开源&#xff0c;它就是 “ChaosBlade”。如果你想要提升…

jmeter-5.3 测试http接口动态数据 windows+Linux双环境

文章目录一、基础组件1. 企业需求2. 创建线程组&#xff1a;3. 创建HTTP请求4. CSV 数据文件组件5. 响应断言二、添加监听器2.1. 添加察看结果树2.2. 添加聚合报告2.3. 监听每秒事务数2.4. 监听 随时间变化的响应时间三、HTTP请求配置3.1. 基础参数四、 响应断言配置四、 CSV 数…

阿里达摩院又火了!引入AI确诊肺炎提速16倍,仅需半小时!网友神回复了

针对新型冠状病毒的确诊&#xff0c;全国大多数医院基本都采用核酸检测。果壳网发文称&#xff1a;从病人样本送到实验室即刻开始测试&#xff0c;到出检测报告&#xff0c;差不多需要8个小时。但是8个小时太长&#xff0c;在现在这种病毒传播速度下&#xff0c;让人焦急万分。…

用java写ods系统_基于数据库的代码自动生成工具,生成JavaBean、生成数据库文档、生成前后端代码等(TableGo v7.0.0版)...

TableGo是基于数据库的代码自动生成工具&#xff0c;低代码编程技术的实现&#xff0c;可以零代码自动生成SpringBoot项目工程、生成JavaBean、生成前后端分离的CRUD代码、生成MyBaits的Mapper映射配置文件、生成数据库设计文档(Word、Excel)、生成Swagger2离线API文档、生成前…

Node.js 应用故障排查手册 —— 冗余配置传递引发的内存溢出

楔子 前面一小节我们以一个真实的压测案例来给大家讲解如何利用 Node.js 性能平台 生成的 CPU Profile 分析来进行压测时的性能调优。那么与 CPU 相关的问题相比&#xff0c;Node.js 应用中由于不当使用产生的内存问题是一个重灾区&#xff0c;而且这些问题往往都是出现在生产…

一分钟在Linux 环境 搭建 SFTP服务器

文章目录一、实战1. 创建sftp组&#xff1a;2. 创建一个用户sftpuser&#xff1a;3. 设置sftpuser用户的密码&#xff0c;会要求你输入两次密码确认&#xff1a;4. 创建一个sftp的上传目录&#xff1a;5. 修改用户sftpuser所在的目录&#xff1a;6. 配置sshd_config&#xff1a…

微服务架构何去何从?

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 孙玄本文经授权转载自架构之美前言微服务架构模式经过5年多的发展&#xff0c;在各行各业如火如荼地应用和实践。如何在企业中优雅地设计微服务架构&#xff1f;是企业面对的一个重要问题。本文将讲述微服务架构1.0设计与实践…

天马行空脚踏实地,阿里巴巴有群百里挑一的天才应届生

阿里巴巴有一群天马行空脚踏实地的阿里星。 天下网商记者 王安忆 阿里巴巴的春季校招已经启动。在阿里的技术大咖储备团队中&#xff0c;有三分之一是来自高校招聘&#xff0c;这当中&#xff0c;有一项名为阿里星的神秘计划。这是校招中专门针对高校顶尖大学生的一个培养计划&…

linux Nas挂载

文章目录一、NAS服务端1. 首先查看服务器上是否有nfs和rpc相关软件2. 设置共享3. 使配置生效:4. 查看所有可挂载5. rpcbind启和动nfs6.配置防火墙7. 查看防火墙的状态8. 启动防火墙9. 开放端口10. 重新启动防火墙11. 查看已开放的端口二、客户端(应用服务器)2.1.查看空间分布2.…

GitHub 标星 14000+,阿里开源的 SEATA 如何应用到极致?

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者简介&#xff1a;袁鸣凯&#xff0c;家乐福技术总监&#xff0c; 高知特有限技术公司中国区架构师&#xff0c;HP上海研发技术专家&#xff0c;夸客金融首席架构师&#xff0c;现任家乐福中国区技术总监。多年互联网、企业级SOA…

阿里小二的日常工作要被TA们“接管”了!

昨天有人偷偷告诉我说 阿里巴巴其实是一家科技公司&#xff01; 我想了整整一夜 究竟是谁走漏了风声 那么重点来了&#xff0c;阿里到底是如何在内部的办公、生活中&#xff0c;玩转“黑科技”的呢&#xff1f; AI取名&#xff1a;给你专属的“武侠”花名 花名是阿里巴巴独…

对话Ruby创始人松本行弘、阿里高级技术专家朴灵!

4月25日&#xff0c;云栖社区联合阿里云国际站&#xff0c;特别邀请了Ruby创始人Matz&#xff08;松本行弘&#xff09;、阿里云高级技术专家朴灵&#xff0c;来为开发者们分享干货。 在本次活动上可以了解到Ruby语言最新的动态&#xff0c;Ruby和新语言golang在性能方面的差别…

Serverless 终结 Kubernetes?

戳蓝字“CSDN云计算”关注我们哦&#xff01;Kubernetes 是基础架构管理的终极解决方案吗&#xff1f;还是说我们更加需要 Serverless&#xff1f;究竟哪种技术能够解救运维团队&#xff1f;不要忘记&#xff0c;NoOps 的世界即将到来。作者 | Daniele Fontani译者 | 弯月封图 …

代号“凤凰”,阿里新零售秘密武器,今年要打入100个城市

2019年&#xff0c;淘鲜达要在100个城市完成1000个门店的新零售改造。 天下网商记者 张文政 过去一年&#xff0c;初平三分之二的时间在出差&#xff0c;足迹遍及山东、河南、江西、湖南等地。 初平是天猫超市事业群战略合作部总经理&#xff0c;负责天猫超市旗下“淘鲜达”…

VS Code 批量操作

文章目录1. 关键词批量选中2. 末尾批量编辑3. 垂直批量编辑4. 垂直批量选中5. 批量选中整行6. 批量复制整行1. 关键词批量选中 Ctrld 选中相同的词句&#xff0c;批量编辑 2. 末尾批量编辑 shirtalti移动到最后&#xff0c;批量编辑 3. 垂直批量编辑 Ctrlalt↓垂直批量编…

Node.js 应用故障排查手册 —— 利用 CPU 分析调优吞吐量

楔子 在我们想要新上线一个 Node.js 应用之前&#xff0c;尤其是技术栈切换的第一个 Node.js 应用&#xff0c;由于担心其在线上的吞吐量表现&#xff0c;肯定会想要进行性能压测&#xff0c;以便对其在当前的集群规模下能抗住多少流量有一个预估。本案例实际上正是在这样的一…