Записки программиста, обо всем и ни о чем. Но, наверное, больше профессионального.

2012-07-20

6 лет назад

Наткнулся в своих архивах на одну папку, 2006 года.
Видимо это было время, когда я пытался решить для себя — на какой платформе/технологии сфокусироваться. В итоге получилось как обычно, заказчики ставят такие условия, что выбирать-то и не из чего, жри что дают. Но, во всяком случае, понять с чем едят Java в вебе я успел.

А конкретно вот что (материалы из старой папки).

Типа предисловие.

Здесь хочу создать краткий обзор технологий и решений применяемых при построении масштабируемого веб-проекта. Если точнее, то "введение в тему". Итак, веб-проект, серверная его часть на Java...

Обьясняю: столкнулся я с проблемой, не могу найти внятного описания набора технологий, механизмов и продуктов из которых строится (или можно построить) масштабируемый веб сайт в основе работы которого лежат Java технологии. Не надо сразу отправлять к документации на некие продукты... я говорю о некоей вводной статье, которая дает понятие о том как все это работает в целом.
По отдельности и в разных местах всё есть, даже больше чем нужно. А вот чтоб в одном месте и последовательно, без излишнего углубления в несущественные детали... Не нашел.

В первую очередь для себя, а также и для других страждущих ликбеза (думаю я не одинок) хочу собрать в одном месте (статье, например) информацию, пошагово, от простого к сложному, обьясняющую, чем живет мир веб разработчиков на Java.

Текст сильно черновой, наброски. Да и терминологию надо уточнять. При создании статьи использованы материалы с RSDN forum. Большое спасибо живущим там профессионалам.

Простейший вариант веб сервера на Java

Любое веб приложение делится минимум на две части — клиент (работает в браузере пользователя) и сервер. Клиента мы рассматривать не будем, не здесь. Рассмотрим сервер.
Начинается сервер с обработчика протокола HTTP (Apache HTTPD, MS IIS). Его задача (основная) получить от клиента HTTP запрос и выдать ответ, обычно — текст HTML страницы.
Дабы выдаваемые страницы были "живыми" содержимое надо генерировать программно. Нивапрос — веб сервер по HTTP запросу может определить, что надо запустить некую программу, например PHP, которая и сгенерирует страницу.

А теперь забудем про PHP и представим, что веб сервер - это некая ява-машина (не Java runtime), под управлением которой запускаются и работают ява-программы, называемые servlet (сервлет).

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

Сервлет — это просто Java-класс, реализующий интерфейс javax.servlet.Servlet. В случае веб применения, сервлет чаще всего наследуется из класса javax.servlet.http.HttpServlet. Веб-приложение может содержать произвольное количество классов сервлетов. Также, веб-приложение содержит xml-файл, где заданы соответствия URL и имен классов сервлетов.

