前言
虽然PowerJob
官方说支持JPA
各种数据源,但在PG
数据库的兼容性上,确实存在小问题,issue
也有相关原理描述,官方采用的优雅方式并未真正解决问题,因为只解决了从@Lob
字段读取的时候,自动建表的时候还是会生成oid
类型。本文从0到1,从源码开始一步步解决编译、运行、部署过程中遇到的问题,并分享出来,希望对大家有所帮助。
本地开发环境说明
开发依赖 | 版本 |
---|---|
数据库 | PostgreSQL |
JDK | 17 |
源码编译、启动
- 调度中心(
powerjob-server
):- https://github.com/PowerJob/PowerJob.git
- https://gitee.com/KFCFans/PowerJob.git
- 修改源码tech.powerjob.server.persistence.config.dialect.PowerJobPGDialect
package tech.powerjob.server.persistence.config.dialect;
import org.hibernate.dialect.PostgreSQL10Dialect;
import org.hibernate.type.descriptor.sql.LongVarbinaryTypeDescriptor;
import org.hibernate.type.descriptor.sql.LongVarcharTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import java.sql.Types;
/**
* PostgreSQL 数据库支持,需要在 application.properties 中添加以下配置项进行激活
* spring.datasource.remote.hibernate.properties.hibernate.dialect=tech.powerjob.server.persistence.config.dialect.PowerJobPGDialect
*
* @author Kung Yao
* @author Echo009
* 2021/3/24 下午 04:23
* 1074_King
*/
public class PowerJobPGDialect extends PostgreSQL10Dialect {
/**解决建表时,@Lob字段会生成oid类型,需要改成text类型*/
public PowerJobPGDialect() {
super();
registerColumnType(Types.BLOB, "bytea");
registerColumnType(Types.CLOB, "text");
}
/**解决读取@Lob字段时,使用Text类型*/
@Override
public SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
switch (sqlCode) {
case Types.CLOB:
return LongVarcharTypeDescriptor.INSTANCE;
case Types.NCLOB:
case Types.BLOB:
return LongVarbinaryTypeDescriptor.INSTANCE;
}
return super.getSqlTypeDescriptorOverride(sqlCode);
}
}
- 编译
JDK17+
- 修改
lombok
版本<properties> <lombok.version>1.18.28</lombok.version> </properties>
- 增加依赖
<dependency> <groupId>org.jboss.xnio</groupId> <artifactId>xnio-nio</artifactId> <version>3.8.7.Final</version> <scope>runtime</scope> </dependency>
- 编译:
mvn compile -Pdev -DskipTests=true -e
- PG数据库需要增加配置:
spring.datasource.remote.hibernate.properties.hibernate.dialect=tech.powerjob.server.persistence.config.dialect.PowerJobPGDialect
- 相关问题描述:
https://github.com/PowerJob/PowerJob/issues/153#issuecomment-812771783
- 相关问题描述:
- 数据库初始化
CREATE DATABASE "powerjob-daily" WITH ENCODING = 'UTF8' CONNECTION LIMIT = -1 IS_TEMPLATE = False CREATE ROLE powerjob WITH LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD 'powerjob'; COMMENT ON ROLE powerjob IS 'powerjob'; GRANT ALL PRIVILEGES ON DATABASE "powerjob-daily" TO powerjob;
- 启动参数增加:
--spring.profiles.active=daily
- 浏览器访问:
http://127.0.0.1:7700/
4.x
: 注册应用,然后登录5.x
: 超级管理员登录:ADMIN
/powerjob_admin
- 前端页面(powerjob-console):
- https://github.com/PowerJob/PowerJob-Console.git
- https://gitee.com/KFCFans/PowerJob-Console.git
执行器(powerjob-worker)
- 参考资料:
https://www.yuque.com/powerjob/guidence/deploy_worker
- pom依赖
<dependency>
<groupId>tech.powerjob</groupId>
<artifactId>powerjob-worker-spring-boot-starter</artifactId>
<version>${powerjob.version}</version>
</dependency>
处理器(Processor)
package com.wen3.powerjob.demo.jobs;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import tech.powerjob.worker.annotation.PowerJobHandler;
import tech.powerjob.worker.core.processor.ProcessResult;
import tech.powerjob.worker.core.processor.TaskContext;
import tech.powerjob.worker.core.processor.sdk.BasicProcessor;
import tech.powerjob.worker.log.OmsLogger;
/**
* 单机处理器:BasicProcessor
*
* 单机执行的策略下,server 会在所有可用 worker 中选取健康度最佳的机器进行执行。单机执行任务需要实现接口 BasicProcessor,代码示例如下:
*/
// 支持 SpringBean 的形式
@Component
public class BasicProcessorDemo implements BasicProcessor {
@Override
public ProcessResult process(TaskContext context) throws Exception {
System.out.println("BasicProcessorDemo");
// 在线日志功能,可以直接在控制台查看任务日志,非常便捷
OmsLogger omsLogger = context.getOmsLogger();
omsLogger.info("BasicProcessorDemo start to process, current JobParams is {}.", context.getJobParams());
return new ProcessResult(true, "result is xxx");
}
@PowerJobHandler(name = "xxx1")
public void xx1(TaskContext context) throws Exception {
System.out.println("xxx1");
// 在线日志功能,可以直接在控制台查看任务日志,非常便捷
OmsLogger omsLogger = context.getOmsLogger();
omsLogger.info("xx1");
}
@PowerJobHandler(name = "xxx2")
public void xx2(TaskContext context) throws Exception {
System.out.println("xxx2");
// 在线日志功能,可以直接在控制台查看任务日志,非常便捷
OmsLogger omsLogger = context.getOmsLogger();
omsLogger.info("xx2");
}
}
docker镜像制作
java
打包:mvn package -Pdev -DskipTests=true -e
- 把打包后的
powerjob-server-starter-4.3.9.jar
、构建脚本、Dockerfile
放到同一个目录
-rwxr-xr-x 1 root root 268 May 4 11:05 docker-build.sh
-rw-r--r-- 1 root root 2712 May 4 10:43 Dockerfile
-rw-r--r-- 1 root root 135117797 May 4 11:03 powerjob-server-starter-4.3.9.jar
- 执行构建脚本:
./docker-build.sh
构建脚本
version=4.3.9
# 删除旧镜像
docker rmi -f imgsreg.ipipa.cn:20443/base/powerjob-server:$version
# 构建 powerjob-server 镜像
docker build -t imgsreg.ipipa.cn:20443/base/powerjob-server:$version .
docker push imgsreg.ipipa.cn:20443/base/powerjob-server:$version
k8s部署yaml文件制作
service制作
apiVersion: v1
kind: Service
metadata:
name: powerjob
namespace: kube-public
labels:
app: vxiao-powerjob
spec:
type: NodePort
ports:
- name: http
port: 17700
targetPort: 7700
nodePort: 17700
- name: akka
port: 10086
targetPort: 10086
nodePort: 10086
- name: oms-http
port: 10010
targetPort: 10010
nodePort: 10010
selector:
app: powerjob
deployment制作
apiVersion: apps/v1
kind: Deployment
metadata:
name: powerjob
namespace: kube-public
spec:
replicas: 1
revisionHistoryLimit: 0
selector:
matchLabels:
app: powerjob
template:
metadata:
labels:
app: powerjob
spec:
containers:
- name: powerjob
imagePullPolicy: Always
image: xxxx:port/base/powerjob-server:4.3.9
env:
- name: JAVA_PROGRAM_ARGS
value: >-
--spring.profiles.active=product
--spring.datasource.remote.hibernate.properties.hibernate.dialect=tech.powerjob.server.persistence.config.dialect.PowerJobPGDialect
--spring.datasource.core.driver-class-name=org.postgresql.Driver
--spring.datasource.core.jdbc-url=jdbc:postgresql://xxx:5432/powerjob-product?autoReconnect=true&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&useNewIO=true&rewriteBatchedStatements=true&CharSet=utf8&serverTimezone=GMT&autoReconnection=true&remarks=true&useSSL=false
--spring.datasource.core.username=powerjob
--spring.datasource.core.password=powerjob
ports:
- containerPort: 7700
- containerPort: 10086
- containerPort: 10010
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 7700
initialDelaySeconds: 30
failureThreshold: 2
periodSeconds: 15
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 7700
initialDelaySeconds: 15
periodSeconds: 15
startupProbe:
httpGet:
path: /actuator/health/readiness
port: 7700
failureThreshold: 30
periodSeconds: 15
resources:
requests:
cpu: 0.5
memory: 500Mi
limits:
cpu: 1
memory: 1Gi
k8s部署
kubectl apply -f powerjob.yaml -n kube-public
运行截图
- 在首页先注册应用
- 使用注册的应用名称和密码进行登录
- 在任务管理中新建任务
参考资料
- 官网:
http://www.powerjob.tech/
- 在线文档:
https://www.yuque.com/powerjob/guidence/intro
- 快速开始:
https://www.yuque.com/powerjob/guidence/quick_start