четверг, 24 декабря 2015 г.

Hadoop and Big Data Tutorials


This week, a collection of useful articles and tutorials on using tools for ETL, ELT, ingest, manipulation and preparing data for your data lake.
Start developing with Hadoop ASAP with a quick start Docker container from Cloudera.
Some great tips on using Flume.
Working with Cell-level Security in HBase.
Getting started with Apache Zeppelin (Spark).
Avoiding the Mess in Hadoop Clusters.
Real-time Stock Prediction with an Open Source Data Stack.
A deep-dive presentation on Spark SQL.
Two good introductions to Apache Spark and here.
Information on the upcoming Apache Spark 1.6.
An Overview of DataFrames with Apache Spark and Scala.
Tips and Tricks for Scaling Apache Spark.
Introduction to Apache Spark with Python.
Two free GitBooks on Apache Spark (Mastering Apache Spark and Databricks Spark Reference Applications).

пятница, 18 декабря 2015 г.

from-threadstolambda and bigdata interesting

https://events.yandex.ru/lib/talks/2066/
http://www.slideshare.net/yandex/from-threadstolambda-yandex?next_slideshow=1

http://jug.ua/2015/12/apache_drill_and_apache_spark/

Возможное зацикливание редиректа.

У нас сайт на хттпс, но админу нужен доступ в хттп. И у нас после логина под админом случается бесконечное зацикливание - причина тому HTTP Strict Transport Security (HSTS).
В хроме она включена по умолчанию, а ФФ нужно включать, также поддержка есть у Safari и будет от Microsoft.
Сайты могут поддерживать и https и http одновременно, но страницы с уязвимыми данными от пользователя обслуживаются только в https, но пользователь может ввести урл без  протокола или с незащищенным протоколом и передать уязвимые данные в сеть, где они могут быть перехваченными.
Для этого страницы под https могут добавлять заголовок:
Strict-Transport-Security: max-age=16070400; includeSubDomains
Теперь браузер запоминает, что данный домен верхнего уровня должен быть только под https на указанное время. И браузер уже все запросы отправляет только по TSL.

chrome://net-internals/#hsts - включить/выключить, очистить кеш.

четверг, 17 декабря 2015 г.

Как тестить сервлеты в юнит тестах

Для этого нам понадобятся следующие библиотеки:
org.springframework:spring-test:4.1.7.RELEASE (для моков запроса и ответа)
org.jsoup:jsoup:1.7.3 (для разбора хтмл страницы и выборки элементов на ней)
- шаблонизатор для генерации хтмл ответа сервлеты(ну можно например воспользоваться com.github.spullara.mustache.java:compiler:0.9.0)

Интерфейс java Cucumber для Dependency Injection containers

Определяется например в cucumber.properties cucumber.api.java.ObjectFactory=my.pack.MyObjFactory
Служит для сборки приемочных тестов кукумбера классами поддрежки и другими.

вторник, 15 декабря 2015 г.

TDD with Mocks. "Mock Objects" framework

Почему TDD(write test first)?
1) Мы фокусируемся на исследовании предметной области, которую мы разрабатываем, и по определению не можем знать хорошо сразу, а не на продумывании реализации и архитектуры сразу(изобретении), что подразумевает - мы знаем домен уже хорошо сразу, что будет возможным только через, возможно, полгода работы с проектом.
2) Мы не смиряемся с "так получилось", мы пишем в ракурсе "нужно так".
3) Покрытость тестами, позволяет нам не бояться рефакторить, и наша архитектура эволюционирует и рождается, это какбы путь "обреченный" на хорошую архитектуру.

По-быстрому свободной формы json c Jackson

ObjectMapper jacksonMapper = new ObjectMapper();
JsonNodeFactory jsonNodeFactory = new JsonNodeFactory(false);
JsonFactory jsonFactory = new JsonFactory();

final ObjectNode jsonRoot = jsonNodeFactory.objectNode();

jsonRoot.set("error", 
  jsonNodeFactory.objectNode()
              .put("code", 1)
              .put("msg", "Message")
);
jsonRoot.putNull("nullField");
//ResourceResponse resp;
resp.setContentType("application/json;");
    jacksonMapper.writeTree(
        jsonFactory.createGenerator(resp.getWriter()),
        jsonRoot
    );
    resp.getWriter().flush();

среда, 9 декабря 2015 г.

Интересный набор курсов на PluralSite

http://blog.pluralsight.com/learning-path-ethical-hacking

среда, 2 декабря 2015 г.

Аннотации для профилирования

@IfProfileValue - для активайии/деактивации тестов, в зависимости от значений системных переменных(те который получаются так Map env = System.getenv(); , а устанавливаются либо "export some=hello; java app" | "some=hello java app" | "java app -Dsome=hello")
@IfProfileValue(name = "test-groups", values = { "unit-tests", "integration-tests" })
 public void testWhichRunsForUnitOrIntegrationTestGroups() {
     // ...
 }

Для инициализации бина в конкретной среде, которая определяется профилем, используется другая аннотация:
@Profile({"p1", "!p2"})

пятница, 27 ноября 2015 г.

Как заимпортить все цепочку сертификатов в truststore из общего pem файла

1) Переводим в формат архива для цепочек:

$ openssl pkcs7 -in new\ cert\ -\ PKCS\ \(inter\ CA\).txt -out certschain.p7b

$ openssl pkcs7 -print_certs -in certschain.p7b -out newcertschain.pem
2) в трастстор.

Транасформиция перевода строки windows файлов в unix

Некоторые форматы критичны к переводу строки, например pem, поэтому если он был сохранен в Windows, его нужно будет конвертировать. На  Unix это делается вот так:

$ tr -d '\r' < original.pem > fixed.pem
Так удаляется символ "возврата каретки" и остается только "новой строки".

воскресенье, 15 ноября 2015 г.

Nim workshop

$ - nim toString
    Expl:  $a[0]



Data exchange with C

