diff --git a/pom.xml b/pom.xml
index 4acacd1..aef9610 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,9 +37,33 @@
1.8
1.7.1
1.3.61
-
+ 2.2.6.RELEASE
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
com.jcraft
jsch
@@ -69,6 +93,12 @@
org.apache.shiro
shiro-core
1.4.2
+
+
+ slf4j-api
+ org.slf4j
+
+
@@ -174,12 +204,12 @@
redis.clients
jedis
3.4.1
-
-
-
- org.springframework.boot
- spring-boot-starter-data-redis
- 2.5.2
+
+
+ slf4j-api
+ org.slf4j
+
+
@@ -188,11 +218,11 @@
8.0.16
-
+
javax.servlet
- servlet-api
- ${servlet.version}
+ javax.servlet-api
+ 3.1.0
provided
@@ -240,10 +270,32 @@
3.1.6
+
+
+
+
+
+
org.apache.activemq
- activemq-all
- 5.13.3
+ activemq-broker
+
+
+ org.apache.activemq
+ activemq-client
+
+
+ org.apache.activemq
+ activemq-pool
+
+
+ org.apache.activemq
+ activemq-spring
+
+
+
+ javax.jms
+ javax.jms-api
@@ -302,12 +354,32 @@
com.rabbitmq
amqp-client
4.8.0
+
+
+ slf4j-api
+ org.slf4j
+
+
org.apache.hbase
hbase-client
1.3.5
+
+
+ slf4j-log4j12
+ org.slf4j
+
+
+ log4j
+ log4j
+
+
+ slf4j-api
+ org.slf4j
+
+
@@ -377,4 +449,30 @@
+
+
+
+
+
+ src/test/resources
+
+
+ src/main/resources
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
diff --git a/src/main/java/io/github/ehlxr/BuddApplication.java b/src/main/java/io/github/ehlxr/BuddApplication.java
new file mode 100644
index 0000000..65f4c21
--- /dev/null
+++ b/src/main/java/io/github/ehlxr/BuddApplication.java
@@ -0,0 +1,39 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright © 2021 xrv
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package io.github.ehlxr;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @author ehlxr
+ * @since 2021-08-29 09:35.
+ */
+@SpringBootApplication
+public class BuddApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(BuddApplication.class, args);
+ }
+}
diff --git a/src/main/java/io/github/ehlxr/redis/Main.java b/src/main/java/io/github/ehlxr/redis/Main.java
new file mode 100644
index 0000000..a0258e2
--- /dev/null
+++ b/src/main/java/io/github/ehlxr/redis/Main.java
@@ -0,0 +1,72 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright © 2021 xrv
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package io.github.ehlxr.redis;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.stereotype.Component;
+
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author ehlxr
+ * @since 2021-08-29 12:18.
+ */
+@Component
+public class Main implements ApplicationListener {
+ private static final Logger log = LoggerFactory.getLogger(Main.class);
+ @Autowired
+ @Qualifier("lettuceDAOImpl")
+ private RedisDAO redisDAO;
+
+ @Override
+ public void onApplicationEvent(ContextRefreshedEvent event) {
+ Runnable runnable = () -> {
+ String uuid = UUID.randomUUID().toString();
+ log.info("{} retry lock...", Thread.currentThread().getName());
+ Boolean lock = redisDAO.getDistributedLock("lock", uuid, 30_000);
+ if (lock) {
+ log.info("{} get lock!", Thread.currentThread().getName());
+
+ try {
+ TimeUnit.SECONDS.sleep(1);
+ // ...
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } finally {
+ Boolean locak = redisDAO.releaseDistributedLock("lock", uuid);
+ log.info("{} release lock {}", Thread.currentThread().getName(), locak);
+ }
+ }
+ };
+ new Thread(runnable, "t1").start();
+ new Thread(runnable, "t2").start();
+ }
+}
diff --git a/src/main/java/io/github/ehlxr/redis/RedisDAO.java b/src/main/java/io/github/ehlxr/redis/RedisDAO.java
index 7f73809..a21b23d 100644
--- a/src/main/java/io/github/ehlxr/redis/RedisDAO.java
+++ b/src/main/java/io/github/ehlxr/redis/RedisDAO.java
@@ -73,7 +73,6 @@ public interface RedisDAO {
/**
* 获取分布式锁
*
- * @param logId 日志 id
* @param key key
* @param value value,需要保证全局唯一,用来删除分布式锁时判断身份使用
* @param expireTime 锁过期时间,毫秒,防止业务崩溃未删除锁,导致死锁
@@ -84,7 +83,6 @@ public interface RedisDAO {
/**
* 释放分布式锁
*
- * @param logId 日志 id
* @param key key
* @param value value,需要和获取锁时传入的一致
* @return 是否释放成功锁
@@ -95,7 +93,6 @@ public interface RedisDAO {
* 分布式限流队列,在时间窗口内(包含该时间点),判断是否达到限流的阀值
* 本接口实现的方法通过加锁避免并发问题,性能不高。只是为了说明限流逻辑如何实现
*
- * @param logId 日志 id
* @param key key
* @param count 限流阀值
* @param timeWindow 限流时间窗口
@@ -107,7 +104,6 @@ public interface RedisDAO {
* 分布式限流队列,在时间窗口内(包含该时间点),判断是否达到限流的阀值
* 本接口实现的方法通过 Lua 脚本避免并发问题,性能较高。
*
- * @param logId 日志 id
* @param key key
* @param count 限流阀值
* @param timeWindow 限流时间窗口
diff --git a/src/main/java/io/github/ehlxr/redis/RedisTemplateConfig.java b/src/main/java/io/github/ehlxr/redis/RedisTemplateConfig.java
new file mode 100644
index 0000000..8b17958
--- /dev/null
+++ b/src/main/java/io/github/ehlxr/redis/RedisTemplateConfig.java
@@ -0,0 +1,31 @@
+package io.github.ehlxr.redis;
+
+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.serializer.StringRedisSerializer;
+
+/**
+ * @author ehlxr
+ */
+@Configuration
+public class RedisTemplateConfig {
+ @Bean(name = "redisTemplate")
+ public RedisTemplate getRedisTemplate(RedisConnectionFactory factory) {
+ return buildRedisTemplateByString(factory);
+ }
+
+ /**
+ * 构建 redisTemplate 使用 string序列化
+ */
+ public RedisTemplate buildRedisTemplateByString(RedisConnectionFactory factory) {
+ RedisTemplate redisTemplate = new RedisTemplate<>();
+ redisTemplate.setConnectionFactory(factory);
+ redisTemplate.setKeySerializer(new StringRedisSerializer());
+ redisTemplate.setValueSerializer(new StringRedisSerializer());
+ redisTemplate.setHashKeySerializer(new StringRedisSerializer());
+ redisTemplate.setHashValueSerializer(new StringRedisSerializer());
+ return redisTemplate;
+ }
+}
diff --git a/src/main/java/io/github/ehlxr/redis/impl/JedisDAOImpl.java b/src/main/java/io/github/ehlxr/redis/impl/JedisDAOImpl.java
index 5a6249f..75a23e3 100644
--- a/src/main/java/io/github/ehlxr/redis/impl/JedisDAOImpl.java
+++ b/src/main/java/io/github/ehlxr/redis/impl/JedisDAOImpl.java
@@ -27,7 +27,6 @@ package io.github.ehlxr.redis.impl;
import io.github.ehlxr.redis.RedisDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.params.SetParams;
@@ -41,10 +40,11 @@ import java.util.List;
* @author ehlxr
* @since 2021-07-15 22:44.
*/
+// @Component("jedisDAOImpl")
public class JedisDAOImpl implements RedisDAO {
private final Logger log = LoggerFactory.getLogger(JedisDAOImpl.class);
- @Autowired
+ // @Autowired
private JedisCluster jc;
@Override
diff --git a/src/main/java/io/github/ehlxr/redis/impl/LettuceDAOImpl.java b/src/main/java/io/github/ehlxr/redis/impl/LettuceDAOImpl.java
index 6e00943..5d70625 100644
--- a/src/main/java/io/github/ehlxr/redis/impl/LettuceDAOImpl.java
+++ b/src/main/java/io/github/ehlxr/redis/impl/LettuceDAOImpl.java
@@ -32,6 +32,7 @@ import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
+import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
@@ -40,18 +41,19 @@ import java.util.concurrent.TimeUnit;
* @author ehlxr
* @since 2021-07-15 22:51.
*/
+@Component("lettuceDAOImpl")
public class LettuceDAOImpl implements RedisDAO {
private static final Logger log = LoggerFactory.getLogger(LettuceDAOImpl.class);
@Autowired
- private RedisTemplate rt;
+ private RedisTemplate redisTemplate;
@Override
public Boolean getDistributedLock(String key, String value, long expireTime) {
Boolean set = false;
try {
- set = rt.opsForValue().setIfAbsent(key, value, expireTime, TimeUnit.MILLISECONDS);
- log.debug("getLock redis key: {}, value: {}, expireTime: {}, result: {}", key, value, expireTime, set);
+ set = redisTemplate.opsForValue().setIfAbsent(key, value, expireTime, TimeUnit.MILLISECONDS);
+ log.info("getLock redis key: {}, value: {}, expireTime: {}, result: {}", key, value, expireTime, set);
} catch (Exception e) {
log.error("getLock redis key: {}, value: {}, expireTime: {}", key, value, expireTime, e);
}
@@ -63,7 +65,7 @@ public class LettuceDAOImpl implements RedisDAO {
Long execute = null;
try {
RedisScript redisScript = new DefaultRedisScript<>(RELEASE_LOCK_LUA, Long.class);
- execute = rt.execute(redisScript, Collections.singletonList(key), value);
+ execute = redisTemplate.execute(redisScript, Collections.singletonList(key), value);
log.debug("releaseLock redis key: {}, value: {}, result: {}", key, value, execute);
} catch (Exception e) {
log.error("releaseLock redis key: {}, value: {}", key, value, e);
@@ -75,17 +77,17 @@ public class LettuceDAOImpl implements RedisDAO {
public synchronized Boolean slideWindow(String key, int count, long timeWindow) {
try {
long nowTime = System.currentTimeMillis();
- ListOperations list = rt.opsForList();
+ ListOperations list = redisTemplate.opsForList();
String farTime = list.index(key, count - 1);
if (farTime == null) {
list.leftPush(key, String.valueOf(nowTime));
- rt.expire(key, timeWindow + 1000L, TimeUnit.MILLISECONDS);
+ redisTemplate.expire(key, timeWindow + 1000L, TimeUnit.MILLISECONDS);
return true;
}
if (nowTime - Long.parseLong(farTime) > timeWindow) {
list.rightPop(key);
list.leftPush(key, String.valueOf(nowTime));
- rt.expire(key, timeWindow + 1000L, TimeUnit.MILLISECONDS);
+ redisTemplate.expire(key, timeWindow + 1000L, TimeUnit.MILLISECONDS);
return true;
}
return false;
@@ -103,7 +105,7 @@ public class LettuceDAOImpl implements RedisDAO {
Long execute = null;
try {
RedisScript redisScript = new DefaultRedisScript<>(SLIDE_WINDOW_LUA, Long.class);
- execute = rt.execute(redisScript, Collections.singletonList(key), String.valueOf(count - 1), String.valueOf(timeWindow), String.valueOf(System.currentTimeMillis()));
+ execute = redisTemplate.execute(redisScript, Collections.singletonList(key), String.valueOf(count - 1), String.valueOf(timeWindow), String.valueOf(System.currentTimeMillis()));
log.debug("slideWindowLua redis key: {}, count: {}, timeWindow: {}, result: {}", key, count, timeWindow, execute);
} catch (Exception e) {
log.error("slideWindowLua redis key: {}, count: {}, timeWindow: {}", key, count, timeWindow, e);
diff --git a/src/main/java/io/github/ehlxr/springamq/controller/ActivemqController.java b/src/main/java/io/github/ehlxr/springamq/controller/ActivemqController.java
index 5350e9d..2c9b379 100644
--- a/src/main/java/io/github/ehlxr/springamq/controller/ActivemqController.java
+++ b/src/main/java/io/github/ehlxr/springamq/controller/ActivemqController.java
@@ -26,7 +26,6 @@ package io.github.ehlxr.springamq.controller;
import io.github.ehlxr.springamq.mq.producer.queue.QueueSender;
import io.github.ehlxr.springamq.mq.producer.topic.TopicSender;
-import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@@ -37,8 +36,8 @@ import javax.annotation.Resource;
/**
* @description controller测试
*/
-@Controller
-@RequestMapping("/activemq")
+// @Controller
+// @RequestMapping("/activemq")
public class ActivemqController {
@Resource
diff --git a/src/main/java/io/github/ehlxr/springamq/mq/consumer/queue/QueueReceiver1.java b/src/main/java/io/github/ehlxr/springamq/mq/consumer/queue/QueueReceiver1.java
index b00662c..abbfdb8 100644
--- a/src/main/java/io/github/ehlxr/springamq/mq/consumer/queue/QueueReceiver1.java
+++ b/src/main/java/io/github/ehlxr/springamq/mq/consumer/queue/QueueReceiver1.java
@@ -25,8 +25,6 @@
package io.github.ehlxr.springamq.mq.consumer.queue;
-import org.springframework.stereotype.Component;
-
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
@@ -35,7 +33,7 @@ import javax.jms.TextMessage;
/**
* @description 队列消息监听器
*/
-@Component
+// @Component
public class QueueReceiver1 implements MessageListener {
@Override
diff --git a/src/main/java/io/github/ehlxr/springamq/mq/consumer/queue/QueueReceiver2.java b/src/main/java/io/github/ehlxr/springamq/mq/consumer/queue/QueueReceiver2.java
index 9ebaa23..1e8f1f4 100644
--- a/src/main/java/io/github/ehlxr/springamq/mq/consumer/queue/QueueReceiver2.java
+++ b/src/main/java/io/github/ehlxr/springamq/mq/consumer/queue/QueueReceiver2.java
@@ -25,8 +25,6 @@
package io.github.ehlxr.springamq.mq.consumer.queue;
-import org.springframework.stereotype.Component;
-
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
@@ -35,7 +33,7 @@ import javax.jms.TextMessage;
/**
* @description 队列消息监听器
*/
-@Component
+// @Component
public class QueueReceiver2 implements MessageListener {
@Override
diff --git a/src/main/java/io/github/ehlxr/springamq/mq/consumer/topic/TopicReceiver1.java b/src/main/java/io/github/ehlxr/springamq/mq/consumer/topic/TopicReceiver1.java
index b6ac7fd..9f6345a 100644
--- a/src/main/java/io/github/ehlxr/springamq/mq/consumer/topic/TopicReceiver1.java
+++ b/src/main/java/io/github/ehlxr/springamq/mq/consumer/topic/TopicReceiver1.java
@@ -24,8 +24,6 @@
package io.github.ehlxr.springamq.mq.consumer.topic;
-import org.springframework.stereotype.Component;
-
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
@@ -34,7 +32,7 @@ import javax.jms.TextMessage;
/**
* @description Topic消息监听器
*/
-@Component
+// @Component
public class TopicReceiver1 implements MessageListener{
@Override
diff --git a/src/main/java/io/github/ehlxr/springamq/mq/consumer/topic/TopicReceiver2.java b/src/main/java/io/github/ehlxr/springamq/mq/consumer/topic/TopicReceiver2.java
index e492482..2dbe2d5 100644
--- a/src/main/java/io/github/ehlxr/springamq/mq/consumer/topic/TopicReceiver2.java
+++ b/src/main/java/io/github/ehlxr/springamq/mq/consumer/topic/TopicReceiver2.java
@@ -24,8 +24,6 @@
package io.github.ehlxr.springamq.mq.consumer.topic;
-import org.springframework.stereotype.Component;
-
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
@@ -34,7 +32,7 @@ import javax.jms.TextMessage;
/**
* @description Topic消息监听器
*/
-@Component
+// @Component
public class TopicReceiver2 implements MessageListener{
@Override
diff --git a/src/main/java/io/github/ehlxr/springamq/mq/producer/queue/QueueSender.java b/src/main/java/io/github/ehlxr/springamq/mq/producer/queue/QueueSender.java
index 74022f3..2e28553 100644
--- a/src/main/java/io/github/ehlxr/springamq/mq/producer/queue/QueueSender.java
+++ b/src/main/java/io/github/ehlxr/springamq/mq/producer/queue/QueueSender.java
@@ -24,24 +24,21 @@
package io.github.ehlxr.springamq.mq.producer.queue;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
-import org.springframework.stereotype.Component;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
/**
- * @description 队列消息生产者,发送消息到队列
+ * @description 队列消息生产者,发送消息到队列
*/
-@Component("queueSender")
+// @Component("queueSender")
public class QueueSender {
- @Autowired
- @Qualifier("jmsQueueTemplate")
+ // @Autowired
+ // @Qualifier("jmsQueueTemplate")
private JmsTemplate jmsTemplate;//通过@Qualifier修饰符来注入对应的bean
/**
@@ -49,7 +46,7 @@ public class QueueSender {
* @param queueName 队列名称
* @param message 消息内容
*/
- public void send(String queueName,final String message){
+ public void send(String queueName, final String message) {
jmsTemplate.send(queueName, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
diff --git a/src/main/java/io/github/ehlxr/springamq/mq/producer/topic/TopicSender.java b/src/main/java/io/github/ehlxr/springamq/mq/producer/topic/TopicSender.java
index 6bc6fb2..c0b65a0 100644
--- a/src/main/java/io/github/ehlxr/springamq/mq/producer/topic/TopicSender.java
+++ b/src/main/java/io/github/ehlxr/springamq/mq/producer/topic/TopicSender.java
@@ -24,11 +24,8 @@
package io.github.ehlxr.springamq.mq.producer.topic;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
-import org.springframework.stereotype.Component;
import javax.jms.JMSException;
import javax.jms.Message;
@@ -38,11 +35,11 @@ import javax.jms.Session;
* @description Topic生产者发送消息到Topic
*/
-@Component("topicSender")
+// @Component("topicSender")
public class TopicSender {
- @Autowired
- @Qualifier("jmsTopicTemplate")
+ // @Autowired
+ // @Qualifier("jmsTopicTemplate")
private JmsTemplate jmsTemplate;
/**
diff --git a/src/main/java/io/github/ehlxr/test/OOMTest.java b/src/main/java/io/github/ehlxr/test/OOMTest.java
index acfcc49..26b1d61 100644
--- a/src/main/java/io/github/ehlxr/test/OOMTest.java
+++ b/src/main/java/io/github/ehlxr/test/OOMTest.java
@@ -28,7 +28,8 @@ import java.util.ArrayList;
import java.util.Random;
/**
- * -Xms600m -Xmx600m -XX:SurvivorRatio=8 -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/Users/ehlxr/Downloads/hprof/1.hprof
+ * -Xms600m -Xmx600m -XX:SurvivorRatio=8 -XX:+PrintGCDetails
+ * -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/Users/ehlxr/Downloads/hprof/1.hprof
*
* @author ehlxr
* @since 2021-08-08 21:26.
@@ -48,7 +49,7 @@ public class OOMTest {
}
class Picture {
- private byte[] pixels;
+ private final byte[] pixels;
public Picture(int length) {
this.pixels = new byte[length];
diff --git a/src/main/java/io/github/ehlxr/test/StudentTrace.java b/src/main/java/io/github/ehlxr/test/StudentTrace.java
index 4cdd665..6d13f70 100644
--- a/src/main/java/io/github/ehlxr/test/StudentTrace.java
+++ b/src/main/java/io/github/ehlxr/test/StudentTrace.java
@@ -13,13 +13,13 @@ import java.util.List;
* @create 16:11
*/
public class StudentTrace {
- static List webpages = new ArrayList();
+ static List webpages = new ArrayList<>();
public static void createWebPages() {
for (int i = 0; i < 100; i++) {
WebPage wp = new WebPage();
- wp.setUrl("http://www." + Integer.toString(i) + ".com");
+ wp.setUrl("http://www." + i + ".com");
wp.setContent(Integer.toString(i));
webpages.add(wp);
}
diff --git a/src/main/resources/ActiveMQ.xml b/src/main/resources/ActiveMQ.xml
index 89ceee1..735e8f6 100644
--- a/src/main/resources/ActiveMQ.xml
+++ b/src/main/resources/ActiveMQ.xml
@@ -1,68 +1,60 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..dfc592a
--- /dev/null
+++ b/src/main/resources/application-dev.yml
@@ -0,0 +1,7 @@
+server:
+ port: 8081
+
+spring:
+ redis:
+ host: 127.0.0.1
+ port: 6379
\ No newline at end of file
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 0000000..5e2d0aa
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,20 @@
+spring:
+ profiles:
+ active: dev
+ application:
+ name: budd
+
+logging:
+ file:
+ path: /datalog/weblog/${spring.application.name}
+ config: classpath:logback-spring.xml
+
+server:
+ tomcat:
+ uri-encoding: UTF-8
+ accept-count: 1000
+ connection-timeout: 30000
+ servlet:
+ context-path: /budd
+ session:
+ timeout: 60
\ No newline at end of file
diff --git a/src/main/resources/applicationContext.xml b/src/main/resources/applicationContext.xml
index d638e98..143da5e 100644
--- a/src/main/resources/applicationContext.xml
+++ b/src/main/resources/applicationContext.xml
@@ -1,25 +1,19 @@
-
-
-
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties
deleted file mode 100644
index 7da5d58..0000000
--- a/src/main/resources/log4j.properties
+++ /dev/null
@@ -1,27 +0,0 @@
-### direct log messages to stdout and logFile###
-log4j.rootCategory=INFO, stdout,logFile
-
-# OpenSymphony Stuff
-log4j.logger.com.opensymphony=INFO
-log4j.logger.org.apache.struts2=INFO
-log4j.logger.org.apache.commons=INFO
-
-# Spring Stuff
-log4j.logger.org.springframework=INFO
-log4j.logger.org.springframework.oxm=INFO
-
-# Hibernate Stuff
-log4j.logger.org.hibernate=INFO
-log4j.logger.org.hibernate.type=INFO
-log4j.logger.org.hibernate.tool.hbm2ddl=INFO
-
-log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-log4j.appender.stdout.layout.ConversionPattern=[%p] %-d{yyyy-MM-dd HH\:mm\:ss} [%t] [%c.%M\:%L] %m%n
-
-#log4j.appender.logFile=org.apache.log4j.RollingFileAppender
-#log4j.appender.logFile.File=${webapp.root}/logs/amq.log
-#log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
-#log4j.appender.logFile.layout.ConversionPattern=[%p] %-d{yyyy-MM-dd HH\:mm\:ss} [%t] [%c.%M\:%L] %m%n
-#log4j.appender.logFile.MaxFileSize = 5MB
-#log4j.appender.logFile.MaxBackupIndex =3
\ No newline at end of file
diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..c8a8078
--- /dev/null
+++ b/src/main/resources/logback-spring.xml
@@ -0,0 +1,276 @@
+
+
+
+
+
+
+
+
+ logback
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ debug
+
+
+ ${CONSOLE_LOG_PATTERN}
+
+ UTF-8
+
+
+
+
+
+
+
+ ${LOG_PATH}/debug.log
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} [%L] - %msg%n
+ UTF-8
+
+
+
+
+ ${LOG_PATH}/debug/%d{yyyy-MM-dd}.%i.log
+
+ 100MB
+
+
+ 15
+
+
+
+ debug
+ ACCEPT
+ DENY
+
+
+
+
+
+
+ ${LOG_PATH}/info.log
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} [%L] - %msg%n
+ UTF-8
+
+
+
+
+ ${LOG_PATH}/info/%d{yyyy-MM-dd}.%i.log
+
+ 100MB
+
+
+ 15
+
+
+
+ info
+ ACCEPT
+ DENY
+
+
+
+
+
+
+ ${LOG_PATH}/warn.log
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} [%L] - %msg%n
+ UTF-8
+
+
+
+ ${LOG_PATH}/warn/%d{yyyy-MM-dd}.%i.log
+
+ 100MB
+
+
+ 15
+
+
+
+ warn
+ ACCEPT
+ DENY
+
+
+
+
+
+
+ ${LOG_PATH}/error.log
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} [%L] - %msg%n
+ UTF-8
+
+
+
+ ${LOG_PATH}/error/%d{yyyy-MM-dd}.%i.log
+
+ 100MB
+
+
+ 15
+
+
+
+ ERROR
+ ACCEPT
+ DENY
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/spring-mvc.xml b/src/main/resources/spring-mvc.xml
index 89b8503..19d5d35 100644
--- a/src/main/resources/spring-mvc.xml
+++ b/src/main/resources/spring-mvc.xml
@@ -1,40 +1,28 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
index 197ad2e..080b3d7 100644
--- a/src/main/webapp/WEB-INF/web.xml
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -1,71 +1,70 @@
- ActiveMQSpringDemo
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
-
-
- log4jConfigLocation
- classpath:log4j.properties
-
-
- log4jRefreshInterval
- 6000
-
-
-
- org.springframework.web.util.Log4jConfigListener
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
- characterEncoding
- org.springframework.web.filter.CharacterEncodingFilter
-
- encoding
- UTF-8
-
-
- forceEncoding
- true
-
-
-
- characterEncoding
- /*
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
- contextConfigLocation
- classpath*:applicationContext.xml,classpath*:ActiveMQ.xml
-
-
- org.springframework.web.context.ContextLoaderListener
-
-
+
+
+
+
+
+
+
+
+
-
-
- SpringMVC
- org.springframework.web.servlet.DispatcherServlet
+
+
+
+
-
- contextConfigLocation
- classpath:spring-mvc.xml
-
- 1
-
-
- SpringMVC
-
- /
-
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/io/github/ehlxr/BuddApplicationTest.java b/src/test/java/io/github/ehlxr/BuddApplicationTest.java
new file mode 100644
index 0000000..4510eb8
--- /dev/null
+++ b/src/test/java/io/github/ehlxr/BuddApplicationTest.java
@@ -0,0 +1,23 @@
+package io.github.ehlxr;
+
+
+import org.junit.jupiter.api.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+/**
+ * Unit test for simple App.
+ */
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class BuddApplicationTest {
+ private static final Logger log = LoggerFactory.getLogger(BuddApplicationTest.class);
+
+ @Test
+ public void redisLockTest() {
+
+ }
+}