做搜狗网站优化/seo优化培训公司
文章目录
- 需求
- 一、考虑方案
- 二、实现思路
- 三、代码实现
- 3.1 引入xxl-core 核心包
- 3.2 远程调用
- 3.2.0 yaml
- 3.2.1 配置类
- 3.2.2 入参
- 3.2.3 任务返回实体
- 3.2.4 任务调用
- 3.3 cron生成器
- 3.4 handler实现
- 3.4 测试
- 踩坑
需求
类似预约会议,设置提醒
- 添加数据记录(会议开始时间、会议开始前xx分钟提醒会议人员参会)
- 开启一个定时任务(从开始时间算,前xx分钟出发一次性任务)
- 定时任务执行后需要删除该任务(不然会堆积大量无效任务)
特点:动态创建任务(无法硬编码设置任务@Scheduled
)、任务只执行一次后丢弃
一、考虑方案
- redis 订阅发布过期提醒
pass: redis 服务器密码没找到 /(ㄒoㄒ)/~~ - 定时任务每分钟查询当前时间需要执行的数据去发短信
太耗费资源 - xxljob 动态创建任务 任务执行完毕后销毁
就这个吧
二、实现思路
- gitee上下载个不要钱的源码 xxl-job
- 本地先跑起来,换换数据库驱动,导表,修改一下数据库连接等
- 会议服务引入xxl-job core 核心包
- 根据xxl-job 接口地址和参数,远程调用创建任务、开始任务、删除任务等操作
- 根据业务创建corn生成器 给xxl-job做参数
三、代码实现
3.1 引入xxl-core 核心包
<dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.4.2-SNAPSHOT</version>
</dependency>
3.2 远程调用
3.2.0 yaml
xxl:job:userName: adminpassword: 123456accessToken: default_token # #调度中心通讯TOKEN [选填]:非空时启用 对应xxl-job 配置文件中的xxl.job.accessTokenadmin:addresses: http://127.0.0.1:8080/xxl-job-admin #xxljob调度中心部署 例如:http://127.0.0.1:8080/xxl-job-adminexecutor:appname: xxl-job-pd #xxljob配置的执行器名称,ip: #执行器IP,默认为空表示自动获取IPport: 9999 #xxljob配置的端口号,默认为9999logpath: /data/xxl-job/jobhandler #执行器运行日志文件存储磁盘路径logretentiondays: -1 #调度中心日志表数据保存天数,过期日志自动清理;限制大于等于7时生效,否则, 如-1,关闭自动清理功能
3.2.1 配置类
package com.gsafety.bg.pd.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Data
@Component
@ConfigurationProperties(prefix = "xxl.job")
public class XxlJobProperties {private String userName;private String password;private String accessToken;private Admin admin;private Executor executor;@Datapublic static class Admin {private String addresses;}@Datapublic static class Executor {private String appname;private String ip;private Integer port;private String logpath;private Integer logretentiondays;}
}
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.annotation.Resource;/*** @ClassName: XxlJobConfig* @Description: xxl_job配置类*/
@Configuration
public class XxlJobConfig {@Resourceprivate XxlJobProperties properties;@Beanpublic XxlJobSpringExecutor xxlJobExecutor() {XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();xxlJobSpringExecutor.setAdminAddresses(properties.getAdmin().getAddresses());xxlJobSpringExecutor.setAppname(properties.getExecutor().getAppname());xxlJobSpringExecutor.setIp(properties.getExecutor().getIp());xxlJobSpringExecutor.setPort(properties.getExecutor().getPort());xxlJobSpringExecutor.setAccessToken(properties.getAccessToken());xxlJobSpringExecutor.setLogPath(properties.getExecutor().getLogpath());xxlJobSpringExecutor.setLogRetentionDays(properties.getExecutor().getLogretentiondays());return xxlJobSpringExecutor;}
}
3.2.2 入参
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.time.LocalDateTime;
import java.util.Date;/*** xxl-job info* @author xuxueli 2016-1-12 18:25:49*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class XxlJobReq {private String jobDesc;//任务描述private String author;// 负责人private String executorParam;// 执行器,任务参数private LocalDateTime startTime; //计划时间private long hour; //计划时间前 hour小时后执行private long min; //计划时间前 min分钟后执行
}
3.2.3 任务返回实体
import lombok.Data;@Data
public class ReturnT {private int code;private String msg;private int content;}
3.2.4 任务调用
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gsafety.bg.gsdss.common.utils.json.JsonUtil;
import com.gsafety.bg.pd.config.XxlJobProperties;
import com.gsafety.bg.pd.model.dto.req.XxlJobReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;import javax.annotation.Resource;
import java.io.IOException;
import java.net.HttpCookie;
import java.util.*;/*** @Description: xxljob工具类*/@Slf4j
@Configuration
public class XxlJobService {//该MAP主要用于缓存Xxl-Job的Cookieprivate static Map<String, String> loginCookie = new HashMap<>();@Resourceprivate XxlJobProperties properties;public Map<String, Object> createFormData(XxlJobReq xxlJob) {Map<String, Object> formData = new HashMap<>();formData.put("jobGroup", 2); //xxl_job_group表对应的组formData.put("jobDesc", xxlJob.getJobDesc()); //任务名称formData.put("author", xxlJob.getAuthor()); //用户姓名formData.put("alarmEmail", "");formData.put("scheduleType", "CRON");formData.put("scheduleConf", CronGenerator.cronStr(xxlJob.getStartTime(),xxlJob.getHour(),xxlJob.getMin())); //cron表达式formData.put("schedule_conf_CRON", "");formData.put("schedule_conf_FIX_RATE", "");formData.put("schedule_conf_FIX_DELAY", "");formData.put("glueType", "BEAN");formData.put("executorHandler", "msgJobHandler");//写死了,有多个处理可以用传参方式formData.put("executorParam", xxlJob.getExecutorParam()); //传json文件的保存路径formData.put("executorRouteStrategy", "FIRST");formData.put("childJobId", "");formData.put("misfireStrategy", "DO_NOTHING");formData.put("executorBlockStrategy", "SERIAL_EXECUTION");formData.put("executorTimeout", "0");formData.put("executorFailRetryCount", "0");formData.put("glueRemark", "GLUE代码初始化");formData.put("glueSource", "");//构建好以后调用XxlJobClient的addJob方法并传递formData参数,这个类及方法的实现在下面return formData;}//添加定时任务public Integer addJob(XxlJobReq xxlJob) {//这里的url接口路径一定要是自己F12抓取到的HttpRequest request = HttpRequest.post(properties.getAdmin().getAddresses() + "/jobinfo/add").header("Content-Type", "multipart/form-data")//每次请求都需要带上Cookie,getCookie方法在后面.header("Cookie", getCookie()).form(createFormData(xxlJob));try {// 执行 HTTP POST 请求创建定时任务HttpResponse response = request.execute();String result = response.body();if (StrUtil.isNotBlank(result) && 200 == response.getStatus()) {//定时任务创建成功后拿到任务idReturnT obj = JsonUtil.of(result, ReturnT.class);log.info("定时任务创建成功,任务ID为:" + obj.toString());return obj.getContent();} else {log.error("定时任务创建失败");}} catch (Exception e) {log.info("定时任务创建失败,发生异常:" + e.getMessage());}return null;}//启动定时任务public void startJob(Integer jobId) {//创建后的定时任务默认是STOP状态,所以我们还要通过定时任务id调度任务启动接口HttpRequest requests = HttpRequest.post(properties.getAdmin().getAddresses() + "/jobinfo/start").header("Content-Type", "multipart/form-data").header("Cookie", getCookie()).form("id", jobId);//通过HTTP请求启动定时任务HttpResponse responses = requests.execute();String results = responses.body();if (StrUtil.isNotBlank(results) && 200 == responses.getStatus()) {log.info("定时任务{}启动成功。", jobId);} else {log.error("定时任务{}启动失败。", jobId);}}//停止定时任务public void stopJob(Integer jobId) {//通过定时任务id调度任务停止接口HttpRequest requests = HttpRequest.post(properties.getAdmin().getAddresses() + "/jobinfo/stop").header("Content-Type", "multipart/form-data").header("Cookie", getCookie()).form("id", jobId);//通过HTTP请求停止定时任务HttpResponse responses = requests.execute();String results = responses.body();if (StrUtil.isNotBlank(results) && 200 == responses.getStatus()) {log.info("定时任务{}停止成功。", jobId);} else {log.error("定时任务{}停止失败。", jobId);}}/*** 2.查询定时任务:* 因为是动态实时创建定时任务,所以建议单独创建一个执行器去执行这些定时任务,方便后续批量进行查询出来进行删除。* 这里入参执行器ID,通过执行器ID来查询该执行器下所有Stop状态的定时任务,因为Xxl-job定时任务默认*在执行完最后一次任务后就会自动进入STOP状态,这样查询出来所有STOP状态任务后方便我们后续进行删除清理定时任务。*/public List<Long> SelectJob(Integer jobGroup) {HttpRequest request = HttpRequest.post(properties.getAdmin().getAddresses() + "/jobinfo/pageList").header("Content-Type", "multipart/form-data").header("Cookie", getCookie()).form("jobGroup", jobGroup).form("triggerStatus", 0).form("start", 0);//执行 HTTP POST 请求启动定时任务HttpResponse response = request.execute();// 解析响应体ObjectMapper mapper = new ObjectMapper();List<Long> idList = new LinkedList<>();try {JsonNode responseNode = mapper.readTree(response.body());JsonNode dataNode = responseNode.get("data");//遍历删除id对应的定时任务if (dataNode.isArray()) {for (JsonNode node : dataNode) {Long id = node.get("id").asLong();idList.add(id);}}} catch (IOException e) {System.out.println("解析响应体时发生异常:" + e.getMessage());}return idList;}/*** 3.删除定时任务:* Xxl-job目前没有没有直接批量进行删除定时任务的,所以我们使用遍历去挨个删除,如果考虑到性能问题,单独创建一个定时来调用该删除方法即可,每天凌晨去执行该删除清理的定时任务。*/public void removalJob(List<Long> idList) {for (Long id : idList) {HttpRequest requests = HttpRequest.post(properties.getAdmin().getAddresses() + "/jobinfo/remove").header("Content-Type", "multipart/form-data").header("Cookie", getCookie()).form("id", id);//执行HTTP请求删除定时任务HttpResponse response = requests.execute();if (StrUtil.isNotBlank(response.body()) && 200 == response.getStatus()) {log.info("定时任务{}删除成功。", id);} else {log.error("定时任务{}删除失败。", id);}}}//获取Cookiepublic String getCookie() {for (int i = 0; i < 3; i++) {String cookieStr = loginCookie.get("XXL_JOB_LOGIN_IDENTITY");if (cookieStr != null) {return "XXL_JOB_LOGIN_IDENTITY=" + cookieStr;}login();}throw new RuntimeException("获取 xxl-job cookie 失败!");}//优先到MAP缓存中获取,如果没有获取到则会请求xxljob的登录来获取Cookie,这里提供三次失败可重试。public void login() {String url = properties.getAdmin().getAddresses()+"/login";HttpResponse response = HttpRequest.post(url).form("userName", properties.getUserName()).form("password", properties.getPassword()).execute();List<HttpCookie> cookies = response.getCookies();Optional<HttpCookie> cookieOpt = cookies.stream().filter(cookie -> cookie.getName().equals("XXL_JOB_LOGIN_IDENTITY")).findFirst();if (!cookieOpt.isPresent())throw new RuntimeException("获取 xxl-job cookie 失败!");String value = cookieOpt.get().getValue();loginCookie.put("XXL_JOB_LOGIN_IDENTITY", value);}}
3.3 cron生成器
import lombok.extern.slf4j.Slf4j;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;@Slf4j
public class CronGenerator {public static String cronStr(LocalDateTime baseTime,long h,long m) {// 计算计划时间h小时m分钟后的时间点LocalDateTime delayTime = baseTime.plusHours(h).plusMinutes(m);// 创建Cron表达式String cronExpression = generateCronExpression(delayTime);log.info("Cron expression for [h] hours and [m] minutes from baseTime: " + cronExpression);return cronExpression;}public static String generateCronExpression(LocalDateTime dateTime) {// 将LocalDateTime转换为Cron表达式的格式DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ss mm HH dd MM ? yyyy");// 生成Cron表达式return dateTime.format(formatter);}
}
3.4 handler实现
package com.gsafety.bg.pd.service.job;import com.xxl.job.core.context.XxlJobContext;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import java.util.List;@Component
@Slf4j
public class JobHandlers {private XxlJobService xxlJobService;@XxlJob("msgJobHandler")public void msgJobHandler() {XxlJobHelper.log("XXL-JOB, msgJobHandler.");String jobParam = XxlJobContext.getXxlJobContext().getJobParam();log.info("任务参数: " + jobParam);XxlJobHelper.log("任务参数: " + jobParam);//解析必要参数后发送提醒,参数按业务需要传入,这里就可以接收到}@XxlJob("clearJobHandler")public void clearJobHandler() {XxlJobHelper.log("XXL-JOB, clearJobHandler.");List<Long> jobIds = xxlJobService.SelectJob(2);xxlJobService.removalJob(jobIds);XxlJobHelper.log("清理任务: " + jobIds);}
}
3.4 测试
@PostMapping("v1/test")public String test(@RequestBody @Valid XxlJobReq xxlJob){Integer jobId = xxlJobService.addJob(xxlJob);xxlJobService.startJob(jobId);return jobId.toString();}
踩坑
- 代码暂时还没有设置清理无效任务,可设置定时任务,每天定时执行
clearJobHandler
即可。 - corn 通常为周期性任务,设置一次性任务可以直接指定年月日时间即可
例如:CRON:00 56 15 16 07 ? 2024
,即2024-07-06 15:56:00执行一次,执行后xxljob会自动将任务stop - 开发环境和本地调试
xxljob bean方式执行任务,任务会自动注册到xxljob,可点击注册节点查看注册的ip,如果开发环境和本地不通,那么部署在开发环境服务器的xxljob会找不到你本地的服务,任务会执行失败。要确保注册到xxljob的ip是其可以访问到的ip。如果已经注册了访问不到的ip,可以清一下xxl_job_registry
表中对应的ip记录。
相关文章:

xxl-job 动态创建一次性定时任务
文章目录 需求一、考虑方案二、实现思路三、代码实现3.1 引入xxl-core 核心包3.2 远程调用3.2.0 yaml3.2.1 配置类3.2.2 入参3.2.3 任务返回实体3.2.4 任务调用 3.3 cron生成器3.4 handler实现3.4 测试 踩坑 需求 类似预约会议,设置提醒 添加数据记录(…...

网页制作技术:概念、现状与展望?
网页制作技术:概念、现状与展望? 李升伟 网页制作技术是指用于创建和维护网站的一系列技术和方法。 概念: 它涉及多个方面,包括使用 HTML(超文本标记语言)来构建网页的结构和内容,使用 CSS&…...

Kafka Producer之数据重复和乱序问题
文章目录 1. 数据重复2. 数据乱序 为了可靠性,Kafka有消息重试机制,但是同时也带来了2大问题 1. 数据重复 消息发送到broker后,broker记录消息数据到log中,但是由于网络问题,producer没有收到acks,于是再次…...

Java前后端分离开发的步骤以及注意事项
在现代Web应用程序开发中,前后端分离是一种常见的架构模式。这种模式将前端(用户界面)和后端(业务逻辑和数据处理)分开独立开发和部署,从而提高开发效率、代码的可维护性和团队协作能力。本文将介绍Java前后…...

C#绘制阻抗圆图初步
阻抗圆图,或者叫史密斯图,是无线电设计方面用的; 基本的阻抗圆图如下, 下面尝试用C#能不能画一下; 先在网上找一个画坐标的C#类,它的效果如下; 自己再增加一个函数,可以绘制中心在…...

【STC89C51单片机】定时器/计数器的理解
目录 定时器/计数器1. 定时器怎么定时简单理解(加1经过了多少时间)什么是时钟周期什么是机器周期 2.如何设置定时基本结构相关寄存器1. TMOD寄存器2. TCON寄存器 代码示例 定时器/计数器 STC89C51单片机的定时器和计数器(Timers and Counter…...

数据建模标准-关系建模
数据模型定义:DAMA数据治理体系中将数据模型定义为一种文档形式,数据模型是用来将数据需求从业务传递到IT,以及在IT内部从分析师、建模师和架构师到数据库设计人员和开发人员的主要媒介; 作用:记录数据需求和建模过程中产生的数据…...

Qt日志库QsLog使用教程
前言 最近项目中需要用到日志库。上一次项目中用到了log4qt库,这个库有个麻烦的点是要配置config文件,所以这次切换到了QsLog。用了后这个库的感受是,比较轻量级,嘎嘎好用,推荐一波。 下载QsLog库 https://github.c…...

07. Hibernate 会话工厂(SessionFactory)
1. 前言 Hibernate 的核心价值观是:开发者们!做你们应该做的。脏的、累的、没技术含义的由本尊来做。 本节课和大家一起好好的聊聊 Hibernate 的核心组件之一:会话工厂(SessionFactory)。 通过本节课,你…...

使用Nginx实现高效负载均衡
概述 Nginx是一款高性能的HTTP和反向代理服务器,广泛用于Web服务的负载均衡。它能有效分发流量至多个后端服务器,提高网站的可用性和响应速度,同时增强系统的可扩展性和安全性。本文将介绍如何配置Nginx进行负载均衡,并提供具体的…...

华为OD机考题(基础API)
基础API 字典排序 List<String> listnew ArrayList(); //add list member Arrays.sort(list);List<Map<String,Integer>> listnew ArrayList(); //add list member Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {Over…...

<数据集>UA-DETRAC车辆识别数据集<目标检测>
数据集格式:VOCYOLO格式 图片数量:20500张 标注数量(xml文件个数):20500 标注数量(txt文件个数):20500 标注类别数:4 标注类别名称:[car, van, others, bus] 序号类别名称图片数框数1car201871259342…...

学生管理系统(C语言)(Easy-x)
课 程 报 告 课 程 名 称: 程序设计实践 专 业 班 级 : XXXXX XXXXX 学 生 姓 名 : XXX 学 号 : 231040700302 任 课 教 师 &a…...

C# 解析省份、城市、区域 json文件
一、json文件内容如下,(小程序里好像有用到...): 二、读取包含省份城市区域的json文件,并整理成想要的结果: string path Server.MapPath("/js"); string file System.IO.Path.Combine(path, "数据.…...

用C语言写的一个扫雷小游戏
头文件 调用头文件和声明函数 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <time.h> #include <stdlib.h>#define ROW 9 #define COL 9#define ROWS ROW2 #define COLS COL2#define EASY_CONT 10//声明函数 //初始化棋盘函数 void InitB…...

C++——类和对象(初始化列表和运算符重载与静态与友元)
文章目录 初始化列表语法结构定义和使用案例初始化列表初始化常量成员: 注意事项 运算符重载加法运算符重载语法结构示例注意事项 减法运算符重载语法结构示例注意事项 等于运算符重载等于运算符 的重载语法示例注意事项 大于运算符重载大于运算符 > 的重载语法…...

【WPF】图片剪裁-ImageCropping
【WPF】图片剪裁-ImageCropping 背景技术栈实现思路核心代码界面布局Style处理逻辑使用技巧预览下载背景 机缘巧合吧,当时在全网寻找图像剪裁工具,但大都不能满足需求,于是决定动手写。当然如果只是为了完成这么一个功能就没有必要记录了,主要是不依赖与第三方图像库,且实…...

C++的模板(十二):forward模板
标准库的std::forward模板有一个类型T参数。在实际使用时,T取什么值应该不存在疑惑: class A { public:A() {}A(int n):n(n) {}template <class T> A(T &&a);void print(A &&a) { printf("A&&\n"); }void pri…...

docker desktop历史版本安装
1.安装choco Windows安装 choco包管理工具-CSDN博客 2.通过choco安装 下面例子为安装旧版2.3.0.2,其它版本类似 Chocolatey Software | Docker Desktop 2.3.0.2 https://download.docker.com/win/stable/45183/Docker%20Desktop%20Installer.exe choco install docker-des…...

Ubuntu系统成功安装Docker教程
服务器版本: Ubuntu 22.04.3 LTS 1. 卸载旧版本 Docker 的旧版本被称为 docker,docker.io 或 docker-engine 。如果已安装,需要卸载: sudo apt-get remove docker docker-engine docker.io containerd runc2. 更新 apt 软件包 …...

C++ 匹配并提取包括加中括号的日期时间的正则表达式
在C中,你可以使用std::regex库来匹配包含日期和时间的字符串。以下是一个简单的例子,它展示了如何使用正则表达式来匹配形如[YYYY-MM-DD HH:MM:SS]的字符串。include <iostream> #include <string> #include <regex> int main() { …...

一文-深入了解Ansible常见模块、安装和部署
1 Ansible 介绍 Ansible是一个配置管理系统configuration management system, python 语言是运维人员必须会的语言, ansible 是一个基于python 开发的(集合了众多运维工具 puppet、cfengine、chef、func、fabric的优点)自动化运维工具, 其功能实现基于ss…...

etcd的备份与恢复
一 为什么使用etcd 与ZooKeeper相比,etcd更简单,安装、部署和使用更加容易,并且etcd的某些功能是ZooKeeper所没有的。因此,在很多场景下,etcd 比ZooKeeper更受用户的青,具体表现在如下几个方面: 1 etcd更…...

从 Pandas 到 Polars 十八:数据科学 2025,对未来几年内数据科学领域发展的预测或展望
我在2021年底开始使用Polars和DuckDB。我立刻意识到这些库很快就会成为数据科学生态系统的核心。自那时起,这些库的受欢迎程度呈指数级增长。 在这篇文章中,我做出了一些关于未来几年数据科学领域的发展方向和原因的预测。 这篇文章旨在检验我的预测能力…...

【postgresql】pg_dump备份数据库
pg_dump 介绍 pg_dump 是一个用于备份 PostgreSQL 数据库的实用工具。它可以将数据库的内容导出为一个 SQL 脚本文件或其他格式的文件,以便在需要时进行恢复或迁移。 基本用法 pg_dump [选项] [数据库名] 命令选项 -h 或 --host:指定数据库服务器的主…...

服务器的80和443端口关闭也能申请SSL证书
一、简介 在服务器的80和443端口关闭的情况下,确实可以申请SSL证书,但申请过程和方法会根据证书类型和验证方式的不同而有所差异。 通常如果是网站域名申请SSL证书,哪怕服务器的80、443端口都打不开,也可以通过DNS解析的方式来验…...

Odoo17应用、模型、字段
新建最简应用 先启用开发人员模式。 新建一个没有菜单项的空壳应用(模块/插件): 必须至少包含 2 个文件: __manifest__.py 文件和文件 __init__.py 。 该 __init__.py 文件目前可以保持为空,我们将在下一章中返回。另一方面,该…...

Airtest的控制手机滑动位置偏差修正方法总结
提起Airtest的控制手机滑动位置,就会想起swipe,因为这种方法比较常见,对于没有精度控制的朋友完全够用, 我现在遇到精度控制时,大家都觉得精度不够,现在我对滑动精度控制,找到比较好的方法&…...

【机器学习】Grid Search: 一种系统性的超参数优化方法
🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 💫个人格言: "如无必要,勿增实体" 文章目录 Grid Search: 一种系统性的超参数优化方法引言什么是Grid Search?Gr…...

Laravel Passport:API认证的瑞士军刀
Laravel Passport:API认证的瑞士军刀 在现代Web应用中,API的安全认证是一个核心问题。Laravel Passport提供了一个全面的解决方案,用于构建OAuth2.0认证服务器。它使得API的认证变得简单而强大,支持多种认证方式,包括…...