# Шаблон розгортання — Gateway

> Дізнайтеся, чому і як спочатку надсилати сигнали до єдиної точки доступу OTLP, а звідти до бекендів

---

LLMS index: [llms.txt](/llms.txt)

---

Схема розгортання шлюзу-колектора складається з застосунків або інших колекторів, які надсилають телеметричні сигнали до єдиної точки кінцевого доступу [OTLP](/docs/specs/otlp/). Ця точка доступу надається одним або кількома екземплярами колектора, що працюють як самостійний сервіс, наприклад, у Kubernetes deployment. Зазвичай точка доступу надається для кожного кластера, центру обробки даних або регіону.

У загальному випадку ви можете використовувати готовий балансувальник навантаження для розподілу навантаження між Колекторами:

![Концепція розгортання шлюзу](../../img/otel-gateway-sdk.svg)

Для випадків використання, коли дані телеметрії необхідно обробляти в певному колекторі, використовуйте дворівневу конфігурацію. Колектор першого рівня має конфігурований конвеєр із [експортером з балансуванням навантаження з урахуванням ідентифікатора трасування/назви сервісу][lb-exporter]. На другому рівні кожен колектор отримує та обробляє телеметрію, яка може бути спрямована саме до нього. Наприклад, ви можете використовувати експортер з балансуванням навантаження на першому рівні для надсилання даних до колектора другого рівня, налаштованого з [процесором вибірки наприкінці][tailsample-processor], щоб усі відрізки для певного трасування досягали того самого екземпляра колектора, де застосовується політика вибіркового відбору наприкінці.

На наступній діаграмі показано цю конфігурацію з використанням експортера з балансуванням навантаження:

![Розгортання шлюзу з експортером балансування навантаження](../../img/otel-gateway-lb-sdk.svg)

1. У застосунку SDK налаштовано на надсилання даних OTLP до центрального місця.
2. Колектор налаштований на використання експортера з балансуванням навантаження для розподілу сигналів між групою Колекторів.
3. Колектори надсилають телеметричні дані до одного або кількох бекендів.

## Приклади {#examples}

Наступні приклади показують, як налаштувати шлюз-колектор із загальними компонентами.

### NGINX як "готовий" балансувальник навантаження {#nginx-as-an-out-of-the-box-load-balancer}

Припустимо, у вас є три колектори (`collector1`, `collector2` та `collector2`), налаштовані, і ви хочете балансувати трафік між ними за допомогою NGINX, ви можете використовувати наступну конфігурацію:

```nginx
server {
    listen 4317 http2;
    server_name _;

    location / {
            grpc_pass      grpc://collector4317;
            grpc_next_upstream     error timeout invalid_header http_500;
            grpc_connect_timeout   2;
            grpc_set_header        Host            $host;
            grpc_set_header        X-Real-IP       $remote_addr;
            grpc_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

server {
    listen 4318;
    server_name _;

    location / {
            proxy_pass      http://collector4318;
            proxy_redirect  off;
            proxy_next_upstream     error timeout invalid_header http_500;
            proxy_connect_timeout   2;
            proxy_set_header        Host            $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

upstream collector4317 {
    server collector1:4317;
    server collector2:4317;
    server collector3:4317;
}

upstream collector4318 {
    server collector1:4318;
    server collector2:4318;
    server collector3:4318;
}
```

### Експортер балансування навантаження {#load-balancing-exporter}

Для конкретного прикладу централізованої моделі розгортання Колектора спочатку розглянемо експортер з балансуванням навантаження. Він має два основні поля конфігурації:

- `resolver` визначає де знайти підлеглі (downstream) Колектори або бекенди. Якщо ви використовуєте субключ `static`, вам треба вручну вказати всі URL-адреси Колекторів. Інший підтримуваний резолвер — це DNS резолвер, який періодично перевіряє оновлення та виявляє IP-адреси. Для цього типу резолвера підключення `hostname` вказує імʼя хосту для запиту, щоб отримати список IP-адрес.
- Полем `routing_key` вказує експортеру маршрутизувати відрізки до конкретних підлеглих Колекторів. Якщо ви встановите це поле на `traceID`, експортер з балансуванням навантаження експортує відрізки на основі їх `traceID`. В іншому випадку, якщо ви використовуєте `service` як значення для `routing_key`, він експортує відрізки на основі назви їх сервісу, що корисно при використанні конекторів, таких як [конектор метрик відрізків][spanmetrics-connector], щоб усі відрізки сервісу надсилалися до одного і того ж підлеглого Колектора для збору метрик, гарантуючи точні агрегування.

Колектор першого рівня, що обслуговує точку доступу OTLP, буде налаштований, як показано нижче:

    <ul class="nav nav-tabs" id="tabs-0" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-00-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-00-00" role="tab"
          data-td-tp-persist="static" aria-controls="tabs-00-00" aria-selected="true">
        Static
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-00-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-00-01" role="tab"
          data-td-tp-persist="dns" aria-controls="tabs-00-01" aria-selected="false">
        DNS
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-00-02-tab" data-bs-toggle="tab" data-bs-target="#tabs-00-02" role="tab"
          data-td-tp-persist="dns with service" aria-controls="tabs-00-02" aria-selected="false">
        DNS with service
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-0-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-00-00" role="tabpanel" aria-labelled-by="tabs-00-00-tab" tabindex="0">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">receivers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">otlp</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocols</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">grpc</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">endpoint</span><span class="p">:</span><span class="w"> </span><span class="m">0.0.0.0</span><span class="p">:</span><span class="m">4317</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">exporters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">loadbalancing</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocol</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">otlp</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">tls</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">insecure</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">resolver</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">static</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostnames</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="l">collector-1.example.com:4317</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="l">collector-2.example.com:5317</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="l">collector-3.example.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">service</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">pipelines</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">traces</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">receivers</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">otlp]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">exporters</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">loadbalancing]</span><span class="w">
</span></span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-00-01" role="tabpanel" aria-labelled-by="tabs-00-01-tab" tabindex="0">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">receivers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">otlp</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocols</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">grpc</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">endpoint</span><span class="p">:</span><span class="w"> </span><span class="m">0.0.0.0</span><span class="p">:</span><span class="m">4317</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">exporters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">loadbalancing</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocol</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">otlp</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">tls</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">insecure</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">resolver</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">dns</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">collectors.example.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">service</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">pipelines</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">traces</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">receivers</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">otlp]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">exporters</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">loadbalancing]</span><span class="w">
</span></span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-00-02" role="tabpanel" aria-labelled-by="tabs-00-02-tab" tabindex="0">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">receivers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">otlp</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocols</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">grpc</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">endpoint</span><span class="p">:</span><span class="w"> </span><span class="m">0.0.0.0</span><span class="p">:</span><span class="m">4317</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">exporters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">loadbalancing</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">routing_key</span><span class="p">:</span><span class="w"> </span><span class="l">service</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocol</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">otlp</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">tls</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">insecure</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">resolver</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">dns</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">collectors.example.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">5317</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">service</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">pipelines</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">traces</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">receivers</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">otlp]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">exporters</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">loadbalancing]</span><span class="w">
</span></span></span></code></pre></div>
    </div>
</div>


Експортер балансування навантаження генерує [метрики](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/loadbalancingexporter#metrics), включаючи `otelcol_loadbalancer_num_backends` та `otelcol_loadbalancer_backend_latency`, які ви можете використовувати для моніторингу справності та продуктивності Колектора точки доступу OTLP.

## Компроміси {#trade-offs}

Переваги:

- Розділення обовʼязків, таких як централізоване управління обліковими даними
- Централізоване управління політиками (наприклад, фільтрація певних логів або вибірковий відбір)

Недоліки:

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

[lb-exporter]: https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/loadbalancingexporter
[tailsample-processor]: https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/tailsamplingprocessor
[spanmetrics-connector]: https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/spanmetricsconnector

## Кілька Колекторів та принцип єдиного записувача {#multiple-collectors-and-the-single-writer-principle}

Всі потоки даних метрик в OTLP повинні мати [єдиного записувача](/docs/specs/otel/metrics/data-model/#single-writer). При розгортанні декількох Колекторів у конфігурації шлюзу важливо переконатися, що всі потоки метрик мають єдиного записувача і глобальний унікальний ідентифікатор.

### Потенційні проблеми {#potential-problems}

Одночасний доступ з декількох застосунків, які змінюють або звітують про ті самі дані, може призвести до втрати даних або погіршення їх якості. Наприклад, ви можете побачити неузгоджені дані з декількох джерел на одному ресурсі, де різні джерела можуть перезаписати один одного, оскільки ресурс не має однозначної ідентифікації.

Існують закономірності в даних, які можуть дати певне уявлення про те, чи відбувається це чи ні. Наприклад, при візуальному огляді серія з незрозумілими прогалинами або стрибками в одній серії може свідчити про те, що кілька колекторів надсилають одну й ту ж вибірку. Ви також можете побачити помилки у вашому бекенді. Наприклад, у бекенді Prometheus:

`Error on ingesting out-of-order samples`

Ця помилка може вказувати на те, що в двох завданнях існують однакові цілі, а порядок міток часу неправильний. Наприклад:

- Метрика `M1` отримана в `T1` з міткою часу 13:56:04 зі значенням `100`.
- Метрика `M1` отримана о `T2` з міткою часу 13:56:24 зі значенням `120`
- Метрика `M1` отримана о `T3` з часовою міткою 13:56:04 зі значенням `110`
- Метрика `M1` отримана о 13:56:24 зі значенням `120
- Метрика `M1`, отримана о 13:56:04 зі значенням `110

### Поради {#best-practices}

- Використовуйте [обробник атрибутів Kubernetes](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/k8sattributesprocessor) для додавання міток до різних ресурсів Kubernetes.
- Використовуйте [процесор виявлення ресурсів](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/resourcedetectionprocessor/README.md) для виявлення інформації про ресурси на хості та збору метаданих про ресурси.

## Наступні кроки {#next-steps}

Дізнайтеся, як [поєднати](/docs/collector/deploy/other/agent-to-gateway/) шаблони агента та шлюзу для створення надійної та масштабованої архітектури Колектора.
