侧边栏壁纸
  • 累计撰写 39 篇文章
  • 累计创建 51 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

XXL-JOB(HA)& 微服务集成

叶子
2024-04-29 / 0 评论 / 0 点赞 / 71 阅读 / 1,874 字

官方文档

https://www.xuxueli.com/xxl-job/#5.4.3 调度中心HA(集群)
image

调度中心HA(集群)

负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦,提高了系统可用性和稳定性,同时调度系统性能不再受限于任务模块;
支持可视化、简单且动态的管理调度信息,包括任务新建,更新,删除,GLUE开发和任务报警等,所有上述操作都会实时生效,同时支持监控调度结果以及执行日志,支持执行器Failover。

  • DB配置保持一致;
  • 集群机器时钟保持一致(单机集群忽视);
  • 建议:推荐通过nginx为调度中心集群做负载均衡,分配域名。调度中心访问、执行器回调配置、调用API服务等操作均通过该域名进行。

执行器HA(集群)

负责接收调度请求并执行任务逻辑。任务模块专注于任务的执行等操作,开发和维护更加简单和高效;
接收“调度中心”的执行请求、终止请求和日志请求等。

  • 执行器回调地址(xxl.job.admin.addresses)需要保持一致;执行器根据该配置进行执行器自动注册等操作。
  • 同一个执行器集群内AppName(xxl.job.executor.appname)需要保持一致;调度中心根据该配置动态发现不同集群的在线执行器列表。

任务HA(Failover)

执行器如若集群部署,调度中心将会感知到在线的所有执行器,如“127.0.0.1:9997, 127.0.0.1:9998, 127.0.0.1:9999”。

当任务”路由策略”选择”故障转移(FAILOVER)”时,当调度中心每次发起调度请求时,会按照顺序对执行器发出心跳检测请求,第一个检测为存活状态的执行器将会被选定并发送调度请求。

调度成功后,可在日志监控界面查看“调度备注”,如下;

“调度备注”可以看出本地调度运行轨迹,执行器的”注册方式”、”地址列表”和任务的”路由策略”。”故障转移(FAILOVER)”路由策略下,调度中心首先对第一个地址进行心跳检测,心跳失败因此自动跳过,第二个依然心跳检测失败……
直至心跳检测第三个地址“127.0.0.1:9999”成功,选定为“目标执行器”;然后对“目标执行器”发送调度请求,调度流程结束,等待执行器回调执行结果。

故障转移 & 失败重试

一次完整任务流程包括”调度(调度中心) + 执行(执行器)”两个阶段。

“故障转移”发生在调度阶段,在执行器集群部署时,如果某一台执行器发生故障,该策略支持自动进行Failover切换到一台正常的执行器机器并且完成调度请求流程。

“失败重试”发生在”调度 + 执行”两个阶段,支持通过自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;

部署

镜像准备

  • xxl-job-admin
 docker build -t xuxueli/xxl-job-admin:2.4.2 .
  • 微服务集成xxl-job
    • 修改pom.xml
<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>2.4.0</version>
</dependency>
  • 增加配置类
package com.icss.ebu.spms.sioc.task.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;

/**
 * xxl-job config
 *
 * @author xuxueli 2017-04-28
 */
@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;
    }

    /**
     * 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
     *
     *      1、引入依赖:
     *          <dependency>
     *             <groupId>org.springframework.cloud</groupId>
     *             <artifactId>spring-cloud-commons</artifactId>
     *             <version>${version}</version>
     *         </dependency>
     *
     *      2、配置文件,或者容器启动变量
     *          spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
     *
     *      3、获取IP
     *          String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
     */


}
  • application.yml增加配置
xxl:
  job:
    admin:
      addresses: http://10.88.40.40:18080/xxl-job-admin,http://10.88.40.40:28080/xxl-job-admin
    accessToken: default_token
    executor:
      appname: 应用名
      address:
      ip:
      port: 9998
      logpath: ./data/applogs/xxl-job/jobhandler
      logretentiondays: 30
  • 任务改造
@XxlJob("test")
public void test() {
    log.info("定时 开始 !");
    try {
        System.out.println("to do something...");
    } catch (Exception e) {
        log.error("定时 异常!", e);
    }
    log.info("定时 结束 !");
}
  • 应用服务镜像准备
FROM openjdk:8-jre-slim
MAINTAINER lizemin

ENV PARAMS=""
ENV JAVA_OPTS=" -Dfile.encoding=UTF-8 "

ENV TZ=PRC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

ADD target/*.jar /app.jar

ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /app.jar $PARAMS"]

docker-compose

version: '3.8'
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "19200:80"
    volumes:
          - "E:/Docker/xxl-job/nginx/conf/nginx.conf:/etc/nginx/nginx.conf"
          - "E:/Docker/xxl-job/nginx/conf.d:/etc/nginx/conf.d"
          - "E:/Docker/xxl-job/nginx/log:/var/log/nginx"
          - "E:/Docker/xxl-job/nginx/html:/usr/share/nginx/html"
  xxlJobAdmin1:
    image: xuxueli/xxl-job-admin:2.4.2
    container_name: xxlJobAdmin1
    ports:
      - "18080:8080"
    volumes:
          - "E:/Docker/xxl-job/log-1:/data/applogs"
  xxlJobAdmin2:
    image: xuxueli/xxl-job-admin:2.4.2
    container_name: xxlJobAdmin2
    ports:
      - "28080:8080"
    volumes:
          - "E:/Docker/xxl-job/log-2:/data/applogs"
  task1:
    image: 应用名:1.0.0
    container_name: task1
  task2:
    image: 应用名:1.0.0
    container_name: task2
  task3:
    image: 应用名:1.0.0
    container_name: task3
  task4:
    image: 应用名:1.0.0
    container_name: task4

nginx配置

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

	upstream xxlJobAdmin{
			server xxlJobAdmin1:8080;
			server xxlJobAdmin2:8080;
	}

    server {
		listen       80;
		listen  [::]:80;
		server_name  localhost;

		#access_log  /var/log/nginx/host.access.log  main;

		location / {
			root   /usr/share/nginx/html;
			index  index.html index.htm;
		}
		
		location /xxl-job-admin {
			proxy_pass http://xxlJobAdmin;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			add_header Access-Control-Allow-Origin *;
		}
			
		error_page   500 502 503 504  /50x.html;
		location = /50x.html {
			root   /usr/share/nginx/html;
		}
		
	}
	
}

验证

  1. 访问nginx 登录xxl-job-admin

http://10.88.40.40:19200/xxl-job-admin/toLogin
账号密码:admin/123456

  1. 执行器验证

image-1714397757909

  1. 任务管理
    image-1714397772038
    image-1714397774686

  2. 故障转移验证
    image-1714397779887

0

评论区