从单体到集群系列目录

从单体到集群(1) - 使用Nginx配置静态资源并搭建Tomcat集群

从单体到集群(2) - keepalived+Nginx实现高可用集群

从单体到集群(3) - LVS+Keepalived+Nginx实现高可用集群负载均衡

--------------------------------------------------------------------------------------------------------------------------

1.前言

       最近看了慕课网-Java架构师成长直通车的课,感觉受益颇深,这门课讲述了如何把一个电商项目从单体架构,逐渐演变成集群架构,分布式架构,微服务容器化架构(当然这不是广告,只是我个人感觉这门课不错,推荐给大家,我这么菜也不会有人找我发广告。。。)。写这个系列的博客的目的一个是为了记录下自己的感受和心得,以便日后复习巩固知识;另一个是可以为那些有基础理论知识,但缺少实践的小伙伴们提供一个例程Demo,可以实际体验一下自己动手架构的魅力。本人保证此篇博文属个人原创,绝非盲目的复制粘贴,文中所有实例均经过实践,请大家放心。

2.素材与软件版本

软件版本:

       IDAE:2019.2.2

       VMware:12.5.2

       虚拟机镜像:CentOs7.3标准版

       Xshell:Xshell6

       Postman:7.33.1

       Tomcat:8.5.41

       Nginx:1.18.0稳定版

       此系列项目素材取自慕课网-Java架构师成长直通车的课程,素材下载链接如下,请小伙伴们按需下载。后台项目为foodie-dev,前端项目有两个,foodie-shop为前端商城主体项目,foodie-center为前端商城个人中心项目。

       先来看下后台项目,采用springboot模块化开发,持久层采用tk.mybatis的通用mapper,数据库为MySql。api为对外暴露的接口,common为公共类模块,mapper为Dao层模块,pojo为实体类模块,service为业务层模块,另外数据库SQL文件在src目录下,使用前建库导入即可,项目也很简单,拉下来改下springboot配置文件就能跑了。

       foodie-shop为前端商城项目采用VUE框架编写,里面全是静态资源,下载下来直接丢tomcat。和后台有关的配置在app.js文件中(一定要记得修改这个文件中的配置),如果修改了后台服务访问路径,记得同步修改前端配置,此项目中支付功能暂时不可用,其他均功能正常。

       foodie-center为前端个人中心项目,负责处理个人用户有关的业务逻辑

先在本地把项目跑起来:

       1.从github上把foodie-dev、foodie-shop、foodie-center三个项目拉到本地导入IDEA

       2.在mysql中创建名为foodie-shop-dev的库,编码选择utf8mb4,导入后台项目根目录src下的sql文件

       3.修改后台服务foodie-dev中springboot配置文件,同步修改前端项目foodie-shop中app.js的配置,保持和后台接口服务一致

       4.将前端项目丢tomcat启动

       5.启动后台服务,前端页面可以正常展示数据,f12控制台不报错

3.架构演变目标

       目前的架构为单体应用最基础的架构,后端服务打成war包和前端项目一起丢到tomcat里面发布。

       关于springboot打war包直接在项目中搜索"打包war"按照注释操作就可以。

但是因为单体架构存在着如下的缺点:

       1.单节点宕机会导致整体服务崩溃

       2.迭代,测试,部署的耦合度太高

       3.单节点并发能力有限

       所以我们要采用Nginx为静态资源提供服务,并配置后台服务的tomcat集群,以确保单节点故障整体服务不会挂掉。细心的小伙伴可能会问了用Nginx为tomcat集群作转发,万一单节点的Nginx挂了怎么办?之后会用到keepAlived为Nginx做一个集群并且实现双主热备。可能还有的小伙伴会问,单节点并发能力不够,用Nginx做了后台服务集群的转发,那这样前端并发请求的压力就落到Nginx头上了,如何保证Nginx可以顶得住前端并发请求的压力呢?之后会用LVS(四层代理技术,Nginx为七层代理)+keepAlived来实现Nginx的集群化,以及健康检查,双主热备等等,不要急慢慢来。扯了这么多,此篇博文要实现的架构为:

4.具体实操

       首先我们要先准备三台虚拟机,并配置他们的IP以及开放宿主机远程访问,遇到问题的小伙伴可以参考我这篇博文:VMware CentOS7 Ping指令报错:Name or service not known,然后将软件包上传到对应的电脑上(150上传Nginx和前端项目,171和172上传Tomcat和后端项目war包)。

4.1 安装Nginx

       在192.168.1.150这台电脑安装Nginx,先安装依赖库:

yum install gcc-c++
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
yum install -y openssl openssl-devel

       解压,需要注意,解压后得到的是源码,源码需要编译后才能安装:

tar -zxvf nginx-1.18.0.tar.gz

        编译之前,先创建nginx临时目录,如果不创建,在启动nginx的过程中会报错:

mkdir /var/temp/nginx -p

       在nginx目录,输入如下命令进行配置,目的是为了创建makefile文件:

./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi

       make编译

make

       安装

make install

       进入sbin目录启动nginx

./nginx
// 停止:./nginx -s stop
// 重新加载:./nginx -s reload

       启动后正常来说就可以访问了,如果不能访问的话用telnet查看一下端口是否开放,以及防火墙是否关闭。

4.2 使用Nginx为静态资源提供服务

       首先我们把两个前端项目上传到150这台虚拟机上的/home路径下:

       然后进入我们nginx的配置文件路径/usr/local/nginx/conf,nginx可以通过indlude命令导入其他配置文件,所以我们单独新建一个配置文件imooc.conf文件,写入如下内容:

server {
        listen  90;
        server_name localhost;
        location / {
                root /home/foodie-shop;
                index index.html;
        }
}

       然后在nginx.conf文件内用include指令导入新建的配置文件:

       最后进入sbin目录重启nginx服务:

./nginx -s reload

       再访问IP+90端口:

       可以看到页面转发正常,说明nginx配置成功,但缺少一部分数据,这是因为后台服务和数据库还没有配置,我们现在192.168.1.150这台虚拟机搭建一个mysql服务(推荐使用docker启一个mysql5.7的容器,如果仅仅只是学会用docker的话其实不是很难,容器部署非常快捷),然后在192.168.1.171和192.168.1.172这两台虚拟机上部署一个tomcat并启动服务,然后修改前端项目app.js中后端接口服务的配置(因为还没有搭建tomcat集群,所以先写成192.168.1.171:8080/foodie-dev-api-1.0-SNAPSHOT):

       至此配置Nginx静态资源服务结束。

4.3 使用Nginx搭建Tomcat集群

       首先我们先进入192.168.1.150这台虚拟机,打开imooc.conf配置文件,增加如下配置:

upstream tomcats{
        server  192.168.1.171:8080;
        server  192.168.1.172:8080;
}
server{
        listen  88;
        server_name     localhsot;
        location /{
                proxy_pass http://tomcats;
        }
}
server {
        listen  90;
        server_name localhost;

        location / {
                root /home/foodie-shop;
                index index.html;
        }
}

       重新启用配置后我们访问http://192.168.1.150:88,可以看到直接跳转到171这台虚拟机的tomcat里

       当然我们再点击刷新的话,就可以跳转到172这台虚拟机里,可见Nginx的默认负载均衡算法为轮询。

4.4 前后端同步配置修改,完成联调

       上面我们现实了Nginx搭建tomcat集群,但光做到这样没什么用,重点是把项目中js的请求分发到Tomcat集群上。要解决这个问题,首先我们要去掉Tomcat中项目的项目名,因为Nginx的upstream模块只能填写IP+端口号,不能带上项目名一起转发。打开Tomcat根目录/conf/server.xml文件,在<host>...</host>标签中加入一段配置:

<Context path="" docBase="foodie-dev-api-1.0-SNAPSHOT" debug="0"/>

       这样就可以去掉项目名,直接用IP+端口号来访问了。接着我们去修改192.168.1.150这台虚拟机前端商城项目/home/foodie-shop/js下的app.js文件中后台接口服务的地址:

serverUrl: "http://192.168.1.150:88",      // 接口服务接口地址

       请求分发的整体流程为:浏览器首先请求192.168.1.150的90端口,Nginx会把请求转发到前端商城项目foodie-shop上。然后foodie-shop项目app.js文件中配置了后台接口服务的地址为192.168.1.150的88端口,Nginx在监听到该端口的请求后,会将请求分发到192.168.1.171和192.168.1.172这两台虚拟机的Tomcat上,最终实现Tomcat集群的负载均衡。流程图为:

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