Избранное | Русский | Войти

Среда сервлетов Java

App Engine выполняет веб-приложение Java с помощью Java 6 JVM в безопасной "тестовой" среде. App Engine вызывает классы сервлетов приложения, чтобы обрабатывать в этой среде запросы и готовить ответы.

Выбор версии Java API

App Engine знает, что приложение нужно использовать в среде выполнения Java, если для загрузки приложения использовалось средство AppCfg из Java SDK.

На момент создания этого текста существует только одна версия API Java App Engine. Этот API представлен файлом appengine-api-*.jar, включенным в SDK (где * представляет версию API и SDK). Для выбора используемой приложением версии API следует включить этот файл JAR в каталог приложения WEB-INF/lib/. При выпуске новой версии среды выполнения Java, содержащей изменения, не совместимые с существующими приложениями, у этой среды будет новый номер версии. Приложение будет продолжать использовать предыдущую версию, пока вы не замените файл JAR новой версией (из нового SDK) и не загрузите приложение заново.

Запросы и сервлеты

При получении App Engine веб-запросов для приложения он вызывает сервлет, соответствующий URL по описанию в дескрипторе развертывания приложения (файл web.xml в каталоге WEB-INF/). Он использует Java Servlet API для предоставления данных запроса сервлету и принятия данных ответа.

App Engine использует несколько веб-серверов для работы приложения и автоматически подбирает количество, необходимое для надежной обработки запроса. Данный запрос может быть направлен любому серверу, а не только тому серверу, который обработал предыдущий запрос от того же пользователя.

Следующий пример класса сервлета отображает простое сообщение в браузере пользователя.

import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        resp.setContentType("text/plain");
        resp.getWriter().println("Hello, world");
    }
}

Ответы

App Engine вызывает сервлет с объектом запроса и объектом ответа и ожидает заполнения и возврата сервлетом объекта ответа. После возврата сервлетом данные в объекте ответа отправляются пользователю.

App Engine не поддерживает отправку данных клиенту, выполнение в приложении дополнительных вычислений и отправки дополнительных данных. Иными словами, App Engine не поддерживает организацию данных в "поток" в ответ на один запрос.

Если клиент отправляет заголовки HTTP с запросом, указывающим возможность получения сжатого содержания (gzip), App Engine автоматически сжимает данные запроса и присоединяет соответствующие заголовки ответа. Чтобы обеспечить надежное получение клиентом сжатых ответов, используются заголовки запроса Accept-Encoding и User-Agent. Чтобы принудительно сжать содержание, настраиваемым клиентам необходимо указать значение "gzip" в заголовках Accept-Encoding и User-Agent.

Таймер запросов

Обработчику запросов отведено ограниченное количество времени на создание и возврат ответа на запрос. Оно составляет примерно 30 секунд. Когда оно истекает, обработка запроса прерывается.

Среда выполнения Java прерывает работу сервлета, создавая com.google.apphosting.api.DeadlineExceededException. Если обработчик запроса не перехватывает это исключение, среда выполнения вернет клиенту ошибку сервера HTTP 500 (как и со всеми неперехваченными исключениями).

Обработчик запроса может перехватить эту ошибку для настройки ответа. Среда выполнения дает обработчику запроса немного больше времени (меньше секунды) на подготовку пользовательского ответа после создания исключения.

Хотя выполнение запроса может занимать до 30 секунд, App Engine оптимизирован для приложений с короткими запросами, выполнение которых обычно занимает несколько сотен миллисекунд. Эффективное приложение должно быстро отвечать на большинство запросов. Приложение, не удовлетворяющее этому требованию, не удастся эффективно масштабировать на инфраструктуре App Engine.

Тестовая среда

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

Приложение App Engine не в состоянии:

  • Осуществлять запись в файловую систему. Для хранения постоянных данных приложения должны использовать хранилище данных App Engine. Можно осуществлять чтение из файловой системы. Кроме того, доступны все файлы, добавленные с помощью приложения.
  • Открывать канал или производить доступ к узлу напрямую. Приложение может использовать службу получения данных по URL App Engine для выполнения HTTP- и HTTPS-запросов на порты 80 и 443 соответственно.
  • Создавать подпроцесс или поток. Веб-запрос к приложению должен быть обработан одним процессом за несколько секунд. Чтобы избежать перегрузки веб-сервера, прерываются процессы, на выполнение которых требуется длительное время.
  • Выполнять другие виды системных вызовов.

Потоки

Приложение Java не может создавать новые группы java.lang.ThreadGroup или потоки java.lang.Thread. Эти ограничения применяются и классам JRE, использующим потоки. Например, приложение не может создавать новые java.util.concurrent.ThreadPoolExecutor или java.util.Timer. Приложение может выполнять операции с текущим потоком, например Thread.currentThread().dumpStack().

Файловая система

Приложение Java не может использовать классы, которые используются для записи в файловую систему, например java.io.FileWriter. Приложение может считывать собственные файлы из файловой системы с помощью таких классов, как java.io.FileReader Приложение может также получать доступ к своим файлам как к "ресурсам", например Class.getResource() или ServletContext.getResource().

Через файловую систему приложению доступны только файлы, которые считаются "файлами ресурсов". По умолчанию все файлы в WAR являются "файлами ресурсов". Файлы можно исключить из этого набора с помощью файла appengine-web.xml.

java.lang.System

Функции класса java.lang.System, не применимые к App Engine, отключены.

Следующие методы System ничего не делают в App Engine: exit(), gc(), runFinalization(), runFinalizersOnExit()

