Spring 周报
This Week in Spring - November 12th, 2024
More »Java, Spring Boot, Microservice, Cloud, Architecture and DevOps Tutorials
Spring Boot 和 GraalVM 原生镜像应用程序,由出色的 Oracle GraalVM 开发倡导者 Alina Yurenko演示。
More »以下是 SivaLabs 博客 中的一些文章,记录在此,方便后面阅读。
如果你正在寻找使用 SpringBoot 实现微服务的详细实用指南,那么 Java 微服务:实用指南就是你的最佳选择
在使用 JPA 时,我们多少次希望看到使用实际参数值而不是占位符生成的 SQL 查询?我们可以使用p6spy-spring-boot-starter来记录使用实际参数生成的 SQL 语句。
More »今天做了什么:
ChatGPT 编写一个 RateLimitAspect 类,实现基于用户的 get 查询请求的限流功能
@Aspect
@Component
public class RateLimitAspect {
private final RedisTemplate<String, Object> redisTemplate;
private final Logger logger = LoggerFactory.getLogger(RateLimitAspect.class);
private final int maxRequests; // Maximum number of requests
private final int timeWindow; // Time window in seconds
@Autowired
public RateLimitAspect(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
this.maxRequests = 100; // Default maximum number of requests is 100
this.timeWindow = 60; // Default time window is 60 seconds
}
@Before("@annotation(getMapping)")
public void applyRateLimit(JoinPoint joinPoint, GetMapping getMapping) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes()).getRequest();
if (request != null && HttpMethod.GET.matches(request.getMethod())) {
String username = request.getUserPrincipal().getName(); // Get the username
if (username != null && !username.isEmpty()) {
String rateLimitKey = "rate_limit:" + username;
incrementAndCheckRateLimit(rateLimitKey, request);
}
}
}
private void incrementAndCheckRateLimit(String rateLimitKey, HttpServletRequest request) {
Long currentRequests = redisTemplate.execute((RedisCallback<Long>) connection -> {
Object nativeConnection = connection.getNativeConnection();
String script = "local current = redis.call('INCR', KEYS[1])\n"
+ "if tonumber(current) == 1 then\n"
+ " redis.call('EXPIRE', KEYS[1], ARGV[1])\n"
+ "end\n"
+ "return current";
return (Long) ((RedisOperations<?, ?>) nativeConnection).execute(
(RedisCallback<Object>) connection1 -> connection1.eval(
script.getBytes(),
redisTemplate.getKeySerializer(), // Use custom Key serializer
redisTemplate.getValueSerializer(), // Use custom Value serializer
Collections.singletonList(rateLimitKey.getBytes()),
Collections.singletonList(String.valueOf(timeWindow).getBytes())
)
);
});
if (currentRequests > maxRequests) {
String urlWithParams = getRequestUrlWithParams(request);
logger.warn("Rate limit exceeded for key: {}. Request URL with Params: {}",
rateLimitKey, urlWithParams);
throw new RateLimitException();
}
}
private String getRequestUrlWithParams(HttpServletRequest request) {
String url = request.getRequestURL().toString();
String queryString = request.getQueryString();
if (queryString != null && !queryString.isEmpty()) {
url += "?" + queryString;
}
return url;
}
}
调整 spring-cloud-examples 目录,通过源码分析 SpringBoot 2.7.18 启动过程
More »今天做了什么:
Spring Cloud Config 是一个基于http协议的远程配置实现方式。通过统一的配置管理服务器进行配置管理,客户端通过http协议主动的拉取服务的的配置信息,完成配置获取。
More »今天做了什么:
重构 foodie-cloud 项目
阅读博客 https://blog.csdn.net/weixin_42189048
More »