nginx使用入门
1、nginx(engine x):HTTP和反向代理服务器、邮件代理服务器、通用的TCP/UDP代理服务器。
2、安装(CentOS):yum install nginx.x86_64
3、nginx进程
nginx有一个master进程和几个worker进程。master进程的主要工作是读取和检查配置,并维护worker进程,而worker进程负责处理请求。nginx使用基于事件的模型和依赖于OS的机制,以有效地在worker进程中分发请求。
启动之后,可通过nginx -s signal来控制nginx,signal可取值stop(快速关闭)、quit(优雅关闭:等worker进程处理完请求再停止nginx进程)、reload(重新加载配置)和reopen(重新打开log文件)。
master进程收到reload的信号时,会检查语法并尝试应用新的配置。如果成功,master进程将启动新的worker进程并请求旧的worker进程退出(停止接受新的连接,并继续处理现有的请求直到完成);否则,master进程将回滚配置。
也可以借助Unix kill发信号给nginx进程。比如,给master进程(假设PID为1628)发送QUIT信号:kill -s QUIT 1628。
master进程的PID默认保存在nginx.pid(/usr/local/nginx/logs或/var/run目录)。
运行日志:/usr/local/nginx/logs或/var/log/nginx目录下的access.log和error.log。
4、配置文件
1)缺省情况下,配置文件为nginx.conf,位于/usr/local/nginx/conf或/etc/nginx或/usr/local/etc/nginx。
2)结构
nginx可包含多个模块,它们被指令(directive)所控制。指令分为简单指令和块指令。简单指令包含名字和参数,以;结束。块指令和简单指令结构相同,但它是以{}包含的一组指示(instruction)结束。若一个块指令在{}中包含其他指令,则称之为上下文(context),如events、http、server和location。
在任何上下文之外的指令即是在主上下文中,如events和http指令。
3)静态文件服务器
http {
server { # 监听80端口,通过http://localhost/访问
location / {
root /data/www; # 设置请求的根目录
}
location /images/ {
root /data;
}
}
}
http块中一般会包含几个server块(不同的端口和server_name)。
如上配置,则http://localhost/images/example.png请求的是/data/images/example.png,而http://localhost/some/example.html请求的是/data/www/some/example.html,也就是将匹配到的location块中root指令的参数加到请求的URI前面。
如果一个请求匹配到多个location块,nginx将选择最长前缀的那个。如上面第一个请求实际上也匹配到了第一个location块,但nginx会选择第二个location块。
4)代理服务器(在客户端和服务器之间作请求和应答的转发)
server { location / { proxy_pass http://localhost:8080/; # 把请求转发给实际的(被代理)服务器。参数:URL
# proxy_set_header field value; # 为请求头部重新定义或追加字段 } location ~ \.(gif|jpg|png)$ { # 匹配所有以.gif/.jpg/.png结尾的URI。正则表达式必须在前面加上~ root /data/images; } } server { # 实际的(被代理)服务器 listen 8080; root /data/up1; # 当location块没有自己的root指令时,使用该配置 location / { } }
若有多个location块匹配到,则优先选择带有正则表达式的location块,而不是最长前缀的location块。
5)FastCGI代理。FastCGI服务器:运行由多种框架和编程语言(如PHP)构建的应用。
除了静态图片请求外,将其他所有请求通过FastCGI协议路由到FastCGI服务器:
server { location / { fastcgi_pass localhost:9000; # 使用fastcgi_pass而不是proxy_pass fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # 该指令设置传递给FastCGI服务器的参数 fastcgi_param QUERY_STRING $query_string; # (PHP)SCRIPT_FILENAME指定脚本名,而QUERY_STRING用于传递请求参数 } location ~ \.(gif|jpg|png)$ { root /data/images; } }
6)HTTPS服务器
服务器证书是公开的,它会被发送到每个客户端,而私钥则保存在一个访问受限的文件中(对于nginx的master进程可读)。当然,它们也可保存在同一个(访问受限的)文件中。
(1)HTTPS服务器优化
SSL操作需要消耗额外的CPU。在一个多处理器系统中,应运行多个worker进程(不少于可用的CPU内核数)。最CPU密集型的操作是SSL的握手过程。有两个方法可以让每个客户端的这些操作达到最少:1)使用keepalive连接;2)重用SSL的session参数,以避免并行连接和后续连接的SSL握手过程。session可保存在SSL的session cache中。1MB的cache可保存大约4000个session。示例:
worker_processes auto; http { ssl_session_cache shared:SSL:10m; # 参数含义:"worker进程间共享:cache名字:cache大小" ssl_session_timeout 10m; # cache超时时间,默认为5分钟 server { listen 443 ssl; # (必须)指定ssl参数 server_name www.example.com; keepalive_timeout 70; ssl_certificate www.example.com.crt; # (必须)指定服务器证书位置 ssl_certificate_key www.example.com.key; # (必须)指定私钥文件位置 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # 限制连接使用的协议。这里的配置为默认值 ssl_ciphers HIGH:!aNULL:!MD5; # 限制连接使用的密码(cipher)。这里的配置为默认值 ...
7)HTTP负载均衡器
在多个应用实例间实现负载均衡是一个很常用的技巧,可以达到优化资源利用、最大化吞吐量、降低延迟和保证容错配置的效果。
nginx可以作为一个非常高效的HTTP负载均衡器:通过将流量分发到几个应用服务器,提高web应用的性能、可扩展性和可靠性。
nginx支持的负载均衡方式(method):round-robin(以循环方式将请求分发到各个应用服务器)、least-connected(将下一个请求分发到活跃连接数最小的服务器)、ip-hash(基于客户端IP的哈希值将请求分发到某个服务器)。
(1)默认的负载均衡配置
http { upstream myapp1 { # 不指定method时,取默认值round-robin server srv1.example.com; # 应用的3个实例分别运行在srv1/srv2/srv3 server srv2.example.com; server srv3.example.com; } server { listen 80; location / { # 所有请求都被代理转发至server组myapp1 proxy_pass http://myapp1; # 使用https协议,以配置HTTPS的负载均衡;使用fastcgi_pass以配置FastCGI的负载均衡等 } } }
(2)least-connected
当一些请求耗时较长时,least-connected能够保证各个应用实例上的负载更加均衡。nginx将尝试把请求分发给比较空闲的服务器。配置:
upstream myapp1 { # upstream定义一组服务器 least_conn; # 指定least-connected方式 server srv1.example.com; server srv2.example.com; server srv3.example.com; }
(3)会话持久性
在round-robin或least-connected方式下,同一个客户端的不同请求可能被导向到不同服务器。
如果需要把一个客户端“绑定”到某个特定的应用服务器,保持客户端会话的持久性,可以使用ip-hash方式。此时,客户端IP被用作哈希的key,以决定选择哪个服务器(除非该服务器不可用)来处理请求。
配置方面,使用ip_hash指令代替(2)中的least_conn即可。
(4)加权的负载均衡
使用服务器加权可以进一步影响负载均衡算法的结果。
upstream myapp1 { server srv1.example.com weight=3; # 每5个请求会以3:1:1的比例分配给srv1/srv2/srv3 server srv2.example.com; server srv3.example.com; }
8)WebSocket代理
为了将客户端和服务器之间的连接从HTTP/1.1切换到WebSocket,需要使用HTTP/1.1中的协议切换机制:
# http请求首部。服务器将协议切换成Upgrade首部所列的协议(响应报文的状态码为101)
Connection:Upgrade Upgrade:websocket
但有一个问题:Upgrade和Connection是逐跳首部(只能用于发送端所在的连接,转发到另一个连接时可能引起问题),不能从客户端传递到被代理服务器。为了让被代理服务器知道客户端想切换到WebSocket,必须显式传递这些首部:
location /chat/ { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; # 如Upgrade:websocket proxy_set_header Connection "upgrade"; }
9)其他配置项
(1)主上下文
# 指定worker进程数,可简单地设置为可用的CPU核心数(类似于auto) worker_processes number | auto; # 指定worker进程所能打开文件的最大数量(RLIMIT_NOFILE) worker_rlimit_nofile number;
(2)events上下文
# 指定一个worker进程能同时打开的最大连接数(包括所有连接,比如和被代理服务器的连接、和客户端的连接) worker_connections number; # 默认值为512
参考资料:
http://nginx.org/
不断学习中。。。