Я пытаюсь решить эту проблему, но, к сожалению, я не могу понять это.
Что я пытаюсь?
Я пытаюсь перенаправить местоположение на веб-приложение Jersey 2 (JAX-RS 2), которое может взаимодействовать с запросами, как обычно, но с той разницей, что в нем есть дополнительные части URL-адреса. Приложение Java с Jersey 2 работает на изображении докеры tomcat.
Позвольте мне попытаться объяснить это лучше:
Вот как все мои запросы работали:
[IP-address]:8888/myJersey2App/something/function
Недавно я также добавил SSL, так что мой сервер взаимодействует с https.
Скажем, URL для моего сайта:
Таким образом, запрос будет выглядеть следующим образом:
https://my.example.com/myJersey2App/something/function
Конфигурация Nginx:
events{
}
http{
server{
listen 80;
listen [::]:80;
server_name my.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name my.example.com;
###
# ssl configuration ...
###
location / {
proxy_pass http://localhost:8888;
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-Proto $scheme;
}
}
}
Это работает, так как Джерси 2 все еще получает, что /myJersey2App/something/function
- это тот же путь, что и в коде.
Конфигурация Web.xml:
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/myJersey2App/*</url-pattern>
</servlet-mapping>
Это пример того, как Джерси 2 взаимодействует с запросами:
@Path("something")
public class JavaClass {
@GET
@Path("/function")
@Produces(MediaType.TEXT_PLAIN)
public Response myFunction() {
return Response.ok().entity("MyFunction!").build();
}
Чего я хочу?
Сейчас я должен запустить несколько докеров с тем же приложением, но с другим портом и URL-адресом.
Вот как это следует запросить:
Работает на порту 7777:
https://my.example.com/docker1/myJersey2App/something/function
Работает на порту 8888:
https://my.example.com/docker2/myJersey2App/something/function
Работает на порте 9999:
https://my.example.com/docker3/myJersey2App/something/function
Это на самом деле то же самое, но с той разницей, что dockerX находится в URL-адресе.
Вот как я думал, что конфигурация Nginx будет:
...
server {
listen 443 ssl http2;
server_name my.example.com;
###
# ssl configuration ...
###
location /docker1 {
proxy_pass http://localhost:7777;
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-Proto $scheme;
}
location /docker2 {
proxy_pass http://localhost:8888;
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-Proto $scheme;
}
location /docker3 {
proxy_pass http://localhost:9999;
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-Proto $scheme;
}
}
...
К сожалению, приложение Jersey2 не будет распознавать URL-адрес, так как dockerX находится внутри URL-адреса, конечно, поскольку dockerX не упоминается в коде (что не следует упоминать!)
Можно ли сконфигурировать Nginx так, чтобы приложение в Джерси все равно могло распознать его, даже если URL-адрес будет выглядеть так:
https://my.example.com/docker1/abc/def/ghi/myJersey2App/something/function
Моя заявка на Джерси должна по-прежнему признать, что она должна начинаться только с /myJersey2App/
Я думал о чем-то вроде "пользователь видит еще URL-адрес dockerX, но в фоновом режиме он обрабатывается следующим образом:
http://localhost:8888/myJersey2App/something/function
Итак, пользователь видит это:
https://my.example.com/docker2/myJersey2App/something/function
Но за этим обращаются так:
http://localhost:8888/myJersey2App/something/function
Можно ли настроить Nginx, чтобы он работал так?
Надеюсь, ты сможешь помочь мне в этой проблеме.
Я только что разобрался.
Вот как должна выглядеть конфигурация nginx:
...
location /docker1 {
rewrite /docker1/(.*) /$1 break;
proxy_pass http://localhost:7777;
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-Proto $scheme;
}
location /docker2 {
rewrite /docker2/(.*) /$1 break;
proxy_pass http://localhost:8888;
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-Proto $scheme;
}
location /docker3 {
rewrite /docker3/(.*) /$1 break;
proxy_pass http://localhost:9999;
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-Proto $scheme;
}
...
Когда вы выполняете запрос, вы все равно видите часть dockerX, но за ней обрабатывается, как если бы часть dockerX не существует, потому что rewrite удаляет эту часть. И хорошо, что приложение Java Java может работать нормально, не изменяя фактическое приложение "Джерси-2".