SlideShare uma empresa Scribd logo
1 de 33
Baixar para ler offline
ngx_small_lightで
動的サムネイル生成
                    Tatsuhiko Kubo
              cubicdaiya@gmail.com
      at 第2回 闇鍋プログラミング勉強会
自己紹介
•   久保 達彦 (bokko)

•   @cubicdaiya

•   インフラ兼ソフトウェアエンジニア@pixiv

◎主な担当分野
    ○ミドルウェアの開発・メンテ
    ○パフォーマンスチューニング
    ○アプリケーション開発・インフラもやるよ
周りがPHPやRuby書いてる中、黙々とC書いてます
ngx_small_light

• 画像サムネイル生成サーバ with Nginx
• サムネイルの生成パターンをURLで指定
• 画像の変換はImageMagickで行う
• mod_small_lightのNginx移植版
URLのパスを変えるだけで
              いろんなサムネイルを生成♪




 /tank.jpg   /small_light(p=medium)/tank.jpg /small_light(p=small)/tank.jpg

オリジナル                   Mサイズ                            Sサイズ
ngx_small_lightでできること

• 画像のリサイズ
• 枠の付加
• アイコン埋め込み
• フォーマット変換(例:PNG -> JPEG)
• etc
Nginx

• 高速・省メモリなHTTPサーバ
• イベント駆動
• Apacheと同様、拡張モジュールが作れる
• ただし、コンパイル時に組み込む必要有り
設定ファイル
server {
    listen 80;
    server_name localhost;

    # small_lightを有効にする
    small_light on;
    # 変換パターンを定義
    small_light_pattern_define medium dw=500,dh=500;
    small_light_pattern_define small dw=120,dh=120;

    location ~ small_light[^/]*/(.+)$ {
        set $file $1;
        rewrite ^ /$file;
    }
}
ngx_small_lightのディレクティブ


       small_light          ngx_small_lightのon/off


small_light_pattern_define 生成パターンに名前を付ける


 small_light_material_dir   合成素材用ディレクトリ
small_light



• ngx_small_lightのon/off(デフォルトはoff)
small_light on;
small_light_pattern_define


  • サムネイル生成パターンに名前を付ける
small_light_pattern_define medium dw=500,dh=500;


 以下の二つのURLは同じレスポンスを返す
http://localhost/small_light(dw=500,dh=500)/tank.jpg
http;//localhost/small_light(p=medium)/tank.jpg

  dw, dh:生成するサムネイルの幅と高さ
small_light_material_dir

      • 合成用素材ディレクトリ
small_light_material_dir /var/materials;



      • embedicon, ix, iyと組み合わせて使う
http://localhost/small_light(embedicon=icon.jpg,ix=0,iy=0)/tank.jpg



      •
     tank.jpgの座標(0, 0)に/var/materials/icon.jpgを埋め込む
主なパラメータ
   dw            生成するサムネイルの幅
   dh           生成するサムネイルの高さ
   cw              キャンバスの幅
   ch             キャンバスの高さ
   cc              キャンバスの色
   bw              ボーダー(枠)の幅
   bh             ボーダー(枠)の高さ
    q               画質(quality)
   of      生成するサムネイルのフォーマット(jpg,gif,png)
jpeghint        JPEG用最適化オプション
主なパラメータ
   dw             生成するサムネイルの幅
   dh            生成するサムネイルの高さ
   cw               キャンバスの幅
   ch              キャンバスの高さ
   cc               キャンバスの色
   bw               ボーダー(枠)の幅
   bh              ボーダー(枠)の高さ
    q                画質(quality)
   of       生成するサムネイルのフォーマット(jpg,gif,png)
jpeghint         JPEG用最適化オプション
           その他のパラメータについては
  http://p.tl/2sX9 (githubのWiki)を見てね♪
その他のプロダクト

• mod_small_light( by NHN Japan)
• mod_tofu( by クックパッド)
• Magickly
• Image Filter(Nginx標準モジュール)
その他のプロダクト

 • mod_small_light( by NHN Japan)
 • mod_tofu( by クックパッド)
 • Magickly
 • Image Filter(Nginx標準モジュール)
あれ?Nginxに同じことするモジュールある?
Image Filter
 Nginx標準モジュール
さっきと同じことをする設定ファイル(ImageFilter)

