分布式缓存与Session共享

Memcached(分布式内存缓存)解决两个核心问题:

    1. 高并发读请求压力: 通过缓存热点数据,减少数据库 MySQL 的 I/O 压力。
    1. 集群 Session 丢失: 在多台 Tomcat 服务器之间共享用户登录状态(Session)。

Memcached服务器搭建 (Linux)

1. 安装与配置

  • 环境: CentOS 6
  • 安装命令:
1
2
3
yum -y install memcached
chkconfig memcached on # 设置开机自启
service memcached start # 启动服务
  • 验证: 使用 telnet 192.168.200.143 11211 连接,通过 setget 命令测试存储功能。

2. Spring 客户端配置

applicationContext.xml 中配置客户端连接池:

  • **SockIOPool**:连接池配置,定义 Memcached 服务器地址 (192.168.200.143:11211) 和权重。
  • **MemCachedClient**:注入连接池,提供 set/get 等操作方法。

Spring AOP 自动缓存策略 (核心)

无侵入式缓存,通过 AOP 切面拦截 Service 层的方法,自动实现“读缓存、写缓存、删缓存”,业务代码几乎不需要改动。

1. 核心拦截逻辑

拦截类型 匹配方法 (Pointcut) 执行动作 (Advice)
读取缓存 get* 开头的方法 1. 先查 Memcached。
2. 命中:直接返回数据。
3. 未命中:执行 DB 查询 -> 存入 Memcached -> 返回。
修改缓存 add* / update* / delete* 1. 执行业务逻辑(修改数据库)。
2. 清理缓存:遍历 Memcached 中所有 Key,删除以当前类名开头的 Key(防止脏数据)。

2. 缓存 Key 生成策略

为了保证 Key 的唯一性,采用以下格式:

1
2
3
// 格式:全限定类名 + 方法名 + 序列化后的参数
// 示例:cn.itcast.core.service.ProductServiceImpl.getProductByKey.1
String key = packageName + "." + methodName + "." + JSON.stringify(args);

注意:参数使用 ObjectMapper 序列化为 JSON 字符串,确保不同参数的调用不会产生缓存冲突。


集群 Session 共享

负载均衡环境中,用户请求会被分发到不同的 Tomcat 服务器。由于 Session 默认存储在 Tomcat 内存中,导致用户登录后访问不同 IP 时 Session 丢失(反复退出)。

1.解决方案:CacheSessionProvider

将 Session 数据从 Tomcat 内存迁移到 Memcached 中。

  • 实现类: CacheSessionProvider 实现 SessionProvider 接口。
  • Key 策略: 使用浏览器返回的 JSESSIONID 作为 Memcached 的 Key。
  • Value 结构: Map<String, Serializable> (存储用户对象等属性)。
  • 流程:
    1. login 成功后,将用户对象放入 CacheSessionProvider
    2. Provider 调用 memCachedClient.set(jsessionId, userMap, timeout) 存入 Memcached。
    3. 后续所有请求(无论分发到哪台服务器),都去 Memcached 拿数据,实现状态共享。
    4. logout 时调用 memCachedClient.delete(jsessionId) 销毁数据。

总结:
通过 Memcached 实现了“读写分离”(查询走缓存,修改清缓存)和“状态共享”(Session 集中存),是构建高可用、高性能电商平台的基石。