2017-06-23 12 views
0

バージンクォーツジョブを使用して、Redisに接続して操作を実行しています。私は、マスターノードだけに接続するようにRedisTemplateを設定しました。RedisTemplateをリフレッシュする

Redisでフェールオーバーが発生し、新しいマスターが選択された場合、sentinel.confのclient-reconfig-scriptを介して通知されます。この後、私はRedisTemplateを新しいマスターと話すように再配線しようとしています。この再配線部分は機能しません。石英仕事とRedisTemplateため

春のブート設定:

package com.XXX.XXX; 

import org.quartz.JobDetail; 
import org.quartz.SimpleTrigger; 
import org.quartz.Trigger; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Primary; 
import org.springframework.core.io.ClassPathResource; 
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; 
import org.springframework.data.redis.core.RedisTemplate; 
import org.springframework.scheduling.quartz.JobDetailFactoryBean; 
import org.springframework.scheduling.quartz.SchedulerFactoryBean; 
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean; 
import org.springframework.scheduling.quartz.SpringBeanJobFactory; 

import de.chandre.quartz.spring.AutowiringSpringBeanJobFactory; 
import de.chandre.quartz.spring.QuartzSchedulerAutoConfiguration; 

@SpringBootApplication(exclude = { QuartzSchedulerAutoConfiguration.class }) 
public class OrderProcessorApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(OrderProcessorApplication.class, args); 
    } 

    @Bean 
    public JobDetailFactoryBean jobDetail() { 
     JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean(); 
     jobDetailFactory.setJobClass(OrderProcessorJob.class); 
     jobDetailFactory.setDurability(true); 
     return jobDetailFactory; 
    } 

    @Value("${job.interval}") 
    private int interval; 

    @Bean 
    public SimpleTriggerFactoryBean trigger(JobDetail job) { 
     SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean(); 
     trigger.setJobDetail(job); 
     trigger.setRepeatInterval(interval); 
     trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY); 
     return trigger; 
    } 

    @Bean 
    public SchedulerFactoryBean scheduler(Trigger trigger, JobDetail job) { 
     SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean(); 
     schedulerFactory.setConfigLocation(new ClassPathResource("quartz.properties")); 

     schedulerFactory.setJobFactory(springBeanJobFactory()); 
     schedulerFactory.setJobDetails(job); 
     schedulerFactory.setTriggers(trigger); 
     return schedulerFactory; 
    } 

    @Autowired 
    private ApplicationContext ap; 

    @Bean 
    @Primary 
    public SpringBeanJobFactory springBeanJobFactory() { 
     AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory(); 
     jobFactory.setApplicationContext(ap); 
     return jobFactory; 
    } 

    // @Bean 
    // @Qualifier("sentinel") 
    // public RedisTemplate<String, Object> createRedisTemplate() { 
    // RedisSentinelConfiguration sc = new RedisSentinelConfiguration() 
    // .master("redis-cluster") 
    // .sentinel("127.0.0.1", 26179) 
    // .sentinel("127.0.0.1", 26381); 
    // 
    // JedisConnectionFactory jcf = new JedisConnectionFactory(sc); 
    // jcf.setUsePool(true); 
    // jcf.afterPropertiesSet(); 
    // 
    // RedisTemplate rt = new RedisTemplate(); 
    // rt.setConnectionFactory(jcf); 
    // rt.afterPropertiesSet(); 
    // return rt; 
    // } 

    @Bean 
    @Primary 
    public RedisTemplate<String, Object> createMasterOnlyRedisTemplate() { 
     JedisConnectionFactory jcf = new JedisConnectionFactory(); 
     jcf.setHostName("127.0.0.1"); 
     jcf.setPort(6379); 
     jcf.setUsePool(true); 
     jcf.afterPropertiesSet(); 

     RedisTemplate rt = new RedisTemplate(); 
     rt.setConnectionFactory(jcf); 
     rt.afterPropertiesSet(); 
     return rt; 
    } 
} 
センチネルによって呼び出さ

更新RESTサービス:石英ジョブは私が手Redisのために接続しようと横に成功し、リフレッシュを呼び出した後

package com.store.platform; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; 
import org.springframework.data.redis.core.RedisTemplate; 
import org.springframework.http.MediaType; 
import org.springframework.web.bind.annotation.RequestBody; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RestController; 

import com.kohls.store.platform.common.model.ui.UpdateRedisMaster; 

@RestController 
@RequestMapping(path = "/refresh", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) 
public class Test { 

    @Autowired 
    private RedisTemplate<String, Object> rt; 

