2017-04-17 56 views
1

我試圖使用nginx作爲負載均衡器/代理服務器,它指向一系列的tomcat服務器。這是我當前的nginx配置。使用nginx作爲代理到java web servlet

server { 

    listen 80; 
    server_name _; 
    rewrite^https://$http_host$request_uri? permanent; 
} 

server { 
    listen 443; 

    resolver 127.0.0.11 valid=5s; 

    ssl on; 
    ssl_certificate /etc/nginx/certs/default.crt;  # path to your cacert.pem 
    ssl_certificate_key /etc/nginx/certs/default.key; # path to your privkey.pem 
    ssl_verify_client off; 
    server_name localhost; 
    fastcgi_param HTTPS    on; 
    fastcgi_param HTTP_SCHEME   https; 

    charset utf-8; 
    client_max_body_size 200M; 

    set $app https://app:8443; 
    set $auth https://auth:8443/authentication/; 
    set $discovery https://discovery:8443/discovery/; 

    location/{ 
     proxy_pass $app; 
    } 
    location /authentication { 
     proxy_pass $auth; 
    } 
    location /discovery { 
     proxy_pass $discovery; 
     proxy_set_header Host $http_host; 
     proxy_set_header X_FORWARDED_PROTO https; 
    } 

} 

這是dockerized如果它有任何區別,但供應無法正確解析,而文檔工作正常。文檔和配置之間的唯一區別是'文檔'通過tomcat提供純html文件。 (tomcat7標準/ docs /),而配置實際上是一個java servlet(JaxRS/spring等)。

如果我直接點擊圖片,它會按預期工作,而如果我嘗試通過nginx擊中同一端點,則無法解析。

我的docker-compose配置供參考。

version: '2' 
services: 
    db: 
    image: db:nodata 
    expose: 
    - 5433 
    zk: 
    image: zookeeper 
    ports: 
    - 2181:2181 
    discovery: 
    image: services_discovery:latest 
    env_file: docker_environment 
    expose: 
    - 8443 
    ports: 
    - 8443:8443 
    links: 
    - db 
    - zk 
    app: 
    image: tomcat-jsse-ssl:7-jdk8 
    volumes: 
    - ./app/www/:/usr/local/tomcat7/webapps/ROOT/ 
    expose: 
    - 8443 
    ports: 
    - 8444:8443 
    auth: 
    image: tomcat-jsse-ssl:7-jdk8 
    volumes: 
    - ./authentication/www/authentication/:/usr/local/tomcat7/webapps/authentication/ 
    expose: 
    - 8443 
    proxy: 
    build: ./proxy/ 
    depends_on: 
    - 'auth' 
    - 'app' 
    - 'discovery' 
    ports: 
    - 443:443 
    restart: always 

隨着圖像的運行,我可以解決以下網址就好了。

即。兩個容器都運行良好:

服務器日誌:

proxy_1  | 172.20.0.1 - - [24/Apr/2017:00:04:28 +0000] "GET /discovery/ready HTTP/1.1" 404 400 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36" 
proxy_1  | 172.20.0.1 - - [24/Apr/2017:00:04:43 +0000] "GET /discovery/api/swagger.json HTTP/1.1" 404 400 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36" 
proxy_1  | 172.20.0.1 - - [24/Apr/2017:00:04:57 +0000] "GET /discovery/ready HTTP/1.1" 404 400 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36" 

發現Tomcat的訪問日誌(當直接訪問)

172.20.0.1 - - [23/Apr/2017:00:02:38 +0000] "GET /discovery/ready HTTP/1.1" 200 70 
172.20.0.2 - - [24/Apr/2017:00:04:28 +0000] "GET /discovery/ HTTP/1.0" 404 949 
172.20.0.2 - - [24/Apr/2017:00:04:43 +0000] "GET /discovery/ HTTP/1.0" 404 949 
172.20.0.2 - - [24/Apr/2017:00:04:57 +0000] "GET /discovery/ HTTP/1.0" 404 949 

的第一項是,當我打服務器直接通過https://localhost:8443/discovery/ready其他所有內容 是當nginx發送請求到服務器。由於某些原因,它不能正確地翻譯請求。

任何想法/建議,將不勝感激?

注意:爲了解決這個問題,我簡化了示例/配置,任何對「provisioning」的引用現在都是「discovery」。

更新:我想出了爲什麼它打破了'servlet'。它實際上是不斷打破。它將剝離除基礎之外的所有網址。例如

https://localhost/authentication?q=dummy

變得 172.20.0.3 - - [24 /月/ 2017:03:22:06 0000] 「GET /認證/ HTTP/1.0」 200 28

註釋該查詢參數被刪除。

+0

容器是否在同一個碼頭網絡上? – BMitch

+0

是的,同一個網絡。如果我輸入nginx容器,我會看到所有不同的容器,並且可以像我說的那樣ping它們,只要數據是靜態的html/css就好了。 – csgeek

+0

您在配置容器日誌中看到錯誤嗎?你能告訴哪個容器生成了404嗎? – BMitch

回答

1

nginx的文檔說,你是RESPONSABLE重建網址:

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

所以,你可以嘗試使用正則表達式來捕捉URI的其餘部分,並把它在proxy_pass部分:

location ~* ^/discovery/(.*) { 
    proxy_pass $discovery$1$is_args$args; 
    .... other configs.... 
} 
+0

這對我來說真棒!只是幾個跟進問題。我假設(。*)被映射到$ 1。我從http://nginx.org/en/docs/http/ngx_http_core_module.html獲得了$ vars定義。有什麼目的〜* – csgeek

+0

啊,明白了。 〜*標記爲正則表達式模式。謝謝! – csgeek