nginx - 使用 nginx 作为代理到 java web servlet

标签 nginx docker reverse-proxy internal-load-balancer

我正在尝试使用 nginx 作为负载平衡器/代理服务器,它指向一系列 tomcat 服务器。这是我当前的 nginx 配置。

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

随着图像的运行,我可以很好地解析以下 URL。
  • https://localhost:8443/discovery/ready
  • https://localhost:8444/

  • IE。两个容器都运行良好:
  • https://localhost/通过 nginx 加载工作正常。
  • https://localhost/authentication/通过 nginx 加载工作正常。
  • https://localhost/discovery/ready ==> 404.

  • 服务器日志:
    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 向服务器发送请求的时候。由于某种原因,它没有正确翻译请求。

    任何想法/建议将不胜感激?

    注意:出于这个问题的目的,我简化了我的示例/配置,并且对“配置”的任何引用现在都是“发现”。

    更新:我弄清楚为什么它会破坏“servlet”。它实际上一直在中断。它正在剥离除基础之外的所有 URL。

    例如。

    https://localhost/authentication?q=dummy

    变成
    172.20.0.3 - - [2017 年 4 月 24 日:03:22:06 +0000] “GET/authentication/HTTP/1.0”200 28

    请注意,查询参数已被剥离。

    最佳答案

    nginx 文档说您有责任重建 url:

    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....
    }
    

    关于nginx - 使用 nginx 作为代理到 java web servlet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43443669/

    相关文章:

    javascript - 在 Angular cli 中配置代理

    http - 如何使用 NewSingleHostReverseProxy 处理错误

    nginx 代理 ELK

    php - 无法将 https 站点重定向到另一个 url - nginx 服务器 block

    同时在fedora上运行php7和php5

    caching - Nginx如何完全禁用代理缓存

    docker - 无法使用 docker 存储库中 vendor 目录中的包

    nginx - 带有 Flask 和 Gunicorn 的 Google Cloud Run : Nginx needed?

    docker - 如何重新启动docker镜像而不是重新启动docker?

    docker - 进程启动后如何执行docker命令