1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/kkk001-dal-job

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

dal-job (Распределенная работа как локальная)

Описание

Dal-job — это децентрализованная легковесная распределённая система управления задачами. Она не имеет центрального узла, а код выполняется на различных модулях.

Эта система помогает разработчикам сосредоточиться на бизнес-логике при работе в распределенной среде, не беспокоясь о повторном выполнении задач.

Основные функции:

  • Выполнение задачи одной машиной в распределенной среде одновременно.
  • Запись журнала выполнения задачи, включающего записи выполнения, время выполнения, журнал ошибок и т.д. (job_log).
  • Запись информации о задачах в системе (job_info).
  • Предоставление встроенных механизмов повторной попытки выполнения задачи для сценариев, требующих повторной попытки. Включает предварительную и последующую повторную попытку.
  • Возможность указания нескольких экземпляров для параллельного запуска, но требуется гарантия отсутствия дублирования и пропуска данных в логике задачи.

Пример решения: При получении данных можно использовать случайно сгенерированный уникальный глобальный ключ для получения данных и их обработки.

Вопросы для размышления

В распределенной среде, использующей децентрализованную распределенную задачу, следует решить следующие проблемы:* 1. Мы сталкиваемся с возможностью многопоточной среды на одном экземпляре, что требует обеспечения выполнения одной задачи одним потоком. (Это случается редко, так как задачи контролируются своими модулями, обычно один экземпляр машины выполняет одну задачу одним потоком.)

    1. Мы работаем в многопроцессорной среде, которая требует обеспечения того, чтобы в любой момент времени только один процесс мог выполнять задачу на нескольких машинах.
    1. В распределённой среде системы времени могут различаться между машинами, что приводит к тому, что задачи не выполняются одновременно. Нужно гарантировать, что только одна машина правильно выполняет задачу.

Принцип работы

Используется строковый блокировщик базы данных для обеспечения выполнения одной задачи одной машиной в любое время.

Детали: использует [пессимистическую блокировку + проверка состояния задачи + ограничение времени] для реализации выполнения одной задачи одной машиной в условиях многопоточности и многопроцессорности (особенно многопроцессорности).

Технологии

Используются Quartz + MySQL. Также хорошо интегрируются со Spring. Предоставлены аннотации (@TimedTask) для конфигурации задач.

Быстрый старт

ТаймерDal-job поддерживает запуск одного экземпляра и нескольких экземпляров в распределённой среде. При запуске нескольких экземпляров задачи будут выполняться на всех экземплярах, и вам потребуется решить проблему получения данных.Dal-job предоставляет конфигурацию задач в виде аннотаций, подробнее см. com.kvn.dal.core.single_node.SingleNodeJob.java

@Target({TYPE})
@Retention(RUNTIME)
public @interface TimedTask {
    String corn();
}
boolean isGlobalSingle() default true; // В распределённой среде, следует ли запускать синглтоном
String desc() default "";
}

Пример планировщика задач:

@TimedTask(corn = "0 0/1 * * * ?", desc = "тестовый job222")
@Service
public class MyTestJob2 implements ExecutableTask {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println(DateTime.now() + "--" + Thread.currentThread().getName() + "---------------doBizJob2222--------");
        try {
            Thread.sleep(3000L);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if (new Random().nextInt() % 2 == 0) {
            throw new RuntimeException("biz выполнение MyTestJob2 произошло с ошибкой, xxxxxxxxx");
        }
    }
}

Повторная попытка выполнения задач

Dal-job предоставляет встроенную реализацию повторной попытки выполнения задач, что позволяет легко выполнять периодическую повторную попытку для некорректных данных.

Повторная попытка делится на два типа: первый — это предварительная повторная попытка; второй — последняя повторная попытка.

Предварительная повторная попыткаПредварительная повторная попытка заключается в том, чтобы независимо от того, успешно ли была выполнена бизнес-логика, записывать лог выполнения (таблица: job_beforehand_retry). Если возникают указанные исключения, то запись помечается как требующая повторной попытки. При выполнении задачи, которая требует повторной попытки, она направляется соответствующим методом повторной попытки.Принцип: используется подход AOP для перехвата методов, требующих повторной попытки (@BeforehandRetry).

@BeforehandRetry:

/**
 * Предварительная компенсация, гарантирующая, что каждое выполнение бизнес-логики имеет запись. Это может привести к снижению производительности.
 * @author wzy
 * @date 2017-07-14 17:03:45
 */
@Target({METHOD})
@Retention(RUNTIME)
@Inherited
public @interface BeforehandRetry {
    /**
     * Исключение для повторной попытки, по умолчанию это BizRetryNeedException. Для бизнес-исключений повторная попытка не требуется!
     */
    Class<? extends Throwable> retryFor() default BizRetryNeedException.class;
    /**
     * Максимальное количество повторных попыток
     */
    int maxRetryCount() default 3;
}

