Подтвердить что ты не робот

Некоторые фундаментальные, но важные вопросы о веб-разработке?

Я разработал некоторые веб-приложения до сих пор, используя PHP, Python и Java. Но некоторые фундаментальные, но очень важные вопросы по-прежнему не в моих силах, поэтому я сделал этот пост, чтобы получить помощь и разъяснения от вас, ребята.

Предположим, что я использую некоторый язык программирования в качестве моего внутреннего языка (PHP/Python/.Net/Java и т.д.), и я развертываю свое приложение с веб-сервером (apache/lighttpd/nginx/IIS и т.д.). И предположим, что в момент времени T одна из моих страниц получала 100 одновременных запросов от разных пользователей. Поэтому мои вопросы:

  • Как мой веб-сервер обрабатывает такие 100 одновременных запросов? Будет ли веб-сервер генерировать один процесс/поток для каждого запроса? (если да, процесс или поток?)
  • Как работает интерпретатор бэкэнд-языка? Как он обрабатывает запрос и генерирует правильный html? Будет ли интерпретатор генерировать процесс/поток для каждого запроса? (Если да, процесс или поток?)
  • Если интерпретатор будет генерировать процесс/поток для каждого запроса, как об этих процессах (потоках)? Поделитесь ли они некоторым кодовым пространством? Будут ли они общаться друг с другом? Как обрабатывать глобальные переменные во внутренних кодах? Или они независимые процессы (потоки)? Как долго длится процесс/поток? Будут ли они уничтожены при обработке запроса и ответ будет возвращен?
  • Предположим, что веб-сервер может поддерживать только 100 одновременных запросов, но теперь он получил 1000 одновременных запросов. Как он справляется с такой ситуацией? Будут ли они обрабатывать их как очередь и обрабатывать запрос, когда сервер доступен? Или другие подходы?
  • В наши дни я прочитал некоторые статьи о кометах. И я обнаружил, что длительное соединение может быть хорошим способом обработки многопользовательских пользователей в режиме реального времени. Итак, как насчет длительной связи? Является ли это особенностью некоторых определенных веб-серверов или доступно для каждого веб-сервера? Длительное соединение потребует длительного процесса интерпретации?

Спасибо всем. Эти вопросы меня очень раздражали. Поэтому надеюсь, что вы сможете помочь. Более подробный ответ будет оценен очень сильно. И, пожалуйста, добавьте некоторые ссылки.

С уважением.


EDIT: Недавно я прочитал несколько статей о CGI и fastcgi, что заставляет меня понять, что подход fastcgi должен быть типичным подходом к запросу hanlde.

протокол мультиплексирует одно транспортное соединение между несколькими независимыми запросами FastCGI. Это поддерживает приложения, которые могут обрабатывать параллельные запросы с использованием методов, управляемых событиями или многопоточными методами.

Цитата из спецификация fastcgi, в которой упоминалось соединение, которое может обрабатывать несколько запросов и может быть реализовано в mutli-threaded тек. Мне интересно, как это соединение можно трактовать как процесс, и он может генерировать несколько потоков для каждого запроса. Если это правда, я стал больше запутанным в том, как обрабатывать общий ресурс в каждом потоке?

P.S благодарит Томаса за то, что он пригласил почту на несколько сообщений, но я думаю, что вопросы связаны друг с другом, и лучше группировать их вместе.

Благодарим С.Лотта за большой ответ, но некоторые ответы на каждый вопрос слишком кратки или вообще не рассматриваются.

Благодарим всех за ответ, что делает меня ближе к истине.

Подробный ответ будет оценен очень сильно!

4b9b3361

Ответ 1

