TOMCAT+Memcached

发布于:2025-08-07 ⋅ 阅读:(21) ⋅ 点赞:(0)

本文章主要介绍memcached,如何有效提高数据处理的效率,最后会有一个配合nginx以及tomcat的综合实验去教大家如何运用

介绍

Memcached 只支持能序列化的数据类型,不支持持久化,基于Key-Value的内存缓存系统。memcached 虽然没有像redis所具备的数据持久化功能,比如RDB和AOF都没有,但是可以通过做集群同步的方式, 让各memcached服务器的数据进行同步,从而实现数据的一致性,即保证各memcached的数据是一样的,即使有任何一台 memcached 发生故障,只要集群中有一台 memcached 可用就不会出现数据丢失。

当其他memcached 重新加入到集群的时候,可以自动从有数据的memcached 当中自动获取数据并 提供服务。 Memcached 借助了操作系统的 libevent 工具做高效的读写。

libevent是个程序库,它将Linux的epoll、 BSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥高 性能。

memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能 Memcached 支持最大的内存存储对象为1M,超过1M的数据可以使用客户端压缩或拆分报包放到多个 key中,比较大的数据在进行读取的时候需要消耗的时间比较长,memcached 最适合保存用户的 session实现session共享 Memcached存储数据时, Memcached会去申请1MB的内存, 把该块内存称为一个slab, 也称为一个page Memcached 支持多种开发语言,包括:JAVA,C,Python,PHP,C#,Ruby,Perl等

部署

/usr/local/tomcat/webapps/ROOT/

PORT表示监听端口,USER表示运行 Memcached 的系统用户,MAXCONN表示最大链接数,CACHESIZE表示最大内存容量(单位MB),OPTIONES表示监听的所有的IPv4和v6地址

systemctl enabled --now memcached
[root@tom1 ~]# netstat -lntup | grep memcached
tcp        0      0 0.0.0.0:11211           0.0.0.0:*               LISTEN      986/memcached
tcp6       0      0 ::1:11211               :::*                    LISTEN      986/memcached

 常用命令

五种常用的存储命令

set、add、replace、get、delete

语法格式:

command <key> <flags> <expiration time> <bytes> <value>

 key 用于查找缓存值,flags 可以包括键值对的整型参数,expiration time表示存储的时间长度

bytes 缓存中存储的字节数,value 存储的值

示例

[root@tom1 ~]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
add lab 0 60 4 #0 表示是否压缩 60过期时间 4字节长
test
STORED
get lab
VALUE lab 0 4
test
END
set lab 0 60 5 #修改
test1
STORED
add foo 0 60 5
one
delete foo
CLIENT_ERROR bad data chunk
ERROR
get foo
END

这个很简单,没什么好说的,直接上项目

实战

本实验用到三台主机,IP分别为192.168.118.171/172/173,mask 24。其中172,173作为tomcat主机,同时运行memcached,171运行nginx,复制调度

反向代理多机模式:

利用nginx的反向代理功能,将用户的请求全部转发给到同一个tomcat主机

部署tomcat

下面的操作在172/173这两台主机上面做

官网:Apache Tomcat® - Welcome!

官方文档:Apache Tomcat 8 (8.5.100) - Documentation Index

#安装Java环境
 yum install java-1.8.0-openjdk.x86_64 -y
[root@tom1 ~]# java -version
openjdk version "1.8.0_382"
OpenJDK Runtime Environment (build 1.8.0_382-b05)
OpenJDK 64-Bit Server VM (build 25.382-b05, mixed mode)

#解压生成tomcat的程序目录
[root@tom1 ~]# ls
anaconda-ks.cfg   apache-tomcat-9.0.107.tar.gz
[root@tom1 ~]# tar -zxvf apache-tomcat-9.0.107.tar.gz -C /usr/local

编辑一份系统服务脚本vim /etc/systemd/system/tomcat.service

[Unit]
Description=Apache Tomcat Web Application Container
After=network.target

[Service]
Type=forking
Environment=CATALINA_PID=/usr/local/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/usr/local/tomcat
Environment=CATALINA_BASE=/usr/local/tomcat
EnvironmentFile=/usr/local/tomcat/conf/tomcat.conf
PrivateTmp=true

ExecStart=/usr/local/tomcat/bin/startup.sh