Пример: com.kvn.dal.core.beforehand_retry.BeforehandRetryBizService.java

@Service
public class BeforehandRetryBizService {
    @BeforehandRetry
    public String doBiz(Foo foo, String param){
        System.out.println("--->isRetryThread:" + ThreadContext.getContext().isRetryThread());
        System.out.println("Параметры: Foo=" + JSON.toJSONString(foo) + ", param=" + param);
        System.out.println("Выполнение бизнес-логики завершилось с ошибкой >>>>>>>>");
    }
}
throw new BizRetryNeedException("Бизнес-операция завершилась ошибкой, требуется повторная попытка! ! !");
}
}

### Повторная попытка после выполнения операции

Повторная попытка после выполнения операции — это ситуация, когда бизнес-операция завершается с ошибкой, а необходимые для повторной попытки данные сохраняются в базе данных (таблица: job_retry). Затем через расписание задач происходит автоматическая повторная попытка.
```Для классов, требующих повторной попытки, можно реализовать интерфейс `IRetrySupport` или наследовать от класса `AbstractRetrySupport`.

Интерфейс `IRetrySupport.java`
>
    public interface IRetrySupport {
        /**
         * Повторная попытка
         * @param retryContext контекст повторной попытки
         * @return результат повторной попытки: true | false
         */
        boolean retry(AfterwardRetryContext retryContext);
    }

**Пример реализации:** реализация через интерфейс `com.kvn.dal.core.afterward_retry.AfterwardRetryBizService.java`
>
    @Service
    public class AfterwardRetryBizService implements IRetrySupport {
        @Resource
        IJobRetryDao jobRetryDao;

        public void executeBiz() {
            System.out.println(DateTime.now() + "--" + Thread.currentThread().getName() + "---------------doBizJob2222--------");
            try {
                Thread.sleep(3000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Foo foo = new Foo(1001, "xxx");
            try {
                throw new RuntimeException("executeBiz异常,xxxxxxxxx");
            } catch (Exception e) {
                ArrayList<RetryParam> retryLs = new RetryParamListWrapper().buildRetryParam(foo).buildRetryParam("xxx").buildRetryParam("hehehe").toArrayList();
                JobRetry retry = JobRetry.createJobRetry(getClass(), "key001", retryLs);
                jobRetryDao.add(retry);
                throw e;
            }
        }
    }        @Override
        public Boolean retry(AfterwardRetryContext retryContext) {
            /** Реализация логики повторной попытки */
            String retryDataKey = retryContext.getRetryDataKey();
            List<RetryParam> paramLs = retryContext.getRetryParamLs();
            Foo foo = paramLs.get(0).restoreParam(Foo.class);
            String originParam1 = paramLs.get(1).restoreParam(String.class);
            String originParam2 = paramLs.get(2).restoreParam(String.class);
            // или
            Foo foo2 = retryContext.getRetryParamValueMap().get(Foo.class).get(0);
            String originParam1_ = retryContext.getRetryParamValueMap().get(String.class).get(0);
            String originParam2_ = retryContext.getRetryParamValueMap().get(String.class).get(1);
``````markdown
## Пример: способ наследования класса

`com.kvn.dal.core.afterward_retry.AfterwardRetryBestPracticeService.java`

```java
@Service
public class AfterwardRetryBestPracticeService extends AbstractRetrySupport {
    public void executeBiz() {
        System.out.println(DateTime.now() + "--" + Thread.currentThread().getName() + "---------------doBizJob2222--------");
        try {
            Thread.sleep(3000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Foo foo = new Foo(1001, "xxx");
        try {
            throw new RuntimeException("выполнение executeBiz завершилось ошибкой, xxxxxxxxx");
        } catch (Exception e) {
            this.retryEnqueue("key001", foo, "hehe", "утро");
            throw e; // При возникновении исключения завершаем выполнение бизнес-логики
        }
    }

    @Override
    public Boolean retry(AfterwardRetryContext retryContext) {
        // Реализация логики повторной попытки
        return true;
    }
}

План

    1. Поддержка управления задачами через интерфейс, позволяющий осуществлять мониторинг и управление задачами в режиме реального времени
    1. Расширение методов сериализации данных повторной попытки, поддерживающих JSON, Protostuff, Kryo и другие

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Описание недоступно Развернуть Свернуть
Apache-2.0
Отмена

Обновления (3)

все

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/kkk001-dal-job.git
git@api.gitlife.ru:oschina-mirror/kkk001-dal-job.git
oschina-mirror
kkk001-dal-job
kkk001-dal-job
master