从使用传统Web框架到切换到Spring Boot后的总结

1、前言

其实我接触 Spring Boot 的时间并不长,所以还算一个初学者,这篇文章也算是我对 Spring Boot 学习以及使用过程中的复盘,如果文章出现描述错误或表达不清晰的地方,欢迎大家在评论区留言互动。

没想到 Spring Boot 这两年竟然普及的这么快, 两年前刚毕业的时候,因为待的是二线城市的小公司,公司的技术栈并不追求新颖,而是追求稳定、能用就行的理念,所以项目上就一直使用传统的 SSM、SSH。

当搭建后端框架时,需要手动添加 Maven 配置、各种 XML 配置,反正就是一个项目创建就要配置一遍,从我两年前写的这篇 SSM框架搭建,就可以看出该过程是有多么的繁琐,甚至有时候因为配置错误以致于一上午就又可以愉快的划水了…

而项目部署时也是头大,首先需要安装 Tomcat,然后将项目编译打包成 war 包,再将 war 包放在 Tomcat 的 webapp 目录下部署运行,这个过程就觉得很不方便…

汇总一下构建一个传统项目需要的步骤:

  • 配置 web.xml,加载 Spring 和 Spring MVC
  • 配置数据库连接、配置 Spring 事务
  • 配置加载配置文件的读取,开启注解
  • 配置日志文件
  • Redis、MQ 等等 …
  • 配置完成之后部署 Tomcat 调试
  • 可能还需要考虑各个版本的兼容性,jar 包冲突的各种可行性。

因为如上种种问题,当一接触到 Spring Boot 后就被它简单的操作吸引了…

真羡慕现在的小伙伴,一上来就是用的 Spring Boot 了~ 不用再像我那会一样。

2、Spring Boot 解决的问题

Spring Boot 的出现大大简化了传统 Web 框架的搭建过程,提高了开发效率,Spring Boot 总结后有以下几个特点:

  • 可以快速的创建 Spring 应用。
  • 使用嵌入式的Servlet容器,应用无需打成WAR包
  • 整合了大量第三方框架,做到开箱即用。
  • 约定大于配置。

这几个特点基本上也是面试 Spring Boot 时常问的,也正是因为这几个特点让之前繁琐的搭建过程变的简单。

我们都知道,特点并不是解决问题的关键,所以我们要了解,Spring Boot 到底是如何解决问题的。

2.1、自动配置

之前我们使用 XML 方式时,有相当大的部分就是对 Bean 进行初始化并配置,比如下面这一段就是配置数据库连接信息:

<!-- 配置 数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver" /><property name="url" value="jdbc:mysql://10.211.55.4:3306/test" /><property name="username" value="root" /><property name="password" value="123456" />
</bean>

而使用 Spring Boot 后,会根据某些约定的规则对所有配置的 Bean 进行初始化,也就是约定优于配置,然后有的小伙伴就会问,那么什么是约定优于配置呢?

约定优于配置可以这样理解:

  1. 开发人员仅需要规定应用中不符合约定的部分。
  2. 在没有规定配置的地方,采用默认配置

举例说明:

不符合规定的部分:例如,如果模型中有个名为 User 的类,那么数据库中对应的表就会默认命名为 user。只有在偏离这一约定时,例如将该表命名为 “user_info”,才需写有关这个名字的配置。

规定默认配置的地方:

  1. Maven 的目录结构。项目创建后默认有 resources 文件夹,用于存放资源配置文件。默认的编译生成的类都在targe文件夹下面。
  2. Spring Boot默认的配置文件必须是,也只能是后缀名为 yml 或者 properties 的文件,且名称唯一。
  3. application.yml中默认的属性。数据库连接信息必须是以 spring: datasource: 为前缀;再就是其他环境配置,比如端口号、请求路径等,后面单独写一篇文章关于默认配置文件的。

是否对这个 yml 或者 properties 文件中配置了信息就实现了配置有点好奇?

我们还是以数据库连接信息为例:在 Spring Boot 中有一个 DataSourceAutoConfiguration 配置类,这个类会自动查找 application.yml 或者 properties 文件里的 spring.datasource.* 路径,然后相关属性会自动配置到数据源中。这个过程就属于约定大于配置,如果感兴趣的小伙伴可以进入这个类看看。

2.2、内嵌容器

Spring Boot 应用程序可以不用部署到外部容器中,比如 Tomcat。Spring Boot 应用可以直接通过 Maven 命令将项目编译成可执行的 jar 包,通过 java -jar 命令启动即可,非常方便。