ExecStop=/usr/local/tomcat/bin/shutdown.sh

TimeoutStartSec=60
TimeoutStopSec=60

User=tomcat
Group=tomcat

[Install]
WantedBy=multi-user.target

然后直接启动:systemctl start mycat

[root@tom1 ~]# netstat -lntup | grep java
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      3422java
tcp6       0      0 :::8080                 :::*                    LISTEN      3422java

 部署nginx

由于只是用到一个反向代理的功能,就不去专门编译安装了直接dnf install nginx -y

然后写一份反向代理的配置:vim /etc/nginx/conf.d/vhost.conf

upstream tomcat {
  hash $cookie_JSESSIONID;
  server  192.168.118.173:8080;
  server  192.168.118.172:8080;
}
server {
  listen  80;
  server_name  www.openlab.com; //虚拟主机的名词
  root  /web/test; //访问上面的虚拟主机时指定其根目录

  location  ~ \.jsp$ { //将jsp的请求丢给tomcat处理
    proxy_pass http://tomcat;
  }
}

上面提到了一个hash $cookie_JSESSIONID;,这个是针对于浏览器访问时携带的session做一个hash,保证处理浏览器持续访问的请求都是同一个后端tomcat处理的

结合

最后就是memcached和tomcat的配合,实现msm这个架构(memcached session manager)

这个主要功能就是提供将tomcat的session会话保持大豆memecached,然后实现高可用

 参考链接:https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration

上面如果不能访问或者没法下载这个包话: https://pan.baidu.com/s/1KQsf7jJwi9zC8kMq2K5YZw 提取码: 2333

[root@tom1 ~]# unzip tomcat-memcache-jar.zip
[root@tom1 ~]# cd jar/
[root@tom1 jar]# ls
asm-5.2.jar                              minlog-1.3.1.jar
kryo-3.0.3.jar                           msm-kryo-serializer-2.3.2.jar
kryo-serializers-0.45.jar                objenesis-2.6.jar
memcached-session-manager-2.3.2.jar      reflectasm-1.11.9.jar
memcached-session-manager-tc9-2.3.2.jar  spymemcached-2.12.3.jar
#将上面的全部丢给/usr/local/tomcat/lib/
[root@tom1 jar]# cp -p ./* /usr/local/tomcat/lib/

我们需要配置一下tomcat的context.xml文件,这个文件是针对于 web运行时的环境和资源环境,尤其常用于配置 JNDI 数据源、监听器和 Session 管理等。

添加这些配置

    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
        memcachedNodes="n1:192.168.118.172:11211,n2:192.168.118.173:11211"
        failoverNodes="n1"
        requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
     transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"/>

上面主要是来自MSM插件,用来实现Session共享的,其中字段memcachedNodes定义了两个节点分别为172和173的11211端口,也就是memcached监听的端口。failoverNodes表示优先不使用的节点,也就是优先存储在n2节点,当n2不可用时,才用n1。注:这里有个技巧,也就时我们配置的优先不用的节点是和tomcat共同在一起的主机IP,也就是本台主机优先存储于其他的主机上面,实在不行后才存储在本台主机上。这种优先不用本机的策略可以避免单价故障导致数据丢失,是一种构建高可用集群的经典做法

大约这个位置,不要写出<Context> 

 准备一份jsp文件用来测试

[root@tom1 ~]# cat /usr/local/tomcat/webapps/ROOT/test.jsp
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info:
<%
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>
<%
out.println("<br> ID " + session.getId()+"<br>");
String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
out.print("<b>Session list</b>");
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println( name + " = " + value+"<br>");
System.out.println( name + " = " + value);
}
%>
<form action="test.jsp" method="POST">
name:<input type=text size=20 name="dataName">
<br>
key:<input type=text size=20 name="dataValue">
<br>
<input type=submit>
</form>
</body>
</html>

然后自己一定要关闭selinux和关闭firewalld

插入几组数据,然后刷新浏览器也是依旧在172这台主机

然后我们人为的关闭172着他主机,你会发现里面的存储数据也是一样的 

这里的test=123没有了是由于它存储时间到了,不影响效果。可以看到起到了session保持的效果,即使一台主句挂了,也无所谓


网站公告

今日签到

点亮在社区的每一天
去签到