How to Download a File Partially

May 22, 2020

Как скачивать файл порциями

Иногда требуется скачивать файл порциями. Причины бывают разные, например слишком “большой” объем файла, ширина канала не достаточна или сервер ограничивает объем данных для скачивания.

В этой статье опишу каким образом реализовать скачивание файла небольшими порциями через протокол HTTP.

Об HTTP

Для таких целей HTTP предоставляет заголовок Range для запроса. В котором указывается диапазон байтов для скачивания. Заголовок Range относится только к телу запроса, заголовки сюда не входят.

Спецификация определяет следующие форматы указания значений заголовка:

Range: bytes=first-byte-pos "-" [last-byte-pos]

first-byte-pos - начальное смещение байта с которого необходимо начать (продолжить) скачивание, оно должно быть больше либо равно 0, и меньше либо равно last-byte-pos;

last-byte-pos - конечное смещение байта до которого необходимо скачать файл, оно должно быть больше либо равно first-byte-pos и при этом меньше либо равно скачиваемому размеру файла минус один (потому что это смещение, то есть индекс в массиве байтов).

Read more

SSH Configuration

Mar 20, 2019

Вступление

Не буду описывать что такое SSH и зачем оно нужно. Эта статья из рубрики советов. В своё время я достаточно долго просидел в консоли Linux. И за этот период наработал привычки, которые могут оказаться полезными.

Добавляйте алиасы серверам

В подавляющем большинстве случаев подключение к серверу по SSH выполняется следующей командой:

$ ssh aukhatov@172.28.10.56

Выглядит довольно коротко и ясно. Всё бы ничего когда серверов один или два. Ситуация усложняется когда количество серверов увеличивается, надо по IP понимать что за сервер (или имени хоста это в лучшем случае).

А еще хуже когда учётные записи и порты для подключения на сервера отличаются. С точки зрения безопасности так даже предпочтительнее и в окружения типа PRED-PROD, PROD скорее всего так и будет.

Для таких случаев у SSH есть способ задать алиас на подключение:

~/.ssh/config

Host pg-db                  # алиас, лучше называть осмысленно у нас вымышленный Postgres DB
  User aukhatov             # пользователь от которого подключаемся
  HostName 172.28.10.56     # IP-адрес хоста для подключения или доменное имя
  Port 22                   # стандартный порт, можно не указывать

Теперь подключение к вымышленному серверу с Postgres DB осуществляется командой:

$ ssh pg-db

Используйте SSH ключи для аутентификации

Пароли не всегда удобны, не всегда безопасны, легко ошибиться. А когда много раз вводишь и где-то все равно ошибаешься это сильно раздражает и потом забываешь зачем вообще сюда пришёл потому что забыл пока вспоминал пароль.

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

Чтобы проходит аутентификацию по открытому ключу, необходимо выполнить команду:

$ ssh-copy-id pg-db

Эта встроенная в *nix утилита, которая копирует ваш открытый SSH ключ из ~/.ssh/id_rsa.pub и добавляет его в специальный .ssh/authorized_keys файл. Если вы поменяете ключ, то данное упражнение придётся проделывать заново.

После того как открытый ключ скопирован на удалённый сервер, то подключение осуществляется без пароля.

Тонкие моменты

Может быть такое, что у вас локально имеются разные пары ключей, и хочется подключаться на разные серваки по разным ключам. Такое тоже предусмотрено, для этого в ~/.ssh/config есть у Host есть параметр IdentifyFile

Host pg-db                                  # алиас, лучше называть осмысленно
  User aukhatov                             # пользователь от которого подключаемся
  HostName 172.28.10.56                     # IP-адрес хоста для подключения или доменное имя
  Port 22                                   # стандартный порт, можно не указывать
  IdentifyFile ~/.ssh/another_private_key   # путь к приватному ключу

Для не стандартной пары приватного и открытого ключа также можно выполнить команду ssh-copy-id, только уже с опцией -i и указанием открытого ключа

$ ssh-copy-id -i ~/.ssh/another_public_key pg-db

В конфигурация SSH сервера можно вообще отключить аутентификацию по паролю:

/etc/ssh/sshd_config

 PasswordAuthentication no

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

Clean Up Your Docker Images

Mar 18, 2019

Show All Docker Images

$ docker images

Output:

REPOSITORY                         TAG                 IMAGE ID            CREATED             SIZE
jemalloc                           latest              f55e72747051        47 hours ago        897MB
centos-java-slim                   8u201-b09           a0e265286b7f        12 days ago         3.55MB
aukhatov/centos-java               8u201-b09           31f71c1b4eda        12 days ago         311MB
aukhatov/srping-boot-auth-server   0.1.0               c6159d63ad1c        2 weeks ago         136MB
aukhatov/mem-eat                   1.0                 4e6aa1979b36        4 weeks ago         105MB
openjdk                            8-jdk-alpine        792ff45a2a17        5 weeks ago         105MB
centos                             7                   1e1148e4cc2c        3 months ago        202MB
postgres                           latest              f9b577fb1ed6        3 months ago        311MB
ubuntu                             latest              cd6d8154f1e1        6 months ago        84.1MB
redis                              latest              bfcb1f6df2db        10 months ago       107MB
eclipse-mosquitto                  latest              bd592a7a5bcf        14 months ago       4.38MB

Get Docker Image Ids

docker images | tr -s ' ' | cut -d ' ' -f3

Output:

IMAGE
f55e72747051
a0e265286b7f
31f71c1b4eda
c6159d63ad1c
4e6aa1979b36
792ff45a2a17
1e1148e4cc2c
f9b577fb1ed6
cd6d8154f1e1
bfcb1f6df2db
bd592a7a5bcf

Clean Up All Docker Images

And you can pass the previous command result into the docker rmi command.

$ docker rmi -f $(docker images | tr -s ' ' | cut -d ' ' -f3)

Clean Up All Docker Container

$ docker rm $(docker ps -a | tr -s ' ' | cut -d ' ' -f1)

Singleton Pattern in Java

Mar 17, 2019

Существует несколько способов создания Singleton объектов в Java. Рассмотрим несколько из них, разделив на две группы.

Шаблон Singleton используется для ограничения создания экземпляра класса и гарантирует что в JVM существует только один экземпляр этого класса.

Ленивые

Ленивая инициализация - означает, что экземпляр создается по требованию.

С двойной проверкой (Lazy initialization with double check)

Данный подход в Интеренет ресурсах является самым популярным, только я не знаю почему. Основная проблема заключается когда два потока входят в первое условие if а экземпляр еще не создан. Далее блокировка на классе и затем снова проверка экземпляра на null, чтобы убедиться окончательно.

public class Singleton {

    private static volatile Singleton INSTANCE = null;
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        if (INSTANCE == null) {
            synchronized (Singleton.class) {
                if (INSTANCE == null) {
                    INSTANCE = new Singleton();
                }
            }
        }
        return INSTANCE;
    }
}

Через внутренний класс (Lazy initialization by using inner class)

Реализация через внутренний класс основана на гарантиях спецификации языка Java (JLS).

public class Singleton {
    
    private Singleton() {}
    
    private static class SingletonHolder {
        static final Singleton INSTANCE = new Singleton();
    }
    
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}
Read more