1. Зависит от веб-сервера (а иногда и от конфигурации). Описание различных моделей:

  • Apache с mpm_prefork (по умолчанию в unix): обрабатывается за запрос. Чтобы свести к минимуму время запуска, Apache поддерживает пул простаивающих процессов, ожидающих обработки новых запросов (которые вы настраиваете размер). Когда приходит новый запрос, мастер-процесс делегирует его доступному рабочему, в противном случае создается новый. Если бы поступило 100 запросов, если у вас не было 100 рабочих, работающих на холостом ходу, для обработки нагрузки необходимо выполнить некоторую разметку. Если количество незанятых процессов превышает значение MaxSpare, некоторые из них будут получены после завершения запросов до тех пор, пока не будет достаточно всего количества незанятых процессов.

  • Apache с mpm_event, mpm_worker, mpm_winnt: поток за запрос. Аналогично, в большинстве ситуаций apache поддерживает пул простаивающих потоков, а также настраивается. (Небольшая деталь, но функционально такая же: mpm_worker запускает несколько процессов, каждый из которых многопоточен).

  • Nginx/Lighttpd: это легкие серверы на основе событий, которые используют select()/epoll()/poll() для мультиплексирования нескольких сокетов без необходимости нескольких потоков или процессов. Благодаря очень тщательной кодировке и использованию неблокирующих API, они могут масштабироваться до тысяч одновременных запросов на товарное оборудование, предоставляя доступную полосу пропускания и правильно настроенные ограничения файлового дескриптора. Суть в том, что реализация традиционных встроенных языков сценариев практически невозможна в контексте сервера, это отрицательно повлияет на большинство преимуществ. Оба поддерживают FastCGI, однако, для внешних языков сценариев.

2. В зависимости от языка или на некоторых языках, на какой модели развертывания вы используете. Некоторые конфигурации серверов допускают только определенные модели развертывания.

  • Apache mod_php, mod_perl, mod_python: эти модули запускают отдельный интерпретатор для каждого работника apache. Большинство из них не могут работать с mpm_worker очень хорошо (из-за различных проблем с обеспечением безопасности потоков в клиентском коде), поэтому они в основном ограничены forking-моделями. Это означает, что для каждого процесса apache у вас есть интерпретатор php/perl/python. Это значительно увеличивает объем памяти: если данный apache-работник обычно занимает около 4 МБ памяти в вашей системе, один с PHP может принимать 15 МБ, а один с Python может принимать 20-40 МБ для среднего приложения. Некоторые из них будут разделяемой памятью между процессами, но в целом эти модели очень трудно масштабировать очень большие.

  • Apache (поддерживаемые конфигурации), Lighttpd, CGI: это, в основном, метод отмирания хостинга. Проблема с CGI заключается в том, что вы не только разворачиваете новый процесс обработки запросов, вы делаете это для -все-запроса, а не только тогда, когда вам нужно увеличить нагрузку. Поскольку динамические языки сегодня имеют довольно большое время запуска, это создает не только много работы для вашего веб-сервера, но и значительно увеличивает время загрузки страницы. Небольшой perl script может работать нормально как CGI, но большое приложение python, ruby ​​или java довольно громоздко. В случае Java вы можете ожидать второй или более только для запуска приложения, только чтобы повторить это снова при следующем запросе.

  • Все веб-серверы, FastCGI/SCGI/AJP: это "внешняя" модель хостинга динамических языков. Существует целый список интересных вариантов, но суть в том, что ваше приложение прослушивает какой-то сокет, а веб-сервер обрабатывает HTTP-запрос, а затем отправляет его через другой протокол в сокет только для динамических страниц (статические страницы обычно обрабатываются непосредственно веб-сервером).

    Это дает много преимуществ, потому что вам понадобятся менее динамичные рабочие, чем вам нужна возможность обработки соединений. Если для каждых 100 запросов половина предназначена для статических файлов, таких как изображения, CSS и т.д., И, кроме того, если большинство динамических запросов коротки, вы можете получить 20 динамических работников, которые будут обрабатывать 100 одновременных клиентов. То есть, поскольку обычное использование поддерживаемого соединения с сервером на 80% бездействует, ваши динамические интерпретаторы могут обрабатывать запросы от других клиентов. Это намного лучше, чем подход mod_php/python/perl, где, когда пользователь загружает файл CSS или вообще ничего не загружает, ваш интерпретатор сидит там с использованием памяти и не выполняет никаких действий.

  • Apache mod_wsgi: Это относится, в частности, к хостингу python, но он использует некоторые преимущества приложений, размещенных на веб-сервере (простая настройка) и внешнего хостинга (мультиплексирование процессов). Когда вы запускаете его в режиме демона, mod_wsgi только делегирует запросы вашим рабочим демонам, когда это необходимо, и, таким образом, 4 демона могут обрабатывать 100 одновременных пользователей (зависит от вашего сайта и его рабочей нагрузки).

  • Phusion Passenger: Пассажир - это система хостинга apache, которая в основном предназначена для размещения рубиновых приложений, и, как и mod_wsgi, обеспечивает преимущества как внешнего, так и управляемого веб-сервера.