location ~ /resize/(medium|small)/([^/]*.jpg)$ {
    set $type $1;
    set $file $2;
    rewrite ^ /$file;
}
location ~ /[^/]*.jpg$ {
    if ($type = medium) {
        set $w 500;
        set $h 500;
    }
    if ($type = small) {
        set $w 120;
        set $h 120;
    }
    image_filter_jpeg_quality $q;
    image_filter resize $w $h;
}
ngx_small_lightの場合
server {
    listen 80;
    server_name localhost;

    # small_lightを有効にする
    small_light on;
    # 変換パターンを定義
    small_light_pattern_define medium dw=500,dh=500;
    small_light_pattern_define small dw=120,dh=120;

    location ~ small_light[^/]*/(.+)$ {
        set $file $1;
        rewrite ^ /$file;
    }
}

          こっちの方がシンプルですよね♪
Image Filterのイケてないところ


•   設定が複雑化しやすい

•   変換の種類(resize,crop)や画質をディレクティブで指定しな
    ければならない

•   名前付きパターンを実現しようとするとリクエストパラメー
    タの解析ロジックを設定ファイル内に埋め込む必要がある

•   設定ファイルではなくプログラムを書いてる気分
ngx_small_lightの設定がシンプルな理由




•   パラメータの解析をモジュール側でやってる

•   設定ファイル側は単にマッチしたパスをモジュール
    側に渡すだけ
その分の代償(パラメータのパーサ)
ngx_int_t ngx_http_small_light_parse_params(
    ngx_http_request_t *r,
    ngx_http_small_light_ctx_t *ctx,
    ngx_str_t *define_pattern,
    char *pv)
{
    char *tk, *tv, *sp1, *sp2;
    char *k, *kk, *v, *vv;
    ngx_str_t ks;
    char p[BUFSIZ];
    if (define_pattern->len > BUFSIZ - 1) {
        return NGX_ERROR;
    }
    ngx_cpystrn(p, define_pattern->data, define_pattern->len + 1);
    tk = strtok_r(p, ",", &sp1);
    while (tk != NULL) {
        tv = strtok_r(tk, "=", &sp2);
        k = tv;
        v = strtok_r(NULL, "=", &sp2);
        if (k == NULL || v == NULL) {
            return NGX_OK;
        }
        kk = ngx_palloc(r->pool, ngx_strlen(k) + 1);
        ngx_cpystrn(kk, k, ngx_strlen(k) + 1);
        ks.data = kk;
        ks.len = ngx_strlen(kk);
        if (ngx_strcmp(k, "p") == 0) {
            ngx_cpystrn(pv, v, ngx_strlen(v) + 1);
        } else {
            vv = ngx_palloc(r->pool, ngx_strlen(v) + 1);
            ngx_cpystrn(vv, v, ngx_strlen(v) + 1);
            ngx_hash_add_key(&ctx->params, &ks, vv, NGX_HASH_READONLY_KEY);
        }
        tk = strtok_r(NULL, ",", &sp1);
    }

    return NGX_OK;
}
ところで、
サムネイル生成サーバ作って
何かうれしいことあるのか?という話
画像をアップロードできるような
   Webサービスの場合



•   サムネイルは普通、アップロード時に生成される

•   各画像毎に何種類ものサムネイルが生成される
続・画像をアップロードできるような
    Webサービスの場合
続・画像をアップロードできるような
      Webサービスの場合


■新しい種類のサムネイルが突然必要になることがある
続・画像をアップロードできるような
      Webサービスの場合


■新しい種類のサムネイルが突然必要になることがある

 ●全画像毎に新規にサムネイル生成するとか無理(時間がかかりすぎる)
続・画像をアップロードできるような
      Webサービスの場合


■新しい種類のサムネイルが突然必要になることがある

 ●全画像毎に新規にサムネイル生成するとか無理(時間がかかりすぎる)

■希にしか参照されないサムネイルがある
続・画像をアップロードできるような
      Webサービスの場合


■新しい種類のサムネイルが突然必要になることがある

 ●全画像毎に新規にサムネイル生成するとか無理(時間がかかりすぎる)

■希にしか参照されないサムネイルがある
 ●画像ストレージの容量がもったいない
続・画像をアップロードできるような
      Webサービスの場合


■新しい種類のサムネイルが突然必要になることがある

 ●全画像毎に新規にサムネイル生成するとか無理(時間がかかりすぎる)

■希にしか参照されないサムネイルがある
 ●画像ストレージの容量がもったいない



        そこで動的生成ですよ!
ただ、サムネイルの生成処理自体はとても重いので
  前段でキャッシュするのがマナーです。
最後に

    • ngx_small_lightはgithubで公開中
https://github.com/cubicdaiya/ngx_small_light

    • バグレポート&パッチ ウェルカム!
ご静聴ありがとございました

Mais conteúdo relacionado

Mais procurados

CloudAtCostを使ってみた
CloudAtCostを使ってみたCloudAtCostを使ってみた
CloudAtCostを使ってみたnemumu
 
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)Yuuki Namikawa
 
約束なんていらないPromiseよりもasync/awaitだ!
約束なんていらないPromiseよりもasync/awaitだ!約束なんていらないPromiseよりもasync/awaitだ!
約束なんていらないPromiseよりもasync/awaitだ!kaz3391
 
国内レンタルサーバとAWSで負荷テストしてみました。
国内レンタルサーバとAWSで負荷テストしてみました。国内レンタルサーバとAWSで負荷テストしてみました。
国内レンタルサーバとAWSで負荷テストしてみました。株式会社雲屋ネットワーク
 
PHPで大規模ブラウザゲームを開発してわかったこと
PHPで大規模ブラウザゲームを開発してわかったことPHPで大規模ブラウザゲームを開発してわかったこと
PHPで大規模ブラウザゲームを開発してわかったことKentaro Matsui
 
第8回KPF発表資料
第8回KPF発表資料第8回KPF発表資料
第8回KPF発表資料cryks
 
Java EE勉強会 開発合宿 成果発表
Java EE勉強会 開発合宿 成果発表Java EE勉強会 開発合宿 成果発表
Java EE勉強会 開発合宿 成果発表Akihiro Harai
 
Rubyによるお手軽分散処理
Rubyによるお手軽分散処理Rubyによるお手軽分散処理
Rubyによるお手軽分散処理maebashi
 
20140828 #ssmjp 社内チューニンガソンで優勝したはなし
20140828 #ssmjp 社内チューニンガソンで優勝したはなし20140828 #ssmjp 社内チューニンガソンで優勝したはなし
20140828 #ssmjp 社内チューニンガソンで優勝したはなしMasahiro NAKAYAMA
 
サーバーサイドボトルネックの探し方
サーバーサイドボトルネックの探し方サーバーサイドボトルネックの探し方
サーバーサイドボトルネックの探し方Yugo Shimizu
 
ストリーム処理エンジン「Zero」の開発と運用
ストリーム処理エンジン「Zero」の開発と運用ストリーム処理エンジン「Zero」の開発と運用
ストリーム処理エンジン「Zero」の開発と運用Eiichi Sato
 
