Nginx动静分离实现负载均衡

转载自   Nginx动静分离实现负载均衡

前期准备

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

Nginx.conf配置

  1 # 定义Nginx运行的用户 和 用户组 如果对应服务器暴露在外面的话建议使用权限较小的用户 防止被入侵2 # user www www;3 4 #Nginx进程数, 建议设置为等于CPU总核心数5 worker_processes 8;6 7 #开启全局错误日志类型8 error_log /var/log/nginx/error.log info;9 10 #进程文件11 pid /var/run/nginx.pid;12 13 #一个Nginx进程打开的最多文件描述数目 建议与ulimit -n一致14 #如果面对高并发时 注意修改该值 ulimit -n 还有部分系统参数 而并非这个单独确定15 worker_rlimit_nofile 65535;16 17 events{18 #使用epoll模型提高性能19 use epoll;20 #单个进程最大连接数21 worker_connections 65535;22 }23 24 http{25 #扩展名与文件类型映射表26 include mime.types;27 #默认类型28 default_type application/octet-stream;29 sendfile on;30 tcp_nopush on;31 tcp_nodelay on;32 keepalive_timeout 65;33 types_hash_max_size 2048;34 #日志35 access_log /var/log/nginx/access.log;36 error_log /var/log/nginx/error.log;37 #gzip 压缩传输38 gzip on;39 gzip_min_length 1k;  #最小1K40 gzip_buffers 16 64K;41 gzip_http_version 1.1;42 gzip_comp_level 6;43 gzip_types text/plain application/x-javascript text/css application/xml application/javascript;44 gzip_vary on;45 #负载均衡组46 #静态服务器组47 upstream static.zh-jieli.com {48 server 127.0.0.1:808 weight=1;49 }50 #动态服务器组51 upstream zh-jieli.com {52 server 127.0.0.1:8080;53 #server 192.168.8.203:8080;54 }55 #配置代理参数56 proxy_redirect off;57 proxy_set_header Host $host;58 proxy_set_header X-Real-IP $remote_addr;59 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;60 client_max_body_size 10m;61 client_body_buffer_size 128k;62 proxy_connect_timeout 65;63 proxy_send_timeout 65;64 proxy_read_timeout 65;65 proxy_buffer_size 4k;66 proxy_buffers 4 32k;67 proxy_busy_buffers_size 64k;68 #缓存配置69 proxy_cache_key '$host:$server_port$request_uri';70 proxy_temp_file_write_size 64k;71 proxy_temp_path /dev/shm/JieLiERP/proxy_temp_path;72 proxy_cache_path /dev/shm/JieLiERP/proxy_cache_path levels=1:2 keys_zone=cache_one:200m inactive=5d max_size=1g;73 proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;74 75 server{76 listen 80;77 server_name erp.zh-jieli.com;78 location / {79 index index; #默认主页为 /index80 #proxy_pass http://jieli;81 }82 location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {83 proxy_cache cache_one;84 proxy_cache_valid 200 304 302 5d;85 proxy_cache_valid any 5d;86 proxy_cache_key '$host:$server_port$request_uri';87 add_header X-Cache '$upstream_cache_status from $host';88 proxy_pass http://static.zh-jieli.com;89 #所有静态文件直接读取硬盘90 #   root /var/lib/tomcat7/webapps/JieLiERP/WEB-INF ;91 expires 30d; #缓存30天92 }93 #其他页面反向代理到tomcat容器94 location ~ .*$ {95 index index;96 proxy_pass http://zh-jieli.com;97 }98 }99 server{
100 listen 808;
101 server_name static;
102 location / {
103 
104 }
105 location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
106 #所有静态文件直接读取硬盘
107 root /var/lib/tomcat7/webapps/JieLiERP/WEB-INF ;
108 expires 30d; #缓存30天
109 }
110 }
111 }

基本配置这个文件,就可以实现负载均衡了。但是里面的各种关系要了解就比较麻烦了。

 

实例讲解