Когда сервлет-контейнер получает HTTP-запрос (например, http://domain.com:8080/webapp/servlet/name/), он находит соответствующее запросу веб-приложение (webapp) и загружает соответствующий класс сервлета (ища имя класса сервлета, соответствующего URI='/servlet/name/').

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

Технология JSP (Java Server Pages) является прямым расширением сервлетов. И смахивает она на использование PHP: JSP-файл представляет собой HTML-страницу, с Java-вставками в специальных тегах. Перед первым запуском (или во время) JSP компилируются в обычные сервлеты.

говорится о том, что сервлеты это инструмент для низкоуровневого (относительно) решения задачи "отработка запроса клиента", в случае, если частые изменения дизайна страниц не требуются. В то время как JSP это ориентированнй скорее на представительскую (presentation) сторону способ сделать страницы динамическими. Банально удобнее дизайнить внешний вид страниц. БОльшее разделение логики и внешнего вида.

Контейнер сервлетов поддерживает всё необходимое для реализации достаточно серьезного веб приложения: управление заголовками HTTP, аутентификацией, механизм сессий (с использованием кукисов - cookie) и прочие удобные и стандартные штуки: java.sun.com/j2ee/sdk_1.3/techdocs/api

Также контейнер может поддерживать разделяемый пул ресурсов, доступных сервлетам, например подключения к БД tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto
Эта фича может заметно поднять производительность - не надо при отработке каждого запроса клиента открывать БД, закрывать БД...

Установим сервлет-контейнер - Tomcat

Давайте попробуем установить необходимые компоненты для запуска веб-сервера под которым мы сможем запускать сервлеты и JSP.

http://tomcat.apache.org/ - The Apache Tomcat Servlet/JSP Container.
Отсюда мы возьмем бинарную сборку для Windows, конкретно отсюда: http://tomcat.apache.org/download-55.cgi версия 5.5.20 Binary Distributions Core Windows service installer. Почти 5 мегабайт.

Ранее я отсюда скачал и установил у себя JRE 1.5 и JDK 1.5 Standard Edition.
У меня это хозяйство расположилось на диске так:
P:\app\Java\jdk1.5.0_09\
P:\app\Java\jre1.5.0_09\
* Запускаем инсталлятор Tomcat: apache-tomcat-5.5.20.exe
* Установка FULL
* Куда ставить: p:\Tomcat5.5 (это будет переменная '''$CATALINA_HOME''' в дальнейшем)
* Порт 8080
* Админский юзер admin
* Админский пароль 123456789
* Ява рантайм оно само нашло в P:\app\Java\jre1.5.0_09
* оставил галки "запустить" и "показать ридми"
Визард почему то сам не закрылся, пришлось давить кнопу "Cancel".

В системе появился сервис Tomcat5, слушающий аж три порта 8009, 8080, 8005.
В трее появилась иконка. По щелчку открывается панель Apache Tomcat Properties.
По адресу http://localhost:8080/ в браузере открывается "поздравительная" страничка:

If you're seeing this page via a web browser, it means you've setup Tomcat successfully. Congratulations!

И действительно, мы видим результат отработки JSP страницы лежащей в
$CATALINA_HOME/webapps/ROOT/index.jsp

Далее в программе: написание простейшего (но своего!) приложения, в виде сервлета. Как затравку, нам предлагают взять файл
P:\Tomcat5.5\webapps\tomcat-docs\appdev\sample\sample.war
и положить его в
P:\Tomcat5.5\webapps\
а в результате, по адресу http://localhost:8080/sample/ мы увидим предлагаемый нам пример приложения на ява. Этот процесс описан в документации http://localhost:8080/tomcat-docs/appdev/processes.html по ссылке Example App

Установка админской консоли

версия 5.5.20 Binary Distributions - Administration Web Application
скачиваем пакет администрирования, 2.2 мегабайта.
Выдали файл apache-tomcat-5.5.20-admin.zip
распакуем его, в C:\TEMP так, что получается
c:\Temp\apache-tomcat-5.5.20\conf\
c:\Temp\apache-tomcat-5.5.20\server\
и эти два каталога переписываем в (прямо поверх)
P:\Tomcat5.5\conf\
P:\Tomcat5.5\server\
на самом деле файлы из пакета будут просто добавлены в конфигурацию Томкета.
Теперь по адресу http://localhost:8080/admin доступно приложение администрирования.

Конфигурация сервера (каталоги, порты, журналы,...)

Интеграция с веб-сервером Apache HTTPD

Включить поддержку SSL в Tomcat

Реализовать веб-приложение (сервлет)

Здесь я продемонстрирую процесс создания и установки не самого сложного приложения на базе сервлетов.

Нам понадобится инструментарий

* JDK - http://java.sun.com/javase/downloads/index_jdk5.jsp (у меня JDK 1.5), Java Development Kit понятно и без перевода;
* Tomcat + manager (установку этого дела я уже продемонстрировал), сервлет контейнер и средство управления;
* Ant - http://ant.apache.org/bindownload.cgi (у меня версия 1.7 почти 11 мегабайт), автоматизатор процесса разработки, по типу утилиты make, только на яве и для явы.

Я распаковал Ant в каталог, далее называемый ANT_HOME
P:\ant\
так, что получился путь P:\ant\bin\

Перед тем как использовать инструментарий я всегда выполняю команды (иначе работать не будет):
 set PATH=P:\ant\bin;%PATH% 
 set ANT_HOME=P:\ant 
 set JAVA_HOME=P:\app\Java\jdk1.5.0_09 
 set CATALINA_HOME=P:\Tomcat5.5 
Подробности можно узнать здесь: http://ant.apache.org/manual/index.html

Также я выполнил рекомендацию по включению в Ant библиотеки для общения с Tomcat:
COPY P:\Tomcat5.5\server\lib\catalina-ant.jar P:\ant\lib\catalina-ant.jar

Создание приложения

Я создал структуру каталогов для проекта (как рекомендовано в инструкциях к Ant и Tomcat) причем каталог sample может находитьсся где угодно, у меня внутре c:\j\
 md sample\docs 
 md sample\src\mypackage 
 md sample\web\WEB-INF 
 copy build.xml.template sample\build.xml 
этот build.xml - инструкции для Ant, его надо будет отредактировать, шаблон доступен здесь: http://tomcat.apache.org/tomcat-5.5-doc/appdev/build.xml.txt

Создал текстовый файл sample\build.properties (используется Антом)
с содержимым:
app.path=/VDemo1 
catalina.home=P:/Tomcat5.5 
manager.username=admin 
manager.password=123456789 
manager.url=http://localhost:8080/manager 

Tomcat нужны инструкции, что делать с приложением, которое ему подсовывают, для этого - отсюда: http://tomcat.apache.org/tomcat-5.5-doc/appdev/web.xml.txt
взял содержимое (заготовку) для файла deployment descriptor (непременно надо отредактировать) и положил в:
sample\web\WEB-INF\web.xml

Создал файл (исходный код примитивного сервлета):
sample\src\mypackage\VExampleOne.java
с содержимым:
package mypackage; 

import java.io.*; 
import java.text.*; 
import java.util.*; 
import javax.servlet.*; 
import javax.servlet.http.*; 

public class VExampleOne extends HttpServlet { 
 public void doGet ( 
   HttpServletRequest request, 
   HttpServletResponse response) 
  throws IOException, ServletException { 
  String title = "My first app!"; 
  response.setContentType("text/html"); 
  PrintWriter out = response.getWriter(); 

  out.println("<html>"); 
  out.println("<head>"); 
  out.println("<title>" + title + "</title>"); 
  out.println("</head>"); 
  out.println("<body bgcolor=\"white\">"); 
  out.println("<h1>" + title + "</h1>"); 
  out.println("</body>"); 
  out.println("</html>"); 
 } // doGet 
} // VExampleOne class 

Теперь самое время отредактировать содержимое build-файла для Анта:
sample\build.xml
<project name="My first webapp" default="compile" basedir="."> 
  <property file="build.properties"/> 
  <property name="app.name"      value="VDemo1"/> 
  <property name="app.path"      value="/${app.name}"/> 
  <property name="app.version"   value="0.1-dev"/> 
  <property name="build.home"    value="${basedir}/build"/> 
  <property name="catalina.home" value="P:/Tomcat5.5"/> 
  <property name="dist.home"     value="${basedir}/dist"/> 
  <property name="docs.home"     value="${basedir}/docs"/> 
  <property name="manager.url"   value="http://localhost:8080/manager"/> 
  <property name="src.home"      value="${basedir}/src"/> 
  <property name="web.home"      value="${basedir}/web"/> 

  <taskdef name="deploy"   classname="org.apache.catalina.ant.DeployTask"/> 
  <taskdef name="list"     classname="org.apache.catalina.ant.ListTask"/> 
  <taskdef name="reload"   classname="org.apache.catalina.ant.ReloadTask"/> 
  <taskdef name="undeploy" classname="org.apache.catalina.ant.UndeployTask"/> 

  <property name="compile.debug"       value="true"/> 
  <property name="compile.deprecation" value="false"/> 
  <property name="compile.optimize"    value="true"/> 

  <path id="compile.classpath"> 
 <pathelement location="${catalina.home}/common/classes"/> 
 <fileset dir="${catalina.home}/common/endorsed"> 
  <include name="*.jar"/> 
 </fileset> 
 <fileset dir="${catalina.home}/common/lib"> 
  <include name="*.jar"/> 
 </fileset> 
 <pathelement location="${catalina.home}/shared/classes"/> 
 <fileset dir="${catalina.home}/shared/lib"> 
  <include name="*.jar"/> 
 </fileset> 
  </path> 

  <target name="all" depends="clean,compile" 
 description="Clean build and dist directories, then compile"/> 

  <target name="clean" 
 description="Delete old build and dist directories"> 
    <delete dir="${build.home}"/> 
    <delete dir="${dist.home}"/> 
  </target> 

  <target name="compile" depends="prepare" 
 description="Compile Java sources"> 
    <mkdir    dir="${build.home}/WEB-INF/classes"/> 
    <javac srcdir="${src.home}" 
          destdir="${build.home}/WEB-INF/classes" 
            debug="${compile.debug}" 
      deprecation="${compile.deprecation}" 
         optimize="${compile.optimize}"> 
        <classpath refid="compile.classpath"/> 
    </javac> 
    <copy  todir="${build.home}/WEB-INF/classes"> 
      <fileset dir="${src.home}" excludes="**/*.java"/> 
    </copy> 
  </target> 

  <target name="dist" depends="compile,javadoc" 
   description="Create binary distribution"> 
    <mkdir   dir="${dist.home}/docs"/> 
    <copy    todir="${dist.home}/docs"> 
      <fileset dir="${docs.home}"/> 
    </copy> 
    <jar jarfile="${dist.home}/${app.name}-${app.version}.war" 
         basedir="${build.home}"/> 
  </target> 

  <target name="install" depends="compile" 
   description="Install application to servlet container"> 
    <deploy url="${manager.url}" 
       username="${manager.username}" 
       password="${manager.password}" 
           path="${app.path}" 
       localWar="file://${build.home}"/> 
  </target> 

  <target name="javadoc" depends="compile" 
   description="Create Javadoc API documentation"> 
    <mkdir          dir="${dist.home}/docs/api"/> 
    <javadoc sourcepath="${src.home}" 
                destdir="${dist.home}/docs/api" 
           packagenames="*"> 
      <classpath refid="compile.classpath"/> 
    </javadoc> 
  </target> 

  <target name="list" 
   description="List installed applications on servlet container"> 
    <list    url="${manager.url}" 
        username="${manager.username}" 
        password="${manager.password}"/> 
  </target> 

  <target name="prepare"> 
    <mkdir  dir="${build.home}"/> 
    <mkdir  dir="${build.home}/WEB-INF"/> 
    <mkdir  dir="${build.home}/WEB-INF/classes"/> 
    <copy todir="${build.home}"> 
      <fileset dir="${web.home}"/> 
    </copy> 
    <mkdir  dir="${build.home}/WEB-INF/lib"/> 
  </target> 

  <target name="reload" depends="compile" 
   description="Reload application on servlet container"> 
    <reload url="${manager.url}" 
       username="${manager.username}" 
       password="${manager.password}" 
           path="${app.path}"/> 
  </target> 

  <target name="remove" 
   description="Remove application on servlet container"> 
    <undeploy url="${manager.url}" 
         username="${manager.username}" 
         password="${manager.password}" 
             path="${app.path}"/> 
  </target> 

</project> 

Теперь редактируем деплоймент дескриптор
sample\web\WEB-INF\web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> 
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" 
    version="2.4"> 

    <display-name>First VS Java webapp</display-name> 
    <description> Simple example of Java webapp. </description> 

    <servlet> 
        <servlet-name>VDemo1Servlet1</servlet-name> 
        <servlet-class>mypackage.VExampleOne</servlet-class> 
    </servlet> 

    <servlet-mapping> 
        <servlet-name>VDemo1Servlet1</servlet-name> 
        <url-pattern>/servlet1</url-pattern> 
    </servlet-mapping> 
</web-app> 
Выглядит это все кошмарно, но только до тех пор, пока своими руками не сделаешь пару итераций и не осознаешь, что к чему.

Установка приложения в Tomcat

Проверим как компилируется, запустив командный файл такого содержимого:
rem установки переменных я приводить больше не буду, примем "по умолчанию": 
set PATH=P:\ant\bin;%PATH% 
set ANT_HOME=P:\ant 
set JAVA_HOME=P:\app\Java\jdk1.5.0_09 
set CATALINA_HOME =P:\Tomcat5.5 
pushd sample 
start "compile" /wait cmd.exe /k ant all 

У меня все откомпилировалось, теперь проинсталлируем приложение:
pushd sample 
start "remove" /wait cmd.exe /c ant remove 
start "install" /wait cmd.exe /k ant install 

По адресу http://localhost:8080/VDemo1/servlet1
должна появиться страница с текстом
My first app!

Ура, товарищи, оно работает. Вебприложение из одного сервлета. Минимальнее не бывает.

Дальше - самостоятельная работа, я буду копать направления - сервлет генерирует XML а в конце преобразует его в HTML с помощью подготовленных дизайнером XSL файлов; все данные для работы лежат в БД; интеграция с Apache HTTPD. Кстати, простейшие тесты показали увеличение скорости от 5 до 10 раз, по сравнению с кодом на PHP. Я не говорю уже о возможностях кластеризации, встроенных в саму технологию ява контейнеров.

Масштабируем, сервер приложений

С ростом проекта может понадобится функциональность, недостижимая в рамках простых веб-контейнеров. Например вам нужно для отработки запроса обратиться к нескольким базам данных, что-то отправить в унаследованную систему и отправить уведомление куда нибудь еще... в общем, обработать данные сразу из многих источников. При этом, необходимо соблюдать требования ACID. Нет, конечно, можно все сделать ручками... Но велосипед уже есть: сервер приложений, всем очень нравится, например, Jboss.

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

Итого картина у меня сейчас приблизительно такая - вебконтейнер под которым крутятся сервлеты и JSP образует второй уровень, если первым считать пользователя с браузером в руках. Для примитивных случаев этого достаточно. А если не достаточно, добавляем СП (еще говорят сервер J2EE), например контейнер EJB. Получаем третий уровень, на который высаживаем тяжелый компутинг. Причем СП создается обычно таким образом, чтобы его можно было посадить на кластер или ферму.

Терминология, понятия

Редакции Java, варианты платформы
Существует три основных редакции языка и базовых библиотек:
* j2SE - Java 2 Standard Edition
* J2EE - Java 2 Enterprise Edition
* J2ME - Java 2 Micro Edition
Микроедишн - это для портативных, мелких устройств. Например, в мобильных телефонах живет именно J2ME. Стандард - это базовый набор средств "просто для разработки и запуска просто ява программ". А нас как разработчиков неслабых веб проектов, интересует в основном энтерпрайз едишн. Там масса дополнительных библиотек, спецификаций и средств для поддержки распределенных масштабируемых управляемых ява систем.

Паттерны проектирования, обьектно-ориентированное программирование
Методология составления программ и программных комплексов. Играет очень важную роль в мире Java. Если вы не знаете, что такое паттерны проектирования, немедленно найдите хорошую книгу по этому вопросу и изучите. Иначе будет многое непонятно.

XML - eXtensible Markup Language
Наиболее важный и общеупотребимый формат данных, язык и средство для соединения подсистем в мире корпоративных (и не только) проектов. Применяйте хмл где можно и нельзя - все будут думать что вы крутой.

Servlet, сервлеты
Ява программы, исполняемые на сервере, если искать аналогии, то ближе всего к сервлетам будут CGI программы для веб сервера. Сервлеты могут динамически генерировать вебстраницы отправляемые клиентам в ответ на запросы.
Сервлеты эффективны при разработке веб приложений, в которых идет работа с БД, динамически генерируется содержимое, отображаемое браузерами, сохраняется уникальная для каждого клиента информация о сеансе.
Сервлеты обычно являются потоками одного процесса в виртуальнй машине ява.

JSP - Java Server Pages
Опять же, по аналогии - ближе всего PHP или ASP страницы веб сервера. Задачи почти такие же как и у сервлетов, только удобнее ваять дизайн, применяя JSP. В конечном итоге, JSP все равно компилирются в сервлеты. Сами страницы содержат
Скриптлеты - Scriptlet
исходный код коротких подпрограмм на языке Java. Эти скриптлеты обычно используют для выполнения работы некие компоненты -
JavaBeans - бины
Самостоятельные классы ява, построенные в соответствии с компонентной моделью Java.

TagLib - Tag Library
Ява библиотеки для использования в JSP. Позволяют простым использованием специальных тегов в странице добиться богатой функциональности. Дают возможность веб-дизайнерам добавлять динамическое содержание без программирования.

JSTL - JSP Standard Tag Library
Стандартный набор библиотек TagLib.

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

SOAP - Simple Object Access Protocol
протокол на базе XML, по этому протоколу можно использовать веб-сервисы.

EJB - Enterprise JavaBeans
Компонентная модель ява, применяется для построения бизнес логики корпоративных приложений. Содержит сеансовые компоненты (с состоянием и без), поддержку распределенных транзакций, компоненты управления данными (компоненты-сущности) для управления сущностями хранимыми в БД. Дает возможность строить надежные и устойчивые многоуровневые приложения. Используя RMI и контейнеры EJB, компоненты способствуют распределению логики по разным узлам сети.
И многое другое...

Сервер приложений
Окружение, среда выполнения, платформа для компонентов корпоративного приложения. Обеспечивают выполнение распределенных транзакций, управление производительностью, коммуникации между подсистемами. Создает условия для взаимодействия между различными компонентами и уровнями проекта. Управляют персистентностью, жизненным циклом, безопасностью.
И многое другое...

JMS - Java Message Service
Технология использования в ява средств промежуточного (middleware) ПО ориентированного на работу с сообщениями. Коммуникации путем обмена сообщениями, в двух моделях "точка-точка" или "издатель-подписчик". В EJB есть компоненты управляемые сообщениями.

Tomcat Client Deployer (TCD)
Инструмент для установки веб-приложения в сервлет-контейнер Tomcat. Утилита командной строки.

Коллекция ссылок по теме


Комментариев нет:

Отправить комментарий

Архив блога

Ярлыки

linux (241) python (191) citation (186) web-develop (170) gov.ru (159) video (124) бытовуха (115) sysadm (100) GIS (97) Zope(Plone) (88) бурчалки (84) Book (83) programming (82) грабли (77) Fun (76) development (73) windsurfing (72) Microsoft (64) hiload (62) internet provider (57) opensource (57) security (57) опыт (55) movie (52) Wisdom (51) ML (47) driving (45) hardware (45) language (45) money (42) JS (41) curse (40) bigdata (39) DBMS (38) ArcGIS (34) history (31) PDA (30) howto (30) holyday (29) Google (27) Oracle (27) tourism (27) virtbox (27) health (26) vacation (24) AI (23) Autodesk (23) SQL (23) Java (22) humor (22) knowledge (22) translate (20) CSS (19) cheatsheet (19) hack (19) Apache (16) Manager (15) web-browser (15) Никонов (15) functional programming (14) happiness (14) music (14) todo (14) PHP (13) course (13) scala (13) weapon (13) HTTP. Apache (12) Klaipeda (12) SSH (12) frameworks (12) hero (12) im (12) settings (12) HTML (11) SciTE (11) USA (11) crypto (11) game (11) map (11) HTTPD (9) ODF (9) купи/продай (9) Photo (8) benchmark (8) documentation (8) 3D (7) CS (7) DNS (7) NoSQL (7) cloud (7) django (7) gun (7) matroska (7) telephony (7) Microsoft Office (6) VCS (6) bluetooth (6) pidgin (6) proxy (6) Donald Knuth (5) ETL (5) NVIDIA (5) Palanga (5) REST (5) bash (5) flash (5) keyboard (5) price (5) samba (5) CGI (4) LISP (4) RoR (4) cache (4) car (4) display (4) holywar (4) nginx (4) pistol (4) spark (4) xml (4) Лебедев (4) IDE (3) IE8 (3) J2EE (3) NTFS (3) RDP (3) holiday (3) mount (3) Гоблин (3) кухня (3) урюк (3) AMQP (2) ERP (2) IE7 (2) NAS (2) Naudoc (2) PDF (2) address (2) air (2) british (2) coffee (2) fitness (2) font (2) ftp (2) fuckup (2) messaging (2) notify (2) sharepoint (2) ssl/tls (2) stardict (2) tests (2) tunnel (2) udev (2) APT (1) CRUD (1) Canyonlands (1) Cyprus (1) DVDShrink (1) Jabber (1) K9Copy (1) Matlab (1) Portugal (1) VBA (1) WD My Book (1) autoit (1) bike (1) cannabis (1) chat (1) concurrent (1) dbf (1) ext4 (1) idioten (1) join (1) krusader (1) license (1) life (1) migration (1) mindmap (1) navitel (1) pneumatic weapon (1) quiz (1) regexp (1) robot (1) science (1) serialization (1) spatial (1) tie (1) vim (1) Науру (1) крысы (1) налоги (1) пианино (1)