-
Notifications
You must be signed in to change notification settings - Fork 7
/
chap20.xml
1017 lines (876 loc) · 44.7 KB
/
chap20.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[
<!ENTITY BASEID "djangobook.chap20">
]>
<chapter lang="ru" id="&BASEID;">
<title id="&BASEID;.title">
Развёртывание Django
</title>
<para>
Перевод © Чепиков Александр <achepikau • gmail • com>
</para>
<para>
Редактирование © Попов Руслан <radz • yandex • ru>
</para>
<para>
На протяжении всей книги мы перечислили множество задач, на
решение которых нацелена разработка Django — это простота
использования, дружелюбность к новичкам, освобождение от рутинной
работы.
</para>
<para>
Однако с самого начала работы над Django существовала еще одна
важная задача: Django должнен быть по возможности простым в
развертывании и обрабатывать большой трафик при ограниченных
требованиях к ресурсам.
</para>
<para>
Причина очевидна, если взглянуть на исходные данные этой задачи:
небольшая <quote>семейная</quote> газета из Канзаса вряд ли была в
состоянии приобрести высококлассное серверное оборудование,
поэтому авторы Django сконцентрировались на выжимании наилучшей
производительности из доступных им ресурсов. Более того,
разработчики Django долгое время работали и как системные
администраторы — просто потому что имеющегося в наличии
оборудования <emphasis>не хватало</emphasis> для принятия на
работу системного администратора на полную ставку — несмотря
на то, что их сайты обрабатывали к тому времени десятки миллионов
обращений в сутки.
</para>
<para>
Когда же Django превратился в проект с открытым исходным кодом,
нацеленность на производительность и простоту развертывания стала
важной и по другой причине: у свободных разработчиков аналогичные
требования. Те из них, кто хотел использовать Django, были рады
тому, что смогут платить всего 10 долларов за хостинг не очень
большого (среднего) сайта.
</para>
<para>
Но возможность масштабирования <quote>вниз</quote> — это
только половина успеха. Django должен масштабироваться и
<quote>вверх</quote>, чтобы удовлетворить запросы крупных компаний
и корпораций. Поэтому Django придерживается общего подхода для
LAMP-подобных веб приложений, который часто называют
<quote><emphasis>ничего общего</emphasis></quote>.
<note>
<title>
Как расшифровывается LAMP?
</title>
<para>
Аббревиатура LAMP изначально была придумана для описания
популярного набора программного обеспечения с открытым кодом,
который используется в работе многих вебсайтов:
<itemizedlist>
<listitem>
<para>
Linux (Операционная система);
</para>
</listitem>
<listitem>
<para>
Apache (Веб сервер);
</para>
</listitem>
<listitem>
<para>
MySQL (Сервер базы данных);
</para>
</listitem>
<listitem>
<para>
PHP (Язык программирования).
</para>
</listitem>
</itemizedlist>
</para>
<para>
Впоследствии, однако, эта аббревиатура стала скорее
обозначением каких-то совокупностей общих типов программ с
открытым кодом, нежели конкретного набора приложений.
Поэтому, хотя Django использует Python и не привязана к
конкретной базе данных, философия LAMP сильно влияет на
умонастроения разработчиков Django.
</para>
<para>
Было даже несколько (в основном юмористических) попыток
придумать похожую аббревиатуру для описания технологий,
используемых в Django. Авторам данной книги пришлись по душе
сокращения LAPD (Linux, Apache, PostgreSQL и Django), PAID
(PostgreSQL, Apache, Internet и Django), а так же девиз
<quote>Use Django and get PAID!</quote>, что буквально
означает <quote>Применяй Django и получай зарплату!</quote>.
</para>
</note>
</para>
<section id="&BASEID;.shared-nothing">
<title id="&BASEID;.shared-nothing.title">
Ничего общего
</title>
<para>
По своей сути данный подход означает, что приложение использует
множество программных компонентов, слабо связанных между собой.
Такая архитектура появилась, как альтернатива на превалирующий
когда-то подход: монолитный сервер приложений, объединяющий язык
программирования, базу данных, веб сервер и даже часть
операционной системы в один процесс (например, Java).
</para>
<para>
И когда приходит время увеличить размеры приложения, это может
стать основной проблемой: практически невозможно распределить
монолитный процесс на физически разные компьютеры, поэтому
монолитным приложениям требуются очень мощные сервера. Такие
сервера, естественно, стоят десятки и даже сотни тысяч долларов,
что препятствует их использованию небольшими компаниями и
физическими лицами, всегда испытывающими нехватку денег.
</para>
<para>
Сообщество LAMP, однако, обращает внимание на то, что если
разбить каждую часть веб приложения на отдельные компоненты, то
вполне можно стартовать с недорогого сервера и просто добавлять
такие же сервера по мере роста проекта. Если сервер базы данных
за 3 тысячи долларов не справляется с нагрузкой, достаточно
просто купить ещё один (второй, третий или четвертый) столько
раз, сколько потребуется. Если потребовалось дополнительное
дисковое пространство, несложно добавить еще один NFS сервер.
</para>
<para>
Для того, чтобы такой подход всё-таки работал, веб приложения не
должны быть привязаны к одному серверу при обработке запроса,
или даже части запроса. В сильно распределенных LAMP (и Django)
системах по крайней мере полдюжины серверов могут использоваться
для выдачи одной веб страницы! Вариантов построения таких
систем множество, но все они сводятся к следующим принципам:
<itemizedlist>
<listitem>
<para>
<emphasis>Текущее состояние не сохраняется
локально.</emphasis> Другими словами, любые общие данные
для различных запросов должны храниться в базе данных либо
в централизованной кэш-системе.
</para>
</listitem>
<listitem>
<para>
<emphasis>Программа не должна быть замкнута на
использование локальных ресурсов.</emphasis> Например, веб
сервер не должен полагаться на то, что сервер базы данных
работает на одном с ним физическом сервере. Он должен
поддерживать работу с удаленной базой данных.
</para>
</listitem>
<listitem>
<para>
<emphasis>Каждый компонент в приложении должен быть легко
заменяем и поддерживать репликацию.</emphasis> Например,
если веб сервер Apache по каким-то причинам не подходит
для текущего приложения, должна быть возможность без
проблем заменить его другим веб сервером. Или в случае
выхода из строя компьютера с веб сервером можно заменить
его на другой с минимальным временем простоя. Помните,
весь этот подход базируется на использовании недорогих,
широко распространенных компьютеров. Выход из строя
отдельных серверов должен быть предусмотрен заранее.
</para>
</listitem>
</itemizedlist>
</para>
<para>
Как и следовало ожидать, Django соответствует этим принципам
более или менее точно — ни один из компонентов Django не
нарушает данного подхода — но знание его основ поможет,
когда наступит время для увеличения размеров приложения.
</para>
<para>
<note>
<title>
Как это работает?
</title>
<para>
Такие рассуждения могут выглядеть неплохо на бумаге (или на
вашем экране), но как всё это работает на самом деле?
</para>
<para>
Хорошо, вместо того, чтобы отвечать непосредственно на
вопрос, давайте посмотрим на крайне неполный список
компаний, которые основали свой бизнес на этой основе. Вы
могли уже встречать их названия: Amazon, Blogger,
Craigslist, Facebook, Google, LiveJournal, Slashdot,
Wikipedia, Yahoo, YouTube.
</para>
<para>
Перефразируя известную сцену из <quote>Когда Гарри встретил
Салли</quote>: <quote>У нас будет всё то же, что и у
них!</quote>
</para>
</note>
</para>
</section>
<section id="&BASEID;.personal-preferences">
<title id="&BASEID;.personal-preferences.title">
Что предпочитают разработчики Django?
</title>
<para>
Перед тем, как погрузиться в детали, сделаем небольшое
отступление.
</para>
<para>
Сообщество open source знаменито своими так называемыми
<quote>религиозными войнами</quote>; множество (цифровых) чернил
пролито в спорах о текстовых редакторах
(<command>emacs</command> против <command>vi</command>),
операционных системах (Linux против Windows и против MacOS),
серверов баз данных (MySQL против PostgreSQL) и, естественно, о
языках программирования.
</para>
<para>
Мы стараемся оставаться в стороне от всех этих битв. На это
просто нет времени.
</para>
<para>
Однако существует множество вариантов для развертывания Django и
нас постоянно спрашивают от том, что же мы сами
предпочитаем. Практически всегда мы воздерживаемся от
комментариев, так как это приводит только к разжиганию нового
витка вышеупомянутых споров. Но ради того, чтобы закончить с
этим и полностью раскрыть карты, мы указываем наши предпочтения:
<itemizedlist>
<listitem>
<para>
Операционная система — Linux (Ubuntu, если быть ещё
точнее);
</para>
</listitem>
<listitem>
<para>
Веб сервер — Apache с поддержкой mod_python;
</para>
</listitem>
<listitem>
<para>
Сервер базы данных — PostgreSQL.
</para>
</listitem>
</itemizedlist>
</para>
<para>
Но мы знаем многих пользователей Django, выбравших другие
варианты развертывания и, тем не менее, достигших больших
успехов.
</para>
</section>
<section id="&BASEID;.using-apache-mod_python">
<title id="&BASEID;.using-apache-mod_python.title">
Использование Django с Apache и mod_python
</title>
<para>
Apache с поддержкой <token>mod_python</token> на текущий момент
является наиболее стабильной и надёжной средой при развёртывании
Django на рабочем сервере.
</para>
<para>
<token>mod_python</token> (<ulink
url="http://www.djangoproject.com/r/mod_python/"/>) — это
модуль для Apache, позволяющий встроить Python в ядро Apache и
загрузить программы на Python в память веб сервера при его
запуске. Исполняемый код хранится в памяти до конца работы
процесса Apache, что дает значительный прирост
производительности.
</para>
<para>
Для работы Django необходим Apache версии 2.x и mod_python
версии 3.x, в качестве МП-модуля рекомендуется использовать
Prefork, а не Worker.
<note>
<para>
Обсуждение настройки Apache выходит
<emphasis>далеко</emphasis> за рамки данной книги, поэтому
при необходимости мы просто будем делать ссылки на некоторые
детали. В сети Интернет есть много хороших ресурсов для тех,
кто хочет узнать больше об этом веб сервере. Вот некоторые
из них, которые нравятся нам самим:
<itemizedlist>
<listitem>
<para>
Документация по Apache в свободном онлайн доступе:
<ulink
url="http://www.djangoproject.com/r/apache/docs/"/>;
</para>
</listitem>
<listitem>
<para>
Книга <emphasis>Pro Apache, Third Edition</emphasis>
(Apress, 2004), автор Peter Wainwright: <ulink
url="http://www.djangoproject.com/r/books/pro-apache/"/>;
</para>
</listitem>
<listitem>
<para>
Книга <emphasis>Apache: The Definitive Guide, Third
Edition</emphasis> (O’Reilly, 2002), авторы Ben Laurie
и Peter Laurie: <ulink
url="http://www.djangoproject.com/r/books/apache-pra/"/>.
</para>
</listitem>
</itemizedlist>
</para>
</note>
</para>
<section id="&BASEID;.using-apache-mod_python.base-settings">
<title id="&BASEID;.using-apache-mod_python.base-settings.title">
Базовые настройки
</title>
<para>
Чтобы настроить Django для использования mod_python, сперва
необходимо убедиться, что установлен Apache с поддержкой
mod_python. Обычно это означает, что в конфигурационном файле
Apache присутствует соответствующая директива
<token>LoadModule</token>:
<screen>
<![CDATA[
LoadModule python_module /usr/lib/apache2/modules/mod_python.so
]]>
</screen>
</para>
<para>
Теперь добавим в этот файл следующие строки:
<screen>
<![CDATA[
<Location "/">
SetHandler mod_python
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonDebug On
</Location>
]]>
</screen>
</para>
<para>
Вместо <token>mysite.settings</token> необходимо вписать имя
модуля настроек Django для вашего сайта.
</para>
<para>
Такая директива означает, что Apache должен обрабатывать все
URL, начинающиеся от корня сайта, используя обработчик
mod_python от Django. Он передает ему значение переменной
<varname>DJANGO_SETTINGS_MODULE</varname>, чтобы mod_python
знал, какие настройки использовать.
</para>
<para>
Отметим, что мы использовали директиву
<token><![CDATA[<Location>]]></token>, а не
<token><![CDATA[<Directory>]]></token>. Последняя из них
указывает на путь в файловой системе, тогда как
<token><![CDATA[<Location>]]></token> используется при
формировании структуры URL для вебсайта. Использование
<token><![CDATA[<Directory>]]></token> в таком случае является
бессмысленным.
</para>
<para>
Обычно Apache запускается от имени специального пользователя,
которое отличается от вашего логина в систему и имеет другие
настройки <token>path</token> и
<token>sys.path</token>. Поэтому необходимо указать для
mod_python, где искать ваш проект и файлы Django:
<screen>
<![CDATA[
PythonPath "['/путь/к/проекту', '/путь/к/django'] + sys.path"
]]>
</screen>
</para>
<para>
Вы можете добавить дополнительные директивы, такие, как
<token>PythonAutoReload Off</token>, для увеличения
производительности. Полный список опций можно найти в
документации по mod_python.
</para>
<para>
Рекомендуем отключить опцию <token>PythonDebug</token>
(<token>PythonDebug Off</token>) для рабочей версии
приложения. Если оставить ее включенной, ваши пользователи
увидят некрасивый и избыточный стек ошибок Python, когда
возникнут проблемы с mod_python.
</para>
<para>
Перегрузите Apache и теперь любой запрос к вашему сайту (либо
виртуальному хосту, если вы разместили директиву внутри блока
<token><![CDATA[<VirtualHost>]]></token>) будет обрабатываться
Django.
<note>
<para>
Если разворачивать Django в подкаталоге, то есть глубже
корневого URL, то он не сможет обрезать префикс URL из
шаблонов URL. Например, если настройки Apache похожи на
эти:
<screen>
<![CDATA[
<Location "/mysite/">
SetHandler mod_python
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonDebug On
</Location>
]]>
</screen>
то все шаблоны URL должны начинаться с префикса
<token>/mysite/</token>. По этой причине мы обычно
рекомендуем разворачивать Django в корень домена или
виртуального хоста. Либо, как вариант, можно просто
<quote>сдвинуть</quote> все URL вниз на один уровень,
используя промежуточный файл со схемой URL:
<screen>
<![CDATA[
urlpatterns = patterns('',
(r'^mysite/', include('normal.root.urls')),
)
]]>
</screen>
</para>
</note>
</para>
</section>
<section id="&BASEID;.using-apache-mod_python.more-one">
<title id="&BASEID;.using-apache-mod_python.more-one.title">
Несколько проектов Django на одном сервере Apache
</title>
<para>
Запустить несколько проектов Django на одном сервере Apache
несложно. Это может понадобится, например, когда у
независимого веб разработчика есть несколько клиентов и только
один сервер.
</para>
<para>
Для реализации данного подхода используется блок
<token>VirtualHost</token>:
<screen>
<![CDATA[
NameVirtualHost *
<VirtualHost *>
ServerName www.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</VirtualHost>
<VirtualHost *>
ServerName www2.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
</VirtualHost>
]]>
</screen>
</para>
<para>
Если необходимо установить два различных проекта в рамках
одного и того же виртуального хоста, нужно принять меры, чтобы
не допустить смешивания двух различных кэш-копий кода
приложений. Используем директиву
<token>PythonInterpreter</token>, чтобы указать в каждой
директиве <token><![CDATA[<Location>]]></token> свой
обработчик:
<screen>
<![CDATA[
<VirtualHost *>
ServerName www.example.com
# ...
<Location "/something">
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonInterpreter mysite
</Location>
<Location "/otherthing">
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
PythonInterpreter mysite_other
</Location>
</VirtualHost>
]]>
</screen>
</para>
<para>
Значения параметров для директивы
<token>PythonInterpreter</token> можно установить любые,
главное, чтобы они отличались между собой для различных блоков
<token><![CDATA[<Location>]]></token>.
</para>
</section>
<section id="&BASEID;.using-apache-mod_python.dev-server">
<title id="&BASEID;.using-apache-mod_python.dev-server.title">
Запуск тестового сервера под mod_python
</title>
<para>
Посколько mod_python кэширует загруженный Python код, то при
развертывании Django приложений нужно помнить о необходимости
рестартовать Apache каждый раз, когда в исходный код внесены
изменения. Это быстро может надоесть, поэтому мы предлагаем
способ бысто обойти это ограничение: просто добавьте директиву
<token>MaxRequestsPerChild 1</token> в файл конфигурации,
чтобы заставить Apache полностью перегружать все при каждом
запросе. Только не нужно делать этого на рабочем сервере,
иначе мы запретим вам использовать Django.
</para>
<para>
Если вы относитесь к тем программистам, кто отлаживает код,
используя беспорядочно разбросанные операторы
<token>print</token> (как мы), учтите, что оператор
<token>print</token> не работает в случае использования
mod_python и результат его работы не появится в логе Apache,
как, возможно, кое-кто ожидал. Для того, чтобы печатать
отладочную информацию, рекомендуем использовать стандартный
Python модуль <token>logging</token>. Более подробную
информацию можно посмотреть тут: <ulink
url="http://docs.python.org/lib/module-logging.html"/>. Альтернативным
вариантом может быть вывод отладочной информации в шаблонах
страниц сайта.
</para>
</section>
<section id="&BASEID;.using-apache-mod_python.static-content">
<title id="&BASEID;.using-apache-mod_python.static-content.title">
Работа с Django и статическим контентом на одном сервере Apache
</title>
<para>
Django не рекомендуется использовать для обслуживания запросов
к статическим файлам (контенту); эту работу лучше оставить для
веб сервера. Рекомендуется использовать отдельный веб сервер
(на котором не работает Django) для обработки запросов к
статической информации. Более подробная информация см. ниже в
разделе "Масштабирование FIXME".
</para>
<para>
Однако, если нет других вариантов, кроме работы со статическим
контентом на том же сервере Apache, где развернут Django,
необходимо отключить mod_python для отдельных частей сайта:
<screen>
<![CDATA[
<Location "/media/">
SetHandler None
</Location>
]]>
</screen>
</para>
<para>
Вместо <token>/media/</token> необходимо указать корневой URL
для статических файлов на вашем сайте.
</para>
<para>
Можно использовать директиву
<token><![CDATA[<LocationMatch>]]></token> и работать через
регулярные выражения. Например, вот такая настройка
конфигурации позволяет использовать Django от корня сайта, но
полностью отключает Django для подкаталога
<filename>media</filename>, а также для любого URL,
оканчивающегося на <filename>.jpg</filename>,
<filename>.gif</filename> или <filename>.png</filename>:
<screen>
<![CDATA[
<Location "/">
SetHandler mod_python
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</Location>
<Location "/media/">
SetHandler None
</Location>
<LocationMatch "\.(jpg|gif|png)$">
SetHandler None
</LocationMatch>
]]>
</screen>
</para>
<para>
Во всех случаях необходимо настроить директиву
<token>DocumentRoot</token>, чтобы Apache знал, где ему искать
статические файлы.
</para>
</section>
<section id="&BASEID;.using-apache-mod_python.error-handling">
<title id="&BASEID;.using-apache-mod_python.error-handling.title">
Обработка ошибок
</title>
<para>
При использовании Apache/mod_python ошибки перехватываются на
уровне Django — другими словами, они не передаются на
уровень Apache и поэтому не появляются в логе ошибок Apache.
</para>
<para>
Исключением тут будет случай, когда что-то серьёзно запорчено
при установке Django. Тогда в броузере будет выдаваться
страница с ошибкой <quote>Internal Server Error</quote> (код
ошибки 500) и полный стек ошибки Python записывается в лог
ошибок Apache. Такое сообщение занимает несколько строк. (Да,
это выглядит некрасиво и неудобно для изучения, но так
работает mod_python).
</para>
</section>
<section id="&BASEID;.using-apache-mod_python.seg-fault">
<title id="&BASEID;.using-apache-mod_python.seg-fault.title">
Устранение ошибок, приводящих к падению Apache
</title>
<para>
Иногда Apache падает после установки Django. Если это
произошло, то практически всегда это результат одного из двух
возможных случаев, не связанных непосредственно с Django:
<itemizedlist>
<listitem>
<para>
Возможно, в приложении используется модуль
<token>pyexpat</token> (применяется для разбора XML),
который может конфликтовать с версией этого же модуля,
встроенной непосредственно в Apache. Подробнее
см. статью <quote>Expat заставляет Apache сбоить</quote>
по адресу <ulink
url="http://www.djangoproject.com/r/articles/expat-apache-crash/"/>.
</para>
</listitem>
<listitem>
<para>
Возможно, в текущей конфигурации одновременно
используются mod_python и mod_php на одном и том же
сервере Apache, а в качестве базы данных выступает
MySQL. В некоторых случаях это может привести к
конфликту версий для драйверов MySQL между Python и
PHP. Полная информация по данной проблеме доступна в
mod_python FAQ по адресу <ulink
url="http://www.djangoproject.com/r/articles/php-modpython-faq/"/>.
</para>
</listitem>
</itemizedlist>
</para>
<para>
Если после этого проблемы с mod_python продолжаются, следующим
хорошим ходом будет создание <quote>скелета</quote> сайта под
mod_python без подлючения библиотек Django. Это самый простой
способ изолировать проблемы, специфические именно для
mod_python. В статье <quote>Заставляем mod_python
работать</quote> эта процедура детально описывается: <ulink
url="http://www.djangoproject.com/r/articles/getting-modpython-working/"/>.
</para>
<para>
На следующем этапе рекомендуем сделать тестовый скрипт и
включить в него всё, что вы используете в Django приложении
— представления, модели, шаблоны URL, конфигурацию RSS и
т.п. Включите этот код в тестовую функцию обработчика и
вызывайте тестовый URL. Если это приводит к проблеме, то
считаем, что проблема где-то в коде, использующем
Django. Комментируя одну за одной строки с
<token>import</token>, мы доберемся до конкретного модуля,
вызывающего ошибку. Далее то же самое проделываем с кодом
модуля, пока не локализуем ошибку. Системные утилиты, такие,
как <command>ldconfig</command> в Linux,
<command>otool</command> в Mac OS и <token>ListDLLs</token>
(от SysInternals) в Windows, помогут найти общие зависимости и
возможные конфликты версий.
</para>
</section>
</section>
<section id="&BASEID;.using-apache-mod_wsgi">
<title id="&BASEID;.using-apache-mod_wsgi.title">
Использование Django с Apache и mod_wsgi
</title>
<para>
Источники: <ulink
url="http://code.google.com/p/modwsgi/wiki/QuickInstallationGuide"/>,
<ulink
url="http://ericholscher.com/blog/2008/jul/8/setting-django-and-mod_wsgi/"/>.
</para>
<para>
Есть несколько причин для перехода с <token>mod_python</token>
на <token>mod_wsgi</token>:
<itemizedlist>
<listitem>
<para>
<token>mod_python</token> больше не поддерживается разработчиком;
</para>
</listitem>
<listitem>
<para>
<token>mod_wsgi</token> требует меньше ресурсов для своей
работы и обладает большими возможностями в настройке.
</para>
</listitem>
</itemizedlist>
</para>
<section id="&BASEID;.using-apache-mod_wsgi.apache-reqs">
<title id="&BASEID;.using-apache-mod_wsgi.apache-reqs.title">
Поддерживаемые версии Apache
</title>
<para>
Поддерживаются следующие версии Apache — 1.3, 2.0 и 2.2.
</para>
<para>
При использовании Apache 1.3 можно динамически подгружать его
модули. В случае, когда модули статически слинкованы с Apache,
некоторые компоненты <token>mod_wsgi</token> будут работать
некорректно.
</para>
<para>
При использовании Apache 2.0 и 2.2 нет разницы, работаете вы с
<token>prefork</token> или <token>worker</token> MPM.
</para>
<para>
Чтобы иметь возможность <token>mod_wsgi</token> в режиме
сервиса, надо использовать Apache 2.0 и 2.2, также
соответствующие библиотеки Apache должны быть собраны с
поддержкой потоков.
</para>
<para>
На Linux, если Apache устанавливается из репозитория, следует
установить для него пакеты разработчика.
</para>
<para>
Для большинства дистрибутивов Linux, пакет разработчика для
Apache 2.x называется <token>apache2-dev</token>, сам Apache
находится в пакете <token>apache2</token>. Тем не менее,
некоторые дистрибутивы различают пакеты разработчика по типу
MPM, для которого они собраны. В таком случае, пакет может
называться как <token>apache2-worker-dev</token> или
<token>apache2-prefork-dev</token>. При использовании Apache
2.x не стоит устанавливать пакет <token>apache-dev</token>,
так как он относится к Apache 1.3.
</para>
</section>
<section id="&BASEID;.using-apache-mod_wsgi.python-reqs">
<title id="&BASEID;.using-apache-mod_wsgi.python-reqs.title">
Поддерживаемые версии Python
</title>
<para>
Можно использовать Python версий 2.3-2.5. Используемая версия
Python должна быть собрана с поддержкой потоков.
</para>
<para>
На Linux, если Python устанавливается из репозитария, следует
установить для него пакеты разработчика.
</para>
<para>
Желательно, чтобы Python был доступен в виде разделяемой
библиотеки. Если это не ваш случай, то <token>mod_wsgi</token>
будет требовать больше памяти и могут возникнуть конфликты с
<token>mod_python</token> (если оба модуля будут загружены в
одно время), что может привести к падению Apache.
</para>
</section>
<section id="&BASEID;.using-apache-mod_wsgi.install">
<title id="&BASEID;.using-apache-mod_wsgi.install.title">
Установка модуля
</title>
<para>
Пример установки модуля на Ubuntu:
<screen>
<![CDATA[
# wajig search mod_wsgi
libapache2-mod-wsgi - Python WSGI adapter module for Apache
# wajig install libapache2-mod-wsgi
Чтение списков пакетов... Готово
Построение дерева зависимостей
Чтение информации о состоянии... Готово
Предлагаемые пакеты:
apache2-mpm-worker apache2-mpm-event
НОВЫЕ пакеты, которые будут установлены:
libapache2-mod-wsgi
Необходимо скачать 113kБ архивов.
Получено:1 http://ru.archive.ubuntu.com intrepid/universe libapache2-mod-wsgi 2.3-1 [113kB]
Получено 113kБ за 1s (111kБ/c)
...
* Reloading web server config apache2
#
]]>
</screen>
</para>
</section>
<section id="&BASEID;.using-apache-mod_wsgi.interface">
<title id="&BASEID;.using-apache-mod_wsgi.interface.title">
Интерфейс к модулю
</title>
<para>
Создайте внутри вашего проекта каталог, а в каталоге файл
<filename>django.wsgi</filename>. Например, в моём случае это
будет так:
<screen>
<![CDATA[
$ cd ~/development/cargo
$ mkdir apache
$ emacs apache/django.wsgi
]]>
</screen>
</para>
<para>
Скопируйте нижеприведённый код в файл
<filename>django.wsgi</filename>:
<screen>
<![CDATA[
import os, sys
# место, где лежит джанго
sys.path.append('/home/rad/devel/django-trunk/')
# место, где лежит проект
sys.path.append('/home/rad/devel/')
# файл конфигурации проекта
os.environ['DJANGO_SETTINGS_MODULE'] = 'cargo.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
]]>
</screen>
</para>
<para>
Вы создали интерфейс между Django и <token>WSGI</token>. Если
после этого, вы начнёте получать сообщения об ошибках,
допустим, что недоступен ваш проект или какой-то из его
модулей, проверьте <token>sys.path</token>.
</para>
</section>
<section id="&BASEID;.using-apache-mod_wsgi.config">
<title id="&BASEID;.using-apache-mod_wsgi.config.title">
Конфигурация сервера
</title>
<para>
Откройте конфигурационный файл вашего сервер, например,
<filename>/etc/apache2/sites-available/cargo.caml.ru</filename>
и внесите в него изменения:
<screen>
<![CDATA[
<VirtualHost *>
DocumentRoot /var/www-cargo/
ServerAdmin ruslаn.pоpоv@gmаil.cоm
ServerName cargo
WSGIScriptAlias / /home/rad/devel/cargo/apache/django.wsgi
WSGIDaemonProcess cargo processes=2 maximum-requests=5 threads=1
WSGIProcessGroup cargo
ErrorLog "|/usr/sbin/rotatelogs /var/log/apache2/cargo.error.%Y-%m-%d.log 86400"
CustomLog "|/usr/sbin/rotatelogs /var/log/apache2/cargo.access.%Y-%m-%d.log 86400" combined
ServerSignature On
Alias /css/ "/home/rad/django/cargo/css/"
Alias /js/ "/home/rad/django/cargo/js/"
Alias /pics/ "/home/rad/django/cargo/pics/"
Alias /djangobook/pics/ "/home/rad/django/cargo/djangobook/pics/"
Alias /media/ "/home/rad/django/cargo/media/"
Alias /adminmedia/ "/home/rad/devel/django-trunk/django/contrib/admin/media/"
</VirtualHost>
]]>
</screen>
</para>
<para>
Особое внимание надо уделить трём строкам, которые начинаются
с <token>WSGI...</token>. Строка с
<token>WSGIScriptAlias</token> ссылается на файл, который был
создан ранее. Другие две строки необходимы в случае, когда вы
размещаете на сервере несколько виртуальных сайтов.
<note>
<para>
Следует принять во внимание то, что директива
<token>WSGIDaemonProcess</token> и соответствующие
элементы не доступны под ОС MS Windows, а также при
использовании Apache 1.3. <ulink
url="http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives">Подробности...</ulink>
</para>
</note>
</para>