vertx限流
This commit is contained in:
parent
99fcb47f55
commit
220ec74d5a
@ -0,0 +1,18 @@
|
||||
package com.sf.vertx.api.pojo;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ApiCurrentLimitingConfig implements Serializable {
|
||||
private static final long serialVersionUID = 8042924090032324660L;
|
||||
private Integer threshold; // 2, // 限流阈值
|
||||
private Integer timeWindow; //1, //时间窗口,单位s
|
||||
private String defaultResponse;
|
||||
// ": "{
|
||||
// \"msg\": \"接口繁忙请重试\",
|
||||
// \"code\": 501,
|
||||
// \"data\": \"到达限流阈值\",
|
||||
// }" // 默认限流响应,JSON字符串。
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.sf.vertx.api.pojo;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class AppCurrentLimitingConfig implements Serializable {
|
||||
private static final long serialVersionUID = 5851544674347437522L;
|
||||
private Integer threshold; // 2, // 限流阈值(APP总和)
|
||||
private Integer timeWindow; //1, //时间窗口,单位s
|
||||
private String defaultResponse;
|
||||
// ": "{
|
||||
// \"msg\": \"接口繁忙请重试\",
|
||||
// \"code\": 501,
|
||||
// \"data\": \"到达限流阈值\",
|
||||
// }" // 默认限流响应,JSON字符串。
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding//src/main/resources=UTF-8
|
||||
encoding//src/test/java=UTF-8
|
||||
encoding//src/test/resources=UTF-8
|
||||
encoding/<project>=UTF-8
|
||||
|
@ -0,0 +1,48 @@
|
||||
package com.sf.vertx.config;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.SerializationException;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONReader;
|
||||
import com.alibaba.fastjson2.JSONWriter;
|
||||
|
||||
/**
|
||||
* Redis使用FastJson序列化
|
||||
*
|
||||
* @author ztzh
|
||||
*/
|
||||
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
|
||||
{
|
||||
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
|
||||
|
||||
private Class<T> clazz;
|
||||
|
||||
public FastJson2JsonRedisSerializer(Class<T> clazz)
|
||||
{
|
||||
super();
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] serialize(T t) throws SerializationException
|
||||
{
|
||||
if (t == null)
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T deserialize(byte[] bytes) throws SerializationException
|
||||
{
|
||||
if (bytes == null || bytes.length <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String str = new String(bytes, DEFAULT_CHARSET);
|
||||
|
||||
return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType);
|
||||
}
|
||||
}
|
69
sf-vertx/src/main/java/com/sf/vertx/config/RedisConfig.java
Normal file
69
sf-vertx/src/main/java/com/sf/vertx/config/RedisConfig.java
Normal file
@ -0,0 +1,69 @@
|
||||
package com.sf.vertx.config;
|
||||
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
/**
|
||||
* redis配置
|
||||
*
|
||||
* @author ztzh
|
||||
*/
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
public class RedisConfig extends CachingConfigurerSupport
|
||||
{
|
||||
@Bean(name = "redisTemplate")
|
||||
@SuppressWarnings(value = { "unchecked", "rawtypes" })
|
||||
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory)
|
||||
{
|
||||
RedisTemplate<Object, Object> template = new RedisTemplate<>();
|
||||
template.setConnectionFactory(connectionFactory);
|
||||
|
||||
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
|
||||
|
||||
// 使用StringRedisSerializer来序列化和反序列化redis的key值
|
||||
template.setKeySerializer(new StringRedisSerializer());
|
||||
template.setValueSerializer(serializer);
|
||||
|
||||
// Hash的key也采用StringRedisSerializer的序列化方式
|
||||
template.setHashKeySerializer(new StringRedisSerializer());
|
||||
template.setHashValueSerializer(serializer);
|
||||
|
||||
template.afterPropertiesSet();
|
||||
return template;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DefaultRedisScript<Long> limitScript()
|
||||
{
|
||||
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
|
||||
redisScript.setScriptText(limitScriptText());
|
||||
redisScript.setResultType(Long.class);
|
||||
return redisScript;
|
||||
}
|
||||
|
||||
/**
|
||||
* 限流脚本
|
||||
*/
|
||||
private String limitScriptText()
|
||||
{
|
||||
return "local key = KEYS[1]\n" +
|
||||
"local count = tonumber(ARGV[1])\n" +
|
||||
"local time = tonumber(ARGV[2])\n" +
|
||||
"local current = redis.call('get', key);\n" +
|
||||
"if current and tonumber(current) > count then\n" +
|
||||
" return tonumber(current);\n" +
|
||||
"end\n" +
|
||||
"current = redis.call('incr', key)\n" +
|
||||
"if tonumber(current) == 1 then\n" +
|
||||
" redis.call('expire', key, time)\n" +
|
||||
"end\n" +
|
||||
"return tonumber(current);";
|
||||
}
|
||||
}
|
@ -3,22 +3,22 @@ package com.sf.vertx.constans;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
@Component
|
||||
public class RedisConfig {
|
||||
public class RedisKeyConfig {
|
||||
|
||||
@Value("${server.vertx.environment}")
|
||||
private String vertxEnvironment;
|
||||
|
||||
public static final String BASE_REDIS_KEY = "vertx:config:";
|
||||
public static String APP_CONFIG_SET_KEY = null;
|
||||
public static String APP_CURRENT_LIMITING_CONFIG_KEY = null;
|
||||
public static String APP_CONFIG_PREFIX_KEY = null;
|
||||
public static String VERTX_CONFIG_STRING_KEY = null;
|
||||
|
||||
public void init() {
|
||||
APP_CONFIG_PREFIX_KEY = BASE_REDIS_KEY + vertxEnvironment;
|
||||
APP_CONFIG_SET_KEY = APP_CONFIG_PREFIX_KEY + ":set";
|
||||
APP_CURRENT_LIMITING_CONFIG_KEY = APP_CONFIG_PREFIX_KEY + ":app";
|
||||
VERTX_CONFIG_STRING_KEY = BASE_REDIS_KEY + vertxEnvironment + ":vertx";
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
package com.sf.vertx.handle;
|
||||
|
||||
import io.vertx.codegen.annotations.VertxGen;
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
|
||||
/***
|
||||
* 限流熔断, redis存储
|
||||
* @author xy
|
||||
*
|
||||
*/
|
||||
@VertxGen
|
||||
public interface RateLimitHandler extends Handler<RoutingContext> {
|
||||
|
||||
static RateLimitHandler create(String instance) {
|
||||
switch (instance) {
|
||||
case "redis":
|
||||
RedisRateLimiter redisRateLimiter = new RedisRateLimiter();
|
||||
return new RateLimitHandlerRedisImpl(redisRateLimiter);
|
||||
default:
|
||||
// 本地缓存
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.sf.vertx.handle;
|
||||
|
||||
/***
|
||||
* 内存存储
|
||||
* @author xy
|
||||
*
|
||||
*/
|
||||
public class RateLimitHandlerImpl {
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.sf.vertx.handle;
|
||||
|
||||
import com.sf.vertx.api.pojo.AppCurrentLimitingConfig;
|
||||
import com.sf.vertx.init.DynamicBuildServer;
|
||||
import com.sf.vertx.service.impl.AppConfigServiceImpl;
|
||||
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import io.vertx.ext.web.handler.HttpException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/***
|
||||
* redis存储
|
||||
*
|
||||
* @author xy
|
||||
*
|
||||
*/
|
||||
@Slf4j
|
||||
public class RateLimitHandlerRedisImpl implements RateLimitHandler {
|
||||
private RedisRateLimiter rateLimiter;
|
||||
|
||||
public RateLimitHandlerRedisImpl(RedisRateLimiter rateLimiter) {
|
||||
this.rateLimiter = rateLimiter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(RoutingContext rc) {
|
||||
String sacAppHeaderKey = rc.request().headers().get(DynamicBuildServer.SAC_APP_HEADER_KEY);
|
||||
// TODO 判断是否开启限流配置
|
||||
log.info("RateLimitHandlerRedisImpl request:{}", sacAppHeaderKey);
|
||||
// rc.next();
|
||||
// return;
|
||||
// 获取模式
|
||||
int pattern = 1; // 1:app,2:接口默认,3:服务接口配置限流策略
|
||||
if (rateLimiter.acquire(rc, pattern)) {
|
||||
log.info("rateLimiter.acquire true");
|
||||
rc.next();
|
||||
return;
|
||||
} else {
|
||||
switch (pattern) {
|
||||
case 1:
|
||||
AppCurrentLimitingConfig appCurrentLimitingConfig = AppConfigServiceImpl
|
||||
.getAppCurrentLimitingConfig(sacAppHeaderKey);
|
||||
rc.fail(new HttpException(429, appCurrentLimitingConfig.getDefaultResponse()));
|
||||
return;
|
||||
// JsonObject dataJson = new JsonObject(appCurrentLimitingConfig.getDefaultResponse());
|
||||
// rc.response().setChunked(true).setStatusCode(429).putHeader("Content-Type", "application/json").end(dataJson.toBuffer());
|
||||
// return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.sf.vertx.handle;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
|
||||
import com.sf.vertx.api.pojo.AppCurrentLimitingConfig;
|
||||
import com.sf.vertx.constans.RedisKeyConfig;
|
||||
import com.sf.vertx.init.DynamicBuildServer;
|
||||
import com.sf.vertx.service.impl.AppConfigServiceImpl;
|
||||
import com.sf.vertx.utils.SpringUtils;
|
||||
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class RedisRateLimiter {
|
||||
public Boolean acquire(RoutingContext rc, int pattern) {
|
||||
String appCode = rc.request().headers().get(DynamicBuildServer.SAC_APP_HEADER_KEY);
|
||||
//TODO 先测试app模式,后面通过app缓存获取模式
|
||||
switch (pattern) {
|
||||
case 1:
|
||||
String key = RedisKeyConfig.APP_CURRENT_LIMITING_CONFIG_KEY +":"+ appCode;
|
||||
return rateLimiter(key, appCode);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Boolean rateLimiter(String key, String appCode) {
|
||||
RedisTemplate<String, Integer> redisTemplate = SpringUtils.getBean("redisTemplate", RedisTemplate.class);
|
||||
AppCurrentLimitingConfig appCurrentLimitingConfig = AppConfigServiceImpl.getAppCurrentLimitingConfig(appCode);
|
||||
Object count = redisTemplate.opsForValue().get(key);
|
||||
//redisTemplate.delete(key);
|
||||
log.info("count:{}", count);
|
||||
if(count == null) {
|
||||
// 初始化,设置过期时间
|
||||
redisTemplate.opsForValue().increment(key);
|
||||
log.info("redis app threshold: {}", redisTemplate.opsForValue().get(key));
|
||||
redisTemplate.expire(key, appCurrentLimitingConfig.getTimeWindow(), TimeUnit.SECONDS);
|
||||
} else if(Integer.valueOf(count.toString()) < appCurrentLimitingConfig.getThreshold()) {
|
||||
redisTemplate.opsForValue().increment(key);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,10 @@
|
||||
package com.sf.vertx.handle;
|
||||
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
|
||||
public interface RestfulFailureHandler extends Handler<RoutingContext> {
|
||||
static RestfulFailureHandlerImpl create() {
|
||||
return new RestfulFailureHandlerImpl();
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.sf.vertx.handle;
|
||||
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import io.vertx.ext.web.handler.HttpException;
|
||||
|
||||
public class RestfulFailureHandlerImpl implements RestfulFailureHandler {
|
||||
|
||||
@Override
|
||||
public void handle(RoutingContext frc) {
|
||||
Throwable failure = frc.failure();
|
||||
if (failure instanceof HttpException) {
|
||||
HttpException httpException = (HttpException) failure;
|
||||
// frc.response().setStatusCode(404).end();
|
||||
JsonObject dataJson = new JsonObject(httpException.getPayload());
|
||||
frc.response().setChunked(true).setStatusCode(httpException.getStatusCode())
|
||||
.putHeader("Content-Type", "application/json").end(dataJson.toBuffer());
|
||||
return;
|
||||
}
|
||||
frc.response().setStatusCode(500).setStatusMessage("Server internal error:" + failure.getMessage()).end();
|
||||
}
|
||||
|
||||
}
|
@ -19,9 +19,11 @@ import com.sf.vertx.api.pojo.SacService;
|
||||
import com.sf.vertx.api.pojo.VertxConfig;
|
||||
import com.sf.vertx.arithmetic.roundRobin.SacLoadBalancing;
|
||||
import com.sf.vertx.arithmetic.roundRobin.WeightedRoundRobin;
|
||||
import com.sf.vertx.constans.RedisConfig;
|
||||
import com.sf.vertx.constans.RedisKeyConfig;
|
||||
import com.sf.vertx.handle.BodyHandler;
|
||||
import com.sf.vertx.handle.ProxyHandler;
|
||||
import com.sf.vertx.handle.RateLimitHandler;
|
||||
import com.sf.vertx.handle.RestfulFailureHandler;
|
||||
import com.sf.vertx.security.MainSecurity;
|
||||
import com.sf.vertx.service.AppConfigService;
|
||||
import com.sf.vertx.service.impl.AppConfigServiceImpl;
|
||||
@ -33,9 +35,11 @@ import io.vertx.core.http.HttpClient;
|
||||
import io.vertx.core.http.HttpServer;
|
||||
import io.vertx.core.http.HttpServerOptions;
|
||||
import io.vertx.core.http.HttpServerRequest;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.core.net.SocketAddress;
|
||||
import io.vertx.ext.web.Router;
|
||||
import io.vertx.ext.web.client.WebClient;
|
||||
import io.vertx.ext.web.handler.HttpException;
|
||||
import io.vertx.httpproxy.HttpProxy;
|
||||
import io.vertx.httpproxy.ProxyContext;
|
||||
import io.vertx.httpproxy.ProxyInterceptor;
|
||||
@ -61,12 +65,12 @@ public class DynamicBuildServer implements ApplicationRunner {
|
||||
private AppConfigService appConfigService;
|
||||
|
||||
@Autowired
|
||||
private RedisConfig redisConfig;
|
||||
private RedisKeyConfig redisKeyConfig;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
// 初始化redis key
|
||||
redisConfig.init();
|
||||
redisKeyConfig.init();
|
||||
// 加载vertx、应用配置
|
||||
appStartLoadData();
|
||||
}
|
||||
@ -122,7 +126,11 @@ public class DynamicBuildServer implements ApplicationRunner {
|
||||
WebClient mainWebClient = WebClient.create(VERTX);
|
||||
// mainHttpRouter.route().handler(ProxyHandler.create(proxy));
|
||||
|
||||
mainHttpRouter.route().handler(BodyHandler.create()).handler(ProxyHandler.create(mainWebClient,proxy));
|
||||
// TODO 实例化方式 从 VertxConfig 读取
|
||||
String instance = "redis";
|
||||
mainHttpRouter.route().handler(RateLimitHandler.create(instance)).handler(BodyHandler.create())
|
||||
.handler(ProxyHandler.create(mainWebClient, proxy)).failureHandler(RestfulFailureHandler.create());
|
||||
// mainHttpRouter.route().handler(BodyHandler.create()).handler(ProxyHandler.create(mainWebClient,proxy));
|
||||
}
|
||||
|
||||
public SocketAddress resolveOriginAddress(ConcurrentHashMap<String, AppConfig> cacheAppConfig,
|
||||
|
@ -13,8 +13,9 @@ import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.alibaba.fastjson2.TypeReference;
|
||||
import com.sf.vertx.api.pojo.AppConfig;
|
||||
import com.sf.vertx.api.pojo.AppCurrentLimitingConfig;
|
||||
import com.sf.vertx.api.pojo.VertxConfig;
|
||||
import com.sf.vertx.constans.RedisConfig;
|
||||
import com.sf.vertx.constans.RedisKeyConfig;
|
||||
import com.sf.vertx.service.AppConfigService;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -26,32 +27,49 @@ public class AppConfigServiceImpl implements AppConfigService {
|
||||
private String vertxEnvironment;
|
||||
@Autowired
|
||||
private RedisTemplate<String, String> redisTemplate;
|
||||
private static final ConcurrentHashMap<String, AppConfig> cacheAppConfig = new ConcurrentHashMap<>();
|
||||
|
||||
private static final ConcurrentHashMap<String, AppConfig> CACHE_APP_CONFIG = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentHashMap<String, AppCurrentLimitingConfig> CACHE_APP_CURRENT_LIMITING_CONFIG = new ConcurrentHashMap<>();
|
||||
|
||||
public static boolean appDataSecurity(String appCode) {
|
||||
return cacheAppConfig.get(appCode) != null && cacheAppConfig.get(appCode).getDataSecurity() != null ? true : false;
|
||||
return CACHE_APP_CONFIG.get(appCode) != null && CACHE_APP_CONFIG.get(appCode).getDataSecurity() != null ? true
|
||||
: false;
|
||||
}
|
||||
|
||||
public static AppCurrentLimitingConfig getAppCurrentLimitingConfig(String appCode) {
|
||||
return CACHE_APP_CURRENT_LIMITING_CONFIG.get(appCode);
|
||||
}
|
||||
|
||||
/***
|
||||
* 从redis加载数据
|
||||
*/
|
||||
public ConcurrentHashMap<String, AppConfig> loadAllConfig() {
|
||||
Set<String> set = redisTemplate.opsForZSet().range(RedisConfig.APP_CONFIG_SET_KEY, 0, -1);
|
||||
Set<String> set = redisTemplate.opsForZSet().range(RedisKeyConfig.APP_CONFIG_SET_KEY, 0, -1);
|
||||
for (String appCode : set) {
|
||||
String appCodeKey = RedisConfig.APP_CONFIG_PREFIX_KEY + ":" + appCode;
|
||||
String appCodeKey = RedisKeyConfig.APP_CONFIG_PREFIX_KEY + ":" + appCode;
|
||||
String appCodeValue = redisTemplate.opsForValue().get(appCodeKey);
|
||||
if (StringUtils.isNotBlank(appCodeValue)) {
|
||||
AppConfig appConfig = JSON.parseObject(appCodeValue, new TypeReference<AppConfig>() {});
|
||||
cacheAppConfig.put(appCode, appConfig);
|
||||
AppConfig appConfig = JSON.parseObject(appCodeValue, new TypeReference<AppConfig>() {
|
||||
});
|
||||
CACHE_APP_CONFIG.put(appCode, appConfig);
|
||||
|
||||
}
|
||||
}
|
||||
log.info("cacheAppConfig:{}", JSON.toJSONString(cacheAppConfig));
|
||||
return cacheAppConfig;
|
||||
|
||||
// TODO 限流
|
||||
AppCurrentLimitingConfig appCurrentLimitingConfig = new AppCurrentLimitingConfig();
|
||||
appCurrentLimitingConfig.setThreshold(1);
|
||||
appCurrentLimitingConfig.setTimeWindow(10);
|
||||
appCurrentLimitingConfig.setDefaultResponse(
|
||||
"{\n" + " \"msg\": \"接口繁忙请重试\",\n" + " \"code\": 501,\n" + " \"data\": \"到达限流阈值\"\n" + "}");
|
||||
CACHE_APP_CURRENT_LIMITING_CONFIG.put("dsafdsfadafhappd", appCurrentLimitingConfig);
|
||||
CACHE_APP_CURRENT_LIMITING_CONFIG.put("dsafdsfadafhappC", appCurrentLimitingConfig);
|
||||
log.info("cacheAppConfig:{}", JSON.toJSONString(CACHE_APP_CONFIG));
|
||||
|
||||
return CACHE_APP_CONFIG;
|
||||
}
|
||||
|
||||
public AppConfig getAppConfig(String appCode) {
|
||||
String appCodeKey = RedisConfig.APP_CONFIG_PREFIX_KEY + ":" + appCode;
|
||||
String appCodeKey = RedisKeyConfig.APP_CONFIG_PREFIX_KEY + ":" + appCode;
|
||||
String appCodeValue = redisTemplate.opsForValue().get(appCodeKey);
|
||||
if (StringUtils.isNotBlank(appCodeValue)) {
|
||||
AppConfig appConfig = JSONObject.parseObject(appCodeValue, AppConfig.class);
|
||||
@ -62,39 +80,39 @@ public class AppConfigServiceImpl implements AppConfigService {
|
||||
|
||||
/***
|
||||
* 新增、修改
|
||||
*
|
||||
* @param appConfig
|
||||
*/
|
||||
public void addAppConfig(String appConfigStr) {
|
||||
AppConfig appConfig = JSON.parseObject(appConfigStr, AppConfig.class);
|
||||
redisTemplate.opsForZSet().add(RedisConfig.APP_CONFIG_SET_KEY, appConfig.getAppCode(), 0);
|
||||
String appCodeKey = RedisConfig.APP_CONFIG_PREFIX_KEY + ":" + appConfig.getAppCode();
|
||||
redisTemplate.opsForZSet().add(RedisKeyConfig.APP_CONFIG_SET_KEY, appConfig.getAppCode(), 0);
|
||||
String appCodeKey = RedisKeyConfig.APP_CONFIG_PREFIX_KEY + ":" + appConfig.getAppCode();
|
||||
redisTemplate.opsForValue().set(appCodeKey, appConfigStr);
|
||||
|
||||
// 发送redis队列,vertx处理
|
||||
//String queue = RedisConfig.VETX_ENVIRONMENT_KEY+vertxEnvironment+":list";
|
||||
// String queue = RedisKeyConfig.VETX_ENVIRONMENT_KEY+vertxEnvironment+":list";
|
||||
|
||||
}
|
||||
|
||||
/***
|
||||
* 删除
|
||||
*
|
||||
* @param appConfig
|
||||
*/
|
||||
public void deleteAppConfig(AppConfig appConfig) {
|
||||
redisTemplate.opsForZSet().remove(RedisConfig.APP_CONFIG_SET_KEY, appConfig.getAppCode());
|
||||
String appCodeKey = RedisConfig.APP_CONFIG_PREFIX_KEY + ":" + appConfig.getAppCode();
|
||||
redisTemplate.opsForZSet().remove(RedisKeyConfig.APP_CONFIG_SET_KEY, appConfig.getAppCode());
|
||||
String appCodeKey = RedisKeyConfig.APP_CONFIG_PREFIX_KEY + ":" + appConfig.getAppCode();
|
||||
redisTemplate.delete(appCodeKey);
|
||||
|
||||
|
||||
// 发送redis队列,vertx处理
|
||||
//String queue = RedisConfig.VETX_ENVIRONMENT_KEY+vertxEnvironment+":list";
|
||||
// String queue = RedisKeyConfig.VETX_ENVIRONMENT_KEY+vertxEnvironment+":list";
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 加载vertx配置
|
||||
*/
|
||||
public VertxConfig loadVertxConfig() {
|
||||
String vertxConfigKey = RedisConfig.VERTX_CONFIG_STRING_KEY;
|
||||
String vertxConfigKey = RedisKeyConfig.VERTX_CONFIG_STRING_KEY;
|
||||
String vertxConfigValue = redisTemplate.opsForValue().get(vertxConfigKey);
|
||||
if (StringUtils.isNotBlank(vertxConfigValue)) {
|
||||
VertxConfig vertxConfig = JSONObject.parseObject(vertxConfigValue, VertxConfig.class);
|
||||
@ -105,13 +123,14 @@ public class AppConfigServiceImpl implements AppConfigService {
|
||||
|
||||
/***
|
||||
* 新增、修改
|
||||
*
|
||||
* @param appConfig
|
||||
*/
|
||||
public void addVertxConfig(VertxConfig vertxConfig) {
|
||||
String vertxConfigKey = RedisConfig.VERTX_CONFIG_STRING_KEY;
|
||||
String vertxConfigKey = RedisKeyConfig.VERTX_CONFIG_STRING_KEY;
|
||||
redisTemplate.opsForValue().set(vertxConfigKey, JSONObject.toJSONString(vertxConfig));
|
||||
|
||||
// 发送redis队列,vertx处理
|
||||
//String queue = RedisConfig.VETX_ENVIRONMENT_KEY+vertxEnvironment+":list";
|
||||
// String queue = RedisKeyConfig.VETX_ENVIRONMENT_KEY+vertxEnvironment+":list";
|
||||
}
|
||||
}
|
||||
|
151
sf-vertx/src/main/java/com/sf/vertx/utils/SpringUtils.java
Normal file
151
sf-vertx/src/main/java/com/sf/vertx/utils/SpringUtils.java
Normal file
@ -0,0 +1,151 @@
|
||||
package com.sf.vertx.utils;
|
||||
|
||||
import org.springframework.aop.framework.AopContext;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* spring工具类 方便在非spring管理环境中获取bean
|
||||
*
|
||||
* @author ztzh
|
||||
*/
|
||||
@Component
|
||||
public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware
|
||||
{
|
||||
/** Spring应用上下文环境 */
|
||||
private static ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
private static ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
|
||||
{
|
||||
SpringUtils.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
|
||||
{
|
||||
SpringUtils.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象
|
||||
*
|
||||
* @param name
|
||||
* @return Object 一个以所给名字注册的bean的实例
|
||||
* @throws org.springframework.beans.BeansException
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getBean(String name) throws BeansException
|
||||
{
|
||||
return (T) beanFactory.getBean(name);
|
||||
}
|
||||
|
||||
public static <T> T getBean(String name, Class<T> classType) throws BeansException
|
||||
{
|
||||
return (T) beanFactory.getBean(name, classType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类型为requiredType的对象
|
||||
*
|
||||
* @param clz
|
||||
* @return
|
||||
* @throws org.springframework.beans.BeansException
|
||||
*
|
||||
*/
|
||||
public static <T> T getBean(Class<T> clz) throws BeansException
|
||||
{
|
||||
T result = (T) beanFactory.getBean(clz);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
|
||||
*
|
||||
* @param name
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean containsBean(String name)
|
||||
{
|
||||
return beanFactory.containsBean(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
|
||||
*
|
||||
* @param name
|
||||
* @return boolean
|
||||
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
|
||||
*
|
||||
*/
|
||||
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException
|
||||
{
|
||||
return beanFactory.isSingleton(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return Class 注册对象的类型
|
||||
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
|
||||
*
|
||||
*/
|
||||
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException
|
||||
{
|
||||
return beanFactory.getType(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果给定的bean名字在bean定义中有别名,则返回这些别名
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
|
||||
*
|
||||
*/
|
||||
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
|
||||
{
|
||||
return beanFactory.getAliases(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取aop代理对象
|
||||
*
|
||||
* @param invoker
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getAopProxy(T invoker)
|
||||
{
|
||||
return (T) AopContext.currentProxy();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前的环境配置,无配置返回null
|
||||
*
|
||||
* @return 当前的环境配置
|
||||
*/
|
||||
public static String[] getActiveProfiles()
|
||||
{
|
||||
return applicationContext.getEnvironment().getActiveProfiles();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置文件中的值
|
||||
*
|
||||
* @param key 配置文件的key
|
||||
* @return 当前的配置文件的值
|
||||
*
|
||||
*/
|
||||
public static String getRequiredProperty(String key)
|
||||
{
|
||||
return applicationContext.getEnvironment().getRequiredProperty(key);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user