前言
本章大致说明一下在linux上使用Nginx,因为各方面的原因,只对单服务器的情况进行演示。有条件的可以进行多个服务器的测试。
学习知识就得从3w开始——what、why、how,即是什么,为什么用,怎么样。
原创不易,如需转载,请标明出处!谢谢!
什么是nginx
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。 ----百度百科
可以看出nginx的在国内的使用范围是很广的,各个大厂都在使用,他的特点也是非常明确。高性能、高并发、反向代理等。特别是支持高达 50,000 个并发连接数的响应。
Nginx的安装
Nginx的安装,这里就不再赘述,有兴趣的可以移步我的另一篇文章Nginx的安装,写的非常详细,按着步骤走就可以了,有什么问题可以留言。
因为nginx的优点,我们经常拿它做一下一些功能。
反向代理
有反向就有正向,在说反向代理之前,我们先说一下正向代理。
1. 正向代理
一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。 -----百度百科
一般的正向代理,任何可以连接到该代理服务器的软件,就可以通过代理访问任何的其他服务器,然后把数据返回给客户端,这里代理服务器只对客户端负责。
比如:一个用户想访问外网,是不能直接访问的,这时候,可以建立一个代理服务器(如VPN),告诉它要访问的外网地址,它就会给用户的客户端返回外网内容了。这里的代理服务器就是正向代理。
2. 反向代理
反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。反向代理服务器通常可用来作为Web加速,即使用反向代理作为Web服务器的前置机来降低网络和服务器的负载,提高访问效率。 -----百度百科
反向代理的话,如果他反向代理了两个服务,那么之后客户端访问这两个服务器的时候,该代理服务器才会给它代理,也就是说,这里的代理服务器只对该代理服务器所代理的服务器负责。
比如:反向代理服务器代理了两台服务器,用户想访问这两台服务器的内容,是不能直接访问的,对用户而言,它只知道反向代理的地址,必须通过反向代理服务器来进行访问。
总结
正向代理和反向代理都是位于客户端和服务器之间,但是正向代理是对客户端负责的,客户端可以发指令让它对任何服务器进行访问。而反向代理是对代理的服务器负责,对外不会暴露代理服务器地址。客户端以为代理服务器就是目标服务器。
反向代理示例一
场景:浏览器访问80端口的nginx,nginx代理8080端口的tomcat。
步骤:
1、确保tomcat的端口是8080端口,可以到tomcat的conf/server.xml中查看或修改。
2、进入nginx的配置文件conf/nginx.conf,在http的server中,lisen为nginx的端口,server_name为对外的IP,我们需要修改为自己的IP,location块中新增proxy_pass,表示代理的地址。写入tomcat的IP+端口。如下。然后保存并推出。
3、启动tomcat和nginx,这里不再赘述
4、在浏览器输入nginx设置的IP。按理说应该填写IP+80端口的,但是http的端口也是80,所有此处可以不写。看到如下界面,表示成功!
反向代理示例二(根据路径跳转不同的服务)
场景:浏览器访问9000端口的nginx,不过一个路径中有dev,一个路径中有pro,要求,dev的跳转8080tomcat,pro的跳转8081tomcat。
步骤:
1、准备两个tomcat,一个为8080端口,一个为8081端口
8080的tomcat的webapp中新建一个文件夹,dev,其中放置一个test.html,里面写着8080
8081的tomcat的webapp中新建一个文件夹,pro,其中放置一个test.html,里面写着8081
2、修改nginx的配置文件。将conf/nginx.conf文件打开,修改listen为9000,server_name为服务器IP,特别注意的是下面的location,~正则表达式表示路径中包含dev或者pro,注意两个/,proxy_pass 是转发的路径地址。如果有小伙伴不想创建上面的dev等文件夹,也可以在此处写全就好。
3、添加防火墙端口
先查看需要的9000端口是否打开
firewall-cmd --list-ports
如果没有就添加并重启防火墙
firewall-cmd --zone=public --add-port=9000/tcp --permanent
systemctl restart firewalld
4、启动tomcat和nginx
5、测试
成功!实际生产中,这些参数都是根据实际情况改变,两台tomcat也会变成多台并部署在不同服务器上,但是原理都是一样的。
负载均衡
负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。 -------百度百科
当nginx代理多台服务器时,客户端发来的请求,nginx会将它们根据自身配置,分发给不同的服务器处理,默认情况为轮询,也是可以修改的,大致分为如下几类
1、轮询(默认)
nginx收到请求后,会将请求依次分发给不同的服务器,几乎平均的方式,即1-2-3-1-2-3这样依次循环。
2、权重
我们可以给服务器设置权重,来提高它获取到请求的机会。权重越高,获取到请求的机会就越多。
有时候,我们服务器的配置不同,就可以用这种方式,给性能好的服务器更大的权重是最优解。
3、ip_hash
nginx按每个请求的ip的hash值进行分发。每个ip固定访问某台服务器。解决了session的问题。
4、最小连接法
nginx会将请求分发给连接数最少的服务器。
负载均衡的示例
场景:浏览器模拟用户发请求,看返回结果
1、轮询
1.1、准备两个tomcat,端口分别为8080和8081,在webapps中分别新建一个test文件夹,并放入一个test.html,html的内容分别为8080和8081
1.2、修改nginx.conf文件内容如下
proxyservers是我们随意定义的名称,不可加入_等符号
内容为server + ip + 端口
location是匹配路径中含有test的就转发到我们定义的proxyservers中,因为这什么都没设置,所有是轮询模式。
1.3、启动tomcat和nginx
1.4、在浏览器输入ip+端口+路径(http://ip:9000/test/test.html),测试结果
会发现8080和8081交替出现
2、权重
2.1 在轮询的基础上新增权重weight
2.2 重启nginx
2.3 测试
发现出现8080的概率大约是8081的一倍。
动静分离
这里的动静指的是动态资源和静态资源。
这有点类似于静态页面和动态页面,但也不完全一致,静态页面指的是不会与后台交互、页面总是不会改变的页面。(不会改变指的是打开多次都是一样的效果),静态资源则是生成这个页面说需要的一些资源,比如Html、Css、Js、图片等。动态页面则是会产生与后台的交互功能。可能每个人进来看到的页面都是不一样的。当动态页面向后台发送请求,返回的就是动态资源。这些资源会与数据库交互或者程序运算等。Tomcat对静态资源的加载并不是很高性能。因此,前后端分离,动静分离等概念是非常热门的。
nginx在做动静分离时是非常不错的。当请求过来时,它将动态资源通过某种规则转发给相应的动态资源服务器。如果是静态资源则会调用相应的资源进行响应。
动静分离示例
场景:当用户发送/photos/时显示图片,当用户发送/pages/时显示页面
步骤:
1、准备一个文件夹,里面再放两个文件夹,一个叫photos,一个叫pages,photo里放一张图片,pages里放一个html静态页面
2、准备一个tomcat,并启动,默认端口8080,当然也可以修改。
3、修改nginx配置文件。打开conf下的nginx.conf文件,如下修改
server块中
listen为nginx端口
server_name为nginx的ip地址
location / 是模拟接收动态资源,访问tomcat服务器。
location /pages/是获取页面,root是页面在服务器上的地址。
location /photos/是获取图片,autoindex可以不加,是用来显示一个资源页面的。
4、启动nginx
5、页面测试。输入nginx的ip+端口+路径可进行访问
如上表示操作成功!
nginx.conf分析
nginx.conf文件是在nginx/conf目录下
分析部分摘抄于https://blog.csdn.net/weixin_42167759/article/details/85049546,此篇文章讲的不错。
##代码块中的events、http、server、location、upstream等都是块配置项##
##块配置项可以嵌套。内层块直接继承外层快,例如:server块里的任意配置都是基于http块里的已有配置的##
##Nginx worker进程运行的用户及用户组
#语法:user username[groupname] 默认:user nobody nobody
#user用于设置master进程启动后,fork出的worker进程运行在那个用户和用户组下。当按照"user username;"设置时,用户组名与用户名相同。
#若用户在configure命令执行时,使用了参数--user=usergroup 和 --group=groupname,此时nginx.conf将使用参数中指定的用户和用户组。
#user nobody;
##Nginx worker进程个数:其数量直接影响性能。
#每个worker进程都是单线程的进程,他们会调用各个模块以实现多种多样的功能。如果这些模块不会出现阻塞式的调用,那么,有多少CPU内核就应该配置多少个进程,反之,有可能出现阻塞式调用,那么,需要配置稍多一些的worker进程。
worker_processes 1;
##ssl硬件加速。
#用户可以用OpneSSL提供的命令来查看是否有ssl硬件加速设备:openssl engine -t
#ssl_engine device;
##守护进程(daemon)。是脱离终端在后台允许的进程。它脱离终端是为了避免进程执行过程中的信息在任何终端上显示。这样一来,进程也不会被任何终端所产生的信息所打断。##
##关闭守护进程的模式,之所以提供这种模式,是为了放便跟踪调试nginx,毕竟用gdb调试进程时最繁琐的就是如何继续跟进fork出的子进程了。##
##如果用off关闭了master_proccess方式,就不会fork出worker子进程来处理请求,而是用master进程自身来处理请求
#daemon off; #查看是否以守护进程的方式运行Nginx 默认是on
#master_process off; #是否以master/worker方式工作 默认是on
##error日志的设置#
#语法: error_log /path/file level;
#默认: error_log / log/error.log error;
#当path/file 的值为 /dev/null时,这样就不会输出任何日志了,这也是关闭error日志的唯一手段;
#leve的取值范围是debug、info、notice、warn、error、crit、alert、emerg从左至右级别依次增大。
#当level的级别为error时,error、crit、alert、emerg级别的日志就都会输出。大于等于该级别会输出,小于该级别的不会输出。
#如果设定的日志级别是debug,则会输出所有的日志,这一数据量会很大,需要预先确保/path/file所在的磁盘有足够的磁盘空间。级别设定到debug,必须在configure时加入 --with-debug配置项。
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
##pid文件(master进程ID的pid文件存放路径)的路径
#pid logs/nginx.pid;
events {
#仅对指定的客户端输出debug级别的日志: 语法:debug_connection[IP|CIDR]
#这个设置项实际上属于事件类配置,因此必须放在events{……}中才会生效。它的值可以是IP地址或者是CIRD地址。
#debug_connection 10.224.66.14; #或是debug_connection 10.224.57.0/24
#这样,仅仅以上IP地址的请求才会输出debug级别的日志,其他请求仍然沿用error_log中配置的日志级别。
#注意:在使用debug_connection前,需确保在执行configure时已经加入了--with-debug参数,否则不会生效。
worker_connections 1024;
}
##核心转储(coredump):在Linux系统中,当进程发生错误或收到信号而终止时,系统会将进程执行时的内存内容(核心映像)写入一个文件(core文件),以作为调试只用,这就是所谓的核心转储(coredump).
http {
##嵌入其他配置文件 语法:include /path/file
#参数既可以是绝对路径也可以是相对路径(相对于Nginx的配置目录,即nginx.conf所在的目录)
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监听的端口
#语法:listen address:port [ default(deprecated in 0.8.21) | default_server | [ backlog=num | rcvbuf=size | sndbuf=size | accept_filter=filter | deferred | bind | ssl ] ]
#default_server: 如果没有设置这个参数,那么将会以在nginx.conf中找到的第一个server块作为默认server块
listen 8080;
#主机名称:其后可以跟多个主机名称,开始处理一个HTTP请求时,nginx会取出header头中的Host,与每个server中的server_name进行匹配,以此决定到底由那一个server来处理这个请求。有可能一个Host与多个server块中的server_name都匹配,这时会根据匹配优先级来选择实际处理的server块。server_name与Host的匹配优先级见文末。
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
#location / {
# root html;
# index index.html index.htm;
#}
##location 语法: location [=|~|~*|^~] /uri/ { ... }
# location的使用实例见文末。
#注意:location时有顺序的,当一个请求有可能匹配多个location时,实际上这个请求会被第一个location处理。
location / {
proxy_pass http://192.168.1.60;
}
#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;
# }
#}
}
server_name与Host的匹配优先级
首先选择所有字符串完全匹配的server_name 如:www.testwab.com
其次选择通配符在前面的server_name 如:.testwab.com
其次选择通配符在后面的server_name 如:www.testwab.
最后选择使用正在表达式才匹配的server_name 如:~^.testwab.com$
原创不易,如需转载,请标明出处!谢谢!