Nginx+Tomcat 动静分离实现负载均衡

0.前期准备

使用Debian环境。安装Nginx(默认安装),一个web项目,安装tomcat(默认安装)等。php

1.一份Nginx.conf配置文件

 

 

基本配置这个文件,就能够实现负载了。可是里面的各类关系要了解就比较麻烦了。这篇博客,也不是教学篇,是记录一下,方便之后本身看了。html

2.基础讲解

如今假使有一台电脑192.168.8.203这台电脑,上面部署了Tomcat,里面8080端口有J2EE的服务,经过浏览器能够正常浏览网页。如今有一个问题tomcat是一个比较全面的web容器,对静态网页的处理,应该是比较费资源的,特别是每次都要从磁盘读取静态页面,而后返回。前端

这中间会消耗Tomcat的资源,可能会使那些动态页面解析性能影响。秉承Linux哲学,一个软件只作一件事的原则。Tomcat就应该只处理JSP动态页面。这里就用到之前了解的Nginx来进行反向代理。第一步代理,实现动静网页分离。这个很简单的。nginx

 

修改nginx的配置文件 /etc/nginx/nginx.conf 默认有个配置文件的。其实大部分都差很少,关键仍是server段的设置。这里我设置server段如上所示,其余段复制就能够了。web

server段里面的解释以下:第35行为监听本机80端口。37-39行表示默认主页,这里的默认主页我是index.jsp 对应到我项目中是一个index。 这里根据须要能够改成redis

indexindex.jspindex.htmlindex.htmindex.phpsql

具体可参考其余文章。 关键的第40行,这个是正则匹配,网上也有不少介绍。这里匹配我项目中用到的全部静态网页后缀。第41行是代理地址。这里我代理到个人web应用中。expires 30d缓存为30天,这里的缓存是对应到前端页面,用户的Cache-Control字段浏览器

第44行中那个正则是匹配无后缀的页面。我项目中jsp页面是无后缀的。这里能够根据须要进行修改。一样代理到192.168.8.203:8080这里。到这里你可能会问,这有毛意思啊?固然不是这样了。简单的实现静动分离,咱们能够把第41行进行修改,改成缓存

root   /var/lib/tomcat7/webapps/JieLiERP/WEB-INFtomcat

表示不代理,直接从本地磁盘拿。经过查tomcat日志能够看到静态页面是没有访问到的。但这样又有一个问题。

这样的灵活性很差,对下面要讲到的内存缓存和集群部署来讲都是不友好的,因此又有了下面的这种写法。再写一个server段。

 

此次监听808端口,而后上上面的代码41行就能够修改成 proxy_pass http://192.168.8.203:808了,到这里就实现了动静分离了。若是多台服务器,就修改对应的ip就能够了。若是发现链接不上的,要检查一下防火墙,权限等外部问题,这个配置是这样的。

若是单纯这样的话,咱们会发现页面直接传输过于占用带宽。对应web的优化,这里想到的是经过对页面进行gzip压缩,而后传到用户那里,再解压,这样能够有效的减小带宽。这里就会用到Nginx 的gzip模块了。默认的Nginx是集成有gzip模块的。只需在http段增长下面配置便可。

 

给个首页看看效果

不要在乎请求数不同,那两个请求是谷歌插件来的。不用以为我在骗你。

做为假使有不少人访问的网站来讲,缓存确定是很重要的东西了。

一开始是想经过插件,让Nginx和Redis进行合成,而后Nginx使用Redis来缓存的,可是发现配置起来很麻烦,还要本身下载插件,从新编译Nginx,比较麻烦,因此这里以为用Nginx自带的缓存也是不错的选择。

虽然效率比不上redis,可是有仍是比没有好。Nginx默认的缓存是磁盘文件系统的缓存,而不是像Redis那样的内存级别的缓存。一开始我觉得Nginx就只有这样。后来查了写资料,才知道是我太天真了,对Linux不是很了解致使的。Linux的一切皆文件。

原来咱们能够把文件缓存到内存对应的Linux文件系统中。我说的可能比较难以理解,请自行搜索/dev/shm 这个文件目录。咱们把文件缓存到这个文件目录里,其实就至关与内存的缓存了。只不过仍是靠文件系统管理。因此比不上自定义格式的Redis那样的内存缓存。

在http段进行基本配置

 

 

