2016-11-02 20 views
4

Amazon S3でホストされている大きなダウンロードファイル(5 GB以上のものもあります)があります。私のメインサーバーはNginxです。 Amazon S3には公開アクセス権がありません。ファイルは署名されたURLで提供されます。Amazon S3を使用してNginxで帯域幅を制限する

Amazon S3を使用する際に帯域幅を制限する方法はありますか? Amazon S3にはオプションはありませんが、Nginxをプロキシとして使用してそこから作ることはできますか?

私はそのリンクからの例を使用しようとしています:

https://coderwall.com/p/rlguog/nginx-as-proxy-for-amazon-s3-public-private-files

このコードブロック:

location ~* ^/proxy_private_file/(.*) { 
    set $s3_bucket  'your_bucket.s3.amazonaws.com'; 
    set $aws_access_key 'AWSAccessKeyId=YOUR_ONLY_ACCESS_KEY'; 
    set $url_expires  'Expires=$arg_e'; 
    set $url_signature 'Signature=$arg_st'; 
    set $url_full   '$1$aws_access_key&$url_expires&$url_signature'; 

    proxy_http_version  1.1; 
    proxy_set_header  Host $s3_bucket; 
    proxy_set_header  Authorization ''; 
    proxy_hide_header  x-amz-id-2; 
    proxy_hide_header  x-amz-request-id; 
    proxy_hide_header  Set-Cookie; 
    proxy_ignore_headers "Set-Cookie"; 
    proxy_buffering  off; 
    proxy_intercept_errors on; 

    resolver    172.16.0.23 valid=300s; 
    resolver_timeout  10s; 

    proxy_pass    http://$s3_bucket$url_full; 

}

を何私は理解していないことはどのようにすることができていますPHPから作成した署名付きURLをそのNginx Configに渡しますか?だから、私はプロキシとして署名されたURLに行くようにNginxに伝えることができます。

+0

それ* - HTTP([ 'proxy_limit_rate']で://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_limit_rate)、おそらく?それは本当に "帯域幅"を制限したいのですか、それともクライアントごとに1秒あたりの要求ですか? –

+0

私の問題は、私はAmazon S3用の署名付きURLを作成するためのプラグインを使用しています。このプラグインは、PHPのようなものを使用して、Signed URLにユーザをリダイレクトします:** header( 'Location:'。$ signedURL); ** Nginxはこのシナリオでどこに置くことができますか? – user1002601

+0

@ Michael-sqlbot私はサーバーにはあまりよくないので、私に同行してください。ユーザーリクエスト** example.com/files/file1.txt ** PHPは、署名されたURLを生成します。 ** amazon/bucket/file1.txt **と同様に、PHPのヘッダーを提供しました。私は** amazon/bucket/file.txt ** URLをNginx confに入れてプロキシリクエストを行う必要があります。どうやってやるの? – user1002601

答えて

0

解決策が見つかりました。ここにあります:

最初にhttpブロックをあなたのnginx設定で開きます。 IPごとの接続を制限するために必要なゾーンを作成します。

limit_conn_zone $binary_remote_addr zone=addr:10m; 

は今またはどこでもそれを定義し/etc/nginx/conf.d/sitename.conf であなたのサーバブロックを開きます。内部の場所を作成します。私たちは、ここでPHPリクエストをリダイレクトします:

location ~* ^/internal_redirect/(.*?)/(.*) { 
# Do not allow people to mess with this location directly 
# Only internal redirects are allowed 
internal; 

# Location-specific logging, so we can clearly see which requests 
# passing through proxy and what is happening there 
access_log /var/log/nginx/internal_redirect.access.log main; 
error_log /var/log/nginx/internal_redirect.error.log warn; 

# Extract download url from the request 
set $download_uri $2; 
set $download_host $1; 

# Extract the arguments from request. 
# That is the Signed URL part that you require to get the file from S3 servers 
if ($download_uri ~* "([^/]*$)") { 
    set $filename $1; 
} 

# Compose download url 
set $download_url $download_host/$download_uri?$args; 

# Set download request headers 
proxy_http_version  1.1; 
proxy_set_header  Connection ""; 
proxy_hide_header  x-amz-id-2; 
proxy_hide_header  x-amz-request-id; 
proxy_hide_header  Set-Cookie; 
proxy_ignore_headers "Set-Cookie"; 

# Activate the proxy buffering, without it limiting bandwidth speed in proxy will not work! 
proxy_buffering on; 

# Buffer 512 KB data 
proxy_buffers 32 16k; 

proxy_intercept_errors on; 
resolver  8.8.8.8 valid=300s; 
resolver_timeout  10s; 

# The next two lines could be used if your storage 
# backend does not support Content-Disposition 
# headers used to specify file name browsers use 
# when save content to the disk 
proxy_hide_header Content-Disposition; 
add_header Content-Disposition 'attachment; filename="$filename"'; 

# Do not touch local disks when proxying 
# content to clients 
proxy_max_temp_file_size 0; 

# Limit the connection to one per IP address 
limit_conn addr 1; 

# Limit the bandwidth to 300 kilobytes 
proxy_limit_rate 300k; 

# Set logging level to info so we can see everything. 
# All levels you can set: info | notice | warn | error 
limit_conn_log_level info; 

# Finally download the file and send it to client 
# Beware that you can shouldn't include "htttp://" or "https://" 
# in proxy. Doing that will cause an "invalid port in upstream" error. 
proxy_pass $download_url; 
} 

PHPで最後の仕上げを作成し、nginxのにあなたの署名URLを送信:*実行可能なようです

header('X-Accel-Redirect: ' . '/internal_redirect/' . $YOUR_SIGNED_URL); 
関連する問題