XXL-JOB分布式定时任务框架快速入门

news2024/11/13 22:37:57

文章目录

    • 前言
      • 定时任务
      • 分布式任务调度
    • 1、XXL-JOB介绍
      • 1.1 XXL-JOB概述
      • 1.2 XXL-JOB特性
      • 1.3 整体架构
    • 2、XXL-JOB任务中心环境搭建
      • 2.1 XXL-JOB源码下载
      • 2.2 IDEA导入xxljob工程
      • 2.3 初始化数据库
      • 2.4 Docker安装任务管理中心
    • 3、XXL-JOB任务注册测试
      • 3.1 引入xxl-job核心依赖
      • 3.2 配置xxljob相关信息
      • 3.3 定义定时任务执行方法
      • 3.4 配置任务执行器
      • 3.5 配置任务执行计划
      • 3.6 调度流程
    • 4、CRON表达式入门
      • 4.1 cron表达式介绍
      • 4.2 cron表达式语法介绍
      • 4.3 cron表达式阅读练习
  • 5、总结
    • 5.1 XXL-JOB 执行原理
    • 5.2 XXLO-JOB 工作流程
    • 5.3 如何保证任务不重复执行

前言

定时任务

一般在项目中实现定时任务主要是两种技术方案,一种是Spring Task,另一种是xxl-job,其中Spring Task是适合单体项目中使用,而xxl-job是分布式任务调度框架,更适合在分布式项目中使用。

分布式任务调度

在微服务架构体系中,服务之间通过网络交互来完成业务处理的,在分布式架构下,一个服务往往会部署多个实例来运行我们的业务,如果在这种分布式系统环境下运行任务调度,我们称之为分布式任务调度。

在这里插入图片描述

分布式系统的特点,并且提高任务的调度处理能力:

  • 并行任务调度
    • 并行任务调度实现靠多线程,如果有大量任务需要调度,此时光靠多线程就会有瓶颈了,因为一台计算机CPU的处理能力是有限的。
    • 如果将任务调度程序分布式部署,每个结点还可以部署为集群,这样就可以让多台计算机共同去完成任务调度,我们可以将任务分割为若干个分片,由不同的实例并行执行,来提高任务调度的处理效率。
  • 高可用
    • 若某一个实例宕机,不影响其他实例来执行任务。
  • 弹性扩容
    • 当集群中增加实例就可以提高并执行任务的处理效率。
  • 任务管理与监测
    • 对系统中存在的所有定时任务进行统一的管理及监测。
    • 让开发人员及运维人员能够时刻了解任务执行情况,从而做出快速的应急处理响应。
  • 避免任务重复执行
    • 当任务调度以集群方式部署,同一个任务调度可能会执行多次,比如在电商系统中到点发优惠券的例子,就会发放多次优惠券,对公司造成很多损失,所以我们需要控制相同的任务在多个运行实例上只执行一次。

1、XXL-JOB介绍

1.1 XXL-JOB概述

​ XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。
​ 目前已有多家公司接入xxl-job,包括比较知名的大众点评,京东,优信二手车,北京尚德,360金融 (360),联想集团 (联想),易信 (网易)等;

1.2 XXL-JOB特性

官方地址:http://www.xuxueli.com/xxl-job

在这里插入图片描述

更多详情见官网;

1.3 整体架构

在这里插入图片描述

xxl-job架构图(官图):

在这里插入图片描述

调度中心

  • 负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码;
  • 主要职责为执行器管理、任务管理、监控运维、日志管理等

任务执行器

  • 负责接收调度请求并执行任务逻辑;
  • 只要职责是注册服务、任务执行服务(接收到任务后会放入线程池中的任务队列)、执行结果上报、日志服务等

任务:负责执行具体的业务处理。调度中心与执行器之间的工作流程如下:

在这里插入图片描述

执行流程

  1. 任务执行器根据配置的调度中心的地址,自动注册到调度中心。
  2. 达到任务触发条件,调度中心下发任务。
  3. 执行器基于线程池执行任务,并把执行结果放入内存队列中、把执行日志写入日志文件中。
  4. 执行器消费内存队列中的执行结果,主动上报给调度中心。
  5. 当用户在调度中心查看任务日志,调度中心请求任务执行器,任务执行器读取任务日志文件并返回日志详情。