怎么不需要 Servlet 容器就启动起来了呢?

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

只要加上这个依赖,Spring Boot 就帮我们默认内嵌了 Tomcat,当然同样也支持修改,比如可以使用 jetty(见标签7修改默认内置的Tomcat容器)。

内嵌就内嵌了吧,简单看一下 Tomcat 在 Spring Boot 中是如何启动的。

可以看一下我写的这篇文章:https://www.cnblogs.com/niceyoo/p/14019428.html

2.3、应用监控

应用监控是项目部署中必不可少的环节,以前我们怎么知道系统实际运行的情况呢?

需要我们人为的进行运维监控,比如对 cpu、内存、数据库连接等监控。如果是对系统接口,那么可能会单独写个测试接口来判断当前应用的健康程度,当然,大部分情况接口只要返回200就认为当前应用是健康的。

但是这种情况会存在很大的问题,首先前者会浪费人力资源,后者则因为固定接口形式无法真正意义上判断应用的健康状态。

而 Spring Boot 中提供了一个用于监控和管理自身应用信息的模块—Actuator,通过 Actuator,可以实现对程序内部运行情况进行监控,比如 Bean 加载情况、环境变量、日志信息、线程信息等。当然也可以自定义跟业务相关的监控,通过 Actuator 的端点信息进行暴露。这个有点 DevOps 的意思。

如何集成到 Spring Boot 中呢?

只需要在 pom.xml 中添加如下依赖即可:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

应用启动则直接可以访问:

  • http://localhost:port/actuator 查看所有端点信息。
  • http://localhost:port/actuator/env 查看该应用全部环境属性。

application配置文件中可配置的参数:

management:endpoints:web:# actuator的访问路径,替换默认/actuatorbase-path: /monitor# 设置是否暴露端点 默认只有health和info可见exposure:# include: env   # 方式1: 暴露端点env,配置多个以,隔开include: "*"     # 方式2: 包括所有端点,注意需要添加引号# 排除端点,如果不排除则只需要访问该应用的/shutdown 端点就能实现关闭该应用的远程操作exclude: shutdownserver:port: 8888  #新开监控端口,不和应用用同一个端口,endpoint:health:show-details: always # 显示db、redis、rabbti连接情况等shutdown:enabled: true  #默认情况下,除shutdown以外的所有端点均已启用。手动开启

按照如上配置则访问路径为:http://localhost:8888/monitor

我们可以看到有很多节点(图中省略),这些结点被称作 端点,如下是这些端点的描述:

ID描述默认启用默认公开
auditevents公开当前应用程序的审计事件信息YesNo
beans显示应用程序中所有Spring bean的完整列表YesNo
conditions显示在配置和自动配置类上评估的条件以及它们是否匹配的原因YesNo
configprops显示所有@ConfigurationProperties对照的列表YesNo
env从Spring的ConfigurableEnvironment中公开属性YesNo
flyway显示已应用的任何Flyway数据库迁移YesNo
health显示应用程序健康信息YesYes
httptrace显示HTTP跟踪信息(默认情况下,最后100个HTTP请求-响应交互)YesNo
info显示任意应用程序信息YesYes
loggers显示和修改应用程序中记录器的配置YesNo
liquibase显示已应用的任何Liquibase数据库迁移YesNo
metrics显示当前应用程序的“指标”信息YesNo
mappings显示所有@RequestMapping路径对照的列表YesNo
scheduledtasks显示应用程序中调度的任务YesNo
sessions允许从Spring Session支持的会话存储中检索和删除用户会话YesNo
shutdown让应用程序优雅地关闭NoNo
threaddump执行线程转储YesNo

如上所知,如果想显示应用程序健康信息,那么就访问 health 端点,即:

http://127.0.0.1:8888/monitor/health
image-20201122204029210
其他的大家可以自行尝试看一下,额外需要注意的是 shutdown 端点,项目中一定要排除,否则只需要访问该应用的 /shutdown 端点就能实现该应用的远程关闭操作,十分危险。

这就完了?

显然不是,上边这样直接访问端点,然后返回 JSON 数据,显然很不直观,毕竟现在很流行可视化嘛~ 咳咳。

所以这时候我们可以通过 Spring Boot Admin 来对 actuator 返回的这些数据进行整理。

关于 Spring Boot Admin 的介绍:

