設定 Docker
不久前嘗試 Docker 化整套 PredictionIO(PIO) 設置。當中包括 Apache HBase 和 Spark 的設定,令人非常頭痛。最後花了一個多星期才做到一個可以勉強運行的原型。除了這些 PredictionIO 組件外,我還添加了一個 Nginx 容器作為運行 PredictionIO Event(事件)和 Prediction(預測)服務器的兩個容器的 Reverse Proxy(反向代理)。事件服務器有一個 REST Event(事件) API,可以把實時的用戶事件通過 HTTP POST 請求發送到事件服務器。由於我們想從前端 Javascript 收集事件並發送到事件服務器,我們必須在 Nginx 中啟用 CORS(跨來源資源共享)。數據流如下圖所示。
我們希望打開來自同一個域的 CORS 請求。(即本例中的* .pio.com)
Nginx 容器端口80被映射到 Docker 伺服器,它是連接兩國個 PIO 服務的唯一通路。然後根據主機名將請求路由到不同的上游。以下是兩個 Nginx 的配置文件。
upstream.conf
1
2
3
4
5
6
7
|
upstream pio-event-server {
server pio-event-server:7070;
}
upstream pio-prediction-server {
server pio-prediction-server:8000;
}
|
pio-proxy.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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
# PIO Event Server reverse proxy
server {
listen 80;
server_name event.pio.com;
location / {
# Check if the origin of th request
set $cors '';
if ($http_origin ~* (https?://.*\.pio\.com?(:[0-9]+)?$)) {
set $cors 'on';
}
if ($request_method = OPTIONS) {
set $cors "${cors}_options";
}
# Allow CORS on preflight request
if ($cors = 'on_options') {
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept';
return 204;
}
# Proxy pass to upstream
proxy_pass http://pio-event-server;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
# Allow CORS on other requests after returning from the upstreams
if ($cors = 'on') {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept';
}
}
}
# PIO Prediction Server reverse proxy
server {
listen 80;
server_name query.pio.com;
location / {
# Loadbalance
proxy_pass http://pio-prediction-server;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
|
請注意,如 proxy-pio.conf 中強調的那樣,add_header 指令必須寫在 proxy_pass 語句之後。
最後,我們可以利用 Chrome Inspector 來檢查是否在 Response header(回應標頭)中添加了 CORS 的頭欄位。