    @RequestMapping(method = RequestMethod.POST) 
    public void refresh(@RequestBody UpdateRedisMaster um) { 
     JedisConnectionFactory jcf = (JedisConnectionFactory) rt.getConnectionFactory(); 
     jcf.setHostName(um.getIp()); 
     jcf.setPort(um.getPort()); 
     jcf.setShardInfo(null); 
     jcf.afterPropertiesSet(); 
    } 
} 

次の例外:

org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool 
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:204) ~[spring-data-redis-1.8.4.RELEASE.jar:na] 
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:348) ~[spring-data-redis-1.8.4.RELEASE.jar:na] 
    at org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:129) ~[spring-data-redis-1.8.4.RELEASE.jar:na] 
    at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:92) ~[spring-data-redis-1.8.4.RELEASE.jar:na] 
    at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:79) ~[spring-data-redis-1.8.4.RELEASE.jar:na] 
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:194) ~[spring-data-redis-1.8.4.RELEASE.jar:na] 
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:169) ~[spring-data-redis-1.8.4.RELEASE.jar:na] 
    at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:91) ~[spring-data-redis-1.8.4.RELEASE.jar:na] 
    at org.springframework.data.redis.core.DefaultValueOperations.set(DefaultValueOperations.java:182) ~[spring-data-redis-1.8.4.RELEASE.jar:na] 
    at com.XXX.platform.OrderProcessorJob.execute(OrderProcessorJob.java:32) ~[classes/:na] 
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.3.0.jar:na] 
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [quartz-2.3.0.jar:na] 
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool 
    at redis.clients.util.Pool.getResource(Pool.java:53) ~[jedis-2.9.0.jar:na] 
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:226) ~[jedis-2.9.0.jar:na] 
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:16) ~[jedis-2.9.0.jar:na] 
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:194) ~[spring-data-redis-1.8.4.RELEASE.jar:na] 
    ... 11 common frames omitted 
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused) 
    at redis.clients.jedis.Connection.connect(Connection.java:207) ~[jedis-2.9.0.jar:na] 
    at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:93) ~[jedis-2.9.0.jar:na] 
    at redis.clients.jedis.BinaryJedis.connect(BinaryJedis.java:1767) ~[jedis-2.9.0.jar:na] 
    at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:106) ~[jedis-2.9.0.jar:na] 
    at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:868) ~[commons-pool2-2.4.2.jar:2.4.2] 
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:435) ~[commons-pool2-2.4.2.jar:2.4.2] 
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363) ~[commons-pool2-2.4.2.jar:2.4.2] 
    at redis.clients.util.Pool.getResource(Pool.java:49) ~[jedis-2.9.0.jar:na] 
    ... 14 common frames omitted 
Caused by: java.net.ConnectException: Connection refused (Connection refused) 
    at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_121] 
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_121] 
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_121] 
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_121] 
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_121] 
    at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_121] 
    at redis.clients.jedis.Connection.connect(Connection.java:184) ~[jedis-2.9.0.jar:na] 
    ... 21 common frames omitted 

私は一貫したデータを取得したいなぜ私は読み書き用にマスターを使用したいのか、冗長性とフェイルオーバー用にスレーブを使用するのかということです。

私はこの問題について2日間殴られました。どんな助けも高く評価されます。

答えて

0

自分のRedisConnectionFactoryを作成して問題を解決できました。

public class SPRedisConnectionFactory implements InitializingBean, RedisConnectionFactory, DisposableBean { 

    private Jedis jedis; 

    private String[] nodes; 

    private Map<String, String[]> nodeMap; 

    @Value("${master.node}") 
    private String masterNode; 

    @Override 
    public void afterPropertiesSet() throws Exception { 
     nodeMap = Arrays.stream(this.nodes) 
       .map(n -> n.split(":")) 
       .collect(toMap(n -> n[0] + ":" + n[1], n -> n)); 
     System.out.println(nodeMap); 
    } 

    @Override 
    public RedisConnection getConnection() { 
     String[] master = nodeMap.get(masterNode); 
     jedis = new Jedis(master[0], parseInt(master[1]), 2000); 
     jedis.connect(); 

     JedisConnection c = new JedisConnection(jedis); 
     return c; 
    } 

    @Override 
    public RedisClusterConnection getClusterConnection() { 
     throw new UnsupportedOperationException(); 
    } 

    @Override 
    public boolean getConvertPipelineAndTxResults() { 
     return false; 
    } 

    @Override 
    public RedisSentinelConnection getSentinelConnection() { 
     throw new UnsupportedOperationException(); 
    } 

    @Override 
    public DataAccessException translateExceptionIfPossible(RuntimeException e) { 
     return null; 
    } 

    @Override 
    public void destroy() throws Exception { 
     jedis.disconnect(); 
    } 
} 

Connections to multiple Redis servers with Spring Data Redisからこのアイデアを得ました。

関連する問題