Nginx服务器如何搭建做到负载均衡?

投稿人/来源:程序员食堂 | 2018-10-26 14:06:29 |

1.什么是Nginx?

Nginx也是一款服务器,我们常用它做:如反向代理、负载均衡、动态与静态资源的分离的工作。

反向代理:相对应的是正向代理,如果你使用过代理服务器的话就明白,我们访问某一个网站并非直接访问目标网站,而是告诉代理服务器我需要访问什么目标网站,由代理服务器发出请求给目标网站,将目标网站访问结果再转发给你,此时,你是请求代理方。而反向代理是此时代理服务器做服务器的代理,我们的访问请求并非直接访问到目标服务器上,而是访问代理服务器,由代理服务器决定什么样的请求以什么样的方式访问正式服务器。

负载均衡:目前大多数的网站都会采用负载均衡手段来针对目前用户的指数级增长来减少对单点服务器的负载压力,比如目前我们拥有3台真实服务器,我们需要根据相应策略决定什么样的用户请求分配到哪个真实服务器,比如按照轮询的方式,用户请求挨个到达代理服务器,此时代理服务器按照第一个请求转发至第一台真实服务器,第二个请求转发到第二个服务器上,依次类推,这样可以防止大量的用户请求全部访问到同一台物理机上,单点物理机的性能始终有限的,当然这可能对服务器数据访问时候造成事务性的失效,在Web方面可能造成Session访问的问题,这不在本文讨论方面内。

动态静态资源分离:最方便列举就是Java的JSP和静态资源如:.js/.css/.html/.png方面的资源分离,之前开发web方面的程序时候我们习惯将html、css等资源文件也放置于Tomcat之中,用户访问后tomcat需要将请求的这些静态资源文件一并返回给用户,再者如果有多台同业务逻辑的tomcat服务器的话,同样的资源还需要在每个服务器上放一份,同时也增加了tomcat服务器的网络IO,十分不合算的,如果我们只讲JSP之类的请求交给tomcat,而代理服务器上存放静态资源,当用户的请求非动态资源的时候,我们完全可以将代理服务器的静态资源直接返回给用户,而不去增大Tomcat的压力,tomcat只需要负责逻辑处理和动态资源的加载就可以了。

基于上述的Nginx优势,决定搭建一下Nginx+Tomcat的组合来进行测试,包括参数传递,post、get传递参数是否有影响,还有Nginx的工作模式master和worker的工作方式进行一些浅薄的总结。如有错误,恳请大家指出。

2.Nginx的安装问题?

安装部分这里就不在细说了,网上的教程很多,我们直接从配置文件开始吧

3.配置文件

总结

#usernobody;#这里是核心worker数,一般设置为与cpu核心数相同的数目,避免进程切换造成的上下文切换耗费资源,cpu信息可以从/proc/cpuinfo中查看worker_processes1;#error_loglogs/error.log;#error_loglogs/error.lognotice;#error_loglogs/error.loginfo;#pidlogs/nginx.pid;events{#useepollmodel使用epoll模型,采用异步非阻塞模型加快处理速度useepoll;worker_connections1024;}http{includemime.types;default_typeapplication/octet-stream;#log_formatmain'$remote_addr-$remote_user[$time_local]"$request"'#'$status$body_bytes_sent"$http_referer"'#'"$http_user_agent""$http_x_forwarded_for"';#access_loglogs/access.logmain;#设定通过nginx上传文件的大小client_max_body_size300m;#使用sendfile函数在两个文件描述符之间直接传递数据(完全在内核中操作,传送),从而避免了内核缓冲区数据和用户缓冲区数据之间的拷贝,操作效率很高,被称之为零拷贝。sendfileon;#tcp_nopushon;#keepalive_timeout0;#连接活跃时间keepalive_timeout65;#使用压缩数据减少IO量,但是在不支持数据解压浏览器可能产生乱码#gzipon;#静态服务器组#设定静态资源服务器访问接口upstreamstatic.zh-jieli.com{serverlocalhost:808weight=1;}#动态服务器组upstreamzh-jieli.com{#设置Hash轮询规则#ip_hash;#weight:serverip:portweight=10#默认轮询#fair:按照后端服务器的响应时间来分配#url_hash:按照url规则进行分配,使得固定的请求分配到固定的服务器上serverlocalhost:8080;serverlocalhost:8081;}server{listen808;server_namestatic;location/{}location~.*.(js|css|ico|png|jpg|eot|svg|ttf|woff){#所有静态文件直接读取硬盘内容:读取的静态资源存放位置root/apache-tomcat-8.5.24/webapps/ROOT;#资源是否进行缓存与缓存时间expires30d;#缓存30天}}server{listen80;server_namelocalhost;#charsetkoi8-r;#access_loglogs/host.access.logmain;location/{roothtml;indexindex1.htmlindex.htm;}location~.*.(js|css|ico|png|jpg|eot|svg|ttf|woff){#proxy_cachecache_one;proxy_cache_valid2003043025d;proxy_cache_validany5d;proxy_cache_key'$host:$server_port$request_uri';add_headerX-Cache'$upstream_cache_statusfrom$host';proxy_passhttp://static.zh-jieli.com;#所有静态文件直接读取硬盘root/apache-tomcat-8.5.24/webapps/ROOT;expires30d;#缓存30天}#其他页面反向代理到tomcat容器location^~/tomcat{indexindex;#proxy_passhttp://localhost:8080/;#设定代理服务器组proxy_passhttp://zh-jieli.com/;}error_page500502503504/50x.html;location=/50x.html{roothtml;}}}

整个nginx工作时当http请求到来时,由nginx针对nginx.conf配置好的规则,对location进行正则匹配,匹配到相应的正则,进行location内部的处理 关于Nginx的location配置附上一篇博客,很nice http://seanlook.com/2015/05/17/nginx-location-rewrite/

里面很详细列出了各种要求的location匹配规则,

值得注意的一点是: location匹配遵循最长原则,即满足了之前的匹配规则后,除了遇见^会终止向下继续匹配,其他情况会依次向下搜索,知道找到合适的location匹配规则然后进行处理 Nginx在模块功能上分三个模块:

Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。

Filters (过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。

Proxies (代理类模块)。此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。 因为是测试,所以我的两个tomcat都安装到了同一台本地机器上 生产环境中根据需要进行配置相应的IP就好了 本地写好相应的测试代码+log4j将信息日志打到相应的位置用来观察参数是否传递过来。

TestOne.java

Log4jUtils.java

packagecom.nginx.controllers;importcom.nginx.utils.Log4jUtils;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestParam;@Controller@RequestMapping("/test")publicclassTestOne{@RequestMapping("/getname")publicvoidtest(@RequestParam(value="name")Stringname){//用来记录获取的参数name,可以通过查看日志进行确认Log4jUtils.getLogger().info("mynameis"+name);}}

demo

packagecom.nginx.utils;importorg.apache.log4j.Logger;publicclassLog4jUtils{privatestaticfinalLoggerlogger=Logger.getLogger(Logger.class);publicstaticLoggergetLogger(){returnlogger;}}

这里简单做了两个的demo程序,做相应的测试,将项目打成war包后上传至Linux服务器,移动到tomcat/webapps中,tomcat进行热部署 先测试当前的tomcat是否能正常运行,由于没有做区别页面,就直接看日志来判断了。

如图:以轮询方式进行访问8080和8081监听的tomcat 上述方式是get请求进行的测试,我们来试试post。