(1). 前言

看到一位运维同学的nginx配置,特意记录下来,这个配置,非常的简洁,不用每次都要添加location.只需要按照这个规范:

  1. 定义URL按照(*-service)开头.
  2. 每上线一个服务,仅只需要定义一个upstream(upstream的名称就是:*-service的名称).

(2). nginx.conf

worker_processes  1;

error_log  logs/error.log;

events {
    worker_connections  1024;
}


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

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    # 定义服务名称(hello-service)
    upstream hello-service {
        server   127.0.0.1:9090;
        server   127.0.0.1:9091;
    }

	# 定义服务名称(test-service)
    upstream test-service {
        server   127.0.0.1:8090;
        server   127.0.0.1:8091;
    }
	
	# 定义服务名称(default-service)
	upstream default-service {
	    server   127.0.0.1:7090;
	    server   127.0.0.1:7091;
	}

    server {
        listen       8080;
        server_name  localhost;
		
		# nginx的location是有顺序的
		location ~ .*\.(js|css|png|jpg|gif|html|woff|ttf|svg|eot|map|ico|woff2)$ {
			root /home/data/html;
		}

        # / : 是URL的最后一个,利用这个功能,进行URL的重写.
        location / {
			# 设置微服务的名称为默认的微服务名称
            set $service_name "default-service";
			
			# 判断URL是否为:/*-service/
			# 比如:http://localhost:8080/hello-service,那么,$service_name=hello-service
            if ($request_uri ~ ^/(.*)-service/(.*)$) {
   		       set $service_name "$1-service";
	        }
			
			# 对URL进行重写(实际,在微服务后,不需要重写,全部请求打到gateway就可以了)
			# 比如:/hello-service/hello 会重写成: /hello
			#  最终请求为:http://$service_name/hello
	        rewrite ^/(.*)-service/(.*)$ /$2 break;
			
			# proxy_pass 指向的upstream都是个变量
	        proxy_pass http://$service_name;
        }
    }

    include servers/*;
}

(3). 测试

# 1. 请求URL
lixin-macbook:~ lixin$ curl http://localhost:8080/test-service/test.do

# 2. 观察错误日志(tail -500f logs/error.log)
2018/09/23 18:59:03 [error] 11298#0: *54 kevent() reported that connect() failed (61: Connection refused) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET /test-service/test.do HTTP/1.1", upstream: "http://127.0.0.1:8090/test.do", host: "localhost:8080"
2018/09/23 18:59:03 [error] 11298#0: *54 kevent() reported that connect() failed (61: Connection refused) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET /test-service/test.do HTTP/1.1", upstream: "http://127.0.0.1:8091/test.do", host: "localhost:8080"

# 3. 请求URL
lixin-macbook:~ lixin$ curl http://localhost:8080/hello-service/test.do

# 4. 观察错误日志(tail -500f logs/error.log)
2018/09/23 19:00:03 [error] 11298#0: *57 kevent() reported that connect() failed (61: Connection refused) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET /hello-service/test.do HTTP/1.1", upstream: "http://127.0.0.1:9090/test.do", host: "localhost:8080"
2018/09/23 19:00:03 [error] 11298#0: *57 kevent() reported that connect() failed (61: Connection refused) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET /hello-service/test.do HTTP/1.1", upstream: "http://127.0.0.1:9091/test.do", host: "localhost:8080"

# 5. 在日志上看起来是有两个请求,是因为失败的情况下,Nginx会向另一个发起请求
#    如果请求是正常的情况下,是不会有两次请求的.