docker-compose 运行
参考:https://thingsboard.io/docs/mqtt-broker/install/cluster/docker-compose-setup/
下载源代码
git clone -b release-1.3.0 https://github.com/thingsboard/tbmq.git cd tbmq/docker
创建逻辑卷并执行安装程序
More »
Java, Spring Boot, Microservice, Cloud, Architecture and DevOps Tutorials
参考:https://thingsboard.io/docs/mqtt-broker/install/cluster/docker-compose-setup/
下载源代码
git clone -b release-1.3.0 https://github.com/thingsboard/tbmq.git
cd tbmq/docker
创建逻辑卷并执行安装程序
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 »今天做了什么:
集成 Spring Cloud Config 使用文件保存配置文件
More »今天做了什么:
安装 spring cli
More »今天做了什么:
今天做了什么:
实体类中可以不用添加@TableId,减少实体类对 mybatis-plus-annotation的依赖
More »