3. Опять же, я разберу вопрос на основе моделей хостинга, где это применимо.

  • mod_php, mod_python, mod_perl: Только общие библиотеки C вашего приложения обычно будут совместно использоваться между работниками Apache. Это происходит из-за того, что apache сначала запускает, а затем загружает динамический код (который из-за тонкостей в основном не может использовать общие страницы). Переводчики не общаются друг с другом в рамках этой модели. Глобальные переменные обычно не разделяются. В случае mod_python вы можете иметь глобальные переменные между запросами в процессе, но не через процессы. Это может привести к некоторому очень странному поведению (браузеры редко поддерживают одно и то же соединение навсегда, а большинство открывают несколько для данного веб-сайта), поэтому будьте очень осторожны с тем, как вы используете глобальные переменные. Используйте что-то вроде memcached или базы данных или файлов для таких вещей, как хранение сеанса и другие кэш-биты, которые необходимо использовать.

  • FastCGI/SCGI/AJP/Proxied HTTP: поскольку ваше приложение по сути является сервером само по себе, это зависит от языка, на котором написан сервер (обычно это тот же язык, что и ваш код, но не всегда) и различные факторы. Например, в большинстве развертываний Java используется поток за запрос. Python и его "flup" FastCGI-библиотека могут работать как в предпродажном, так и в потоковом режиме, но поскольку Python и его GIL ограничены, вы, скорее всего, получите лучшую производительность от prefork.

  • mod_wsgi/пассажир: mod_wsgi в режиме сервера можно настроить, как он обрабатывает вещи, но я бы порекомендовал вам дать ему фиксированное количество процессов. Вы хотите сохранить свой код python в памяти, развернуться и подготовиться к работе. Это лучший подход для обеспечения предсказуемости и низкого уровня ожидания.

Почти во всех упомянутых выше моделях время жизни процесса/потока больше, чем один запрос. Большинство настроек следуют некоторым вариантам в модели apache: Храните некоторых запасных рабочих вокруг, при необходимости создавайте больше, когда их можно использовать, когда их слишком много, на основе нескольких настраиваемых ограничений. Большинство из этих настроек - не уничтожить процесс после запроса, хотя некоторые могут очистить код приложения (например, в случае PHP fastcgi).

4. Если вы скажете, что "веб-сервер может обрабатывать только 100 запросов", это зависит от того, означает ли вы собственно веб-сервер или динамическую часть веб-сервера. Существует также разница между фактическими и функциональными пределами.

В случае Apache, например, вы настроите максимальное количество рабочих (соединений). Если это число соединений было 100 и было достигнуто, никакие соединения не будут приняты apache до тех пор, пока кто-то не отключится. С включенным режимом keep-alive эти 100 соединений могут оставаться открытыми в течение длительного времени, намного дольше, чем один запрос, а остальные 900 человек, ожидающих запросы, вероятно, будут отсутствовать.

Если у вас есть достаточно высокие лимиты, вы можете принять всех этих пользователей. Однако даже с самым легким апачем стоимость составляет около 2-3 МБ на одного работника, поэтому только с помощью apache вы можете говорить о 3gb + памяти только для обработки соединений, не говоря уже о других возможно ограниченных ресурсах ОС, таких как идентификаторы процессов, дескрипторы файлов, и буферов, и это до рассмотрения вашего кода приложения.

Для lighttpd/Nginx они могут обрабатывать большое количество подключений (тысяч) в крошечном объеме памяти, часто всего несколько мегабайт на тысячу подключений (зависит от таких факторов, как буферы и то, как настроен async IO apis). Если мы исходим из предположения, что большинство ваших подключений остаются в живых и 80% (или более) бездействуют, это очень хорошо, поскольку вы не тратите время на динамическое время или большую часть памяти.

В любой внешней размещенной модели (mod_wsgi/fastcgi/ajp/proxied http), скажем, у вас только 10 работников и 1000 пользователей делают запрос, ваш веб-сервер будет помещать запросы вашим динамическим сотрудникам. Это идеально: если ваши запросы возвращаются быстро, вы можете продолжать работать с гораздо большей нагрузкой на пользователя, не требуя больше рабочих. Обычно премия - это соединения памяти или БД, и в порядке очередности вы можете обслуживать гораздо больше пользователей с одинаковыми ресурсами, вместо того чтобы отрицать некоторых пользователей.

Будьте осторожны: скажите, что у вас есть одна страница, которая строит отчет или выполняет поиск, и занимает несколько секунд, и многие пользователи связывают рабочих с этим: кто-то, желающий загрузить вашу первую страницу, может быть поставлен в очередь на несколько секунд в то время как все эти длительные запросы завершаются. Альтернативы используют отдельный пул работников для обработки URL-адресов в вашем разделе приложения для отчетов или для отдельной публикации (например, в фоновом задании), а затем для последующего опроса своего завершения. Здесь много вариантов, но вам нужно подумать над своим приложением.

5.. Большинство людей, использующих apache, которым необходимо обрабатывать множество одновременных пользователей, по причине большого объема памяти, отключились. Или Apache с включенной поддержкой, с коротким сроком хранения в режиме ожидания, скажем, 10 секунд (так что вы можете получить свою первую страницу и изображения /CSS в одной загрузке страницы). Если вам действительно нужно масштабировать до 1000 подключений или больше, и вы хотите продолжать жить, вы захотите посмотреть Nginx/lighttpd и другие облегченные серверы на основе событий.

Можно отметить, что если вы хотите использовать apache (для удобства использования конфигурации или для размещения определенных настроек), вы можете поместить Nginx перед apache, используя HTTP-прокси. Это позволит Nginx обрабатывать связи keep-alive (и, желательно, статические файлы) и apache для обработки только работы grunt. Интересно, что Nginx лучше, чем apache, при написании лог файлов. Для развертывания производства мы были очень довольны nginx перед apache (с mod_wsgi в этом случае). Apache не выполняет регистрацию доступа и не обрабатывает статические файлы, что позволяет нам отключить большое количество модулей внутри apache, чтобы сохранить его небольшую площадь.

Я уже ответил на это уже, но нет, если у вас длинное соединение, он не должен иметь никакого отношения к тому, как долго работает интерпретатор (пока вы используете внешнее размещенное приложение, которое к настоящему времени должно быть ясными значительно превосходит). Поэтому, если вы хотите использовать комету и долго оставаться в живых (что обычно хорошо, если вы можете справиться с этим), рассмотрите nginx.

Бонусный вопрос FastCGI. Вы упомянули, что fastcgi может мультиплексироваться в одном соединении. Это действительно поддерживается протоколом (я считаю, что концепция известна как "каналы" ), так что теоретически один сокет может обрабатывать множество соединений. Тем не менее, это не обязательная особенность разработчиков fastcgi, и на самом деле я не верю, что есть один сервер, который использует это. Большинство респондентов fastcgi не используют эту функцию, потому что реализация этого очень сложна. Большинство веб-серверов будут производить только один запрос через данный сокет fastcgi за раз, а затем сделать следующий через этот сокет. Таким образом, у вас часто есть только один сокет fastcgi для процесса/потока.

Используется ли ваше приложение fastcgi для обработки или потоковой передачи (и реализуете ли вы его через "главный" процесс, принимающий соединения, делегирование или просто много процессов, каждый из которых делает свое дело) зависит от вас; и зависит от возможностей вашего языка программирования и ОС. В большинстве случаев все, что по умолчанию используется библиотекой, должно быть прекрасным, но будьте готовы к некоторому бенчмаркингу и настройке параметров.

Что касается общего состояния, я рекомендую вам притвориться, что каких-либо традиционных применений совместного процесса в процессе работы не существует: даже если они могут работать сейчас, возможно, вам придется разделить своих динамических работников на нескольких компьютерах позже. Для таких штатов, как тележки для покупок и т.д.; db может быть лучшим вариантом, информация для входа в сеанс может храниться в защищенных файлах, а для временного состояния что-то похожее на memcached довольно аккуратно. Чем меньше вы полагаетесь на функции, которые обмениваются данными (подход "общий-ничего" ), тем больше вы можете масштабировать в будущем.

Postscript: Я написал и развернул множество динамических приложений во всей области настроек выше: все перечисленные выше веб-серверы и все в диапазоне PHP/Python/Ruby/Java. Я интенсивно тестировал (используя как бенчмаркинг, так и наблюдение в реальном мире) методы, и результаты иногда удивляют: меньше часто бывает больше. После того как вы ушли от размещения своего кода в процессе веб-сервера, вы часто можете уйти с очень небольшим количеством сотрудников FastCGI/Mongrel/mod_wsgi/etc. Это зависит от того, сколько времени ваше приложение остается в БД, но очень часто бывает, что больше процессов, чем 2 * количество процессоров, на самом деле ничего не принесет вам.

Ответ 2

Как мой веб-сервер обрабатывает такие 100 одновременных запросов? Создает ли веб-сервер один процесс/поток для каждого запроса? (если да, процесс или поток?)

Это меняется. Apache имеет как потоки, так и процессы для обработки запросов. Apache запускает несколько параллельных процессов, каждый из которых может запускать любое количество одновременных потоков. Вы должны настроить Apache для управления тем, как это происходит на каждом запросе.

Как работает интерпретатор бэкэнд-языка? Как он обрабатывает запрос и генерирует правильный html? Будет ли интерпретатор генерировать процесс/поток для каждого запроса? (Если да, процесс или поток?)

Это зависит от конфигурации вашего Apache и вашего языка. Для Python один типичный подход заключается в том, чтобы в фоновом режиме выполнялись процессы демона. Каждому процессу Apache принадлежит процесс демона. Это делается с модулем mod_wsgi. Его можно настроить несколькими способами.

Если интерпретатор будет генерировать процесс/поток для каждого запроса, как насчет этих процессов (потоков)? Поделитесь ли они некоторым кодовым пространством? Будут ли они общаться друг с другом? Как обрабатывать глобальные переменные во внутренних кодах? Или они независимые процессы (потоки)? Как долго длится процесс/поток? Будут ли они уничтожены при обработке запроса и ответ будет возвращен?

Темы имеют одинаковый код. По определению.

Процессы будут использовать один и тот же код, потому что это работает Apache.

Они не намеренно - общаются друг с другом. У вашего кода нет способа легко определить, что еще происходит. Это по дизайну. Вы не можете определить, в каком процессе вы работаете, и не можете определить, какие другие потоки выполняются в этом пространстве процесса.

Процессы длительные. Они не создаются (и не должны) динамически создаваться. Вы настраиваете Apache для разблокировки нескольких параллельных копий самого себя, когда он начинает избегать накладных расходов на создание процесса.

Создание темы имеет гораздо меньшие накладные расходы. Как Apache обрабатывает потоки внутри, не имеет большого значения. Тем не менее, вы можете подумать об Apache как о начале потока за запрос.

Предположим, что веб-сервер может поддерживать только 100 одновременных запросов, но теперь он получил 1000 одновременных запросов. Как он справляется с такой ситуацией? Будут ли они обрабатывать их как очередь и обрабатывать запрос, когда сервер доступен? Или другие подходы?

Это вопрос "масштабируемости". Короче - как производительность ухудшится по мере увеличения нагрузки. Общий ответ заключается в том, что сервер становится медленнее. Для некоторого уровня нагрузки (скажем, 100 одновременных запросов) достаточно доступных процессов, что все они работают очень быстро. На некотором уровне нагрузки (например, 101 одновременный запрос) он начинает замедляться. На другом уровне нагрузки (кто знает, сколько запросов) он становится настолько медленным, что вы недовольны скоростью.

Существует внутренняя очередь (как часть работы TCP/IP, как правило), но нет регулятора, который ограничивает рабочую нагрузку до 100 одновременных запросов. Если вы получаете больше запросов, создается больше потоков (не больше процессов), и все происходит медленнее.

Ответ 3

Начнем с того, что подробные ответы на все ваши вопросы немного, IMHO.

В любом случае, несколько коротких ответов на ваши вопросы:

<Ь > # 1

Это зависит от архитектуры сервера. Apache - это многопроцессорный и, возможно, многопоточный сервер. Существует мастер-процесс, который прослушивает сетевой порт и управляет пулом рабочих процессов (где в случае "рабочий" mpm каждый рабочий процесс имеет несколько потоков). Когда приходит запрос, он направляется одному из простаивающих работников. Мастер управляет размером рабочего пула, запуская и завершая работу работников в зависимости от нагрузки и настроек конфигурации.

Теперь, lighthttpd и nginx отличаются; они представляют собой так называемые архитектуры на основе событий, где множественные сетевые соединения мультиплексируются на один или несколько рабочих процессов/потоков, используя поддержку ОС для мультиплексирования событий, такую ​​как классический select()/poll() в POSIX, или более масштабируемый, но к сожалению ОС-специфические механизмы, такие как epoll в Linux. Преимущество этого заключается в том, что для каждого дополнительного сетевого подключения требуется всего несколько сотен байт памяти, позволяя этим серверам открывать десятки тысяч подключений, что, как правило, было бы непомерно для архитектуры запроса/процесса/потока, такой как apache, Однако эти серверы на основе событий могут использовать несколько процессов или потоков для использования нескольких ядер процессора, а также для одновременного выполнения системных вызовов блокировки, таких как обычный ввод/вывод файлов POSIX.

Для получения дополнительной информации см. несколько устаревшую страницу C10k от Дэна Кегеля.

<Ь > # 2

Опять же, это зависит. Для классического CGI для каждого запроса запускается новый процесс. Для mod_php или mod_python с apache интерпретатор встроен в процессы apache и, следовательно, нет необходимости запускать новый процесс или поток. Однако это также означает, что для каждого процесса apache требуется довольно много памяти, и в сочетании с проблемами, описанными выше для # 1, ограничена масштабируемость.

Чтобы избежать этого, можно создать отдельный пул супертяжелых процессов, на которых работают интерпретаторы, и прокси-сервер сторонних веб-серверов для внутренних серверов, когда необходимо создать динамический контент. Это, по сути, подход, применяемый FastCGI и mod_wsgi (хотя они используют собственные протоколы, а не HTTP, поэтому, возможно, технически это не проксирование). Это также типично подход, выбранный при использовании серверов, основанных на событиях, поскольку редко используется код для генерации динамического контента, который необходим для правильной работы в среде, основанной на событиях. То же самое касается многопоточных подходов, если код динамического содержимого не является потокобезопасным; можно иметь, скажем, интерфейс apache-сервера с потоковым рабочим mpm-проксированием на серверы Apache сервера, на котором запущен PHP-код с однопоточным префиксом mpm.

<Ь > # 3

В зависимости от того, на каком уровне вы спрашиваете, они будут использовать некоторую память через механизм кэширования ОС, да. Но в целом, с точки зрения программиста, они независимы. Обратите внимание, что эта независимость сама по себе не является плохим, поскольку она позволяет прямолинейное масштабирование по горизонтали нескольким машинам. Но, увы, часто требуется некоторое количество сообщений. Один простой подход заключается в общении через базу данных, предполагая, что он необходим по другим причинам, как это обычно бывает. Другой подход заключается в использовании некоторой выделенной системы кэширования распределенной памяти, такой как memcached.

<Ь > # 4

Зависит. Они могут быть поставлены в очередь или сервер может ответить с некоторым подходящим кодом ошибки, таким как HTTP 503, или сервер может просто отказаться от соединения в первую очередь. Как правило, все это может происходить в зависимости от того, как загружен сервер.

<Ь > # 5

Жизнеспособность этого подхода зависит от архитектуры сервера (см. мой ответ на №1). Для сервера на основе событий сохранение открытых соединений не является большой проблемой, но для apache это, безусловно, связано с большим объемом памяти, необходимой для каждого соединения. И да, для этого, безусловно, требуется длительный процесс интерпретатора, но, как описано выше, за исключением классического CGI, это в значительной степени предоставляется.

Ответ 4

Веб-серверы - это многопоточная среда; помимо использования переменных области приложения, пользовательский запрос не взаимодействует с другими потоками.

Итак:

  • Да, новый поток будет создан для каждого пользователя
  • Да, HTML будет обрабатываться для каждого запроса
  • Вам понадобятся переменные с областью приложения
  • Если вы получите больше запросов, чем можете, они будут помещены в очередь. Если они доработаны до заданного периода ожидания, пользователь получит свой ответ или "сервер занят", как ошибка.
  • Комета не предназначена для любого сервера/языка. Вы можете добиться такого же результата, запросив свой сервер каждые n секунд, не имея дело с другими неприятными проблемами нитей.

Ответ 5

Потому что изолировать процесс - это то, что у вас не всегда есть контроль или знание, что я узнал до сих пор, что я должен напишите код, который опирается на потоки, и " контексты", чтобы хранить данные, которые "классически" будут храниться как статические данные. Но даже это может измениться в ближайшем будущем с появлением Continuations.