电商平台 lnmp 架构之 nginx+tomcat

Posted 123坤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了电商平台 lnmp 架构之 nginx+tomcat相关的知识,希望对你有一定的参考价值。

电商平台 lnmp 架构之 nginx+tomcat

tomcat 结合 memcache

LAMP -> LAMJ
将 LAMP 架构中的 php 换成 jsp 就有了现在所说的 LAMJ 架构。

nginx+tomcat+jdk

  • tomcat
    Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。
    当在一台机器上配置好 nginx 服务器时,可利用 nginx 响应 html 页面的访问请求。实际上 Tomcat 是 nginx 服务器的扩展,但运行时它是独立运行的,所以当你运行 tomcat 时,它实际上作为一个与 nginx 独立的进程单独运行的。
    jdk
    JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。
    架构方案
    此时已经掌握了nginx的负载均衡,因此我们将tomcat和jdk安装在node2和node3上,只有处理jsp请求时,通过负载均衡访问node2和node3

先来配置java 的环境,直接用rpm 包来操作:

[root@server2 ~]# ls
apache-tomcat-7.0.37.tar.gz  jdk-8u121-linux-x64.rpm
[root@server2 ~]# rpm -ivh jdk-8u121-linux-x64.rpm
[root@server2 ~]# javac		##查看是否安装完成
[root@server2 ~]# tar zxf apache-tomcat-7.0.37.tar.gz 
[root@server2 ~]# ls
apache-tomcat-7.0.37  apache-tomcat-7.0.37.tar.gz  jdk-8u121-linux-x64.rpm
[root@server2 ~]# mv apache-tomcat-7.0.37 /usr/local/tomcat
[root@server2 ~]# cd /usr/local/tomcat/
[root@server2 tomcat]# ls
bin   lib      logs    RELEASE-NOTES  temp     work
conf  LICENSE  NOTICE  RUNNING.txt    webapps

用脚本来直接运行:

[root@server2 tomcat]# bin/startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar

开启之后,会开启一个8080端口:

[root@server2 tomcat]# netstat -antuple | grep 8080
tcp6       0      0 :::8080                 :::*                    LISTEN      0          29277      3935/java 

开启之后,此时便可以访问:


作为一个应用软件,用户不可能用8080来访问,用户默认访问的是80。
前端访问流程: client -> nginx:80 -> *.jsp -> tomcat:8080,由于使用的是 java,相对还是比较耗内存的,所以需要多来几个做负载均衡。nginx 可以承受高并发,而 tomcat 不行。

在 server3 上也安装上述同样的过程。

[root@server3 ~]# ls
apache-tomcat-7.0.37.tar.gz  jdk-8u121-linux-x64.rpm
[root@server3 ~]# rpm -ivh jdk-8u121-linux-x64.rpm 

[root@server3 ~]# tar zxf apache-tomcat-7.0.37.tar.gz -C /usr/local/
[root@server3 ~]# cd /usr/local/
[root@server3 local]# ls
apache-tomcat-7.0.37  etc    include  lib64    sbin   src
bin                   games  lib      libexec  share
[root@server3 local]# ln -s apache-tomcat-7.0.37/ tomcat
[root@server3 local]# ls	##软连接方便升级
apache-tomcat-7.0.37  etc    include  lib64    sbin   src
bin                   games  lib      libexec  share  tomcat
[root@server3 local]# cd tomcat/
[root@server3 tomcat]# ls
bin   lib      logs    RELEASE-NOTES  temp     work
conf  LICENSE  NOTICE  RUNNING.txt    webapps
[root@server3 tomcat]# bin/startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar

然后在nginx主机上设置tomcat的负载均衡;

[root@server1 conf]# pwd
/usr/local/nginx/conf
[root@server1 conf]# vim nginx.conf

 26 
 27     upstream tomcat 
 28     server 172.25.25.2:8080;
 29     server 172.25.25.3:8080;
 30     
 95         location ~ \\.jsp$ 
 96             proxy_pass   http://tomcat;
 97         
 98 

此时在访问时,虽然能访问到tomcat 的信息,但是由于发布页面信息不一致,此时看到的并不是之前的页面信息。


在 tomcat 所在主机上用一个测试页test.jsp来测试当前的状态;

[root@westos lnmp]# scp test.jsp root@172.25.25.2:/usr/local/tomcat/webapps/ROOT/
[root@westos lnmp]# scp test.jsp root@172.25.25.3:/usr/local/tomcat/webapps/ROOT/

此时再次访问,当在测试时,发现提交的数据前面的会被后面的数据覆盖;


由于session 不共享;当我们只开启一个tomcat时,产生的数据会保存到本地,但是当开启两个tomcat时,由于在负载均衡状态,受到nginx的调度,node2端提交数据后直接跳到了node3,与之前的建立的session断开了,再次回来数据就不存在了。为了解决这个问题,我们需要重新编译,添加sticky模块。sticky粘值能让同一个服务器的请求放到同一个后端上。

