Nginx双机热备的实现步骤

本站所有内容来自互联网收集,仅供学习和交流,请勿用于商业用途。如有侵权、不妥之处,请第一时间联系我们删除!Q群:迪思分享

免费资源网 – https://freexyz.cn/

目前所接触的项目还不涉及到分布式,都是单机模式。不过好在至今没出过什么大问题,基本能满足客户的需求。

由于数据量不是很大,单机的性能已经可以满足,按理不应该做加法,毕竟部署的越复杂,维护起来就越麻烦。

性能虽然可以满足,但有一个不得不提的痛点:项目无法随时更新。

目前的解决方式是:白天改bug、测试,等到晚上客户不使用系统时才停机维护,效率相对较低。

有没有可能让项目可以随时更新?

答案肯定是有,相对简单的解决方案是:双机热备(应用双活) 。

什么是双机热备?

这里引用一下百度百科的解释。

双机热备是应用于服务器的一种解决方案,其构造思想是主机和从机通过TCP/IP网络连接,正常情况下主机处于工作状态,从机处于监视状态,一旦从机发现主机异常,从机将会在很短的时间之内代替主机,完全实现主机的功能。

就是同时部署两套系统,一主一备。主节点负责对外提供服务,备用节点默认不提供服务,只有在主节点出问题的情况下,备用节点才顶替主节点,继续对外提供服务。

大哥不行了,二弟替一会儿。

可以解决什么问题?

利用这个思路,是否可以实现同时部署AB两套系统,当系统需要更新维护时,停用A服务,B服务顶替A工作。待A服务更新完毕后,A服务启动提供升级后的服务,B服务停用再更新。实现应用的热插拔?

答案当然也是可以的。

纸上得来终觉浅,绝知此事要躬行。

本人写了个小demo亲测!

实现思路

搭建项目前先简单理一下思路。

要做的分为以下几步:

1、启动两套简单的Web服务

2、服务内就两个简单的方法

保存值到Session

从Session取值

3、Nginx配置负载均衡,PC01主,PC02备

3、保存Session到PC01服务,然后停用PC01

4、从PC02服务取值,看PC02能否正常工作并访问Session

如果服务可以无缝切换,Session也都正常则表示成功。

项目环境

两套SpringBoot服务(双活)

Redis(实现Session共享)

Nginx(负载均衡-主备模式) (也可使用KeepAlived)

为什么需要Redis?

使用多套系统无法避开的一个问题就是Session,再也不能像以前单机模式下直接从request中getSession了,Session是保存在服务器的,多个服务器之间无法共享Session。关于共享Session有很多实现方案,这里采用的是Redis。

搭建步骤

1、先简单看一下前端

由于只讲环境搭建,所以项目竟可能的简单。

只有两个功能,保存值到Session和从Session中取值。const PATH = ‘/backend/; //保存到Session function saveSession() { const personName = $(#personName).val(); if (personName.length <= 0) { alert(请输入再保存); return; } $.ajax({ type:post, url: PATH+”test/save”, async:false, xhrFields: { withCredentials: true }, crossDomain: true, data: { personName:personName }, success: function(json) { $(#screen).text(json); } }); } //查询Session function requestServer() { $.ajax({ type:post, url: PATH+”test/query”, async:false, xhrFields: { withCredentials: true }, crossDomain: true, success: function(json) { $(#screen).text(json); } }); }

2、再看一下后端服务

很简单的一个服务,就两个方法:保存值到session、从session中取值

只从request中获取SessionId作为Key,数据作为Value保存到Redis。@RestController @RequestMapping(“/test”) public class TestController { private static final String SERVER = “PC01”; @Autowired private RedisUtil redisUtil; @RequestMapping(“/save”) public Object save(String personName, HttpServletRequest request, HttpServletResponse response) { String sessionId = request.getRequestedSessionId(); if (redisUtil.set(sessionId, personName)) { return SERVER+”,Session保存成功”; } return “Session保存失败”; } @RequestMapping(“/query”) public Object query(HttpServletRequest request) { String sessionId = request.getRequestedSessionId(); Object personName = redisUtil.get(sessionId); if (personName != null) { return “Hello,” + personName+”,我是”+SERVER; } return “Session为空”; } }

项目会编译两个jar包,同时部署。

PC01对应8081端口,PC02对应8082端口。

3、Nginx配置负载均衡

#主备模式,backup只有在主节点故障时才提供服务 upstream backend { server 127.0.0.1:8081; server 127.0.0.1:8082 backup; } server { listen 81; server_name localhost; location /{ #前端 root www/back; } location /backend{ #反向代理到8081、8082 proxy_pass http://backend; } }

到这一步环境就算搭建完成了。

4、测试

现在虽然PC01和PC02都是启动的,但是只有PC01对外提供服务。

我们将‘小潘’保存到Session,然后查询。

可以看到,我们现在访问的是PC01服务,且Session也保存成功了。

接下来,我们停用PC01服务。[root@localhost test]# lsof -i:8081 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 71972 root 13u IPv6 88606 0t0 TCP *:tproxy (LISTEN) [root@localhost test]# kill -9 71972

强制杀掉进程,项目会不会因此而挂掉呢?

再次请求查询Session

可以看到,项目并没有挂掉。不仅如此,而且Session也能正常访问,PC02迅速顶替了PC01的位置,继续对外提供服务。

接下来,就可以对PC01进行维护更新了,更新好了直接启用,PC02又会退居幕后,等待下一次复出。

整个过程对于用户而言是无缝的。

利用双机热备,不仅可以实现项目的随时更新,而且还实现了高可用。即使PC01意外宕机,PC02也会迅速接替,不至于整个项目瘫痪。


© 版权声明
THE END
★喜欢这篇文章吗?喜欢的话,麻烦动动手指支持一下!★
点赞7 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容