C typeNim type
intcint
unsigned longculong
floatcfloat
int x[4]array[4, cint]
int*ptr int
char*cstring
char**cstringArray = ptr array [0..ArrayDummySize, cstring]

addr x[0] -> to   ptr [type]

# - first argument
@ - other comma separated args

Emit pragma - used to javascript generation in nim, but it's also possible to generate C - but this is bad idea.




Heap - is always garbadge colected




Jester - web [micro]framework on Nim


/nimongo -- by Rostislav
/exort       -- by Rostislav

Vagrant


emerald - nim templating engine

http://www.buildout.org/

Nim компилируется быстрее С++ и Rust, но меделеннее Golang.

graced references


nake - сборка



SDL2


syngraph

Adobe After Effect - композиции для карты

opengl


python - для прототипирования, потом раньше переводили на C++
сейчас Юра для прототипирования использует Nim

jnim - гегерирует код java из nim для передачи в jvm - для работы в android

coveralls - для тест каверидж.

интерполирование

uho3D

NimScript - виртуальная машина для интерпретации, можно кодить в интепретации.

SDL - делает связку OpenGL c чем-то:)

Nim - Nimrod - король первый в истории человечества, но это слово матюк по английски, поэтому название укоротили, но корона в названии осталась.

Compile Function Evaluation
const vs let?
Яркий пример:
Задача получить список файлов в директории.
- При компайл тайме(const): мы не реагируем приложением в рантайме на добавление новых файлов в эту директорию.
- При рантайме(let): реагируем на добавление файлов без пересборки приложений.







четверг, 5 ноября 2015 г.

Mac os sed replace in-place problem

В макосе правка прям в файле не работает если не указать явно пустой постфикс для бекапного первоисточника:

sed -i '' 's/oldword/newword/' file1.txt
      ^ note the space

воскресенье, 11 октября 2015 г.

Cucumber configurations

Иногда нужно проверить только один сценарий, для этого мы указываем кукумберу в опциях его имя:
$ mvn test -Dcucumber.options="--name 'Message is too long'"
Scenario: Message is too long
  When Sean shouts:
  """  
  This is a really long message  so long in fact that 
  I am not going to be allowed  to send it, at list 
  if I keep typing like this  until the length is over 
  the limit of 180  characters...  
  """  
  Then nobody nears Sean's message
Кроме того в имя мы можем подствить регулярное выражение и запустить несколько сценариев, которые ему подойдут!

пятница, 25 сентября 2015 г.

Как продебажить Maven проект на фазе тестов

Подход 1.

Запускаем в проекте:

$ mvn -Dmaven.surefire.debug test
Процесс Mojo запуститься, для тестов он запустит отдельных процесс, который будет выполняться паралельно, паралельный процесс запустится на порту 5005, и остановится ожидая подключения дебагера на этот порт.
Теперь мы можем из IDE подключиться удаленным подключением к этому порту по протоколу  jdwp.


Подход 2.

Все то же самое, но отключаем создание второго потока под тесты. Зачем это может быть нужно? Может потому что если настроить на несколько потоков, то на свободных потоках будут запускаться несколько тестов одновременно, после того как мы подключимся приложение остановится только там где стоят точки останова, все остальные тесты могут в фоне повыполняться, пока мы дебажим один тест, и мы уже вспомнив о другом должны будем все перезапускать сначала?

$ mvn -Dmaven.surefire.debug -DforkCount=0 test
Так мы знаем что ничего другого в фоне не выполняется.

Подход 3.
Иногда нужно изменить порт, или что-то другое в настройках дебага, для этого указываем параметры передаваемые jvm при запуске(java [параметры]) явно:
$ mvn -Dmaven.surefire.debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -Xnoagent -Djava.compiler=NONE" test

Либо чтобы не писать много буков каждый раз при перезапуске, так:

$ export MAVEN_OPTS=-Dmaven.surefire.debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -Xnoagent -Djava.compiler=NONE"
$ mvn test
Так в текущей сессии терминала мы можем не указывать maven.surefire.debug параметр.

Подход 4.
Отдебажить только один тестовый класс:
$ mvn -Dtest=MySuperClassTest -Dmaven.surefire.debug test

Подход 5.
Можно с версии 2.0.8 сократить количетсво букв, чтобы не указывать maven.surefire.debug,  так:
$ mvnDebug -DforkCount=0 test

В результате этих манипуляций jvm запустит наш jar проекта и будет ожидать удаленного подключения.

JPDA

Java Platform Debugger Architecture (JPDA)

Java Virtual Machine Profiler Interface (JVMPI) и Java Virtual Machine Debug Interface (JVMDI) были замещены в JDK 5.0 новым инетерфейсом  Java Virtual Machine Tool Interface (JVM TI)

JVM TI нативный программный интерфейс для использования сторонними инструментами, чтобы получать состояния JVM. Решаются такие задачи как профилирование, отладка, мониторинг, анализ потоков, coverage analysis tools.

JDWP (Java Debug Wire Protocol) - протокол для общения между дебагером и JVM, которую он дебажит.

JDWP Interface - C-шный интерфейс для протокола.

JDI (Java Debug Interface) - высокоуровневый Java интерфейс, наверно для дебагеров написанных на Java.

Получить доступ к классам WAR модуля

Для модуля интеграционных и приемочных тестов нужен доступ к классам из модуля для веб-архива. Для этого нужно в модуле веб-архива добавить нстройку war-плагина:
<plugin>
  <artifactid>maven-war-plugin</artifactid>
  <version>[2.6,)</version>
  <configuration>
    <attachclasses>true</attachclasses>
  </configuration>
</plugin>

Ну а в зависимом модуле, поставить зависимость и определить для нее classifier в classes 
<dependency>
            <groupId>de.scsynergy</groupId>
            <artifactId>Dms</artifactId>
            <version>0.1</version>
            <classifier>classes</classifier>
            <scope>test</scope>
        </dependency>

среда, 16 сентября 2015 г.

here document & here string

