ratch-job

repository·master·Indexed 42 days ago

https://github.com/ratch-job/ratch-job

A high-performance, distributed task scheduling platform written in Rust. It is designed as a drop-in, enhanced replacement for xxl-job, featuring full protocol compatibility, built-in Raft-based distributed storage to eliminate external database dependencies, and high concurrency capabilities. Version 0.2.2 provides a Web Console and an Open-API for programmatic task management.

Tokens
15.6K
Snippets
51
Records
73
Agent score
53%

What's inside ratch-job

  1. Overview of ratch-job

    master

    ratch-job is a distributed task scheduling platform implemented in Rust. It is designed to be fully compatible with the xxl-job protocol while enhancing scheduling capabilities. Key features include:

    • Built-in Raft Distributed Storage: Does not depend on external databases; it can run as a standalone service.
    • High Concurrency: Uses a Raft leader to replace MySQL locks, significantly improving scheduling concurrency.
    • High Performance: Lightweight and efficient (e.g., running 1000 tasks/sec with ~38% single-core CPU and 85MB RAM).
    • Smooth Migration: Full compatibility with xxl-job allows existing xxl-job applications to migrate easily.
    • Management Options: Provides both a Web Console for UI management and an Open-API for programmatic management.
  2. Namespace Data Model and Actor Communication

    master

    Namespaces are managed via an Actor model using NamespaceManager. The system distinguishes between Raft-replicated requests (for state changes) and standard business requests (for read-only queries).

    Actor Message Types

    Raft Requests (NamespaceManagerRaftReq)

    Used for operations that must be synchronized across the cluster via Raft:

    • AddNamespace: Creates a new namespace.
    • UpdateNamespace: Modifies an existing namespace.
    • Remove: Deletes a namespace.

    Business Requests (NamespaceManagerReq)

    Used for local, non-replicated reads:

    • GetNamespace: Retrieves a single namespace by id.
    • QueryNamespace: Performs paginated queries with type filtering.

    Data Structures

    • Namespace: The in-memory object containing id, name, and type.
    • NamespaceDo: The Protobuf persistence object used for serialization.
    • NamespaceInfo: The API response object used for returning namespace details.
  3. Configure Namespace Isolation for Executors

    master

    ratch-job supports multi-namespace isolation. Tasks can be isolated by namespace, which is managed via the Web Console.

    When an executor registers, ratch-job attempts to parse the namespace from the application name using the format ns://{namespace}/{appName}. If this format is not used, it defaults to the xxl namespace.

    Default Namespace (xxl):

    xxl.job.executor.appname=xxl-job-executor-sample

    Custom Namespace (e.g., 'dev'):

    xxl.job.executor.appname=ns://dev/xxl-job-executor-sample
    # Using a custom namespace 'dev'
    xxl.job.executor.appname=ns://dev/xxl-job-executor-sample
  4. Namespace Snapshotting and Persistence

    master

    To ensure durability and fast recovery, NamespaceManager implements snapshotting logic using the T_NAMESPACE table identifier.

    Snapshot Lifecycle

    1. Build Snapshot: The build_snapshot() method iterates through the in-memory BTreeMap, serializes each Namespace into a NamespaceDo protobuf object, and creates a SnapshotRecordDto with tree=T_NAMESPACE. This is sent to the SnapshotWriterActor.
    2. Load Snapshot: During recovery, load_snapshot_record() identifies records marked as T_NAMESPACE, uses a BytesReader to deserialize them back into NamespaceDo, and reconstructs the in-memory state.
    3. Completion: load_completed() executes initialization logic once the full state is restored.

    Persistence Implementation

    • Serialization: Uses to_do() to convert memory objects to Protobuf.
    • Deserialization: Implements From<NamespaceDo<'_>> to convert Protobuf back to memory objects, utilizing Cow::Borrowed to minimize string copying.
  5. Connect a Java Executor to ratch-job

    master

    To connect a Java-based xxl-job executor to ratch-job, update your application.properties with the following settings:

    # Point to the ratch-job Open-API address
    xxl.job.admin.addresses=http://127.0.0.1:8725/xxl-job-admin
    
    # Match the ratch-job global token
    xxl.job.accessToken=default_token

    Once configured and running, the executor and its instances will appear in the ratch-job Web Console under Executor Management (执行器管理).

    xxl.job.admin.addresses=http://127.0.0.1:8725/xxl-job-admin
    xxl.job.accessToken=default_token
  6. Install ratch-job via Homebrew (macOS)

    master

    For macOS users, you can install ratch-job using Homebrew by tapping the official repository:

    # Add the tap
    brew tap ratch-job/ratch-job 
    
    # Install
    brew install ratch-job
    
    # Run
    ratchjob
    
    # Upgrade to latest version
    brew upgrade ratch-job
    brew tap ratch-job/ratch-job 
    brew install ratch-job
    ratchjob
  7. Install and run ratch-job (Single Node)

    master

    You can deploy ratch-job in a single-node configuration using several methods:

    Download Binary

    Download the appropriate package for your system from [GitHub Releases], extract it, and run the executable.

    Linux/macOS:

    tar -xvf ratchjob-x86_64-apple-darwin-v0.1.4.tar.gz
    ./ratchjob

    Windows: Run ratchjob.exe after extraction.

    Note: The default console is accessible at http://127.0.0.1:8825/ratchjob/.

    Docker

    docker pull qingpan/ratchjob:stable
    docker run --name myratchjob -p 8725:8725 -p 8825:8825 -p 8925:8925 -d qingpan/ratchjob:stable

    Note: The container uses /io as the data directory.

    Cargo (Rust)

    cargo install ratchjob
    ratchjob

    Source Code

    git clone https://github.com/ratch-job/ratch-job.git
    cd ratch-job
    cargo build --release
    cargo run --release
    # Example: Running via binary
    tar -xvf ratchjob-x86_64-apple-darwin-v0.1.4.tar.gz
    ./ratchjob
  8. Manage jobs with ScheduleManager

    master

    The ScheduleManager is an Actix actor responsible for job scheduling, task lifecycle management, and handling retries. It coordinates with a TaskManager to trigger jobs and uses Raft for cluster-wide consistency.

    Key capabilities include:

    • Job Lifecycle: Adding, updating, and removing jobs.
    • Task Tracking: Monitoring running tasks, handling task callbacks (success/failure), and managing task history logs.
    • Retry Logic: Automatically handling task retries (RedoType::Retry), timeouts (RedoType::Timeout), and re-executions (RedoType::Redo).
    • Clustering: Responding to Raft vote changes to ensure only the master node performs scheduling.
  9. Understand the ratch-job permission model

    master

    The permission system follows a hierarchical structure: User $\rightarrow$ Role $\rightarrow$ Functional Module $\rightarrow$ Permission Resource.

    Permission resources are categorized into two types:

    1. Web Resources: Managed by the frontend to control page visibility and access.
    2. HTTP Request Paths: Managed by backend interceptors to control access to specific API endpoints based on the URL path and HTTP method.

    Roles are represented by string values:

    • 0: Manager
    • 1: Developer
    • 2: Visitor
    • `` (empty): None
  10. Configure ratch-job via Environment Variables

    master

    ratch-job can be configured using environment variables. Below are the key configuration parameters:

    KeyDescriptionDefault
    RUST_LOGLog level (debug, info, warn, error)info
    RATCH_HTTP_API_PORTHTTP Open-API port8725
    RATCH_HTTP_CONSOLE_PORTIndependent Console port8825
    RATCH_GRPC_CLUSTER_PORTgRPC port for Raft cluster communication8925
    RATCH_DATA_DIRLocal database directoryratch_db
    DEFAULT_XXL_JOB_ADMIN_PREFIX_PATHCustom xxl-job API path/xxl-job-admin
    RATCH_XXL_DEFAULT_ACCESS_TOKENGlobal xxl-job tokendefault_token
    RATCH_RAFT_NODE_IDNode ID1
    RATCH_RAFT_NODE_ADDRNode address (Ip:GrpcPort)127.0.0.1:8925
    RATCH_RAFT_AUTO_INITInitialize as leader node (only on startup)true
    RATCH_RAFT_JOIN_ADDRAddress of the leader to join (only on first startup)
    RATCH_CLUSTER_TOKENToken for cluster communication validation
    RATCH_GMT_OFFSET_HOURSLog timezone offset in hourslocal
    RATCH_INIT_ADMIN_USERNAMEInitial admin usernameadmin
    RATCH_INIT_ADMIN_PASSWORDInitial admin passwordadmin
  11. Understand PrivilegeGroup and permission logic

    master

    A PrivilegeGroup<T> is a data model used to manage access control via whitelists and blacklists. It supports both explicit lists of items and 'all-or-nothing' modes.

    Key Concepts

    • Whitelist: If whitelist_is_all is true, all keys are permitted. Otherwise, only keys present in the whitelist set are permitted.
    • Blacklist: If blacklist_is_all is true, all keys are denied. Otherwise, keys present in the blacklist set are denied.
    • Permission Logic: A key is permitted if it is in the whitelist AND NOT in the blacklist (at_whitelist(key) && !at_blacklist(key)).
    • Enabled State: If enabled is false, the group's logic is bypassed (though the implementation details of how enabled interacts with the check depend on the caller, the check_permission method specifically evaluates the lists).

    Common States

    • empty(): Enabled, but with empty whitelists/blacklists (effectively restrictive).
    • all(): Enabled, with whitelist_is_all set to true (effectively permissive).
    // Example of checking permission for a specific key
    let group = PrivilegeGroup::new(flags, whitelist, blacklist);
    let is_allowed = group.check_permission(&some_key);