目录结构
src-main-java-com-cache-config/controller/service
src-main-resources-application.yml/bootstrap.yml/lockback-spring.xml
src-pom.xml
java
config.RedisConfig
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.lang.reflect.Method;
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Override
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(target.getClass().getName());
stringBuilder.append(method.getName());
for (Object param : params) {
stringBuilder.append(params.toString());
}
return stringBuilder.toString();
}
};
}
@Bean
public CacheManager cacheManager(LettuceConnectionFactory connectionFactory) {
//以锁写入的方式创建我们的写入对象
RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
//创建默认的缓存配置对象
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
//根据我们的默认配置和写入方式创建缓存的管理器
RedisCacheManager manager = new RedisCacheManager(writer, cacheConfiguration);
return manager;
}
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory factory) {
RedisTemplate<String,Object> template = new RedisTemplate();
template.setConnectionFactory(factory);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
config.Swaggerconfig
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
@Configuration
public class SwaggerConfig {
@Value("${swagger.title}")
private String title;
@Value("${swagger.description}")
private String description;
@Value("${swagger.contactName}")
private String contactName;
@Value("${swagger.email}")
private String email;
@Value("${swagger.licenseUrl}")
private String licenseUrl;
@Value("${swagger.version}")
private String version;
@Value("${swagger.basePackge}")
private String basePackge;
@Bean
public Docket docket(ApiInfo apiInfo) {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo)
.select().apis(RequestHandlerSelectors.basePackage(basePackge)).paths(PathSelectors.any()).build();
}
@Bean
public ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title(title)
.description(description)
.contact(new Contact(contactName, null, email))
.version(version)
.licenseUrl(licenseUrl)
.build();
}
}
controller.CacheController
import com.qianfeng.smsplatform.cache.service.CacheService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import java.util.Set;
@RestController
@RequestMapping("/cache")
public class CacheController {
private static final Logger LOGGER = LoggerFactory.getLogger(CacheController.class);
@Autowired
private CacheService cacheService;
/**
*
* @param key set 的 key
* @param value
* @param expireSecond 有效期 是一个秒
*/
@GetMapping(value = "/save2cache")
@ApiOperation("存储字符串类型的数据")
public boolean save2Cache(@ApiParam(name = "key",required = true,value = "保存的 key") String key,
@ApiParam(name = "value",required = true,value = "保存的 value") String value,
@ApiParam(name = "expireSecond",required = true,value = "有效期")Integer expireSecond) {
LOGGER.error("save2cache执行了:传递的 key 是{},value 是{},有效期是{}",key,value,expireSecond);
cacheService.save2Cache(key,value,expireSecond);
return true;
}
@GetMapping("/get/{key}")
@ApiOperation("从 redis 中获取字符串类型的数据")
public String get(@PathVariable String key) {
return cacheService.get(key);
}
//
// /**
// * 这个方法应该要接收具体类型的参数,而不是直接接收一个 Object
// * @param key
// * @param value
// */
// @GetMapping(value = "/save2cache")
// public void save2Cache(String key, Object value, Integer expireSecond) {
// cacheService.save2Cache(key,value,expireSecond);
// }
//
// /**
// * 这个方法应该要接收具体类型的参数,而不是直接接收一个 Object
// * @param key
// * @param value
// */
// @GetMapping(value = "/save2cache")
// public void save2Cache(String key, Object value) {
// cacheService.save2Cache(key,value);
// }
@GetMapping(value = "/save2cache/{key}/{value}")
@ApiOperation("永久保存数据到redis")
public boolean save2Cache(@PathVariable String key,@PathVariable String value) {
LOGGER.error("save2cache执行了 key:{} value:{}",key,value);
cacheService.save2Cache(key,value);
return true;
}
//因为我们还没有考虑好存放的具体是对象是什么,所以暂时还无法编写获取对象的方法,实际上就是调用了 get 方法
@RequestMapping("/getbject/{key}")
public Object getObject(@PathVariable String key) {
return cacheService.getObject(key);
}
@ApiOperation("从 redis 中删除指定 key")
@PostMapping("/delete")
public Long del(String... keys) {
LOGGER.error("delete执行了 keys{}",keys);
return cacheService.del(keys);
}
@PostMapping("/expire/{key}/{seconds}")
@ApiOperation("给指定的 key 设置有效期")
public boolean expire(@PathVariable String key, @PathVariable long seconds) {
LOGGER.error("expire执行了 keys{} seconds{}",key,seconds);
return cacheService.expire(key, seconds);
}
@GetMapping("/incr")
@ApiOperation("递增")
public long incr(String key, @RequestParam(defaultValue = "1") long delta) {
LOGGER.error("incr执行了 keys{} delta{}",key,delta);
return cacheService.incr(key,delta);
}
@GetMapping("/decr")
@ApiOperation("递减")
public long decr(String key,@RequestParam(defaultValue = "-1") long delta) {
LOGGER.error("decr执行了 keys{} delta{}",key,delta);
return cacheService.decr(key,delta);
}
@GetMapping("/hmget/{key}")
@ApiOperation("从 redis 中获取 hash 类型的数据")
public Map<Object, Object> hGetAll(@PathVariable String key) {
LOGGER.error("hmget执行了 key{}",key);
return cacheService.hGetAll(key);
}
/**
* 注意,这个方法要有返回值,哪怕随便返回一个东西都行,否则调用方可能会出现空指针异常,不知道什么情况
* @param key
* @param map
* @return
*/
@PostMapping("/hmset/{key}")
@ApiOperation("保存 json 到 redis 的 hash 中")
public boolean hMset(@PathVariable String key, @RequestBody Map<String, Object> map) {
LOGGER.error("hMset执行了 key{} map{}",key,map);
cacheService.hMset(key, map);
return true;
}
@RequestMapping(value = "/hget/{key}/{field}", method = RequestMethod.GET)
public String hget(@PathVariable("key")String key, @PathVariable("field")String field){
Object result = cacheService.hget(key, field);
return result == null ? null : result.toString();
}
@RequestMapping("/keys/{keyPattern}")
public Set<String> getKeys(@PathVariable String keyPattern) {
return cacheService.getKeys(keyPattern);
}
@PostMapping("/zadd/{key}/{value}/{score}")
public boolean zAdd(@PathVariable String key,@PathVariable String value, @PathVariable double score){
return cacheService.zAdd(key, value, score);
}
/**
* 获取 zet 指定范围内的数据
* @param key
* @param min
* @param max
*/
@RequestMapping("/zrangebyscore/{key}/{min}/{max}")
public Set<Object> zRangeByScore(@PathVariable String key,@PathVariable double min,@PathVariable double max){
return cacheService.zRangeByScore(key, min, max);
}
}
service.CacheService
import java.util.Map;
import java.util.Set;
public interface CacheService {
/**
* 保存数据到缓存中
* @param key
* @param value
* @param expireSecond
*/
void save2Cache(String key, String value, Integer expireSecond);
void save2Cache(String key, Object value, Integer expireSecond);
void save2Cache(String key, Object value);
void save2Cache(String key, String value);
/**
* 查询
* @param key
* @return
*/
String get(String key);
/**
* 如果当时放的是对象,取出来应该转成对象
* @param key
* @return
*/
Object getObject(String key);
/**
* 删除 key
* @param keys
* @return
*/
Long del(String... keys);
/**
* 设置有效期
* @param key
* @param seconds
* @return
*/
boolean expire(String key, long seconds);
/**
* 自增
* @param key
* @param delta 步长
* @return
*/
long incr(String key, long delta);
/**
* 自减
* @param key
* @param delta
* @return
*/
long decr(String key, long delta);
/**
* 查询 hash 的所有数据
* @param key
* @return
*/
Map<Object, Object> hGetAll(String key);
/**
* hash 的存放数据
* @param key
* @param map
*/
void hMset(String key, Map<String, Object> map);
/**
* 从 hash 中获取某个属性的值
* @param key
* @param field
* @return
*/
Object hget(String key, String field);
/**
* 查询 redis 中以符合表达式的 key
* @param keyPattern
* @return
*/
Set<String> getKeys(String keyPattern);
/**
* 向 redis 中存放 zet 数据
* @param key
* @param value
* @param score
* @return
*/
boolean zAdd(String key, String value, double score);
/**
* 获取 zet 指定范围内的数据
* @param key
* @param min
* @param max
*/
Set<Object> zRangeByScore(String key, double min, double max);
}
service.impl.RedisServiceImpl
import com.qianfeng.smsplatform.cache.service.CacheService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Service
public class RedisServiceImpl implements CacheService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Override
public void save2Cache(String key, String value, Integer expireSecond) {
redisTemplate.opsForValue().set(key, value, expireSecond, TimeUnit.SECONDS);
}
@Override
public void save2Cache(String key, Object value, Integer expireSecond) {
redisTemplate.opsForValue().set(key, value, expireSecond, TimeUnit.SECONDS);
}
@Override
public void save2Cache(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}
@Override
public void save2Cache(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
@Override
public String get(String key) {
// redisTemplate.setKeySerializer(new StringRedisSerializer());
// redisTemplate.setValueSerializer(new StringRedisSerializer());
Object result = redisTemplate.opsForValue().get(key);
return (String) result;
}
@Override
public Object getObject(String key) {
return redisTemplate.opsForValue().get(key);
}
@Override
public Long del(String... keys) {
return redisTemplate.delete(CollectionUtils.arrayToList(keys));
}
@Override
public boolean expire(String key, long seconds) {
return redisTemplate.expire(key,seconds,TimeUnit.SECONDS);
}
@Override
public long incr(String key, long delta) {
return redisTemplate.opsForValue().increment(key,delta);
}
@Override
public long decr(String key, long delta) {
return redisTemplate.opsForValue().decrement(key,delta);
}
@Override
public Map<Object, Object> hGetAll(String key) {
return redisTemplate.opsForHash().entries(key);
}
@Override
public void hMset(String key, Map<String, Object> map) {
redisTemplate.opsForHash().putAll(key, map);
}
@Override
public Object hget(String key, String field) {
return redisTemplate.opsForHash().get(key,field);
}
@Override
public Set<String> getKeys(String keyPattern) {
return redisTemplate.keys(keyPattern);
}
@Override
public boolean zAdd(String key, String value, double score) {
redisTemplate.opsForZSet().add(key, value, score);
return true;
}
@Override
public Set<Object> zRangeByScore(String key, double min, double max) {
Set<Object> objects = redisTemplate.opsForZSet().rangeByScore(key, min, max);
return objects;
}
}
CacheStartApp
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@SpringBootApplication
@EnableDiscoveryClient
@EnableSwagger2
public class CacheStartApp {
public static void main (String[] args){
SpringApplication.run(CacheStartApp.class,args);
}
}
resources
application.yml
server:
port: 8888
swagger:
title: 缓存服务API列表
description: 没有描述
contactName: WisemanDong
email: WisemanDong@qq.com
licenseUrl: https://www.apache.org/licenses/LICENSE-2.0
version: 9020.2020.2020
basePackge: com.q******g.smsplatform.cache.controller
bootstrap.yml
spring:
application:
name: cache-service
cloud:
config:
discovery:
enabled: true
service-id: SMS_PLATFORM_CONFIG_SERVER
label: master
profile: '@profileActive@'
profiles:
active: '@profileActive@'
#理论上应该放在bootstrap-local.yml 文件中,但是没有加载,所以先挪过来
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="6000000" debug="false">
<property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} %-5p [%t:%c{1}:%L] - %msg%n"/>
<property name="LOG_PATH" value="./smsplatform/logs/cache/"/>
<!-- 系统级配置文件 开始 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${LOG_PATTERN}</Pattern>
</layout>
</appender>
<!-- stdout -->
<appender name="rootstdout"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${LOG_PATH}rootstdout.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<FileNamePattern>${LOG_PATH}rootstdout.%i.log.zip</FileNamePattern>
<MinIndex>1</MinIndex>
<MaxIndex>20</MaxIndex>
</rollingPolicy>
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${LOG_PATTERN}</Pattern>
</layout>
</appender>
<!-- debug -->
<appender name="rootDebug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${LOG_PATH}root-debug.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<FileNamePattern>${LOG_PATH}root-debug.%i.log.zip</FileNamePattern>
<MinIndex>1</MinIndex>
<MaxIndex>10</MaxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${LOG_PATTERN}</Pattern>
</layout>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- info -->
<appender name="rootInfo" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${LOG_PATH}root-info.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<FileNamePattern>${LOG_PATH}root-info.%i.log.zip</FileNamePattern>
<MinIndex>1</MinIndex>
<MaxIndex>10</MaxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${LOG_PATTERN}</Pattern>
</layout>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- warn -->
<appender name="rootWarn" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${LOG_PATH}root-warn.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<FileNamePattern>${LOG_PATH}root-warn.%i.log.zip</FileNamePattern>
<MinIndex>1</MinIndex>
<MaxIndex>10</MaxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${LOG_PATTERN}</Pattern>
</layout>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- error -->
<appender name="rootError" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${LOG_PATH}root-error.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_PATH}root-error.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${LOG_PATTERN}</Pattern>
</layout>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>Error</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<springProfile name="local">
<root level="info">
<!-- 本地测试时使用,将日志打印到控制台,实际部署时请注释掉 -->
<appender-ref ref="STDOUT"/>
<appender-ref ref="rootstdout"/>
<appender-ref ref="rootDebug"/>
<appender-ref ref="rootInfo"/>
<appender-ref ref="rootWarn"/>
<appender-ref ref="rootError"/>
</root>
</springProfile>
<springProfile name="dev">
<root level="info">
<!-- 本地测试时使用,将日志打印到控制台,实际部署时请注释掉 -->
<appender-ref ref="rootstdout"/>
<appender-ref ref="rootDebug"/>
<appender-ref ref="rootInfo"/>
<appender-ref ref="rootWarn"/>
<appender-ref ref="rootError"/>
</root>
</springProfile>
<springProfile name="prod">
<root level="info">
<!-- 本地测试时使用,将日志打印到控制台,实际部署时请注释掉 -->
<appender-ref ref="rootstdout"/>
<appender-ref ref="rootDebug"/>
<appender-ref ref="rootInfo"/>
<appender-ref ref="rootWarn"/>
<appender-ref ref="rootError"/>
</root>
</springProfile>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<jmxConfigurator/>
</configuration>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>sms-platformnz1907</artifactId>
<groupId>com.qianf</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sms-platform-cache</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
</dependencies>
<!--
指定资源文件目录,防止无法读到我们的属性
-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>local</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<profileActive>local</profileActive>
</properties>
</profile>
<profile>
<id>dev</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<profileActive>dev</profileActive>
</properties>
</profile>
<profile>
<id>prod</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<profileActive>prod</profileActive>
</properties>
</profile>
</profiles>
</project>
search applicaiton.yml
server:
port: 24678
spring:
application:
name: sms-platform-search
rabbitmq:
host: 192.168.3.19
virtual-host: /test
data:
elasticsearch:
index:
name: sms_submit_log
type: sms_submit_log_type
host: 192.168.3.18
port: 9000
connectTimeOut: 1000
socketTimeOut: 30000
connectionRequestTimeOut: 500
maxConnectNum: 100
maxConnectPerRoute: 100
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka
Cache服务调用
CacheService
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@FeignClient(value = "CACHE-SERVICE", fallback = CacheServiceFallback.class)
public interface CacheService {
@RequestMapping(value = "/cache/get/{key}", method = RequestMethod.GET)
String get(@PathVariable("key") String key);
@RequestMapping(value = "/cache/getbject/{key}", method = RequestMethod.GET)
Object getObject(@PathVariable("key") String key);
@RequestMapping(value = "/cache/delete", method = RequestMethod.POST)
boolean del(@RequestParam("keys") String... keys);
@RequestMapping(value = "/cache/hmset/{key}", method = RequestMethod.POST)
boolean hmset(@PathVariable("key") String key, @RequestBody Map map);
@RequestMapping(value = "/cache/hmget/{key}", method = RequestMethod.GET)
public Map hmget(@PathVariable("key") String key);
@RequestMapping(value = "/cache/save2cache", method = RequestMethod.GET)
void set(@RequestParam("key") String key, @RequestParam("value") String value, @RequestParam("expireSecond") Long expireSecond);
@RequestMapping(value = "/cache/save2cache/{key}/{value}", method = RequestMethod.GET)
void saveCache(@PathVariable("key") String key, @PathVariable("value") String value);
@RequestMapping(value = "/cache/incr", method = RequestMethod.GET)
public Long incr(@RequestParam("key") String key, @RequestParam("delta") long value);
}
CacheServiceFallback+startApp
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class CacheServiceFallback implements CacheService {
@Override
public String get(String key) {
return "";
}
@Override
public Object getObject(String key) {
return null;
}
@Override
public boolean del(String... keys) {
return false;
}
@Override
public boolean hmset(String key, Map map) {
return false;
}
@Override
public Map hmget(String key) {
return null;
}
@Override
public void set(String key, String value, Long expireSecond) {
}
@Override
public void saveCache(String key, String value) {
}
@Override
public Long incr(String key, long value) {
return null;
}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@ServletComponentScan//扫描我们的 servlet 注解相关的对象
@EnableFeignClients
public class InterfaceStartApp {
public static void main (String[] args){
SpringApplication.run(InterfaceStartApp.class,args);
}
}
Cache2
Cache2-application.yml
server:
port: 30000
spring:
application:
name: lcsd-sms-platform-cache
redis:
host: woaijava.haha
port: 8400
password: redis001
database: 13
timeout: 100000
eureka:
client:
service-url:
defaultZone: http://admin:admin@localhost:10000/eureka/
Cache2-CacheService
import java.util.Map;
import java.util.Set;
public interface CacheService {
//保存数据
Boolean set(String key, Object value, int expireTime);
Boolean set(String key, String value, int expireTime);
Boolean set(String key, Object value);
Boolean set(String key, String value);
//获取数据
String get(String key);
Object getAndSet(String key, String value);
Object getObject(String key);
//查询大小
long size(String key);
//批量删除
void del(String... keys);
//设置生存时间
boolean expire(String key, long seconds);
//获取生存时间
long getExpire(String key);
//自增number
long incr(String key, long number);
//自减number
long decr(String key, long number);
//查询
Set<String> keys(String pattern);
//hash查询
Map<Object, Object> hget(String key);
//hash添加
boolean hset(String key, Map<String, Object> map);
//========================重复的方法by波以2为结尾,如果用的顺手酌情使用========================
String getFromRedis2(String key); //从redis获取数据
boolean save2redis2(String key, String value, long expireTime); //保存到redis
boolean deleteKey2(String key); //删除key
boolean expire2(String key, long expireTime); //设置有效期
Long getAutoIncrementId2(String key, int count); //自增
//从redis中获取指定的key对应的set集合
Set<String> sMembers2(String key);
Long sadd2(String key, String value, long expireTime);
Long sadd2(String key, String[] value, long expireTime);
String hGet2(String key, String field);
Map<Object, Object> hGetAll2(String key);
Set<String> keys2(String pattern);
}
Cache2-CacheServiceImpl
import com.netflix.discovery.converters.Auto;
import com.qianfeng.service.CacheService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Service
public class CacheServiceImpl implements CacheService {
Logger logger = LoggerFactory.getLogger (CacheServiceImpl.class);
@Autowired
private StringRedisTemplate template;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* @param key
* @param value
* @param expireTime
* @return
*/
@Override
public Boolean set(String key, Object value, int expireTime) {
try {
redisTemplate.opsForValue ().set (key, value, expireTime, TimeUnit.SECONDS);
return true;
} catch (Exception e) {
e.printStackTrace ();
return false;
}
}
/**
* @param key
* @param value
* @param expireTime
* @return
*/
@Override
public Boolean set(String key, String value, int expireTime) {
try {
redisTemplate.opsForValue ().set (key, value);
redisTemplate.expire(key,10000,TimeUnit.SECONDS);
return true;
} catch (Exception e) {
e.printStackTrace ();
return false;
}
}
/**
* @param key
* @param value
* @return
*/
@Override
public Boolean set(String key, Object value) {
try {
redisTemplate.opsForValue ().set (key, value);
return true;
} catch (Exception e) {
e.printStackTrace ();
return false;
}
}
/**
* @param key
* @param value
* @return
*/
@Override
public Boolean set(String key, String value) {
try {
redisTemplate.opsForValue ().set (key, value);
return true;
} catch (Exception e) {
e.printStackTrace ();
return false;
}
}
/**
* @param key
* @return
*/
@Override
public String get(String key) {
return key == null ? null : (String) redisTemplate.opsForValue ().get (key);
}
/**
* 获取旧值并重新赋值
*
* @param key
* @param value
* @return
*/
@Override
public Object getAndSet(String key, String value) {
return redisTemplate.opsForValue ().getAndSet (key, value);
}
/**
* @param key
* @return
*/
@Override
public Object getObject(String key) {
return key == null ? null : redisTemplate.opsForValue ().get (key);
}
/**
* 获取指定字符串长度
*
* @param key
* @return
*/
@Override
public long size(String key) {
return redisTemplate.opsForValue ().size (key);
}
/**
* @param keys
*/
@Override
public void del(String... keys) {
if (keys != null && keys.length > 0) {
if (keys.length == 1) {
redisTemplate.delete (keys[0]);
} else {
redisTemplate.delete (CollectionUtils.arrayToList (keys));
}
}
}
/**
* 根据key设置生存时间
*
* @param key
* @param seconds
* @return
*/
@Override
public boolean expire(String key, long seconds) {
return redisTemplate.expire (key, seconds, TimeUnit.SECONDS);
}
/**
* 根据key获取过期时间
*
* @param key
* @return 返回0代表永久有效
*/
@Override
public long getExpire(String key) {
return redisTemplate.getExpire (key, TimeUnit.SECONDS);
}
/**
* 自增
*
* @param key
* @param number
* @return
*/
@Override
public long incr(String key, long number) {
if (number < 0) {
throw new RuntimeException ("递增因子必须大于0");
}
return redisTemplate.opsForValue ().increment (key, number);
}
/**
* 递减
*
* @param key
* @param number
* @return
*/
@Override
public long decr(String key, long number) {
if (number < 0) {
throw new RuntimeException ("递减因子必须大于0");
}
return redisTemplate.opsForValue ().increment (key, -number);
}
/**
* @param pattern
* @return
*/
@Override
public Set<String> keys(String pattern) {
return redisTemplate.keys (pattern);
}
/**
* 获取hash对应的所有值
*
* @param key
* @return
*/
@Override
public Map<Object, Object> hget(String key) {
return redisTemplate.opsForHash().entries (key);
}
/**
* 以map集合的形式添加键值对
*
* @param key
* @param map
* @return
*/
@Override
public boolean hset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash ().putAll (key, map);
// redisTemplate.expire(key,1000,TimeUnit.SECONDS);
return true;
} catch (Exception e) {
e.printStackTrace ();
return false;
}
}
//====================以下为2的方法的实现=========================
@Override
public String getFromRedis2(String key) {
logger.error ("从redis中获取字符串数据,key为 {}", key);
return template.opsForValue ().get (key);
}
@Override
public boolean save2redis2(String key, String value, long expireTime) {
logger.error ("save2redis执行了,key为{},value为{},过期时间为{}", key, value, expireTime);
try {
template.opsForValue ().set (key, value);
//
// 设置过期时间
// if(expireTime != -1){
// expireTime = Math.abs(expireTime);
// redisTemplate.expire(key,expireTime,TimeUnit.MILLISECONDS);
// }else{
// //持久化
// redisTemplate.persist(key);
// }
// template.expire (key, expireTime, TimeUnit.MILLISECONDS);
return true;
} catch (Exception e) {
e.printStackTrace ();
logger.error ("save2redis执行失败,key为{},value为{},过期时间为{}", key, value, expireTime);
}
return false;
}
@Override
public boolean deleteKey2(String key) {
try {
template.delete (key);
logger.error ("deleteKey执行了,key为{}", key);
return true;
} catch (Exception e) {
e.printStackTrace ();
logger.error ("deleteKey执行失败,key为{}", key);
}
return false;
}
@Override
public boolean expire2(String key, long expireTime) {
try {
if (expireTime < 0) {
expireTime = Math.abs (expireTime);
}
template.expire (key, expireTime, TimeUnit.MILLISECONDS);
logger.error ("expire执行了,key为{},过期时间为{}", key, expireTime);
return true;
} catch (Exception e) {
e.printStackTrace ();
logger.error ("expire执行失败了,key为{},过期时间为{}", key, expireTime);
}
return false;
}
@Override
public Long getAutoIncrementId2(String key, int count) {
//key如果不存在 会返回1
//如果key对应的数据不是数据或者不是string格式的数据,则会抛出异常
try {
Long increment = template.opsForValue ().increment (key, count);
logger.error ("获取自增数据执行了,key为{},count为{}", key, count);
return increment;
} catch (Exception e) {
e.printStackTrace ();
logger.error ("获取自增数据失败,key为{}", key);
}
return null;
}
@Override
public Set<String> sMembers2(String key) {
try {
Set<String> members = template.opsForSet ().members (key);
logger.error ("获取set集合数据执行了,key为{},", key);
return members;
} catch (Exception e) {
logger.error ("获取set集合数据失败,key为{},", key);
e.printStackTrace ();
}
return null;
}
@Override
public Long sadd2(String key, String value, long expireTime) {
try {
Long result = template.opsForSet ().add (key, value);
if (expireTime != -1) {
//代表需要设置有效期
expireTime = Math.abs (expireTime);
template.expire (key, expireTime, TimeUnit.MILLISECONDS);
} else {
//持久化
template.persist (key);
}
return result;
} catch (Exception e) {
e.printStackTrace ();
}
return null;
}
@Override
public Long sadd2(String key, String[] value, long expireTime) {
try {
Long result = template.opsForSet ().add (key, value);
if (expireTime != -1) {
//代表需要设置有效期
expireTime = Math.abs (expireTime);
template.expire (key, expireTime, TimeUnit.MILLISECONDS);
} else {
//持久化
template.persist (key);
}
return result;
} catch (Exception e) {
e.printStackTrace ();
}
return null;
}
@Override
public String hGet2(String key, String field) {
Object o = template.opsForHash ().get (key, field);
return o == null ? null : o.toString ();
}
@Override
public Map<Object, Object> hGetAll2(String key) {
Map<Object, Object> map = template.opsForHash ().entries (key);
return map;
}
@Override
public Set<String> keys2(String pattern) {
return template.keys (pattern);
}
}
Cache2-CacheController
import com.qianfeng.service.CacheService;
import com.qianfeng.service.impl.CacheServiceImpl;
import io.lettuce.core.RedisException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import java.util.Set;
@RestController
@RequestMapping("/cache")
public class CacheController {
private Logger logger = LoggerFactory.getLogger (CacheServiceImpl.class);
@Autowired
private CacheService cacheService;
//存object对象到cache,不设置过期时间
@PostMapping(value = "/saveObj/{key}/{value}")
public void set(@PathVariable("key") String key, @PathVariable("value") Object value) {
cacheService.set (key, value);
}
//存字符串到cache,并设置过期时间,-1为永不过期
@RequestMapping(value = "/save2Cache", method = RequestMethod.GET)
public void save2Cache(@RequestParam("key") String key,
@RequestParam("value") String value,
@RequestParam("expireSecond") Integer expireSecond) {
checkParams (key);
logger.error ("设置过期时间的key:{},value:{},expireSecond:{}", key, value, expireSecond);
cacheService.set (key, value, expireSecond);
}
//存字符串类型的数据到cache
@RequestMapping(value = "/saveCache", method = RequestMethod.GET)
public void saveCache(@RequestParam("key") String key,
@RequestParam("value") String value) {
checkParams (key);
logger.error ("存的key:{},value:{}", key, value);
cacheService.set (key, value);
}
//获取缓存中的String值
@RequestMapping(value = "/get", method = RequestMethod.GET)
public String get(@RequestParam("key") String key) {
checkParams (key);
logger.info ("获取的key:{}", key);
return cacheService.get (key);
}
//获取缓存中的值object
@RequestMapping(value = "/getObject", method = RequestMethod.GET)
public Object getObject(@RequestParam("key") String key) {
checkParams (key);
logger.error ("获取任意类型的key:{}", key);
return cacheService.getObject (key);
}
//从redis删除字符串类型的数据
@RequestMapping(value = "/del", method = RequestMethod.POST)
public boolean del(@RequestParam("key") String key) {
logger.info ("删除的key:{}", key);
checkParams (key);
cacheService.del (key);
return true;
}
//存map类型的数据到cache
@RequestMapping(value = "hset", method = RequestMethod.POST)
public boolean hset(@RequestParam("key") String key,
@RequestBody Map<String, Object> map) {
checkParams (key);
logger.info ("存map的key:{},map:{}", key, map);
return cacheService.hset (key, map);
}
//返回hash表key中的map值
@RequestMapping(value = "hget", method = RequestMethod.GET)
public Map hget(@RequestParam("key") String key) {
checkParams (key);
logger.info ("获取hash的key:{}", key);
Map<Object, Object> map = cacheService.hget (key);
System.out.println (map.toString ());
return map;
}
//传入一个key,通过redis取得自增id的值
@RequestMapping(value = "/incr", method = RequestMethod.GET)
public Long incr(@RequestParam("key") String key,
@RequestParam("value") long value) {
checkParams (key);
logger.info ("自增的key:{}", key);
return cacheService.incr (key, value);
}
//传入一个key,通过redis取得自减id值
@RequestMapping(value = "/decr", method = RequestMethod.GET)
public Long decr(@RequestParam("key") String key,
@RequestParam("value") long value) {
checkParams (key);
logger.error ("自减的key:{},", key);
return cacheService.decr (key, value);
}
//设置过期时间
@RequestMapping(value = "/expire", method = RequestMethod.GET)
public boolean expire(@RequestParam("key") String key,
@RequestParam("expireSecond") Integer expireSecond) {
checkParams (key);
logger.error ("设置过期时间的key:{}", key);
return cacheService.expire (key, expireSecond);
}
//获取前缀为keys的集合
@RequestMapping(value = "/keys", method = RequestMethod.GET)
public Set<String> keys(@RequestParam("pattern") String pattern) {
checkParams (pattern);
logger.error ("获取集合的key:{}", pattern);
return cacheService.keys (pattern);
}
//检查参数
public void checkParams(String key) {
if (StringUtils.isEmpty (key)) {
throw new RedisException ("参数不能为空");
}
}
//=========以下为2方法的Controller,为了区分上面方法,避免重复,以2做后缀=========
@PostMapping("/set/{key}/{value}/{expireTime}")
boolean save2redis2(@PathVariable String key, @PathVariable String value, @PathVariable long expireTime) {
//此处应该判断key是不是空
if (StringUtils.isEmpty (key)) {
return false;
}
return cacheService.save2redis2 (key, value, expireTime);
}
@GetMapping("/get/{key}")
public String getFromRedis2(@PathVariable("key") String key) {
return cacheService.getFromRedis2 (key);
}
@PostMapping("/delete/{key}")
boolean deleteKey2(@PathVariable String key) {
//此处应该判断key是不是空
if (StringUtils.isEmpty (key)) {
return false;
}
return cacheService.deleteKey2 (key);
}
@PostMapping("/expire/{key}/{expireTime}")
boolean expire2(@PathVariable String key, @PathVariable long expireTime) {
//此处应该判断key是不是空
if (StringUtils.isEmpty (key)) {
return false;
}
return cacheService.expire2 (key, expireTime);
}
@PostMapping("/increment/{key}/{count}")
Long getAutoIncrementId2(@PathVariable String key, @PathVariable int count) {
if (StringUtils.isEmpty (key)) {
return -1L;
}
return cacheService.getAutoIncrementId2 (key, count);
}
@RequestMapping("/smembers/{key}")
public Set<String> sMembers2(@PathVariable String key) {
//此处需要判断key是不是空的
return cacheService.sMembers2 (key);
}
@PostMapping("/sadd/{key}/{value}/{expireTime}")
Long sadd2(@PathVariable String key, @PathVariable String value, @PathVariable long expireTime) {
return cacheService.sadd2 (key, value, expireTime);
}
@PostMapping("/sadd")
Long sadd2(String key, String[] values, long expireTime) {
return cacheService.sadd2 (key, values, expireTime);
}
@RequestMapping("/hget/{key}/{field}")
public String hGet2(@PathVariable String key, @PathVariable String field) {
return cacheService.hGet2 (key, field);
}
@RequestMapping("/hgetall/{key}")
public Map<Object, Object> hGetAll2(@PathVariable String key) {
return cacheService.hGetAll2 (key);
}
@RequestMapping("/keys/{pattern}")
public Set<String> keys2(@PathVariable String pattern) {
return cacheService.keys2 (pattern);
}
}