通过这两个的配置就基本能实现了,这里说几个注意项,也是困扰我好久的问题。上面第一段代码第6行,proxy_ignore_headers 若是web项目中的html的head头里面指定

 

这些不缓存的话,就要加上proxy_ignore_headers的配置项了。还有一点就是/dev/shm下面的文件系统权限默认只给root用户,因此要chmod 777 -R /dev/shm 这样不是很安全的作法,若是实际上线能够给定某个用户组,关于用户组的设置是配置的第一行

userwww www;

上面第二段代码的第6行是增长一个header字段方便查看是否击中缓存。

咱们rm -rf /dev/shm/JieLiERP/proxy_* 下面的全部文件(注意这里若是是进行屡次测试的话要nginx -s reload 从新读取配置或重启服务,由于你rm -rf只是删除了缓存文件,可是缓存的结构信息还在nginx进程里面,结构还在,若是不重启的话,是会出现访问不到的)

因此要记得重启哦。下面是运行效果

第一次访问

第二次访问,在浏览器中Ctrl+Shift+R 强制刷新

到这里就能够看到效果了。咱们查看一下/dev/shm这个里面

到这里已经快结束了。最后也是比较关键的一个技术点,就是集群,集群,集群。这个就要用到upstream了,看到最开头的配置文件了吗,就是那个

 

 

上面那个就是集群组了。upstream是关键字,static 和 dynamic是两个服务器集群组的名称。以第一个为例,server 127.0.0.1:808 是服务器地址,后面的weight=1 是权重。有多个就写多个。

亲测试过,集群中的一个坏了,不影响系统运行。至于更多的轮询规则,能够参考网上更多的资料。这里很少说。至于怎么使用呢? proxy_pass 

http://192.168.8.203:808 改成 proxy_pass http://static; 这样便可实现均衡。

到这里就结束了。

把上面各个部分根据本身需求配置起来就能够实现单机房负载均衡了。 上面这种作法有一个缺点就是在前面的那一台nginx若是当机,后面因此机器就失去了被访问的能力了,因此须要在前面实现多个nginx多机房的负载。关于这个就是另一个话题了。目前尚未研究。之后有机会再说了。

上面动态服务器组若是是那种须要保存用户状态的话,会有问题,就是session问题,好比我在server1进行登陆后,下一次动态服务器组进行轮询后可能分配到server2,就会形成要从新登陆。

治标的办法是,配置轮询规则,根据用户请求的IP进行Hash,而后分配对应的服务器。具体配置以下:

 

这样就能够实现一个用户对应一个服务器节点。这样就不会有重复登陆的问题。另外一种治本的办法是,利用缓存系统进行session的统一存储管理。具体的作法我尚未试验过,参考资料有相关的文章,能够了解一下。

Nginx增长SSL功能,一样的Nginx默认是有SSL模块功能,咱们不用额外安装,只须要简单的配置就能够了。首先咱们先来生成一些必要的证书。制做的过程仍是比较简单的。

 

 

下面就是配置Nginx了,咱们能够把须要用到的client.pem, client.pem, client.key,unsecure这三个文件放到Nginx的一个目录下,剩下的Nginx配置以下:

 

重启Nginx,咱们就能够访问Https网站了。 可是他喵的出现这个

这个是没有什么问题,具体缘由是这个CA证书要获得承认。因此咱们上面本身生成的https证书,只是本身生成的,若是要变成下面这种,就须要花钱购买了,剩下的这个本身上网解决。

(虽然本身生成的证书能够用,可是仍是抵挡不了DNS欺骗,因此这种不安全证书,跟没有实际上是同样的。不过听说这样能够阻止运营商劫持。)

增长一个,就是在咱们输入http链接时自动跳转到安全的https链接。这个仍是比较实用的。方法仍是有多种的,具体能够看参考资料里面的博客。我是使用下面这一种,我以为是比较简单的,代码改动比较少的。就是对80端口进行代理转发。

 

为何某些人会一直比你优秀,是由于他自己就很优秀还一直在持续努力变得更优秀,而你是否是还在知足于现状心里在窃喜,

欢迎工做一到五年的Java工程师朋友们加入Java架构开发:744677563

群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用本身每一分每一秒的时间来学习提高本身,不要再用"没有时间“来掩饰本身思想上的懒惰!趁年轻,使劲拼,给将来的本身一个交代!

相关文章
相关标签/搜索