РСсайз ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ Π½Π° Π»Π΅Ρ‚Ρƒ

ΠŸΡ€Π°ΠΊΡ‚ΠΈΡ‡Π΅ΡΠΊΠΈ Π² любом Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π΅ΠΌ изобраТСния сущСствуСт ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎΡΡ‚ΡŒ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½Π½Ρ‹Π΅ ΠΊΠΎΠΏΠΈΠΈ этих ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, ΠΏΡ€ΠΈΡ‡Π΅ΠΌ Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ, Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠ² Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ нСсколько.
Π’Π°ΠΊ ΠΆΠ΅ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π³ΠΎΠ»ΠΎΠ²Π½ΡƒΡŽ боль Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²Ρ‹Ρ… Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² Π½Π° ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ. ΠžΡ‚ΡΡŽΠ΄Π° Π·Π°Π΄Π°Ρ‡Π°:

Π—Π°Π΄Π°Ρ‡Π°

ΠžΠ±ΠΎΠ·Π½Π°Ρ‡ΠΈΠΌ список Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ:

  • Π€ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ изобраТСния Π»ΡŽΠ±Ρ‹Ρ… Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠ² Π½Π° Π»Π΅Ρ‚Ρƒ Π±Π΅Π· внСсСния Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»Π° Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² любой ΠΌΠΎΠΌΠ΅Π½Ρ‚ сущСствования прилоТСния;
  • Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ изобраТСния Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ запросС;
  • Π—Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ формирования Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ нСустановлСнных Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠ².

Объясню послСдний ΠΏΡƒΠ½ΠΊΡ‚, ΠΈΠ±ΠΎ ΠΎΠ½ слСгка ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΡ€Π΅Ρ‡ΠΈΡ‚ ΠΏΠ΅Ρ€Π²ΠΎΠΌΡƒ ΠΏΡƒΠ½ΠΊΡ‚Ρƒ. Если ΠΌΡ‹ сдСлаСм ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π»ΡŽΠ±Ρ‹Ρ… ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, Ρ‚ΠΎ сущСствуСт Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π°Ρ‚Π°ΠΊΠΈ Π½Π° сайт ΠΏΡƒΡ‚Π΅ΠΌ формирования большого количСства запросов Π½Π° рСсайз изобраТСния Π² бСсконСчноС количСство Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠ², поэтому эту ΡƒΡΠ·Π²ΠΈΠΌΠΎΡΡ‚ΡŒ трСбуСтся Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ.

ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ установки nginx

Для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π²Ρ‹ΡˆΠ΅ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ Π½Π°ΠΌ потрСбуСтся ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π½Π°Π±ΠΎΡ€ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ nginx:

ΠœΠΎΠ΄ΡƒΠ»ΠΈ ngx_http_image_filter_module ΠΈ ngx_http_secure_link_module ΠΏΠΎ-ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π½Π΅ ставятся поэтому ΠΈΡ… Π½ΡƒΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π½Π° этапС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ установки nginx:

phoinix@phoinix-work:~/src/nginx-0.8.29
$ ./configure --with-http_secure_link_module --with-http_image_filter_module

ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ nginx

Π’ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ нашСго хоста добаляСм Π½ΠΎΠ²Ρ‹ΠΉ location ΠΈ ΠΎΠ±Ρ‰ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ кСша:

...
    proxy_cache_path /www/myprojects/cache levels=1:2 keys_zone=image-preview:10m;
...
    server {
...
        location ~ ^/preview/([cir])/(.+) {
        # Π’ΠΈΠΏ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ
            set                         $oper $1;
        # ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ изобраТСния ΠΈ ΠΏΡƒΡ‚ΡŒ ΠΊ Ρ„Π°ΠΉΠ»Ρƒ
            set                         $remn $2;
        # ΠŸΡ€ΠΎΠΊΡΠΈΡ€ΡƒΠ΅ΠΌ Π½Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ хост
            proxy_pass                  http://myproject.ru:81/$oper/$remn;
            proxy_intercept_errors      on;
            error_page                  404 = /preview/404;
        # ΠšΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅
            proxy_cache                 image-preview;
            proxy_cache_key             "$host$document_uri";
        # 200 ΠΎΡ‚Π²Π΅Ρ‚Ρ‹ ΠΊΠ΅ΡˆΠΈΡ€ΡƒΠ΅ΠΌ Π½Π° 1 дСнь
            proxy_cache_valid           200 1d;
        # ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΡ‚Π²Π΅Ρ‚Ρ‹ ΠΊΠ΅ΡˆΠΈΡ€ΡƒΠ΅ΠΌ Π½Π° 1 ΠΌΠΈΠ½ΡƒΡ‚Ρƒ
            proxy_cache_valid           any 1m;
        }
        
        # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ ΠΎΡˆΠΈΠ±ΠΊΡƒ
        location = /preview/404 {
            internal;
            default_type                image/gif;
            alias                       /www/myprojects/image/noimage.gif;
        }
...
    }
