知乎專欄 | 多維度架構 | 微信號 netkiller-ebook | QQ群:128659835 請註明“讀者” |
例 45.5. Nginx + Tomcat
server { listen 80; server_name www.example.com; charset utf-8; access_log /var/log/nginx/www.example.com.access.log; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } location ~ ^/WEB-INF/ { deny all; } location ~ \.(html|js|css|jpg|png|gif|swf)$ { root /www/example.com/www.example.com; expires 1d; } location ~ \.(ico|fla|flv|mp3|mp4|wma|wmv|exe)$ { root /www/example.com/www.example.com; expires 7d; } location ~ \.flv { flv; } location ~ \.mp4$ { mp4; } }
背景:網站推廣審核需要隱藏或不現實首頁,其他頁面正常
需求:要求訪問首頁事顯示指定頁面
server { listen 80; server_name any.netkiller.cn; charset utf-8; access_log /var/log/nginx/any.netkiller.cn.access.log; error_log /var/log/nginx/any.netkiller.cn.error.log; location /index.html { ssi on; proxy_set_header Accept-Encoding ""; proxy_pass http://172.16.0.1/www/temp.html; proxy_set_header Host www.netkiller.cn; } location / { ssi on; rewrite ^/$ /zt/your.html; proxy_set_header Accept-Encoding ""; proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } error_page 404 /error/404.html; error_page 403 /error/403.html; error_page 502 /error/502.html; error_page 500 502 503 504 /error/500.html; location ~ ^/WEB-INF/ { deny all; } location ~ \.(html|js|css|jpg|png|gif|swf)$ { root /www/netkiller.cn/www.netkiller.cn; expires 1d; } location ~ \.(ico|fla|flv|mp3|mp4|wma|wmv|exe)$ { root /www/netkiller.cn/www.netkiller.cn; flv; mp4; expires 7d; } location /zt { root /www/netkiller.cn/www.netkiller.cn; rewrite ^(.*)\;jsessionid=(.*)$ $1 break; expires 1d; } location ^~ /zt/other/ { ssi on; proxy_set_header Accept-Encoding ""; proxy_pass http://172.16.0.1/www/; proxy_set_header Host www.netkiller.cn; proxy_cache www; proxy_cache_valid 200 302 1m; } location /module { root /www/netkiller.cn/www.netkiller.cn; } }
環境
User -> Http2 CDN -> Http2 Nginx -> proxy_pass 1.1 -> Tomcat
背景,預設情況下 tomcat 不會主動推送 Cookie 域,例如下面的HTTP頭
Set-Cookie: JSESSIONID=8542E9F58C71937B3ABC97F002CE039F;path=/;HttpOnly
這樣帶來一個問題,在瀏覽器中預設Cookie域等於 HTTP_HOST 頭(www.example.com),如果網站只有一個域名沒有問題,如果想共享Cookie給子域名下所有域名 *.example.com 無法顯示。
通過配置Tomcat sessionCookieDomain="example.com" 可以實現推送 Cookie 域
<Context path="" docBase="/www/netkiller.cn/www.netkiller.cn" reloadable="false" sessionCookieName="PHPSESSID" sessionCookieDomain="netkiller.cn" sessionCookiePath="/" />
這樣的配置一般用戶的需求都可以滿足。我的需求中還有一項,在伺服器綁定多個域名(二級域名)。問題來了 Tomcat 將始終推送 netkiller.cn 這個域。其他域名無法正確設置Cookie
$ curl -s -I -H https://www.netkiller.cn/index.jsp | grep Set-Cookie Set-Cookie: PHPSESSID=4DBAF36AA7B79CE1ACBA8DD67702B945;domain=netkiller.cn;path=/;HttpOnly $ curl -s -I -H 'Host: www.test.com' https://www.test.com/index.jsp | grep Set-Cookie Set-Cookie: PHPSESSID=4DBAF36AA7B79CE1ACBA8DD67702B945;domain=netkiller.cn;path=/;HttpOnly $ curl -s -I -H 'Host: www.example.com' https://www.example.com/index.jsp | grep Set-Cookie Set-Cookie: PHPSESSID=4DBAF36AA7B79CE1ACBA8DD67702B945;domain=netkiller.cn;path=/;HttpOnly
怎樣處理需求呢,我想了兩個方案,一個方案是在Nginx中配置,另一個方案是在代碼中解決。其中Nginx處理起來比較靈活無需開發測試介入,最終選擇nginx方案
server { listen 443 ssl http2 default_server; server_name _; location ~ \.(do|jsp|action)$ { ssi on; proxy_set_header Accept-Encoding ""; proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; set $domain $host; if ($host ~* ^([^\.]+)\.([^\.]+)\.([^\.]+)$) { set $domain $2.$3; } proxy_cookie_domain netkiller.cn $domain; } }
server_name _; 接受任何域名綁定,default_server 將vhost 設置為預設主機。最終測試結果:
$ curl -s -I -H https://www.netkiller.cn/index.jsp | grep Set-Cookie Set-Cookie: PHPSESSID=4DBAF36AA7B79CE1ACBA8DD67702B945;domain=netkiller.cn;path=/;HttpOnly $ curl -s -I -H https://www.example.com/index.jsp | grep Set-Cookie Set-Cookie: PHPSESSID=4DBAF36AA7B79CE1ACBA8DD67702B945;domain=example.com;path=/;HttpOnly $ curl -s -I -H https://www.domain.com/index.jsp | grep Set-Cookie Set-Cookie: PHPSESSID=4DBAF36AA7B79CE1ACBA8DD67702B945;domain=domain.com;path=/;HttpOnly