现在假使有一台电脑192.168.8.203这台电脑,上面部署了Tomcat,里面8080端口有J2EE的服务,通过浏览器可以正常浏览网页。现在有一个问题tomcat是一个比较全面的web容器,对静态网页的处理,应该是比较费资源的,特别是每次都要从磁盘读取静态页面,然后返回。这中间会消耗Tomcat的资源,可能会使那些动态页面解析性能影响。秉承Linux哲学,一个软件只做一件事的原则。Tomcat就应该只处理JSP动态页面。这里就用到以前了解的Nginx来进行反向代理。第一步代理,实现动静网页分离。这个很简单的。

 1 worker_processes 8;2 3 pid /var/run/nginx.pid;4 5 worker_rlimit_nofile 65535;6 7 events{8 use epoll;9 worker_connections 65535;
10 }
11 
12 http{
13 include mime.types;
14 default_type application/octet-stream;
15 sendfile on;
16 tcp_nopush on;
17 tcp_nodelay on;
18 keepalive_timeout 65;
19 types_hash_max_size 2048;
20 
21 proxy_redirect off;
22 proxy_set_header Host $host;
23 proxy_set_header X-Real-IP $remote_addr;
24 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
25 client_max_body_size 10m;
26 client_body_buffer_size 128k;
27 proxy_connect_timeout 65;
28 proxy_send_timeout 65;
29 proxy_read_timeout 65;
30 proxy_buffer_size 4k;
31 proxy_buffers 4 32k;
32 proxy_busy_buffers_size 64k;
33 
34 server{
35 listen 80;
36 server_name xxx.com;
37 location / {
38 index index; 
39 }
40 location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
41 proxy_pass http://192.168.8.203:8080;
42 expires 30d; 
43 }
44 location ~ .*$ {
45 index index;
46 proxy_pass http://192.168.8.203:8080;
47 }
48 }
49 }

修改nginx的配置文件 /etc/nginx/nginx.conf 默认有个配置文件的。其实大部分都差不多,关键还是server段的设置。这里我设置server段如上所示,其他段复制就可以了。server段里面的解释如下:第35行为监听本机80端口。37-39行表示默认主页,这里的默认主页我是index.jsp 对应到我项目中是一个index。 这里根据需要可以改为 

 index index.jsp index.html index.htm index.php

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

 

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

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

表示不代理,直接从本地磁盘拿。通过查tomcat日志可以看到静态页面是没有访问到的。但这样又有一个问题。这样的灵活性不好,对下面要讲到的内存缓存和集群部署来说都是不友好的,所以又有了下面的这种写法。再写一个server段。

 1 server{2 listen 808;3 server_name static;4 location / {5 6 }7 location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {8 #所有静态文件直接读取硬盘9 root /var/lib/tomcat7/webapps/JieLiERP/WEB-INF ;
10 expires 30d; #缓存30天
11 }
12 }

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

如果单纯这样的话,我们会发现页面直接传输过于占用带宽。对应web的优化,这里想到的是通过对页面进行gzip压缩,然后传到用户那里,再解压,这样可以有效的减少带宽。这里就会用到Nginx 的gzip模块了。默认的Nginx是集成有gzip模块的。只需在http段增加下面配置即可。

1 gzip on;
2 gzip_min_length 1k;  #最小1K
3 gzip_buffers 16 64K;
4 gzip_http_version 1.1;
5 gzip_comp_level 6;
6 gzip_types text/plain application/x-javascript text/css application/xml application/javascript;
7 gzip_vary on;

 

给个首页看看效果

 

不要在意请求数不一样,那两个请求是谷歌插件来的。不用觉得我在骗你。

作为假使有很多人访问的网站来说,缓存肯定是很重要的东西了。一开始是想通过插件,让Nginx和Redis进行合成,然后Nginx使用Redis来缓存的,但是发现配置起来很麻烦,还要自己下载插件,重新编译Nginx,比较麻烦,所以这里觉得用Nginx自带的缓存也是不错的选择。虽然效率比不上redis,但是有还是比没有好。Nginx默认的缓存是磁盘文件系统的缓存,而不是像Redis那样的内存级别的缓存。一开始我以为Nginx就只有这样。后来查了写资料,才知道是我太天真了,对Linux不是很了解导致的。Linux的一切皆文件。原来我们可以把文件缓存到内存对应的Linux文件系统中。我说的可能比较难以理解,请自行搜索/dev/shm 这个文件目录。我们把文件缓存到这个文件目录里,其实就相当与内存的缓存了。只不过还是靠文件系统管理。所以比不上自定义格式的Redis那样的内存缓存。

