加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

springboot-42-状态机redis持久化

(2018-02-01 16:16:18)
分类: 微服务

Spring 状态机的创建有两种方式,一种是通过@Configuaration在启动时创建由spring管理的单例状态机,但是这种办法创建的状态机受制于单例模式,无法获取具有大量重复配置的状态机。所以我们可以通过StateMachineBuilder来创建无状态的不受spring管理的状态机。这样可以并发处理多个同样配置的状态机。

http://blog.sina.com.cn/s/blog_7d1968e20102wxm2.html中,我们使用了内存来保存Spring状态机中的某些状态,并在新的状态机中载入这些状态。内存毕竟受限较大,我们试图将其存入mongo或者redis,以方便状态机状态的后续处理。

l  我们可以利用spring-statemachine的自有组件将整个状态机上下文持久化到redismongodb中,在新的事件到来时,利用StateMachineBuilder创建无状态状态机,重载持久化的状态机,也就是本文的内容。

l  也可以利用DDD创建自己的领域模型,包含状态机的状态,自己存入数据库中,并在新的事件到来时,手动读取数据库里的状态,利用StateMachineBuilder创建无状态状态机,手动重载持久化的状态机。

 

1.       依赖

 

<dependency>
   <groupId>
org.springframework.statemachine</groupId>
   <artifactId>
spring-statemachine-core</artifactId>
   <version>
1.2.3.RELEASE</version>
</dependency>

<dependency>
   <groupId>
org.springframework.statemachine</groupId>
   <artifactId>
spring-statemachine-redis</artifactId>
   <version>
1.2.3.RELEASE</version>
</dependency>

 

2.       配置

 

package com.scn7th.simple;

import
com.scn7th.model.Events;
import
com.scn7th.model.States;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.context.annotation.Bean;
import
org.springframework.context.annotation.Configuration;
import
org.springframework.data.redis.connection.RedisConnectionFactory;
import
org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import
org.springframework.statemachine.StateMachinePersist;
import
org.springframework.statemachine.persist.DefaultStateMachinePersister;
import
org.springframework.statemachine.persist.RepositoryStateMachinePersist;
import
org.springframework.statemachine.persist.StateMachinePersister;
import
org.springframework.statemachine.redis.RedisStateMachineContextRepository;
import
org.springframework.statemachine.redis.RedisStateMachinePersister;
import
redis.clients.jedis.JedisPoolConfig;


@Configuration
public class PersistConfig {
   
@Autowired
   
private InMemoryStateMachinePersist inMemoryStateMachinePersist;

   
@Bean(name = "inMemoryPersister")
   
public StateMachinePersister<States, Events, String> inMemoryPersister() {
       
return new DefaultStateMachinePersister<>(inMemoryStateMachinePersist);
   
}

   
@Bean(name = "redisPersister")
   
public RedisStateMachinePersister<States, Events> redisPersister() {
       
return new RedisStateMachinePersister<>(redisPersist());
   
}

   
public StateMachinePersist<States, Events, String> redisPersist() {
        RedisStateMachineContextRepository<States
, Events> repository = new RedisStateMachineContextRepository<>(redisConnectionFactory());
        return new
RepositoryStateMachinePersist<>(repository);
   
}

   


   
@Bean
   
public RedisConnectionFactory redisConnectionFactory(){
        JedisConnectionFactory jedisConnectionFactory =
new JedisConnectionFactory(jedisPoolConfig());
       
jedisConnectionFactory.setDatabase(1);
       
jedisConnectionFactory.setHostName("172.19.67.138");
       
jedisConnectionFactory.setPort(6379);
       
jedisConnectionFactory.setUsePool(true);
        return
jedisConnectionFactory;
   
}

   

   
@Bean
   
public JedisPoolConfig jedisPoolConfig(){
        JedisPoolConfig jedisPoolConfig =
new JedisPoolConfig();
       
jedisPoolConfig.setMaxIdle(60);
       
jedisPoolConfig.setMaxWaitMillis(-1);
       
jedisPoolConfig.setMinIdle(1);
       
jedisPoolConfig.setMaxTotal(60);
        return
jedisPoolConfig;
   
}

}

 

3.       状态机builder

 

package com.scn7th.simple;

import
com.scn7th.model.Events;
import
com.scn7th.model.States;
import
org.springframework.beans.factory.BeanFactory;
import
org.springframework.statemachine.StateMachine;
import
org.springframework.statemachine.config.StateMachineBuilder;
import
org.springframework.stereotype.Component;

import
java.util.EnumSet;


@Component
public class MyStateMachineBuilder {
   
public StateMachine<States, Events> build(BeanFactory beanFactory) throws Exception {
        StateMachineBuilder.Builder<States
, Events> builder = StateMachineBuilder.builder();
       
builder.configureConfiguration()
                .withConfiguration()
                .machineId(
"hehe")
                .beanFactory(beanFactory)
;

       
builder.configureStates()
                .withStates()
                .initial(States.
S0)
                .end(States.
S3)
                .states(EnumSet.allOf(States.
class));

       
builder.configureTransitions()
                .withExternal()
                .source(States.
S0)
                .target(States.
S1)
                .event(Events.
A)
                .and()
                .withExternal()
                .source(States.
S1)
                .target(States.
S0)
                .event(Events.
E)
                .and()
                .withExternal()
                .source(States.
S1)
                .target(States.
S2)
                .event(Events.
B)
                .and()
                .withExternal()
                .source(States.
S2)
                .target(States.
S3)
                .event(Events.
C);

        return
builder.build();
   
}
}

 

4.       测试

 

package com.scn7th.simple;

import
com.scn7th.StatemachinePersistApplicationTests;
import
com.scn7th.model.Events;
import
com.scn7th.model.States;
import
org.junit.Test;
import
org.springframework.beans.factory.BeanFactory;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.statemachine.StateMachine;
import
org.springframework.statemachine.persist.StateMachinePersister;

import
javax.annotation.Resource;


public class SimpleTest extends StatemachinePersistApplicationTests{
   
@Resource(name = "machine1")
   
private StateMachine<States, Events> stateMachine1;

   
@Resource(name = "machine2")
   
private StateMachine<States, Events> stateMachine2;

   
@Autowired
   
private MyStateMachineBuilder myStateMachineBuilder;

   
@Autowired
   
private BeanFactory beanFactory;

   
@Resource(name = "inMemoryPersister")
   
private StateMachinePersister<States, Events, String> inMemoryPersister;

   
@Resource(name = "redisPersister")
   
private StateMachinePersister<States, Events, String> redisPersister;

   
@Test
   
public void testSimple() throws Exception {
       
stateMachine1.start();
       
stateMachine1.sendEvent(Events.A);
       
inMemoryPersister.persist(stateMachine1, "mySM");
        
inMemoryPersister.restore(stateMachine2, "mySM");
       
System.out.println(stateMachine2.getState().getId());
   
}

   
@Test
   
public void testRedis() throws Exception {
       
stateMachine1.start();
       
stateMachine1.sendEvent(Events.A);
       
redisPersister.persist(stateMachine1, "mySMRedis");
       
StateMachine<States, Events> stateMachine3 = myStateMachineBuilder.build(beanFactory);
       
redisPersister.restore(stateMachine3, "mySMRedis");
       
System.out.println(stateMachine3.getState().getId());
       
stateMachine3.sendEvent(Events.B);
       
System.out.println(stateMachine3.getState().getId());
   
}
}

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有