Spring Boot Admin 是用于管理和监控 Spring Boot 应用程序运行状态的。在 Spring Boot 项目中可以通过集成 Spring Boot Admin Client 向 Spring Boot Admin Server 进行注册(通过 HTTP),这样我们就可以在 Spring Boot Admin Server 统一管理 Spring Boot 应用。可视化是端点之上的 Vue 项目。

提供功能如下:

  • 显示健康状态及详细信息,如JVM和内存指标、数据源指标、缓存指标
  • 跟踪并下载日志文件
  • 查看jvm系统-和环境属性
  • 查看Spring启动配置属性
  • 方便loglevel管理
  • 查看线程转储
  • 视图http-traces
  • 查看http端点
  • 查看计划任务
  • 查看和删除活动会话(使用spring-session)
  • 状态更改通知(通过电子邮件、Slack、Hipchat…)
  • 状态变化的事件日志(非持久性)
  • ……

使用 Spring Boot Admin 也是非常的简单,直接添加如下依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-server</artifactId><version>2.3.0</version>
</dependency>
<dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-client</artifactId><version>2.3.0</version>
</dependency>

配置文件如下:

spring:boot:admin:# 修改上下文路径context-path: /adminclient:url: http://127.0.0.1:${server.port}/admin

再在启动类上加上 @EnableAdminServer 注解,齐活,完事。

通过如上界面,我们可以清楚的看到应用的名称和 IP 端口信息,应用名称是默认的,也可以在配置文件中通过 spring.application.name 来自定义名称。

我们还可以点击服务信息进去查看详情,左边是对应的功能菜单,右边是数据展示的页面。详情中有健康信息、线程信息、JVM 内存等信息,都通过图形的方式展示,一目了然。

通过左侧功能菜单可以看到还有 日志、JVM、缓存 等管理功能,大家可以点点看看。

2.4、Spring Boot Starter 开箱即用

关于 Spring Boot Starter 相信大家一定不陌生,很多第三方工具的引入都是涉及到 Starter 包,Starter 包可以说是 Spring Boot 中的核心功能,Starter 的出现,简化了 Spring 很多工作。不懂就问环节:什么是 Starter?

大家可以看一下我转载的这篇文章:

https://www.cnblogs.com/niceyoo/p/14022406.html

总之,Starter 包简化框架集成难度,将 Bean 的自动装配逻辑封装在 Starter 包内部,同时也简化了 Maven Jar 包的依赖,对框架的集成只需要加入一个 Starter 包的配置,降低了烦琐配置的出错几率。

如下是 Spring Boot 提供的开箱即用 Starter 包:

starterdesc
spring-boot-starter-web用于快速构建Web,包含 RESTful 风格框架、SpringMVC和默认的嵌入式容器Tomcat
spring-boot-starter-test用于测试
spring-boot-starter-data-jpa带有Hibermate的Spring Data JPA,用于操作数据库。
spring-boot-starter-jdbc传统的JDBC支持
spring-boot-starter-thymeleaf支持Thymeleaf模板
spring-boot-starter-mail支持Java Mail、Spring Email 发送邮件
spring-boot-starter-integrationSpring框架创建的一个API,面向企业应用集成(EAI)
spring-boot-starter-mobileSpringMVC的扩展,用来简化手机上的Web应用程序开发
spring-boot-starter-data-redis快速整合并操作 Redis:通过Spring Data Redis、Redis Client使用Redis
spring-boot-starter-validationBean Validation是一个数据验证的规范,Hibernate Validator是一个数据验证框架
spring-boot-starter-websocket相对于非持久的协议HTTP,Websocket 是一个持久化的协议
spring-boot-starter-web-servicesSOAP Web Services
spring-boot-starter-hateoas为服务添加HATEOAS功能
spring-boot-starter-security用Spring Security进行身份验证和授权
spring-boot-starter-data-rest用Spring Data REST公布简单的REST服务

3、Spring Boot 项目的创建方式

创建 Spring Boot 有两种方式:

  • 手动创建一个 Maven 项目,然后添加 Spring Boot 需要的依赖;
  • 通过 Spring Initializr 脚手架创建;

工具环境 IDEA,下文是基于 Spring Initializr 脚手架创建。

通过 IDEA 创建 Spring Boot 项目实在是太简单了:

关于下一步之后,无非就是选择创建项目的方式(Maven/Gradle),Spring Boot 版本(2.2.2.RELEASE),引入的依赖(Web/SQL/NoSQL/Security等),在这就不赘述了。