在http段进行基本配置

1 #缓存配置
2 proxy_cache_key '$host:$server_port$request_uri';
3 proxy_temp_file_write_size 64k;
4 proxy_temp_path /dev/shm/JieLiERP/proxy_temp_path;
5 proxy_cache_path /dev/shm/JieLiERP/proxy_cache_path levels=1:2 keys_zone=cache_one:200m inactive=5d max_size=1g;
6 proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;
 1 location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {2 proxy_cache cache_one;3 proxy_cache_valid 200 304 302 5d;4 proxy_cache_valid any 5d;5 proxy_cache_key '$host:$server_port$request_uri';6 add_header X-Cache '$upstream_cache_status from $host';7 proxy_pass http://192.168.8.203:808;8 9 expires 30d; #缓存30天
10 }

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

1 <meta http-equiv="pragma" content="no-cache">
2 <meta http-equiv="cache-control" content="no-cache">
3 <meta http-equiv="expires" content="0">

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

user www www;

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

我们rm -rf /dev/shm/JieLiERP/proxy_* 下面的所有文件(注意这里如果是进行多次测试的话要nginx -s reload 重新读取配置或重启服务,因为你rm -rf只是删除了缓存文件,但是缓存的结构信息还在nginx进程里面,结构还在,如果不重启的话,是会出现访问不到的)

 

所以要记得重启哦。下面是运行效果

第一次访问

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

 

到这里就可以看到效果了。我们查看一下/dev/shm这个里面

 

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

#负载均衡组
#静态服务器组
upstream static {
server 127.0.0.1:808 weight=1;
server 192.168.8.203:808 weight=1;
}
#动态服务器组
upstream dynamic {
server 127.0.0.1:8080;
#server 192.168.8.203:8080;
}

上面那个就是集群组了。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,然后分配对应的服务器。具体配置如下:

1 upstream dynamic{
2 ip_hash;
3 server 127.0.0.1:8080;
4 server 192.168.0.203:8080;
5 }

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

Nginx增加SSL功能,同样的Nginx默认是有SSL模块功能,我们不用额外安装,只需要简单的配置就可以了。首先我们先来生成一些必要的证书。制作的过程还是比较简单的。

 1 #制作CA证书2 openssl genrsa -des3 -out ca.key 20483 openssl req -new -x509 -days 7305 -key ca.key -out ca.crt4 5 #生成Nginx服务器所需证书,并使用CA签名6 openssl genrsa -des3 -out client.key 10247 openssl req -new -key client.key -out client.csr8 openssl x509 -req -in client.csr -out client.pem -signkey client.key -CA ca.crt -CAkey ca.key -CAcreateserial -days 36509 
10 #取消证书密码
11 openssl rsa -in client.key -out client.key.unsecure

 

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

 1 server{2 server_name localhost;3 listen 443 ssl;4 root html;5 location / {6 index index.html index.html;7 }8 ssl on;9 ssl_certificate keys/client.pem;
10 ssl_certificate_key keys/client.key.unsecure;
11 }

重启Nginx,我们就可以访问Https网站了。 但是他喵的出现这个

 

 

这个是没有什么问题,具体原因是这个CA证书要得到认可。所以我们上面自己生成的https证书,只是自己生成的,如果要变成下面这种,就需要花钱购买了,剩下的这个自己上网解决。(虽然自己生成的证书可以用,但是还是抵挡不了DNS欺骗,所以这种不安全证书,跟没有其实是一样的。不过据说这样可以阻止运营商劫持。)

 

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

1 server{
2 server_name localhost;
3 listen 80;
4 rewrite ^(.*)$ https://$host$1 permanent;
5 }

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/326156.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html5动画是什么,10个HTML5动画 让你忘掉Flash是啥(组图)

