Как корректно перезапустить django, работающий fcgi позади nginx?

[11175] Этот ответ [11110] wiki сообщества [11110]. Если вы чувствуете, что это может быть улучшено, не стесняйтесь [11111] отредактируйте его [11111]! [11175] [11156] Предыстория: что является дополнительным? [11156] [11176] В Swift [11112] [ 1126] [11112] является [11113] общим типом [11113], который может содержать значение (любого вида) или вообще не имеет значения. [11176] [11177] Во многих других языках программирования особое значение «дозорного» часто используется для указания отсутствия [11132] значения [11132]. В Objective-C, например, [1127] (нулевой указатель [11114] [11114]) указывает на отсутствие объекта. Но это становится более сложным при работе с примитивными типами - следует ли использовать [1128], чтобы указать отсутствие целого числа, или, возможно, [1129] или какое-либо другое целое число? Если какое-либо конкретное значение выбрано так, чтобы оно означало «no integer», это означает, что он больше не может считаться значением [11133] [11133]. [11177] [11178] Swift - это безопасный тип языка, что означает, что язык помогает вам четко понимать типы ценностей, с которыми может работать ваш код. Если часть вашего кода ожидает String, тип безопасности предотвращает передачу Int Int по ошибке. [11178] [11179] В Swift [11250] [11134] любой тип [11134] можно сделать необязательным [11250]. Необязательное значение может принимать любое значение от исходного типа [11115] [11135] или [11135] [11115] специальное значение [1130]. ​​[11179] [11180] Опционы определяются с суффиксом [1131] типа: [11180]

private fun sendNotification() {
    val notificationId = 100
    val chanelid = "chanelid"
    val intent = Intent(this, MainActivity::class.java)
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
    val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // you must create a notification channel for API 26 and Above
        val name = "my channel"
        val description = "channel description"
        val importance = NotificationManager.IMPORTANCE_DEFAULT
        val channel = NotificationChannel(chanelid, name, importance);
        channel.setDescription(description);
        // Register the channel with the system; you can't change the importance
        // or other notification behaviors after this
        val notificationManager = getSystemService(NotificationManager::class.java)
        notificationManager.createNotificationChannel(channel)
    }

    val mBuilder = NotificationCompat.Builder(this, chanelid)
            .setSmallIcon(R.drawable.ic_notification)
            .setContentTitle("Want to Open My App?")
            .setContentText("Open my app and see good things")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true) // cancel the notification when clicked
            .addAction(R.drawable.ic_check, "YES", pendingIntent) //add a btn to the Notification with a corresponding intent

    val notificationManager = NotificationManagerCompat.from(this);
    notificationManager.notify(notificationId, mBuilder.build());
}
[11181] Отсутствие значения в необязательном указывается в [1132]: [11181] [11182] (Обратите внимание, что это [1133] не совпадает с [1134] в Objective-C. В Objective-C [1135] имеется отсутствие действительного указателя объекта [11136] [11136], в Swift, Optionals (11116) Возможно, [11116].) [11182]
[11157] Почему я получил «[11137] фатальную ошибку: неожиданно найден nil в то время как разворачивание необязательного значения [11137] "? [11157] [11183] Чтобы получить доступ к необязательному значению (если оно есть вообще), вам нужно [11251] развернуть [11251] его. Необязательное значение может быть развернуто безопасно или принудительно. Если вы принудительно развернете опцию, и она [11138] не имеет значения [11138], ваша программа выйдет из строя с указанным выше сообщением. [11183] [11184] Xcode покажет вам сбой, выделив строку кода. Проблема возникает в этой строке. [11184] [11185] [11117] [11170] [11170] [11117] [11185] [11186] Этот сбой может происходить с двумя различными видами развязывания силы: [11186] [11162] 1. Explicit Force Unwrapping [11162] [11187] Это делается с оператором [1136] на опциональном. Например: [11187]

[11188] Как здесь [1137] здесь [1138], вы получите крушение на линии, где вы принудительно разворачиваете его. [11188] [11163] 2. Неявно отключенные опции [11163] [11189] Они определены с помощью [1139], а не [1140] после типа. [11189]

[11190] Предполагается, что эти дополнительные элементы содержат значение. Поэтому всякий раз, когда вы получаете доступ к неявно развернутому факультативному, он автоматически будет принудительно развернут для вас. Если он не содержит значения, он сработает. [11190] [115] [11191] Чтобы определить, какая переменная вызвала сбой, вы можете удерживать ⌥ , показывая это определение, где вы можете найти необязательный тип. [11191] [11192] [11171] [11171] [11192] [11193] IBOutlets, в частности, обычно являются неявно развернутыми опциями. Это связано с тем, что ваш xib или раскадровка свяжет выходы во время выполнения [11139] после [11139] инициализации. Поэтому вы должны убедиться, что вы не получаете доступ к розеткам до их загрузки. Вы также должны проверить правильность соединений в вашем файле раскадровки / xib, в противном случае значения будут [1141] во время выполнения и, следовательно, сбой, когда они неявно разворачиваются. [11193]


[11158] Когда мне нужно принудительно развернуть Необязательный? [11158] [11164] Explicit Force Unwrapping [11164] [11194] Как правило, вы никогда не должны принудительно принудительно разворачивать опцию с помощью оператора [1142]. Могут быть случаи, когда использование [1143] приемлемо - но вы должны использовать его только когда вы на 100% уверены, что опционально содержит значение. [11194] [11195] Хотя [11140] может [11140] быть местом, где вы можете использовать развертывание силы, как вы знаете для факта [11141] [11141], что необязательный содержит значение - нет [11142] одиночного [ 11142], где вы не можете безопасно разворачивать эту опцию вместо этого. [11195] [11196] [11131] [11131] [11196] [11165] Неявно разобранные опции [11165] [11197] Эти переменные сконструированы так, что вы можете отложить их назначение до более позднего времени в своем коде. Это [11143] ваша [11143] ответственность за то, чтобы они имели ценность, прежде чем вы к ним обращались. Однако, поскольку они связаны с развертыванием силы, они по-прежнему по своей сути небезопасны, поскольку они [11144] предполагают, что [11144] ваша ценность не равна нулю, хотя присвоение значения nil действительно. [11197] [11198] Вы должны использовать неявно развернутые опции как [11145] в последней инстанции [11145]. Если вы можете использовать [11118] ленивую переменную [11118] или предоставить значение по умолчанию [11119] по умолчанию [11119] для переменной - вы должны сделать это вместо использования неявно развернутого необязательного. [11198] [11199] Однако существует несколько сценариев [11120], в которых неявно развернутые опции являются полезными [11120], и вы все еще можете использовать различные способы безопасного их развертывания, как указано ниже, но вы должны [11146] всегда [11146] используйте их с должной осторожностью. [11199]
[11159] Как я могу безопасно иметь дело с опциями? [11159] [11200] Самый простой способ проверить, содержит ли опциональное значение, сравнить его с [1144]. [11200] [116] [11201] Однако в 99,9% случаев, когда вы работаете с опциями, вы действительно захотите получить доступ к содержащемуся в нем значению, если он содержит один. Для этого вы можете использовать [11147] Необязательное связывание [11147]. [11201] [11166] Необязательное связывание [11166] [11202] Необязательное связывание позволяет проверить, содержит ли опциональное значение значение, и позволяет назначить развернутое значение новой переменной или константе. Он использует синтаксис [1145] или [1146], в зависимости от необходимости изменения значения новой переменной после привязки к ней. [11202] [11203] Например: [11203] [117] [11204] Что это значит, сначала проверьте, что опция содержит значение. Если он [11148] делает [11148], то «развернутое» значение присваивается новой переменной ([1147]), которую вы можете свободно использовать, как если бы она не была необязательной. Если в необязательном [11149] не указано значение [11149], то будет предложено предложение else, как и следовало ожидать. [11204] [11205] Что отличное от необязательного связывания, вы можете одновременно развернуть несколько опций. Вы можете просто отделить инструкции запятой. Заявление будет выполнено, если все дополнительные опции были развернуты. [11205] [118] [11206] Еще один опрятный трюк заключается в том, что вы можете также использовать запятые, чтобы проверить какое-то условие на значение после его разворачивания. [11206] [119] [11207] Единственный улов с использованием необязательного связывания в выражении if состоит в том, что вы можете получить доступ к развернутому значению из области действия инструкции. Если вам нужен доступ к значению из-за пределов области действия инструкции, вы можете использовать инструкцию [11150] guard [11150]. [11207] [11208] Инструкция [11121] охранника [11121] позволяет вам определить условие для успеха - и текущая область действия будет продолжать выполнение только в том случае, если это условие выполнено. Они определены с синтаксисом [1148]. [11208] [11209] Итак, чтобы использовать их с необязательной привязкой, вы можете сделать это: [11209] [1110] [11210] (Обратите внимание, что внутри тела охранника вы [11252] должны [11252] использовать один из [11122] управляет передающими операторами [11122], чтобы выйти из области текущего исполняемого кода). [11210] [11211] Если [1149] содержит значение, оно будет развернуто и назначено новому [ 1150] константа. После этого код [11151] после [11151] охранник продолжит выполнение. Если он не содержит значения - защитник выполнит код в скобках, что приведет к передаче управления, так что код сразу после этого не будет выполнен. [11211] [11212] Настоящая опрятная информация о сторожевых выражениях - это разворачиваемое значение, которое теперь доступно для использования в коде, который следует за оператором (поскольку мы знаем, что будущий код может [11152] выполнять только [11152], если необязательный имеет значение ). Это отлично подходит для устранения [11123] «пирамид смерти» [11123], созданных вложением нескольких операторов if. [11212] [11213] Например: [11213] [1111] [11214] Охранники также поддерживают те же аккуратные трюки, которые поддерживаются оператором if, такие как разворачивание нескольких опций в одно и то же время и использование предложения [1151]. [11214] ] [11215] Если вы используете оператор if или guard полностью зависит от того, требует ли какой-либо будущий код [11153] [11153] необязательный, чтобы содержать значение. [11215] [11167] Nil Coalescing Operator [11167] [11216] [11124] Nil Coalescing Operator [11124] - отличная сокращенная версия тернарного условного оператора [11125] [11125], в первую очередь предназначенная для преобразования опций в непараллельные. Он имеет синтаксис [1152], где [1153] является необязательным типом, а [1154] - это тот же тип, что и [1155] (хотя обычно он не является необязательным). [11216] [11217] Это, по сути, позволяет вам сказать: «Если [1156] содержит значение, разверните его. Если это не произойдет, то вместо этого верните [1157] ". Например, вы можете использовать его следующим образом: [11217] [1112] [11218] Это определит константу [1158] типа [1159], которая либо будет содержать значение [1160], если она содержит значение, или [1161] в противном случае. [11218] [11219] Это просто сокращение для: [11219] [1113] [11168] Необязательная цепочка [11168] [11220] Вы можете использовать [11126] Необязательный цепочек [11126], чтобы вызвать метод или получить доступ к свойству на необязательном. Это просто делается путем суффикса имени переменной с помощью [1162] при ее использовании. [11220] [11221] Например, скажем, у нас есть переменная [1163], типа необязательного экземпляра [1164]. [11221] [1114] [11222] Если бы мы хотели вызвать метод на [1165], который ничего не возвращает, мы можем просто сделать: [11222] [1115] [11223] Если [1166] содержит значение, этот метод будет призвал его. Если это не так, ничего плохого не произойдет - код просто продолжит выполнение. [11223] [11224] (Это похоже на посылку сообщений в [1167] в Objective-C) [11224] [11225]. Поэтому это также можно использовать для установки свойств, а также методов вызова. Например: [11225] [1116] [11226] Опять же, ничего плохого здесь не произойдет, если [1168] - [1169]. Ваш код просто продолжит выполнение. [11226] [11227] Еще один опрятный трюк, который необязательная цепочка позволяет вам проверить, была ли успешная установка свойства или вызов метода. Вы можете сделать это, сравнив возвращаемое значение с [1170]. [11227] [11228] (Это связано с тем, что необязательное значение вернет [1171], а не [1172] на метод, который ничего не возвращает) [11228] [11229] Например: [11229] [ 1117] [11230] Однако при попытке доступа к свойствам или вызовам, возвращающим значение, все становится немного сложнее. Поскольку [1173] является необязательным, все, что возвращается от него, также будет необязательным. Чтобы справиться с этим, вы можете либо разворачивать опции, которые возвращаются с использованием одного из вышеуказанных методов, либо самостоятельно распаковывать [1174], прежде чем обращаться к методам или вызовам, возвращающим значения. [11230] [11231] Кроме того, как следует из названия, вы можете «объединить» эти утверждения вместе. Это означает, что если [1175] имеет необязательное свойство [1176], которое обладает свойством [1177], вы можете написать следующее: [11231] [1118] [11232] Опять же, поскольку [1178] и [1179] являются необязательными , значение, возвращаемое с [1180], всегда будет необязательным, независимо от того, является ли [1181] необязательным. [11232] [11169] [1182] и [1183] [11169] [11233] Часто недоиспользуемая функция с опциями - это способность использовать функции [1184] и [1185]. Они позволяют применять необязательные преобразования к необязательным переменным. Если параметр имеет значение, вы можете применить к нему заданное преобразование. Если он не имеет значения, он останется [1186]. [11233] [11234] Например, допустим, у вас есть необязательная строка: [11234] [1119] [11235] Применяя к нему функцию [1187] - мы можем использовать функцию [1188], чтобы связать ее с другой строкой. [11235] [11236] Поскольку [1189] принимает необязательный строковый аргумент, мы не можем напрямую вводить нашу необязательную строку. Однако, используя [1190], мы можем использовать allow [1191], если [1192] имеет значение. [11236] [11237] Например: [11237] [1120] [11238] Однако, если [1193] не имеет значения, [1194] вернется [1195]. Например: [11238] [1121] [11239] [1196] работает аналогично [1197], за исключением того, что позволяет вам вернуть [11154] другой [11154] дополнительный из корпуса закрывания. Это означает, что вы можете ввести опцию в процесс, который требует нестандартного ввода, но может выводить необязательный сам. [11239] [11160] [1198] [11160] [11240] Система обработки ошибок Swift может быть безопасно использована с [11127] Do-Try-Catch [11127]: [11240] [1122] [11241] Если [1199] выдает ошибку, ошибка будет безопасно обнаружена в блоке [11100]. [11241] [11242] Константа [11101], которую вы видите в блоке [11102], не была объявлена ​​нами - она ​​автоматически генерируется [11103]. [11242] [11243] Вы также можете объявить [11104] самостоятельно, у него есть то преимущество, что он может использовать его в полезном формате, например: [11243] [1123] [11244] Используя [11105], этот способ - это правильный способ попробовать, поймать и обработать ошибки, возникающие из функций броска. [11244] [11245] Также есть [11106], который поглощает ошибку: [11245] [1124] [11246] Но система обработки ошибок Swift также предоставляет способ «принудительно попробовать» с помощью [11107]: [11246] [1125] [11247] Концепции, описанные в этом сообщении, также применимы здесь: если ошибка будет сброшена, приложение будет аварийно. [11247] [11248] [11155] Вы должны использовать только [11108], если вы можете доказать, что его результат никогда не потерпит неудачу в вашем контексте - и это очень редко. [11155] [11248] [11249] В большинстве случаев вы будете использовать полную систему Do-Try-Catch - и необязательную, [11109], в редких случаях, когда обработка ошибки не важна. [11249]
[11161] Ресурсы [11161] [11253] [11172] [11128] Документация Apple на быстрых опциях [11128] [11172] [11173] [11129] Когда использовать и когда не использовать неявно развернутые опциональные опции [11129] [11173] [11174] [11130] Узнайте, как отладить сбой приложения для iOS [11130] [11174] [11253]