GPUをJavaで使う話(Java Casual Talks #1)
GPUをJavaで使う話(Java Casual Talks #1)GPUをJavaで使う話(Java Casual Talks #1)
GPUをJavaで使う話(Java Casual Talks #1)なおき きしだ
 
Fission で 始める Containerless Kubernetes #serverlesstokyo
Fission で 始める Containerless Kubernetes #serverlesstokyoFission で 始める Containerless Kubernetes #serverlesstokyo
Fission で 始める Containerless Kubernetes #serverlesstokyoy_taka_23
 
60分でつかった気になるMicrosoft Azure
60分でつかった気になるMicrosoft Azure 60分でつかった気になるMicrosoft Azure
60分でつかった気になるMicrosoft Azure Kazumi Hirose
 
pixivのインフラを支える技術
pixivのインフラを支える技術pixivのインフラを支える技術
pixivのインフラを支える技術Ryuta Kamizono
 
Html5勉強会資料 2012821
Html5勉強会資料 2012821Html5勉強会資料 2012821
Html5勉強会資料 2012821Cohei Aoki
 

Mais procurados (20)

CloudAtCostを使ってみた
CloudAtCostを使ってみたCloudAtCostを使ってみた
CloudAtCostを使ってみた
 
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)
 
約束なんていらないPromiseよりもasync/awaitだ!
約束なんていらないPromiseよりもasync/awaitだ!約束なんていらないPromiseよりもasync/awaitだ!
約束なんていらないPromiseよりもasync/awaitだ!
 
国内レンタルサーバとAWSで負荷テストしてみました。
国内レンタルサーバとAWSで負荷テストしてみました。国内レンタルサーバとAWSで負荷テストしてみました。
国内レンタルサーバとAWSで負荷テストしてみました。
 
Scala on Hadoop
Scala on HadoopScala on Hadoop
Scala on Hadoop
 
PHPで大規模ブラウザゲームを開発してわかったこと
PHPで大規模ブラウザゲームを開発してわかったことPHPで大規模ブラウザゲームを開発してわかったこと
PHPで大規模ブラウザゲームを開発してわかったこと
 
第8回KPF発表資料
第8回KPF発表資料第8回KPF発表資料
第8回KPF発表資料
 
Java EE勉強会 開発合宿 成果発表
Java EE勉強会 開発合宿 成果発表Java EE勉強会 開発合宿 成果発表
Java EE勉強会 開発合宿 成果発表
 
Rubyによるお手軽分散処理
Rubyによるお手軽分散処理Rubyによるお手軽分散処理
Rubyによるお手軽分散処理
 
ゼロから始めるBlob
ゼロから始めるBlobゼロから始めるBlob
ゼロから始めるBlob
 
20140828 #ssmjp 社内チューニンガソンで優勝したはなし
20140828 #ssmjp 社内チューニンガソンで優勝したはなし20140828 #ssmjp 社内チューニンガソンで優勝したはなし
20140828 #ssmjp 社内チューニンガソンで優勝したはなし
 
サーバーサイドボトルネックの探し方
サーバーサイドボトルネックの探し方サーバーサイドボトルネックの探し方
サーバーサイドボトルネックの探し方
 
ストリーム処理エンジン「Zero」の開発と運用
ストリーム処理エンジン「Zero」の開発と運用ストリーム処理エンジン「Zero」の開発と運用
ストリーム処理エンジン「Zero」の開発と運用
 
GPUをJavaで使う話(Java Casual Talks #1)
GPUをJavaで使う話(Java Casual Talks #1)GPUをJavaで使う話(Java Casual Talks #1)
GPUをJavaで使う話(Java Casual Talks #1)
 
Windows Azure Community Open Day 2012
Windows Azure   Community Open Day 2012Windows Azure   Community Open Day 2012
Windows Azure Community Open Day 2012
 
Microsoft azure
Microsoft azureMicrosoft azure
Microsoft azure
 
Fission で 始める Containerless Kubernetes #serverlesstokyo
Fission で 始める Containerless Kubernetes #serverlesstokyoFission で 始める Containerless Kubernetes #serverlesstokyo
Fission で 始める Containerless Kubernetes #serverlesstokyo
 
60分でつかった気になるMicrosoft Azure
60分でつかった気になるMicrosoft Azure 60分でつかった気になるMicrosoft Azure
60分でつかった気になるMicrosoft Azure
 
pixivのインフラを支える技術
pixivのインフラを支える技術pixivのインフラを支える技術
pixivのインフラを支える技術
 
Html5勉強会資料 2012821
Html5勉強会資料 2012821Html5勉強会資料 2012821
Html5勉強会資料 2012821
 

Semelhante a ngx_small_light at 第2回闇鍋プログラミング勉強会

ピクサー USD 入門 新たなコンテンツパイプラインを構築する
ピクサー USD 入門 新たなコンテンツパイプラインを構築するピクサー USD 入門 新たなコンテンツパイプラインを構築する
ピクサー USD 入門 新たなコンテンツパイプラインを構築するTakahito Tejima
 
恋に落ちるデプロイツール
恋に落ちるデプロイツール恋に落ちるデプロイツール
恋に落ちるデプロイツールtotty jp
 
php5-gd で画像を弄る話
php5-gd で画像を弄る話php5-gd で画像を弄る話
php5-gd で画像を弄る話Yo Ya
 
PythonによるDeep Learningの実装
PythonによるDeep Learningの実装PythonによるDeep Learningの実装
PythonによるDeep Learningの実装Shinya Akiba
 
月間10億pvを支えるmongo db
月間10億pvを支えるmongo db月間10億pvを支えるmongo db
月間10億pvを支えるmongo dbYuji Isobe
 
Native x Webでいいとこどり開発 ~ピグトーク~
Native x Webでいいとこどり開発 ~ピグトーク~Native x Webでいいとこどり開発 ~ピグトーク~
Native x Webでいいとこどり開発 ~ピグトーク~Kazunari Hara
 
Play framework 2.0のおすすめと1.2からのアップグレード
Play framework 2.0のおすすめと1.2からのアップグレードPlay framework 2.0のおすすめと1.2からのアップグレード
Play framework 2.0のおすすめと1.2からのアップグレードKazuhiro Hara
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platformToru Yamaguchi
 
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~Sotaro Kimura
 
はじめての人のためのDeep Learning
はじめての人のためのDeep Learningはじめての人のためのDeep Learning
はじめての人のためのDeep LearningTadaichiro Nakano
 
20170127 JAWS HPC-UG#8
20170127 JAWS HPC-UG#820170127 JAWS HPC-UG#8
20170127 JAWS HPC-UG#8Kohei KaiGai
 
⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2Nishida Kansuke
 
How to use animation packages in R(Japanese)
How to use animation packages in R(Japanese)How to use animation packages in R(Japanese)
How to use animation packages in R(Japanese)sleipnir002
 
Azure IoT Edge で Custom Vision
Azure IoT Edge で Custom VisionAzure IoT Edge で Custom Vision
Azure IoT Edge で Custom VisionYoshitaka Seo
 
Code iq×japanr 公開用
Code iq×japanr 公開用Code iq×japanr 公開用
Code iq×japanr 公開用Nobuaki Oshiro
 
Ruby で高速なプログラムを書く
Ruby で高速なプログラムを書くRuby で高速なプログラムを書く
Ruby で高速なプログラムを書くmametter
 
Pycon2014 django performance
Pycon2014 django performancePycon2014 django performance
Pycon2014 django performancehirokiky
 
Sohu邮箱的python经验
Sohu邮箱的python经验Sohu邮箱的python经验
Sohu邮箱的python经验Ryan Poy
 
いまさら聞けないNGINXコンフィグ_F5-NGINX-Community-20200805
いまさら聞けないNGINXコンフィグ_F5-NGINX-Community-20200805いまさら聞けないNGINXコンフィグ_F5-NGINX-Community-20200805
いまさら聞けないNGINXコンフィグ_F5-NGINX-Community-20200805shinyatsukasaki
 

Semelhante a ngx_small_light at 第2回闇鍋プログラミング勉強会 (20)

ピクサー USD 入門 新たなコンテンツパイプラインを構築する
ピクサー USD 入門 新たなコンテンツパイプラインを構築するピクサー USD 入門 新たなコンテンツパイプラインを構築する
ピクサー USD 入門 新たなコンテンツパイプラインを構築する
 
Linqで画像処理
Linqで画像処理Linqで画像処理
Linqで画像処理
 
恋に落ちるデプロイツール
恋に落ちるデプロイツール恋に落ちるデプロイツール
恋に落ちるデプロイツール
 
php5-gd で画像を弄る話
php5-gd で画像を弄る話php5-gd で画像を弄る話
php5-gd で画像を弄る話
 
PythonによるDeep Learningの実装
PythonによるDeep Learningの実装PythonによるDeep Learningの実装
PythonによるDeep Learningの実装
 
月間10億pvを支えるmongo db
月間10億pvを支えるmongo db月間10億pvを支えるmongo db
月間10億pvを支えるmongo db
 
Native x Webでいいとこどり開発 ~ピグトーク~
Native x Webでいいとこどり開発 ~ピグトーク~Native x Webでいいとこどり開発 ~ピグトーク~
Native x Webでいいとこどり開発 ~ピグトーク~
 
Play framework 2.0のおすすめと1.2からのアップグレード
Play framework 2.0のおすすめと1.2からのアップグレードPlay framework 2.0のおすすめと1.2からのアップグレード
Play framework 2.0のおすすめと1.2からのアップグレード
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platform
 
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
 
はじめての人のためのDeep Learning
はじめての人のためのDeep Learningはじめての人のためのDeep Learning
はじめての人のためのDeep Learning
 
20170127 JAWS HPC-UG#8
20170127 JAWS HPC-UG#820170127 JAWS HPC-UG#8
20170127 JAWS HPC-UG#8
 
⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2
 
How to use animation packages in R(Japanese)
How to use animation packages in R(Japanese)How to use animation packages in R(Japanese)
How to use animation packages in R(Japanese)
 
Azure IoT Edge で Custom Vision
Azure IoT Edge で Custom VisionAzure IoT Edge で Custom Vision
Azure IoT Edge で Custom Vision
 
Code iq×japanr 公開用
Code iq×japanr 公開用Code iq×japanr 公開用
Code iq×japanr 公開用
 
Ruby で高速なプログラムを書く
Ruby で高速なプログラムを書くRuby で高速なプログラムを書く
Ruby で高速なプログラムを書く
 
Pycon2014 django performance
Pycon2014 django performancePycon2014 django performance
Pycon2014 django performance
 
Sohu邮箱的python经验
Sohu邮箱的python经验Sohu邮箱的python经验
Sohu邮箱的python经验
 
いまさら聞けないNGINXコンフィグ_F5-NGINX-Community-20200805
いまさら聞けないNGINXコンフィグ_F5-NGINX-Community-20200805いまさら聞けないNGINXコンフィグ_F5-NGINX-Community-20200805
いまさら聞けないNGINXコンフィグ_F5-NGINX-Community-20200805
 

Mais de Tatsuhiko Kubo

mruby_nginx_module at pyfes 2013.11
mruby_nginx_module at pyfes 2013.11mruby_nginx_module at pyfes 2013.11
mruby_nginx_module at pyfes 2013.11Tatsuhiko Kubo
 
mruby_nginx_module〜Embedded mruby into Nginx〜
mruby_nginx_module〜Embedded mruby into Nginx〜mruby_nginx_module〜Embedded mruby into Nginx〜
mruby_nginx_module〜Embedded mruby into Nginx〜Tatsuhiko Kubo
 
memcached proxy server development and operation
memcached proxy server development and operationmemcached proxy server development and operation
memcached proxy server development and operationTatsuhiko Kubo
 
Inside pixiv's infrastructure〜application cluster side〜
Inside pixiv's infrastructure〜application cluster side〜Inside pixiv's infrastructure〜application cluster side〜
Inside pixiv's infrastructure〜application cluster side〜Tatsuhiko Kubo
 
memcachedからKyotoTycoonへ
memcachedからKyotoTycoonへmemcachedからKyotoTycoonへ
memcachedからKyotoTycoonへTatsuhiko Kubo
 
dtl - diff template library
dtl - diff template librarydtl - diff template library
dtl - diff template libraryTatsuhiko Kubo
 
pixivの画像アップロードシステム
pixivの画像アップロードシステムpixivの画像アップロードシステム
pixivの画像アップロードシステムTatsuhiko Kubo
 

Mais de Tatsuhiko Kubo (14)

mruby_nginx_module at pyfes 2013.11
mruby_nginx_module at pyfes 2013.11mruby_nginx_module at pyfes 2013.11
mruby_nginx_module at pyfes 2013.11
 
mruby_nginx_module
mruby_nginx_modulemruby_nginx_module
mruby_nginx_module
 
mruby_nginx_module〜Embedded mruby into Nginx〜
mruby_nginx_module〜Embedded mruby into Nginx〜mruby_nginx_module〜Embedded mruby into Nginx〜
mruby_nginx_module〜Embedded mruby into Nginx〜
 
memcached proxy server development and operation
memcached proxy server development and operationmemcached proxy server development and operation
memcached proxy server development and operation
 
Inside pixiv's infrastructure〜application cluster side〜
Inside pixiv's infrastructure〜application cluster side〜Inside pixiv's infrastructure〜application cluster side〜
Inside pixiv's infrastructure〜application cluster side〜
 
ngx_small_light
ngx_small_lightngx_small_light
ngx_small_light
 
pixiv thumbnails
pixiv thumbnailspixiv thumbnails
pixiv thumbnails
 
ngx_small_light
ngx_small_lightngx_small_light
ngx_small_light
 
memcachedからKyotoTycoonへ
memcachedからKyotoTycoonへmemcachedからKyotoTycoonへ
memcachedからKyotoTycoonへ
 
dtl - diff template library
dtl - diff template librarydtl - diff template library
dtl - diff template library
 
pixivの画像アップロードシステム
pixivの画像アップロードシステムpixivの画像アップロードシステム
pixivの画像アップロードシステム
 
Memorypool Key
Memorypool KeyMemorypool Key
Memorypool Key
 
String Match Algrithm
String Match AlgrithmString Match Algrithm
String Match Algrithm
 
Diff
DiffDiff
Diff
 

Último

TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 

Último (8)

TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 

ngx_small_light at 第2回闇鍋プログラミング勉強会

  • 1. ngx_small_lightで 動的サムネイル生成 Tatsuhiko Kubo cubicdaiya@gmail.com at 第2回 闇鍋プログラミング勉強会
  • 2. 自己紹介 • 久保 達彦 (bokko) • @cubicdaiya • インフラ兼ソフトウェアエンジニア@pixiv ◎主な担当分野 ○ミドルウェアの開発・メンテ ○パフォーマンスチューニング ○アプリケーション開発・インフラもやるよ 周りがPHPやRuby書いてる中、黙々とC書いてます
  • 3. ngx_small_light • 画像サムネイル生成サーバ with Nginx • サムネイルの生成パターンをURLで指定 • 画像の変換はImageMagickで行う • mod_small_lightのNginx移植版
  • 4. URLのパスを変えるだけで いろんなサムネイルを生成♪ /tank.jpg /small_light(p=medium)/tank.jpg /small_light(p=small)/tank.jpg オリジナル Mサイズ Sサイズ
  • 5. ngx_small_lightでできること • 画像のリサイズ • 枠の付加 • アイコン埋め込み • フォーマット変換(例:PNG -> JPEG) • etc
  • 6. Nginx • 高速・省メモリなHTTPサーバ • イベント駆動 • Apacheと同様、拡張モジュールが作れる • ただし、コンパイル時に組み込む必要有り
  • 7. 設定ファイル server { listen 80; server_name localhost; # small_lightを有効にする small_light on; # 変換パターンを定義 small_light_pattern_define medium dw=500,dh=500; small_light_pattern_define small dw=120,dh=120; location ~ small_light[^/]*/(.+)$ { set $file $1; rewrite ^ /$file; } }
  • 8. ngx_small_lightのディレクティブ small_light ngx_small_lightのon/off small_light_pattern_define 生成パターンに名前を付ける small_light_material_dir 合成素材用ディレクトリ
  • 10. small_light_pattern_define • サムネイル生成パターンに名前を付ける small_light_pattern_define medium dw=500,dh=500; 以下の二つのURLは同じレスポンスを返す http://localhost/small_light(dw=500,dh=500)/tank.jpg http;//localhost/small_light(p=medium)/tank.jpg dw, dh:生成するサムネイルの幅と高さ
  • 11. small_light_material_dir • 合成用素材ディレクトリ small_light_material_dir /var/materials; • embedicon, ix, iyと組み合わせて使う http://localhost/small_light(embedicon=icon.jpg,ix=0,iy=0)/tank.jpg • tank.jpgの座標(0, 0)に/var/materials/icon.jpgを埋め込む
  • 12. 主なパラメータ dw 生成するサムネイルの幅 dh 生成するサムネイルの高さ cw キャンバスの幅 ch キャンバスの高さ cc キャンバスの色 bw ボーダー(枠)の幅 bh ボーダー(枠)の高さ q 画質(quality) of 生成するサムネイルのフォーマット(jpg,gif,png) jpeghint JPEG用最適化オプション
  • 13. 主なパラメータ dw 生成するサムネイルの幅 dh 生成するサムネイルの高さ cw キャンバスの幅 ch キャンバスの高さ cc キャンバスの色 bw ボーダー(枠)の幅 bh ボーダー(枠)の高さ q 画質(quality) of 生成するサムネイルのフォーマット(jpg,gif,png) jpeghint JPEG用最適化オプション その他のパラメータについては http://p.tl/2sX9 (githubのWiki)を見てね♪
  • 14. その他のプロダクト • mod_small_light( by NHN Japan) • mod_tofu( by クックパッド) • Magickly • Image Filter(Nginx標準モジュール)
  • 15. その他のプロダクト • mod_small_light( by NHN Japan) • mod_tofu( by クックパッド) • Magickly • Image Filter(Nginx標準モジュール) あれ?Nginxに同じことするモジュールある?
  • 17. さっきと同じことをする設定ファイル(ImageFilter) location ~ /resize/(medium|small)/([^/]*.jpg)$ { set $type $1; set $file $2; rewrite ^ /$file; } location ~ /[^/]*.jpg$ { if ($type = medium) { set $w 500; set $h 500; } if ($type = small) { set $w 120; set $h 120; } image_filter_jpeg_quality $q; image_filter resize $w $h; }
  • 18. ngx_small_lightの場合 server { listen 80; server_name localhost; # small_lightを有効にする small_light on; # 変換パターンを定義 small_light_pattern_define medium dw=500,dh=500; small_light_pattern_define small dw=120,dh=120; location ~ small_light[^/]*/(.+)$ { set $file $1; rewrite ^ /$file; } } こっちの方がシンプルですよね♪
  • 19. Image Filterのイケてないところ • 設定が複雑化しやすい • 変換の種類(resize,crop)や画質をディレクティブで指定しな ければならない • 名前付きパターンを実現しようとするとリクエストパラメー タの解析ロジックを設定ファイル内に埋め込む必要がある • 設定ファイルではなくプログラムを書いてる気分
  • 20. ngx_small_lightの設定がシンプルな理由 • パラメータの解析をモジュール側でやってる • 設定ファイル側は単にマッチしたパスをモジュール 側に渡すだけ
  • 21. その分の代償(パラメータのパーサ) ngx_int_t ngx_http_small_light_parse_params( ngx_http_request_t *r, ngx_http_small_light_ctx_t *ctx, ngx_str_t *define_pattern, char *pv) {     char *tk, *tv, *sp1, *sp2;     char *k, *kk, *v, *vv;     ngx_str_t ks;     char p[BUFSIZ];     if (define_pattern->len > BUFSIZ - 1) {         return NGX_ERROR;     }     ngx_cpystrn(p, define_pattern->data, define_pattern->len + 1);     tk = strtok_r(p, ",", &sp1);     while (tk != NULL) {         tv = strtok_r(tk, "=", &sp2);         k = tv;         v = strtok_r(NULL, "=", &sp2);         if (k == NULL || v == NULL) {             return NGX_OK;         }         kk = ngx_palloc(r->pool, ngx_strlen(k) + 1);         ngx_cpystrn(kk, k, ngx_strlen(k) + 1);         ks.data = kk;         ks.len = ngx_strlen(kk);         if (ngx_strcmp(k, "p") == 0) {             ngx_cpystrn(pv, v, ngx_strlen(v) + 1);         } else {             vv = ngx_palloc(r->pool, ngx_strlen(v) + 1);             ngx_cpystrn(vv, v, ngx_strlen(v) + 1);             ngx_hash_add_key(&ctx->params, &ks, vv, NGX_HASH_READONLY_KEY);         }         tk = strtok_r(NULL, ",", &sp1);     }     return NGX_OK; }
  • 24. 画像をアップロードできるような Webサービスの場合 • サムネイルは普通、アップロード時に生成される • 各画像毎に何種類ものサムネイルが生成される
  • 26. 続・画像をアップロードできるような Webサービスの場合 ■新しい種類のサムネイルが突然必要になることがある
  • 27. 続・画像をアップロードできるような Webサービスの場合 ■新しい種類のサムネイルが突然必要になることがある ●全画像毎に新規にサムネイル生成するとか無理(時間がかかりすぎる)
  • 28. 続・画像をアップロードできるような Webサービスの場合 ■新しい種類のサムネイルが突然必要になることがある ●全画像毎に新規にサムネイル生成するとか無理(時間がかかりすぎる) ■希にしか参照されないサムネイルがある
  • 29. 続・画像をアップロードできるような Webサービスの場合 ■新しい種類のサムネイルが突然必要になることがある ●全画像毎に新規にサムネイル生成するとか無理(時間がかかりすぎる) ■希にしか参照されないサムネイルがある ●画像ストレージの容量がもったいない
  • 30. 続・画像をアップロードできるような Webサービスの場合 ■新しい種類のサムネイルが突然必要になることがある ●全画像毎に新規にサムネイル生成するとか無理(時間がかかりすぎる) ■希にしか参照されないサムネイルがある ●画像ストレージの容量がもったいない そこで動的生成ですよ!
  • 32. 最後に • ngx_small_lightはgithubで公開中 https://github.com/cubicdaiya/ngx_small_light • バグレポート&パッチ ウェルカム!