Nginx

一、含义

  Nginx(发音同engine x)是一个 Web服务器,也可以用作反向代理,负载平衡器和 HTTP缓存。

  Nginx使用异步事件驱动的方法来处理请求。Nginx的模块化事件驱动架构可以在高负载下提供更可预测的性能。

  Nginx是一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势。与旧版本(<=2.2)的Apache不同,Nginx不采用每客户机一线程的设计模型,而是充分使用异步逻辑从而削减了上下文调度开销,所以并发服务能力更强。整体采用模块化设计,有丰富的模块库和第三方模块库,配置灵活。 在Linux操作系统下,Nginx使用epoll事件模型,得益于此,Nginx在Linux操作系统下效率相当高。同时Nginx在OpenBSD或FreeBSD操作系统上采用类似于epoll的高效事件模型kqueue。

二、安装

  在Ubuntu16.04下安装

sudo apt-get install nginx	

 三、虚拟主机

  虚拟主机使用的是特殊的软硬件技术,把一台运行在因特网上的服务器主机分成多台"虚拟"的主机,每台虚拟主机是一个独立的网站,具有独立的域名,具有完整的Intemet服务器功能(WWW、FTP、Email等)。同一台主机上的虚拟主机之间是完全独立的,在网站访问者看来,每一台虚拟主机和一台独立的主机是完全一样。
  总结:虚拟主机提供了在同一台服务器、同一个 Nginx 进程上运行多个网站的功能。

  Nginx可以配置多种类型的虚拟主机

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

四、基于域名的虚拟主机

1.Nginx的配置文件

  在 /etc/nginx/nginx.conf 目录下的配置文件的详细信息如下:

