springboot项目使用ehcache 作为缓存时,多节点部署导致的令牌认证失败的问题

项目技术栈:
前端VUE 部署容器Nginx  
后端springboot 部署容器Tomcat

一、部署架构

 

前端服务
IP地址
后端服务
IP地址
前端F5
IP1
后端F5
IP4
Nginx1
IP2
Application1
IP5
Nginx2
IP3
Application2
IP6
前端项目部署高可用,通过F5负载均衡两台Nginx的Web服务器,后端通过一台F5负载均衡两台后端应用服务器。

二、配置方案

1 前端 项目的 config.js 配置
Nginx1 部署的前端代码, config.js 配置,VUE_APP_API_BASE_URL配置为Nginx1 的地址
window.basic = {
    production: {
    VUE_APP_API_BASE_URL: 'http://IP2:9077/basedp',
    VUE_APP_SEARCH_TYPE: 'like'
  }
}

Nginx2部署的前端代码,config.js 配置,VUE_APP_API_BASE_URL配置为Nginx2 的地址

window.basic = {
    production: {
    VUE_APP_API_BASE_URL: 'http://IP3:9077/basedp',
    VUE_APP_SEARCH_TYPE: 'like'
  }
}
2 Nginx 配置
Nginx1 nginx.conf 配置,当 Nginx1 接收到请求后将 /basedp/ 路径的转发给后端 F5
server {
    listen 9077;
    server name IP1;


    location /basedp/ {
        proxy pass http://IP4:9088/;
        proxy set header Host $host;
        proxy set header X-Real-IP $remote addr;
        proxy set header X-Forwarded-For $proxy add x forwarded for;
    }
}

Nginx2 nginx.conf配置,当Nginx2接收到请求后将/basedp/路径的转发给后端F5

server {
    listen 9077;
    server name IP1;


    location /basedp/ {
        proxy pass http://IP4:9088/;
        proxy set header Host $host;
        proxy set header X-Real-IP $remote addr;
        proxy set header X-Forwarded-For $proxy add x forwarded for;
    }
}
3 )后端 F5 配置会话保持

 三、处理流程

请求流程:

1. 浏览器访问前端F5获取前端登录页面的静态资源

2. 前端F5转发登录请求到Nginx2

3. Nginx2返回登录页面的静态资源给浏览器,浏览器对静态资源进行渲染(Nginx2上的项目基础路径配置为Nginx2)

4. 浏览器发送登录请求给Nginx2

5. Nginx2 转发登录请求到后端F5(后端F5配置会话保持)

6. 后端F5将登录请求转发到Application1,Application1将生成的令牌存储到Application1的缓存中

7. Application1将登录的结果返回给前端浏览器

8. 浏览器发送获取首页数据的请求给Nginx2

9. Nginx2转发请求到后端F5

10. 后端F5转发获取首页数据的请求到Application1

11. Application1返回首页首页的数据给浏览器

四、异常配置流程分析

请求流程:

(1)浏览器访问前端F5获取前端登录页面的静态资源

(2)前端F5转发登录请求到Nginx1

(3)Nginx1返回前端静态资源给浏览器,浏览器对静态资源进行渲染

(4)浏览器发送登录请求给前端F5

(5)前端F5将登录请求转发到Nginx2

(6)Nginx2 转发登录请求到Application1,Application1将生成的令牌存储到Application1的缓存中

(7)Application1将登录的结果返回给前端浏览器

(8)浏览器发送获取首页数据的请求给前端F5

(9)前端F5转发获取首页数据的请求给Nginx2

(10)Nginx2转发请求到后端F5

(11)后端F5转发获取首页数据的请求到Application2

(12)因为登录令牌的缓存数据还未同步到Application2,因此会导致请求因为令牌认证失败导致请求失败。

备注:因为应用使用Ehcache做应用的缓存,而两个应用中的Ehcache缓存需要相互同步,缓存同步需要一定的时间,这时如果前端登录请求是调用的Application(1)的登录接口,这时令牌就是存储在Application(1)的内存中,登录成功进入系统时,如果请求访问被转发到Application(2)上,这时因为Application(2)中的内存中的令牌信息还没有同步过来,导致请求失败。

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1. 添加 Ehcache 依赖 在 Maven 中添加 Ehcache 的依赖: ```xml <dependency> <groupId>org.ehcache</groupId> <artifactId>ehcache</artifactId> <version>3.8.1</version> </dependency> ``` 2. 创建 Ehcache 配置文件 在项目的 classpath 下创建 Ehcache 的配置文件 ehcache.xml,配置缓存策略和缓存区域。 示例: ```xml <config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://www.ehcache.org/v3' xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd"> <cache alias="userCache"> <key-type>java.lang.String</key-type> <value-type>com.example.User</value-type> <expiry> <ttl unit="seconds">60</ttl> <tti unit="seconds">30</tti> </expiry> <resources> <heap unit="entries">100</heap> <offheap unit="MB">10</offheap> </resources> </cache> </config> ``` 3. 配置 Ehcache 缓存管理器 在 Spring Boot 中,可以通过注解 @EnableCaching 和 @Configuration 注解来配置 Ehcache 缓存管理器。 示例: ```java @Configuration @EnableCaching public class CacheConfig { @Bean public CacheManager cacheManager() { Resource resource = new ClassPathResource("ehcache.xml"); Configuration configuration = ConfigurationFactory.parseConfiguration(resource.getInputStream()); return CacheManagerBuilder.newCacheManagerBuilder() .withCache("userCache", UserCacheConfigurationBuilder.newUserCacheConfigurationBuilder().buildConfig(String.class, User.class)) .withCache("bookCache", BookCacheConfigurationBuilder.newBookCacheConfigurationBuilder().buildConfig(Long.class, Book.class)) .withConfiguration(configuration) .build(true); } } ``` 4. 使用 Ehcache 缓存管理器 在需要使用缓存的方法上添加 @Cacheable、@CachePut 或 @CacheEvict 注解来实现缓存的读取、写入和删除。 示例: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserRepository userRepository; @Cacheable(value = "userCache", key = "#id") public User getUserById(String id) { return userRepository.findById(id).orElse(null); } @CachePut(value = "userCache", key = "#user.id") public User saveOrUpdateUser(User user) { return userRepository.save(user); } @CacheEvict(value = "userCache", key = "#id") public void deleteUserById(String id) { userRepository.deleteById(id); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独行客-编码爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值