Получило распорстранение  в языках программирования из Unix shell-ов - для переопределения инпут потока команды не из файла, а прямо в консоли, - в языках программирования это мультистрочность строки.

среда, 9 сентября 2015 г.

Работа с бинарными дампами MongoDB

Сделать дамп одной базы:
mongodump --db elementary --out db.elementary-09092015.mongodump
tar -zcvf db.elementary-09092015.mongodump.tar.gz db.elementary-09092015.mongodumpp

Восстановить дамп:
tar -xzf db.elementary-09092015.mongodump.tar.gz 
mongorestore db.elementary-09092015.mongodump

четверг, 27 августа 2015 г.

Сетевые интерфейсы в centos/redhat

/etc/sysconfig/network-scripts/
Там могут обитать файлы ifcfg-eth0, ifcfg-eth1.

Skype useful console commands

How To Set A Skype Chat So That New Arrivals See (Some) Chat History

/set options +HISTORY_DISCLOSED

вторник, 30 июня 2015 г.

netstat

Выводит сетевые соединения, таблицы маршрутизации, статистику указанных сетевых интерфейсов, "маскарадируемые" соединения, и multicast memberships

Вывод открытых портов

# netstat -lptu
-l - (--listening)показать только слушающие порты
-p - (--programm)показать PID и имя программы, которой принадлежит открытый сокет
-t - (--tcp)только сокети семейста tcp
-u - (--udp)только сокеты семейста udp


# netstat -tulpn
-n - (--numeric) показать IP адресса, а не имена хостов, а также порты в виде номеров, а не названия протоколов, для которых данные номера считаются "стандартными"

Утилита, которой можно добиться того же:


# lsof -i
Утилита вывода списка открытых файлов
-i - вывести файлы, которых "интернет адресс" соответсвует указанному после ключа, если никакой не указан, то выводятся все Internet и x.25(HP-UX) сетевые файлы (снова можем убедиться в том, что Unix все в ОС считает файлом - даже открытое соединение на сокете). Можем "попросить" вывести все открытые сокеты по протоколы ip6 так: lsof -i6, или только для указанного списка айпишек: lsof -i6 fa:ce:b0:00:: 89:ce:: 

Общение узлов из подсети с глобальной сетью

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

1. Возможно мы можем себе позволить приобрести у ISP не такое количество IP адрессов, сколько у нас узлов(обычно это может быть только один).
2. Проблемы безопасности.
3. Разумная экономия на трафике.

пятница, 26 июня 2015 г.

Сказка о том как в JVM каждый обьект имеет свой собственнный монитор

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

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

stop, suspend, resume are @deprecated. Но если нужно, что тогда?

Если такой функционал нужен, то его нужно реализовывать через флаги.
public class App extends Thread {

  static App self;

  private volatile boolean threadSuspended = false;

  public App(String name) {
    super(name);
  }

  public static void main(String[] args) {

    self = new App("WORKER");

    self.start();

    new Thread(new Runnable() {
      public void run() {
        try {
          Thread.sleep(5000);
          printFromThread("Let's suspend!");
          self._suspend();

          Thread.sleep(5000);
          printFromThread("Let's resume!");
          self._resume();

          Thread.sleep(15000);
          printFromThread("Let's stop!");
          self._stop();

          Thread.sleep(15000);
          printFromThread("I'm going to die...");

        } catch (InterruptedException e) {
          printFromThread("Interrupter is interrupted!!!))))))))))))))))))");
        }
      }
    }, "controller").start();
  }

  private static void printFromThread(String x) {
    System.out.println( "[ " + Thread.currentThread().getName() + " (" + System.nanoTime() + ") ]" + x);
  }

  public void run() {
    Thread thisThread = Thread.currentThread();
    while (self == thisThread) {
      try {
        printFromThread("I'm starting sleeping");
        Thread.sleep(1000);
        printFromThread("I've just finished sleeping");

        synchronized (this) {
          printFromThread("I'm just synchronized");
          while (threadSuspended && self == thisThread) {
            printFromThread("Let's start waiting iteration");
            this.wait();
            printFromThread("Good morning!.....");
          }
        }
      } catch (InterruptedException e) {
        printFromThread("Look's like I was awoken now!");
      }
      repaint();
    }
  }

  public void repaint() {
    printFromThread("<<<<<<<<<<<<<<<<<<< Repainting ... >>>>>>>>>>>>>>>>>>>>>>");
  }

  public synchronized void _suspend() {
    printFromThread("self was suspended.");
    threadSuspended = true;
  }

  public synchronized void _resume() {
    printFromThread("self was resumed");
    threadSuspended = false;
    notify();
  }

  public synchronized void _stop() {
    self = null;
    printFromThread("self was \"nulled\". So let's notify to break wait");
    notify();
  }
}

четверг, 25 июня 2015 г.

Thread Scheduler

В мультипроцессорной/ядерной системе thread scheduler отвечает за распределении процессорного времени между процессами.
JVM по-умолчанию пользуется услугами системного TS, линукс и виндоус работают по схеме преемптив мультизадачности.
У каждого процессора/ядра, есть свой планировщик, но для обобщения обычно говорят об одном.
Преемптив планировщик, карантирует, каким бы низким приоритетом не обладал поток и какие высокоприоритетные потоки не ожидали рядом с ним, он гарантированно получит доступ к выполнению.
Да, первыми идут на выполнение высокоприоритетные процессы, но все они работают не больше определенного в системе количества квантов времени - квант равняется нескольким тикам часов процессора/ядра. Если процесс отработал свой лимит он будет сохранен со своим контекстом(состоянием регистров и текущей точкой выполнения в стеке) и отправлен в конец(или в какое-то место другое - наверняка есть алгорит вычисления места в очереди на основании состояния ждущий и их приоритетов) очереди процессов на выполнение. И следующий процесс из очереди получит доступ к процессору/ядру.