你最近可能已经听到了很多关于Flash是面临垂死挣扎的技术以及它将如何很快被HTML5的取代。就个人而言&#xff0c;我认为HTML5会慢慢取代一些Flash的东西&#xff0c;但Flash会永远有它的一席之地&#xff0c;特别是开发复杂的游戏和丰富的互联网应用。如果你还没有看到HTML5动…

2016蓝桥杯省赛---java---A---6(寒假作业)

题目描述 现在小学的数学题目也不是那么好玩的。 看看这个寒假作业&#xff1a;□ □ □ □ - □ □ □ □ □ □ □ □(如果显示不出来&#xff0c;可以参见【图1.jpg】)每个方块代表1~13中的某一个数字&#xff0c;但不能重复。 比如&#xff1a; 6 7 13 9 - 8 1 …

微服务网关Ocelot

微服务网关是微服务架构中的核心组件,它是客户端请求的门户,它是调用具体服务端的桥梁.下面我们将使用开源项目Ocelot&#xff08;https://github.com/geffzhang/Ocelot&#xff09;搭建一款轻量级服务网关,不过在此之前我们将对微服务网关做个详细介绍,以便大家更加清晰的了解…

分表分库时机选择及策略

转载自 分表分库时机选择及策略 一. 分表 应用场景&#xff1a; 对于大型的互联网应用来说&#xff0c;数据库单表的记录行数可能达到千万级甚至是亿级&#xff0c;并且数据库面临着极高的并发访问。采用Master-Slave复制模式的MySQL架构&#xff0c;只能够对数据库的读进…

2015蓝桥杯省赛---java---A---2(星系炸弹)

