前言

能翻到这篇文章的朋友想必对Web服务器已经不陌生了,那么大家都用过哪些Web服务器服务器呢?
看过我SpringBoot系列文章的朋友,应该知道SpringBoot内置有三大服务器:Tomcat、Jetty、Undertow。
除了上面提到的,我在这里给大家列举了一些比较常见的Web服务器。

目前常见的Web服务器

- Apache(http://httpd.apache.org)
它是世界上用的最多的web服务器,市场占有率达60%左右,模块非常丰富,系统非常稳定,可移植性好,但是比较消耗资源

- Lighttpd(http://www.lighttpd.net)
它是德国人开发的一个开源软件,目标是提供一个高性能的网站,它具有内存开销低,cpu占用低,效能好及模块丰富,Nginx的重要竞争对手之一

- Tomcat(http://tomcat.apache.org)
是一个开源的软件,运行servlet+jsp web应用软件,对静态文件,高并发的处理能力弱。

- IBM websphere
它功能完善,开放的Web应用程序服务器,是IBM电子商务计划的核心部分,它是基于java的应用环境,范围从简单到高级到企业级应用,相于对其它web服务器来说应该比较少

- Microsoft IIS
Microsoft的web服务器产品为Internet information Server (IIS) IIS提供了图形界面管理工具,IIS是一种web服务器组件,其中有 web服务器,FTP服务器,nntp服务器,smtp服务器,因为有window2008和2012的支持,所以IIS也有一定的市场

根据 news.netcraft 上的统计,我们发现,目前(2019年)市面排名第一的并不是上面提到的任何一款Web服务器,而是我们今天的 “主角” Ngnix

什么是Nginx

其实我不介绍,大家应该都能猜的出来,Nginx是一款服务器了!度娘上是这么介绍Nginx的。

Nginx (engine x)
是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。
其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。
2011年6月1日,nginx1.0.4发布。 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

嗯… 战斗民族发明的玩意儿,那战斗力应该很强吧!光看这图标就很 “Rusia” ,Nginx 又名engine x,名如其意,它就是一个服务器引擎。那么到底是什么让这款服务器在这么多老牌企业的服务器中 “鹤立鸡群” 呢?

要想搞清楚这个问题,咱们还得从以上Nginx介绍中的关键词反向代理web服务器概念说起~

反向代理web服务器

说到反向代理,是不是有正向代理呢?没错,传统意义的代理都是属于正向代理,我在这里卖个关子,先讲讲什么是正向代理吧~

正向代理
举个很简单的生活中的栗子,大家应该都听说过 “翻墙” 吧!不是翻学校院墙的翻墙哈!
如果我想在国内使用FaceBook、Instagram,或者想访问Google,很显然是登不上的,这个时候,我就需要去某宝上面买VPN代理服务,或者说在国外用Shadowsocks来搭建一台代理服务器,让代理服务器帮我们请求www.google.com,代理再把请求响应结果再返回客户端。
既然国内的服务器连不上外网,那国外的服务器总该连的上吧!
这台代理服务器充当的就是正向代理的角色!可能这么说,大家还不是很明白,所以给大家画了一张图。很明显我们是知道请求资源的url地址的,只是说中间隔着一堵墙,所以访问不到,需要通过Proxy代理帮我们去访问,然后把消息回传给我们。

反向代理
理解了正向代理,我们再来看反向代理,在这之前,我先问大家一个问题,咱们平时访问www.baidu.com真的就是直接访问百度的某台提供Servlet服务的服务器么(比方说Tomcat)?

答案显然是否定的,怎么理解呢?比方说你想开个咖啡店,资金不够,然后去银行办理贷款,这个时候银行充当的就是反向代理角色,money充当的就是 “资源” 的角色。在此情形下,你是知道要办理贷款,是需要去哪个银行办理业务的,这就相当于你去访问百度的网页www.baidu.com,但是此刻你并不知道这钱到底是谁转入到银行的,当然这也不是你需要关注的点,就好比访问www.baidu.com之后,会返回给你一个页面,但是你并不知道这个资源是源自哪一台服务器?
因此反向代理隐藏了真实的服务端,当我们访问www.baidu.com的时候,背后可能有成千上万台服务器为我们服务,但具体是哪一台,你不知道,也不需要知道,你只需要知道反向代理服务器是谁就好了。www.baidu.com就是我们的反向代理服务器,反向代理服务器会帮我们把请求转发到提供真实服务的服务器那里去。而Nginx就是性能非常好的反向代理服务器,它可以用来做负载均衡

负载均衡

咱们上面又提到一个概念叫负载均衡,也许大家或多或少的听说过分布式集群的项目都需要通过负载均衡来分流,但是为什么需要这么做呢?
在还没有分布式概念的那个年代,我们做一个小项目可能就一台服务器支撑足矣!毕竟电脑都还没完全普及,访问量可以说很少了,但是随着网站的访问量越来越大,服务器的服务模式也得进行相应的升级,比如分离出数据库服务器、分离出图片作为单独服务,这些是简单的数据的负载均衡,将压力分散到不同的机器上。有时候来自web前端的压力,也能让人十分头痛。那么怎样将同一个域名的访问分散到两台或更多的机器上呢?这其实就是另一种负载均衡了,nginx自身就可以做到,只需要做个简单的配置就行。

Nginx 不单可以作为强大的web服务器,也可以作为一个反向代理服务器,而且nginx还可以按照调度规则实现动态、静态页面的分离,可以按照轮询、ip哈希、URL哈希、权重等多种方式对后端服务器做负载均衡,同时还支持后端服务器的健康检查。目前Nginx 的upstream支持 4 种方式的分配。

  • 轮询(默认)
    每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

  • weight
    指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 (比方说性能较好的服务器,我们可以把weight设高,性能差的可以把weight设低,那么对应的可以合理的减少性能差的服务器的压力)

  • ip_hash
    每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

  • fair(第三方)
    按后端服务器的响应时间来分配请求,响应时间短的优先分配。

简单来说就是当一台汤姆猫(Tomcat)承受不了它这个 “年纪” 该承受的压力的时候,它的上级领导Nginx就会想办法多找几个人分担它的工作,注意了,并不是客户端一连接上,Ngnix就会分配任务给汤姆猫处理,比如说我们访问一个静态的页面(一个网站的主页 ),那么这种情况下,Ngnix就不会将请求分配给Tomcat,原因是Ngnix本身是可以存储静态资源的,这个我们后面会讲到,只有当客户访问某个资源的时候,好比说在度娘上搜索 “Marco的Java系列博文” (PS:hahaha,王婆卖瓜,自卖自夸…) ,这个时候Ngnix就会下发指令给空闲的Tomcat,注意这个点,是空闲的Tomcat!

其实负载均衡并不是Nginx独有的,传统意义上负载均衡也就是多加几台Tomcat,一旦请求过来之后,所有的服务器都被 “惊醒”(这就是所谓的 “惊群” 现象 ),然后争相去处理请求(就好像你半夜睡的好好的,上级打电话来 “出Bug啦!快来公司加班!”,难受… 但还是得爬去公司),那么当一个服务器抢到了请求,处理并返回了响应,就好比老板叫来公司的一共有三个人,但是有个同事住的近,一来就把Bug处理了,然后等你来了之后发现,问题已经解决了,虽然心里千万只草泥马奔腾,但是还是笑一笑,回家睡觉。
那么同样,另外两台服务器无缘无故被 “惊醒” ,但是什么事儿都没错,无形之中就浪费了很多资源。因此Ngnix的负载均衡就是为了让每一台服务器的利用率最大化。

以上仅是对Ngnix基本流程和结构的分析,如果想了解更多关于Ngnix原理的内容,可以参见博文
理解Nginx工作原理


负载均衡配置

理论总归是枯燥乏味的,所以我就直接给大家演示一下实战效果啦!

准备三个tomcat

如何解压tomcat之前在 Marco’s Java【SpringBoot番外篇 之 如何让SpringBoot项目在Linux上跑起来!】中讲过,我就不赘述啦,之前解压过后的文件夹名称为apache-tomcat-7.0.90,名字太长啦,所以咱换个好记的,大家可以按照我下面的步骤操作。
需要注意的是tomcat2和tomcat3的端口号都需要修改,需要修改的配置文件在tomcat的conf目录下的server.xml,打开server.xml后从上往下依次按照我下面列出来的数值进行修改(比如tomcat2的server.xml中从上往下依次将没有被注释的port修改为8015 8090 8453 8019 8453)。

#把原来的tomcat的文件名改成下面的tomcat1
mv apache-tomcat-7.0.90 tomcat1
#复制两个tomcat
cp -r tomcat1  tomcat2/
cp -r tomcat1  tomcat3/
​
#修改端口号,文件为server.xml
tomcat1 8005 8080 8443 8009 8443  保持默认
tomcat2 8015 8090 8453 8019 8453
tomcat3 8025 8100 8463 8029 8463
​
#修改三个tomcat里面的webapps里面页面。让其有点区别【这里不做代码展示,自行去改】
启动三个tomcat

通过以下命令启动tomcat,注意文件夹的路径区分。

cd tomcat1/bin
./startup
cd tomcat2/bin
./startup
cd tomcat3/bin
./startup

启动之后我们使用命令ps -ef|grep tomcat可以查看三台服务器是否全部启动完毕,效果如下。

完成这三步操作之后,咱们来试试看用不同的端口访问相同的项目。使用Google分别打开三个标签页面,依次输入项目的访问路径
http://192.168.144.129:8080/carrent_plus
http://192.168.144.129:8090/carrent_plus
http://192.168.144.129:8100/carrent_plus/



均成功登录!大家注意看我们网页的title,区分了不同的tomcat!

配置nginx服务器

好啦,重头戏来了,开启了三台汤姆猫之后,我们就要想办法把他们 “结合成一个” ,当然,这里所谓的 “一个” 只是外界看到的一种假象!实质上是有三台服务器在运转的。
关于nginx服务器下载安装大家可以参考之前的安装教程 Marco’s Java【Ngnix入门(一) 之Nginx下载安装】
在编写我们的配置之前,大家先初步认识一下nginx的配置文件吧!

#user administrator administrators;  #配置用户或者组,默认为nobody nobody。
#worker_processes 2;  #允许生成的进程数,默认为1
#pid /nginx/pid/nginx.pid;   #指定nginx进程运行文件存放地址
#error_log log/error.log debug; #制定日志路径级别 这个设置可以放入全局块 http块 server块
#log的级别依次为:debug|info|notice|warn|error|crit|alert|emerg
events {accept_mutex on;   #设置网路连接序列化,防止惊群现象发生,默认为onmulti_accept on;  #设置一个进程是否同时接受多个网络连接,默认为off#use epoll;      #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventportworker_connections  1024;    #最大连接数,默认为512
}
http {include       mime.types;   #文件扩展名与文件类型映射表default_type  application/octet-stream; #默认文件类型,默认为text/plain#access_log off; #取消服务日志    log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式access_log log/access.log myFormat;  #combined为日志格式的默认值sendfile on;   #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。sendfile_max_chunk 100k;  #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。keepalive_timeout 65;  #连接超时时间,默认为75s,可以在http,server,location块。#server节点上加入以下配置#down 表示当前的server暂时不参与负载#weight 默认为1.weight越大,负载的权重就越大,那么该服务器被访问到的几率就越大#max_fails 允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误#fail_timeout max_fails次失败后,暂停的时间。#backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。upstream servername{   server 192.168.144.129:8080;server 192.168.144.129:8090 backup;  #热备}error_page 404; #错误页server {keepalive_requests 120; #单连接请求上限次数。listen       4545;   #监听端口server_name  accessname;   #监听地址,配置访问的域名(如www.marco.com)      location  ~*^.+$ {       #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。#root path;  #根目录#index vv.txt;  #设置默认页proxy_pass  servername;  #指向上面配置的server的节点,servername要保持一致deny 127.0.0.1;  #拒绝的ipallow 172.18.5.54; #允许的ip           } }
}

了解了nginx的基本配置及其所对应的解释之后,咱们就来着手修改它的配置文件。

#打开/usr/nginx
cd /usr/nginx
#打开conf配置目录
cd conf
#备份里面的nginx.conf[防止改错]
cp -r nginx.conf nginxbak.confbak
#编辑里面的nginx.conf
vi nginx.conf
​
​
#在server节点上加入以下配置
upstream www.marco.com {server 192.168.144.129:8080;server 192.168.144.129:8090;server 192.168.144.129:8100;#ip_hash;这是是用来解决登陆的session的问题
}#修改location的配置server {listen  80;server_name  www.marco.com;#配置访问的域名,并且在同一个配置文件中的server_name不能重复location / {# root   html;# index  index.html index.htm;proxy_pass http://www.marco.com; #指向上面配置的server的节点}
}
启动Nginx并访问

完成以上的配置之后,咱们来启动nginx

输入ps -ef|grep nginx可查看ngnix是否启动成功,启动没问题之后,咱们接着访问http://192.168.144.129/carrent_plus

访问http://192.168.144.129/carrent_plus第一次

访问http://192.168.144.129/carrent_plus第二次

访问http://192.168.144.129/carrent_plus第三次

欸?大家有没有发现,咱们每次刷新页面,我们login页面的title就会轮流的切换?回过头来再看咱们上面提到的负载均衡中轮询这个概念,结合上面的场景,相信大家应该已经知道它是啥意思了。

轮询(默认): 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

使用轮询有个很大的缺陷,怎么说呢… 我来为大家演示一下,大家应该就能懂了,我这边还是先执行登录

我们会发现,一直在登陆中,其实也就是登录失败,当然这不是咱们账号密码或者验证码输错的问题啦

为了演示这个错误,我这里还是画图举例,假设我们第一次请求被Ngnix分发给了Tomcat1,那么此时Tomcat1的session中就有了用户的信息,但是我们的主页中可能会存在从session作用域中获取用户信息的操作,那么这个请求可能会被分发给Tomcat2,很显然,只有Tomcat1的session中才有user的信息,如果想去Tomcat2的session中获取用户信息,显然是不可行的。

因此为了解决这个问题,我们就要使用到负载均衡中提到了另外一个概念ip_hash,它本身是通过Hash算法来转化并区分客户的url的请求,同一个IP地址(这里指的是客户PC端的IP) 请求同一个url地址,那么Nginx就会将这个请求分发给同一个Tomcat,不会分配给其他的服务器去执行请求

ip_hash 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

那么说了这么多,该如何配置呢?修改之前的nginx.conf文件中的upstream加上 ip_hash就OK啦

#在server节点上加入以下配置
upstream www.marco.com {server 192.168.144.129:8080;server 192.168.144.129:8090;server 192.168.144.129:8100;ip_hash; #这是是用来解决登陆的session的问题
}

此时不管我们怎么刷新,页面的title都不会改变,大家可以试试哦!

Marco's Java【Ngnix入门(二) 之反向代理及负载均衡】相关推荐

  1. Nginx入门简介和反向代理、负载均衡、动静分离理解

    场景 Nginx简介 Nginx ("engine x")是一个高性能的 HTTP 和反向代理服务器 特点是占有内存少,并发能力强,事实上 nginx 的并发能力确实在同类型的网页 ...

  2. nginx 转发慢_Nginx快速入门之Nginx反向代理与负载均衡

    知乎视频​www.zhihu.com 概念 什么是反向代理其与正向代理有什么区别? 正向代理是指客户端与目标服务器之间增加一个代理服务器,客户端直接访问代理服务器,在由代理服务器访问目标服务器并返回客 ...

  3. Nginx入门教程-简介、安装、反向代理、负载均衡、动静分离使用实例

    场景 Nginx入门简介和反向代理.负载均衡.动静分离理解 https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/102790862 Ub ...

  4. Nginx简单入门与反向代理和负载均衡

    什么是Nginx   Nginx 是一款高性能的 http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器.由俄罗斯的程序设计师伊戈尔•西索夫(Igor Sysoev)所开发,官方测 ...

  5. Nginx反向代理与负载均衡应用实践(二)

    Nginx反向代理与负载均衡应用实践(二) 链接:https://pan.baidu.com/s/1xB20bnuanh0Avs4kwRpSXQ 提取码:migq 复制这段内容后打开百度网盘手机App ...

  6. 利用Haproxy实现http和TCP反向代理和负载均衡(入门和技术验证)

    系统访问量上去遇到了性能瓶颈,解决方法一般都是从两个方向入手Scale Up 和Scale Out.Scale Up适用于哪些钱多的系统,因为Scale Up其实就是直接升级硬件,CPU.内存.IO哪 ...

  7. nginx一篇入门:安装、静态网站部署、反向代理、负载均衡

    前言: 本文章的nginx和tomcat是在Linux中,使用docker来安装和讲解 本人刚学完nginx,如有不对地方,欢迎指正 目录 ⼀.Nginx的安装与启动 1.什么是Nginx Nginx ...

  8. Nginx反向代理与负载均衡等配置文件示例

    Nginx反向代理于负载均衡等配置文件示例 Nginx.conf配置文件 worker_processes 8;events {worker_connections 1024; }http {incl ...

  9. Nginx之反向代理与负载均衡实现动静分离实战

    Nginx之反向代理与负载均衡实现动静分离实战 什么是反向代理与负载均衡 Nginx仅仅作为Nginx  proxy反向代理使用的,因为这个反向代理功能表现的效果是负载均衡集群的效果. 负载均衡指的是 ...

最新文章

  1. [转]android selector 背景选择器
  2. [shiro] - 怎样使用shiro?
  3. 服务器网站数据库如何保存,服务器怎么保存数据库
  4. 华为、阿里员工在听的英语资源,即将过期,请自取
  5. linux免密登录_Linux SSH免密钥登录总结
  6. linux执行sh提示非标准环境,Linux执行.sh文件时提示No such file or directory该怎么办(三种解决办法)...
  7. android显示圆圈动画,Android实现3个圆圈的动画
  8. sum 去重_总结leetcode上【排列问题】【组合问题】【子集问题】回溯算法去重的两种写法!...
  9. Android中Java与web通信
  10. 镜像资源的使用:100倍速度提升不是梦!
  11. MATLAB 均值估计函数normfit
  12. 英语语法长难句——并列句
  13. [BZOJ]5068: 友好的生物 放缩
  14. 考研英语词汇(部分)快速记忆
  15. Android Wi-Fi Display(Miracast)介绍
  16. 手把手教你使用Keras进行人脸检测和识别
  17. 维基百科图片无法正常显示
  18. Dijkstra——最短路径路由算法java实现
  19. MySql 函数大全
  20. jitpack.io 无法访问或下载依赖库

热门文章

  1. 思科抓包分析三层路由
  2. c1灯光语言,汽车灯光使用大全与常用灯光语言
  3. 和AWS云游四海@越来越国际化的“萤石”
  4. Vue 学习06——Vue父子组件通信、非父子组件通信1
  5. pageadminCMS 站点的添加和管理
  6. 计算机应用基础考试高起专,计算机应用基础试题(高起专)
  7. /etc/hosts 和 hostname 详解
  8. cba篮球暂停次数和时间_一场篮球比赛可以叫多少次暂停?
  9. 深入浅出JavaScript-老杜JavaScript基础教程全套完整版+老杨JS应用篇
  10. 用Turtle实现狗追兔子的建模仿真