做了反向代理和負載均衡的nginx配置檔案簡單示例(nginx.conf) HTTP負載均衡/TCP負載均衡

asashadow發表於2024-12-10

在預設配置的基礎上,啟用http反向代理和負載均衡。同時配置了TCP反向代理和負載均衡。
另外,能夠實現每天生成一個日誌檔案,日誌用json格式,日誌中的日期重新格式化成 yyyy-MM-ddTHH:mm:ss.ZZZ這樣子。
nginx version 1.27.3

nginx.conf

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    ###### 時間相關的幾個變數 ######
    # https://serverfault.com/questions/732395/can-nginx-log-time-in-iso-8601-format-but-include-milliseconds
    # https://thatsamguy.com/nginx-iso8601-time-format/
	#  just the date and time part of $time_iso8601 e.g. 2021-05-21T10:26:19
	map $time_iso8601 $p1_datetime {
		~([^+]+) $1;
    }
	#  just the timezone part of $time_iso8601 e.g. +00:00
	map $time_iso8601 $p2_timezone {
		~\+([0-9:]+)$ $1;
    }
	#  just the millisecond part of $msec e.g. 123 extracted from 1621594635.123
	map $msec $millisec {
		~\.([0-9]+)$ $1;
    }
    ###### 時間相關的幾個變數 ######
    
    # 用json格式記錄日誌
	log_format json_logger escape=json
	'{'
		'"time":"$p1_datetime.$millisec",'
		'"remote_addr":"$remote_addr",'
		'"remote_user":"$remote_user",'
		'"request":"$request",'
		'"status":"$status",'
		'"body_bytes_sent":"$body_bytes_sent",'
		'"http_referer":"$http_referer",'
		'"http_user_agent":"$http_user_agent",'
		'"http_x_forwarded_for":"$http_x_forwarded_for"'
	'}';
    
    # 這個變數給下面access_log日誌檔案的時候用,確保每天建立一個日誌檔案
	map $time_iso8601 $logdate {
		'~^(?<ymd>\d{4}-\d{2}-\d{2})' $ymd;
		default    'date-not-found';
    }
	
    access_log  logs/http_json_access_$logdate.log  json_logger;
	error_log  logs/http_json_error.log;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    
	upstream backend {
		ip_hash;
        server www.example.com:80;
        server www2.example.com:80;
        #server www3.example.com:80 backup;
    }
	
    server {
        listen       8080;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        # 預設配置
		#location / {
        #    root   html;
        #    index  index.html index.htm;
        #}
		
		# 改成load balance
		location / {
			proxy_pass http://backend;
		}

		# 線上狀態頁
		location /nginx_status {
			stub_status on;
			access_log off;
			
			allow 127.0.0.1;
            allow ::1;  # 對於IPv6地址
            deny all;
		}

        #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   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

stream {
	###### 時間相關的幾個變數 ######
    # https://serverfault.com/questions/732395/can-nginx-log-time-in-iso-8601-format-but-include-milliseconds
    # https://thatsamguy.com/nginx-iso8601-time-format/
	#  just the date and time part of $time_iso8601 e.g. 2021-05-21T10:26:19
	map $time_iso8601 $p1_datetime {
		~([^+]+) $1;
    }
	#  just the timezone part of $time_iso8601 e.g. +00:00
	map $time_iso8601 $p2_timezone {
		~\+([0-9:]+)$ $1;
    }
	#  just the millisecond part of $msec e.g. 123 extracted from 1621594635.123
	map $msec $millisec {
		~\.([0-9]+)$ $1;
    }
    ###### 時間相關的幾個變數 ######

    # 用json格式記錄日誌,這裡支援的欄位,跟http裡面的還不完全一致,有些http支援的,這裡不支援,反之亦然
	log_format json_logger escape=json
	'{'
		'"time":"$p1_datetime.$millisec",'
		'"remote_addr":"$remote_addr",'
		'"protocol":"$protocol",'
		'"status":"$status",'
		'"bytes_sent":"$bytes_sent",'
		'"bytes_received":"$bytes_received",'
		'"session_time":"$session_time",'
		'"upstream_addr":"$upstream_addr",'
		'"upstream_bytes_sent":"$upstream_bytes_sent",'
		'"upstream_bytes_received":"$upstream_bytes_received",'
		'"upstream_connect_time":"$upstream_connect_time"'
	'}';

    # 這個變數給下面access_log日誌檔案的時候用,確保每天建立一個日誌檔案
	map $time_iso8601 $logdate {
		'~^(?<ymd>\d{4}-\d{2}-\d{2})' $ymd;
		default    'date-not-found';
    }
	
    access_log logs/tcp_json_access_$logdate.log json_logger; #buffer=32k;
    error_log logs/tcp_json_error.log;
	open_log_file_cache off;	#當設定為off時,Nginx不會在啟動時開啟所有的日誌檔案,也不會追蹤它們的開啟狀態。這意味著如果日誌檔案在執行時被重新命名或刪除,Nginx可能不會立即檢測到這些變化,直到下一次嘗試寫入日誌時。

    upstream backend {
        server 10.12.0.21:5678 weight=1 max_fails=2 fail_timeout=10s;
        server 10.12.0.22:5678 weight=1 max_fails=2 fail_timeout=10s;
        server 10.12.0.23:5678 backup; # 備用伺服器
    }

    server {
        listen 5678;
        proxy_pass backend;
        #proxy_protocol on; # 啟用 PROXY protocol ,需要後端伺服器也支援proxy protocol才行,否則的話,能ping通,但是請求會失敗
        #proxy_timeout 3s; # 設定代理超時時間
    }
}


參考資料

  • TCP and UDP Load Balancing
    https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-udp-load-balancer/
  • Accepting the PROXY Protocol
    https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/
  • TCP Health Checks
    https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-health-check/
  • HTTP Load Balancing
    https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/
  • HTTP Health Checks
    https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/
  • Can nginx log time in ISO 8601 format, but include milliseconds?
    https://serverfault.com/questions/732395/can-nginx-log-time-in-iso-8601-format-but-include-milliseconds
  • Nginx - logging milliseconds in ISO8601 format
    https://thatsamguy.com/nginx-iso8601-time-format/
  • TCP/UDP Load Balancing with NGINX: Overview, Tips, and Tricks
    https://blog.nginx.org/blog/tcp-load-balancing-udp-load-balancing-nginx-tips-tricks
  • nginx windows安裝、使用和配置開機啟動
    https://blog.csdn.net/xiaojin21cen/article/details/84622517
  • nginx--正向代理、反向代理及負載均衡(圖解+配置)
    https://blog.csdn.net/justinqin/article/details/119519019
  • nginx正向代理http, https親測可用
    https://www.cnblogs.com/chenjinxi/p/13265877.html
  • ngx_http_proxy_connect_module
    https://github.com/chobits/ngx_http_proxy_connect_module/
  • 分析Nginx日誌並存入MySQL
    https://panqiincs.me/2019/04/25/nginx-log-to-mysql/

相關文章