2、XXL-JOB任务中心环境搭建

2.1 XXL-JOB源码下载

在这里插入图片描述

在这里插入图片描述

考虑到网络原因,我们选择gitee下的开源地址下载:

在这里插入图片描述

选择最新的2.30版本下载.

2.2 IDEA导入xxljob工程

在这里插入图片描述

2.3 初始化数据库

数据库脚本:https://gitee.com/xuxueli0323/xxl-job/blob/2.3.0/doc/db/tables_xxl_job.sql

将xxljob提供的SQL脚本导入到mysql容器服务中:

在这里插入图片描述

整体如下:

在这里插入图片描述

  • xxl_job_lock:任务调度锁表;
  • xxl_job_group:执行器信息表,维护任务执行器信息;
  • xxl_job_info:调度扩展信息表: 用于保存XXL-JOB调度任务的扩展信息,如任务分组、任务名、机器地址、执行器、执行入参和报警邮件等等;
  • xxl_job_log:调度日志表: 用于保存XXL-JOB任务调度的历史信息,如调度结果、执行结果、调度入参、调度机器和执行器等等;
  • xxl_job_log_report:调度日志报表:用户存储XXL-JOB任务调度日志的报表,调度中心报表功能页面会用到;
  • xxl_job_logglue:任务GLUE日志:用于保存GLUE更新历史,用于支持GLUE的版本回溯功能;
  • xxl_job_registry:执行器注册表,维护在线的执行器和调度中心机器地址信息;
  • xxl_job_user:系统用户表;

注意:

如果表xxl_job_registry导入过程报Specified key was too long; max key length is 767 bytes错误,则将i_g_k_v联合索引相关字段的varchar改小一些即可;

2.4 Docker安装任务管理中心

拉取xxl-job-admin任务中心镜像:

docker pull xuxueli/xxl-job-admin:2.3.0

启动xxl-job任务中心容器:

# 在指定目录构建xxldata目录,然后运行如下docker指令:
docker run -e PARAMS="--spring.datasource.url=jdbc:mysql://192.168.200.128:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=UTC --spring.datasource.username=root --spring.datasource.password=root" -p 8093:8080  -v $PWD/xxldata:/data/applogs --name=xxl-job-admin -d xuxueli/xxl-job-admin:2.3.0


docker run -e PARAMS="--spring.datasource.url=jdbc:mysql://192.168.20.128:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=UTC --spring.datasource.username=root --spring.datasource.password=1234" -p 8093:8080  -v $PWD/xxldata:/data/applogs --name=xxl-job-admin -d xuxueli/xxl-job-admin:2.3.0

访问容器服务:

http://192.168.200.128:8093/xxl-job-admin

效果如下:

在这里插入图片描述

登录进入后效果:

在这里插入图片描述

注意:Docker服务重启时,保证对应的mysql服务启动,否则任务信息无法加载!

3、XXL-JOB任务注册测试

3.1 引入xxl-job核心依赖

通过官方提供的xxljob代码,我们可知道在xxl-job-executor-sample-springboot工程中引入和xxljob的核心依赖:

<!-- xxl-job-core -->
<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>${project.parent.version}</version>
</dependency>

将来我们的项目也可通过这种方式集成xxl-job

3.2 配置xxljob相关信息

接下来就是配置任务工程信息:

在这里插入图片描述

配置完毕后,工程底层通过XxlJobConfig配置类加载配置信息,实现xxljob相关资源的初始化工作:

package com.xxl.job.executor.core.config;
@Configuration
public class XxlJobConfig {
    private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);

    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;

    @Value("${xxl.job.accessToken}")
    private String accessToken;

    @Value("${xxl.job.executor.appname}")
    private String appname;

    @Value("${xxl.job.executor.address}")
    private String address;

    @Value("${xxl.job.executor.ip}")
    private String ip;

    @Value("${xxl.job.executor.port}")
    private int port;

    @Value("${xxl.job.executor.logpath}")
    private String logPath;

    @Value("${xxl.job.executor.logretentiondays}")
    private int logRetentionDays;
    @Bean
    public XxlJobSpringExecutor xxlJobExecutor() {
        logger.info(">>>>>>>>>>> xxl-job config init.");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
        xxlJobSpringExecutor.setAppname(appname);
        xxlJobSpringExecutor.setAddress(address);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
        return xxlJobSpringExecutor;
    }
}

3.3 定义定时任务执行方法

package com.xxl.job.executor.service.jobhandler;
@Component
public class SampleXxlJob {
    private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);


    /**
     * 1、简单任务示例(Bean模式)
     */
    @XxlJob("demoJobHandler")
    public void demoJobHandler() throws Exception {
       //todo 打印时间
       System.out.println("hello xxljob.....");
    }

	//.....省略......

    /**
     * 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;
     */
    @XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
    public void demoJobHandler2() throws Exception {
        XxlJobHelper.log("XXL-JOB, Hello World.");
    }
    public void init(){
        logger.info("init");
    }
    public void destroy(){
        logger.info("destory");
    }
}

说明:

@XxlJob中的value值就是定时任务的一个标识,注解作用的方法就是定时任务要执行逻辑的逻辑方法;

3.4 配置任务执行器

在这里插入图片描述

注意:如果自动注册不识别,可手动录入执行服务地址,格式比如:http://192.168.200.1:9999

3.5 配置任务执行计划

接下来,我们将xxl-job-executor-sample-springboot工程下的demoJobHandler任务,可视化配置,并启动:

在这里插入图片描述

接下来,输入JobHanler,输入的名称保证与@xxljob注解下的value值一致即可:

在这里插入图片描述

xxl-job支持的路由策略非常丰富:

  • FIRST(第一个):固定选择第一个机器;

  • LAST(最后一个):固定选择最后一个机器;

  • ROUND(轮询):在线的机器按照顺序一次执行一个

  • RANDOM(随机):随机选择在线的机器;

  • CONSISTENT_HASH(一致性HASH):每个任务按照Hash算法固定选择某一台机器,且所有任务均匀散列在不同机器上。

  • LEAST_FREQUENTLY_USED(最不经常使用):使用频率最低的机器优先被选举;

  • LEAST_RECENTLY_USED(最近最久未使用):最久未使用的机器优先被选举;

  • FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度;

  • BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度;

  • SHARDING_BROADCAST(分片广播):广播触发对应集群中所有机器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务;

    XL-JOB并不直接提供数据处理的功能,它只会给执行器分配好分片序号,在向执行器任务调度的同时下发分片总数以及分片序号等参数,执行器收到这些参数根据自己的业务需求去利用这些参数。

    分片广播下可以配合如下参数设置合理的调度策略(最简单的如:取模拆分)。

    // 分片节点总数
    int shardTotal = XxlJobHelper.getShardTotal();
    // 当前节点下标,从0开始
    int shardIndex = XxlJobHelper.getShardIndex();
    

还有一些其他参数配置的解析:

  • 子任务:每个任务都拥有一个唯一的任务ID(任务ID可以从任务列表获取),当本任务执行结束并且执行成功时,将会触发子任务ID所对应的任务的一次主动调度,通过子任务可以实现一个任务执行完成去执行另一个任务。
  • 调度过期策略:
    • 忽略:调度过期后,忽略过期的任务,从当前时间开始重新计算下次触发时间;
    • 立即执行一次:调度过期后,立即执行一次,并从当前时间开始重新计算下次触发时间;
  • 阻塞处理策略: 调度过于密集执行器来不及处理时的处理策略;
    • 单机串行(默认):调度请求进入单机执行器后,调度请求进入FIFO队列并以串行方式运行;
    • 丢弃后续调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,本次请求将会被丢弃并标记为失败;
    • 覆盖之前调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,将会终止运行中的调度任务并清空队列,然后运行本地调度任务;
  • 任务超时时间: 支持自定义任务超时时间,任务运行超时将会主动中断任务;
  • 失败重试次数; 支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;

在这里插入图片描述

启动任务查看执行效果:

在这里插入图片描述

在这里插入图片描述

当然,我们也可以随时停止正在被执行的任务;

3.6 调度流程

在这里插入图片描述

4、CRON表达式入门

4.1 cron表达式介绍

cron表达式类似就java中的正则,通过cron表达式可定义周期性的任务计划。

许多开源的定时任务框架大多支持cron表达式;

4.2 cron表达式语法介绍