24
задан Vadim Kotov 11 August 2017 в 13:35
поделиться

4 ответа

Я запустил бы новый процесс fcgi на новом порте, изменил бы nginx конфигурацию, чтобы использовать новый порт, иметь конфигурацию перезагрузки nginx (который сам по себе является корректным), тогда в конечном счете остановите старый процесс (можно использовать netstat для обнаружения, когда последнее соединение со старым портом закрывается).

, С другой стороны, можно изменить fcgi реализацию, чтобы разветвить новый процесс, закрыть все сокеты в ребенке за исключением fcgi сокета сервера, закрыть fcgi сокет сервера в родителе, должностное лицо новый процесс django в ребенке (то, чтобы заставлять его использовать fcgi сокет сервера) и завершить родительский процесс, как только все fcgi соединения закрываются. IOW, реализуйте корректный перезапуск для runfcgi.

15
ответ дан Martin v. Löwis 28 November 2019 в 23:25
поделиться

Можно использовать порождение вместо FastCGI

http://www.eflorenzano.com/blog/post/spawning-django/

3
ответ дан Andrew Kurinnyi 28 November 2019 в 23:25
поделиться

Итак, я пошел дальше и реализовал предложение Мартина. Вот сценарий bash, который я придумал.

pid_file=/path/to/pidfile
port_file=/path/to/port_file
old_pid=`cat $pid_file`