4、Spring Boot 编译打包

Spring Boot 项目打包无非就 「打 jar 包、打 war 包」 这两种情况,这两者的应用场景不同,各有优缺点。

jar 包部署优点:

  • 无须搭建本地web容器,默认内置 Tomcat 容器,可以直接以 java -jar 形式运行;
  • 因为自带web容器,可以避免由于web容器的差异造成不同环境结果不一致问题。
  • 借助容器化,可以进行大规模的部署。

jar 包部署缺点:

  • jar 应用体积过大「可以参考瘦身指南」
  • 数据源无法通过界面进行管理。
  • 修改web容器相关配置比较困难,需要借助代码实现。

war 包部署优点:

  • 可以借助web容器管理界面对应用进行管理。
  • web容器配置较为灵活,配置和程序分离。「jar包方式其实也可以」
  • 应用体积较小,甚至可以借助web容器的包管理功能进一步减小应用大小。

war 包部署缺点:

  • 本地需要搭建web容器
  • 调试较为困难,需要借助web容器。
  • 部署较为困难

至于最终选择哪个,本文不追究,毕竟都是要根据实际项目来说的。

以打 jar 包为例

首先需要在 pom.xml 文件中配置 spring-boot-maven-plugin 打包插件,也就是我们通常看到的:

<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>

这样就可以在 Tmerinal 控制台通过 maven 命令进行打包了:mvn package

或者是可以直接在 IDEA 右侧的 Maven 标签:

有小伙伴可能好奇,难道不需要设置 <packaging>jar</packaging> 吗?

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">...<packaging>jar</packaging>...
</project>

其实默认的 就是 jar 方式。

5、Spring Boot 多环境配置

通常在实际开发中,往往涉及到好几个环境,比如开发环境、本地环境、测试环境等等,通常不同环境下的配置信息是不一样的「比如端口号?数据库连接信息等」,因为我们每次只能使用一个配置环境,如果频繁的修改配置以达到效果,自然是麻烦的不行,且很容易出错。

而在 Spring Boot 中,我们可以通过 spring.profiles.active 来激活对应的配置文件。

比如创建如下三个文件:

application.yml「主文件」

  • application-dev.yml:开发环境
  • application-local.yml:本地环境
  • application-test.yml:测试环境

我们想要使用 dev 开发环境,只需要在 application.yml 中使用 spring.profiles.active=dev 就可以完成指定:

spring:profiles:active: dev

6、替换内置的 Tomcat 容器

尽管Spring Boot内置了 Tomcat ,但是在高并发场景下的 Tomcat 相对来说比较弱。比如在相同的机器配置下,模拟相等的请求数,Undertow在性能和内存使用方面都是最优的。并且Undertow新版本默认使用持久连接,这将会进一步提高它的并发吞吐能力。所以,如果是高并发的业务系统,Undertow 是最佳选择。

问题是怎么替换?

因为 spring-boot-starter-web 中默认自带的容器是 Tomcat,如果想要替换成 Undertow 也是非常简单的。

首先需要排除 spring-boot-starter-web 包中的 Tomcat,然后单独增加 undertow 容器的依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- 排除Tomcat依赖 --><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions>
</dependency><!-- 添加 Undertow依赖 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

7、配置文件的读取

以前读取 spring 的配置文件,都是通过工具类类读取,其实无非就是读取 xml 文件,比如,通过 ClassPathXmlApplicationContext 加载到文件,然后再通过 上下文拿到 对应的Bean,再取参等。

而在 Spring Boot 中读取配置文件有三种方式:

  1. Environment

  2. @Value

  3. @ConfigurationProperties

我们一一看看这三种方式:

application.yml 中的模拟数据:

niceyoo:name: 张三age: 24
7.1、Environment

Environment 用于管理当前的应用环境信息,定义了获取 Profile 的方法,同时继承了 PropertyResolver,PropertyResolver 提供了属性访问的相关方法。

也就是我们可以使用 Environment 的 getProperty() 方法读取指定配置 Key 的内容。

代码中体现:

@Controller
@RequestMapping(value = "/test")
public class TestController {@Autowiredprivate Environment environment;@PostMapping("/test")@ResponseBodypublic void test(@RequestBody User user) {String name = environment.getProperty("niceyoo.name");Integer age = Integer.valueOf(environment.getProperty("niceyoo.age"));System.out.println(name+" " +age);}
}
7.2、@Value

