«Построение колеса» — проектирование глобального контекста HTTP-запросов

Java задняя часть GitHub HTTP Netty
«Построение колеса» — проектирование глобального контекста HTTP-запросов

предисловие

этот разCicadaбыл обновлен до

v1.0.3.

В основном для решения двух проблем,#9 (Количество потоков Boss, кажется, установлено неправильно) #8 (Как вернуть чистое строковое содержимое вместо формата JSON?).

Итак, главное обновление на этот раз:

  • CicadaИспользуйте разумное распределение потоков для обработки потоков запросов на доступ и потоков ввода-вывода.
  • Поддерживает несколько методов ответа (ранее только json, теперь поддерживает текст).
  • Введено для того, чтобы удовлетворить вышеизложенноеcontext.
  • Грациозное отключение.

Среди них, я думаю, основным и наиболее полезным является этоContext, и рефакторинг большей части кода для этого.

Множественные методы ответа

в началеCicadaОтвечать только по умолчаниюjson, что действительно недостаточно гибко. Кроме того, в будущем мы планируем поддерживать синтаксический анализ шаблонов, поэтому лучше добавить его прямо в API, чтобы пользователи могли выбирать разные методы ответа.

Итак, скорректированный API выглядит следующим образом.

хочу вывестиtext/plainВремя.

@CicadaAction("textAction")
public class TextAction implements WorkAction {
    @Override
    public void execute(CicadaContext context, Param param) throws Exception {
        String url = context.request().getUrl();
        String method = context.request().getMethod();
        context.text("hello world url=" + url + " method=" + method);
    }
}

в то время как вывод ответаapplication/jsonКогда вам нужно только написать объект, который должен реагировать наjson()в методе.

Поэтому к исходному бизнес-действию также добавляется контекстный параметр:

/**
 * abstract execute method
 * @param context current context
 * @param param request params
 * @throws Exception throw exception
 */
void execute(CicadaContext context ,Param param) throws Exception;

Давайте посмотрим на этоContextкак это делается.

Cicada Context

Давайте сначала посмотрим, что можно сделать с этим контекстом.

Например, в некоторых сценариях нам нужно получить информацию заголовка в этом запросе, тогда мы можем передать этоContextОбъект получен напрямую.

Конечно, это не просто информация заголовка:

  • Получить заголовки запроса.
  • Установите заголовки ответа.
  • настраиватьcookie.
  • получить запросURL.
  • получить запросmethod(получить/отправить) и т. д.

Фактически, по этим характеристикам видно, что информация на самом деле такая же, как и та,请求、响应тесно связаны, и информация между запросами не должна мешать друг другу.

Такая особенность очень знакома, да, то естьThreadLocalЭта информация может быть сохранена для каждого потока независимо друг от друга.

На этот раз принцип ThreadLocal не будет подробно анализироваться, а будет обсуждаться только его применение в Cicada.

CicadaContext.class

Первый взглядCicadaContextОсновные переменные-члены и методы этого класса.

Переменные-члены — это два интерфейсаCicadaRequest、CicadaResponse, имя может сказать, что оно должно хранить данные запроса и ответа.

HttpDispatcher.class

Контекст, в котором вы хотите сохранить этот запрос, естественно, там, где распространяется реальный запрос.HttpDispatcher.

Два красных прямоугольника побольше.Первая часть — это инициализация и назначение контекста.

Вторая часть, естественно, заключается в разгрузке контекста.

Сначала посмотрите на инициализацию.

CicadaRequest cicadaRequest = CicadaHttpRequest.init(defaultHttpRequest) ;

Первый — инициализировать запрос:

CicadaHttpRequestЕстественно реализованоCicadaRequestинтерфейс:

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

ResponseТакже сочувствие.

Оба этих конкретных класса реализации имеют частные конструкторы, предотвращающие нарушение целостности извне.

Затем сохраните контекст текущего запроса вCicadaContextсередина.

CicadaContext.setContext(new CicadaContext(cicadaRequest,cicadaResponse));

Суть этой функции заключается в использованииThreadLocalхранитьCicadaContext.

    public static void setContext(CicadaContext context){
        ThreadLocalHolder.setCicadaContext(context) ;
    }
    
    private static final ThreadLocal<CicadaContext> CICADA_CONTEXT= new ThreadLocal() ;
    
    /**
     * set cicada context
     * @param context current context
     */
    public static void setCicadaContext(CicadaContext context){
        CICADA_CONTEXT.set(context) ;
    }

Ведение бизнеса и реагирование

Следующий шаг — обработать бизнес и вызвать разные API для разных ответов.

братьcontext.text()Сказать:

По сути, это установка соответствующего метода ответа и запись содержимого ответа.CicadaResponseизhttpContentсередина.

Вызывается после обработки заявкиresponseContent()Ответить:

responseContent(ctx,CicadaContext.getResponse().getHttpContent());

Фактически метод ответа и содержимое ответа, полученные в контексте, возвращаются клиенту.

выгрузить контекст

Последнее, но не менее важное, этовыгрузить контекст.

Если здесь обработка не производится, то по мере увеличения количества запросовThreadLocalВ нем хранится все больше и больше данных, что со временем приведет к переполнению памяти.

такCicadaContext.removeContext()Просто чтобы вовремя удалить текущий контекст.

изящное завершение работы

Наконец, был добавлен новый метод выключения.

На самом деле, используяHookфункция реализована.

Из-за текущегоCicadaОткрытые потоки не занимают слишком много ресурсов, поэтому закрыты только потоки, используемые Netty.

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

Суммировать

CicadaОбновлены 4 версии, и прототипы все есть.

Дальнейшие действия будут сосредоточены на реализации синтаксического анализа шаблонов и маршрутизации запросов аннотаций.MVCсерединаviewЭто почти то же самое.

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

GitHub.com/вместе ОС/…