web服务器之Nginx使用详解

timo-nbktp 1年前 ⋅ 1018 阅读

1 什么是Nginx

Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。

其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

NginxLighttpd一样,都是轻量级、高性能的Web服务器,欧美业界开发者比较钟爱 Lighttpd,国内的公司更青睐Nginx, Lighttpd在国内使用比较少。

2 Linux下搭建Nginx运行环境

可以参考另一篇博文,进行Nginx的基础环境搭建:

http://timoa.cn/post/140

3 Nginx运行中进程间的关系

Nginx服务启动后,会产生如下进程:

部署Nginx时都是使用一个master进程来管理多个worker 进程,一般情况下,worker进程的数量与服务器上的CPU核心数相等,每一个worker进程用来提供互联网服务master进程则只负责监控管理worker进程,当任意一个worker进程出现错误从而导致coredump时,master进程会立刻启动新的worker进程继续服务,另外master进程还为管理员提供命令行服务,包括诸如启动服务、停止服务、重载配置文件、平滑升级程序等操作

master进程完全接管多个worker进程不但可以提高服务的健壮性(一个worker进程出错后,其他worker进程仍然可以正常提供服务),最重要的是,这样可以充分利用现在多核CPU处理并发,另外要把worker进程数量设置得与CPU核心数量一致,这是Nginx与Apache服务器的不同之处。

在Apache上每个进程在一个时刻只处理一个请求,因此如果希望apache服务器拥有并发处理的请求数更多,就要把Apache的进程或线程数设置得更多,通常会达到一台服务器拥有几百个上千个工作进程,这样大量的进程间切换将带来无谓的系统资源消耗。

而Nginx一个worker进程可以同时处理的请求数只受限于内存大小,而且在架构设计上,不同的worker进程之间处理并发请求时几乎没有同步锁的限制,worker进程通常不会进入睡眠状态,因此当Nginx上的进程数与CPU核心数相等时,进程间切换的代价最小,因为,Nginx底层是采用c语言调用Linux内核epoll事件模型来实现的,这是一种多路复用IO模型

4 Nginx虚拟主机配置

4.1 什么是虚拟主机

虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主机,每个虚拟主机可以独立对外提供 www 服务,这样就可以实现一台主机对外提供多个 web 服务,每个虚拟主机之间是独立的,互不影响的。

简单来说,虚拟主机就是,一个nginx服务可以当做多台服务器去使用,可以部署多个web应用。

4.2 Nginx 配置文件的基础结构

# ...

events {
    # ...
}

http {
    # ...
    
    server{
        # ...
    }
    
    # ...
    
    server{
        # ...
    }
}

注:每个 server其实就是一个虚拟主机

4.3 基于Nginx实现虚拟主机的配置

通过 Nginx 可以实现虚拟主机的配置,Nginx 支持三种类型的虚拟主机配置:

  • 基于 IP 的虚拟主机
  • 基于域名的虚拟主机
  • 基于端口的虚拟主机

4.3.1 基于端口的虚拟主机配置(推荐使用)

创建/opt/www/smilehappiness/80目录、/opt/www/smilehappiness/81目录

/opt/www/smilehappiness/82目录、并在目录中,分别添加一个html页面,方便看到不同的效果。

笔者使用的html内容:

<!DOCTYPE html>
<html>
<head>
<title>this is 82 nginx</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to 82 nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

配置文件示例如下:

worker_processes  4;

events {
      worker_connections  65535;
}


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

    sendfile        on;

    keepalive_timeout  65;

    # 基于端口的虚拟主机配置-80端口	
    server {
	# 监听80端口
        listen       80;
        server_name  localhost;

	# 匹配,所有80端口下的/请求
        location / {
	    # 使用root指令,指定虚拟主机目录,即网页存放目录
	    # 比如说,访问http://ip:80即可访问到,/opt/www/smilehappiness/80这个目录下的html或者htm结尾的欢迎页面
            root /opt/www/smilehappiness/80;
	    # 指定欢迎页面,按从左到右顺序查找
            index index.html index.htm;
        }
		
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root html;
        }

    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    # 基于端口的虚拟主机配置-81端口	
    server {
	# 监听81端口
        listen       81;
        server_name  localhost;

        location / {
	    # 比如说,访问http://ip:81即可访问到,/opt/www/smilehappiness/81这个目录下的html或者htm结尾的欢迎页面
            root /opt/www/smilehappiness/81;
            index  index.html index.htm;
        }	
                                           
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

    # 基于端口的虚拟主机配置-82端口	
    server {
	# 监听82端口
        listen       82;
        server_name  localhost;

      	location / {
            root /opt/www/smilehappiness/82;
            index  index.html index.htm;
        } 
                                           
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

}

效果如下:

  • 基于80端口的虚拟主机

访问地址,可以看到如下界面: http://ip:80

  • 基于81端口的虚拟主机

访问地址,可以看到如下界面: http://ip:81

  • 基于82端口的虚拟主机

访问地址,可以看到如下界面: http://ip:82

这样,配置不同的server,每个server中,配置不同的端口号和页面映射路径,这样就完成了,基于端口号的Nginx虚拟主机

注意:如果你是用的是阿里云或者腾讯云等服务器,不要忘记开放防火墙端口,否则可能访问不到页面。

4.3.2 基于域名的虚拟主机配置(推荐使用)

两个域名指向同一台Nginx服务器,用户访问不同的域名显示不同的网页内容。这种方式在企业中其实也用的挺多的,公司一般会设置多个域名,这样根据不同的域名映射同一台Nginx服务器,可以实现不同网站的访问。

下边为了方便测试,修改了本地windows系统的hosts文件,实际项目开发中,公司都有自己的域名,不需要修改本地windows的这个hosts文件。

4.3.2.1 配置 Windows Hosts文件

修改 window 的 hosts 文件:(C:\Windows\System32\drivers\etc

通过修改host文件,指定admin.smilehappiness.cn和user.smilehappiness.cn对应同一个路径:http://ip:80

在hosts文件中,添加以下内容即可:

ip:80 admin.smilehappiness.cn
ip:80 user.smilehappiness.cn

4.3.2.2 配置 Nginx conf文件

创建/opt/www/smilehappiness/admin目录、/opt/www/smilehappiness/user目录并在目录中,分别添加一个html页面,方便看到不同的效果。

配置conf文件示例如下:

worker_processes  4;

events {
      worker_connections  65535;
}


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

    sendfile        on;

    keepalive_timeout  65;

    # 基于域名的虚拟主机配置
    server {
	# 监听80端口
        listen       80;
        server_name  admin.smilehappiness.cn;

        location / {
	    # 使用root指令,指定虚拟主机目录,即网页存放目录
	    # 比如说,访问http://ip:80即可访问到,/opt/www/smilehappiness/admin这个目录下的html或者htm结尾的欢迎页面
            root /opt/www/smilehappiness/admin;
	    # 指定欢迎页面,按从左到右顺序查找
            index index.html index.htm;
        }
		
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root html;
        }

    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    # 基于域名的虚拟主机配置
    server {
	# 监听80端口
        listen       80;
        server_name  user.smilehappiness.cn;

        location / {
	    # 使用root指令,指定虚拟主机目录,即网页存放目录
	    # 比如说,访问http://ip:80即可访问到,/opt/www/smilehappiness/user这个目录下的html或者htm结尾的欢迎页面
            root /opt/www/smilehappiness/user;
	    # 指定欢迎页面,按从左到右顺序查找
            index index.html index.htm;
        }
		
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root html;
        }

    }
 }

这样,就实现了相同的端口号,基于域名的虚拟主机。

4.3.3 基于IP的虚拟主机配置

Linux 操作系统允许添加 IP别名,IP别名就是在一块物理网卡上绑定多个lP地址。这样就能够在使用单一网卡的同一个服务器上运行多个基于IP的虚拟主机。

这种场景用的极少,这里不进行测试了,感兴趣的童鞋们,可以使用下文给出的虚拟主机配置的参考资料链接,进行设置。

5 基于Nginx部署静态网站

这个可以参考上一节中,虚拟主机的配置,以上的配置方式,就是使用root映射到静态资源路径/opt/www/smilehappiness下,读取index.html或者index.htm页面,当然,也可以把静态资源文件放到nginx

默认的静态页面路径/usr/local/nginx/html下,进行资源的访问。

6 基于Nginx实现负载均衡

6.1 什么是负载均衡

负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。

负载均衡构建在原有网络结构之上,它提供了一种透明且廉价有效的方法扩展服务器和网络设备的带宽、加强网络数据处理能力、增加吞吐量、提高网络的可用性和灵活性

6.2 Nginx实现负载均衡的策略

通过以上简单案例我们可以发现,Nginx的各种应用就是基于配置文件的,只需要对其进行配置即可完成,所以实现负载均衡也是对nginx.conf进行配置。

Nginx配置负载均衡需要两个步骤:

  • 配置一个upstream
  • 配置location里面的 proxy_pass

负载均衡大概有以下几种策略,下面逐步进行介绍。

6.2.1 轮询负载均衡策略(默认)

轮寻(round-robin),意思就是每一台机器访问一次,轮流去访问每一台机器

Default load balancing configuration:

http {
    upstream myapp1 {
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://myapp1;
        }
    }
}

以上这个示例,当没有配置负载均衡策略,或者手动配置了这种策略方式,就会采用轮询的负载均衡策略。这个例子中,配置了三个应用实例,当请求打到Nginx服务器上时,会轮训的去访问每一台应用实例,从而达到分流的效果。

6.2.2 最少连接数负载均衡策略

使用least_conn最小连接数负载均衡策略,简单理解,就是在某些请求需要更长时间才能完成的情况下,更公平地控制应用程序实例的负载。Nginx将尝试不会把过多的请求负载到繁忙的应用程序服务器上,而是将新请求分发到较不繁忙的服务器上。

如果使用这种策略,可以使用以下方式进行conf的配置:

http {
    upstream myapp1 {
        least_conn;
	    server srv1.example.com;
	    server srv2.example.com;
	    server srv3.example.com;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://myapp1;
        }
    }
}

6.2.3 权重负载均衡策略

使用轮询的负载均衡策略,是把请求均分到每一个应用实例上,而Weighted load balancing权重负载均衡策略,是把一些请求,分发到服务器资源较好的应用实例上。

如果使用这种策略,可以使用以下方式进行conf的配置:

http {
    upstream myapp1 {
       server srv1.example.com weight=5;
       server srv2.example.com weight=2;
       server srv3.example.com;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://myapp1;
        }
    }
}

以上方式,就是按照比例访问,下面的配置就是5:2:1。整体来看,请求srv1、srv2、srv3三台应用实例的比例大概是5:2:1

6.2.4 ip hash负载均衡策略

ip hash负载均衡策略,相当于一个用户绑定到了后台的一个具体的tomcat机器上,只要ip不变那么该用户就永远是访问后台的某一个固定的tomcat机器,可以用来快速解决session共享的问题,但此方案也存在一些不足,万一这台服务器宕机了,那么用户就不能访问了。

如果使用这种策略,可以使用以下方式进行conf的配置:

http {
    upstream myapp1 {
        ip_hash;
	    server srv1.example.com;
	    server srv2.example.com;
	    server srv3.example.com;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://myapp1;
        }
    }
}

6.2.5 另外几个配置参数说明

Nginx服务,有一个健康检查机制,以此来保证服务的最大可用性。

max_fails指令设置在faild失败期间与服务器通信的连续不成功尝试次数。默认情况下,max_fails设置为1。设置为0时,将禁用此服务器的运行状况检查。

fail_timeout参数还定义将服务器标记为failed的时间。服务器失败后的fail超时间隔之后,nginx将开始用实时客户端的请求优雅地探测服务器。如果探测成功,服务器将被标记为活动的。

upstream backserver { 
	# max_fails 最大的失败次数,失败次数超过该值,就不会负载到该机器
	# fail_timeout 最大失败次数后,再等多久可以再让该机器参与负载
	server srv1.example.com max_fails=3 fail_timeout=5;
	# 其它所有的非backup机器down的时候,才请求backup机器
	server srv2.example.com backup; 
	# down表示当前的server是down状态,不参与负载均衡
	server srv3.example.com down; 
} 

本文参考资料:
Nginx官方文档: http://nginx.org/en/docs/
负载均衡官方配置文档:http://nginx.org/en/docs/http/load_balancing.html
虚拟主机配置参考资料:https://www.jianshu.com/p/b164c001a555

 

--end--

 

 

版权 本着开源共享、共同学习的精神,本文转载自 https://blog.csdn.net/smilehappiness/article/details/106663708 , 如果侵权之处,请联系博主进行删除,谢谢~