Я могу отрегулировать запросы, выполненные распределенным приложением?

Мое приложение делает Запросы к веб-сервису; существует макс. уровень запросов, которые обработает поставщик, таким образом, я должен буду снизить скорость их.

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

Теперь, мы мигрируем от единственного сервера до кластера, таким образом, существует две копии выполнения приложения.

  • Я не могу продолжать проверять на максимальную нагрузку в коде приложения, потому что эти два объединенные узла могли бы превысить позволенную загрузку.
  • Я не могу просто уменьшить нагрузку на каждый сервер, потому что, если другой узел неактивен, первый узел может отослать больше запросов.

Это - среда JavaEE 5. Что лучший способ состоит в том, чтобы отрегулировать запросы, которые отсылает приложение?

11
задан Jerry Coffin 24 February 2010 в 22:57
поделиться

5 ответов

Поскольку вы уже находитесь в среде Java EE, вы можете создать MDB, который обрабатывает все запросы к веб-сервису на основе очереди JMS. Экземпляры приложения могут просто отправлять свои запросы в очередь, а MDB принимает их и вызывает веб-сервис.

Очередь может быть настроена с соответствующим количеством сеансов, которые ограничивают одновременный доступ к вашему веб-сервису, таким образом, ваше регулирование обрабатывается через конфигурацию очереди.

Результаты могут быть возвращены через другую очередь (или даже очередь для каждого экземпляра приложения).

6
ответ дан 3 December 2019 в 08:55
поделиться

MEF управляет временем жизни создаваемых компонентов. В данном примере проблема заключается в том, что объект, который требуется утилизировать, фактически не создается MEF. Возможно, вы хотите сделать что-то подобное:

public class ComponentExporter : IDisposable
{
    private IMyInterface _component;

    [Export]
    public IMyInterface Component
    {
        get
        {
            if (_component != null)
            {
                _component = new MyImplementation();

                // ...
            }
            return _component;
        }
    }

    public void Dispose()
    {
        if (_component != null)
        {
            _component.Dispose();
        }
    }
}

ComponentExporter - это класс, фактически созданный MEF, и если он реализует IDisposable, то MEF распорядится им с контейнером. В этом примере ComponentExporter утилизирует созданный компонент при его утилизации, что, вероятно, является желаемым.

Конечно, было бы проще просто поместить экспорт непосредственно в класс MyImplementation. Я предполагаю, что у вас есть какая-то причина не делать этого, но так бы это выглядело:

[Export(typeof(IMyInterface))]
public class MyImplementation : IMyInterface, IDisposable
{
    // ...
}

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

-121--3176620-

Чтобы увеличить силу пароля, следует использовать более широкий спектр символов. Если у вас есть 8-10 символов в пароле становится довольно трудно взломать. Хотя увеличение его длины сделает его более безопасным, только если вы используете числовые/алфавитные/другие символы.

SHA1 является другим алгоритмом хеширования (один путь шифрование), он медленнее, но имеет более длинный дайджест. (закодированное сообщение) (160 бит), где MD5 имеет только 128 бит.

Тогда SHA2 еще более безопасно, но он использовал меньше.

-121--1000404-

Многие способы сделать это: у вас может быть «координационный агент», который отвечает за передачу «токенов» серверам. Каждый «токен» представляет разрешение на выполнение задачи и т.д. Каждому приложению необходимо запросить «маркеры» для размещения вызовов.

После того, как приложение уничтожит свои маркеры, оно должно попросить еще немного, прежде чем снова перейти к веб-службе.

Конечно, все это усложняется, когда существуют требования в отношении синхронизации каждого вызова, выполняемого каждым приложением из-за параллелизма с веб-службой.

Можно положиться на RabbitMQ , так как доступны привязки Messaging рамки: Java.

2
ответ дан 3 December 2019 в 08:55
поделиться

Я рекомендую использовать beanstalkd для периодической перекачки коллекции запросов (заданий) в трубу (очередь), каждый с соответствующей задержкой. Любое количество "рабочих" потоков или процессов будет ждать следующего запроса, и если рабочий завершит работу раньше, он сможет забрать следующий запрос. Недостатком является то, что нет явного распределения нагрузки между рабочими, но я обнаружил, что распределение запросов из очереди было хорошо сбалансировано.

2
ответ дан 3 December 2019 в 08:55
поделиться

N узлов должны общаться. Существуют различные стратегии:

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

В зависимости от того, насколько высоко вы планируете масштабировать систему в дальнейшем, та или иная стратегия может быть лучшей. Для двух узлов самой простой является широковещательная, но с увеличением числа узлов начинаются проблемы (вы будете тратить больше времени на широковещательную рассылку и ответы на широковещательные запросы, чем на реальное выполнение WS-запросов).

Как узлы будут общаться, зависит от вас. Вы можете открыть TCP-трубу, вы можете транслировать UDP, вы можете сделать полноценный WS только для этой цели, вы можете использовать протокол обмена файлами. Что бы вы ни делали, вы больше не находитесь внутри процесса, поэтому все заблуждения распределенных вычислений применимы.

1
ответ дан 3 December 2019 в 08:55
поделиться

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

Моим обычным решением является JBossCache, отчасти потому, что он поставляется в комплекте с JBoss AppServer, а также потому, что он довольно хорошо справляется с этой задачей. Вы можете использовать его как своего рода распределенную хеш-карту, записывая статистику использования с различной степенью детализации. Обновления в ней могут выполняться асинхронно, поэтому она не замедляет работу.

JBossCache обычно используется для тяжелого распределенного кэширования, но мне он нравится и для более легких задач. Это чистый java, и не требует никаких манипуляций с JVM (в отличие от Terracotta).

1
ответ дан 3 December 2019 в 08:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: