Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点开发的,第一个公开版本0.1.0发布于2004年10月4日。Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强。
nginx有两种工作模式:master-worker模式和单进程模式。在master-worker模式下,有一个master进程和至少一个的worker进程,单进程模式顾名思义只有一个进程。这两种模式有各自的特点和适用场景。
user www www;
#程序运行用户和组
worker_processes auto;
#启动进程,指定nginx启动的工作进程数量,建议按照cpu数目来指定,一般等于cpu核心数目
error_log /home/wwwlogs/nginx_error.log crit;
#全局错误日志
pid /usr/local/nginx/logs/nginx.pid;
#主进程PID保存文件
worker_rlimit_nofile 51200;
#文件描述符数量
events
{
use epoll;
#使用epoll模型,对于2.6以上的内核,建议使用epoll模型以提高性能
worker_connections 51200;
#工作进程的最大连接数量
}
http{
#网站优化参数
server { #具体的某一网站的配置信息
listen 80;#监听端口
root html;#网页根目录(/usr/local/nginx/html)
server_name www.atguigu.com;#服务器域名
indexindex.html;#默认加载页面
access_log logs/access.log;#访问日志保存位置
location (.*)\.php$ {
#用正则匹配具体的访问对象;
}
location {
#跳转等规则;
}
}
server {
#虚拟主机;
}
}
<注意事项>
#pkill -HUPnginx
a、安装nginx时将–with-http_stub_status_module 模块开启
b、修改nginx配置文件(写入要访问的server标签中)
location /nginx_status{
stub_status on;
access_log off;
}
c、客户端访问网址:http://IP/nginx_status
"Active connections"表示当前的活动连接数;
"server accepts handled requests"表示已经处理的连接信息;
三个数字依次表示已处理的连接数、成功的TCP握手次数、已处理的请求数。
a、原理和apache的目录保护原理一样(利用上一个实验接着完成)
b、在状态统计的location中添加:
auth_basic "Welcome to nginx_status!";
auth_basic_user_file /usr/local/nginx/html/htpasswd.nginx;
c、使用http的命令htpasswd进行用户密码文件的创建(生成在上面指定的位置)
#htpasswd -c /usr/local/nginx/html/htpasswd.nginx user
d、重启nginx并再次访问统计页面
a、接着上一个实验完成操作
b、在状态统计的location中添加
allow 192.168.88.1;
deny 192.168.88.0/24;
仅允许192.168.88.1访问服务器
a、提前准备好两个网站的域名,并且规划好两个网站网页存放目录
b、在Nginx主配置文件中并列编写两个server标签,并分别写好各自信息
server{
listen 80;
server_name blog.atguigu.com;
index index.html index.htm index.php;
root html/blog;
access_log logs/blog-access.log main;
}
server{
listen 80;
server_name bbs.atguigu.com;
index index.html index.htm index.php;
root html/bbs;
access_log logs/bbs-access.log main;
}
c、分别访问两个不同的域名验证结果
代理和反向代理?
代理:找别人代替你去完成一件你完不成的事(代购),代理的对象是客户端
反向代理:替厂家卖东西的人就叫反向代理(烟酒代理),代理的对象是服务器端
a、在另外一台机器上安装apache,启动并填写测试页面
b、在nginx服务器的配置文件中添加(写在某一个网站的server标签内)
location / {
proxy_pass http://192.168.88.100:80;#此处填写apache服务器的IP地址
}
c、重启nginx,并使用客户端访问测试
负载均衡(Load Balance)其意思就是将任务分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
a、使用默认的rr轮训算法,修改nginx配置文件
upstream bbs { #此标签在server标签前添加
server 192.168.88.100:80;
server 192.168.88.200:80;
}
server {
........;
#修改自带的location / 的标签,将原内容删除,添加下列两项
location / {
proxy_pass http://bbs; #添加反向代理,代理地址填写upstream声明的名字
proxy_set_headerHost$host; #重写请求头部,保证网站所有页面都可访问成功
}
}
c、开启并设置两台88.100 & 88.200的主机
安装apache并设置不同的index.html页面内容(设置不同页面是为了看实验效果)
d、重启nginx,并使用客户端访问测试
拓展补充:rr算法实现加权轮询(后期集群再讲更多算法类型和功能)
upstream bbs{
server 192.168.88.100:80 weight=1;
server 192.168.88.200:80 weight=2;
}
a、安装nginx时,需要将–with-http_ssl_module 模块开启
b、在对应要进行加密的server标签中添加以下内容开启SSL
server {
.......;
ssl on;
ssl_certificate /usr/local/nginx/conf/ssl/atguigu.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/atguigu.key;
ssl_session_timeout 5m;ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
}
c、生成证书和秘钥文件
注意:在实验环境中可以用命令生成测试,在生产环境中必须要在https证书厂商注册
#openssl genrsa -out atguigu.key 1024
建立服务器私钥,生成RSA密钥
#openssl req -new -key atguigu.key -out atguigu.csr
需要依次输入国家,地区,组织,email。最重要的是有一个common name,可以写你的名字或者域名。如果为了
https申请,这个必须和域名吻合,否则会引发浏览器警报。生成的csr文件交给CA签名后形成服务端自己的证书
#openssl x509 -req -days 365 -sha256 -in atguigu.csr -signkey atguigu.key -out atguigu.crt
生成签字证书
#cp atguigu.crt /usr/local/nginx/conf/ssl/atguigu.crt
#cpatguigu.key /usr/local/nginx/conf/ssl/atguigu.key
将私钥和证书复制到指定位置
d、设置http自动跳转https功能
原有的server标签修改监听端口
server {
..........;
listen 443;
}
新增以下server标签(利用虚拟主机+rewrite的功能)
server{
listen 80;
server_name bbs.atguigu.com;
rewrite ^(.*)$ https://bbs.atguigu.compermanent;
root html;
index index.html index.htm;
}
e、重启nginx,并测试
user www www; #程序运行用户和组
worker_processes auto; #启动进程,指定nginx启动的工作进程数量,建议按照cpu数目来指定,一般等于cpu核心数目
error_log /home/wwwlogs/nginx_error.log crit; #全局错误日志
pid /usr/local/nginx/logs/nginx.pid; #主进程PID保存文件
worker_rlimit_nofile 51200; #文件描述符数量
events {
use epoll; #使用epoll模型,对于2.6以上的内核,建议使用epoll模型以提高性能
worker_connections 51200; #工作进程的最大连接数量,根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把cpu跑到100%就行每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为worker_processes*worker_connections,具体还要看服务器的硬件、带宽等。
}
http { #整体环境配置--网站配置
include mime.types;
default_type application/octet-stream; #设定mime类型,文件传送类型由mime.type文件定义
server_names_hash_bucket_size 128; #保存服务器名字的hash表大小
client_header_buffer_size 32k; #客户端请求头部缓冲区大小
large_client_header_buffers 4 32k; #最大客户端头缓冲大小
client_max_body_size 50m; #客户端最大上传文件大小(M)
sendfile on; #sendfile 指令指定nginx 是否调用sendfile 函数来输出文件,对于普通应用,必须设为on。如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的uptime.
tcp_nopush on; #这个是默认的,结果就是数据包不会马上传送出去,等到数据包最大时,一次性的传输出去,这样有助于解决网络堵塞。(只在sendfile on时有效)
keepalive_timeout 60; #连接超时时间
tcp_nodelay on; #禁用nagle算法,也即不缓存数据。有效解决网络阻塞
#fastcgi设置
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 256k;
gzip on;gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml application xml+rss;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
#limit_conn_zone $binary_remote_addr zone=perip:10m;
##If enable limit_conn_zone,add "limit_conn perip 10;" to server section.server_tokens off;
#隐藏nginx版本号(curl -I 192.168.4.154可以查看,更加安全)
#定义日志格式
#log format
log_format access '$remote_addr -$remote_user [$time_local] "$request"''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" $http_x_forwarded_for';
server {
listen 80 default_server;
#listen [::]:80 default_server ipv6only=on; #监听80端口,WEB服务的监听设置,可以采用"IP地址:端口"形式
server_name www.lnmp.org lnmp.org; #服务器名,可以写多个域名,用空格分隔
index index.html index.htm index.php;#默认网页文件
root /home/wwwroot/default;#网页主目录
#error_page 404 /404.html;
include enable-php.conf;
#开启status状态监测
location /nginx_status {
stub_status on;
access_log off;
}
#静态文件处理,保存期30天
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 30d;
}
#js和css文件处理,保存期12小时
location ~ .*\.(js|css)?$ {
expires 12h;
}
location~ /\. {
deny all;
}
#正确访问日志
access_log /home/wwwlogs/access.log access;
}
include vhost/*.conf; #vhost/下子配置文件生效
}
Nginx本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用Nginx来做服务器,如果一个网站只是静态页面的话,那么就可以通过这种方式来实现部署。
1、首先在文档根目录Docroot(/usr/local/var/www)下创建html目录, 然后在html中放一个index.html;
2、配置nginx.conf中的server
user mengday staff;
http {
server {
listen 80;
server_name localhost;
client_max_body_size 1024M;
# 默认location
location / {
root /usr/local/var/www/html;
index index.html index.htm;
}
}
}
3、访问测试
注意:如果访问图片出现403 Forbidden错误,可能是因为nginx.conf 的第一行user配置不对,默认是#user nobody;是注释的,linux下改成user root; macos下改成user 用户名 所在组; 然后重新加载配置文件或者重启,再试一下就可以了, 用户名可以通过who am i 命令来查看。
4、指令简介
5、location uri正则表达式
小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是\转义特殊字符。
在公司中经常会遇到静态服务器,通常会提供一个上传的功能,其他应用如果需要静态资源就从该静态服务器中获取。
1、在/usr/local/var/www 下分别创建images和img目录,分别在每个目录下放一张test.jpg
http {
server {
listen 80;
server_name localhost;
set $doc_root /usr/local/var/www;
# 默认location
location / {
root /usr/local/var/www/html;
index index.html index.htm;
}
location ^~ /images/ {
root $doc_root;
}
location ~* \.(gif|jpg|jpeg|png|bmp|ico|swf|css|js)$ {
root $doc_root/img;
}
}
}
自定义变量使用set指令,语法 set 变量名值;引用使用变量名值;引用使用变量名; 这里自定义了doc_root变量。
静态服务器location的映射一般有两种方式:
访问http://localhost/test.jpg 会映射到 $doc_root/img
访问http://localhost/images/test.jpg 当同一个路径满足多个location时,优先匹配优先级高的location,由于^~ 的优先级大于 ~, 所以会走/images/对应的location
常见的location路径映射路径有以下几种:
location优先级
当一个路径匹配多个location时究竟哪个location能匹配到时有优先级顺序的,而优先级的顺序于location值的表达式类型有关,和在配置文件中的先后顺序无关。相同类型的表达式,字符串长的会优先匹配。
以下是按优先级排列说明:
优先级搜索问题:不同类型的location映射决定是否继续向下搜索
location优先级从高到底:
(location =) > (location 完整路径) > (location ^~ 路径) > (location ,* 正则顺序) > (location 部分起始路径) > (/)
location = / {
# 精确匹配/,主机名后面不能带任何字符串 /
[ configuration A ]
}
location / {
# 匹配所有以 / 开头的请求。
# 但是如果有更长的同类型的表达式,则选择更长的表达式。
# 如果有正则表达式可以匹配,则优先匹配正则表达式。
[ configuration B ]
}
location /documents/ {
# 匹配所有以 /documents/ 开头的请求,匹配符合以后,还要继续往下搜索。
# 但是如果有更长的同类型的表达式,则选择更长的表达式。
# 如果有正则表达式可以匹配,则优先匹配正则表达式。
[ configuration C ]
}
location ^~ /images/ {
# 匹配所有以 /images/ 开头的表达式,如果匹配成功,则停止匹配查找,停止搜索。
# 所以,即便有符合的正则表达式location,也不会被使用
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配所有以 gif jpg jpeg结尾的请求。
# 但是 以 /images/开头的请求,将使用 Configuration D,D具有更高的优先级
[ configuration E ]
}
location /images/ {
# 字符匹配到 /images/,还会继续往下搜索
[ configuration F ]
}
location = /test.htm {
root /usr/local/var/www/htm;
index index.htm;
}
注意:location的优先级与location配置的位置无关
反向代理应该是Nginx使用最多的功能了,反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
简单来说就是真实的服务器不能直接被外部网络访问,所以需要一台代理服务器,而代理服务器能被外部网络访问的同时又跟真实服务器在同一个网络环境,当然也可能是同一台服务器,端口不同而已。
反向代理通过proxy_pass指令来实现。
启动一个Java Web项目,端口号为8081
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://localhost:8081;
proxy_set_header Host $host:$server_port;
# 设置用户ip地址
proxy_set_header X-Forwarded-For $remote_addr;
# 当请求服务器出错去寻找其他服务器
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
}
}
当我们访问localhost的时候,就相当于访问 localhost:8081了
负载均衡也是Nginx常用的一个功能,负载均衡其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
简单而言就是当有2台或以上服务器时,根据规则随机的将请求分发到指定的服务器上处理,负载均衡配置一般都需要同时配置反向代理,通过反向代理跳转到负载均衡。而Nginx目前支持自带3种负载均衡策略,还有2种常用的第三方策略。
负载均衡通过upstream指令来实现。
upstream web_servers {
server localhost:8081;
server localhost:8082;
}
server {
listen 80;
server_name localhost;
#access_log logs/host.access.log main;
location / {
proxy_pass http://web_servers;
# 必须指定Header Host
proxy_set_header Host $host:$server_port;
}
}
访问地址仍然可以获得响应 http://localhost/api/user/login?username=zhangsan&password=111111 ,这种方式是轮询的
upstream test {
server localhost:8081 weight=1;
server localhost:8082 weight=3;
server localhost:8083 weight=4 backup;
}
示例是4次请求只有一次被分配到8081上,其他3次分配到8082上。backup是指热备,只有当8081和8082都宕机的情况下才走8083
upstream test {
ip_hash;
server localhost:8080;
server localhost:8081;
}
upstream backend {
fair;
server localhost:8080;
server localhost:8081;
}
upstream backend {
hash $request_uri;
hash_method crc32;
server localhost:8080;
server localhost:8081;
}
以上5种负载均衡各自适用不同情况下使用,所以可以根据实际情况选择使用哪种策略模式,不过fair和url_hash需要安装第三方模块才能使用。
动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,这就是网站静态化处理的核心思路。
upstream web_servers {
server localhost:8081;
server localhost:8082;
}
server {
listen 80;
server_name localhost;
set $doc_root /usr/local/var/www;
location ~* \.(gif|jpg|jpeg|png|bmp|ico|swf|css|js)$ {
root $doc_root/img;
}
location / {
proxy_pass http://web_servers;
# 必须指定Header Host
proxy_set_header Host $host:$server_port;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root $doc_root;
}
}
location /permanently/moved/url {
return 301 http://www.example.com/moved/here;
}
location /users/ {
rewrite ^/users/(.*)$ /show?user=$1 break;
}
error_page 404 /404.html;
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 /usr/local/etc/nginx/logs/host.access.log main;
gzip on;
# 禁止访问某个目录
location ~* \.(txt|doc)${
root $doc_root;
deny all;
}