http_handlersocket_json_module

    О назначении модуля можно догодаться из названия. О HandlerSocket говорят много и на разных языках (в основном на японском, английском и последнее время немного на русском).
    Модуль NGX_HTTP_HANDLERSOCKET_JSON_MODULE обращается к данным MySQL через протокол HandlerSocket и отдает данные в формате JSON. Область применения AJAX.
    Исходники

    О конфигурации, особенностях и ограничениях можно почиать ниже.

    Инсталляция

    Инсталляция стандартная, конфигурирование с опцией --add-module:

    ./configure --add-module=/full/path/to/dir/nginx_http_handlersocket_json_module
    далее
    make & sudo make install;
    Конфигурация

    Конфигурация определена в контексте локейшена. Пример ниже:
    location ~ /json/(.+)/{
    hs_json;
     
     hs_json_host  127.0.0.1;
     hs_json_port  9998;
     
     hs_json_db test;
     hs_json_table hs_test;
     
     hs_json_index code;  # PRIMARY default
       hs_json_fields keyid,value,code;
     
     hs_json_op "="; # = default
     hs_json_limit 10; # default 10
     
    set $hs_request $1;
    }


    Более подробно:

    hs_json; — активирует модуль

    Параметры соединения (хост и порт по умолчанию localhost:9998, так что можно не указывать, а вот имя базы данных указать прийдется обязательно):
    hs_json_host 127.0.0.1;
    hs_json_port 9998;
    hs_json_db test;

    Таблица данных и список выбранных полей (все параметры обязательные):
    hs_json_table hs_test;
    hs_json_fields keyid,value,code;

    Индекс, по которому должна осуществляться выборка:
    hs_json_index code;
    При отсутствии данной опции используется PRIMARY индекс.

    Операция, это условие по выборке данных.
    hs_json_op "="; # = default
    Возможны следующие операции: =, <, <=, >, >=
    По умолчанию, при отсутствие директивы применяется операция «равно»

    Ограничение на вывод данных:
    hs_json_limit 10;
    При отсутствии директивы 10.

    Условие на выбор данных, осуществляется через переменную $hs_request. Данные можно назначить как часть урла:
    location ~ /json/(.+)/{
    set $hs_request $1;
      }
    Как переменную GET или COOKIES:
    location ~ /json {
    set $hs_request $get_id;
    }

    ПРИМЕР:
    Пусть необходимо выбрать города по нескольким первым буквам. Список ограничен 10 позициями. Города выбираются из таблицы:
    CREATE TABLE city {
    name VARCHAR(45),
    id INT,
    PRIMARY (id),
    KEY `name` (`name`),
    }
    Если использовать следующую часть конфига:
    location ~ /city/(.+)/${
    ..... // параметры соединения
    hs_json_index name,
    hs_json_fields name;
    hs_json_op ">=";
    set $hs_request $1;
    }

    то это будет аналог запроса: SELECT * FROM cities WHERE city_name >= '$hs_request' LIMIT 10
    Запрос будет браться из последней части урл, Наприме для запроса: http: // myserver.com/city/san/ будет сформирован набор даных:
    [{"name":"San Amaro"},{"name":"San Andreas"},{"name":"San Andrs"} ... ]
    Ошибки

    1. 500 — неправильная конфигурация, ошибка реализации протокола или ошибка ответа HS
    2. 503 — нет соединения с HS или ошибки ввода/вывода
    Если ключ не найден — отдается пустой ответ: {[]}, 404 ошибка не формируется.

    Ограничения
    • Величина выходного буфера должна быть не более 1К (1024), регулируется #define BUFF_SIZE. Для моих задач больше не нужно.
    • Можно использовать только простой индекс (выборка данных только по одному критерию)
    • пока русские буквы не реализованы (UTF-8), устранится в ближайшее время

    О всех багах в багрепорте, о фичах и пожеланиях в личку или комменты

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 52

      +1
      Достаточно интересно.
      Бенчмарки будут? :)
        0
        1200 запросов в сек — хватит?
          0
          ошибся — всего 600
            0
            600 тоже отлично.
              0
              600 на десктопе при одном потоке
              на продакшене (2х4) вполне возможно до 1200
                0
                имхо очень мало и не понятно на каком железе, у меня nginx+tornado(который работает с hs) делает примерно 1500 запросов/сек на Xeon 3050(2ггц), но и этого мало увы очень 8( при том что сам HS дает очень неплохие результаты
                  0
                  тестировалось на слабом железе
            0
            ИМХО, думаю на данный момент для автозаполнения полей это лучшее решение.
              +2
              Не уверен.
              Да, это клево, но программирование на конфиге джинкса вносит дополнительный слой логики, что не хорошо.
                0
                как сказать…

                у меня php-фреймворк завязан на логике ngx конфига. Производительность за счет этого довольно-таки высокая. см статью habrahabr.ru/blogs/hi/109050/
                  0
                  Ага, читал.
                  Но чем проще тем лучше :)
                  Все равно спасибо — мало ли когда пригодится.
                    0
                    все зависит что разрабатываешь. Если визитки — то ни когда не пригодится. Если проекты с притензией посещаемости от 50К, то как выход…
                      +3
                      Тоже спорно. При очень больших нагрузках у вас будет пул серверов за лоад балансером и какой фреймворк выбран окажется второстепенным вопросом; первостепенным будет возможность масштабирования данных в архитектуре приложения.
                        +1
                        и все же есть разница 60 — 80 мс или 20-30 мс
                        ставим четыре сервера за балансером или два???
                    0
                    для этого и реализовывалось :)
                    0
                    поправьте если я не прав, но
                    CREATE TABLE city

                    и
                    FROM cities


                    как то не сходятся, правильно будет

                    FROM city
                      +1
                      догодаться

                      Это просто невыносимо! :)
                        +3
                        а как вам
                        параметры коннекции

                          +1
                          там в гите тоже приколы

                          must to configure
                          can to use
                          can to increase
                            0
                            есть желание помочь проекту — двери всегда открыты
                              0
                              кинь мыло, я добавлю тебя в гит, напишешь хороший README
                          0
                          «параметры коннекции» доставили. слово «соединение» забыли, да?
                            0
                            поправлю — спасибо
                            0
                            А можете привести пример как выполнить 2 запроса к базе? Имеются введу запросы, в которых параметры второго зависят от того, что вернёт первый. Например, надо получить список документов пользователя:
                            1. SELECT user_id по session_id из COOKIES
                            2. SELECT документов по user_id полученном в предыдущем запросе
                              0
                              на каждый запрос к БД свой запрос по HTTP
                              тут без кода на клиенте (js) не обойтись
                                0
                                Описанную ситуацию невозможно решить при помощи js кода на клиента, тут так или иначе надо на стороне сервера выполнять 2 последовательных запроса.

                                Очень жаль, что нет поддержки такого функционала. Это вносит серьёзные ограничения в плане использования модуля. Может всё-таки возможно как-то добавить эту функциональность? Был бы вам очень благодарен!
                                  0
                                  возможно но надо подумать как
                                    0
                                    но есть более первоочередные задачи по проекту
                                      0
                                      Я по этому поводу создал issue на GitHub: github.com/akalend/ngx_http_handlersocket_json_module/issues/1
                                        0
                                        спасибо
                                          0
                                          там нужно иметь приблизительно такой конфиг:
                                          hs_json_sub_fieldlist
                                          hs_json_sub_table
                                          hs_json_sub_index
                                          hs_json_sub_op

                                          При использовании subrequest — limit фвтоматически =1

                                  0
                                  Я правильно понимаю, что нет постоянных соединений с базой и на каждый запрос от клиента устанавливается соединение с базой, затем непосредственно выполняется запрос, затем соединение с базой закрывается? Не вижу в коде закрытия соединения…

                                  Вся работа с базой судя по всему происходит в блокирующем режиме?
                                    0
                                    да, на каждый запрос свое соединение, так надежней.
                                      0
                                      работа с БД в блокирующем режиме,
                                      но так же реализованы модули memcached & redis (см их исходники).
                                      не вижу необходимости усложнения.
                                        +2
                                        Насколько я знаю, «родной» ngx_http_memcached_module работает в асинхронном режиме с использованием upstream-функционала nginx'а.
                                        А то, что всякие поделки работают в блокирующем режиме лишь означает, что их не стоит серьезно рассматривать как кандидатов в production серьезных проектов.
                                          0
                                          на сяет редиса и мемкеша ступил — там сделано через апстрим
                                            +1
                                            я думал, как сделать upstream — но не получается, из-за того что нужно формировать JSON, т.е. обработать каждую «запись» в цикле,
                                            а не отдавать все напрямую по одному ключу, как это реализовано в модуле memcached или редис.

                                            год назад я пытался написать модуль redis_json_module (забирать не по GET а по POP) как upstream, но у меня так и не вышло. Возможно обработать лишь одну итерацию и невозможно сформировать рекордсет. А может я что-то делал не так, нет хороших учителей.

                                            что касается неблокирующего в/в — то я этот вопрос проработаю, спасибо за идею. Спасибо что заглянули в исходники.
                                              0
                                              Я думаю, идеи можно почерпнуть из уже имеющихся модулей тут (например Postgres-модуль, хотя его исходники не смотрел).
                                                0
                                                посмотрю, спасибо
                                                  0
                                                  глянул быстрым взглядом, кой что можно взять, спасибо
                                                0
                                                если будет неблокирующий режим, то можно держать постоянное соединение с базой. Открываем на этапе запуска, закрываем при перезагрузки. Скорость обмена возрастет — это несомненно.
                                                  0
                                                  Возможно, лучшим вариантом будет использование модуля HttpUpstreamKeepaliveModule
                                                    0
                                                    изучу, но чуть позже
                                                    я смотрел исходники этого модуля,
                                            0
                                            А отлов инъекций только регулярный выражением в location?
                                            Или подставляемое значение в запрос проходит Фильтруется через какую-нибудь real_escape_string()?

                                            Спасибо
                                              0
                                              Извините за ошибки — я с телефона
                                                0
                                                каких инъекций?
                                                приведи мне пример хоть одной инъекции в HS?
                                                  0
                                                  Изучил HS, вопрос отпал, спасибо!
                                                0
                                                Программист на Nginx )))

                                                А вообще то, что запросы выполняются в блокирующем режиме это конечно эпик фейл…
                                                  0
                                                  УГ какое-то. Приложение потеряет целостность. Давайте тогда сразу всё перепишем в виде модуля к nginx…
                                                    0
                                                    а можно расшифровать?
                                                      0
                                                      УГ = Унылое Говно. Кэп.
                                                        0
                                                        что нужно сделать чтоб это было лучше?

                                                    Only users with full accounts can post comments. Log in, please.