题目描述 思路分析 方案一 方案二 package TEST;import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date;class Main{public static void main(String[] args) {SimpleDateFormat dateFormat new SimpleDateFormat("yyyy-MM-dd");…

NuGet社区使用体验调查

Nuget 是我们使用.NET Core的一项基础设施&#xff0c;针对国内访问NuGet服务器速度不稳定的问题我们希望通过收集一些来自用户的反馈来改善社区使用NuGet的体验。恳请您花2-3分钟时间完成以下的问题&#xff0c;我们会非常重视您的反馈。当我们收集完成所有的问卷&#xff0c;…

在护卫神上部署javaWeb项目,已经测试通过

以前一直在护卫神上部署PHP项目&#xff0c;今天忽然来了需求是部署javaWeb项目&#xff0c;刚开始一脸蒙蔽&#xff0c;后来发现也不是很难。那么接下来我们看看怎么在护卫神上部署java项目&#xff1a; 第一步&#xff1a;打开护卫神&#xff0c;在护卫神中添加一个网站&…

为什么选择微服务架构?如何取舍?

转载自 为什么选择微服务架构&#xff1f;如何取舍&#xff1f; 微服务是什么 微服务是一种架构风格&#xff0c;一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署&#xff0c;各个微服务之间是松耦合的。每个微服务仅关注于完成…

三星系统和鸿蒙系统,又一设备直升鸿蒙系统,现有操作系统被抛弃,和三星的想法一样!...

又一设备直升鸿蒙系统&#xff0c;现有操作系统被抛弃&#xff0c;和三星的想法一样&#xff01;前段时间华为正式发布了鸿蒙系统&#xff0c;这个系统可以说是期待已久了&#xff0c;在华为处于禁令时期时&#xff0c;鸿蒙被认为是替代安卓的操作系统。在鸿蒙发布后&#xff0…

从真实项目中抠出来的设计模式——第一篇:策略模式

有时候因为种种原因导致我们会写出很多丑陋的代码&#xff0c;比如赶工时&#xff0c;短暂性的偷懒&#xff0c;不会设计模式等等导致代码沉积&#xff0c;一个cs上万行代码这样场景是有发生&#xff0c; 当然这里也包括我。。。所以时间充裕一点之后就想重构一下&#xff0c;…

jquery实现单击div切换背景,再次单击回到原来样式

首先来看看效果图&#xff1a; 1.这是默认的的div样式&#xff1a; 2.当我们单击第一个div时的样式&#xff1a; 3.当我们再次单击第一个div时的样式&#xff1a; 如果你需要的效果是这样的&#xff0c;那么请您继续往下面看&#xff0c;如果不是&#xff0c;您也可以看看实…

Java进阶之对象克隆(复制)

转载自 Java进阶之对象克隆&#xff08;复制&#xff09; 假如说你想复制一个简单变量。很简单&#xff1a; int apples 5; int pears apples; 不仅仅是int类型&#xff0c;其它七种原始数据类型(boolean,char,byte,short,float,double.long)同样适用于该类情况。 但…

如何下载网页中的视频成mp4格式

1.在生活中&#xff0c;我们经常在网页上看到某个视频之后想要下载下来&#xff0c;可是&#xff0c;网上大部分的视频都在几大播放器所占领&#xff0c;比如爱奇艺、优酷、腾讯等等&#xff0c;当你在这些上面下载的时候会发现先要让你下载播放器&#xff0c;才能下载视频。这…

微软CNTK 2.0版本发布,支持C#

微软 CNTK 2.0 版本今天正式发布。 CNTK&#xff08;Cognitive Toolkit&#xff09;是微软的深度学习工具包&#xff0c;可以帮助企业加速图像和语音识别进程。有了今天的更新&#xff0c;企业可以在本地或云端结合 Azure GPU 使用 CNTK了。 伴随着今天的新版本发布&#xff0c…

Android碎片Fragment详讲(1)

Fragment Fragment创建的步骤 1、 继承fragment一定是V4包下的 2、 有且只有一个无参的构造方法 3、 如果Fragment需要显示界面&#xff0c;需要重写onCreateView方法 4、 指定布局资源&#xff0c;或者创建布局&#xff0c;返回即可 静态创建frag…

这些BATJ必考的Java面试题,你都懂了吗?

转载自 这些BATJ必考的Java面试题&#xff0c;你都懂了吗&#xff1f; 题目一 请对比 Exception 和 Error&#xff0c;另外&#xff0c;运行时异常与一般异常有什么区别&#xff1f; 考点分析&#xff1a; 分析 Exception 和 Error 的区别&#xff0c;是从概念角度考察了…

计算机玩游戏特别卡,Win7电脑游戏卡顿怎么办 win7玩游戏卡如何解决

很多人都喜欢在win7系统中玩游戏&#xff0c;而在玩游戏的时候经常会碰到一些故障&#xff0c;比如有很多用户反映的游戏卡顿、玩游戏太卡&#xff0c;这让很多游戏玩家很是苦恼&#xff0c;那么Win7电脑游戏卡顿怎么办呢&#xff1f;下面给大家介绍一下win7玩游戏卡的解决方法…

在IIS上部署你的ASP.NET Core项目

概述 与ASP.NET时代不同&#xff0c;ASP.NET Core不再是由IIS工作进程&#xff08;w3wp.exe&#xff09;托管&#xff0c;而是使用自托管Web服务器&#xff08;Kestrel&#xff09;运行&#xff0c;IIS则是作为反向代理的角色转发请求到Kestrel不同端口的ASP.NET Core程序中&a…

2020蓝桥杯省赛---java---A---2(既分数组)

题目描述 代码实现 package TEST;public class Main {public static void main(String[] args) {int ans 0;for(int i1; i<2020; i)for(int j1; j<2020; j) // if(j>i){{if(gcd(i, j) 1) ans;} // }else { // if(gcd(i, j) …

西安理工大学计算机专业毕业,西安理工大学什么专业好找工作?毕业工资大概多少?答案在这里...

文/圆梦志愿 马老师西安理工大学是中央与地方共建的省属高水平大学&#xff0c;在本省的知名度较高&#xff0c;是一所实力还不错的理工类高校。那么&#xff0c;西安理工大学就业最好的专业是哪些&#xff1f;学校毕业生的薪资水平如何呢&#xff1f;一起来了解一下吧。一、西…