http {
    ......
    ##
    # Virtual Host Configs
    ##
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

  这表了在明默认情况下 nginx 会自动包含 /etc/nginx/conf.d/*.conf 和 /etc/nginx/sites-enabled/* 文件

2.启用站点和可用站点

  默认情况下,在 /etc/nginx/sites-enabled 下有一个默认站点,这个站点也就是 nginx 安装之后的默认站点:

$ cd /etc/nginx/sites-enabled
$ ls -l
total 0
lrwxrwxrwx 1 root root 34 Oct 6 02:19 default -> /etc/nginx/sites-available/default

  vim /etc/nginx/sites-available/default 可以看到如下内容:

server {
      listen 80 default_server;
      listen [::]:80 default_server;
      root /var/www/html;       index index.html index.htm index.nginx-debian.html;
      server_name _;       location / {         try_files $uri $uri/ =404;
      } }  

  在 /etc/nginx/sites-available/ 下建立站点的配置文件,这些站点就是所谓的"可用站点"。
  然后在 link 到/etc/nginx/sites-enabled 下开启站点,这些开启的站点就是所谓"启用站点"。
  通过建立链接来控制可用站点的启用。

五、实战

  创建虚拟主机 basiccloud.net  

  目标: http://basiccloud.net 和 http://www.basiccloud.net 应该都指向同一个虚拟主机。
  在 /etc/nginx/sites-available/ 下新建 basiccloud.net 文件,内容如下:

server {
	listen 80;
	server_name basiccloud.net www.basiccloud.net;
	root /var/www/basiccloud.net;
	index index.html;
}

  然后建立 /var/www/basiccloud.net 目录,准备好站点的html文件(项目代码)。

  将 basiccloud.net 站点文件链接到 /etc/nginx/sites-enabled/ 目录:

sudo ln -s /etc/nginx/sites-available/basiccloud.net /etc/nginx/sites-enabled/basiccloud.net

  配置完成之后,在重新转载前,先验证一下:

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

  验证通过,再重新装载:

sudo nginx -s reload 

 

  创建虚拟主机 dolphin.basiccloud.net
  目标: http://dolphin.basiccloud.net 应该指向另外一个虚拟主机。
  在 /etc/nginx/sites-available/ 下新建 dolphin.basiccloud.net 文件,内容如下:

server {
	listen 80;
	server_name dolphin.basiccloud.net;
	root /var/www/dolphin.basiccloud.net;
	index index.html;
}  

  然后建立 /var/www/dolphin.basiccloud.net 目录,准备好站点的html文件(项目代码)。
  将 dolphin.basiccloud.net 站点文件链接到 /etc/nginx/sites-enabled/ 目录:

sudo ln -s /etc/nginx/sites-available/dolphin.basiccloud.net /etc/nginx/sites-enabled/dolphin.basiccloud.net

  修改完成之后,使用命令检测配置修改结果并重新装载配置:

sudo nginx -t
sudo nginx -s reload

 六、实战二:域名免端口(反向代理)

  在实际使用中,由于web服务器启动于不同进程,因此需要指定不同的端口,也就意味着必然有web应用要使用80之外的端口,这样在地址栏中就必须出现端口号,非常影响用户体验。
  比较好的方式,通过使用不同的域名或者二级域名,然后通过nginx反向代理的方式转发请求给到实际负责处理的服务器。
    下面是这种方式的典型使用场景的例子:

 

  创建虚拟主机 git.basiccloud.net
  目标:http://git.basiccloud.net 应该指向当前机器上运行于 8800 端口的 gitlab 服务器。
  在 /etc/nginx/sites-available/ 下新建 git.basiccloud.net 文件,内容如下:

server {
	listen 80;
	server_name git.basiccloud.net;
	location /{
		proxy_pass http://127.0.0.1:8800;
	}
}

  将 git.basiccloud.net 站点文件链接到 /etc/nginx/sites-enabled/ 目录:

sudo ln -s /etc/nginx/sites-available/git.basiccloud.net /etc/nginx/sites-enabled/git.basiccloud.net

  修改完成之后,使用命令检测配置修改结果并重新装载配置:

sudo nginx -t
sudo nginx -s reload

   

  创建虚拟主机 maven.basiccloud.net
  目标:http://maven.basiccloud.net 应该指向当前机器上运行于 8081 端口的 artifactory 服务器。
  在 /etc/nginx/sites-available/ 下新建 maven.basiccloud.net 文件,内容如下:

server {
	listen 80;
	server_name maven.basiccloud.net;
	location /{
		proxy_pass http://127.0.0.1:8081;
	}
}

  将 maven.basiccloud.net 站点文件链接到 /etc/nginx/sites-enabled/ 目录:

sudo ln -s /etc/nginx/sites-available/maven.basiccloud.net /etc/nginx/sites-enabled/maven.basiccloud.net

七、HTTP配置 

  默认情况下,nginx已经自动开启了对client连接的keep alive支持。一般场景可以直接使用,
  但是对于一些比较特殊的场景,还是有必要调整个别参数。
  需要修改nginx的配置文件(在nginx安装目录下的conf/nginx.conf):

http {
	keepalive_timeout 120s 120s;
	keepalive_requests 10000;
}

  keepalive_timeout指令
  keepalive_timeout指令的语法:

Syntax: keepalive_timeout timeout [header_timeout];
Default: keepalive_timeout 75s;
Context: http, server, location 

  第一个参数设置keep-alive客户端连接在服务器端保持开启的超时值。值为0会禁用keep-alive客户端连接。
  可选的第二个参数在响应的header域中设置一个值“Keep-Alive: timeout=time”。
  这两个参数可以不一样

  注:默认75s一般情况下也够用,对于一些请求比较大的内部服务器通讯的场景,适当加大为120s或者300s。第二个参数通常可以不用设置。

 

  keepalive_requests指令
  keepalive_requests指令用于设置一个keep-alive连接上可以服务的请求的最大数量。当最大请求数量达到时,连接被关闭。默认是100。

    这个参数的真实含义,是指一个keep alive建立之后,nginx就会为这个连接设置一个计
数器,记录这个keep alive的长连接上已经接收并处理的客户端请求的数量。如果达到这
个参数设置的最大值时,则nginx会强行关闭这个长连接,逼迫客户端不得不重新建立新
的长连接。
    这个参数往往被大多数人忽略,因为大多数情况下当QPS(每秒请求数)不是很高时,默认
值100凑合够用。但是,对于一些QPS比较高(比如超过10000QPS,甚至达到
30000,50000甚至更高) 的场景,默认的100就显得太低。
    简单计算一下,QPS=10000时,客户端每秒发送10000个请求(通常建立有多个长连
接),每个连接只能最多跑100次请求,意味着平均每秒钟就会有100个长连接因此被
nginx关闭。同样意味着为了保持QPS,客户端不得不每秒中重新新建100个连接。因
此,如果用netstat命令看客户端机器,就会发现有大量的TIME_WAIT的socket连接(即使
此时keep alive已经在client和nginx之间生效)。
    因此对于QPS较高的场景,非常有必要加大这个参数,以避免出现大量连接被生成再抛
弃的情况,减少TIME_WAIT。
View Code

 

  保持和server的长连接
  为了让nginx和server(nginx称为upstream)之间保持长连接,典型设置如下:

http {
	upstream BACKEND {
		server 192.168.0.1:8080 weight=1 max_fails=2 fail_timeout=30s;
		server 192.168.0.2:8080 weight=1 max_fails=2 fail_timeout=30s;
		keepalive 300; // 这个很重要!
	}
	server {
		listen 8080 default_server;
		server_name "";
		location / {
			proxy_pass http://BACKEND;
			proxy_set_header Host $Host;
			proxy_set_header x-forwarded-for $remote_addr;
			proxy_set_header X-Real-IP $remote_addr;
			add_header Cache-Control no-store;
			add_header Pragma no-cache;
			proxy_http_version 1.1; // 这两个最好也设置
			proxy_set_header Connection "";
			client_max_body_size 3072k;
			client_body_buffer_size 128k;
		}
	}
}

  location设置
  location中有两个参数需要设置:

http {
	server {
		location / {
			proxy_http_version 1.1; // 这两个最好也设置
			proxy_set_header Connection "";
		}
	}
}

  HTTP协议中对长连接的支持是从1.1版本之后才有的,因此最好通过proxy_http_version指令设置为"1.1",而"Connection"header应该被清理。清理的意思,我的理解,是清理从client过来的httpheader,因为即使是client和nginx之间是短连接,nginx和upstream之间也是可以开启长连接的。这种情况下必须清理来自client请求中的"Connection" header。

   

# nginx uwsgi wsgi django关系:
# 第一步:nginx 是对外的服务接口,外部浏览器通过url访问nginx
# 第二步:nginx 接收到浏览器发送过来的http请求,将包进行解析,分析url,
#     如果是静态文件请求就直接访问用户给nginx配置的静态文件目录,直接返回用户请求的静态文件,
#    如果不是静态文件,而是一个动态的请求,那么nginx就将请求转发给uwsgi,uwsgi 接收到请求之后将包进行处理,
#    处理成wsgi可以接受的格式,并发给wsgi,wsgi 根据请求调用应用程序的某个文件,
#    某个文件的某个函数,最后处理完将返回值再次交给wsgi,wsgi将返回值进行打包,
#    打包成uwsgi能够接收的格式,uwsgi接收wsgi 发送的请求,并转发给nginx,nginx最终将返回值返回给浏览器。
# 第三步:要知道第一级的nginx并不是必须的,uwsgi完全可以完成整个的和浏览器交互的流程,但是要考虑到某些情况
#    1 安全问题,程序不能直接被浏览器访问到,而是通过nginx,nginx只开放某个接口,uwsgi本身是内网接口,这样运维人员在nginx上加上安全性的限制,可以达到保护程序的作用。

#    2负载均衡问题,一个uwsgi很可能不够用,即使开了多个work也是不行,毕竟一台机器的cpu和内存都是有限的,有了nginx做代理,一个nginx可以代理多台uwsgi完成uwsgi的负载均衡。

#    3静态文件问题,用django或是uwsgi这种东西来负责静态文件的处理是很浪费的行为,而且他们本身对文件的处理也不如nginx好,所以整个静态文件的处理都直接由nginx完成,静态文件的访问完全不去经过uwsgi以及其后面的东西。 
nginx uwsgi wsgi django关系

 

   Nginx、uwsgi、django关系

 

原文:Nginx的学习笔记

 

posted @ 2017-12-22 15:46  _慕  阅读(244)  评论(0编辑  收藏  举报
Title
返回顶部