@Value 方式就简单多了,直接在接收的属性上加上该注解即可:

@Controller
@RequestMapping(value = "/test")
public class TestController {@Value("niceyoo.name")private String name;@Value("niceyoo.age")private Integer age;@PostMapping("/test")@ResponseBodypublic void test(@RequestBody User user) {System.out.println(name+" " +age);}
}
7.3、@ConfigurationProperties

使用该注解可以直接注入到实体类中,方便值的同一管理。

比如我们创建一个 Model 实体类,定义 name、age 属性,然后实现 get\set 方法,再在实体类上加上 @Configuration 和 @ConfigurationProperties(prefix=“niceyoo”) 注解,并指定前缀为 niceyoo。

@Configuration
@ConfigurationProperties(prefix="niceyoo")
public class Model {private String name;private Integer age;省略get、set方法
}

这样就可以将 niceyoo 下面的值直接对应到实体上了,其中加入 @Configuration 注解,我们在使用时可以直接通过 @Autowired 进行注入。

取值代码:

@Controller
@RequestMapping(value = "/test")
public class TestController {@Autowiredprivate Model model;@PostMapping("/test")@ResponseBodypublic void test(@RequestBody User user) {System.out.println(model.getName()+" " +model.getAge());}
}

总结

以前 Spring 主打轻量级应用框架,但随着外界不断地进行扩充,像是 Shiro、Security、MQ、Redis、ElasticSearch 等等等等, 总之就是 Spring 几乎可以做任何事了,但是相应的问题也来了。

Spring 每集成一个第三方软件,就需要手动增加一些配置,随着新软件的加入,以至于需要引入越来越多的配置,且这些配置各玩各的,难以理解,难以管理,我记得我实习时的那家公司就是这样,各种五花八门的配置文件,以至于经常配置出错,然后解决配置相关的问题就需要好久。

工欲善其行,必先利其器。

Spring Boot 的出现可以说真正的颠覆了以前传统的 Web 项目,开发人员再也不用配置繁琐的 xml 文件了,简直是解放了双手,整个项目的配置文件也变得简洁了。

正所谓简洁并不意味着简单,Spring Boot 只是将众多复杂的功能进行了封装,让我们在使用的时候足够的简单。

关于 Spring Boot 的知识点可以说太多太多了,文中只是把自己能想到的几点描述了出来。

欢迎大家在留言区互动,

博客园持续更新,欢迎关注。希望这篇文章对大家有所帮助。

本文首发于博客园:https://www.cnblogs.com/niceyoo/p/14022503.html

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

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

相关文章

前端学习(2859):简单秒杀系统学习之前端界面布局

<html><head><meta charset"utf-8"><link rel"stylesheet" type"text/css" href"miao.min.css" charset"utf-8"><title>秒杀系统</title></head><body><div class"…

Spring Boot 项目瘦身指南,瘦到不可思议!129M->1.3M

之前在 从使用传统Web框架到切换到Spring Boot后的总结 中提到关于 Spring Boot 编译打包&#xff0c;Spring Boot 应用程序不用额外部署到外部容器中&#xff0c;可以直接通过 Maven 命令将项目编译成可执行的 jar 包&#xff0c;然后通过 java -jar 命令启动即可&#xff0c;…

基于Docker搭建RabbitMQ(多图)

1、一点废话&#xff08;可直接跳转至标题2&#xff09; 通常在拉取镜像之前&#xff0c;除了通过命令执行 docker search xxx 之外&#xff0c;我们还可以通过 Docker 镜像仓库查询指定的镜像。 如下是 rabbitmq 镜像的搜索结果&#xff1a; 一般拉取下载数 stars 数相对比…

基于Docker搭建Redis集群(主从集群)

最近陆陆续续有不少园友加我好友咨询 redis 集群搭建的问题&#xff0c;我觉得之前写的这篇 《基于Docker的Redis集群搭建》 文章一定是有问题了&#xff0c;所以我花了几分钟浏览之前的文章总结了下面几个问题&#xff1a; redis 数量太少&#xff0c;只创建了 3 个实例&…

洛达AirPods鉴别检测工具AB153x_UT,支持1562a 1562f

推荐阅读&#xff1a;AB1562_UT软件分辨真假洛达1562A&#xff0c;洛达1562a怎么鉴别&#xff1f; 洛达 1536u 1562a 1562f 1562m 检测工具&#xff0c; 可根据协议检测出实际使用芯片&#xff0c;免拆机检测华强北airpods使用芯片 一、使用方法 蓝牙连接安卓手机后&#x…