У процессов есть неслько состояний: раннабл, вейтинг, нью - вейтинг процесс не получит доступ даже если подошла его очередь - он ожидает какое-то событие и это будет холостое переключение контекста.
События могут менять приоритет в очереди - если например пришло I/O событие, что запрошенные байты были прочитаны с переферии и могут быть получена с этого момент с памяти в регистры - так процесс пробудится в ближайший момент, но его приоритет резко увеличивается и он уже находится среди высокоприоритетных тредов.

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

среда, 24 июня 2015 г.

Subroutine, Coroutine, Generator

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

Fibers

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

Файберы реализуют ту самую концепцию, что и корутины. Единственное, что можно назвать отличием между ними - это то, что корутины конструкция уровня языка, а файберы - системы.

Плюс такого подхода, что мы уходим от проблем синхронизации.
Минус - что мы не пользуемся на полную мощь ресурсом параллельной системы.
Но подход маппинга платформенной многопоточности на системную N:M с использование файберов пока зывает себя очень хорошо в сравнении с чистый упред

четверг, 18 июня 2015 г.

Программная транзакционная память(SТМ)

Программная транзакционная память(software transactional memory, SТМ) - концепция, которая переносит идею транзакции в межпоточное взаимодействие.
Потоки работают с копией данных из памяти, не блокирую таким образом друг друга, при завершении транзакции происходит коммит, что означает, что все изменения вносятся в журнал виртуальной машины, если не происходит кофликтов в имененном состоянии памяти, то изменения фиксируются в памяти. В случае конфликта изменения откатывается и виртуальная машина выполняет снова траназкционный код с новым состоянием памяти и опять пытается сделать коммит.

На практике такой подход намного концептуально сильнее подхода локов, но приносит дополнительные расходы на виртуальную машину - журнал, повторные попытки и т.д.

Часто в небольших приложениях программы с локами работают быстрее.

Но SТМ решает некоторые задачи, которые не может решить лок, а также программы в такой конецпции намного проще и понятние.

В принцпипе найхудшая оценка алгоритмики подхода = O(n) при n - количество потоков.


SТМ реализован в ядре Clojure.

Модели паралельного программирования в разных языках

C/C++ - нативный подход, используются механизмы многопоточности предоставляемые ядром.

JDK     - по-умолчанию потоки виртуальной машины мапятся  на нативные потоки ОС 1:1, но можно переключить JVM на зеленые потоки - реализацию JDK, которая работатет по факту только в одном системном потоке по-очередно переключаясь между потоками виртуальной машины, симулируя многопоточность, иногда за счет економии на переключениях на уровне ядра, это может быть оправдано.

Python - (CPython) хоть и используется манипулирование нативными потоками, но в этот момент происходит GIL(Global Interpreter Lock), что означает, что в одно и тоже время, только один поток может использовать интерпретатор питона для выполнения его команд, при истечении лимита команд на один поток, происходит переключение на другой. Поэтому паралельной работы в одно и тоже время не происходит. В питон подключаются библиотеки Си, они чаще всего потоконебезопасны, поэтому подход с GIL пытается это обезопасить. В рамках проекта PyPy (в котором компилятор питона пишется на самом питоне) пытаются реализовать модель "Транзакционной памяти"(Software Transactional Memory, SТМ). На данный момент даже в многопоточных вычислениях интерпретатор с STM работает в разы медленней, чем с GIL. Но за счёт JIT PyPy-STM всё равно быстрее, чем CPython.

Erlang - реализут в многопоточности модель "ничего общего"(shared nothing), используются микропроцессы(юзерспес виртуальной памяти), а не потоки, что очень быстро.


четверг, 11 июня 2015 г.

Виртуальная память

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

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


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

Процессы приложений видят свою виртуальную память и не имеют доступа к чужой( при этом, если позволяют права, некоторые процессы могут запросить у ядра доступ к участку памяти другого(чужого) процесса - например debuggers). Также они могут запросить разделенную память с другими процессами у ядра, хотя можно использовать и другие техники межпроцессного взаимодействия - пайпы и сокеты.




суббота, 6 июня 2015 г.

Чему равен размер ссылки в языке программирования?

Размер ссылки всегда равен раздядности регистров процессора (размеру машинного слова).

Это потому, что процессору может адрессоваться к памяти не выше этого числа.
В 32битной архитектуре машинное слово = 4 байта( 8 х 4 = 32).
В 64битной - 8 байт (8 х 8 = 64).


В C/C++ есть тип с названием слово - WORD - его размер 2 байта, это потому что язык был реализован на момент, когда технологический уровень был на уровне 16битной архитектуры, поэтому этот тип в C/C++ исторически сохраняет размерность 2-х байт.

вторник, 21 апреля 2015 г.

Разрешение на маке

Узнать разрешения мониторов подключенных на маке
$ system_profiler SPDisplaysDataType |grep Resolution
Resolution: 1920 x 1080

суббота, 4 апреля 2015 г.

Mac OS. Увидеть почему на стартует apach с php модулем

