В один солнечный день вы интегрируете одну программу в другую. Вы просто следуете руководству. Он строится, запускается и развертывается в вашем кластере. А потом взрывается. Знакомо, не правда ли?
Сегодня я собираюсь рассказать вам историю о Opentracing Tracer и о том, как он может взорваться. Вот главные герои:
- Python tracer предоставлен Instana (ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: очень хороший инструмент, кстати!)
- Многопоточный воркер Python. Приложение на Python, которое запускает несколько процессов и контролирует их. Каждый процесс отвечает за обработку сообщений, поступающих из очереди. Сообщения включают SpanContext для кросс-процессной трассировки (да, мы хотим, чтобы все было видно).
Уже заметили виновника? Спойлер: «запускает несколько процессов». Разберем его пошагово:
1. Инициализация трассировщика. Он довольно стандартный и соответствует документации:
instana.tracer.init(instana_opts.Options(service=’myservice’))
Трассировщик создается в основном сценарии вместе с другими службами и конфигурациями. Предполагается, что это будет синглтон, общая служба, которая отправляет данные трассировки сборщику из всех потоков (и, надеюсь, из всех процессов).
2. Рабочие процессы запускаются с Popen.
3. Промежутки сообщаются обычным способом:
span = extract_tracing_span(carrier) with span: # do useful stuff here # at the end ‘span.__exit__()’ is called automatically # which executes sending span data to the collector
Все выглядит нормально, но пролетам коллектора Instana не сообщают. Почему? Ответ прост: трассировщик успешно инициализирован для родительского процесса. Но этот контекст не копируется в дочерние процессы. Таким образом, childred инициализировал свои собственные трассировщики с настройками по умолчанию и в основном начал отправлять промежутки в черную дыру.
Как решить эту проблему? Легко: перенесите инициализацию трассировщика из родительского процесса в каждый подпроцесс.
Мораль истории
Когда дело доходит до многопроцессного приложения, будьте предельно осторожны с синглтонами, которые создаются в родительском процессе. А если вы не можете передать их от родительского процесса к дочерним - создайте эти синглтоны в дочерних процессах, сделайте их локальными.