​ xxl-job同样支持通过cron表达式来控制任务周期性调度执行表达式包含7个部分:分别从秒、分、时、日、月、星期、年七个时间维度来定义任务执行的周期;

cron表达式时间取值范围:

cron表达式格式:
*    *    *    *    *    *    *
-    -    -    -    -    -    -
|    |    |    |    |    |    |
|    |    |    |    |    |    + year [optional]
|    |    |    |    |    +----- day of week (1 - 7|    |    |    |    +---------- month (1 - 12)
|    |    |    +--------------- day of month (1 - 31)
|    |    +-------------------- hour (0 - 23)
|    +------------------------- min (0 - 59)
+------------------------------ second (0 - 59)
字段允许值允许的特殊字符
0-59, - * /
0-59, - * /
小时0-23, - * /
月内日期1-31, - * ? / L W C
1-12 或者 JAN-DEC, - * /
周内日期1-7 或者 SUN-SAT(注意:周日是1,周一为2,周六位7, - * ? / L C #
年(可选)留空, 1970-2099, - * /

特殊字段含义:

特殊字符意义
*匹配所有的值。如:*在分钟的字段域里表示 每分钟
?只在日期域和星期域中使用。它被用来指定“非明确的值” 不关心
-指定一个范围。如:“10-12”在小时域意味着“10点、11点、12点”
,指定几个可选值。如:“MON,WED,FRI”在星期域里表示“星期一、星期三、星期五”
/指定增量。如:“0/15”在秒域意思是每分钟的0,15,30和45秒。“5/15”在分钟域表示每小时的5,20,35和50。符号“”在“/”前面(如:/10)等价于0在“/”前面(如:0/10)
L表示day-of-month和day-of-week域,但在两个字段中的意思不同,例如day-of-month域中表示一个月的最后一天。如果在day-of-week域表示‘7’或者‘SAT’,如果在day-of-week域中前面加上数字,它表示一个月的最后几天,例如‘6L’就表示一个月的最后一个星期五(在西方,周末索引位为1,那么周一就是2,其它一次类推)
W只允许日期域出现。这个字符用于指定日期的最近工作日。例如:如果你在日期域中写 “15W”,表示:这个月15号最近的工作日。所以,如果15号是周六,则任务会在14号触发。如果15好是周日,则任务会在周一也就是16号触发。如果是在日期域填写“1W”即使1号是周六,那么任务也只会在下周一,也就是3号触发,“W”字符指定的最近工作日是不能够跨月份的。字符“W”只能配合一个单独的数值使用,不能够是一个数字段,如:1-15W是错误的
LWL和W可以在日期域中联合使用,LW表示这个月最后一周的工作日
#只允许在星期域中出现。这个字符用于指定本月的某某天。例如:“6#3”表示本月第三周的星期五(6表示星期五,3表示第三周)。“2#1”表示本月第一周的星期一。“4#5”表示第五周的星期三

参考cron在线表达式:https://www.matools.com/cron/

4.3 cron表达式阅读练习

(1)0 0 2 1 * ? 表示在每月的1日的凌晨2点调整任务

(2)0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业 ★★★

(3)0 15 10 ? 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作

(4)0 0 10,14,16 * * ? 每天上午10点,下午2点,4点

(5)0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时

(6)0 0 12 ? * WED 表示每个星期三中午12点

(7)0 15 10 * * ? 每天上午10:15触发

(8)0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发

(9)0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发

(10)0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发

(12)0 15 10 L * ? 每月最后一日的上午10:15触发

(13)0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发

5、总结

知识梳理:

5.1 XXL-JOB 执行原理

XXL-JOB 分布式任务调度服务由调度中心和执行器组成,调用中心负责按任务调度策略向执行器下发任务,执行器负责接收任务并执行。

5.2 XXLO-JOB 工作流程

  1. 首先部署并启动xxl-job调度中心。(一个java工程)
  2. 首先在微服务添加xxl-job依赖,在微服务中配置执行器
  3. 启动微服务,执行器向调度中心上报自己。
  4. 在微服务中写一个任务方法并用xxl-job的注解去标记执行任务的方法名称。
  5. 在调度中心配置任务调度策略,调度策略就是每隔多长时间执行还是在每天或每月的固定时间去执行,比如每天0点执行,或每隔1小时执行一次等。
  6. 在调度中心启动任务。
  7. 调度中心根据任务调度策略,到达时间就开始下发任务给执行器。
  8. 执行器收到任务就开始执行任务。

5.3 如何保证任务不重复执行

  1. 调度中心按分片广播的方式去下发任务
  2. 执行器收到作业分片广播的参数:分片总数和分片序号,计算 任务id 除以 分片总数得到一个余数,如果余数等于分片序号这时就去执行这个任务,这里保证了不同的执行器执行不同的任务。
  3. 配置调度过期策略为“忽略”,避免同一个执行器多次重复执行同一个任务
  4. 配置任务阻塞处理策略为“丢弃后续调度”,注意:丢弃也没事下一次调度就又可以执行了
  5. 另外还要保证任务处理的幂等性,执行过的任务可以打一个状态标记已完成,下次再调度执行该任务判断该任务已完成就不再执行

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

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

相关文章

rust 编译时报错:type annotations needed for Box

如下图所示&#xff1a; 解决方法&#xff1a; 升级time的版本&#xff1a; cargo update -p time

【Python基础】Python入门基础教程(非常详细){附带源码}

引言 Python 是一种广泛使用的高级编程语言&#xff0c;因其简洁的语法和强大的功能库而受到开发者的喜爱。本教程将带你从零开始&#xff0c;逐步掌握 Python 的基础知识&#xff0c;并通过附带的源码和表格来加深理解。 点击免费领取《CSDN大礼包》&#xff1a;Python入门到…

c语言基础知识详解,c语言入门必看

在线书籍&#xff1a;54笨鸟 前言 C 语言是一门抽象的、面向过程的语言&#xff0c;C 语言广泛应用于底层开发&#xff0c;C 语言在计算机体系中占据着不可替代的作用&#xff0c;可以说 C 语言是编程的基础&#xff0c;也就是说&#xff0c;不管你学习任何语言&#xff0c;都…

最详细!教你学习haproxy七层代理

一、工作原理 &#xff08;1&#xff09;包括 监听端口&#xff1a;HAProxy 会在指定的端口上监听客户端的请求。 例如&#xff0c;它可以监听常见的 HTTP 和 HTTPS 端口&#xff0c;等待客户端连接。请求接收&#xff1a;当客户端发起请求时&#xff0c;HAProxy 接收到请求。…

Gin框架接入pyroscope完美替代pprof实现检测内存泄露

传统检测内存泄露可以看一下我这篇文章Gin框架接入Prometheus,grafana辅助pprof检测内存泄露-CSDN博客 pyroscope被Grafana收购,GPT来总结一下pyroscope的强大之处&#x1f436; pyroscope github地址 pyroscope与grafana的安装 docker compose安装&#xff0c;这里我们其实…

GET和POST这两种常用的HTTP请求方法的区别

GET和POST是HTTP协议中最常用的两种请求方法&#xff0c;它们在使用场景、安全性、数据传输等方面有很大的不同。让我从以下几个方面来比较GET和POST&#xff1a; 1.「用途和语义」 「GET」: 主要用于获取资源 应该是幂等的&#xff0c;即多次请求应该返回相同的结果 通常用…

超详细!!!electron-vite-vue开发桌面应用之开启调试工具(二)

云风网 云风笔记 云风知识库 上篇已经初步搭建完项目&#xff0c;这次配置比较重要的一部分&#xff0c;那就是开启调试工具&#xff0c;这是开发项目比较重要且基础的部分 vite.config.ts配置更新 main: {// Shortcut of build.lib.entry.entry: electron/main.ts,onstart(ar…

2003-2023年高铁数据高铁开通时间数据

2003-2023年高铁数据高铁开通时间数据 1、时间&#xff1a;2003-2023年 2、来源&#xff1a;整理自高铁航线数据库&#xff08;Chinese High-speed Rail and Airline Database&#xff0c;CRAD&#xff09; 3、指标&#xff1a;高铁站名称、开通时间、所在省份、所在城市、所…

通过网关将数据上传到两台eqmx服务器上

我们是通过WAN 来读取数据。 线连接以后打开 然后要配置上去服务器 在这里遇到的问题是我自己搭emqx服务器的时候&#xff0c;没有固定ip地址&#xff0c;这个ip地址要通过ipconfig来获取&#xff0c;然后将其设置为静态IP地址&#xff0c;才可以的。让后emqx服务器还要重新启…

美股开户:新手投资者的完整入门教程

炒美股是许多投资者心中的梦想&#xff0c;但对于新手小白来说&#xff0c;如何开户炒美股可能会显得有些复杂和困难。本文将为您提供一份完整的入门教程&#xff0c;详细介绍从选择券商到完成开户的步骤&#xff0c;帮助您顺利进入美股市场。 选择合适的券商 在开户之前&…

【Linux基础】Linux中的开发工具(1)--yum和vim

目录 ✈️前言一&#xff0c;Linux 软件包管理器 yum1. 什么是软件包2. 如何安装软件3. 如何卸载软件 二&#xff0c;Linux编辑器-vim使用1. vim的基本概念1.1 命令/正常/普通模式1.2 插入模式1.3 底行模式 三&#xff0c;vim命令模式命令集1. 移动光标2. 删除字符3. 复制4. 替…

后端调优——分布式锁选型——入门

文章目录 引言正文分布式锁的定义分布式锁的具体应用场景如何实现分布式锁主动轮询型分布式锁实现思路一、MySQL分布式锁二、Redis分布式锁 监听回调型分布式锁Etcd分布式锁Zookeeper分布式锁 锁的对比 总结 引言 最近面试&#xff0c;一直被问到分布式锁&#xff0c;然后仅仅…

基于Martin实现MapboxGL自定义底图

概述 本文分享基于Martin实现MapboxGL底图的自定义。 实现后效果 Martin简介 Martin 是一个瓦片服务器&#xff0c;它能够从 PostGIS 数据库、PMTiles&#xff08;本地或远程&#xff09;以及 [MBTiles] (https://github.com/mapbox/mbtiles-spec) 文件中快速生成并提供矢量瓦…

七人共享拼团:社交电商的裂变新引擎

在当今电商市场中&#xff0c;七人共享拼团模式以其独特的社交属性和裂变机制&#xff0c;正成为一股不可忽视的力量。这一模式巧妙融合了社交电商的互动性与拼购的实惠性&#xff0c;通过平台利润回馈用户的方式&#xff0c;构建了一个既人性化又高效的奖励体系&#xff0c;旨…

QT 添加程序图标

1. 使用免费网站将其他图片格式转化成ico格式 Ico转换器 &#xff1a; https://cn.free-converter.com/ico-converter 2.qmake项目添加程序图标 在.pro文件内添加语句,如下图 RC_ICONS favicon.ico2.1 程序图标文件添加到项目目录内 2.2 通过windeployqt xxx.exe构建生成的…

动手研发实时口译系统

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…

一文通晓 AI 框架

首先深度学习是机器学习研究领域中的一种范式&#xff0c;而深度学习的概念源于对人工神经网络的研究&#xff0c;很多深度学习算法都使用神经网络进行表示&#xff0c;因为神经网络的性能精度和通用效果都非常好&#xff0c;于是业界习惯性地把深度学习算法等同于 AI。 深度学…

GNSS位移监测站:高精度、高稳定性、高安全性

在现代工程与自然灾害监测领域&#xff0c;GNSS位移监测站以其卓越的功能优势&#xff0c;正逐步成为守护安全、预防灾害的重要工具。其采用的直径114mm加强型立杆&#xff0c;不仅坚固耐用&#xff0c;更严格遵循《地质灾害专群结合监测领警技术指南&#xff08;试行&#xff…

企业建设零信任体系的核心思路

根据安全牛的调查研究发现&#xff0c;零信任安全理念已经较广泛得到国内各类型企业用户的认可&#xff0c;组织对应用零信任进行网络安全建设已经初具信心&#xff0c;零信任理念对网络安全防护工作的价值开始多方面的展现。 企业开展零信任网络建设的需求和驱动因素 本次调…

86.SAP ME工艺路线打开错误

目录 1.SAP ME工艺路线维护界面 2.错误情况 3.解决方法 1.SAP ME工艺路线维护界面 这个功能设计采用jnlp的方式打开&#xff0c;JNLP&#xff08;Java Network Launching Protocol &#xff09;是java提供的一种可以通过浏览器直接执行java应用程序的途径&#xff0c;它使你…