The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
bind AF_UNIX AF_INET помогите открыть сокет, !*! andribas, 12-Мрт-09, 00:38  [смотреть все]
Здравствуйте!
Помогите пожалуйста разобраться!

Использую библиотеку libevent для создания многопоточного демона на C
там есть функции <evhttp.h> - простой веб-сервер запускающий дочерние процессы на запросы методом epoll (linux).

Посмотрел исходники, там при создании сокета (socket) и соответственно bind используется тип AF_INET, то есть адрес:порт.

У меня есть два варианта -
1. использовать nginx и отправлять запросы оттуда методом proxy_pass на свой демон
2. подключаться напрямую к демону.

2-ой вариант работает, но чтобы не вытаскивать все наружу хочу рассмотреть  первый.
Производительность у демона и nginx примерно одинаковая - делал замеры.
Если же в proxy_pass использовать адрес:порт, то IPC происходит медленно, в 3-4 раза снижается производительность, чем если подключаться напрямую.
nginx создает свои worker_processes и у меня вопросы:

1. при отправке через nginx нужен ли epoll() демону?
2. если да, то можно ли использовать epoll() для совместного доступа к сокету типа AF_UNIX?
3. Если нет, то возможно создание пула процессов?
4. Какие будут накладные расходы? (производительность)

Как Вы понимаете, ключевое слово производительность.
Спасибо.

  • bind AF_UNIX AF_INET помогите открыть сокет, !*! angra, 00:56 , 12-Мрт-09 (1)
    >Как Вы понимаете, ключевое слово производительность.

    Нет, ключевое слово "каша" :)

    • bind AF_UNIX AF_INET помогите открыть сокет, !*! andribas, 08:58 , 12-Мрт-09 (2)
      >>Как Вы понимаете, ключевое слово производительность.
      >
      >Нет, ключевое слово "каша" :)

      Хорошо, если так не понятно, приведу куски кода.

      Это мой сервер-демон:

      #include <stdio.h>
      #include <event.h>
      #include <evhttp.h>

      void fhttpd_gencb(struct evhttp_request * evreq, void * arg);

      int main(int argc, char** argv)
      {
          struct event_base *evbase = NULL;
          struct evhttp *evhttp = NULL;
          unsigned short port = 9000;
          const char *host = "127.0.0.1";

          evbase = event_init();
          evhttp_set_gencb(evhttp, &fhttpd_gencb, NULL);
          evhttp_bind_socket(evhttp, host, port);
          event_base_dispatch(evbase);

          evhttp_free(evhttp);
          event_base_free(evbase);

          return 0;
      }

      Он рабочий, можете проверить. Привязывается к localhost:9000
      Вот кусок кода из evhttp_bind_socket():

      fd = socket(AF_INET, SOCK_STREAM, 0);
      r = bind(fd, ai->ai_addr, ai->ai_addrlen);

      Вот способы передачи запроса от nginx:

                  proxy_pass         http://127.0.0.1:9000/;
      либо
                  proxy_pass         http://unix:/tmp/backend.socket:/;


      • bind AF_UNIX AF_INET помогите открыть сокет, !*! alexx, 05:19 , 13-Мрт-09 (3)

        непонятно, причем тут epoll() и что такое совместный доступ к сокету
        у тебя какая-то либа (evhttp) делает http сервис? тебе не нравится, как она это делает ?

        • bind AF_UNIX AF_INET помогите открыть сокет, !*! alexx, 05:24 , 13-Мрт-09 (4)
            напиши еще, как epoll запускает дочерние процессы. он вообще-то этого не должен уметь, это всего лишь нотификация об эвентах , в частности на сокете ...


          • bind AF_UNIX AF_INET помогите открыть сокет, !*! andribas, 08:12 , 13-Мрт-09 (5)
            >  напиши еще, как epoll запускает дочерние процессы. он вообще-то этого
            >не должен уметь, это всего лишь нотификация об эвентах , в
            >частности на сокете ...

            Спасибо, теперь разобрался с этим. дочерних не запускается.
            Loop выглядит так:

            volatile event_gotsig;

            while (event_gotsig) {
              event_gotsig = 0;
              
              if (event_sigcb) {
                res = (*event_sigcb)();
                if (res == -1) {
                  errno = EINTR;
                  return (-1);
                }
              }
            }


            >непонятно, причем тут epoll() и что такое совместный доступ к сокету
            >у тебя какая-то либа (evhttp) делает http сервис? тебе не нравится, как она это делает ?

            Спасибо. epoll тут не при чем. Как писал товарищ выше у меня действительно каша.
            Ну если бы я точно знал, что мне мешает, я бы сам и понял как это сделать.

            Такой сценарий:
            1. Пользователь отправляет запрос на веб-сервер.
            2. Запрос попадает к nginx и он отдает его моей либе.
            3. Я его обрабатываю и отдаю обратно nginx.

            Производительность запросов статических файлов на тестовом компьютере - 20К/сек
            Для либы и для nginx.
            Если к либе делать доступ через nginx не через сокет, а TCP/IP, то ее производительность снижается до 6-7 К/сек.
            Мне не нравится, что я не могу отправить запрос либе методом IPC через сокет.
            И поэтому у меня вопрос - можно ли открывать сокет AF_UNIX вместо AF_INET.
            При этом на nginx у меня стоит workers=2. Надо ли делать 1?

            И какой производительности при этом ожидать вместо 20К/сек?

            • bind AF_UNIX AF_INET помогите открыть сокет, !*! angra, 18:45 , 13-Мрт-09 (6)
              Теперь значительно понятней что вообще хотите сделать и в чем проблема. Пока только такие идеи:
              Можно попробовать самостоятельно открыть AF_UNIX сокет и передавать его в функции libevt. Однако работа с AF_UNIX несколько отличается от работы с AF_INET так что работоспособность будет зависеть от кода самой libevt.
              Использование профайлера в обоих вариантах подключения может помочь найти тормозящий участок кода.
              Возможно играет роль буферизация вывода.



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру