С помощью директивы http nginx вы можете иметь несколько серверов на одном порте с разными именами:
server {
listen 80;
server_name server1.example.com;
location / {
proxy_pass http://server1.example.com;
}
}
server {
listen 80;
server_name server2.example.com;
location / {
proxy_pass http://server2.example.com;
}
}
Возможно ли иметь прокси-сервер nginx для нескольких серверов mysql на одном порте с разными именами, как вы можете с http? Они не являются частью кластера или чего-то еще. У них разные, не связанные таблицы.
stream {
upstream db1.example.com {
server db1.example.com:3306;
#server_name db1.example.com; "server_name" directive is not allowed here
}
upstream db2.example.com {
server db2.example.com:3306;
}
server {
listen 3306;
proxy_pass db1.example.com;
}
#duplicate "3306" address and port pair
#server { listen 3306; proxy_pass db2.example.com; }
}
Да, если nginx был скомпилирован с --with-stream
. https://www.nginx.com/resources/admin-guide/tcp-load-balancing/
Вот один из примеров с таким же портом:
upstream stream_backend {
hash $remote_addr;
server backend1.example.com:12345;
server backend2.example.com:12345;
server backend3.example.com:12346;
}
Второе обновление:
Очевидно, вы не можете ничего подобного:
stream {
upstream db1.example.com {
server db1.example.com:3306;
#server_name db1.example.com; "server_name" directive is not allowed here
}
upstream db2.example.com {
server db2.example.com:3306;
}
server {
listen 3306;
proxy_pass db1.example.com;
}
#duplicate "3306" address and port pair
#server { listen 3306; proxy_pass db2.example.com; }
}
Поскольку прокси-сервер nginx для восходящего потока db1.example.com
конкурирует с db2.example.com
для пакетов на порт 3306. Итак, у вас должен быть прокси для db1.example.com listen
на другом port
чем прокси для db2.example.com
. В противном случае nginx не знал бы, как маршрутизировать пакеты между двумя восходящими потоками. Приносим извинения за неправильное понимание вашего исходного сообщения. server_name
не допускается в определениях потоков, потому что, в отличие от заголовков http, в пакете tcp / udp нет дополнительных метаданных, которые идентифицируют, какой DNS использовался для передачи пакета на nginx.
Можно направлять соединения на основе заголовка SNI, используя Модуль предварительного чтения ssl nginx.
Это зависит от того, как клиент указывает заголовок SNI при открытии соединения.
В приведенном ниже примере nginx прослушивает соединения на порту 443. Соединение с present.myglance.org:443 перенаправляется на порт 4443 (это http-сервер, не показан). Соединение с присутствием-s.myglance.org:443 пересылается потоковому серверу, прослушивающему порт 5502, который завершает соединение ssl и перенаправляет его на порт 6502.
stream {
############################################################
### logging
log_format log_stream '$remote_addr [$time_local] $protocol [$ssl_preread_server_name] [$ssl_preread_alpn_protocols] [$internalport] '
'$status $bytes_sent $bytes_received $session_time';
error_log /home/Logs/error.log debug;
access_log /home/Logs/access.log log_stream;
### https://nginx.org/en/docs/stream/ngx_stream_ssl_preread_module.html
#########################################################################
# Connections on 443 could be raw socket or https / wss
# Distinguish between the two based on the SNI (preread server name)
# Server names with -s are raw socket connections
# Server names without -s are https or wss connections
map $ssl_preread_server_name $internalport {
presence-s.myglance.org 5502;
presence.myglance.org 4443;
default glance-no-upstream-instance;
}
# Note this does not terminate the ssl connection. It just reads the SNI
# header and forwards to the appropriate port
server {
listen 443;
ssl_preread on;
proxy_connect_timeout 20s; # max time to connect to pserver
proxy_timeout 30s; # max time between successive reads or writes
proxy_pass 127.0.0.1:$internalport;
}
server {
listen 5502 ssl;
ssl_preread off;
proxy_pass 127.0.0.1:6502;
}
}
Я много раз искал это, к сожалению, это невозможно, поскольку TCP не имеет понятия имен серверов, поэтому это невозможно. Он работает только в HTTP, потому что клиент отправляет имя хоста, к которому он пытается получить доступ, как часть запроса, позволяя NGINX сопоставить его с конкретным блоком сервера.
Очень обидно, так как мне бы очень хотелось направить TCP-трафик на основе url-адреса.