测试连接redis
parent
056778a476
commit
331d061358
|
@ -5,7 +5,6 @@
|
|||
<database-info product="MySQL" version="5.7.44" jdbc-version="4.2" driver-name="MySQL Connector/J" driver-version="mysql-connector-java-8.0.25 (Revision: 08be9e9b4cba6aa115f9b27b215887af40b159e0)" dbms="MYSQL" exact-version="5.7.44" exact-driver-version="8.0">
|
||||
<extra-name-characters>#@</extra-name-characters>
|
||||
<identifier-quote-string>`</identifier-quote-string>
|
||||
<jdbc-catalog-is-schema>true</jdbc-catalog-is-schema>
|
||||
</database-info>
|
||||
<case-sensitivity plain-identifiers="lower" quoted-identifiers="lower" />
|
||||
<secret-storage>master_key</secret-storage>
|
||||
|
|
|
@ -5,7 +5,28 @@
|
|||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="e53020f6-f301-415a-a26a-d22b9ac05907" name="更改" comment="集成easycode">
|
||||
<change afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-common/src/main/java/com/etl/data/source/common/config/Limit.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-common/src/main/java/com/etl/data/source/common/pojo/Person.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-common/target/classes/com/etl/data/source/common/config/Limit.class" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-common/target/classes/com/etl/data/source/common/pojo/Person.class" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-server/src/main/java/com/etl/data/source/server/aop/LimitAspect.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-server/target/classes/com/etl/data/source/server/aop/LimitAspect.class" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-server/target/test-classes/com/etl/data/source/server/ElDataSourceServerApplicationTests$Person.class" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/dataSources.local.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dataSources.local.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/etl-data-source/el-data-source-common/src/main/java/com/etl/data/source/common/config/RedisLimit.java" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/etl-data-source/el-data-source-common/target/classes/com/etl/data/source/common/config/RedisLimit.class" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/etl-data-source/el-data-source-server/src/main/java/com/etl/data/source/server/aop/RedisLimitAspect.java" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/etl-data-source/el-data-source-server/src/main/java/com/etl/data/source/server/config/RedisConfig.java" beforeDir="false" afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-server/src/main/java/com/etl/data/source/server/config/RedisConfig.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/etl-data-source/el-data-source-server/src/main/java/com/etl/data/source/server/config/RedissonConfig.java" beforeDir="false" afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-server/src/main/java/com/etl/data/source/server/config/RedissonConfig.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/etl-data-source/el-data-source-server/src/main/java/com/etl/data/source/server/controller/DatabaseController.java" beforeDir="false" afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-server/src/main/java/com/etl/data/source/server/controller/DatabaseController.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/etl-data-source/el-data-source-server/src/test/java/com/etl/data/source/server/ElDataSourceServerApplicationTests.java" beforeDir="false" afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-server/src/test/java/com/etl/data/source/server/ElDataSourceServerApplicationTests.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/etl-data-source/el-data-source-server/target/classes/com/etl/data/source/server/aop/RedisLimitAspect$1.class" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/etl-data-source/el-data-source-server/target/classes/com/etl/data/source/server/aop/RedisLimitAspect.class" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/etl-data-source/el-data-source-server/target/classes/com/etl/data/source/server/config/RedisConfig.class" beforeDir="false" afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-server/target/classes/com/etl/data/source/server/config/RedisConfig.class" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/etl-data-source/el-data-source-server/target/classes/com/etl/data/source/server/config/RedissonConfig.class" beforeDir="false" afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-server/target/classes/com/etl/data/source/server/config/RedissonConfig.class" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/etl-data-source/el-data-source-server/target/classes/com/etl/data/source/server/controller/DatabaseController.class" beforeDir="false" afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-server/target/classes/com/etl/data/source/server/controller/DatabaseController.class" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/etl-data-source/el-data-source-server/target/test-classes/com/etl/data/source/server/ElDataSourceServerApplicationTests.class" beforeDir="false" afterPath="$PROJECT_DIR$/etl-data-source/el-data-source-server/target/test-classes/com/etl/data/source/server/ElDataSourceServerApplicationTests.class" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
|
@ -62,7 +83,7 @@
|
|||
"WebServerToolWindowFactoryState": "false",
|
||||
"git-widget-placeholder": "main",
|
||||
"jdk.selected.JAVA_MODULE": "1.8",
|
||||
"last_opened_file_path": "D:/workspace/etl-cloud/etl-heihei/src/main/java",
|
||||
"last_opened_file_path": "D:/workspace/etl-cloud/etl-data-source/el-data-source-common/src/main/java/com/etl/data/source/common",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
|
@ -72,7 +93,7 @@
|
|||
"project.structure.proportion": "0.17",
|
||||
"project.structure.side.proportion": "0.29885057",
|
||||
"settings.editor.selected.configurable": "preferences.lookFeel",
|
||||
"spring.configuration.checksum": "21940204b7449cbc44619bf9f15c4b27",
|
||||
"spring.configuration.checksum": "1d871ffdc938601b3b3345b2b129e57c",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
},
|
||||
"keyToStringList": {
|
||||
|
@ -91,6 +112,7 @@
|
|||
<recent name="com.etl.data.source.server.service" />
|
||||
</key>
|
||||
<key name="CopyFile.RECENT_KEYS">
|
||||
<recent name="D:\workspace\etl-cloud\etl-data-source\el-data-source-common\src\main\java\com\etl\data\source\common" />
|
||||
<recent name="D:\workspace\etl-cloud\etl-common\src\main" />
|
||||
<recent name="D:\workspace\etl-cloud\etl-data-source\el-data-source-server\src\main" />
|
||||
<recent name="D:\workspace\etl-cloud\etl-data-source\src\main" />
|
||||
|
@ -100,6 +122,10 @@
|
|||
<recent name="com.etl.data.source.server" />
|
||||
<recent name="com.etl.data.source" />
|
||||
</key>
|
||||
<key name="CopyClassDialog.RECENTS_KEY">
|
||||
<recent name="com.etl.data.source.server.service" />
|
||||
<recent name="com.etl.data.source.server.service.impl" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunDashboard">
|
||||
<option name="configurationTypes">
|
||||
|
@ -108,7 +134,20 @@
|
|||
</set>
|
||||
</option>
|
||||
</component>
|
||||
<component name="RunManager" selected="Spring Boot.CarApplication">
|
||||
<component name="RunManager" selected="应用程序.ElDataSourceServerApplicationTests">
|
||||
<configuration name="ElDataSourceServerApplicationTests" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
|
||||
<option name="MAIN_CLASS_NAME" value="com.etl.data.source.server.ElDataSourceServerApplicationTests" />
|
||||
<module name="el-data-source-server" />
|
||||
<extension name="coverage">
|
||||
<pattern>
|
||||
<option name="PATTERN" value="com.etl.data.source.server.*" />
|
||||
<option name="ENABLED" value="true" />
|
||||
</pattern>
|
||||
</extension>
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="Main" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
|
||||
<option name="MAIN_CLASS_NAME" value="com.Main" />
|
||||
<module name="etl-heihei" />
|
||||
|
@ -122,22 +161,6 @@
|
|||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="ElDataSourceServerApplicationTests.contextLoads (1)" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true">
|
||||
<module name="el-data-source-server" />
|
||||
<extension name="coverage">
|
||||
<pattern>
|
||||
<option name="PATTERN" value="com.etl.data.source.server.*" />
|
||||
<option name="ENABLED" value="true" />
|
||||
</pattern>
|
||||
</extension>
|
||||
<option name="PACKAGE_NAME" value="com.etl.data.source.server" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.etl.data.source.server.ElDataSourceServerApplicationTests" />
|
||||
<option name="METHOD_NAME" value="contextLoads" />
|
||||
<option name="TEST_OBJECT" value="method" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="ElDataSourceServerApplicationTests.contextLoads" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true">
|
||||
<module name="el-data-source-server" />
|
||||
<extension name="coverage">
|
||||
|
@ -183,11 +206,11 @@
|
|||
</configuration>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="应用程序.ElDataSourceServerApplicationTests" />
|
||||
<item itemvalue="Spring Boot.ElDataSourceServerApplication" />
|
||||
<item itemvalue="Spring Boot.CarApplication" />
|
||||
<item itemvalue="应用程序.Main" />
|
||||
<item itemvalue="Spring Boot.ElDataSourceServerApplication" />
|
||||
<item itemvalue="JUnit.ElDataSourceServerApplicationTests.contextLoads" />
|
||||
<item itemvalue="JUnit.ElDataSourceServerApplicationTests.contextLoads (1)" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
</component>
|
||||
|
@ -209,7 +232,8 @@
|
|||
<workItem from="1719026241976" duration="9213000" />
|
||||
<workItem from="1719104447484" duration="9376000" />
|
||||
<workItem from="1719188994279" duration="10247000" />
|
||||
<workItem from="1719215606901" duration="7883000" />
|
||||
<workItem from="1719215606901" duration="11291000" />
|
||||
<workItem from="1719275369526" duration="6275000" />
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary="第一次">
|
||||
<option name="closed" value="true" />
|
||||
|
@ -235,7 +259,15 @@
|
|||
<option name="project" value="LOCAL" />
|
||||
<updated>1719229225799</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="4" />
|
||||
<task id="LOCAL-00004" summary="集成easycode">
|
||||
<option name="closed" value="true" />
|
||||
<created>1719230664247</created>
|
||||
<option name="number" value="00004" />
|
||||
<option name="presentableId" value="LOCAL-00004" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1719230664247</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="5" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
|
@ -257,4 +289,8 @@
|
|||
<MESSAGE value="集成easycode" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="集成easycode" />
|
||||
</component>
|
||||
<component name="XSLT-Support.FileAssociations.UIState">
|
||||
<expand />
|
||||
<select />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,26 @@
|
|||
package com.etl.data.source.common.config;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
@Documented
|
||||
public @interface Limit {
|
||||
|
||||
// 资源key
|
||||
String key() default "";
|
||||
|
||||
// 最多访问次数
|
||||
double permitsPerSecond();
|
||||
|
||||
// 时间
|
||||
long timeout();
|
||||
|
||||
// 时间类型
|
||||
TimeUnit timeunit() default TimeUnit.MILLISECONDS;
|
||||
|
||||
// 提示信息
|
||||
String msg() default "系统繁忙,请稍后再试";
|
||||
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package com.etl.data.source.common.config;
|
||||
|
||||
|
||||
import com.etl.data.source.common.ennum.LimitType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target({ElementType.METHOD,ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
@Documented
|
||||
public @interface RedisLimit {
|
||||
|
||||
// 资源名称
|
||||
String name() default "";
|
||||
|
||||
// 资源key
|
||||
String key() default "";
|
||||
|
||||
// 前缀
|
||||
String prefix() default "";
|
||||
|
||||
// 时间
|
||||
int period();
|
||||
|
||||
// 最多访问次数
|
||||
int count();
|
||||
|
||||
// 类型
|
||||
LimitType limitType() default LimitType.CUSTOM;
|
||||
|
||||
// 提示信息
|
||||
String msg() default "系统繁忙,请稍后再试";
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.etl.data.source.common.pojo;
|
||||
|
||||
import io.swagger.models.auth.In;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @ClassName Persion
|
||||
* @Description 描述
|
||||
* @Author ZeZhang.Liu
|
||||
* @Date 2024/6/25 9:32
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Person {
|
||||
private String name;
|
||||
|
||||
private Integer age;
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,52 @@
|
|||
package com.etl.data.source.server.aop;
|
||||
|
||||
import com.etl.common.exception.LimitException;
|
||||
import com.etl.data.source.common.config.Limit;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.util.concurrent.RateLimiter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.stereotype.Component;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Aspect
|
||||
@Component
|
||||
public class LimitAspect {
|
||||
|
||||
private final Map<String, RateLimiter> limitMap = Maps.newConcurrentMap();
|
||||
|
||||
@Around("@annotation(com.etl.data.source.common.config.Limit)")
|
||||
public Object around(ProceedingJoinPoint pjp) throws Throwable {
|
||||
MethodSignature signature = (MethodSignature)pjp.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
//拿limit的注解
|
||||
Limit limit = method.getAnnotation(Limit.class);
|
||||
if (limit != null) {
|
||||
//key作用:不同的接口,不同的流量控制
|
||||
String key=limit.key();
|
||||
RateLimiter rateLimiter;
|
||||
//验证缓存是否有命中key
|
||||
if (!limitMap.containsKey(key)) {
|
||||
// 创建令牌桶
|
||||
rateLimiter = RateLimiter.create(limit.permitsPerSecond());
|
||||
limitMap.put(key, rateLimiter);
|
||||
log.info("新建了令牌桶={},容量={}",key,limit.permitsPerSecond());
|
||||
}
|
||||
rateLimiter = limitMap.get(key);
|
||||
// 拿令牌
|
||||
boolean acquire = rateLimiter.tryAcquire(limit.timeout(), limit.timeunit());
|
||||
// 拿不到命令,直接返回异常提示
|
||||
if (!acquire) {
|
||||
log.debug("令牌桶={},获取令牌失败",key);
|
||||
throw new LimitException(limit.msg());
|
||||
}
|
||||
}
|
||||
return pjp.proceed();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
package com.etl.data.source.server.aop;
|
||||
|
||||
import com.etl.common.exception.LimitException;
|
||||
import com.etl.data.source.common.config.RedisLimit;
|
||||
import com.etl.data.source.common.ennum.LimitType;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Aspect
|
||||
@Configuration
|
||||
public class RedisLimitAspect {
|
||||
|
||||
private final RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
public RedisLimitAspect(RedisTemplate<String, Object> redisTemplate) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
}
|
||||
|
||||
@Around("@annotation(com.etl.data.source.common.config.RedisLimit)")
|
||||
public Object around(ProceedingJoinPoint pjp){
|
||||
MethodSignature methodSignature = (MethodSignature)pjp.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
RedisLimit annotation = method.getAnnotation(RedisLimit.class);
|
||||
LimitType limitType = annotation.limitType();
|
||||
|
||||
String name = annotation.name();
|
||||
String key;
|
||||
|
||||
int period = annotation.period();
|
||||
int count = annotation.count();
|
||||
|
||||
switch (limitType){
|
||||
case IP:
|
||||
key = getIpAddress();
|
||||
break;
|
||||
case CUSTOMER:
|
||||
key = annotation.key();
|
||||
break;
|
||||
default:
|
||||
key = StringUtils.upperCase(method.getName());
|
||||
}
|
||||
ImmutableList<String> keys = ImmutableList.of(StringUtils.join(annotation.prefix(), key));
|
||||
try {
|
||||
String luaScript = buildLuaScript();
|
||||
DefaultRedisScript<Number> redisScript = new DefaultRedisScript<>(luaScript, Number.class);
|
||||
Number number = redisTemplate.execute(redisScript, keys, count, period);
|
||||
log.info("Access try count is {} for name = {} and key = {}", number, name, key);
|
||||
if(number != null && number.intValue() == 1){
|
||||
return pjp.proceed();
|
||||
}
|
||||
throw new LimitException(annotation.msg());
|
||||
}catch (Throwable e){
|
||||
if(e instanceof LimitException){
|
||||
log.debug("令牌桶={},获取令牌失败",key);
|
||||
throw new LimitException(e.getLocalizedMessage());
|
||||
}
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("服务器异常");
|
||||
}
|
||||
}
|
||||
|
||||
public String buildLuaScript(){
|
||||
return "redis.replicate_commands(); local listLen,time" +
|
||||
"\nlistLen = redis.call('LLEN', KEYS[1])" +
|
||||
// 不超过最大值,则直接写入时间
|
||||
"\nif listLen and tonumber(listLen) < tonumber(ARGV[1]) then" +
|
||||
"\nlocal a = redis.call('TIME');" +
|
||||
"\nredis.call('LPUSH', KEYS[1], a[1]*1000000+a[2])" +
|
||||
"\nelse" +
|
||||
// 取出现存的最早的那个时间,和当前时间比较,看是小于时间间隔
|
||||
"\ntime = redis.call('LINDEX', KEYS[1], -1)" +
|
||||
"\nlocal a = redis.call('TIME');" +
|
||||
"\nif a[1]*1000000+a[2] - time < tonumber(ARGV[2])*1000000 then" +
|
||||
// 访问频率超过了限制,返回0表示失败
|
||||
"\nreturn 0;" +
|
||||
"\nelse" +
|
||||
"\nredis.call('LPUSH', KEYS[1], a[1]*1000000+a[2])" +
|
||||
"\nredis.call('LTRIM', KEYS[1], 0, tonumber(ARGV[1])-1)" +
|
||||
"\nend" +
|
||||
"\nend" +
|
||||
"\nreturn 1;";
|
||||
}
|
||||
|
||||
public String getIpAddress(){
|
||||
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
|
||||
String ip = request.getHeader("x-forwarded-for");
|
||||
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
|
||||
ip = request.getHeader("WL-Client-IP");
|
||||
}
|
||||
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
}
|
|
@ -31,19 +31,6 @@ public class RedisConfig {
|
|||
return jedisPool;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisTemplate<String, Object> template = new RedisTemplate<>();
|
||||
template.setConnectionFactory(redisConnectionFactory);
|
||||
|
||||
// 设置序列化器(如果需要)
|
||||
// 例如:
|
||||
// template.setKeySerializer(new StringRedisSerializer());
|
||||
// template.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
|
||||
|
||||
// ... 其他配置
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ import org.redisson.config.Config;
|
|||
import org.springframework.beans.factory.annotation.Value;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @ClassName RedissonConfig
|
||||
|
@ -36,4 +38,19 @@ public class RedissonConfig {
|
|||
|
||||
return Redisson.create(config);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisTemplate<String, Object> template = new RedisTemplate<>();
|
||||
template.setConnectionFactory(redisConnectionFactory);
|
||||
|
||||
// 设置序列化器(如果需要)
|
||||
// 例如:
|
||||
// template.setKeySerializer(new StringRedisSerializer());
|
||||
// template.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
|
||||
|
||||
// ... 其他配置
|
||||
|
||||
return template;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.etl.data.source.server.controller;
|
||||
|
||||
import com.etl.common.result.Result;
|
||||
import com.etl.data.source.common.config.RedisLimit;
|
||||
import com.etl.data.source.common.config.Limit;
|
||||
import com.etl.data.source.common.pojo.DatabaseConfig;
|
||||
import com.etl.data.source.common.pojo.DatabaseRedis;
|
||||
import com.etl.data.source.common.pojo.resq.ColumnInfo;
|
||||
|
@ -36,7 +36,7 @@ public class DatabaseController {
|
|||
// POST请求映射到/test-database-connection路径
|
||||
@PostMapping("/testDatabaseMysql")
|
||||
@ApiOperation(value = "测试数据库连接")
|
||||
@RedisLimit(key = "cachingTest", count = 2, period = 2, msg = "当前排队人数较多,请稍后再试!")
|
||||
@Limit(key = "testDatabaseMysql", permitsPerSecond = 1, timeout = 500, msg = "当前排队人数较多,请稍后再试!")
|
||||
public Result<String> testDatabaseConnection(@Valid @RequestBody DatabaseConfig config) {
|
||||
String string = databaseService.testDatabaseConnection(config);
|
||||
if (string.equals("ok")) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.etl.data.source.server;
|
||||
|
||||
import com.etl.data.source.common.pojo.Person;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import java.sql.*;
|
||||
|
@ -7,33 +8,53 @@ import java.util.*;
|
|||
|
||||
@SpringBootTest
|
||||
class ElDataSourceServerApplicationTests {
|
||||
@Test
|
||||
void contextLoads() {
|
||||
// List<String> list = Arrays.asList("a", "b", "c");
|
||||
// list.forEach(item -> System.out.println("Lambda方式遍历元素: "+item));
|
||||
//创建一个未排序的列表
|
||||
List<String> list = Arrays.asList("b", "a", "c","aa");
|
||||
//使用传统方式进行排序
|
||||
// Collections.sort(list, new Comparator<String>() {
|
||||
// @Override
|
||||
// public int compare(String o1, String o2) {
|
||||
// return o1.compareTo(o2);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// System.out.println("传统方式排序结果:"+list);
|
||||
// list.sort((s1,s2) -> s1.compareTo(s2));
|
||||
// System.out.println("Lambda方式排序结果:"+list);
|
||||
//创建一个新的列表来存储过滤后的结果
|
||||
// ArrayList<String> filteredLis = new ArrayList<>();
|
||||
// //使用传统方式过滤
|
||||
// for (String item : list) {
|
||||
// if(item.startsWith("a")){
|
||||
// filteredLis.add(item);
|
||||
// }
|
||||
// }
|
||||
// //打印过滤后的列表
|
||||
// System.out.println("传统过滤结果:"+filteredLis);
|
||||
// 假设我们有一个简单的Person类,包含姓名和年龄
|
||||
static class Person {
|
||||
String name;
|
||||
Integer age;
|
||||
|
||||
Person(String name, Integer age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Person{" +
|
||||
"name='" + name + '\'' +
|
||||
", age=" + age +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 示例数据集
|
||||
List<Person> people = new ArrayList<>();
|
||||
people.add(new Person("Alice", 25));
|
||||
people.add(new Person("Bob", null)); // 缺失值
|
||||
people.add(new Person("Charlie", 30));
|
||||
people.add(new Person("Alice", 25)); // 重复数据
|
||||
|
||||
// 1. 处理缺失值
|
||||
List<Person> cleanedPeople = new ArrayList<>();
|
||||
for (Person person : people) {
|
||||
if (person.age == null) {
|
||||
// 假设我们用平均值或某个默认值替换缺失的年龄
|
||||
// 这里简单起见,我们设置为0
|
||||
person.age = 0;
|
||||
}
|
||||
cleanedPeople.add(person);
|
||||
}
|
||||
|
||||
// 2. 处理重复数据
|
||||
Set<Person> uniquePeople = new LinkedHashSet<>(cleanedPeople); // LinkedHashSet保持插入顺序
|
||||
cleanedPeople.clear();
|
||||
cleanedPeople.addAll(uniquePeople);
|
||||
|
||||
// 3. 数据格式化(这里只是一个简单的打印示例)
|
||||
for (Person person : cleanedPeople) {
|
||||
System.out.println(person);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue