前言:

    本文是在Linux下具体使用和重新了解一下Nginx。前提,先有Linux和Nginx环境,如果没有环境,可以先参考网上的相关配置哈。如果,新接手了一台服务器,可直接先检查是否已配置nginx环境。游览器直接访问服务器的ip,nginx默认端口是80,出现以下页面则证明nginx安装成功。

nginx 反向代理 ip host not found in upstream nginx反向代理服务_服务器


    Nginx是什么?

    Nginx是一个高性能的HTTP和反向代理服务器,处理高并发能力非常强大,能经受高负载的考验,有报告表明它能支持高达50,000个并发连接数。

    Nginx能做什么?

    由于Nginx的特性,它经常有如下的使用场景:①正向代理;②反向代理;③负载均衡;④动静分离;⑤高可用集群。

文章目录

  • 一、何为反向代理
  • 二、Nginx配置文件
  • 2.1 第一部分:全局块
  • 2.2 第二部分:events块
  • 2.3 第三部分:http块
  • 2.3.1 全局server块
  • 2.3.2 location块
  • 三、反向代理如何配置
  • 3.1 反向代理实例一
  • 3.2 反向代理实例二
  • 3.3 反向代理实例三
  • 3.3.1 nginx代理流程
  • 3.3.2 配置ip和域名的绑定关系
  • 3.3.3 在配置nginx配置请求转发
  • 四、nginx常用的命令


一、何为反向代理

    在反向代理之前,需要先了解一下正向代理。

    正向代理:如果把局域网外的Internet想象成一个巨大的资源库,则局域网中的客户端要访问Internet,则需要通过代理服务器来访问,这种代理服务就称为正向代理,下面是正向代理的原理图。

    比如,有的公司,日常工作职能局限于单位的局域网,如果想要访问互联网,怎么帮呢?就可以使用正向代理。

nginx 反向代理 ip host not found in upstream nginx反向代理服务_服务器_02


    又比如,梯子就是做正向代理的。正向代理服务器位于客户端和服务器之间,为了向服务器获取数据,客户端要向代理服务器发送一个请求,并指定目标服务器,代理服务器将目标服务器返回的数据转交给客户端。这里的客户端是要进行一些正向代理的设置的。(PS:梯子通俗的讲就是一种中转服务,当我们的电脑接入梯子后,我们对外IP地址就会变成梯子服务器的公网IP,我们请求或接受数据都会通过这个梯子服务器,然后传入到我们本机。)    反向代理:看下图,就能很清楚的明白。其实,客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时,反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。

nginx 反向代理 ip host not found in upstream nginx反向代理服务_html_03


    **总结:**如果是我们客户端自己用,就是正向代理,正向代理代理客户端;如果是服务器再用,用户无感知,就是反向代理,反向代理代理服务器。

     有个问题,如果是反向代理服务器,怎么选择挂在它后面的哪一台具体的服务器呢?答案就是负载均衡。

二、Nginx配置文件

    在学习Nginx之前,要熟知它的配置文件,下面需要做的所有配置(反向代理、负载均衡、动静分离等),都是基于它的配置文件。

    nginx的配置文件在 /usr/local/nginx/conf中的 nginx.conf。(PS:如果修改过nginx.conf配置文件,记得要重启Nginx服务,很重要!)

nginx 反向代理 ip host not found in upstream nginx反向代理服务_html_04


    配置文件中有很多#号,该符号表示注释内容,去掉所有以#开头的段落,精简之后的配置文件内容如下(PS:其实注释掉的地方,都是一些功能的使用代码,需要用到的时候,取消注释即可):

# 主进程叫master,负责管理子进程,子进程叫worker
# worker_processes配置项表示开启几个业务进程,一般和cpu核数有关
worker_processes  1;

events {
    worker_connections  1024;
}

http {
	# include表示可以引入其他文件,此处表示引入http mime类型
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

	# 虚拟主机,可以配置多个
    server {
        listen       80;
        server_name  www.jasonqian.com;   # 需要将www.jasonqian.com替换成证书绑定的域名

        location / {
        	# 路径匹配之后,哪个目录下去匹配相应的网页,html是相对路径
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
	}

    举个例子,新部署一个前端项目

    ①进入nginx.conf配置文件, 添加一个server,修改监听端口为8081 ,修改location下的root对应的 文件夹名称 doorlock;

    ②/usr/local/nginx下新建doorlock文件夹,用来存放打包后的前端静态文件;

    ③修改配置文件之后,要运行命令测试一下,进入目录/usr/local/nginx/sbin 目录下,运行 ./nginx -t;

    ④如果显示没有错误,就执行 ./nginx -s reload,重启Nginx服务

    ⑤通过服务器的IP加端口号,即可访问新部署的项目,如http://139.xxx.211. xxx:8001/cloudBuy/cloudService/。

nginx 反向代理 ip host not found in upstream nginx反向代理服务_前端部署_05

nginx 反向代理 ip host not found in upstream nginx反向代理服务_运维_06


nginx 反向代理 ip host not found in upstream nginx反向代理服务_nginx_07


nginx 反向代理 ip host not found in upstream nginx反向代理服务_前端部署_08


如果想把部署项目的IP访问地址,和域名匹配上,可以在server_name项进行配置( 注意:nginx要求 server_name 不能包含“/” ,所以,可以把http:/去掉即可),不然,可能会报错nginx启动报 server name "*" has suspicious symbols 。配置如下:

nginx 反向代理 ip host not found in upstream nginx反向代理服务_运维_09

去掉注释信息后,可以将nginx.conf配置文件分为三部分:

    举第二个例子,公司旧项目迁移,如何部署一个前端node项目 (ps:读者可忽略,仅做记录)

背景介绍:公司之前的老项目,因更换服务器的原因,需要迁移。项目是前后端分离的,分为nodego 和webgo文件夹,nodego文件主要是做node接口转发请求,实际项目开发主要在webgo文件夹里面。目录结构如下:

nginx 反向代理 ip host not found in upstream nginx反向代理服务_前端部署_10


nginx 反向代理 ip host not found in upstream nginx反向代理服务_运维_11

nginx 反向代理 ip host not found in upstream nginx反向代理服务_前端部署_12


操作流程如下:(前提条件:服务器安装node,npm,pm2)

    ①拷贝node文件夹到服务器指定文件夹,除了node_modules文件夹外,并创建public文件(存放打包之后的前端项目包,public文件夹已在程序中定义好,具体可查看nodego文件夹下的app.js文件) ;

nginx 反向代理 ip host not found in upstream nginx反向代理服务_服务器_13


    ②cd 到当前node文件夹下npm install ;

    ③利用pm2来创建任务;

    测试环境启动命令: (sgnodeh5是项目文件夹的名称)

pm2 start npm --watch --name sgnodeh5 -- run start

    生产环境启动命令:(生产环境可以通过配置node环境来更改服务器配置,具体可查看config配置)
利用pm2来创建任务:当前默认为config-prod (启动时,可选择相关的启动配置文件config-prod)

export NODE_ENV=config-prod && pm2 start npm --watch --name sgnodeerm -- run start

nginx 反向代理 ip host not found in upstream nginx反向代理服务_服务器_14


在服务器上的文件夹路径为/opt/smartgo_erm,文件夹结构如下:

nginx 反向代理 ip host not found in upstream nginx反向代理服务_nginx_15


node配置的请求文件config文件夹如下:

nginx 反向代理 ip host not found in upstream nginx反向代理服务_服务器_16


以上步骤操作完毕,就可以查看对应的访问ip地址了,项目可以正常访问了。

项目在初始化的时候,一般会有配置项目访问默认的端口号,如何更改项目的端口号呢?

可以在nodego文件夹下bin文件中的www文件里面进行修改:

nginx 反向代理 ip host not found in upstream nginx反向代理服务_nginx_17

2.1 第一部分:全局块

worker_processes  1;

    从配置文件开始到events块之间的内容,主要会设置一些影响Nginx服务器整体运行的配置指令,主要包括:配置运行Nginx服务器的用户组,允许生成的work process数,进程PID存放路径,日志存放路径和类型以及配置文件的引入等。
    上面这行worker_processes配置,是Nginx服务器并发进行处理服务的关键配置,该值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的约束。

2.2 第二部分:events块

events {
	worker_connections  1024;
}

    events块涉及的指令,主要影响Nginx服务器与用户的网络连接,常用的设置包括:是否开启对多work process下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种时间驱动模型来处理连接请求,每个work process可以同时支持的最大连接数等。
    上述例子就表示每个work process支持的最大连接数为1024。这部分的配置对Nginx的性能影响较大,在实际中应该灵活配置。

2.3 第三部分:http块

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

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

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
    }
}

    这部分是Nginx服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。需要注意的是:http块也可以包括http全局块、server块。下面的反向代理、动静分离、负载均衡都是在这部分中配置的

  • http全局块:http全局块配置的指令包括:文件引入、MIME-TYPE定义、日志定义、连接超时时间、单链接请求数上限等;
  • server块:这块和虚拟主机有密切关系,从用户角度看,虚拟主机和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。
    每个http块可以包含多个server块,而每个server块就相当于一个虚拟主机。而每个server块也分为全局server块,以及可以同时包含多个location块。