...

Π’Π°ΠΊ ΠΆΠ΅ добаляСм Π½ΠΎΠ²Ρ‹ΠΉ хост Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³:

server {
    server_name                     myproject.ru;
    listen                          81;

    access_log                      /www/myproject.ru/logs/nginx.preview.access_log;
    error_log                       /www/myproject.ru/logs/nginx.preview.error_log info;

    # Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ сСкрСтноС слово для md5
    secure_link_secret              secret;

    # Ошибки отправляСм ΠΎΠ½Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ location
    error_page                      403 404 415 500 502 503 504 = @404;

    # location Для Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π° size
    location ~ ^/i/[^/]+/(.+) {
        
        # грязный Ρ…Π°ΠΊ ΠΎΡ‚ Π˜Π³ΠΎΡ€Ρ БысоСва *
        alias                       /www/myproject.ru/images/$1;
        try_files                   "" @404;
    
        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΡΡ‚ΡŒ ссылки ΠΈ md5
        if ($secure_link = "") { return 404; }
        
        # Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΠ²ΡƒΡŽΡ‰ΠΈΠΉ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€
        image_filter                size;
    }

    # По Π°Π½Π°Π»ΠΎΠ³ΠΈΠΈ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ location для Π΄Ρ€ΡƒΠ³ΠΈΡ… Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²
    location ~ ^/c/[^/]+/(d+|-)x(d+|-)/(.+) {
        set                         $width  $1;
        set                         $height $2;
        
        alias                       /www/myproject.ru/images/$3;
        try_files                   "" @404;
    
        if ($secure_link = "") { return 404; }
    
        image_filter                crop  $width  $height;
    }
    
    location ~ ^/r/[^/]+/(d+|-)x(d+|-)/(.+) {
        set                         $width  $1;
        set                         $height $2;

        alias                       /www/myproject.ru/images/$3;
        try_files                   "" @404;

        if ($secure_link = "") { return 404; }

        image_filter                resize  $width  $height;
    }

    location @404 { return 404; }
}

Π’ ΠΈΡ‚ΠΎΠ³Π΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ изобраТСния ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π±ΠΈΡ€Π°Ρ‚ΡŒ ΠΏΠΎ ссылкам:

* try_files β€” чувствитСлСн ΠΊ ΠΏΡ€ΠΎΠ±Π΅Π»Π°ΠΌ ΠΈ русским символам, поэтому ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΊΠΎΡΡ‚Ρ‹Π»ΡŒ с alias.

ИспользованиС Π² Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ

На ΡƒΡ€ΠΎΠ²Π½Π΅ Π²Π΅Π±-прилоТСния ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡ‰ΡƒΡŽ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ (Perl):

sub proxy_image {
    use Digest::MD5     qw /md5_hex/;
    my %params = @_;
    my $filter = {
                    size    => 'i',
                    resize  => 'r',
                    crop    => 'c'            
                  }->{$params{filter}} || 'r';
    my $path = ($filter ne 'i' ?
                    ( $params{height} || '_' ) . 'x' . ( $params{width} || '_' ) . '/' :
                    ()
               ) . $params{source};
    my $md5 = md5_hex( $path . 'secret' );
    $path = '/preview/' . $filter . '/' . $md5 . '/' . $path;
    return $path;
}

my $preview_path = &proxy_image(
                    source  => 'image1.jpg',
                    height  => 100,
                    width   => 100,
                    filter  => 'resize'
                );

Π₯отя я Π±Ρ‹ Π΅Ρ‰Π΅ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π» Ρ€Π°ΡΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ preview.

Π“Ρ€Π°Π±Π»ΠΈ

ΠŸΡ€ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΈ исходного изобраТСния, ΠΏΡ€Π΅Π²ΡŒΡŽ, СстСствСнно, удалятся ΠΈΠ· кСша Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΠΊΠ° кСш Π½Π΅ инвалидируСтся, Π° Π² нашСм случаС ΠΏΡ€Π΅Π²ΡŒΡŽ ΠΌΠΎΠ³ΡƒΡ‚ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π² Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ суток послС удалСния, Π½ΠΎ это максимум ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com