Следующие методы System возвращают null: inheritedChannel(), console()

Приложение не может содержать или непосредственно вызывать собственный код JNI. Следующие методы System создают исключение java.lang.SecurityException: load(), loadLibrary(), setSecurityManager()

Возвращение

У приложения есть полный, неограниченный, возвратный доступ к своим классам. Оно может создавать запросы к любым закрытым членам, использовать java.lang.reflect.AccessibleObject.setAccessible() и считывать и устанавливать закрытые члены.

Приложение может возвращать классы JRE и API, например java.lang.String и javax.servlet.http.HttpServletRequest. Однако оно может получать доступ только к открытым членам этих классов, но не к защищенным или закрытым.

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

Загрузка пользовательских классов

App Engine полностью поддерживает загрузку пользовательских классов. При этом обратите внимание, что App Engine переопределяет все ClassLoaders, чтобы у всех классов, загружаемых приложением, были одинаковые полномочия. При загрузке пользовательских классов будьте осторожны с посторонним кодом.

"Белый список" JRE

Доступ к классам стандартной библиотеки Java (среда выполнения Java или JRE) ограничен классами, содержащимися в "белом списке" JRE App Engine.

Журналирование

Приложение может записывать сведения в журнал с помощью java.util.logging.Logger. Данные журнала для приложения можно просмотреть и проанализировать с помощью Консоли администрирования или загрузить с помощью appcfg.py request_logs. Консоль администрирования может распознавать уровни журналов классов Logger и в интерактивном режиме отображать сообщения на соответствующем уровне.

Все, что сервлет записывает в стандартный выходной поток (System.out) и стандартный поток ошибок (System.err), захватывается App Engine и записывается в журналы приложения. Строки, записываемые в стандартный выходной канал, попадают в журнал на уровне "INFO", а строки, записываемые в стандартный поток ошибок, попадают в журнал на уровне "WARNING". Будет работать любая инфраструктура журналов (например log4j), записывающая журнал в потоки вывода или ошибок. Но для более точного контроля отображения уровня журнала консоли администрирования инфраструктура записи в журнал должна использовать адаптер java.util.logging.

import java.util.logging.Logger;
// ...

public class MyServlet extends HttpServlet {
    private static final Logger log = Logger.getLogger(MyServlet.class.getName());

    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {

        log.info("An informational message.");

        log.warning("A warning message.");

        log.severe("An error message.");
    }
}

Java SDK App Engine включает файл шаблона logging.properties в каталоге appengine-java-sdk/config/user/. Для использования скопируйте файл в каталог WEB-INF/classes (или в другое место в WAR), затем системное свойство java.util.logging.config.file в "WEB-INF/classes/logging.properties" (или по любому другому пути относительно корня приложения). Системные свойства модно установить в файле appengine-web.xml следующим образом:

<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    ...

    <system-properties>
        <property name="java.util.logging.config.file" value="WEB-INF/classes/logging.properties" />
    </system-properties>

</appengine-web-app>

Новый мастер "плагин Google для Eclipse" создает эти файлы конфигурации журналов и автоматически копирует их в WEB-INF/classes/. Для java.util.logging нужно установить использование этого файла системным свойствам.

Среда

Все системные свойства и переменные среды принадлежат приложению и являются закрытыми. Установка системного свойства влияет только на представление приложения об этом свойстве, но не на представление JVM.

Системные свойства и переменные среды для приложения можно устанавливаются в дескрипторе развертывания.

App Engine устанавливает следующие системные свойства при инициализации JVM на сервере приложения:

  • file.separator
  • path.separator
  • line.separator
  • java.version
  • java.vendor
  • java.vendor.url
  • java.class.version
  • java.specification.version
  • java.specification.vendor
  • java.specification.name
  • java.vm.vendor
  • java.vm.name
  • java.vm.specification.version
  • java.vm.specification.vendor
  • java.vm.specification.name
  • user.dir

Квоты и ограничения

Каждый входящий в приложение запрос учитывается относительно квоты запросов.

Данные, получаемые как часть запроса, учитываются относительно квоты входящего трафика (оплачивается). Данные, отправляемые в ответ на запрос, учитываются относительно квоты исходящего трафика (оплачивается).

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

Процессорное время, потраченное на выполнение обработчика запросов, учитывается относительно квоты процессорного времени (оплачивается).

Подробнее о квотах рассказано в разделе Квоты и в разделе Консоли администрирования "Сведения о квотах".

Помимо квот, к обработчикам запросов применяются следующие ограничения:

Ограничение Величина
Размер запроса 10 мегабайт
Размер ответа 10 мегабайт
Длительность запроса 30 секунд
Одновременные динамические запросы 30 *
Максимальное количество файлов приложения 1000
Максимальное количество статических файлов 1000
Максимальный размер файла приложения 10 мегабайт
Максимальный размер статического файла 10 мегабайт
Максимальный общий размер всех файлов приложения и статических файлов 150 мегабайт

* Приложение может одновременно обрабатывать порядка 30 динамических запросов. Это означает, что приложение, для которого среднее время выполнения запроса на стороне сервера составляет 75 миллисекунд, может без задержки обслужить до (1000 мс/с / 75 мс/запрос) * 30 = 400 запросов в секунду. При выполнении приложений, ограниченных возможностями процессора, может возникать дополнительная задержка в связи с необходимостью освободить ресурсы для других приложений, использующих эти же сервера. Это ограничение не влияет на запросы статических файлов.