Можно ли отправить запрос http с помощью директивы местоположения nginx? - PullRequest
0 голосов
/ 30 декабря 2018

Может быть, это тривиально, но я не нашел ничего значимого, или я не знал, где искать ...

(Как) можно ли отправить команду curl / любой другой, как толькокак запрашивается определенный путь?

Что-то в этом духе, но это действительно сработает:

location / {
curl --data 'v=1&t=pageview&tid=UA-XXXXXXXX-X&cid=123&dp=hit'  https://google-analytics.com/collect
}

Ответы [ 4 ]

0 голосов
/ 08 января 2019

Вот как я это сделал в конце концов - proxy_pass вместо curl - исходя из этого: https://github.com/vorodevops/nginx-analytics-measurement-protocol/tree/master/lua. Код предполагает openresty или просто установлен lua.Не уверен, что формат комментариев совместим (не тестировался), поэтому лучше удалить их перед использованием.

# pick your location 

location /example {

    # invite lua to the party

    access_by_lua_block  {

        # set request parameters

        local request = {
            v = 1,
            t = "pageview",

            # don' forget to put your own property here

            tid = "UA-XXXXXXX-Y",

            # this is a "unique" user id based on a hash of ip and user agent, not too reliable but possibly best that one can reasonably do without cookies

            cid = ngx.md5(ngx.var.remote_addr .. ngx.var.http_user_agent),
            uip = ngx.var.remote_addr,
            dp = ngx.var.request_uri,
            dr = ngx.var.http_referer,
            ua = ngx.var.http_user_agent,

            # here you truncate the language string to make it compatible with the javascript format - you'll want either the first two characters like here (e.g. en) or the first five (e.g en_US) with ...1, 5

            ul = string.sub(ngx.var.http_accept_language, 1, 2)
            }

        # use the location.capture thingy to send everything to a proxy

        local res = ngx.location.capture(  "/gamp",  {
        method = ngx.HTTP_POST,
        body = ngx.encode_args(request)
        })
    }
}


# make a separate location block to proxy the request away

location = /gamp {
    internal;
    expires epoch;
    access_log off;
    proxy_pass_request_headers off;
    proxy_pass_request_body on;
    proxy_pass https://google-analytics.com/collect;
}
0 голосов
/ 03 января 2019

То, что вы пытаетесь сделать - выполнить новый curl экземпляр для Google Analytics при каждом запросе URL на вашем сервере - неправильный подход к проблеме:

  1. Сам Nginx легко может обслуживать 10k + одновременных подключений в любой момент времени в качестве нижнего предела, т. Е. Как минимум, если вы все делаете правильно, см. https://en.wikipedia.org/wiki/C10k_problem.

  2. Вкл.с другой стороны, производительность fork, базового системного вызова , который создает новый процесс, который необходим, если вы хотите запускать curl для каждого запроса, равеночень медленный, порядка 1 000 разрядов в секунду в качестве верхнего предела, например, если вы все делаете правильно, это самый быстрый процесс, который когда-либо будет проходить, см. Ускорение разветвления больших процессов в Linux? .


Какое наилучшее альтернативное решение с улучшенной архитектурой?

  • Я рекомендую выполнить это с помощью пакетной обработки.Вы действительно ничего не получаете, используя Google Analytics в режиме реального времени, и 5-минутная задержка в статистике должна быть более чем достаточной.Вы можете написать простой скрипт на выбранном вами языке программирования, чтобы просмотреть соответствующие http://nginx.org/r/access_log,, собрать данные за требуемый период времени и сделать один пакетный запрос (и / или несколько отдельных запросов из одного процесса).) в Google Analytics с необходимой информацией о каждом посетителе за последние 5 минут.Вы можете запустить его как процесс-демон или как скрипт из задания cron, см. crontab(5) и crontab(1).

  • В качестве альтернативы, если вы все еще хотите обрабатывать данные в Google Analytics в режиме реального времени (что я не рекомендую, поскольку большинство этих сервисов реализовано на основе возможной согласованности ,это означает, что сама GA не обязательно гарантирует точную статистику в реальном времени за последние XX секунды / минуты / часы / и т. д.), тогда вы можете захотеть реализовать какой-нибудь демон для обработки статистики в реальном времени:

    • Я бы по-прежнему предложил использовать access_log в таком демоне, например, через эквивалент tail -f /var/www/logs/access_log в вашем любимом языке программирования, где вы открываете access_log файл в виде потока и обработка данных по мере поступления и по мере поступления.

    • В качестве альтернативы, вы можете реализовать этот демон, чтобы иметь сам интерфейс HTTP-запроса и дублировать каждый входящий rравносильно как вашему фактическому бэкэнду, так и этому дополнительному серверу.Вы можете мультиплексировать это через nginx с помощью не встроенных по умолчанию auth_request или add_after_body, чтобы создать «бесплатный» подзапрос для каждого запроса.Этот подзапрос отправляется на ваш сервер, например, в Go .На сервере должно быть не менее двух подпрограмм : одна будет обрабатывать входящие запросы в очередь (реализована через буферизованный строковый канал), немедленно отправляя ответ клиенту, чтобы не задерживать nginx в восходящем направлении;другой получал запросы от первого через chan string от первого, обрабатывая их по ходу и отправляя соответствующие запросы в Google Analytics.

В конечном счете, каким бы путем вы ни пошли, вам, возможно, все же захочется реализовать некоторый уровень пакетной обработки и / или регулирования, потому что я думаю, что в какой-то момент сама Google Analytics, вероятно, столкнется с регулированием, если вы продолжите отправлять запросы изодин и тот же IP-адрес на чрезмерной основе без какой-либо пакетной реализации на карту.Согласно Каков предел скорости для прямого использования API Google Analytics Measurement Protocol? , а также https://developers.google.com/analytics/devguides/collection/protocol/v1/limits-quotas, может показаться, что большинство библиотек применяют внутренние ограничения на количество запросов в секунду, которое онибуду отправлять в Google.

0 голосов
/ 05 января 2019

Если все, что вам нужно, это отправить запрос в Google Analytics, то это можно сделать проще: Nginx может на лету изменять HTML-код страницы, встраивая код GA перед закрывающим тегом </body>:

sub_filter_once on;

sub_filter '</body>' "<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-XXXXXXXX-X', 'auto');
ga('send', 'pageview');
</script></body>";

location / {
}

Этот модуль Nginx называется sub.

0 голосов
/ 01 января 2019

(как указано в комментариях), ngx_http_lua_module может это сделать!

location / {
          access_by_lua_block  {
            os.execute("/usr/bin/curl --data 'v=1&t=pageview&tid=UA-XXXXXXXX-X&cid=123&dp=hit'  https://google-analytics.com/collect >/dev/null 2>/dev/null") 
        }
}

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

>/dev/null 2>/dev/null &")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...