Что-то грепанье логов и запустк через сервисную утилиту никакой информации о проблема не давал:
➜ ~ tail -f /var/log/apache2/*

➜ ~ sudo apachectl restart

Оказалось, что прямой вызов дает информацию
Можно так:
/usr/sbin/httpd -k restart
httpd: Syntax error on line 59 of /private/etc/apache2/httpd.conf: Cannot load libexec/apache2/mod_authn_default.so into server: dlopen(/usr/libexec/apache2/mod_authn_default.so, 10): image not found

И все же цивилизиванный выход оказался тоже:
➜  ~  apachectl configtest
httpd: Syntax error on line 59 of /private/etc/apache2/httpd.conf: Cannot load libexec/apache2/mod_authn_default.so into server: dlopen(/usr/libexec/apache2/mod_authn_default.so, 10): image not found

пятница, 3 апреля 2015 г.

MacPorts. Узнать где установленны части указанного апликации(port).

Пример:
➜  ~   port contents nginx
Port nginx contains:
  /Library/LaunchDaemons/org.macports.nginx.plist
  /opt/local/etc/LaunchDaemons/org.macports.nginx/org.macports.nginx.plist
  /opt/local/etc/nginx/koi-utf
  /opt/local/etc/nginx/koi-win
  /opt/local/etc/nginx/win-utf
  /opt/local/sbin/nginx
  /opt/local/share/nginx/examples/fastcgi.conf.default
  /opt/local/share/nginx/examples/fastcgi_params.default
  /opt/local/share/nginx/examples/mime.types.default
  /opt/local/share/nginx/examples/nginx.conf.default
  /opt/local/share/nginx/examples/scgi_params.default
  /opt/local/share/nginx/examples/uwsgi_params.default
  /opt/local/share/nginx/html/50x.html
  /opt/local/share/nginx/html/index.html
  /opt/local/var/log/nginx/.turd_nginx
  /opt/local/var/run/nginx/.turd_nginx

Полезные онлайн-сервисы

http://temp-mail.org/ - сервис временной почты, фишка в том, что пока у нас идентификатор сессии в браузере, почта сохраняется, покрайней мере за ночь ее никакя джоба не почистила.

четверг, 2 апреля 2015 г.

SELECT из SELECT

Задачка 15 из http://www.sql-ex.ru/learn_exercises.php

Задание: 15 (Serge I: 2003-02-03)
Найдите размеры жестких дисков, совпадающих у двух и более PC. Вывести: HD

Спасибо Максиму вспомнил как сделать селект из селекта, а то реально залип - нужно обязательно называть как-то вьюху, которая получается из подзапроса:)

SELECT pcView.hd FROM (SELECT hd, count(code) as pc_count_with_such_hd from PC
GROUP BY hd
HAVING count(code) > 1) pcView

SQL WITH expression в мощных RDBM

Задачка 14 из http://www.sql-ex.ru/learn_exercises.php
Задание: 14 (Serge I: 2012-04-20)
Найти производителей, которые выпускают более одной модели, при этом все выпускаемые производителем модели являются продуктами одного типа.
Вывести: maker, type


with PrdCountByType as (select 
  maker, type, count(model) as prd_count from Product 
group by 
  maker, type 
),
MakerWithCounts as (select maker, count(type) as c_type, sum(prd_count) as prd_count from PrdCountByType
group by 
  maker
having 
  count(type) < 2 and sum(prd_count) > 1)
Select distinct maker, type from Product where maker in (select maker from MakerWithCounts)


среда, 1 апреля 2015 г.

Web Speed Efficiency. Список ресурсов.

Рекомендации:
https://developers.google.com/speed/
https://developer.yahoo.com/performance/

Онлайн аналитик тулы:
http://www.webpagetest.org/


вторник, 24 марта 2015 г.

Задачки по алгоритмам

Тренировка алгоритмики(задачки) -
https://projecteuler.net/
http://www.spoj.com/

суббота, 14 марта 2015 г.

Создание распределенной системы на Amazon AWS. Установка DNS слоя.

Amazon Route 53 - высокодоступный масштабируемый облачный сервис разрешения доменных имен.
Перенаправляет запросы пользователей к инфраструктуре AWS: напрямую к инстанциям EC2, или же на балансировщики нагрузки Elastic Load Balancing; или даже на внешнюю инфраструктуру не AWS.

Стратегии принятия решений разрешения доменных имен:

  1. Latency Based Routing - Route 53 пингует каждый узел распределенной системы и откуда быстрее приходит ответ, туда и отправляется запрос.
  2. Geo DNS - решение о перенаправлении принимается на основании из какого региона посетитель, нужно не забывать также указывать направление по умолчанию, чтобы не предусмотренный регион не остался без ответа. Также если какой-то сервер лежит(а Route53 пингует перед там как туда отправлять запрос), то запрос пойдет также на дефолтовый сервер.
  3. Weighted Round Robin - любимая стратегия маркетологов, потому что с ее помощью можно организовать A/B тестирование. Каждому узлу устанавливается вес и с соответсвующей распределенной вероятносью запросы пользователей распределяются по узлам. Также она применяется когда мы хотим какой-то новый релиз протестировать на продакшине, но чтобы если что-то там не так только маленький процент пользователей, испытал неудобства, для этого на узел с новым кодом ставим маленький вес.
  4. DNS Failover - есть основной узел и есть запасной, на который идут запросы, когда упал первый, обычно вторым может быть простая страничка с сообщением что, что-то не так, но мы уже фиксим.
Также могут быть комбинации этих стратегий, когда Route53 перенаправяет на другой Route53. Самый яркий пример это когда на входе стоит Route53 со стратегией DNS Failover, второй узел - вебсервер со страницей извинения, а первый это Route53 с какойнибудь Latency Based Routing, за которой находятся узлы с балансировщиками, за ними же десятки, а то и сотни серверов.

пятница, 13 марта 2015 г.

NativeScript&ReactNative

новые тренды в разработке нейтивных мобильных приложений… с помощью javascript :)

NativeScript:
https://www.nativescript.org/
http://developer.telerik.com/featured/nativescript-works/

И React Native:
http://www.railslove.com/stories/fresh-on-our-radar-react-native
http://jlongster.com/First-Impressions-using-React-Native

суббота, 7 марта 2015 г.

Docker Troubleshooting

Docker deamon logging

Чтобы поменять уровень логировния нужно для начала остановить демон и запустить с измененным уровнем логирования


# service docker stop
docker stop/waiting
# docker -d -l debug &

Но чтобы это было более удобно для сервиса(когда он подымается атоматически, а не руками):
# /etc/default/docker
DOCKER_OPTS="--log-level=fatal"

вторник, 3 марта 2015 г.

Docker networking

Виды сетей у докера(Docker Network Types)

Closed Network/ None Network - контейнеры находясь в такой сети закрыты от и для внешнего мира
Bridge Network - вид по-умолчанию, где создается мост, через который контейнеры могут общаться с внешним миром и между собой на поточном хосте. В каждом контейнере созадется свой личный сетевой интерфейс, который соединяется с мостом для общений.
Host Network - прямой доступ на сетевой интерфейс хозяйской машины, как на родной
Overlay Network - тип сети, который позволяет находиться контейнерам в одной сети, не смотря на то, что они между собой запущены на разных хостах.

Посмотреть доступные сети докера на хосте. По умолчанию будут следующие:

$ docker network ls
NETWORK ID      NAME            DRIVER          SCOPE
77bf6b8ff5cf    bridge          bridge          local
9aac4cefdaf1    host            host            local
b8aa8b4a699f    none            null            local

Closed Network/ None Network

Пример как запустить изолированный конртейнер:
$ docker run -d --net none busybox sleep 1000
Внутри у такого контейнера только один сетевой интерфейс lo, который лупбек - тоесть это только локалхост.

Bridge Network

Внутри у контейнера, который по умолчанию подключен к bridge сети, уже два сетевых интерфейса lo и eth0, которая уже локальная сеть типа Mask: 255.255.0.0
Но контейнеры с разных сетей типа мост не могут уже иметь доступа к друг другу. Можем создать еще одну сеть типа мост:
$ docker network create --driver bridge my_bridge_network
$ docker network inspect my_bridge_network
[
   {
      "Name": "my_bridge_network",
      ...
      "IPAM": {
        "Driver": "default",
        "Config": [
           {
             "Subnet": "172.18.0.0/16",
             "Gateway": "172.18.0.1"
           }
        ]
      },
      ...
   }
]
$ docker run -d --name container_3 --net my_bridge_network busybox sleep 1000
Но мы можем подключать контейнеры к нескольким сетям, так контейнер который запущен был в другой сети сможет общаться с контейнера с сети по умолчанию
$ docker network connect bridge container_3
Вот так контейнер получил, доступ к контейнерам с другой сети. Так он получил еще +один сетевой интерфейс eth1.
Ну и когда доступ больше предоставлять не стоит, то
$ docker network disconnect bridge container_3
Так сетевой интерфейс eth1 удаляется у контейнера.
  Следующя информация может быть уже устаревшей, но принцип остается следующим.
Docker всегда создает дополнительный сетевой интерфейс в системе с именем bridge0(скорее всего на момент 11.02.2017 он уже с именем docker0).
Этот интерфейс является ничем иным как мостом(bridge) или виртуальным свитчером - устройство которое перебрасывает пакеты между двумя устройствами для коммуникации между ними.
Чтобы исследовать любой сетевой мост в системе нужна следующая утилита:
# apt-get install bridge-utils
# yum install bridge-utils

Посмотрим что он нам раскажет о нашем мосте:
# brctl show docker0
bridge name       bridge id           STP enabled      interfaces
docker0           8000.56847afe9799   no
Сейчас мы не видим ни одного интерфейса подключенного к мосту - это означает, что у нас нет запущенных образов:)

Наваляем побыстрому образок:
echo "\
#Test for networking module \
FROM ubuntu:15.04 \
RUN apt-get update && apt-get install -y iputils-ping traceroute \
ENTRYPOINT /bin/bash " > Dockerfile
#
# docker build -t="net-img" .
И запустим с него два контейнера
# docker run -it --name=net1 net-img #Ctrl+P+Q
# docker run -it --name=net2 net-img #Ctrl+P+Q
#
# docker ps
CONTAINER ID       IMAGE             COMMAND       CREATED
STATUS             PORTS             NAMES
d37d347f84d8       net-img:latest    "/bin/bash"   0 minutes ago Up 0 minutes
c0e85b69ecce       net-img:latest    "/bin/bahs"   1 minutes ago Up 1 minutes
Вураля и у нас появились два дополнительных сетевых интерфейса, которые завязаны на наш докеровский мост:
# brctl show docker0
bridge name       bridge id           STP enabled      interfaces
docker0           8000.56847afe9799   no               veth095066e
                                                       vethe7516ef
# ifconfig
...
veth095066e Link encap:Ethernet HWaddr ...
...
vethe7516ef Link encap:Ethernet HWaddr ...

Virtual Ethernet  - имя интерфейсов.

Host Network

Наименее защищенная сеть, такие контейнеры называются\ открытыми. Они получают доступ на пряму к сетевым интерфесам хостовой машины.

Линкование контейнеров

https://docs.docker.com/userguide/dockerlinks/
Обычно апликация у нас находится на одном контейнере, а база данных на другом. Нужен унифицированный механизм, который бы нам давал возможность связывать новоподнятый узел горизонтального масштабирования.
Тут нам приходит на помощь линкование контейнеров, мы не выставляем порты наружу, и связь апликация с базой сверхсекьюрная - доступа снаружи нет - коммуникация возможна только между контейнерами.

$ sudo docker run -d --name db training/postgres
$ sudo docker run -d -P --name web --link db:db training/webapp python app.py
Залинкованные порты описаны в переменных окружения контейнера, откуда апликация их и может достать:
 DB_NAME=/web2/db
 DB_PORT=tcp://172.17.0.5:5432
 DB_PORT_5432_TCP=tcp://172.17.0.5:5432
 DB_PORT_5432_TCP_PROTO=tcp
 DB_PORT_5432_TCP_PORT=5432
 DB_PORT_5432_TCP_ADDR=172.17.0.5
А вообще если конкретный контейнер даже если не предоставляет никаких переменных окружения, то линкование, добавляет в /etc/hosts по имени прилинкованного контейнера его ip адрес, и мы можем использовать это имя для сетевых конектов.

Раскрытие портов из контейнера

Чтобы апликация из контейнера вышла "в свет" по сети, нужно контейнерный порт привязать на хостовый.
Для начала в Dockerfile:
EXPOSE 80
Потом при запуске контейнера нужно сделать собственно привязку на конкретный порт:
root# docker run -d -p 5000:80 --name=web1 apache-img

Чтобы увидеть что куда привязано, можем либо это посмотреть через docker ps или лучше через специальзированную команду, чтобы не распыляться на лишнюю информацию:
root# docker port web1
80/tcp -> 0.0.0.0:5000
0.0.0.0 - кстати означает, что порт 5000 подвязан на все сетевые интерфейсы хоста, которые имеют адресс IP4. Если нужно на конкретный, то нужно кроме порта указывать и конкретный ip.

Мы тоже можем раскрывать не только tcp, но и другие траспортные протоколы:
root# docker run -d -p 192.168.56.50:5001:80/udp --name=web2 apache-img

С ключем -P происходит запуск, который мапит все выставленные наружу порты контейнера на случайные порты хоста:
root# docker run -d -P --name=web-random-host-port apache-img

Network protocols

Протоколы, которые базируются на IP.

Сетевые службы пользуются предопределенными портами, описание портов и служб находится в файле:
/etc/services
Возле порта также находится указание по какому транспортному протоколу происходит соединение TCP, UDP, другие.


strace

утилита, через которую можно увидить какие системные вызовы делает и отправляет сигналы указанная команда.
Это как некий лог сишных вызовов по чтению файлов и дергания системных процедур.
Например, чтобы посмотреть действительно ли netstat пользуется файлом /etc/services мы можем выполнить:
root# strace netstat -atl 2>&1 | grep services
open("/etc/services", O_RDONLY|O_CLOEXEC) = 4
read(4, "# /etc/service:\n# $Id: services"..., 4096) = 4096
Как видим открывает и читает.

Эта утилита полезна, когда мы понимаем, что у нас какая-то ошибка в команде/утилите/апликации, но не понятно по ее логам, какая и как ее исправлять, то иногда трасировка дает нам шанс. Иногда это даже спасение в NodeJs приложениях.

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

git branch -u remotename/remotebranchname localbranchname
или
git branch --set-upstream-to=remotename/remotebranchname localbranchname

суббота, 28 февраля 2015 г.

Dockerfile

Build cache - когда мы отбилдили какойнибудь Dockerfile последующие билды будут в разы быстрее, потому что будет билдится только новое, все остальные слои просто используются.
Но можно: docker build --no-cache=true {...}

FROM - базовый образ/имидж из которой создается текущий контейнер.
RUN - команды, которые будут запускаться при сборке этого образа. Каждая такая команда запускается в writable layer предыдущего образа, и потом комитится, создавая образ для следующей RUN строки, таким образом, если у нас изменения происходят на какой-то из строк RUN, то может использоваться кеш из образа который выше изменения, и только последующий перевыполняются и перезаписуют свои образы. Чем меньше RUN тем меньше дискогового пространства будет задействовано, но во время активного написания билда, полезно использовать много RUN, чтобы эффективные/быстрее пробовать/проверять стремные изменения, потом можно обьединить в один RUN, когда все оттестировано.
CMD - команды, которые будут запускаться каждый раз при запуске контейнера. По факту в виде shell form это запускается как /bin/bash -c "то что мы определили". И мы тут можем начинять и пайпами и переадресацией потоков и т.д.
Exec form - ["commOrArg1", "commOrArg2"] этот вариант не требует чтобы в контейнере была установлена оболочка, также каждая команда экранируется.
Команды cmd могут быть подменены на этапе запуска контейнера путем:
docker run ... {команда}
ENTRYPOINT - не может быть перегружена docker run ... в отличии от CMD. Зато все, что мы передаем таким способом на этапе запуска, интрепритируется как аргументы в ENTRYPOINT. Таким образом мы уже не можем попасть в запущеный контейнер через такой аргумент. Например:
ENTRYPOINT ["echo"]
И мы пытаемся:
# docker run -it mycontainer /bin/bash
Но мы не подключимся к нему, а получим:
# docker run -it mycontainer /bin/bash
/bin/bash
#

Чтобы все-таки ENTRYPOINT перегрузить полностью можно воспользоваться ключем --entrypoint.

В докер-файлах пользуются ENTRYPOINT чтобы определить процесс, который будет работать в контейнере, а CMD - чтобы определить дефолтовые параметры для него, которые также можно переопределить при запуске контейнера если что:

ENV var1=val1 var2=val2 - определение переменный окружения
VOLUME ["/data"] - создаеть отвязанное от контейнера хранилище, которое будет храниться в стандартном месте хостовой машины(var/lib/docker/vfs/dir/CONTAINERHASH), при удалении контейнера место останется с данными, также можно разделять с другими контейнерами общее хранилище или загружать оттуда некие индивидуальные настройки под контейнер.

EXPOSE 80 - указываем какой порт мы открываем из контейнера. А при запуске с помощью параметра -p мы уже определяем порт хоста, который подвязывается на порт контейнера и у нас получается пайп снаружи в контейнер.

ADD vs COPY
COPY - копирует файлы с указанного места ОС-хозяина в контейнер.
ADD - тут можно указывать первым аргументом и место/ресурс в файловой системе и URL удаленного сетевого ресурса, если ресурсы заархивирован, то он еще и розархивируется в контейнере.
Всегда лучше использовать COPY, если мы имеем дело с местом в ОС, и только если нам нужен архив или ресурс из сети, то тогда ADD.

Docker volumes

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

Запуск apache web-server и папки проекта

So here’s what I figured I would need to do:
  • Run apache in the foreground from the project root.
  • Craft a minimal apache configuration file for serving PHP from a single doc root.
  • Extra credit: get apache to log to the console in the foreground.

пятница, 27 февраля 2015 г.

Private Docker Registry

Registry - там где хранятся образы докер.

1. Можем воспользоваться открытым реджистри. 
# docker login [registry_url] --username=coreer
Password:
Login Succeeded! 
# docker push myrepositoty/myimage:mytag

if [registry_url] == empty then docker logs in "https://hub.docker.com/"

2. Можем подключить из своей сети несекьюрный(http или https публичного ключа которого мы не имеем) реджистри.
Debian family: /etc/default/docker
Redhat family: /etc/sysconfig/docker
Добавляем строку DOCKER_OPTS="--insecure-registry registry.mydomain.com"

3. Или добавить сертифакат в доверенные. 
# cp devdockerCA.crt /usr/local/share/ca-certificates/
# update-ca-certificates

4. Поднять себе локально реджистри
# docker run -d -p 5000:5000 --restart=always --name registry registry:2

registry v1 - проект на python, который предоставляет возможность поднять сервис с регистром для доков(образов), который мы можем развернуть в своей сети. И заливать туда приватные доки и качать от туда.

registry v2 - проект на golang. Уже стабилен.


Docker основные команды

docker run
  --cpu-shares=
  --memory=
docker run -it ubuntu:14.04 /bin/bash
-i - interective
-t - подключить tty 
ubuntu - repository name
14.04 - image name
/bin/bash - команда которую выполнить при старте контейнера PID1 (родитель всех процессов - в Linux это init)

docker run -d ubuntu:14.04 /bin/nginx start
-d detache запустить в фоне

четверг, 26 февраля 2015 г.

curl и wget


сURL -- это утилита для приема передачи файлов в роли клиента через разные протоколы (http,ftp,scp,smtp и многие другие), ипользуя урл синтаксис. Это часть проекта cURL, в который также входит библиоте libcurl, ее api можно использовать в своих приложениях.

Командная утилита очень богата, например для http, с помощью ее можно передавать куки, проводить аутентификацию, использовать запросы гет, пост, пут и др.

wget -- это гну этилита. Означает www get. Предназначение получать файлы с веб сервера. Работает с протоколами хттп, хттпс и фтп. Пожет скачивать рекурсивно(как веб-гусеница, скачивая все, на что есть ссылки с уже загруженного ресурса).

Это из

Чтобы скачать сайт целиком с помощью wget нужно выполнить команду:
wget -r -k -l 7 -p -E -nc http://site.com/

Справочник по командам wget и curl

wget — консольная утилита для скачивания файлов/сайтов, умеет выкачивать файлы рекурсивно, следуя по ссылкам автоматически.

вторник, 24 февраля 2015 г.

Установка docker на Ubuntu

1. Обновить ядро до версии >3.8 - потому что docker нуждается в фичах cgroup & namespaces:
user@host$ apt-cache search linux-headers-$(uname -r)
linux-headers-3.2.0-76-generic - Linux kernel headers for version 3.2.0 on 64bit x86 SMP
linux-headers-3.2.0-76-generic-pae - Linux kernel headers for version 3.2.0 on 64bit x86 SMP
user@host$
user@host$
user@host$
user@host$ sudo apt-get install linux-image-generic-lts-trusty linux-headers-generic-lts-trusty
....
user@host$ sudo shutdown -r now
....
user@host$ apt-cache search linux-headers-$(uname -r)
linux-headers-3.8.0-44-generic - Linux kernel headers for version 3.8.0 on 64bit x86 SMP

2. сама установка https://docs.docker.com/installation/ubuntulinux 

пятница, 20 февраля 2015 г.

ldd

ldd (List Dynamic Dependencies) - *nix утилита, которая позволяет узанть какими разделяемыми библиотеками ОС пользуется переданный как параметр бинаркник.
Стремные бинарники лучше не проверять, потому что утилита их запускает.

вторник, 17 февраля 2015 г.

Работа с юзерами

Создать юзера и поставить ему пароль:
# adduser tom
# passwd tom

Добавить новосозданного юзера в группы:
# useradd -G admins,ftp,www,developers jerry


Создать новую группу:
# groupadd developers


Поставить основную группу новосозданному юзеру:
# useradd -g developers tony
А теперь посмотрим где он и что он
# id tony


Добавить существующего юзера в группу:
usermod -a -G ftp tony


Установить существующему юзеру основную группу:
# usermod -g www tony


суббота, 14 февраля 2015 г.

Терминалы Linux

Терминал - это интерфейс через который мы совершаем управление ОС.

пятница, 13 февраля 2015 г.

Возможные загрузчики Linux

PXELINUX - для загрузки по сети.
SYSLINUX - для загрузки из USB устройства
ISOLINUX - для закрзки из оптического устройства
EXTLINUX - альтернатива GRUB

PXE

PXE - Preboot eXecution Environment(пикси), спецификация описывает стандартизированную слиент-серверную среду, которая загружает софтверную сборку, полученную из сети, на PXE-настоенный клиент.

Hardware: на клиенте для этого нужен PXE-совместимый Network Interface Controller (NIC: к сети -  Ethernet, WIFI, Token ring, ATM; к метеринке - встроенный, PCI, USB, FireWire etc).

Протоколы по которым происходит передача: DHCP(Dynamic Host Configuration Protocol - для динамического распространения по сети конфигурационных параметров(IP адреса для интрефейсов и сервисов), позволяет не вносить админу в новый узел сети это руками), TFTP(Trivial File Transfer Protocol - для простого get и put из/на сервер).

Процес:
1) DHCP request ->    <- dhcp="" p="" response="">2) TFTP get ->  <- p="" pxelinux.0="">3) TFTP get Config ->  <- default="" p="" pxelinux.cfg="">4) Retrieve Kernel(по какому протоколу?) ->   <- -="" disk="" initrd="" linux="" nitial="" p="" ram="">5) Загрузка и дальнейший старт или инсталяция.


среда, 11 февраля 2015 г.

AWS Terminology

AWS - Amazon Web Services
IAM - Identity and Access Management. Users&Groups, Accesses through policies.
AMI - Amazon Machine Image. Образ виртуальной машины: архитектура железа, ос.
EC2 - Elastic Cloud. Создание AMI, загрузка их в S3, безопасность и сетевые настройки доступа к AMI, планирование расходов на облачную инфраструктуру.
S3 - Simple Storage Service. Файорвый хостинг. На пример им пользуется Dropbox, Ubuntu One.
CloudFront - реализация CDN сервиса от Amazon.

четверг, 15 января 2015 г.

Формула расчета максимального обьема памяти для jvm

Max memory = [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss]