Nginxで構築するキャッシュプロキシサーバ

Nginxを使えば簡単にプロキシサーバを構築することができます。手元で動かせるサンプルコードをGithubで公開しています。git cloneしてご利用ください。PCにDockerがインストールされていれば簡単に動作環境を構築することができます。

https://github.com/shoyan/nginx-proxy-cache

キャッシュを有効にする

Nginxのキャッシュ機能はデフォルトでは有効ではないので、設定する必要があります。

/etc/nginx/nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
user  nginx;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;


events {
worker_connections 1024;
}


http {
# キャッシュの場所を指定する
# levels: キャッシュの階層レベル
# keys_zone: 使用する共有メモリゾーンの名前とサイズ
proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=my-key:10m;
proxy_temp_path /var/cache/nginx/tmp;

include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

include /etc/nginx/conf.d/*.conf;
}

次にlocationディレクティブでキャッシュを有効にします。

/etc/nginx/conf.d/default.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
server {
listen 80;
server_name localhost;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

location / {
# 8081のポートで起動しているサーバにプロキシする
proxy_pass http://app:8081/;
# 全てのアクセスをキャッシュする
proxy_ignore_headers Cache-Control;
# my-keyというキー名でキャッシュを登録
proxy_cache my-key;
# キャッシュは1分間有効にする
proxy_cache_valid any 1m;
# レスポンスヘッダにキャッシュがヒットしたかどうかを付与する
add_header X-Nginx-Cache $upstream_cache_status;
}
}

以上の設定を行えばキャッシュが有効になります。

キャッシュの詳細な設定についてはNginxのドキュメントを参照ください。
ngx_http_proxy_module

アプリサーバはNode.jsで構築しています。1秒でHello Worldを返す単純なアプリサーバです。こちらもDockerで動作するのでNode.jsをPCにインストールする必要はありません。

プロキシサーバとアプリサーバの起動は次のコマンドで行います。

1
2
3
4
5
6
7
$ docker-compose up
Starting proxycachesample_app_1 ...
Starting proxycachesample_app_1 ... done
Starting proxycachesample_proxy_1 ...
Starting proxycachesample_proxy_1 ... done
Attaching to proxycachesample_app_1, proxycachesample_proxy_1
app_1 | Server running at http://localhost:8081/

1回目のアクセスはリクエストがアプリサーバまで行くのでレスポンスタイムは1秒程度かかります。

1
2
3
$ curl http://localhost:8080 -w "%{time_total}"
Hello World
1.009103

2回目からのアクセスはプロキシサーバがキャッシュしているため、レスポンスタイムが速くなります。

1
2
3
$ curl http://localhost:8080  -w "%{time_total}"
Hello World
0.003797

確認が終わったらサーバを停止しておきましょう。サーバの停止はCtrl+Cか次のコマンドで行えます。

1
$ docker-compose stop

エンジニアが意識しておくべきこと

私たちのような物作りに関わるエンジニアが意識しておかないといけないものは成果物(アウトプット)です。成果物とは最終的にユーザーから見えるものです。例えば、Webアプリケーションであれば最終的に画面に出力されるWebページです。

私たちエンジニアは、今やっている作業が成果物に繋がるのかを理解する必要があります。

IT系のエンジニアで多いのはコードの書き方や実装の細部にこだわってしまうことです。そこにこだわってしまうと時間を使い過ぎてしまいます。その結果、私たちが最終的に作っている成果物(ユーザーから見える画面)がおそろかになってしまいます。

コードの書き方や実装の細部を高めることは私たちが目指すゴールではありません。私たちが目指すゴールとは成果物を作り、ユーザーに届けることです。

Gradleのjavaプラグインとは

build.gradleでよく見かけるapply plugin: ‘java'という記述について説明します。この記述をするとgradleにjavaプラグインが追加されます。プラグインはgradleの機能を拡張するためのもので、javaプラグインを追加するとjavaに関連するタスクが使えるようになります。

何もプラグインを追加していないgradleタスクは以下の通りです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$ gradle tasks

> Task :tasks

------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------

Build Setup tasks
-----------------
init - Initializes a new Gradle build.
wrapper - Generates Gradle wrapper files.

Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'gs-gradle'.
components - Displays the components produced by root project 'gs-gradle'. [incubating]
dependencies - Displays all dependencies declared in root project 'gs-gradle'.
dependencyInsight - Displays the insight into a specific dependency in root project 'gs-gradle'.
dependentComponents - Displays the dependent components of components in root project 'gs-gradle'. [incubating]
help - Displays a help message.
model - Displays the configuration model of root project 'gs-gradle'. [incubating]
projects - Displays the sub-projects of root project 'gs-gradle'.
properties - Displays the properties of root project 'gs-gradle'.
tasks - Displays the tasks runnable from root project 'gs-gradle'.

To see all tasks and more detail, run gradle tasks --all

To see more detail about a task, run gradle help --task <task>


BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

Javaプラグインを定義したあとのタスクは以下の通りです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
$ gradle tasks
Starting a Gradle Daemon (subsequent builds will be faster)

> Task :tasks

------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles main classes.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles test classes.

Build Setup tasks
-----------------
init - Initializes a new Gradle build.
wrapper - Generates Gradle wrapper files.

Documentation tasks
-------------------
javadoc - Generates Javadoc API documentation for the main source code.

Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'gs-gradle'.
components - Displays the components produced by root project 'gs-gradle'. [incubating]
dependencies - Displays all dependencies declared in root project 'gs-gradle'.
dependencyInsight - Displays the insight into a specific dependency in root project 'gs-gradle'.
dependentComponents - Displays the dependent components of components in root project 'gs-gradle'. [incubating] help - Displays a help message.
model - Displays the configuration model of root project 'gs-gradle'. [incubating]
projects - Displays the sub-projects of root project 'gs-gradle'.
properties - Displays the properties of root project 'gs-gradle'.
tasks - Displays the tasks runnable from root project 'gs-gradle'.

Verification tasks
------------------
check - Runs all checks.
test - Runs the unit tests.

Rules
-----
Pattern: clean<TaskName>: Cleans the output files of a task.
Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.

To see all tasks and more detail, run gradle tasks --all

To see more detail about a task, run gradle help --task <task>


BUILD SUCCESSFUL in 5s
1 actionable task: 1 executed

Build tasks、Documentation tasks、Verification tasksが追加されています。

IntelliJでSpringBootのアプリケーションを作成する

SpringBootのアプリケーションを作成する方法はいくつかありますが、今回はIntelliJで作成する方法を紹介します。

IntellJを起動してメニューバーから File > New > Project...を選択します。

左メニューよりSpring Initializrを選択してNextを押します。

weather-nitify-slack

Project MetaDataはアプリケーションごとに書き換えますが、今回はデモなのでデフォルトのままです。
Gradleを使うのでTypeをGradle Project を選択してNextを押します。

weather-nitify-slack

Dependenciesでは使いたいライブラリを選択できます。
今回は特に選択せず、Nextを押します。

weather-nitify-slack

Project nameはdemoで作成します。
Project locationでファイルを作成する場所を指定します。

weather-nitify-slack

Finishを押すとSpring Bootのアプリケーションが作成されます。
作成したファイルをGitHubにアップロードしています。

https://github.com/shoyan/spring-boot-demo

わかりやすいスライドを誰でも作れるようになる方法

こんにちは、SHOYANです。この記事はプレゼン研究会 Advent Calendar 2017の21日目の投稿です。

わかりやすいスライドを誰でも作れるようになる方法

本記事ではプレゼンを観る人に理解しやすいスライドを作る方法を紹介します。その方法はとても簡単です。スライドはモバイル端末で作成する。たったこれだけです。モバイル端末で作成することで誰でも文字が少ない簡潔なスライドが作成できるようになります。

文字が多いスライドは聴衆の観る気を無くさせる

文字数が少なくなると必要な情報が伝えられなくなるじゃないかという声が聞こえてきそうです。しかし、観る側の立場となって考えてみましょう。文字がたくさんあるスライドを瞬時に理解できますか?多くの人にとって理解できないはずです。というのも、人間の脳は一度に多くの情報を処理するのは得意ではないからです。脳が処理できない情報過多のスライドが連続するとどういう現象が起こるでしょうか。聴衆はプレゼンを聴く気を無くします。

人間の脳が理解しやすいのはイメージ

人間の脳が理解しやすいのはイメージです。イメージを多くして文字の情報を減らすことで理解しやすくなります。モバイル端末を使うとイメージを使いやすいメリットがあります。大抵のモバイル端末にはカメラ機能があるので、写真を簡単に設定することができるからです。

モバイル端末で作成することで必然的に文字が少なくなります。なぜかといいますと、PCのように多くの文字を打つのは大変なため、必然的に文字が少なくなるからです。さらに、文字を打つのが面倒なので何とか写真を使えないだろうかと考えるようになります。あえて文字が打ちにくいという制約をつけることで発想を転換することができます。

少ない情報でこちらの意図を伝えるためには情報の取捨選択をせざるを得ません。それによって情報の純度の高いスライドを作ることができます。

iPhoneのkeynoteを使う

私はiPhoneのkeynoteを使用しています。まず、iPhoneのkeynoteでスライドのアウトラインを作ります。これで大体7割くらい完成しています。ファイルはiCouldで共有します。理由はPCで最後の仕上げをするからです。最後にPCのkeynoteで全体の調整や必要な情報を盛り込みます。ここで情報を盛り込み過ぎないように注意してください。

スライドの作成手順

まとめると、スライドの作成手順は次のようになります。

  1. iPhoneでアウトラインを作成
  2. PCで仕上げる

ぜひこの方法を試してみてください。PCで作成するよりもスライドが作りやすいと感じるはずです。また、モバイル端末なのでどこでもスライドが作成できます。ちょっとした隙間時間にスライドを作ることができます。スライドの作成が捗ることを実感いただけると思います。