if [[ -f $port_file ]]; then
    last_port=`cat $port_file`
    port_to_use=$(($last_port + 1))
else
    port_to_use=8000
fi

# Reset so me don't go up forever
if [[ $port_to_use -gt 8999 ]]; then
    port_to_use=8000
fi

sed -i "s/$old_port/$port_to_use/g" /path/to/nginx.conf

python manage.py runfcgi host=127.0.0.1 port=$port_to_use maxchildren=5 maxspare=5 minspare=2 method=prefork pidfile=$pid_file

echo $port_to_use > $port_file

kill -HUP `cat /var/run/nginx.pid`

echo "Sleeping for 5 seconds"
sleep 5s

echo "Killing old processes on $last_port, pid $old_pid"
kill $old_pid
15
ответ дан 28 November 2019 в 23:25
поделиться

Я наткнулся на эту страницу, когда искал решение этой проблемы. Все остальное не удалось, поэтому я заглянул в исходный код :)

Решение кажется намного проще. Сервер Django fcgi использует flup, который правильно обрабатывает сигнал HUP: он корректно завершает работу. Итак, все, что вам нужно сделать, это:

  1. отправить сигнал HUP на сервер fcgi (пригодится аргумент pidfile = для runserver)

  2. подождать немного (flup позволяет дочерним процессам 10 секунд, так что подождите пару подробнее; 15 выглядит неплохим числом)

  3. отправил сигнал KILL на сервер fcgi, на всякий случай, если что-то заблокирует его

  4. запустите сервер снова

Вот и все.

10
ответ дан 28 November 2019 в 23:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: