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

时间:2022-04-21
本文章向大家介绍如何搭建Nginx服务器做到负载均衡?,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

小白,这是一篇关于:使用tomcat和Nginx进行配合做负载均衡和静态与动态资源分配的文章,春招前学一下~

好的,大佬!

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.配置文件

#user nobody;

#这里是核心worker数,一般设置为与cpu核心数相同的数目,避免进程切换造成的上下文切换耗费资源,cpu信息可以从/proc/cpuinfo中查看

worker_processes 1;

#error_log logs/error.log;

#error_log logs/error.log notice;

#error_log logs/error.log info;

#pidlogs/nginx.pid;

events {

#use epoll model使用epoll模型,采用异步非阻塞模型加快处理速度

use epoll; worker_connections 1024;}

http { 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; #设定通过nginx上传文件的大小 client_max_body_size 300m;

#使用sendfile函数在两个文件描述符之间直接传递数据(完全在内核中操作,传送),从而避免了内核缓冲区数据和用户缓冲区数据之间的拷贝,操作效率很高,被称之为零拷贝。 sendfile on;

#tcp_nopush on; #keepalive_timeout 0; #连接活跃时间 keepalive_timeout 65;#使用压缩数据减少IO量,但是在不支持数据解压浏览器可能产生乱码 #gzip on; #静态服务器组 #设定静态资源服务器访问接口 upstream static.zh-jieli.com {

server localhost:808 weight=1; } #动态服务器组 upstream zh-jieli.com {

#设置Hash轮询规则

#ip_hash;

#weight: server ip:port weight=10#默认 轮询#

fair:按照后端服务器的响应时间来分配

#url_hash:按照url规则进行分配,使得固定的请求分配到固定的服务器上server localhost:8080;

server localhost:8081;

}

server{ listen 808; server_name static; location / { } location ~ .*.(jscssicopngjpgeotsvgttfwoff) { #所有静态文件直接读取硬盘内容:读取的静态资源存放位置 root /apache-tomcat-8.5.24/webapps/ROOT ;

#资源是否进行缓存与缓存时间 expires 30d; #缓存30天 } }

server { listen 80; server_name localhost;

#charset koi8-r; #access_log logs/host.access.log main; location / { root html;

index index1.html index.htm; } location ~ .*.(jscssicopngjpgeotsvgttfwoff) { #proxy_cache cache_one; proxy_cache_valid 200 304 302 5d; proxy_cache_valid any 5d; proxy_cache_key '$host:$server_port$request_uri'; add_header X-Cache '$upstream_cache_status from $host'; proxy_pass http://static.zh-jieli.com; # 所有静态文件直接读取硬盘 root /apache-tomcat-8.5.24/webapps/ROOT; expires 30d; #缓存30天 }

#其他页面反向代理到tomcat容器 location ^~ /tomcat {

index index; # proxy_pass http://localhost:8080/; #设定代理服务器组 proxy_pass http://zh-jieli.com/; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }}

总结

整个nginx工作时当http请求到来时,由nginx针对nginx.conf配置好的规则,对location进行正则匹配,匹配到相应的正则,进行location内部的处理 关于Nginx的location配置附上一篇博客,很nicehttp://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

import org.springframework.web.bind.annotation.RequestMapping;

@Controller@RequestMapping("/test")public class TestOne { @RequestMapping("/getname") public void test(@RequestParam(value = "name") String name) {//用来记录获取的参数name,可以通过查看日志进行确认Log4jUtils.getLogger().info("my name is" + name); }}

Log4jUtils.java

public class Log4jUtils { private static final Logger logger = Logger.getLogger(Logger.class);

public static Logger getLogger() {

return logger; }}

demo

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

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

测试结果依旧可以正常接收参数,这里就不贴图了

想要学习更多的知识,查看程序员食堂历史消息哦~