此时修改nginx中的配置信息,当来自同一个客户端的请求时就不需要在做负载;

[root@server1 conf]# vim nginx.conf

 26 
 27     upstream tomcat 
 28     sticky;
 29     server 172.25.25.2:8080;
 30     server 172.25.25.3:8080;
 31     
[root@server1 conf]# nginx -s reload

此时再次测试时,来自一个客户端的信息,不会做负载;


可以用日志信息来看:

[root@server2 logs]# pwd
/usr/local/tomcat/logs
[root@server2 logs]# tail catalina.out 
user1 = 123
user2 = 1234
user3 = 111
user4 = 222

此时如果一个后端退出,但是用户端并不知道;还在继续写入,此时由于nginx 对后端有健康检查,此时的已经调度到 server3上,但是之前的数据就会丢失:

[root@server2 tomcat]# bin/shutdown.sh 
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.ja

当session 不共享时,在访问时可能出现在一个tomcat 服务器中,会来回跳,失去session数据,如果不设置粘滞,就会出现购物时想把一个商品加入购物车,但加入购物车后,以前的购物车被清空了。

session共享
ngixn(需scicky模块)+tomcat+memcache实现session交叉存储

memcache实现session交叉存储

node2
如果 node2 的 tomcat 挂掉,那么node2上的数据依然会丢失,因此我们需要 memcache 的加入实现 session 交叉存放,即将访问tomcat2上的数据存放在 memcache3 中,将访问 tomcat3 上的数据存放在 memcache2 中。

在server2 和 server3 上下载需要的jar包,并修改配置信息,完成之后重启服务;

[root@server2 jar]# ls
asm-3.2.jar                              minlog-1.2.jar
kryo-1.04.jar                            msm-kryo-serializer-1.6.3.jar
kryo-serializers-0.10.jar                reflectasm-1.01.jar
memcached-session-manager-1.6.3.jar      spymemcached-2.7.3.jar
memcached-session-manager-tc7-1.6.3.jar
[root@server2 jar]# mv * /usr/local/tomcat/lib/
[root@server2 jar]# cd /usr/local/tomcat/lib/
[root@server2 lib]# ls

[root@server2 conf]# pwd
/usr/local/tomcat/conf
[root@server2 conf]# vim context.xml 
 34 <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
 35  memcachedNodes="n1:172.25.25.2:11211,n2:172.25.25.3:11211"
 36  failoverNodes="n1"     
  #当出现故障时找n1,正常时找n2,实现了session交叉存储       
 37  requestUriIgnorePattern=".*\\.(ico|png|gif|jpg|css|js)$"
 38  transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
 39  />
[root@server2 conf]# yum install -y memcached
[root@server2 conf]# systemctl enable --now memcached
[root@server2 tomcat]# bin/startup.sh 

在 server3 上和 server2 的上操作一样,修改配置文件内容,下载 memcached 服务,并设定开机自启,完成之后启动tomcat.

开启之后,看日志确保启动成功;

[root@server2 logs]# pwd
/usr/local/tomcat/logs
[root@server2 logs]# cat catalina.out
##出现以下信息,表示成功
INFO: MemcachedSessionService finished initialization, sticky true, operation timeout 1000, with node ids [n2] and failover node ids [n1]

测试:

此时沾滞在172.25.25.2上,可看到保存的session;

模拟故障,此时我们停掉n2的 tomcat(bin/shutdown.sh) 将 server2 停掉;


发现 tomcat 换成了172.25.25.3,但是 session 被保留下来了;

可以下载工具,进到应用查看 session 信息;

[root@server3 logs]# yum install telnet
[root@server3 logs]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
get  00E4018D5AEBA6A0C1A6E65F3194C82C-n2
VALUE 00E4018D5AEBA6A0C1A6E65F3194C82C-n2 2048 141
%#00E4018D5AEBA6A0C1A6E65F3194C82C-n2user11111user22222user33333user44444
END

如果一台主机的 tomcatmemcache 都挂掉,或者宕机了,session就没了。

此时是server3接管了,如果此时server2 的 tomcat 开启了之后,server3的 tomcat 挂掉了,那么数据是不会被保存的;因为其并不是时时共享的存储;只是 tomcat 向里面存数据。

但是,如果 server3 只是停掉了 memcached,那么不会有事,数据会自动通过 tomcat 迁移到 server2 上,此时在网页输入数据,会存在 memcached2 里面。

以上是关于电商平台 lnmp 架构之 nginx+tomcat的主要内容,如果未能解决你的问题,请参考以下文章

电商平台 lnmp 架构之 nginx+tomcat

电商平台 lnmp 架构之 mysql 优化

电商平台 lnmp 架构之 mysql 优化

电商平台 lnmp 架构之 mysql 高速缓存--redis

电商平台 lnmp 架构之 mysql 高速缓存--redis

LNMP架构之Discue论坛