云计算百科
云计算领域专业知识百科平台

利用GitHub的Actions功能白嫖一个服务器

前言

对于程序员买个服务器,就是买了一年好几百没啥用,不买有时候确需要用到。就是“食之无味,弃之可惜”,非常鸡肋。这边如果对于服务器只定时跑的功能,那么可以通过GitHub的Actions来实现。这边笔者通过使用Actions发送定时提醒到微信例子,来说明如何白嫖服务器。

这边定时任务比如定时爬取自己想看的电影网上是否有,帮我们自动签到获取积分,打卡提醒。

Actions

GitHub Actions 是 GitHub 提供的一项 持续集成与持续部署(CI/CD) 服务,允许开发者在代码库中编写和执行自动化工作流程(workflows),以实现自动化构建、测试、部署等操作。 Actions可以在 push、pull request、定时任务、手动触发 等事件下运行。 那么我们使用定时任务功能,运行我们的单元测试,达到运行我们的定时任务功能。

定时任务

为了方便维护,这边写的定时任务使用Spring的Scheduled,业务逻辑这块不变。这样将来有钱了使用真正的服务器,可以无缝衔接不用改代码。通过扫描带有@Scheduled注解来获取现有的定时任务方法,以下是封装的单元测试方法。

因为是免费的GitHub Actions定时任务启动时间并不会那么准时,所以这边运行的测试类启动定时任务,需要判断在当前的定时任务是否在配置的时间范围内。

package com.ji.helper.job;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.quartz.CronExpression;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.TimeZone;

@Slf4j
@SpringBootTest
public class DailyJobTest {

@Resource
private DailyJob dailyJob;

/**
* 入口:触发模拟定时任务扫描执行
*/

@Test
public void simulateScheduledExecution() {
log.info("🕒 开始扫描并执行定时任务…");
invokeScheduledMethods(DailyJob.class);
}

/**
* 扫描类中所有标注了 @Scheduled 的方法,并根据 cron 判断是否应执行
*/

@SneakyThrows
private void invokeScheduledMethods(Class<?> targetClass) {
for (Method method : targetClass.getDeclaredMethods()) {
if (method.isAnnotationPresent(Scheduled.class)) {
Scheduled scheduled = method.getAnnotation(Scheduled.class);
String cronExpression = scheduled.cron();

if (shouldExecute(cronExpression, method.getName())) {
log.info("✅ 执行方法:{}", method.getName());
method.invoke(dailyJob); // 调用目标方法
}

log.info("—————————-");
}
}
}

/**
* 判断是否处于 cron 表达式允许的执行时间窗口
*/

@SneakyThrows
private boolean shouldExecute(String cronExpressionStr, String methodName) {
CronExpression cronExpression = new CronExpression(cronExpressionStr);
// 当前北京时间
DateTime beijingNow = new DateTime();
DateTime nowTime = DateUtil.offsetMinute(beijingNow, 5); // 假设检查过去 5 分钟内是否应执行

log.info("🕓 当前北京时间:{},当前时区:{}", beijingNow, TimeZone.getDefault().getID());

// 下次执行时间
Date nextExecutionTime = cronExpression.getNextValidTimeAfter(nowTime);

log.info("📌 method={}, cron={}, 当前时间={}, 下次执行时间={}",
methodName, cronExpressionStr,
nowTime,
DateUtil.format(nextExecutionTime, "yyyy-MM-dd HH:mm:ss"));

// 如果下次执行时间在当前时间之后且小于某个阈值,说明该任务在此窗口内应执行
return DateUtil.between(nowTime, nextExecutionTime, DateUnit.HOUR) < 1;
}

}

且GitHub Actions是国外服务器时间用的是格林威治时间,和北京时间相差8个小时。这边可以在运行前统一配置Java的时区为北京时区,如果不配置那么默认使用服务器时区。在计算时间比较麻烦。

@PostConstruct
public void init() {
log.info("设置默认时区 Asia/Shanghai");
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
}

创建Actions

在这里插入图片描述 以下是actions的配置,其中cron和我们平时定时器配的定时器不太一样,如果在运行中发现异常很可能就是定时器配置错误。

name: Hourly Maven Build

on:
schedule:
cron: '0 * * * *' # 每小时的第 0 分钟执行任务
workflow_dispatch: # 允许手动触发

jobs:
build:
runson: ubuntulatest # 使用最新版本的 Ubuntu

steps:
name: Checkout Code
uses: actions/checkout@v3 # 拉取代码到 CI 环境

name: Cache Maven packages
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: ${{ runner.os }}maven${{ hashFiles('**/pom.xml') }}
restorekeys: |
${{ runner.os }}maven

name: Set up JDK 17
uses: actions/setupjava@v3 # 设置 JDK 版本
with:
javaversion: '17'
distribution: 'temurin'

name: Build with Maven
run: mvn install DskipTests=true Dmaven.javadoc.skip=true B V # 执行 Maven 构建命令

name: Run Tests
run: mvn B test # 执行测试,确保构建没有问题

运行效果

这边推送通知使用的是企业微信机器人接口,最后选择这个是因为公众号目前消息通知藏的特别深不太好查看。查看了企业微信相关接口没有api发送给微信好友的接口,因为企业微信还是不如微信好友方便。且企业微信还有一个问题就是mac上的微信,收不到企业微信消息,对于mac用户更加不友好了。目前还没有找到比较好的解决方案。

在这里插入图片描述

在这里插入图片描述

结语

Github Actions还有一个好处就是提交代码就直接运行了也不用手动部署,平时需要修改啥的那就很方便了。还有一个问题是因为是免费的,有时候在高峰期时间Github Actions不能执行成功。

源码

可关注微信公众号【纪东东】获取源码

在这里插入图片描述

赞(0)
未经允许不得转载:网硕互联帮助中心 » 利用GitHub的Actions功能白嫖一个服务器
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!