AB1562_UT软件分辨真假洛达1562A,洛达1562a怎么鉴别?

一、使用方法 1、下载并安装 AB1562_UT&#xff0c;下载链接 → https://t.1yb.co/kQIC 2、如上图所示&#xff0c;点击顶部的「选择设备」&#xff0c;弹出窗口中选择你的耳机。 3、点击「连接耳机」 4、显示耳机信息 更多测试方法请点击该链接&#xff1a;https://www.cnblo…

MacOS中安装Consul(启动及关闭)

PS&#xff1a;非 brew 安装方式。 官网下载链接&#xff1a;https://www.consul.io/downloads.html 懒得去官网下载&#xff0c;或者官网下载速度慢的可以试一下下方蓝奏云链接。 蓝奏云v1.9.0下载&#xff1a;https://niceyoo.lanzous.com/iUBgwjyd6xa 1、解压并放置指定…

华强北AirPods洛达1562A固件升级教程,带空间音频(艾创力+东莞豪锐)

Hello 大家好&#xff0c;这里是 niceyoo&#xff0c;我是你们的小源。 今天分享的是洛达1562A的固件升级教程。其实一直不想写这篇&#xff0c;主要是怕出现问题&#xff0c;​怎么讲呢&#xff1f;本身刷机这件事是有风险的&#xff0c;就跟手机系统刷机一样&#xff0c;一旦…

集群部署中解决定时任务重复执行的问题-redis分布式锁应用

背景描述 有小伙伴私信我&#xff0c;关于存在定时任务的项目在集群环境下部署如何解决重复执行的问题&#xff0c;PS&#xff1a;定时任务没有单独拆分。 概述&#xff1a;之前的项目都是单机器部署&#xff0c;所以定时任务不会重复消费&#xff0c;只会执行一次。而在集群…

洛达检测软件AB1562UT_1.4.4新版本下载,适用洛达全系列

络达芯片检测调试工具&#xff0c;2020年12月发布的版本&#xff0c;仅支持Android系统手机&#xff1b; 适用于AB1536U,1562A,1562M,1562F。不是络达芯片的不能用&#xff01; 真洛达推荐链接&#xff1a;https://item.taobao.com/item.htm?ftt&id641479139773 一、软件…

支付宝新版SDK-PC扫码支付-手机浏览器H5支付

一、前言 支付宝支付—沙箱环境使用 支付宝新版SDK-PC端扫码支付 手机浏览器H5支付「本文」 PC端扫码支付&#xff0c;其实就是就是 电脑网站支付&#xff0c;本文基于支付宝沙箱环境&#xff0c;不了解的可以看一下上边的链接。 PS&#xff1a;本文是基于支付宝新版 SDK …

华强北耳机修改序列号|支持中英文|自定义修改|傻瓜式一键修改序列号~

软件下载链接>>>&#xff1a;https://t.1yb.co/kQIu 你还在纠结买到的华强北耳机序列号查询不到吗&#xff1f; 你还在纠结因为刷机导致的序列号与充电仓序列号不一致吗&#xff1f; 你还在纠结自己的序列号不够有面吗… 先看一张效果图&#xff1a; 今天分享一下…

CentOS离线安装gcc环境(附安装包+图文并茂)

1、关于gcc linux内核本身不依赖gcc&#xff0c;gcc只是一个编译软件&#xff0c;是在kernel的源码变成可执行文件的时候起作用&#xff0c;真正使用起来就没有什么关系。 查看 gcc 版本 gcc -v 如果没有则显示&#xff1a; 2、安装步骤 2.1、下载gcc安装包 gcc下载地址&…

CentOS7安装redis并配置外网可访问(局域网可参考)

1、安装gcc编辑器 安装redis需要依赖gcc环境&#xff0c;执行如下命令安装&#xff1a; yum install -y gcc如果机器没有网络的话&#xff0c;可以参考这篇文章&#xff1a; CentOS离线安装gcc环境(附安装包图文并茂) 2、下载redis安装包 redis官网&#xff1a;https://re…

悦虎144固件,华强北二代悦虎144固件,1562M芯片144固件

下载地址 https://t.1yb.co/k49w 关于固件 最新的悦虎1562M 144固件&#xff0c;适用于华强北二代悦虎主板&#xff0c;1562M洛达芯片。 关于本次升级&#xff1a;优化功耗&#xff0c;提升续航。