2.3.1 全局server块

最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或IP配置。

2.3.2 location块

一个server块可以配置多个location块。
这块的主要作用是:基于Nginx服务器接收到的请求字符串(例如server_name/uri-string),对虚拟主机名称(也可以是IP别名)之外的字符串(例如:前面的/uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        # 若请求路径像这样:www.xxxx/img/example.png
        # 则访问/img/目录下的文件时,nginx会去/var/www/image/img/目录下找文件
        location /img/ {
            root /var/www/image;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
    }
}

三、反向代理如何配置

3.1 反向代理实例一

实现效果:使用nginx反向代理,访问www.123.com直接跳转到127.0.0.1:8080注意:此处如果想要从www.123.com跳转到本机指定的ip,需要修改本机的hosts文件。此处略过。
配置代码:

server {
	listen       80;
	server_name  192.168.17.129;

	location / {
		root   html;
		index  index.html index.htm;
		proxy_pass  http://127.0.0.1:8080
	}
}

如上配置,Nginx监听80端口,访问域名www.123.com(不加端口号时默认为80端口),故访问该域名时会跳转到127.0.0.1:8080路径上。

此处意思为:nginx反向代理服务监听192.168.17.129的80端口,如果有请求过来,则转到proxy_pass配置的对应服务器上,仅此而已;
location下,同时配置rootproxy_pass选项时,两个选项只会二选一执行;
此处不能配置https反向代理。

实现效果:

nginx 反向代理 ip host not found in upstream nginx反向代理服务_服务器_18

3.2 反向代理实例二

实现效果:使用Nginx反向代理,根据访问的路径跳转到不同端口的服务中,Nginx监听端口为9001
访问http://192.168.17.129/edu/直接跳转到127.0.0.1:8080 访问http://192.168.17.129/vod/直接跳转到127.0.0.1:8081 第一步:需要准备两个tomcat,一个8080端口,一个8081端口,并准备好测试的页面;
第二步:修改nginx的配置文件,在http块中配置server

server {
	listen       9001;
	server_name  192.168.17.129;

	location ~ /edu/ {
		proxy_pass  http://127.0.0.1:8080
	}

	location ~ /vod/ {
		proxy_pass  http://127.0.0.1:8081
	}
}

根据上面的配置,当请求到达Nginx反向代理服务器时,会根据请求路径不同进行分发到不同的服务器上。

实现效果:

nginx 反向代理 ip host not found in upstream nginx反向代理服务_html_19


Nginx完整配置文件:

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

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

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

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

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

3.3 反向代理实例三

3.3.1 nginx代理流程

nginx 反向代理 ip host not found in upstream nginx反向代理服务_nginx_20


本地游览器访问nginx服务器,nginx服务器反向代理tomcat服务器,当我们请求nginx的时候直接访问到tomcat。这里将tomcatnginx安装在了同一台服务器上。

3.3.2 配置ip和域名的绑定关系

由于我们的nginx没有域名,为了演示,因此在本地host文件中配置nginx服务器ip和域名进行绑定。这个host文件的具体位置在C:\Windows\System32\drivers\etc 。在host文件中增加一句配置:

47.104.xxx.xxx www.javatrip.com

前面的ip是服务器的ip地址,后面的域名是随手起的用于绑定这个ip的一个域名。配置好之后,使用域名访问一下tomcat,如果能请求到tomcat默认页面,则配置成功。

nginx 反向代理 ip host not found in upstream nginx反向代理服务_html_21

3.3.3 在配置nginx配置请求转发

在默认的配置文件中做个修改:

server {
    listen       80;
    server_name  47.104.xxx.xxx;

    location / {
        root   html;
        proxy_pass http://127.0.0.1:8080;
        index  index.html index.htm;
    }
}

以上这段配置的意思,就是请求47.104.xxx.xxx:80,都会转发至47.104.xxx.xxx:8080 。
现在游览器访问javatrip.com ,发现直接转发到了tomcat上了,这样简单的反向代理就完成了。

四、nginx常用的命令

使用这些命令时,需要进入/usr/local/nginx/sbin 文件夹:

  • 查看nginx的版本号
在/usr/local/nginx/sbin 目录下执行 ./nginx -v
  • 启动nginx
在/usr/local/nginx/sbin 目录下执行 ./nginx
  • 关闭nginx
在/usr/local/nginx/sbin 目录下执行 ./nginx -s stop
  • 重新加载nginx
在/usr/local/nginx/sbin 目录下执行 ./nginx -s reload