├── mykit-delay-rpc ├── mykit-rpc-dubbo │ ├── mykit-rpc-dubbo-xml │ │ ├── src │ │ │ ├── main │ │ │ │ ├── resources │ │ │ │ │ ├── application.yml │ │ │ │ │ ├── dubbo │ │ │ │ │ │ ├── mykit-delay-dubbo.properties │ │ │ │ │ │ └── mykit-delay-server.xml │ │ │ │ │ ├── spring │ │ │ │ │ │ └── mykit-delay-server-main.xml │ │ │ │ │ └── logback.xml │ │ │ │ └── java │ │ │ │ │ └── io │ │ │ │ │ └── mykit │ │ │ │ │ └── delay │ │ │ │ │ └── MykitDelayServer.java │ │ │ └── test │ │ │ │ ├── resources │ │ │ │ ├── dubbo │ │ │ │ │ └── mykit-delay-client.xml │ │ │ │ └── spring │ │ │ │ │ └── mykit-delay-server-client.xml │ │ │ │ └── java │ │ │ │ └── io │ │ │ │ └── mykit │ │ │ │ └── delay │ │ │ │ └── dubbo │ │ │ │ └── client │ │ │ │ └── MykitDelayClient.java │ │ └── pom.xml │ ├── mykit-rpc-dubbo-server │ │ ├── src │ │ │ ├── main │ │ │ │ ├── resources │ │ │ │ │ ├── application.yml │ │ │ │ │ └── config │ │ │ │ │ │ └── logback.xml │ │ │ │ └── java │ │ │ │ │ └── io │ │ │ │ │ └── mykit │ │ │ │ │ └── delay │ │ │ │ │ └── MykitDelayServer.java │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── io │ │ │ │ └── mykit │ │ │ │ └── deplay │ │ │ │ └── test │ │ │ │ └── MykitDeplayServerTest.java │ │ └── pom.xml │ ├── mykit-rpc-dubbo-common │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── io │ │ │ └── mykit │ │ │ └── delay │ │ │ └── rpc │ │ │ └── dubbo │ │ │ └── MykitDelayDubboInterface.java │ └── pom.xml ├── mykit-rpc-brpc │ └── pom.xml ├── mykit-rpc-grpc │ └── pom.xml ├── mykit-rpc-motan │ └── pom.xml ├── mykit-rpc-sofa │ └── pom.xml ├── mykit-rpc-springcloud │ └── pom.xml ├── mykit-rpc-springcloud-alibaba │ └── pom.xml └── pom.xml ├── mykit-delay-config ├── src │ └── main │ │ ├── resources │ │ ├── properties │ │ │ └── starter.properties │ │ ├── META-INF │ │ │ ├── spring.factories │ │ │ └── spring-configuration-metadata.json │ │ ├── sql │ │ │ └── mykit_delay.sql │ │ └── config │ │ │ └── application.yml │ │ └── java │ │ └── io │ │ └── mykit │ │ └── delay │ │ └── starter │ │ └── ready │ │ ├── MykitDelayFileLoad.java │ │ └── StartGetReady.java └── pom.xml ├── mykit-delay-queue ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── services │ │ │ └── io.mykit.delay.queue.core.ConsumeQueueProvider │ │ └── java │ │ └── io │ │ └── mykit │ │ └── delay │ │ ├── queue │ │ ├── redis │ │ │ ├── event │ │ │ │ ├── JobEvent.java │ │ │ │ ├── JobEventListener.java │ │ │ │ ├── RedisJobTraceEvent.java │ │ │ │ ├── RedisJobEventListener.java │ │ │ │ └── JobEventBus.java │ │ │ ├── support │ │ │ │ ├── Lifecycle.java │ │ │ │ ├── DistributedLock.java │ │ │ │ ├── RedisQueueProperties.java │ │ │ │ └── RedisDistributedLock.java │ │ │ ├── JobWrapp.java │ │ │ ├── RedisQueue.java │ │ │ ├── JobOperationService.java │ │ │ ├── ready │ │ │ │ └── ReadyQueueManager.java │ │ │ └── bucket │ │ │ │ └── BucketQueueManager.java │ │ ├── leader │ │ │ ├── LeaderManager.java │ │ │ ├── ServerNode.java │ │ │ ├── LeaderWorkListener.java │ │ │ └── SimpleLeaderManager.java │ │ ├── extension │ │ │ ├── ExtNamed.java │ │ │ ├── SPI.java │ │ │ └── ExtensionLoader.java │ │ ├── core │ │ │ ├── ConsumeQueueProvider.java │ │ │ ├── Job.java │ │ │ └── Queue.java │ │ ├── activemq │ │ │ ├── ActiveMQSender.java │ │ │ ├── ActiveMQSenderFactory.java │ │ │ ├── TopicSender.java │ │ │ └── QueueSender.java │ │ ├── cqp │ │ │ ├── RocketMQConsumeQueue.java │ │ │ ├── ConsoleConsumeQueue.java │ │ │ └── ActiveMQConsumeQueue.java │ │ └── JobMsg.java │ │ └── common │ │ ├── autoconfigigure │ │ ├── message │ │ │ ├── rocketmq │ │ │ │ ├── RocketMQProperties.java │ │ │ │ └── RocketmqAutoConfiguration.java │ │ │ ├── activemq │ │ │ │ ├── ActiveMQProperties.java │ │ │ │ └── ActiveMQAutoConfiguration.java │ │ │ └── MessageProducer.java │ │ ├── RegistryProperties.java │ │ ├── ha │ │ │ └── LeaderAutoConfiguration.java │ │ └── redis │ │ │ └── RedisQueueAutoConfiguration.java │ │ ├── listener │ │ ├── FailedEventListener.java │ │ └── StartEventListener.java │ │ └── conf │ │ ├── RedisConfig.java │ │ └── AppEnvContext.java └── pom.xml ├── .gitignore ├── mykit-delay-common ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── mykit │ └── delay │ └── common │ ├── utils │ ├── RdbOperation.java │ ├── Status.java │ ├── BlockUtils.java │ ├── Constants.java │ ├── NamedUtil.java │ ├── JobIdGenerator.java │ ├── SnowFlake.java │ └── IpUtils.java │ └── exception │ ├── JobNotFoundException.java │ ├── ConsumeQueueException.java │ └── DelayQueueException.java ├── mykit-delay-healthy ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── mykit │ └── delay │ └── healthy │ ├── QueueHealthIndicator.java │ └── HealthAutoConfiguration.java ├── mykit-delay-test ├── pom.xml └── src │ └── main │ ├── java │ └── io │ │ └── mykit │ │ └── delay │ │ ├── TestDelayQueue.java │ │ └── test │ │ ├── PushTest.java │ │ ├── RoundRobinTest.java │ │ └── DistributedLockTest.java │ └── resources │ └── config │ ├── application.yml │ └── logback.xml ├── mykit-delay-controller ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── mykit │ └── delay │ └── controller │ └── AdminController.java ├── mykit-delay-core ├── src │ └── main │ │ ├── java │ │ └── io │ │ │ └── mykit │ │ │ └── delay │ │ │ └── MykitDelayCoreApplication.java │ │ └── resources │ │ └── config │ │ └── logback.xml └── pom.xml └── NOTICE /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-xml/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | management: 2 | security: 3 | enabled: false -------------------------------------------------------------------------------- /mykit-delay-config/src/main/resources/properties/starter.properties: -------------------------------------------------------------------------------- 1 | log.path=/logs 2 | class.path=classpath: 3 | #取值为consoleCQ、activemqCQ和rocketmqCQ,默认为consoleCQ 4 | default.cq=consoleCQ -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/resources/META-INF/services/io.mykit.delay.queue.core.ConsumeQueueProvider: -------------------------------------------------------------------------------- 1 | io.mykit.delay.queue.cqp.RocketMQConsumeQueue 2 | io.mykit.delay.queue.cqp.ConsoleConsumeQueue 3 | io.mykit.delay.queue.cqp.ActiveMQConsumeQueue 4 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-xml/src/main/resources/dubbo/mykit-delay-dubbo.properties: -------------------------------------------------------------------------------- 1 | dubbo.registry.address=zookeeper://10.31.6.43:2181 2 | dubbo.protocol.name=dubbo 3 | dubbo.protocol.port=20880 4 | dubbo.application.name=mykit-rpc-dubbo -------------------------------------------------------------------------------- /mykit-delay-config/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=io.mykit.delay.common.autoconfigigure.redis.RedisQueueAutoConfiguration,io.mykit.delay.common.autoconfigigure.ha.LeaderAutoConfiguration -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | dubbo: 2 | application: 3 | name: mykit-rpc-dubbo 4 | registry: 5 | address: zookeeper://10.31.6.43:2181 6 | protocol: 7 | name: dubbo 8 | port: 20880 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # maven ignore 2 | target/ 3 | *.jar 4 | *.war 5 | *.zip 6 | *.tar 7 | *.tar.gz 8 | 9 | # eclipse ignore 10 | .settings/ 11 | .project 12 | .classpath 13 | 14 | # idea ignore 15 | .idea/ 16 | *.ipr 17 | *.iml 18 | *.iws 19 | 20 | # temp ignore 21 | *.log 22 | *.cache 23 | *.diff 24 | *.patch 25 | *.tmp 26 | *.java~ 27 | *.properties~ 28 | *.xml~ 29 | *.bak 30 | 31 | # system ignore 32 | .DS_Store 33 | Thumbs.db 34 | 35 | # logs ignore 36 | soft.logs* -------------------------------------------------------------------------------- /mykit-delay-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-delay-common 13 | 14 | 15 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-brpc/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay-rpc 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-rpc-brpc 13 | 14 | 15 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-grpc/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay-rpc 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-rpc-grpc 13 | 14 | 15 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-motan/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay-rpc 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-rpc-motan 13 | 14 | 15 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-sofa/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay-rpc 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-rpc-sofa 13 | 14 | 15 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-springcloud/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay-rpc 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-rpc-springcloud 13 | 14 | 15 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-springcloud-alibaba/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay-rpc 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-rpc-springcloud-alibaba 13 | 14 | 15 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-xml/src/test/resources/dubbo/mykit-delay-client.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /mykit-delay-config/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-delay-config 13 | 14 | 15 | 16 | io.mykit.delay 17 | mykit-delay-common 18 | 1.0-SNAPSHOT 19 | 20 | 21 | -------------------------------------------------------------------------------- /mykit-delay-healthy/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-delay-healthy 13 | 14 | 15 | 16 | io.mykit.delay 17 | mykit-delay-queue 18 | 1.0-SNAPSHOT 19 | 20 | 21 | -------------------------------------------------------------------------------- /mykit-delay-queue/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-delay-queue 13 | 14 | 15 | 16 | io.mykit.delay 17 | mykit-delay-config 18 | 1.0-SNAPSHOT 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /mykit-delay-test/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-delay-test 13 | 14 | 15 | 16 | io.mykit.delay 17 | mykit-delay-controller 18 | 1.0-SNAPSHOT 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /mykit-delay-controller/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-delay-controller 13 | 14 | 15 | 16 | io.mykit.delay 17 | mykit-delay-healthy 18 | 1.0-SNAPSHOT 19 | 20 | 21 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-rpc-dubbo 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-rpc-dubbo-common 13 | 14 | 15 | 16 | io.mykit.delay 17 | mykit-delay-queue 18 | 1.0-SNAPSHOT 19 | 20 | 21 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-xml/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-rpc-dubbo 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-rpc-dubbo-xml 13 | 14 | 15 | 16 | io.mykit.delay 17 | mykit-rpc-dubbo-common 18 | 1.0-SNAPSHOT 19 | 20 | 21 | -------------------------------------------------------------------------------- /mykit-delay-rpc/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-delay-rpc 13 | pom 14 | 15 | mykit-rpc-dubbo 16 | mykit-rpc-motan 17 | mykit-rpc-sofa 18 | mykit-rpc-springcloud 19 | mykit-rpc-springcloud-alibaba 20 | mykit-rpc-grpc 21 | mykit-rpc-brpc 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /mykit-delay-common/src/main/java/io/mykit/delay/common/utils/RdbOperation.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.utils; 17 | 18 | /** 19 | * @author liuyazhuang 20 | * @version 1.0.0 21 | * @date 2019/5/29 22 | * @description 数据库操作标识 23 | */ 24 | public enum RdbOperation { 25 | INSERT, UPDATE, DELETE 26 | } 27 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-xml/src/main/resources/spring/mykit-delay-server-main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-xml/src/test/resources/spring/mykit-delay-server-client.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-xml/src/main/resources/dubbo/mykit-delay-server.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/redis/event/JobEvent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.redis.event; 17 | 18 | import io.mykit.delay.queue.JobMsg; 19 | 20 | /** 21 | * @author liuyazhuang 22 | * @version 1.0.0 23 | * @date 2019/5/30 24 | * @description Job事件 25 | */ 26 | public interface JobEvent { 27 | 28 | JobMsg getJob(); 29 | } 30 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/leader/LeaderManager.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.leader; 17 | 18 | 19 | import io.mykit.delay.queue.redis.support.Lifecycle; 20 | 21 | /** 22 | * @author liuyazhuang 23 | * @version 1.0.0 24 | * @date 2019/5/29 25 | * @description Leader管理器 26 | */ 27 | public interface LeaderManager extends Lifecycle { 28 | 29 | boolean isLeader(); 30 | } 31 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/redis/event/JobEventListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.redis.event; 17 | 18 | import com.google.common.eventbus.Subscribe; 19 | 20 | /** 21 | * @author liuyazhuang 22 | * @version 1.0.0 23 | * @date 2019/5/30 24 | * @description Job事件监听器 25 | */ 26 | public interface JobEventListener { 27 | 28 | @Subscribe 29 | void listen(JobEvent event); 30 | } 31 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/extension/ExtNamed.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.extension; 17 | 18 | import java.lang.annotation.*; 19 | 20 | /** 21 | * @author liuyazhuang 22 | * @version 1.0.0 23 | * @date 2019/5/29 24 | * @description 扩展名称 25 | */ 26 | @Documented 27 | @Retention(RetentionPolicy.RUNTIME) 28 | @Target({ElementType.TYPE}) 29 | public @interface ExtNamed { 30 | String value(); 31 | } 32 | -------------------------------------------------------------------------------- /mykit-delay-common/src/main/java/io/mykit/delay/common/exception/JobNotFoundException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.exception; 17 | 18 | /** 19 | * @author liuyazhuang 20 | * @version 1.0.0 21 | * @date 2019/5/29 22 | * @description 任务未找到异常 23 | */ 24 | public class JobNotFoundException extends DelayQueueException { 25 | 26 | public JobNotFoundException(String errorMessage, Object... args) { 27 | super(errorMessage, args); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /mykit-delay-controller/src/main/java/io/mykit/delay/controller/AdminController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.controller; 17 | 18 | import org.springframework.stereotype.Controller; 19 | import org.springframework.web.bind.annotation.RequestMapping; 20 | 21 | /** 22 | * @author liuyazhuang 23 | * @version 1.0.0 24 | * @date 2019/5/30 25 | * @description 后台管理Controller 待实现 26 | */ 27 | @Controller 28 | @RequestMapping(value = "/admin") 29 | public class AdminController { 30 | } 31 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/extension/SPI.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.extension; 17 | 18 | import java.lang.annotation.*; 19 | 20 | /** 21 | * @author liuyazhuang 22 | * @version 1.0.0 23 | * @date 2019/5/29 24 | * @description 25 | */ 26 | @Documented 27 | @Retention(RetentionPolicy.RUNTIME) 28 | @Target({ElementType.TYPE}) 29 | public @interface SPI { 30 | 31 | /** 32 | * 默认的实现方式 33 | */ 34 | String value() default ""; 35 | } 36 | -------------------------------------------------------------------------------- /mykit-delay-common/src/main/java/io/mykit/delay/common/utils/Status.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.utils; 17 | 18 | /** 19 | * @author liuyazhuang 20 | * @version 1.0.0 21 | * @date 2019/5/29 22 | * @description 状态枚举类 23 | */ 24 | public enum Status { 25 | WaitPut,//待加入 26 | Delay,//已经进入延时队列 27 | Ready,//已经出了延时队列 客户端可以方法此数据 28 | Finish,//客户端已经处理完数据了 29 | Delete,//客户端已经把数据删除了 30 | Restore,//手动恢复重发状态/或者是在实时队列中验证时间出现异常 再次放入buck中 31 | ConsumerFailRestore//消费失败 32 | } 33 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/redis/support/Lifecycle.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.redis.support; 17 | 18 | /** 19 | * @author liuyazhuang 20 | * @version 1.0.0 21 | * @date 2019/5/30 22 | * @description 声明周期接口 23 | */ 24 | public interface Lifecycle { 25 | 26 | /** 27 | * 启动 28 | */ 29 | void start(); 30 | 31 | /** 32 | * 停止 33 | */ 34 | void stop(); 35 | 36 | /** 37 | * 是否正在运行 38 | * @return 是返回true; 否返回false 39 | */ 40 | boolean isRunning(); 41 | } 42 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/leader/ServerNode.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.leader; 17 | 18 | /** 19 | * @author liuyazhuang 20 | * @version 1.0.0 21 | * @date 2019/5/29 22 | * @description 服务器节点 23 | */ 24 | public class ServerNode { 25 | public static final String DIR_SPLITE = "/"; 26 | public static final String ROOT = "mykit-delay"; 27 | public static final String LEADERLATCH = DIR_SPLITE + ROOT + DIR_SPLITE + "latch"; 28 | public static String NAMESPACE = "io-mykit-delay"; 29 | } 30 | -------------------------------------------------------------------------------- /mykit-delay-common/src/main/java/io/mykit/delay/common/exception/ConsumeQueueException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.exception; 17 | 18 | /** 19 | * @author liuyazhuang 20 | * @version 1.0.0 21 | * @date 2019/5/29 22 | * @description 消费者队列异常 23 | */ 24 | public class ConsumeQueueException extends DelayQueueException { 25 | 26 | 27 | private static final long serialVersionUID = 4455481920310547043L; 28 | 29 | public ConsumeQueueException(String errorMessage, Object... args) { 30 | super(errorMessage, args); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/core/ConsumeQueueProvider.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.core; 17 | 18 | import io.mykit.delay.common.exception.ConsumeQueueException; 19 | import io.mykit.delay.queue.extension.SPI; 20 | 21 | /** 22 | * @author liuyazhuang 23 | * @version 1.0.0 24 | * @date 2019/5/29 25 | * @description 消费者队列提供者 26 | */ 27 | @SPI("consoleCQ") 28 | public interface ConsumeQueueProvider { 29 | void init(); 30 | 31 | void consumer(Job job) throws ConsumeQueueException; 32 | 33 | void destory(); 34 | } 35 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/core/Job.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.core; 17 | 18 | /** 19 | * @author liuyazhuang 20 | * @version 1.0.0 21 | * @date 2019/5/29 22 | * @description 任务 23 | */ 24 | public interface Job { 25 | 26 | String getBizKey(); 27 | 28 | 29 | String getTopic(); 30 | 31 | 32 | String getId(); 33 | 34 | 35 | long getDelay(); 36 | 37 | 38 | long getTtl(); 39 | 40 | 41 | String getBody(); 42 | 43 | 44 | long getCreateTime(); 45 | 46 | 47 | int getStatus(); 48 | 49 | 50 | String getSubtopic(); 51 | 52 | String toJsonString(); 53 | } 54 | -------------------------------------------------------------------------------- /mykit-delay-common/src/main/java/io/mykit/delay/common/exception/DelayQueueException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.exception; 17 | 18 | /** 19 | * @author liuyazhuang 20 | * @version 1.0.0 21 | * @date 2019/5/29 22 | * @description 延迟队列异常 23 | */ 24 | public class DelayQueueException extends RuntimeException { 25 | 26 | private static final long serialVersionUID = 5018901344199973515L; 27 | 28 | public DelayQueueException(final String errorMessage, final Object... args) { 29 | super(String.format(errorMessage, args)); 30 | } 31 | 32 | public DelayQueueException(final Throwable cause) { 33 | super(cause); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/activemq/ActiveMQSender.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.activemq; 17 | 18 | /** 19 | * @author liuyazhuang 20 | * @version 1.0.0 21 | * @date 2019/6/12 22 | * @description ActiveMQ消息发送接口 23 | */ 24 | public interface ActiveMQSender { 25 | /** 26 | * 发送消息 27 | * @param name 队列或者主题的名称 28 | * @param message 发送的消息 29 | */ 30 | void send(String name, final String message); 31 | 32 | /** 33 | * 延时发送消息 34 | * @param name 队列或者主题的名称 35 | * @param message 发送的消息 36 | * @param scheduledDelayTime 延时时间 37 | */ 38 | void send(String name, final String message,final long scheduledDelayTime); 39 | } 40 | -------------------------------------------------------------------------------- /mykit-delay-test/src/main/java/io/mykit/delay/TestDelayQueue.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay; 17 | 18 | import io.mykit.delay.queue.core.ConsumeQueueProvider; 19 | import io.mykit.delay.starter.ready.StartGetReady; 20 | import org.springframework.boot.SpringApplication; 21 | import org.springframework.boot.autoconfigure.SpringBootApplication; 22 | 23 | /** 24 | * @author liuyazhuang 25 | * @version 1.0.0 26 | * @date 2019/5/30 27 | * @description 测试延迟队列 28 | */ 29 | @SpringBootApplication 30 | public class TestDelayQueue { 31 | 32 | public static void main(String[] args) { 33 | StartGetReady.ready(ConsumeQueueProvider.class.getName()); 34 | SpringApplication.run(TestDelayQueue.class, args); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /mykit-delay-core/src/main/java/io/mykit/delay/MykitDelayCoreApplication.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay; 17 | 18 | import io.mykit.delay.queue.core.ConsumeQueueProvider; 19 | import io.mykit.delay.starter.ready.StartGetReady; 20 | import org.springframework.boot.SpringApplication; 21 | import org.springframework.boot.autoconfigure.SpringBootApplication; 22 | 23 | /** 24 | * @author liuyazhuang 25 | * @version 1.0.0 26 | * @date 2019/5/30 27 | * @description 程序入口 28 | */ 29 | @SpringBootApplication 30 | public class MykitDelayCoreApplication { 31 | 32 | public static void main(String[] args){ 33 | StartGetReady.ready(ConsumeQueueProvider.class.getName()); 34 | SpringApplication.run(MykitDelayCoreApplication.class, args); 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/core/Queue.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.core; 17 | 18 | import io.mykit.delay.common.exception.DelayQueueException; 19 | import io.mykit.delay.queue.JobMsg; 20 | import io.mykit.delay.queue.redis.support.Lifecycle; 21 | 22 | /** 23 | * @author liuyazhuang 24 | * @version 1.0.0 25 | * @date 2019/5/29 26 | * @description 队列 27 | */ 28 | public interface Queue extends Lifecycle { 29 | 30 | void push(JobMsg job) throws DelayQueueException; 31 | 32 | 33 | boolean ack(String jobMsgId) throws DelayQueueException; 34 | 35 | long getSize(); 36 | 37 | void clear(); 38 | 39 | boolean delete(String jobMsgId); 40 | 41 | JobMsg getJob(String jobId); 42 | 43 | String getImplementType(); 44 | } 45 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/redis/JobWrapp.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.redis; 17 | 18 | import com.alibaba.fastjson.JSONObject; 19 | import io.mykit.delay.queue.JobMsg; 20 | 21 | /** 22 | * @author liuyazhuang 23 | * @version 1.0.0 24 | * @date 2019/5/30 25 | * @description 任务包装类 26 | */ 27 | public class JobWrapp extends JobMsg { 28 | 29 | private static final long serialVersionUID = -4623468942451592116L; 30 | private String buckedName; 31 | 32 | public String getBuckedName() { 33 | return buckedName; 34 | } 35 | 36 | public void setBuckedName(String buckedName) { 37 | this.buckedName = buckedName; 38 | } 39 | 40 | @Override 41 | public String toJsonString() { 42 | return JSONObject.toJSONString(this); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-server/src/main/java/io/mykit/delay/MykitDelayServer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2020-9999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay; 17 | 18 | import io.mykit.delay.queue.core.ConsumeQueueProvider; 19 | import io.mykit.delay.starter.ready.StartGetReady; 20 | import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; 21 | import org.springframework.boot.SpringApplication; 22 | import org.springframework.boot.autoconfigure.SpringBootApplication; 23 | 24 | /** 25 | * @author binghe 26 | * @version 1.0.0 27 | * @description 启动类 28 | */ 29 | @EnableDubbo 30 | @SpringBootApplication 31 | public class MykitDelayServer { 32 | public static void main(String[] args){ 33 | StartGetReady.ready(ConsumeQueueProvider.class.getName()); 34 | SpringApplication.run(MykitDelayServer.class, args); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay-rpc 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-rpc-dubbo 13 | pom 14 | 15 | mykit-rpc-dubbo-xml 16 | mykit-rpc-dubbo-common 17 | mykit-rpc-dubbo-server 18 | 19 | 20 | 21 | UTF-8 22 | 2.7.8 23 | 4.0.1 24 | 25 | 26 | 27 | 28 | org.apache.dubbo 29 | dubbo 30 | ${dubbo.version} 31 | 32 | 33 | spring 34 | org.springframework 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /mykit-delay-common/src/main/java/io/mykit/delay/common/utils/BlockUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.utils; 17 | 18 | /** 19 | * @author liuyazhuang 20 | * @version 1.0.0 21 | * @date 2019/5/29 22 | * @description 块工具 23 | */ 24 | public final class BlockUtils { 25 | 26 | public static final long DEF_SLEEP_TIMES = 100L; 27 | 28 | public static void waitingShortTime() { 29 | sleep(DEF_SLEEP_TIMES); 30 | } 31 | 32 | public static void sleep(final long millis, final boolean isInterrupt) { 33 | try { 34 | Thread.sleep(millis); 35 | } catch (final InterruptedException ex) { 36 | if (isInterrupt) { 37 | Thread.currentThread().interrupt(); 38 | } 39 | 40 | } 41 | } 42 | 43 | public static void sleep(final long millis) { 44 | sleep(millis, false); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/cqp/RocketMQConsumeQueue.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.cqp; 17 | 18 | import io.mykit.delay.common.autoconfigigure.message.MessageProducer; 19 | import io.mykit.delay.common.exception.ConsumeQueueException; 20 | import io.mykit.delay.queue.core.ConsumeQueueProvider; 21 | import io.mykit.delay.queue.core.Job; 22 | import io.mykit.delay.queue.extension.ExtNamed; 23 | 24 | /** 25 | * @author liuyazhuang 26 | * @version 1.0.0 27 | * @date 2019/5/29 28 | * @description RocketMQ消费队列实现 29 | */ 30 | @ExtNamed("rocketmqCQ") 31 | public class RocketMQConsumeQueue implements ConsumeQueueProvider { 32 | 33 | @Override 34 | public void init() { 35 | 36 | } 37 | 38 | @Override 39 | public void consumer(Job job) throws ConsumeQueueException { 40 | MessageProducer.send(job); 41 | } 42 | 43 | @Override 44 | public void destory() { 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/redis/support/DistributedLock.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.redis.support; 17 | 18 | /** 19 | * @author liuyazhuang 20 | * @version 1.0.0 21 | * @date 2019/5/30 22 | * @description 分布式锁 23 | */ 24 | public interface DistributedLock { 25 | 26 | /** 27 | * 尝试加锁 28 | * @param key 加锁的key 29 | * @return 尝试加锁成功返回true; 失败返回false 30 | */ 31 | boolean tryLock(String key); 32 | 33 | /** 34 | * 尝试加锁 35 | * @param key 加锁的key 36 | * @param timeout 超时时间 37 | * @return 尝试加锁成功返回true; 失败返回false 38 | */ 39 | boolean tryLock(String key, long timeout); 40 | 41 | /** 42 | * 加锁操作 43 | * @param key 加锁的key 44 | * @return 加锁成功返回true; 失败返回false 45 | */ 46 | boolean lock(String key); 47 | /** 48 | * 解锁操作 49 | * @param key 解锁的key 50 | * @return 解锁成功返回true; 失败返回false 51 | */ 52 | void unlock(String key); 53 | } 54 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/redis/event/RedisJobTraceEvent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.redis.event; 17 | 18 | import io.mykit.delay.common.utils.RdbOperation; 19 | import io.mykit.delay.queue.JobMsg; 20 | 21 | /** 22 | * @author liuyazhuang 23 | * @version 1.0.0 24 | * @date 2019/5/30 25 | * @description Redis Job 栈事件 26 | */ 27 | public class RedisJobTraceEvent implements JobEvent { 28 | 29 | private JobMsg jobMsg = null; 30 | private RdbOperation operation = RdbOperation.UPDATE; 31 | 32 | public RedisJobTraceEvent(JobMsg jobMsg) { 33 | this.jobMsg = jobMsg; 34 | } 35 | 36 | public RedisJobTraceEvent(JobMsg jobMsg, RdbOperation operation) { 37 | this.jobMsg = jobMsg; 38 | this.operation = operation; 39 | } 40 | 41 | @Override 42 | public JobMsg getJob() { 43 | return jobMsg; 44 | } 45 | 46 | public RdbOperation getOperation() { 47 | return operation; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/leader/LeaderWorkListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.leader; 17 | 18 | import io.mykit.delay.queue.core.Queue; 19 | import org.apache.curator.framework.recipes.leader.LeaderLatchListener; 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | 23 | 24 | /** 25 | * @author liuyazhuang 26 | * @version 1.0.0 27 | * @date 2019/5/29 28 | * @description Leader工作流监听器 29 | */ 30 | public class LeaderWorkListener implements LeaderLatchListener { 31 | public static final Logger LOGGER = LoggerFactory.getLogger(LeaderWorkListener.class); 32 | private Queue queue; 33 | 34 | @Override 35 | public void isLeader() { 36 | LOGGER.warn("is starting work!"); 37 | queue.start(); 38 | } 39 | 40 | @Override 41 | public void notLeader() { 42 | LOGGER.warn("is stoping work!"); 43 | queue.stop(); 44 | } 45 | 46 | public void setQueue(Queue queue) { 47 | this.queue = queue; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-xml/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 6 | 7 | 8 | 9 | 10 | 12 | UTF-8 13 | /home/mykit/deplay/dubbo/logs/mykit-deplay-dubbo-xml.log 14 | 15 | /home/mykit/deplay/dubbo/logs/mykit-deplay-dubbo-xml-%d{yyyy-MM-dd}.log 16 | 10 17 | 19 | 512MB 20 | 21 | 22 | 23 | [%-5level] %d{HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /mykit-delay-config/src/main/resources/sql/mykit_delay.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : 127.0.0.1 5 | Source Server Version : 50615 6 | Source Host : 127.0.0.1:3306 7 | Source Database : sdmq 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 50615 11 | File Encoding : 65001 12 | 13 | Date: 2019-05-30 11:19:56 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | 18 | -- ---------------------------- 19 | -- Table structure for mykit_delay_queue_job 20 | -- ---------------------------- 21 | DROP TABLE IF EXISTS `mykit_delay_queue_job`; 22 | CREATE TABLE `mykit_delay_queue_job` ( 23 | `id` varchar(128) NOT NULL, 24 | `bizkey` varchar(128) DEFAULT NULL, 25 | `topic` varchar(128) DEFAULT NULL, 26 | `subtopic` varchar(250) DEFAULT NULL, 27 | `delay` bigint(20) DEFAULT NULL, 28 | `create_time` bigint(20) DEFAULT NULL, 29 | `body` text, 30 | `status` int(11) DEFAULT NULL, 31 | `ttl` int(11) DEFAULT NULL, 32 | `update_time` datetime(3) DEFAULT NULL, 33 | PRIMARY KEY (`id`), 34 | KEY `mykit_delay_queue_job_ID_STATUS` (`id`,`status`), 35 | KEY `mykit_delay_queue_job_STATUS` (`status`) 36 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 37 | 38 | -- ---------------------------- 39 | -- Table structure for mykit_delay_queue_job_log 40 | -- ---------------------------- 41 | DROP TABLE IF EXISTS `mykit_delay_queue_job_log`; 42 | CREATE TABLE `mykit_delay_queue_job_log` ( 43 | `id` varchar(128) NOT NULL, 44 | `status` int(11) DEFAULT NULL, 45 | `thread` varchar(60) DEFAULT NULL, 46 | `update_time` datetime(3) DEFAULT NULL, 47 | `host` varchar(128) DEFAULT NULL, 48 | KEY `mykit_delay_queue_job_LOG_ID_STATUS` (`id`,`status`) 49 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 50 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-common/src/main/java/io/mykit/delay/rpc/dubbo/MykitDelayDubboInterface.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2020-9999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.rpc.dubbo; 17 | 18 | import io.mykit.delay.common.utils.ResponseMessage; 19 | import io.mykit.delay.queue.redis.JobWrapp; 20 | 21 | /** 22 | * @author binghe 23 | * @version 1.0.0 24 | * @description 发布的Dubbo接口 25 | */ 26 | public interface MykitDelayDubboInterface { 27 | 28 | /** 29 | * 推送消息 30 | */ 31 | ResponseMessage push(JobWrapp jobMsg); 32 | 33 | /** 34 | * 删除任务 35 | */ 36 | ResponseMessage delete(String jobId); 37 | 38 | 39 | /** 40 | * 完成任务 41 | */ 42 | ResponseMessage finish(String jobId); 43 | 44 | /** 45 | * 恢复单个任务 46 | */ 47 | ResponseMessage reStoreJob(String jobId); 48 | 49 | /** 50 | * 提供一个方法 假设缓存中间件出现异常 以及数据错乱的情况 提供恢复功能 51 | * @param expire 过期的数据是否需要重发 true需要, false不需要 默认为true 52 | */ 53 | ResponseMessage reStore(Boolean expire); 54 | 55 | /** 56 | * 清除所有的任务 57 | */ 58 | ResponseMessage clearAll(); 59 | } 60 | -------------------------------------------------------------------------------- /mykit-delay-config/src/main/java/io/mykit/delay/starter/ready/MykitDelayFileLoad.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.starter.ready; 17 | 18 | import java.io.IOException; 19 | import java.io.InputStream; 20 | import java.util.Properties; 21 | 22 | /** 23 | * @author liuyazhuang 24 | * @version 1.0.0 25 | * @date 2019/5/31 26 | * @description 加载Properties文件 27 | */ 28 | public class MykitDelayFileLoad { 29 | 30 | public static final String LOG_PATH = "log.path"; 31 | public static final String CLASS_PATH = "class.path"; 32 | public static final String DEFAULT_CQ = "default.cq"; 33 | 34 | private volatile static Properties mProperties; 35 | 36 | static{ 37 | mProperties = new Properties(); 38 | InputStream in = MykitDelayFileLoad.class.getClassLoader().getResourceAsStream("properties/starter.properties"); 39 | try { 40 | mProperties.load(in); 41 | } catch (IOException e) { 42 | e.printStackTrace(); 43 | } 44 | } 45 | 46 | public static String getStringValue(String key){ 47 | return mProperties.getProperty(key, ""); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-xml/src/main/java/io/mykit/delay/MykitDelayServer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2020-9999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay; 17 | 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | import org.springframework.context.support.ClassPathXmlApplicationContext; 21 | 22 | import java.io.BufferedReader; 23 | import java.io.InputStreamReader; 24 | 25 | /** 26 | * @author binghe 27 | * @version 1.0.0 28 | * @description Dubbo服务 29 | */ 30 | public class MykitDelayServer { 31 | private static final Logger LOGGER = LoggerFactory.getLogger(MykitDelayServer.class); 32 | public static void main(String[] args){ 33 | ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/mykit-delay-server-main.xml"); 34 | context.start(); 35 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 36 | try{ 37 | while (!"exit".equals(br.readLine())){ 38 | Thread.sleep(60000); 39 | } 40 | }catch (Exception e){ 41 | LOGGER.error("启动mykit-rpc-dubbo-xml服务失败 {}", e); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/common/autoconfigigure/message/rocketmq/RocketMQProperties.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.autoconfigigure.message.rocketmq; 17 | 18 | import org.springframework.boot.context.properties.ConfigurationProperties; 19 | 20 | /** 21 | * @author liuyazhuang 22 | * @version 1.0.0 23 | * @date 2019/5/29 24 | * @description RocketMQ属性信息 25 | */ 26 | @ConfigurationProperties(prefix = RocketMQProperties.MYKIT_DELAY_ROCKETMQ_PREFIX) 27 | public class RocketMQProperties { 28 | public static final String MYKIT_DELAY_ROCKETMQ_PREFIX = "mykit.delay.rocketmq"; 29 | private String namesrvAddr; 30 | private String filterSourceRoot = "/home/"; 31 | 32 | public String getNamesrvAddr() { 33 | return namesrvAddr; 34 | } 35 | 36 | public void setNamesrvAddr(String namesrvAddr) { 37 | this.namesrvAddr = namesrvAddr; 38 | } 39 | 40 | public String getFilterSourceRoot() { 41 | return filterSourceRoot; 42 | } 43 | 44 | public void setFilterSourceRoot(String filterSourceRoot) { 45 | this.filterSourceRoot = filterSourceRoot; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/redis/event/RedisJobEventListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.redis.event; 17 | 18 | import io.mykit.delay.common.utils.RdbOperation; 19 | import io.mykit.delay.common.utils.Status; 20 | import io.mykit.delay.queue.JobMsg; 21 | import io.mykit.delay.queue.redis.RdbStore; 22 | 23 | /** 24 | * @author liuyazhuang 25 | * @version 1.0.0 26 | * @date 2019/5/30 27 | * @description Redis Job事件监听器 28 | */ 29 | public class RedisJobEventListener implements JobEventListener { 30 | 31 | private RdbStore store; 32 | 33 | @Override 34 | public void listen(JobEvent event) { 35 | if (event instanceof RedisJobTraceEvent) { 36 | RedisJobTraceEvent e = (RedisJobTraceEvent) event; 37 | JobMsg job = e.getJob(); 38 | if (e.getOperation() == RdbOperation.INSERT && job.getStatus() != Status.Restore.ordinal()) { 39 | store.insertJob(job); 40 | } else { 41 | store.updateJobsStatus(job); 42 | } 43 | } 44 | } 45 | 46 | public void setStore(RdbStore store) { 47 | this.store = store; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /mykit-delay-common/src/main/java/io/mykit/delay/common/utils/Constants.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.utils; 17 | 18 | /** 19 | * @author liuyazhuang 20 | * @version 1.0.0 21 | * @date 2019/5/29 22 | * @description 系统常量类 23 | */ 24 | public class Constants { 25 | 26 | public static final String USER_DIR = "user.dir"; 27 | public static String SOFT_HOME_KEY = "soft.home"; 28 | public static String SOFT_LOG_HOME_KEY = "soft.logs"; 29 | public static String SOFT_HOME = System.getProperty(SOFT_HOME_KEY); 30 | public static String SOFT_LOG_HOME = System.getProperty(SOFT_LOG_HOME_KEY); 31 | 32 | public static final String HEALTH_INDICATOR_NAME = "mykit-delay"; 33 | public static final String CODE_UTF8 = "UTF-8"; 34 | public static final String RUN = "run"; 35 | public static final String IS_CLUSTER = "isCluster"; 36 | public static final String BUCKET_SIZE = "bucketSize"; 37 | public static final String PREFIX = "prefix"; 38 | public static final String NAMESPACE = "namespace"; 39 | public static final String IS_MASTER = "isMaster"; 40 | public static final String MYKIT_DELAY_REGISTRY_ENABLE = "mykit.delay.registry.enable"; 41 | } -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/cqp/ConsoleConsumeQueue.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.cqp; 17 | 18 | import io.mykit.delay.common.exception.ConsumeQueueException; 19 | import io.mykit.delay.common.utils.FastJsonConvert; 20 | import io.mykit.delay.queue.core.ConsumeQueueProvider; 21 | import io.mykit.delay.queue.core.Job; 22 | import io.mykit.delay.queue.extension.ExtNamed; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | /** 27 | * @author liuyazhuang 28 | * @version 1.0.0 29 | * @date 2019/5/29 30 | * @description 控制台消费队列实现 31 | */ 32 | @ExtNamed("consoleCQ") 33 | public class ConsoleConsumeQueue implements ConsumeQueueProvider { 34 | private final Logger logger = LoggerFactory.getLogger(ConsoleConsumeQueue.class); 35 | @Override 36 | public void init() { 37 | 38 | } 39 | 40 | @Override 41 | public void consumer(Job job) throws ConsumeQueueException { 42 | System.out.println(String.format("invoke topic %s json:%s", job.getTopic(), FastJsonConvert.convertObjectToJSON(job))); 43 | logger.info(String.format("invoke topic %s json:%s", job.getTopic(), FastJsonConvert.convertObjectToJSON(job))); 44 | } 45 | 46 | @Override 47 | public void destory() { 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/common/listener/FailedEventListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.listener; 17 | 18 | import io.mykit.delay.queue.redis.RedisQueue; 19 | import io.mykit.delay.queue.redis.RedisQueueImpl; 20 | import org.springframework.boot.context.event.ApplicationFailedEvent; 21 | import org.springframework.context.ApplicationContext; 22 | import org.springframework.context.ApplicationListener; 23 | import org.springframework.context.annotation.Configuration; 24 | 25 | /** 26 | * @author liuyazhuang 27 | * @version 1.0.0 28 | * @date 2019/5/29 29 | * @description 失败事件监听器 30 | */ 31 | @Configuration 32 | public class FailedEventListener implements ApplicationListener { 33 | @Override 34 | public void onApplicationEvent(ApplicationFailedEvent event) { 35 | Throwable throwable = event.getException(); 36 | handler(throwable, event); 37 | } 38 | 39 | private void handler(Throwable throwable, ApplicationFailedEvent event) { 40 | ApplicationContext ctx = event.getApplicationContext(); 41 | if (ctx != null) { 42 | RedisQueue redisQueue = ctx.getBean(RedisQueueImpl.class); 43 | if (redisQueue != null && redisQueue.isRunning()) { 44 | redisQueue.stop(); 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /mykit-delay-common/src/main/java/io/mykit/delay/common/utils/NamedUtil.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.utils; 17 | 18 | import com.google.common.base.Joiner; 19 | 20 | import java.util.List; 21 | import com.google.common.collect.Lists; 22 | 23 | 24 | /** 25 | * @author liuyazhuang 26 | * @version 1.0.0 27 | * @date 2019/5/29 28 | * @description 名称工具类 29 | */ 30 | public class NamedUtil { 31 | public static final String SPLITE_CHAR = ":"; 32 | public static final String LOCK_CHAR = "LOCK"; 33 | 34 | public static String buildBucketName(String prefix, String name, int index) { 35 | List lst = Lists.newArrayList(); 36 | lst.add(prefix); 37 | lst.add(name); 38 | lst.add(index); 39 | return Joiner.on(SPLITE_CHAR).join(lst); 40 | } 41 | 42 | public static String buildPoolName(String prefix, String name, String pool) { 43 | return Joiner.on(SPLITE_CHAR).join(Lists.newArrayList(prefix, name, pool)); 44 | } 45 | 46 | public static String buildRealTimeName(String prefix, String name, String readTimeName) { 47 | return Joiner.on(SPLITE_CHAR).join(Lists.newArrayList(prefix, name, readTimeName)); 48 | } 49 | 50 | public static String buildLockName(String prefix) { 51 | return Joiner.on(SPLITE_CHAR).join(Lists.newArrayList(prefix.concat(":" + LOCK_CHAR))); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /mykit-delay-config/src/main/resources/META-INF/spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "groups": [ 3 | { 4 | "sourceType": "io.mykit.delay.common.autoconfigigure.RegistryProperties", 5 | "name": "mykit-delay.registry", 6 | "type": "io.mykit.delay.common.autoconfigigure.RegistryProperties", 7 | "description": "mykit-delay.registry 配置项" 8 | }, 9 | { 10 | "sourceType": "io.mykit.delay.queue.redis.support.RedisQueueProperties", 11 | "name": "mykit.delay.rqueue", 12 | "type": "io.mykit.delay.queue.redis.support.RedisQueueProperties", 13 | "description": "mykit.delay.rqueue 配置项" 14 | } 15 | ], 16 | "properties": [ 17 | { 18 | "sourceType": "io.mykit.delay.common.autoconfigigure.RegistryProperties", 19 | "name": "mykit.delay.registry.enable", 20 | "type": "java.lang.Boolean", 21 | "description": "是否启用注册中心模式" 22 | }, 23 | { 24 | "sourceType": "io.mykit.delay.common.autoconfigigure.RegistryProperties", 25 | "name": "mykit.delay.registry.namespace", 26 | "type": "java.lang.String", 27 | "description": "namespace" 28 | }, 29 | { 30 | "sourceType": "io.mykit.delay.common.autoconfigigure.RegistryProperties", 31 | "name": "mykit.delay.registry.serverList", 32 | "type": "java.lang.String", 33 | "description": "zk serever list" 34 | }, 35 | { 36 | "sourceType": "io.mykit.delay.queue.redis.support.RedisQueueProperties", 37 | "name": "mykit.delay.rqueue.cluster", 38 | "type": "java.lang.Boolean", 39 | "description": "是否启用集群模式" 40 | }, 41 | { 42 | "sourceType": "io.mykit.delay.queue.redis.support.RedisQueueProperties", 43 | "name": "mykit.delay.rqueue.name", 44 | "type": "java.lang.String", 45 | "description": "队列名称" 46 | }, 47 | { 48 | "sourceType": "io.mykit.delay.queue.redis.support.RedisQueueProperties", 49 | "name": "mykit.delay.rqueue.bucketSize", 50 | "type": "java.lang.Integer", 51 | "description": "分区bucket大小" 52 | } 53 | ] 54 | } -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-xml/src/test/java/io/mykit/delay/dubbo/client/MykitDelayClient.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2020-9999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.dubbo.client; 17 | 18 | import io.mykit.delay.queue.core.ConsumeQueueProvider; 19 | import io.mykit.delay.queue.redis.JobWrapp; 20 | import io.mykit.delay.queue.redis.RedisQueue; 21 | import io.mykit.delay.starter.ready.StartGetReady; 22 | import org.springframework.context.ApplicationContext; 23 | import org.springframework.context.support.ClassPathXmlApplicationContext; 24 | 25 | import java.util.UUID; 26 | 27 | /** 28 | * @author binghe 29 | * @version 1.0.0 30 | * @description dubbo测试客户端 31 | */ 32 | public class MykitDelayClient { 33 | 34 | public static void main(String[] args){ 35 | StartGetReady.ready(ConsumeQueueProvider.class.getName()); 36 | ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/mykit-delay-server-client.xml"); 37 | RedisQueue redisQueue = (RedisQueue) context.getBean("redisQueue"); 38 | JobWrapp jobWrapp = new JobWrapp(); 39 | jobWrapp.setId(UUID.randomUUID().toString()); 40 | jobWrapp.setBuckedName("test"); 41 | jobWrapp.setBizKey("testCode"); 42 | jobWrapp.setBody("测试定时调度"); 43 | jobWrapp.setDelay(1800); 44 | jobWrapp.setCreateTime(System.currentTimeMillis()); 45 | redisQueue.push(jobWrapp); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/cqp/ActiveMQConsumeQueue.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.cqp; 17 | 18 | import io.mykit.delay.common.exception.ConsumeQueueException; 19 | import io.mykit.delay.queue.activemq.ActiveMQSender; 20 | import io.mykit.delay.queue.activemq.ActiveMQSenderFactory; 21 | import io.mykit.delay.queue.core.ConsumeQueueProvider; 22 | import io.mykit.delay.queue.core.Job; 23 | import io.mykit.delay.queue.extension.ExtNamed; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | /** 28 | * @author liuyazhuang 29 | * @version 1.0.0 30 | * @date 2019/6/12 31 | * @description ActiveMQ 消费队列 32 | */ 33 | @ExtNamed("activemqCQ") 34 | public class ActiveMQConsumeQueue implements ConsumeQueueProvider { 35 | private final Logger logger = LoggerFactory.getLogger(ActiveMQConsumeQueue.class); 36 | @Override 37 | public void init() { 38 | 39 | } 40 | 41 | @Override 42 | public void consumer(Job job) throws ConsumeQueueException { 43 | ActiveMQSender activeMQSender = ActiveMQSenderFactory.getActiveMQSender(ActiveMQSenderFactory.JMS_QUEUE_SENDER); 44 | if (activeMQSender != null){ 45 | activeMQSender.send(job.getTopic(), job.toJsonString()); 46 | }else{ 47 | logger.info("未获取到队列发送句柄...."); 48 | } 49 | } 50 | 51 | @Override 52 | public void destory() { 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/common/autoconfigigure/message/rocketmq/RocketmqAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.autoconfigigure.message.rocketmq; 17 | 18 | import com.alibaba.rocketmq.client.producer.DefaultMQProducer; 19 | 20 | import io.mykit.delay.common.autoconfigigure.message.MessageProducer; 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 23 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 24 | import org.springframework.context.annotation.Bean; 25 | import org.springframework.context.annotation.Configuration; 26 | import org.springframework.util.Assert; 27 | 28 | /** 29 | * @author liuyazhuang 30 | * @version 1.0.0 31 | * @date 2019/5/29 32 | * @description RocketMQ注册 33 | */ 34 | @Configuration 35 | @EnableConfigurationProperties(RocketMQProperties.class) 36 | @ConditionalOnClass(value = {DefaultMQProducer.class}) 37 | public class RocketmqAutoConfiguration { 38 | 39 | @Autowired 40 | private RocketMQProperties properties; 41 | 42 | @Bean(initMethod = "init", destroyMethod = "close") 43 | public MessageProducer newMessageProducer() { 44 | Assert.notNull(properties.getNamesrvAddr(), "请正确配置NamesrvAddr"); 45 | MessageProducer producer = new MessageProducer(); 46 | producer.setNamesrvAddr(properties.getNamesrvAddr()); 47 | return producer; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/activemq/ActiveMQSenderFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.activemq; 17 | 18 | import java.util.HashMap; 19 | import java.util.Map; 20 | 21 | /** 22 | * @author liuyazhuang 23 | * @version 1.0.0 24 | * @date 2019/6/12 25 | * @description ActiveMQ发送者工厂类 26 | * 主要是项目启动的时候缓存发送消息的句柄QueueSender和TopicSender, 供实际延时到时向ActiveMQ推送消息使用 27 | * 前提是要在starter.properties中的default.cq 配置为 activemqCQ 28 | */ 29 | public class ActiveMQSenderFactory { 30 | 31 | /** 32 | * 点对点队列模式 33 | */ 34 | public static final String JMS_QUEUE_SENDER = "queueSender"; 35 | 36 | /** 37 | * 发布/订阅模式 38 | */ 39 | public static final String JMS_TOPIC_SENDER = "topicSender"; 40 | 41 | /** 42 | * 存放发送消息句柄QueueSender和TopicSender的缓存结构 43 | */ 44 | private volatile static Map instance; 45 | 46 | static { 47 | instance = new HashMap(); 48 | } 49 | 50 | /** 51 | * 将发送数据的句柄放入缓存 52 | * @param key 缓存中的key 53 | * @param activeMQSender 发送消息的句柄 54 | */ 55 | public static void put(String key, ActiveMQSender activeMQSender){ 56 | instance.put(key, activeMQSender); 57 | } 58 | 59 | /** 60 | * 获取缓存中的发送消息句柄 61 | * @param key 缓存中的key 62 | * @return 发送消息句柄 63 | */ 64 | public static ActiveMQSender getActiveMQSender(String key){ 65 | return instance.get(key); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/redis/event/JobEventBus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.redis.event; 17 | 18 | import com.google.common.eventbus.AsyncEventBus; 19 | import com.google.common.eventbus.EventBus; 20 | import com.google.common.util.concurrent.MoreExecutors; 21 | 22 | import java.util.concurrent.atomic.AtomicBoolean; 23 | 24 | 25 | /** 26 | * @author liuyazhuang 27 | * @version 1.0.0 28 | * @date 2019/5/30 29 | * @description Job事件业务 30 | */ 31 | public class JobEventBus { 32 | private EventBus bus = null; 33 | private AtomicBoolean register = new AtomicBoolean(false); 34 | 35 | private JobEventBus() { 36 | bus = new AsyncEventBus(MoreExecutors.newDirectExecutorService()); 37 | } 38 | 39 | public static JobEventBus getInstance() { 40 | return LazyHolder.JEB; 41 | } 42 | 43 | public void register(JobEventListener listener) { 44 | if (register.compareAndSet(false, true)) { 45 | bus.register(listener); 46 | } 47 | 48 | } 49 | 50 | public void unregister(JobEventListener listener) { 51 | if (register.get()) { 52 | bus.unregister(listener); 53 | } 54 | } 55 | 56 | public void post(JobEvent event) { 57 | if (register.get()) { 58 | bus.post(event); 59 | } 60 | 61 | } 62 | 63 | private static class LazyHolder { 64 | 65 | private static final JobEventBus JEB = new JobEventBus(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/common/listener/StartEventListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.listener; 17 | 18 | import io.mykit.delay.common.conf.AppEnvContext; 19 | import io.mykit.delay.common.utils.Constants; 20 | import io.mykit.delay.queue.redis.RedisQueue; 21 | import io.mykit.delay.queue.redis.RedisQueueImpl; 22 | import org.slf4j.Logger; 23 | import org.slf4j.LoggerFactory; 24 | import org.springframework.context.ApplicationContext; 25 | import org.springframework.context.ApplicationListener; 26 | import org.springframework.context.annotation.Configuration; 27 | import org.springframework.context.event.ContextRefreshedEvent; 28 | 29 | /** 30 | * @author liuyazhuang 31 | * @version 1.0.0 32 | * @date 2019/5/29 33 | * @description 启动事件监听器 34 | */ 35 | @Configuration 36 | public class StartEventListener implements ApplicationListener { 37 | public static final Logger LOGGER = LoggerFactory.getLogger(StartEventListener.class); 38 | 39 | @Override 40 | public void onApplicationEvent(ContextRefreshedEvent event) { 41 | ApplicationContext ctx = event.getApplicationContext(); 42 | if (ctx != null) { 43 | RedisQueue redisQueue = ctx.getBean(RedisQueueImpl.class); 44 | String regEnable = AppEnvContext.getProperty(Constants.MYKIT_DELAY_REGISTRY_ENABLE, "false"); 45 | if (!redisQueue.isRunning() && !Boolean.parseBoolean(regEnable)) { 46 | LOGGER.info("starting Queue StandAlone Model ..."); 47 | redisQueue.start(); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /mykit-delay-test/src/main/resources/config/application.yml: -------------------------------------------------------------------------------- 1 | 2 | mykit: 3 | delay: 4 | logpath: ../logs 5 | registry: 6 | enable: false 7 | namespace: io-mykit-delay 8 | serverList: 127.0.0.1:2181 9 | rocketmq: 10 | namesrvAddr: 127.0.0.1:9876 11 | filterSourceRoot: /home/ 12 | activemq: 13 | # 连接的ActiveMQ failover:(tcp://localhost:61616,tcp://localhost:61617) 14 | brokerUrl: failover:(tcp://127.0.0.1:61616) 15 | username: admin 16 | password: admin123 17 | useExponentialBackOff: true 18 | useAsyncSend: true 19 | maximumRedeliveries: 1 20 | initialRedeliveryDelay: 3000 21 | backOffMultiplier: 2 22 | maximumRedeliveryDelay: 3000 23 | queue_pub_sub_domain: false 24 | topic_pub_sub_domain: true 25 | rqueue: 26 | #是否已集群模式运行 会涉及到分布式锁竞争的情况 默认为false 27 | cluster: false 28 | name: mykit-delay 29 | bucketSize: 4 30 | 31 | spring: 32 | jmx: 33 | enabled: true 34 | application: 35 | name: 'mykit' 36 | version: '1.0.0' 37 | datasource: 38 | url: jdbc:mysql://127.0.0.1:3306/mykit_delay?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true 39 | driverClassName: com.mysql.jdbc.Driver 40 | username: root 41 | password: root 42 | type: com.alibaba.druid.pool.DruidDataSource 43 | filters: stat 44 | maxActive: 30 45 | initialSize: 3 46 | maxWait: 60000 47 | maxIdle: 30 48 | minIdle: 3 49 | timeBetweenEvictionRunsMillis: 60000 50 | minEvictableIdleTimeMillis: 300000 51 | validationQuery: select 'x' 52 | testWhileIdle: true 53 | testOnBorrow: false 54 | testOnReturn: false 55 | poolPreparedStatements: true 56 | maxOpenPreparedStatements: 20 57 | redis: 58 | # host: 192.168.175.11 59 | # password: 60 | # port: 6379 61 | timeout: 60000 62 | database: 1 63 | cluster: 64 | nodes: 65 | - 127.0.0.1:7001 66 | - 127.0.0.1:7002 67 | - 127.0.0.1:7003 68 | - 127.0.0.1:7004 69 | - 127.0.0.1:7005 70 | - 127.0.0.1:7006 71 | pool: 72 | max-idle: 300 73 | min-idle: 10 74 | max-active: 200 75 | max-wait: 10000 76 | 77 | server: 78 | port: 6357 79 | 80 | logging: 81 | config: classpath:config/logback.xml 82 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/redis/RedisQueue.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.redis; 17 | 18 | import io.mykit.delay.common.exception.DelayQueueException; 19 | import io.mykit.delay.queue.JobMsg; 20 | import io.mykit.delay.queue.core.Queue; 21 | import io.mykit.delay.queue.redis.bucket.BucketQueueManager; 22 | import io.mykit.delay.queue.redis.ready.ReadyQueueManager; 23 | import io.mykit.delay.queue.redis.support.RedisQueueProperties; 24 | 25 | import java.io.Closeable; 26 | 27 | /** 28 | * @author liuyazhuang 29 | * @version 1.0.0 30 | * @date 2019/5/30 31 | * @description Redis队列接口 32 | */ 33 | public interface RedisQueue extends Queue, Closeable { 34 | 35 | /** 36 | * 推动任务 37 | * @param job 任务实例 38 | * @throws DelayQueueException 39 | */ 40 | void push(JobMsg job) throws DelayQueueException; 41 | 42 | /** 43 | * 设置属性信息 44 | * @param properties Redis队列属性 45 | */ 46 | void setProperties(RedisQueueProperties properties); 47 | 48 | /** 49 | * 设置任务操作服务接口 50 | * @param jobOperationService 任务操作服务接口 51 | */ 52 | void setJobOperationService(JobOperationService jobOperationService); 53 | 54 | /** 55 | * 设置BucketQueue管理器 56 | * @param bucketQueueManager BucketQueue管理器 57 | */ 58 | void setBucketQueueManager(BucketQueueManager bucketQueueManager); 59 | 60 | /** 61 | * 设置准备队列管理器 62 | * @param readyQueueManager 准备队列管理器 63 | */ 64 | void setReadyQueueManager(ReadyQueueManager readyQueueManager); 65 | 66 | /** 67 | * 构建队列名称 68 | * @return 队列名称 69 | */ 70 | String buildQueueName(); 71 | } 72 | -------------------------------------------------------------------------------- /mykit-delay-config/src/main/resources/config/application.yml: -------------------------------------------------------------------------------- 1 | mykit: 2 | delay: 3 | logpath: ../logs 4 | registry: 5 | enable: false 6 | namespace: io-mykit-delay 7 | serverList: 127.0.0.1:2181 8 | rocketmq: 9 | namesrvAddr: 127.0.0.1:9876 10 | filterSourceRoot: /home/ 11 | activemq: 12 | # 连接的ActiveMQ failover:(tcp://localhost:61616,tcp://localhost:61617) 13 | brokerUrl: failover:(tcp://127.0.0.1:61616) 14 | username: admin 15 | password: admin123 16 | useExponentialBackOff: true 17 | useAsyncSend: true 18 | maximumRedeliveries: 1 19 | initialRedeliveryDelay: 3000 20 | backOffMultiplier: 2 21 | maximumRedeliveryDelay: 3000 22 | queue_pub_sub_domain: false 23 | topic_pub_sub_domain: true 24 | rqueue: 25 | #是否已集群模式运行 会涉及到分布式锁竞争的情况 默认为false 26 | cluster: false 27 | name: mykit-delay 28 | bucketSize: 4 29 | 30 | spring: 31 | jmx: 32 | enabled: true 33 | application: 34 | name: 'mykit-delay' 35 | version: '1.0.0' 36 | datasource: 37 | url: jdbc:mysql://127.0.0.1:3306/mykit_delay?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true 38 | driverClassName: com.mysql.jdbc.Driver 39 | username: root 40 | password: root 41 | type: com.alibaba.druid.pool.DruidDataSource 42 | filters: stat 43 | maxActive: 30 44 | initialSize: 3 45 | maxWait: 60000 46 | maxIdle: 30 47 | minIdle: 3 48 | timeBetweenEvictionRunsMillis: 60000 49 | minEvictableIdleTimeMillis: 300000 50 | validationQuery: select 'x' 51 | testWhileIdle: true 52 | testOnBorrow: false 53 | testOnReturn: false 54 | poolPreparedStatements: true 55 | maxOpenPreparedStatements: 20 56 | redis: 57 | # host: localhost 58 | # password: aJjbuDRYw4 59 | # port: 6380 60 | timeout: 60000 61 | database: 11 62 | cluster: 63 | nodes: 64 | - 10.31.5.65:7001 65 | - 10.31.5.65:7002 66 | - 10.31.5.65:7003 67 | - 10.31.5.65:7004 68 | - 10.31.5.65:7005 69 | - 10.31.5.65:7006 70 | pool: 71 | max-idle: 300 72 | min-idle: 10 73 | max-active: 200 74 | max-wait: 10000 75 | 76 | server: 77 | port: 6355 78 | 79 | logging: 80 | config: file:${soft.home}/config/logback.xml 81 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-server/src/test/java/io/mykit/deplay/test/MykitDeplayServerTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2020-9999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.deplay.test; 17 | 18 | import io.mykit.delay.common.utils.Constants; 19 | import io.mykit.delay.queue.redis.JobWrapp; 20 | import io.mykit.delay.rpc.dubbo.MykitDelayDubboInterface; 21 | import org.apache.dubbo.config.annotation.DubboReference; 22 | import org.junit.BeforeClass; 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.springframework.boot.test.context.SpringBootTest; 26 | import org.springframework.context.annotation.ComponentScan; 27 | import org.springframework.test.context.junit4.SpringRunner; 28 | 29 | import java.util.UUID; 30 | 31 | /** 32 | * @author binghe 33 | * @version 1.0.0 34 | * @description 测试Dubbo 35 | */ 36 | @RunWith(SpringRunner.class) 37 | @SpringBootTest(classes = MykitDeplayServerTest.class) 38 | @ComponentScan(basePackages = "io.mykit.delay") 39 | public class MykitDeplayServerTest { 40 | 41 | @DubboReference(version = "1.0.0") 42 | private MykitDelayDubboInterface mykitDelayDubboInterface; 43 | 44 | @BeforeClass 45 | public static void initClass(){ 46 | System.setProperty(Constants.SOFT_HOME_KEY, "D:/Workspaces/mykit/mykit-delay/mykit-delay/mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-server/target/classes/"); 47 | 48 | } 49 | @Test 50 | public void testPushJob(){ 51 | JobWrapp jobWrapp = new JobWrapp(); 52 | jobWrapp.setId(UUID.randomUUID().toString()); 53 | jobWrapp.setBuckedName("test"); 54 | jobWrapp.setBizKey("testCode"); 55 | jobWrapp.setBody("测试定时调度"); 56 | jobWrapp.setDelay(1800); 57 | jobWrapp.setTopic("testTopic"); 58 | jobWrapp.setCreateTime(System.currentTimeMillis()); 59 | mykitDelayDubboInterface.push(jobWrapp); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /mykit-delay-test/src/main/java/io/mykit/delay/test/PushTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.test; 17 | 18 | import io.mykit.delay.common.utils.JobIdGenerator; 19 | import io.mykit.delay.queue.JobMsg; 20 | import io.mykit.delay.queue.redis.JobWrapp; 21 | import io.mykit.delay.queue.redis.RedisQueue; 22 | import org.junit.Test; 23 | import org.junit.runner.RunWith; 24 | import org.springframework.beans.factory.annotation.Autowired; 25 | import org.springframework.boot.test.context.SpringBootTest; 26 | import org.springframework.test.context.junit4.SpringRunner; 27 | 28 | import java.util.Calendar; 29 | import java.util.Date; 30 | import java.util.Random; 31 | 32 | /** 33 | * @author liuyazhuang 34 | * @version 1.0.0 35 | * @date 2019/5/30 36 | * @description 测试添加任务 37 | */ 38 | @RunWith(SpringRunner.class) 39 | @SpringBootTest 40 | public class PushTest { 41 | @Autowired 42 | private RedisQueue redisQueue; 43 | 44 | @Test 45 | public void pushTest() { 46 | long time = 1000 * (60 * new Random().nextInt(2) + 1); 47 | Calendar calendar = Calendar.getInstance(); 48 | calendar.setTimeInMillis(System.currentTimeMillis() + time); 49 | int hour = calendar.get(Calendar.HOUR_OF_DAY); 50 | int min = calendar.get(Calendar.MINUTE); 51 | int src = calendar.get(Calendar.SECOND); 52 | JobMsg job = new JobWrapp(); 53 | job.setBody(String.format("{你应该在 %s 运行}", hour + ":" + min + ":" + src)); 54 | job.setTopic("test"); 55 | job.setDelay(time); 56 | job.setId(JobIdGenerator.getStringId()); 57 | redisQueue.push(job); 58 | System.out.println(job.getBody()); 59 | System.out.println("执行完成..."); 60 | 61 | // try { 62 | // Thread.sleep(1000L); 63 | // } catch (InterruptedException e) { 64 | // e.printStackTrace(); 65 | // } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/activemq/TopicSender.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.activemq; 17 | 18 | import org.apache.activemq.ScheduledMessage; 19 | import org.springframework.jms.core.JmsTemplate; 20 | import org.springframework.jms.core.MessageCreator; 21 | 22 | import javax.jms.JMSException; 23 | import javax.jms.Message; 24 | import javax.jms.Session; 25 | import javax.jms.TextMessage; 26 | 27 | /** 28 | * @author liuyazhuang 29 | * @version 1.0.0 30 | * @date 2019/6/12 31 | * @description Topic生产者发送消息到Topic 32 | */ 33 | public class TopicSender implements ActiveMQSender{ 34 | 35 | private JmsTemplate jmsTemplate; 36 | 37 | public TopicSender(JmsTemplate jmsTemplate) { 38 | this.jmsTemplate = jmsTemplate; 39 | } 40 | 41 | /** 42 | * 发送一条消息到指定的队列(目标) 43 | * @param topicName 队列名称 44 | * @param message 消息内容 45 | */ 46 | @Override 47 | public void send(String topicName,final String message){ 48 | jmsTemplate.send(topicName, new MessageCreator() { 49 | @Override 50 | public Message createMessage(Session session) throws JMSException { 51 | return session.createTextMessage(message); 52 | } 53 | }); 54 | } 55 | 56 | /** 57 | * 发送一条消息到指定的队列(目标) 58 | * @param topicName 队列名称 59 | * @param message 消息内容 60 | * @param scheduledDelayTime 间隔时间 61 | */ 62 | @Override 63 | public void send(String topicName, final String message, final long scheduledDelayTime) { 64 | jmsTemplate.send(topicName, new MessageCreator() { 65 | @Override 66 | public Message createMessage(Session session) throws JMSException { 67 | TextMessage msg = session.createTextMessage(message); 68 | msg.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, scheduledDelayTime); 69 | return msg; 70 | } 71 | }); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/redis/JobOperationService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.redis; 17 | 18 | import io.mykit.delay.common.utils.Status; 19 | import io.mykit.delay.queue.JobMsg; 20 | 21 | import java.util.List; 22 | 23 | /** 24 | * @author liuyazhuang 25 | * @version 1.0.0 26 | * @date 2019/5/30 27 | * @description 任务操作服务接口 28 | */ 29 | public interface JobOperationService { 30 | /** 31 | * 获取Job元数据 32 | */ 33 | JobMsg getJob(String jobId); 34 | 35 | /** 36 | * 添加Job到元数据池 37 | */ 38 | void addJobToPool(JobMsg jobMsg); 39 | 40 | /** 41 | * 删除元数据此任务 42 | */ 43 | void removeJobToPool(String jobId); 44 | 45 | /** 46 | * 更新元任务池任务的状态 47 | */ 48 | void updateJobStatus(String jobId, Status status); 49 | 50 | /** 51 | * 根据JobId删除元数据 52 | */ 53 | void deleteJobToPool(String jobId); 54 | 55 | /** 56 | * 加一个Job到指定Bucket 57 | */ 58 | void addBucketJob(String bucketName, String JobId, double score); 59 | 60 | /** 61 | * 从指定Bucket删除一个Job 62 | */ 63 | void removeBucketKey(String bucketName, String jobId); 64 | 65 | /** 66 | * 添加一个Job到 可执行队列 67 | */ 68 | void addReadyTime(String readyName, String jobId); 69 | 70 | 71 | /** 72 | * 获取一个实时队列中的第一个数据 73 | */ 74 | String getReadyJob(); 75 | 76 | /** 77 | * 获取指定个数实时队列中的数据 不是用的POP方式 需要手動刪除 78 | */ 79 | List getReadyJob(int size); 80 | 81 | /** 82 | * 刪除实时队列中的一个数据 83 | */ 84 | boolean removeReadyJob(String jobId); 85 | 86 | /** 87 | * 获取bucket中最顶端的一个Job 88 | */ 89 | String getBucketTop1Job(String bucketName); 90 | 91 | /** 92 | * 批量获取顶端数据 只获取满足条件的数据 最多size行 93 | */ 94 | List getBucketTopJobs(String bucketName, int size); 95 | 96 | /** 97 | * 清空所有任务 98 | */ 99 | void clearAll(); 100 | } 101 | -------------------------------------------------------------------------------- /mykit-delay-core/src/main/resources/config/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 9 | 10 | 11 | 12 | 15 | %clr(%d{HH:mm:ss.SSS}){faint} %clr([%thread]){faint} %clr(%-5level){magenta}%clr(%-40.40logger{40}){cyan} %L %clr(:){faint}- %msg%n 16 | 17 | 18 | 19 | 20 | 21 | 22 | ${logpath}/mykit-delay-%d{yyyy-MM-dd}.log 23 | 30 24 | 25 | 26 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{40} - %msg%n 27 | 28 | 29 | 30 | 31 | ${logpath}/mykit-delay-track-%d{yyyy-MM-dd}.log 32 | 30 33 | 34 | 35 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{40} - %msg%n 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /mykit-delay-test/src/main/resources/config/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 9 | 10 | 11 | 12 | 15 | %clr(%d{HH:mm:ss.SSS}){faint} %clr([%thread]){faint} %clr(%-5level){magenta}%clr(%-40.40logger{40}){cyan} %L %clr(:){faint}- %msg%n 16 | 17 | 18 | 19 | 20 | 21 | 22 | ${logpath}/mykit-delay-%d{yyyy-MM-dd}.log 23 | 30 24 | 25 | 26 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{40} - %msg%n 27 | 28 | 29 | 30 | 31 | ${logpath}/mykit-delay-track-%d{yyyy-MM-dd}.log 32 | 30 33 | 34 | 35 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{40} - %msg%n 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/activemq/QueueSender.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.activemq; 17 | 18 | import org.apache.activemq.ScheduledMessage; 19 | import org.springframework.beans.factory.annotation.Autowired; 20 | import org.springframework.beans.factory.annotation.Qualifier; 21 | import org.springframework.jms.core.JmsTemplate; 22 | import org.springframework.jms.core.MessageCreator; 23 | 24 | import javax.jms.JMSException; 25 | import javax.jms.Message; 26 | import javax.jms.Session; 27 | import javax.jms.TextMessage; 28 | 29 | /** 30 | * @author liuyazhuang 31 | * @version 1.0.0 32 | * @date 2019/6/12 33 | * @description 队列消息生产者,发送消息到队列 34 | */ 35 | public class QueueSender implements ActiveMQSender{ 36 | 37 | private JmsTemplate jmsTemplate; 38 | 39 | public QueueSender(JmsTemplate jmsTemplate) { 40 | this.jmsTemplate = jmsTemplate; 41 | } 42 | 43 | /** 44 | * 发送一条消息到指定的队列(目标) 45 | * @param queueName 队列名称 46 | * @param message 消息内容 47 | */ 48 | @Override 49 | public void send(String queueName,final String message){ 50 | jmsTemplate.send(queueName, new MessageCreator() { 51 | @Override 52 | public Message createMessage(Session session) throws JMSException { 53 | return session.createTextMessage(message); 54 | } 55 | }); 56 | } 57 | 58 | /** 59 | * 发送一条消息到指定的队列(目标) 60 | * @param queueName 队列名称 61 | * @param message 消息内容 62 | * @param scheduledDelayTime 间隔时间 63 | */ 64 | @Override 65 | public void send(String queueName,final String message,final long scheduledDelayTime){ 66 | jmsTemplate.send(queueName, new MessageCreator() { 67 | @Override 68 | public Message createMessage(Session session) throws JMSException { 69 | TextMessage msg = session.createTextMessage(message); 70 | msg.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, scheduledDelayTime); 71 | return msg; 72 | } 73 | }); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /mykit-delay-test/src/main/java/io/mykit/delay/test/RoundRobinTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.test; 17 | 18 | import io.mykit.delay.queue.redis.RedisQueue; 19 | import io.mykit.delay.queue.redis.RedisQueueImpl; 20 | import io.mykit.delay.queue.redis.support.RedisQueueProperties; 21 | 22 | /** 23 | * @author liuyazhuang 24 | * @version 1.0.0 25 | * @date 2019/5/30 26 | * @description 27 | */ 28 | public class RoundRobinTest { 29 | 30 | public static void main(String[] args) { 31 | RedisQueueProperties properties = new RedisQueueProperties(); 32 | properties.setBucketSize(1); 33 | properties.setPrefix("io.mykit.delay"); 34 | properties.setName("b"); 35 | final RedisQueue redisQueue = new RedisQueueImpl(); 36 | redisQueue.setProperties(properties); 37 | new Thread(new Runnable() { 38 | @Override 39 | public void run() { 40 | for (int i = 0; i < 5; i++) { 41 | System.out.println(redisQueue.buildQueueName()); 42 | System.out.println(redisQueue.buildQueueName()); 43 | System.out.println(redisQueue.buildQueueName()); 44 | System.out.println(redisQueue.buildQueueName()); 45 | } 46 | } 47 | }).start(); 48 | new Thread(new Runnable() { 49 | @Override 50 | public void run() { 51 | for (int i = 0; i < 5; i++) { 52 | System.out.println(redisQueue.buildQueueName()); 53 | System.out.println(redisQueue.buildQueueName()); 54 | System.out.println(redisQueue.buildQueueName()); 55 | System.out.println(redisQueue.buildQueueName()); 56 | System.out.println(redisQueue.buildQueueName()); 57 | System.out.println(redisQueue.buildQueueName()); 58 | System.out.println(redisQueue.buildQueueName()); 59 | System.out.println(redisQueue.buildQueueName()); 60 | } 61 | } 62 | }).start(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-server/src/main/resources/config/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 9 | 10 | 11 | 12 | 15 | %clr(%d{HH:mm:ss.SSS}){faint} %clr([%thread]){faint} %clr(%-5level){magenta}%clr(%-40.40logger{40}){cyan} %L %clr(:){faint}- %msg%n 16 | 17 | 18 | 19 | 20 | 21 | 22 | ${logpath}/mykit-delay-dubbo-%d{yyyy-MM-dd}.log 23 | 30 24 | 25 | 26 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{40} - %msg%n 27 | 28 | 29 | 30 | 31 | ${logpath}/mykit-delay-dubbo-track-%d{yyyy-MM-dd}.log 32 | 30 33 | 34 | 35 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{40} - %msg%n 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /mykit-delay-healthy/src/main/java/io/mykit/delay/healthy/QueueHealthIndicator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.healthy; 17 | 18 | import io.mykit.delay.common.utils.Constants; 19 | import io.mykit.delay.queue.core.Queue; 20 | import io.mykit.delay.queue.leader.LeaderManager; 21 | import io.mykit.delay.queue.leader.ServerNode; 22 | import io.mykit.delay.queue.redis.RedisQueue; 23 | import io.mykit.delay.queue.redis.support.RedisQueueProperties; 24 | import org.springframework.boot.actuate.health.Health; 25 | import org.springframework.boot.actuate.health.HealthIndicator; 26 | 27 | /** 28 | * @author liuyazhuang 29 | * @version 1.0.0 30 | * @date 2019/5/29 31 | * @description 队列健康注册器 32 | */ 33 | public class QueueHealthIndicator implements HealthIndicator { 34 | private Queue queue; 35 | private LeaderManager leaderManager; 36 | private RedisQueueProperties redisQueueProperties; 37 | 38 | public QueueHealthIndicator(RedisQueue queue, LeaderManager leaderManager, RedisQueueProperties 39 | redisQueueProperties) { 40 | this.queue = queue; 41 | this.leaderManager = leaderManager; 42 | this.redisQueueProperties = redisQueueProperties; 43 | } 44 | 45 | @Override 46 | public Health health() { 47 | try { 48 | Health.Builder builder = Health.up(); 49 | if (leaderManager == null) { 50 | builder.withDetail(Constants.RUN, queue.isRunning()); 51 | } else { 52 | builder.withDetail(Constants.RUN, queue.isRunning()).withDetail(Constants.IS_MASTER, leaderManager.isLeader()); 53 | } 54 | return builder 55 | .withDetail(Constants.IS_CLUSTER, redisQueueProperties.isCluster()) 56 | .withDetail(Constants.BUCKET_SIZE, redisQueueProperties.getBucketSize()) 57 | .withDetail(Constants.PREFIX, redisQueueProperties.getPrefix()) 58 | .withDetail(Constants.NAMESPACE, ServerNode.NAMESPACE) 59 | .build(); 60 | } catch (Exception e) { 61 | return Health.down(e).build(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /mykit-delay-config/src/main/java/io/mykit/delay/starter/ready/StartGetReady.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.starter.ready; 17 | 18 | import io.mykit.delay.common.utils.Constants; 19 | import org.springframework.util.ResourceUtils; 20 | 21 | import java.io.File; 22 | import java.io.FileNotFoundException; 23 | 24 | /** 25 | * @author liuyazhuang 26 | * @version 1.0.0 27 | * @date 2019/5/29 28 | * @description 准备启动类 29 | */ 30 | public class StartGetReady { 31 | 32 | private static final String LOG_PATH = MykitDelayFileLoad.getStringValue(MykitDelayFileLoad.LOG_PATH); 33 | private static final String CLASS_PATH = MykitDelayFileLoad.getStringValue(MykitDelayFileLoad.CLASS_PATH); 34 | private static final String DEFAULT_CQ = MykitDelayFileLoad.getStringValue(MykitDelayFileLoad.DEFAULT_CQ); 35 | 36 | public static void ready(String defaultCQKey){ 37 | if (System.getProperty(Constants.SOFT_HOME_KEY) == null) { 38 | System.setProperty(Constants.SOFT_HOME_KEY, getClazzPathUrl()); 39 | } 40 | if (System.getProperty(Constants.SOFT_LOG_HOME_KEY) == null) { 41 | System.setProperty(Constants.SOFT_LOG_HOME_KEY, "".concat(LOG_PATH)); 42 | } 43 | //配置消费队列 44 | if(System.getProperty(defaultCQKey) == null){ 45 | System.setProperty(defaultCQKey, DEFAULT_CQ); 46 | } 47 | } 48 | 49 | public static void ready() { 50 | if (System.getProperty(Constants.SOFT_HOME_KEY) == null) { 51 | System.setProperty(Constants.SOFT_HOME_KEY, getClazzPathUrl()); 52 | } 53 | if (System.getProperty(Constants.SOFT_LOG_HOME_KEY) == null) { 54 | System.setProperty(Constants.SOFT_LOG_HOME_KEY, "".concat(LOG_PATH)); 55 | } 56 | } 57 | 58 | private static String getClazzPathUrl() { 59 | File path = null; 60 | try { 61 | path = new File(ResourceUtils.getURL(CLASS_PATH).getPath()); 62 | } catch (FileNotFoundException e) { 63 | e.printStackTrace(); 64 | } 65 | if (!path.exists()) 66 | path = new File(""); 67 | return path.getAbsolutePath(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/common/conf/RedisConfig.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.conf; 17 | 18 | import org.springframework.context.annotation.Bean; 19 | import org.springframework.context.annotation.Configuration; 20 | import org.springframework.data.redis.connection.RedisConnectionFactory; 21 | import org.springframework.data.redis.core.RedisTemplate; 22 | import org.springframework.data.redis.serializer.RedisSerializer; 23 | import org.springframework.data.redis.serializer.SerializationException; 24 | import org.springframework.data.redis.serializer.StringRedisSerializer; 25 | import org.springframework.util.SerializationUtils; 26 | 27 | /** 28 | * @author liuyazhuang 29 | * @version 1.0.0 30 | * @date 2019/5/29 31 | * @description Redis配置 32 | */ 33 | @Configuration 34 | public class RedisConfig { 35 | 36 | @Bean 37 | public RedisTemplate redisTemplate(RedisConnectionFactory factory) { 38 | final RedisTemplate template = new RedisTemplate(); 39 | template.setConnectionFactory(factory); 40 | template.setKeySerializer(new StringRedisSerializer()); 41 | template.setHashValueSerializer(new RedisSerializer() { 42 | @Override 43 | public byte[] serialize(Object o) throws SerializationException { 44 | return SerializationUtils.serialize(o); 45 | } 46 | 47 | @Override 48 | public Object deserialize(byte[] bytes) throws SerializationException { 49 | return SerializationUtils.deserialize(bytes); 50 | } 51 | }); 52 | //template.setHashValueSerializer( new GenericToStringSerializer< Object >( Object.class ) ); 53 | template.setValueSerializer(new RedisSerializer() { 54 | @Override 55 | public byte[] serialize(Object o) throws SerializationException { 56 | return SerializationUtils.serialize(o); 57 | } 58 | 59 | @Override 60 | public Object deserialize(byte[] bytes) throws SerializationException { 61 | return SerializationUtils.deserialize(bytes); 62 | } 63 | }); 64 | return template; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /mykit-delay-healthy/src/main/java/io/mykit/delay/healthy/HealthAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.healthy; 17 | 18 | import io.mykit.delay.common.conf.AppEnvContext; 19 | import io.mykit.delay.common.utils.Constants; 20 | import io.mykit.delay.queue.leader.LeaderManager; 21 | import io.mykit.delay.queue.leader.SimpleLeaderManager; 22 | import io.mykit.delay.queue.redis.RedisQueue; 23 | import io.mykit.delay.queue.redis.support.RedisQueueProperties; 24 | import org.springframework.beans.factory.annotation.Autowired; 25 | import org.springframework.boot.actuate.health.CompositeHealthIndicator; 26 | import org.springframework.boot.actuate.health.HealthAggregator; 27 | import org.springframework.boot.actuate.health.HealthIndicator; 28 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 29 | import org.springframework.context.annotation.Bean; 30 | import org.springframework.context.annotation.Configuration; 31 | import org.springframework.core.Ordered; 32 | import org.springframework.core.annotation.Order; 33 | 34 | import java.util.Map; 35 | 36 | /** 37 | * @author liuyazhuang 38 | * @version 1.0.0 39 | * @date 2019/5/29 40 | * @description 健康检查自动配置 41 | */ 42 | @Configuration 43 | @Order(Ordered.LOWEST_PRECEDENCE + 1000) 44 | public class HealthAutoConfiguration { 45 | @Autowired 46 | private HealthAggregator healthAggregator; 47 | 48 | 49 | @Bean 50 | @Autowired(required = false) 51 | @ConditionalOnMissingBean 52 | public HealthIndicator jikexiuHealthIndicator(RedisQueue redisQueue, RedisQueueProperties properties) { 53 | CompositeHealthIndicator compositeHealthIndicator = new CompositeHealthIndicator(healthAggregator); 54 | Map leaderManagerMap = AppEnvContext.getCtx().getBeansOfType(LeaderManager.class); 55 | LeaderManager manager = null; 56 | if (leaderManagerMap != null && !leaderManagerMap.isEmpty()) { 57 | manager = AppEnvContext.getCtx().getBean(SimpleLeaderManager.class); 58 | } 59 | 60 | compositeHealthIndicator.addHealthIndicator(Constants.HEALTH_INDICATOR_NAME, new QueueHealthIndicator(redisQueue, manager, properties)); 61 | return compositeHealthIndicator; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/common/autoconfigigure/RegistryProperties.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.autoconfigigure; 17 | 18 | import org.springframework.boot.context.properties.ConfigurationProperties; 19 | 20 | import java.util.Objects; 21 | /** 22 | * @author liuyazhuang 23 | * @version 1.0.0 24 | * @date 2019/5/29 25 | * @description 注册属性信息 26 | */ 27 | @ConfigurationProperties(prefix = RegistryProperties.MYKIT_DELAY_REGISTRY_PREFIX) 28 | public class RegistryProperties { 29 | public static final String MYKIT_DELAY_REGISTRY_PREFIX = "mykit.delay.registry"; 30 | 31 | 32 | private String enable = Objects.toString(Boolean.FALSE); 33 | private String serverList; 34 | 35 | private int maxRetries = 100; 36 | 37 | private int maxSleepTimeMilliseconds; 38 | 39 | private int baseSleepTimeMilliseconds; 40 | 41 | private String namespace = "io-mykit-delay"; 42 | 43 | public String getServerList() { 44 | return serverList; 45 | } 46 | 47 | public void setServerList(String serverList) { 48 | this.serverList = serverList; 49 | } 50 | 51 | public int getMaxRetries() { 52 | return maxRetries; 53 | } 54 | 55 | public void setMaxRetries(int maxRetries) { 56 | this.maxRetries = maxRetries; 57 | } 58 | 59 | public int getMaxSleepTimeMilliseconds() { 60 | return maxSleepTimeMilliseconds; 61 | } 62 | 63 | public void setMaxSleepTimeMilliseconds(int maxSleepTimeMilliseconds) { 64 | this.maxSleepTimeMilliseconds = maxSleepTimeMilliseconds; 65 | } 66 | 67 | public int getBaseSleepTimeMilliseconds() { 68 | return baseSleepTimeMilliseconds; 69 | } 70 | 71 | public void setBaseSleepTimeMilliseconds(int baseSleepTimeMilliseconds) { 72 | this.baseSleepTimeMilliseconds = baseSleepTimeMilliseconds; 73 | } 74 | 75 | public String getEnable() { 76 | return enable; 77 | } 78 | 79 | public void setEnable(String enable) { 80 | this.enable = enable; 81 | } 82 | 83 | public String getNamespace() { 84 | return namespace; 85 | } 86 | 87 | public void setNamespace(String namespace) { 88 | this.namespace = namespace; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/common/conf/AppEnvContext.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.conf; 17 | 18 | import org.springframework.beans.BeansException; 19 | import org.springframework.boot.bind.RelaxedPropertyResolver; 20 | import org.springframework.context.ApplicationContext; 21 | import org.springframework.context.ApplicationContextAware; 22 | import org.springframework.context.EnvironmentAware; 23 | import org.springframework.context.annotation.Configuration; 24 | import org.springframework.core.Ordered; 25 | import org.springframework.core.annotation.Order; 26 | import org.springframework.core.env.Environment; 27 | import org.springframework.util.StringUtils; 28 | 29 | /** 30 | * @author liuyazhuang 31 | * @version 1.0.0 32 | * @date 2019/5/29 33 | * @description 程序运行环境上下文 34 | */ 35 | @Configuration 36 | @Order(Ordered.HIGHEST_PRECEDENCE - 50) 37 | public class AppEnvContext implements EnvironmentAware, ApplicationContextAware { 38 | 39 | private static Environment env; 40 | private static ApplicationContext ctx; 41 | 42 | public static String getProperty(String key) { 43 | 44 | return env.getProperty(key); 45 | } 46 | 47 | public static String getProperty(String key, String defaultValue) { 48 | 49 | String v = getProperty(key); 50 | return StringUtils.isEmpty(v) ? defaultValue : v; 51 | } 52 | 53 | /** 54 | * 55 | * getRelaxedPropertyResolver( "spring.datasource.").getProperty("url"); 56 | *

57 | * 58 | */ 59 | public static RelaxedPropertyResolver getRelaxedPropertyResolver(String prefix) { 60 | 61 | RelaxedPropertyResolver propertyResolver = new RelaxedPropertyResolver(env, prefix); 62 | return propertyResolver; 63 | } 64 | 65 | public static Environment getEnv() { 66 | return env; 67 | } 68 | 69 | public static ApplicationContext getCtx() { 70 | return ctx; 71 | } 72 | 73 | protected void finalize() throws Throwable { 74 | super.finalize(); 75 | env = null; 76 | } 77 | 78 | @Override 79 | public void setEnvironment(Environment environment) { 80 | env = environment; 81 | } 82 | 83 | @Override 84 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 85 | ctx = applicationContext; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /mykit-delay-test/src/main/java/io/mykit/delay/test/DistributedLockTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.test; 17 | 18 | import io.mykit.delay.queue.redis.support.DistributedLock; 19 | import io.mykit.delay.queue.redis.support.RedisDistributedLock; 20 | import io.mykit.delay.queue.redis.support.RedisSupport; 21 | import org.junit.Test; 22 | import org.junit.runner.RunWith; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.boot.test.context.SpringBootTest; 27 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 28 | import org.springframework.test.context.junit4.SpringRunner; 29 | import org.springframework.test.context.web.WebAppConfiguration; 30 | 31 | import java.util.concurrent.ExecutorService; 32 | import java.util.concurrent.Executors; 33 | 34 | /** 35 | * @author liuyazhuang 36 | * @version 1.0.0 37 | * @date 2019/5/30 38 | * @description 测试分布式锁 39 | */ 40 | @RunWith(SpringRunner.class) 41 | @SpringBootTest 42 | public class DistributedLockTest { 43 | 44 | public static final Logger LOGGER = LoggerFactory.getLogger(DistributedLockTest.class); 45 | @Autowired 46 | private RedisSupport redisSupport; 47 | 48 | @Test 49 | public void test1() { 50 | final DistributedLock lock = new RedisDistributedLock(redisSupport); 51 | ExecutorService executorService = Executors.newFixedThreadPool(5); 52 | for (int i = 0; i < 20; i++) { 53 | final int index = i; 54 | executorService.execute(new Runnable() { 55 | @Override 56 | public void run() { 57 | try { 58 | if (index >= 10) { 59 | lock.lock("test002"); 60 | } else { 61 | lock.lock("test001"); 62 | } 63 | 64 | LOGGER.info("我得到锁了 {} ", index); 65 | Thread.sleep(500); 66 | } catch (InterruptedException e) { 67 | e.printStackTrace(); 68 | } finally { 69 | if (index >= 10) { 70 | lock.unlock("test002"); 71 | } else { 72 | lock.unlock("test001"); 73 | } 74 | } 75 | } 76 | }); 77 | 78 | } 79 | try { 80 | Thread.sleep(1000000L); 81 | } catch (InterruptedException e) { 82 | e.printStackTrace(); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/JobMsg.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue; 17 | 18 | import java.io.Serializable; 19 | 20 | import com.alibaba.fastjson.JSONObject; 21 | import io.mykit.delay.common.utils.Status; 22 | import io.mykit.delay.queue.core.Job; 23 | 24 | /** 25 | * @author liuyazhuang 26 | * @version 1.0.0 27 | * @date 2019/5/29 28 | * @description Job消息 29 | */ 30 | public class JobMsg implements Serializable, Job { 31 | private static final long serialVersionUID = 8994262570014046230L; 32 | private String topic; 33 | private String subtopic; 34 | /** 35 | * 预留字段 36 | **/ 37 | private String id; 38 | private String bizKey; 39 | private long delay; 40 | private long ttl; 41 | /***预留字段**/ 42 | private String body; 43 | private long createTime = System.currentTimeMillis(); 44 | private int status = Status.WaitPut.ordinal(); 45 | 46 | public String getBizKey() { 47 | return bizKey; 48 | } 49 | 50 | public void setBizKey(String bizKey) { 51 | this.bizKey = bizKey; 52 | } 53 | 54 | public String getTopic() { 55 | 56 | return topic; 57 | } 58 | 59 | public void setTopic(String topic) { 60 | this.topic = topic; 61 | } 62 | 63 | public String getId() { 64 | return id; 65 | } 66 | 67 | public void setId(String id) { 68 | this.id = id; 69 | } 70 | 71 | public long getDelay() { 72 | return delay; 73 | } 74 | 75 | public void setDelay(long delay) { 76 | this.delay = delay; 77 | } 78 | 79 | public long getTtl() { 80 | return ttl; 81 | } 82 | 83 | public void setTtl(long ttl) { 84 | this.ttl = ttl; 85 | } 86 | 87 | public String getBody() { 88 | return body; 89 | } 90 | 91 | public void setBody(String body) { 92 | this.body = body; 93 | } 94 | 95 | public long getCreateTime() { 96 | return createTime; 97 | } 98 | 99 | public void setCreateTime(long createTime) { 100 | this.createTime = createTime; 101 | } 102 | 103 | public int getStatus() { 104 | return status; 105 | } 106 | 107 | public void setStatus(int status) { 108 | this.status = status; 109 | } 110 | 111 | public String getSubtopic() { 112 | return subtopic; 113 | } 114 | 115 | public void setSubtopic(String subtopic) { 116 | this.subtopic = subtopic; 117 | } 118 | 119 | @Override 120 | public String toJsonString() { 121 | return JSONObject.toJSONString(this); 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /mykit-delay-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-delay 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-delay-core 13 | 14 | 15 | 16 | io.mykit.delay 17 | mykit-delay-controller 18 | 1.0-SNAPSHOT 19 | 20 | 21 | 22 | 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-maven-plugin 27 | 28 | 29 | 30 | 31 | org.apache.maven.plugins 32 | maven-jar-plugin 33 | 2.6 34 | 35 | 36 | 37 | true 38 | lib/ 39 | io.mykit.delay.MykitDelayCoreApplication 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.apache.maven.plugins 48 | maven-dependency-plugin 49 | 2.10 50 | 51 | 52 | copy-dependencies 53 | package 54 | 55 | copy-dependencies 56 | 57 | 58 | ${project.build.directory}/lib 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | org.apache.maven.plugins 67 | maven-surefire-plugin 68 | 2.17 69 | 70 | true 71 | 72 | 73 | 74 | 75 | 76 | 77 | src/main/resources 78 | ${project.build.directory}/classes 79 | 80 | **/* 81 | 82 | true 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/common/autoconfigigure/ha/LeaderAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.autoconfigigure.ha; 17 | 18 | import io.mykit.delay.common.autoconfigigure.RegistryProperties; 19 | import io.mykit.delay.common.conf.AppEnvContext; 20 | import io.mykit.delay.common.utils.IpUtils; 21 | import io.mykit.delay.queue.leader.LeaderManager; 22 | import io.mykit.delay.queue.leader.LeaderWorkListener; 23 | import io.mykit.delay.queue.leader.ServerNode; 24 | import io.mykit.delay.queue.leader.SimpleLeaderManager; 25 | import io.mykit.delay.queue.redis.RedisQueue; 26 | import org.apache.curator.framework.CuratorFrameworkFactory; 27 | import org.apache.curator.framework.recipes.leader.LeaderLatchListener; 28 | import org.apache.zookeeper.server.ZooKeeperServer; 29 | import org.springframework.beans.factory.annotation.Autowired; 30 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 31 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 32 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 33 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 34 | import org.springframework.context.annotation.Bean; 35 | import org.springframework.context.annotation.Configuration; 36 | import org.springframework.core.Ordered; 37 | import org.springframework.core.annotation.Order; 38 | 39 | /** 40 | * @author liuyazhuang 41 | * @version 1.0.0 42 | * @date 2019/5/29 43 | * @description Leader配置 44 | */ 45 | @Configuration 46 | @EnableConfigurationProperties(RegistryProperties.class) 47 | @ConditionalOnProperty(prefix = RegistryProperties.MYKIT_DELAY_REGISTRY_PREFIX, value = "enable", havingValue = "true") 48 | @ConditionalOnClass(value = {ZooKeeperServer.class, CuratorFrameworkFactory.class}) 49 | @Order(Ordered.LOWEST_PRECEDENCE + 50) 50 | public class LeaderAutoConfiguration { 51 | 52 | @Autowired 53 | private RegistryProperties registryProperties; 54 | 55 | 56 | @Bean 57 | @Autowired 58 | @ConditionalOnMissingBean 59 | public LeaderLatchListener leaderLatchListenerImpl(RedisQueue redisQueue) { 60 | LeaderWorkListener listener = new LeaderWorkListener(); 61 | listener.setQueue(redisQueue); 62 | return listener; 63 | } 64 | 65 | @Bean(name = "simpleLeaderManager", initMethod = "init", destroyMethod = "stop") 66 | @Autowired 67 | @ConditionalOnMissingBean 68 | public LeaderManager leaderManager(LeaderLatchListener leaderLatchListener) { 69 | SimpleLeaderManager slm = new SimpleLeaderManager(); 70 | slm.setProperties(registryProperties); 71 | slm.addListener(leaderLatchListener); 72 | ServerNode.NAMESPACE = registryProperties.getNamespace(); 73 | slm.setServerName(IpUtils.getIp() + ":" + AppEnvContext.getProperty("server.port")); 74 | return slm; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /mykit-delay-common/src/main/java/io/mykit/delay/common/utils/JobIdGenerator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.utils; 17 | 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | import org.springframework.util.StringUtils; 21 | 22 | /** 23 | * @author liuyazhuang 24 | * @version 1.0.0 25 | * @date 2019/5/29 26 | * @description Job ID 生成器 27 | *

28 |  *      -DmachineId=num 机器标识
29 |  *  
30 | */ 31 | public class JobIdGenerator { 32 | public static final Logger LOGGER = LoggerFactory.getLogger(JobIdGenerator.class); 33 | public static final int DATACENTER = 2; 34 | public static final int DEFAULT_MACHINED = 1; 35 | public static final String MACHINE_ID = "machineId"; 36 | private static SnowFlake snowFlake = null; 37 | 38 | static { 39 | int m = machinedId(); 40 | LOGGER.info(" machined {}", m); 41 | snowFlake = new SnowFlake(DATACENTER, m); 42 | } 43 | 44 | private static int machinedId() { 45 | //通过获取IP地址最后一位来获取 46 | String MACHINED = System.getProperty(MACHINE_ID); 47 | if (!StringUtils.isEmpty(MACHINED)) { 48 | try { 49 | return Integer.parseInt(MACHINED); 50 | } catch (Exception e) { 51 | return DEFAULT_MACHINED; 52 | } 53 | } 54 | return DEFAULT_MACHINED; 55 | } 56 | 57 | public static long getLongId() { 58 | return snowFlake.nextId(); 59 | } 60 | 61 | public static String getStringId() { 62 | return String.valueOf(snowFlake.nextId()); 63 | } 64 | 65 | // public static void main(String[] args) { 66 | // final Map c= Maps.newHashMap(); 67 | // final Map c1=Maps.newHashMap(); 68 | // final AtomicLong atomicLong=new AtomicLong(0); 69 | // for(int i=0;i<20;i++){ 70 | // new Thread(new Runnable() { 71 | // @Override 72 | // public void run() { 73 | // for(int i=0;i<5000;i++){ 74 | // String k=getStringId(); 75 | // atomicLong.incrementAndGet(); 76 | // System.out.println(k+"=="+c.containsKey(k)+"--"+atomicLong.get()); 77 | // if(!c.containsKey(k)){ 78 | // c.put(k,i); 79 | // }else{ 80 | // throw new RuntimeException(String.format("id %s重复了",k)); 81 | // } 82 | // 83 | // 84 | // } 85 | // c1.put(Thread.currentThread().getName(),""); 86 | // } 87 | // }).start(); 88 | // } 89 | // while(c1.size()>=20){ 90 | // System.out.println(c.size()); 91 | // } 92 | // try { 93 | // Thread.sleep(5000000L); 94 | // } catch (InterruptedException e) { 95 | // e.printStackTrace(); 96 | // } 97 | // } 98 | } 99 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/redis/support/RedisQueueProperties.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.redis.support; 17 | import org.springframework.boot.context.properties.ConfigurationProperties; 18 | /** 19 | * @author liuyazhuang 20 | * @version 1.0.0 21 | * @date 2019/5/30 22 | * @description Redis队列配置属性 23 | */ 24 | @ConfigurationProperties(prefix = RedisQueueProperties.REDIS_QUEUE_PREFIX) 25 | public class RedisQueueProperties { 26 | public static final String REDIS_QUEUE_PREFIX = "mykit.delay.rqueue"; 27 | private String name; 28 | private String prefix = "io.mykit.delay"; 29 | private String originPool = "pools"; 30 | private String readyName = "ready"; 31 | private int bucketSize = 3; 32 | 33 | /** 34 | * buck轮询时间 35 | **/ 36 | private long buckRoundRobinTime = 300; 37 | /** 38 | * ready轮询时间 39 | **/ 40 | private long readyRoundRobinTime = 200; 41 | private boolean cluster = false; 42 | 43 | public String getName() { 44 | return name; 45 | } 46 | 47 | public void setName(String name) { 48 | this.name = name; 49 | } 50 | 51 | public String getPrefix() { 52 | return prefix; 53 | } 54 | 55 | public void setPrefix(String prefix) { 56 | this.prefix = prefix; 57 | } 58 | 59 | public String getOriginPool() { 60 | return originPool; 61 | } 62 | 63 | public void setOriginPool(String originPool) { 64 | this.originPool = originPool; 65 | } 66 | 67 | public String getReadyName() { 68 | return readyName; 69 | } 70 | 71 | public void setReadyName(String readyName) { 72 | this.readyName = readyName; 73 | } 74 | 75 | public int getBucketSize() { 76 | return bucketSize; 77 | } 78 | 79 | public void setBucketSize(int bucketSize) { 80 | this.bucketSize = bucketSize; 81 | } 82 | 83 | public boolean isCluster() { 84 | return cluster; 85 | } 86 | 87 | public void setCluster(boolean cluster) { 88 | this.cluster = cluster; 89 | } 90 | 91 | public long getBuckRoundRobinTime() { 92 | if (buckRoundRobinTime <= 0) { 93 | buckRoundRobinTime = 500; 94 | } 95 | return buckRoundRobinTime; 96 | } 97 | 98 | public void setBuckRoundRobinTime(long buckRoundRobinTime) { 99 | this.buckRoundRobinTime = buckRoundRobinTime; 100 | } 101 | 102 | public long getReadyRoundRobinTime() { 103 | if (readyRoundRobinTime <= 0) { 104 | readyRoundRobinTime = 500; 105 | } 106 | return readyRoundRobinTime; 107 | } 108 | 109 | public void setReadyRoundRobinTime(long readyRoundRobinTime) { 110 | this.readyRoundRobinTime = readyRoundRobinTime; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/redis/support/RedisDistributedLock.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.redis.support; 17 | import io.mykit.delay.common.utils.BlockUtils; 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | 21 | /** 22 | * @author liuyazhuang 23 | * @version 1.0.0 24 | * @date 2019/5/30 25 | * @description 基于Redis实现的分布式锁 26 | */ 27 | public class RedisDistributedLock implements DistributedLock { 28 | 29 | public static final Logger LOGGER = LoggerFactory.getLogger(RedisDistributedLock.class); 30 | private static final long DEFAULT_LOCK_TIMEOUT = 1000 * 60 * 3; 31 | private RedisSupport redisSupport; 32 | 33 | public RedisDistributedLock() { 34 | 35 | } 36 | 37 | public RedisDistributedLock(RedisSupport redisSupport) { 38 | this.redisSupport = redisSupport; 39 | } 40 | 41 | public static boolean isEmpty(Object str) { 42 | return (str == null || "".equals(str)); 43 | } 44 | 45 | @Override 46 | public boolean tryLock(String key) { 47 | throw new RuntimeException("待实现"); 48 | } 49 | 50 | private boolean interLock(String key) { 51 | //得到锁后设置的过期时间,未得到锁返回0 52 | while (true) { 53 | long expireTime = getCuurentMillis() + DEFAULT_LOCK_TIMEOUT + 1; 54 | if (redisSupport.setNx(key, String.valueOf(expireTime))) { 55 | redisSupport.pExpire(key, DEFAULT_LOCK_TIMEOUT); 56 | return true; 57 | } else { 58 | String curLockTimeStr = redisSupport.get(key); 59 | if (!isEmpty(curLockTimeStr) && getCuurentMillis() > Long.valueOf(curLockTimeStr)) { 60 | String setAftercurLockTimeStr = redisSupport.getSet(key, String.valueOf(expireTime)); 61 | //仍然过期,则得到锁 62 | if (setAftercurLockTimeStr != null && setAftercurLockTimeStr.equals(curLockTimeStr)) { 63 | redisSupport.pExpire(key, DEFAULT_LOCK_TIMEOUT); 64 | return true; 65 | } 66 | } 67 | } 68 | BlockUtils.sleep(10); 69 | if (LOGGER.isDebugEnabled()) { 70 | LOGGER.debug("没有获取锁 {} 正在等待...", key); 71 | } 72 | } 73 | } 74 | 75 | private long getCuurentMillis() { 76 | return System.currentTimeMillis(); 77 | } 78 | 79 | @Override 80 | public boolean tryLock(String key, long timeout) { 81 | throw new RuntimeException("待实现"); 82 | } 83 | 84 | @Override 85 | public boolean lock(String key) { 86 | return interLock(key); 87 | } 88 | 89 | @Override 90 | public void unlock(String key) { 91 | if (!isEmpty(key)) { 92 | redisSupport.deleteKey(key); 93 | } 94 | } 95 | 96 | public void setRedisSupport(RedisSupport redisSupport) { 97 | this.redisSupport = redisSupport; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /mykit-delay-rpc/mykit-rpc-dubbo/mykit-rpc-dubbo-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mykit-rpc-dubbo 7 | io.mykit.delay 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | mykit-rpc-dubbo-server 13 | 14 | 15 | 16 | org.apache.dubbo 17 | dubbo-spring-boot-starter 18 | ${dubbo.version} 19 | 20 | 21 | org.slf4j 22 | slf4j-log4j12 23 | 24 | 25 | 26 | 27 | io.mykit.delay 28 | mykit-rpc-dubbo-common 29 | 1.0-SNAPSHOT 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-maven-plugin 38 | 39 | 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-jar-plugin 44 | 2.6 45 | 46 | 47 | 48 | true 49 | lib/ 50 | io.mykit.delay.MykitDelayServer 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | org.apache.maven.plugins 59 | maven-dependency-plugin 60 | 2.10 61 | 62 | 63 | copy-dependencies 64 | package 65 | 66 | copy-dependencies 67 | 68 | 69 | ${project.build.directory}/lib 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | org.apache.maven.plugins 78 | maven-surefire-plugin 79 | 2.17 80 | 81 | true 82 | 83 | 84 | 85 | 86 | 87 | 88 | src/main/resources 89 | ${project.build.directory}/classes 90 | 91 | **/* 92 | 93 | true 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /mykit-delay-common/src/main/java/io/mykit/delay/common/utils/SnowFlake.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.utils; 17 | 18 | /** 19 | * @author liuyazhuang 20 | * @version 1.0.0 21 | * @date 2019/5/29 22 | * @description 雪花算法生成分布式序列号 23 | */ 24 | public class SnowFlake { 25 | /** 26 | * 起始的时间戳 27 | */ 28 | private final static long START_STMP = 1505699432705L; 29 | 30 | /** 31 | * 每一部分占用的位数 32 | */ 33 | private final static long SEQUENCE_BIT = 12; //序列号占用的位数 34 | private final static long MACHINE_BIT = 5; //机器标识占用的位数 35 | private final static long DATACENTER_BIT = 5;//数据中心占用的位数 36 | 37 | /** 38 | * 每一部分的最大值 39 | */ 40 | private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT); 41 | private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT); 42 | private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT); 43 | 44 | /** 45 | * 每一部分向左的位移 46 | */ 47 | private final static long MACHINE_LEFT = SEQUENCE_BIT; 48 | private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT; 49 | private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT; 50 | 51 | private long datacenterId; //数据中心 52 | private long machineId; //机器标识 53 | private long sequence = 0L; //序列号 54 | private long lastStmp = -1L;//上一次时间戳 55 | 56 | public SnowFlake(long datacenterId, long machineId) { 57 | if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) { 58 | throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0"); 59 | } 60 | if (machineId > MAX_MACHINE_NUM || machineId < 0) { 61 | throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0"); 62 | } 63 | this.datacenterId = datacenterId; 64 | this.machineId = machineId; 65 | } 66 | 67 | /** 68 | * 产生下一个ID 69 | */ 70 | public synchronized long nextId() { 71 | long currStmp = getNewstmp(); 72 | if (currStmp < lastStmp) { 73 | throw new RuntimeException("Clock moved backwards. Refusing to generate id"); 74 | } 75 | 76 | if (currStmp == lastStmp) { 77 | //相同毫秒内,序列号自增 78 | sequence = (sequence + 1) & MAX_SEQUENCE; 79 | //同一毫秒的序列数已经达到最大 80 | if (sequence == 0L) { 81 | currStmp = getNextMill(); 82 | } 83 | } else { 84 | //不同毫秒内,序列号置为0 85 | sequence = 0L; 86 | } 87 | 88 | lastStmp = currStmp; 89 | 90 | return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分 91 | | datacenterId << DATACENTER_LEFT //数据中心部分 92 | | machineId << MACHINE_LEFT //机器标识部分 93 | | sequence; //序列号部分 94 | } 95 | 96 | private long getNextMill() { 97 | long mill = getNewstmp(); 98 | while (mill <= lastStmp) { 99 | mill = getNewstmp(); 100 | } 101 | return mill; 102 | } 103 | 104 | private long getNewstmp() { 105 | return System.currentTimeMillis(); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/redis/ready/ReadyQueueManager.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.redis.ready; 17 | import io.mykit.delay.queue.core.ConsumeQueueProvider; 18 | import io.mykit.delay.queue.core.Queue; 19 | import io.mykit.delay.queue.extension.ExtensionLoader; 20 | import io.mykit.delay.queue.redis.JobOperationService; 21 | import io.mykit.delay.queue.redis.support.DistributedLock; 22 | import io.mykit.delay.queue.redis.support.Lifecycle; 23 | import io.mykit.delay.queue.redis.support.RedisQueueProperties; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | import java.util.Timer; 28 | import java.util.concurrent.atomic.AtomicBoolean; 29 | 30 | /** 31 | * @author liuyazhuang 32 | * @version 1.0.0 33 | * @date 2019/5/30 34 | * @description Redis队列管理器 35 | */ 36 | public class ReadyQueueManager implements Lifecycle { 37 | 38 | public static final Logger LOGGER = LoggerFactory.getLogger(ReadyQueueManager.class); 39 | public static final String THREAD_NAME = "mykit-ready-queue-%s"; 40 | public boolean daemon = true; 41 | private volatile AtomicBoolean isRuning = new AtomicBoolean(false); 42 | private RedisQueueProperties properties; 43 | private Timer timer; 44 | private JobOperationService jobOperationService; 45 | private Queue delayQueue; 46 | private String threadName; 47 | private DistributedLock lock = null; 48 | 49 | 50 | @Override 51 | public void start() { 52 | if (isRuning.compareAndSet(false, true)) { 53 | threadName = String.format(THREAD_NAME, 1); 54 | timer = new Timer(threadName, daemon); 55 | RealTimeTask task = new RealTimeTask(); 56 | task.setProperties(properties); 57 | task.setJobOperationService(jobOperationService); 58 | task.setDelayQueue(delayQueue); 59 | task.setLock(lock); 60 | task.setConsumeQueueProvider(ExtensionLoader.getExtension(ConsumeQueueProvider.class)); 61 | timer.schedule(task, 500, properties.getReadyRoundRobinTime()); 62 | LOGGER.info(String.format("Starting Ready Thead %s ....", threadName)); 63 | } 64 | } 65 | 66 | @Override 67 | public void stop() { 68 | if (isRuning.compareAndSet(true, false)) { 69 | if (timer != null) { 70 | timer.cancel(); 71 | LOGGER.info(String.format("stoping timer %s .....", threadName)); 72 | } 73 | } 74 | } 75 | 76 | @Override 77 | public boolean isRunning() { 78 | return isRuning.get(); 79 | } 80 | 81 | public void setProperties(RedisQueueProperties properties) { 82 | this.properties = properties; 83 | } 84 | 85 | public void setDaemon(boolean daemon) { 86 | this.daemon = daemon; 87 | } 88 | 89 | public void setDelayQueue(Queue delayQueue) { 90 | this.delayQueue = delayQueue; 91 | } 92 | 93 | public void setJobOperationService(JobOperationService jobOperationService) { 94 | this.jobOperationService = jobOperationService; 95 | } 96 | 97 | public void setLock(DistributedLock lock) { 98 | this.lock = lock; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /mykit-delay-common/src/main/java/io/mykit/delay/common/utils/IpUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.utils; 17 | 18 | import java.net.InetAddress; 19 | import java.net.NetworkInterface; 20 | import java.net.SocketException; 21 | import java.net.UnknownHostException; 22 | import java.util.Enumeration; 23 | 24 | /** 25 | * @author liuyazhuang 26 | * @version 1.0.0 27 | * @date 2019/5/29 28 | * @description IP工具类 29 | */ 30 | public final class IpUtils { 31 | /** 32 | * IP地址的正则表达式. 33 | */ 34 | public static final String IP_REGEX = "((\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\." + 35 | "(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})"; 36 | 37 | private static volatile String cachedIpAddress; 38 | 39 | /** 40 | * 获取本机IP地址. 41 | * 42 | *

43 | * 有限获取外网IP地址. 44 | * 也有可能是链接着路由器的最终IP地址. 45 | *

46 | * 47 | * @return 本机IP地址 48 | */ 49 | public static String getIp() { 50 | if (null != cachedIpAddress) { 51 | return cachedIpAddress; 52 | } 53 | Enumeration netInterfaces; 54 | try { 55 | netInterfaces = NetworkInterface.getNetworkInterfaces(); 56 | } catch (final SocketException ex) { 57 | throw new RuntimeException(ex); 58 | } 59 | String localIpAddress = null; 60 | OUTW: 61 | while (netInterfaces.hasMoreElements()) { 62 | NetworkInterface netInterface = netInterfaces.nextElement(); 63 | Enumeration ipAddresses = netInterface.getInetAddresses(); 64 | while (ipAddresses.hasMoreElements()) { 65 | InetAddress ipAddress = ipAddresses.nextElement(); 66 | if (isPublicIpAddress(ipAddress)) { 67 | String publicIpAddress = ipAddress.getHostAddress(); 68 | cachedIpAddress = publicIpAddress; 69 | return publicIpAddress; 70 | } 71 | if (isLocalIpAddress(ipAddress)) { 72 | localIpAddress = ipAddress.getHostAddress(); 73 | break OUTW; 74 | } 75 | } 76 | } 77 | cachedIpAddress = localIpAddress; 78 | return localIpAddress; 79 | } 80 | 81 | private static boolean isPublicIpAddress(final InetAddress ipAddress) { 82 | return !ipAddress.isSiteLocalAddress() && !ipAddress.isLoopbackAddress() && !isV6IpAddress(ipAddress); 83 | } 84 | 85 | private static boolean isLocalIpAddress(final InetAddress ipAddress) { 86 | return ipAddress.isSiteLocalAddress() && !ipAddress.isLoopbackAddress() && !isV6IpAddress(ipAddress); 87 | } 88 | 89 | private static boolean isV6IpAddress(final InetAddress ipAddress) { 90 | return ipAddress.getHostAddress().contains(":"); 91 | } 92 | 93 | /** 94 | * 获取本机Host名称. 95 | * 96 | * @return 本机Host名称 97 | */ 98 | public static String getHostName() { 99 | try { 100 | return InetAddress.getLocalHost().getHostName(); 101 | } catch (final UnknownHostException ex) { 102 | throw new RuntimeException(ex); 103 | } 104 | } 105 | 106 | public static String getHostAndIp() { 107 | String name = ""; 108 | try { 109 | name = getIp(); 110 | } catch (Exception e) { 111 | // 112 | } 113 | try { 114 | name = name.concat("/").concat(getHostName()); 115 | } catch (Exception e) { 116 | // 117 | } 118 | return name; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/common/autoconfigigure/message/activemq/ActiveMQProperties.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.autoconfigigure.message.activemq; 17 | 18 | import org.springframework.boot.context.properties.ConfigurationProperties; 19 | 20 | /** 21 | * @author liuyazhuang 22 | * @version 1.0.0 23 | * @date 2019/6/11 24 | * @description ActiveMQ的配置类 25 | */ 26 | @ConfigurationProperties(prefix = ActiveMQProperties.MYKIT_DELAY_ACTIVEMQ_PREFIX) 27 | public class ActiveMQProperties { 28 | 29 | public static final String MYKIT_DELAY_ACTIVEMQ_PREFIX = "mykit.delay.activemq"; 30 | 31 | private String brokerUrl; 32 | private String username; 33 | private String password; 34 | private boolean useExponentialBackOff; 35 | private boolean useAsyncSend; 36 | private int maximumRedeliveries; 37 | private int initialRedeliveryDelay; 38 | private int backOffMultiplier; 39 | private int maximumRedeliveryDelay; 40 | private boolean queue_pub_sub_domain; 41 | private boolean topic_pub_sub_domain; 42 | 43 | public String getBrokerUrl() { 44 | return brokerUrl; 45 | } 46 | 47 | public void setBrokerUrl(String brokerUrl) { 48 | this.brokerUrl = brokerUrl; 49 | } 50 | 51 | public String getUsername() { 52 | return username; 53 | } 54 | 55 | public void setUsername(String username) { 56 | this.username = username; 57 | } 58 | 59 | public String getPassword() { 60 | return password; 61 | } 62 | 63 | public void setPassword(String password) { 64 | this.password = password; 65 | } 66 | 67 | public boolean isUseExponentialBackOff() { 68 | return useExponentialBackOff; 69 | } 70 | 71 | public void setUseExponentialBackOff(boolean useExponentialBackOff) { 72 | this.useExponentialBackOff = useExponentialBackOff; 73 | } 74 | 75 | public boolean isUseAsyncSend() { 76 | return useAsyncSend; 77 | } 78 | 79 | public void setUseAsyncSend(boolean useAsyncSend) { 80 | this.useAsyncSend = useAsyncSend; 81 | } 82 | 83 | public int getMaximumRedeliveries() { 84 | return maximumRedeliveries; 85 | } 86 | 87 | public void setMaximumRedeliveries(int maximumRedeliveries) { 88 | this.maximumRedeliveries = maximumRedeliveries; 89 | } 90 | 91 | public int getInitialRedeliveryDelay() { 92 | return initialRedeliveryDelay; 93 | } 94 | 95 | public void setInitialRedeliveryDelay(int initialRedeliveryDelay) { 96 | this.initialRedeliveryDelay = initialRedeliveryDelay; 97 | } 98 | 99 | public int getBackOffMultiplier() { 100 | return backOffMultiplier; 101 | } 102 | 103 | public void setBackOffMultiplier(int backOffMultiplier) { 104 | this.backOffMultiplier = backOffMultiplier; 105 | } 106 | 107 | public int getMaximumRedeliveryDelay() { 108 | return maximumRedeliveryDelay; 109 | } 110 | 111 | public void setMaximumRedeliveryDelay(int maximumRedeliveryDelay) { 112 | this.maximumRedeliveryDelay = maximumRedeliveryDelay; 113 | } 114 | 115 | public boolean isQueue_pub_sub_domain() { 116 | return queue_pub_sub_domain; 117 | } 118 | 119 | public void setQueue_pub_sub_domain(boolean queue_pub_sub_domain) { 120 | this.queue_pub_sub_domain = queue_pub_sub_domain; 121 | } 122 | 123 | public boolean isTopic_pub_sub_domain() { 124 | return topic_pub_sub_domain; 125 | } 126 | 127 | public void setTopic_pub_sub_domain(boolean topic_pub_sub_domain) { 128 | this.topic_pub_sub_domain = topic_pub_sub_domain; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/common/autoconfigigure/message/activemq/ActiveMQAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.autoconfigigure.message.activemq; 17 | 18 | import io.mykit.delay.queue.activemq.ActiveMQSender; 19 | import io.mykit.delay.queue.activemq.ActiveMQSenderFactory; 20 | import io.mykit.delay.queue.activemq.QueueSender; 21 | import io.mykit.delay.queue.activemq.TopicSender; 22 | import org.apache.activemq.ActiveMQConnectionFactory; 23 | import org.apache.activemq.RedeliveryPolicy; 24 | import org.apache.activemq.pool.PooledConnectionFactory; 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.context.annotation.Configuration; 29 | import org.springframework.jms.core.JmsTemplate; 30 | 31 | /** 32 | * @author liuyazhuang 33 | * @version 1.0.0 34 | * @date 2019/6/12 35 | * @description 配置ActiveMQ 36 | */ 37 | @Configuration 38 | @EnableConfigurationProperties(ActiveMQProperties.class) 39 | public class ActiveMQAutoConfiguration { 40 | 41 | @Autowired 42 | private ActiveMQProperties properties; 43 | 44 | @Bean 45 | public RedeliveryPolicy activeMQRedeliveryPolicy(){ 46 | RedeliveryPolicy policy = new RedeliveryPolicy(); 47 | policy.setUseExponentialBackOff(properties.isUseExponentialBackOff()); 48 | policy.setMaximumRedeliveries(properties.getMaximumRedeliveries()); 49 | policy.setInitialRedeliveryDelay(properties.getInitialRedeliveryDelay()); 50 | policy.setBackOffMultiplier(properties.getBackOffMultiplier()); 51 | policy.setMaximumRedeliveryDelay(properties.getMaximumRedeliveryDelay()); 52 | return policy; 53 | } 54 | 55 | @Bean 56 | public ActiveMQConnectionFactory activeMQConnectionFactory(){ 57 | ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(); 58 | activeMQConnectionFactory.setBrokerURL(properties.getBrokerUrl()); 59 | activeMQConnectionFactory.setUserName(properties.getUsername()); 60 | activeMQConnectionFactory.setPassword(properties.getPassword()); 61 | activeMQConnectionFactory.setUseAsyncSend(properties.isUseAsyncSend()); 62 | activeMQConnectionFactory.setRedeliveryPolicy(activeMQRedeliveryPolicy()); 63 | return activeMQConnectionFactory; 64 | } 65 | 66 | @Bean 67 | public PooledConnectionFactory connectionFactory(){ 68 | PooledConnectionFactory factory = new PooledConnectionFactory(); 69 | factory.setConnectionFactory(activeMQConnectionFactory()); 70 | return factory; 71 | } 72 | 73 | @Bean 74 | public JmsTemplate jmsQueueTemplate(){ 75 | JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory()); 76 | jmsTemplate.setPubSubDomain(properties.isQueue_pub_sub_domain()); 77 | return jmsTemplate; 78 | } 79 | 80 | @Bean 81 | public JmsTemplate jmsTopicTemplate(){ 82 | JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory()); 83 | jmsTemplate.setPubSubDomain(properties.isTopic_pub_sub_domain()); 84 | return jmsTemplate; 85 | } 86 | 87 | @Bean 88 | public ActiveMQSender queueSender(){ 89 | ActiveMQSender queueSender = new QueueSender(jmsQueueTemplate()); 90 | ActiveMQSenderFactory.put(ActiveMQSenderFactory.JMS_QUEUE_SENDER, queueSender); 91 | return queueSender; 92 | } 93 | 94 | @Bean 95 | public ActiveMQSender topicSender(){ 96 | ActiveMQSender topicSender = new TopicSender(jmsTopicTemplate()); 97 | ActiveMQSenderFactory.put(ActiveMQSenderFactory.JMS_TOPIC_SENDER, topicSender); 98 | return topicSender; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright 2018-yyyy Adam Lu(刘亚壮). 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | 15 | ================================================================ 16 | Dependencies: 17 | 18 | Spring: 19 | 20 | * LICENSE: 21 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 22 | * HOMEPAGE: 23 | * http://www.springsource.org 24 | 25 | Javassist: 26 | 27 | * LICENSE: 28 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 29 | * HOMEPAGE: 30 | * http://www.jboss.org/javassist 31 | 32 | Netty: 33 | 34 | * LICENSE: 35 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 36 | * HOMEPAGE: 37 | * http://netty.io 38 | 39 | Mina: 40 | 41 | * LICENSE: 42 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 43 | * HOMEPAGE: 44 | * http://mina.apache.org 45 | 46 | Grizzly: 47 | 48 | * LICENSE: 49 | * http://www.gnu.org/licenses/gpl-2.0.html (General Public License 2.0) 50 | * HOMEPAGE: 51 | * http://grizzly.java.net 52 | 53 | HttpClient: 54 | 55 | * LICENSE: 56 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 57 | * HOMEPAGE: 58 | * http://hc.apache.org 59 | 60 | Hessian: 61 | 62 | * LICENSE: 63 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 64 | * HOMEPAGE: 65 | * http://hessian.caucho.com 66 | 67 | XStream: 68 | 69 | * LICENSE: 70 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 71 | * HOMEPAGE: 72 | * http://xstream.codehaus.org 73 | 74 | FastJson: 75 | 76 | * LICENSE: 77 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 78 | * HOMEPAGE: 79 | * http://code.alibabatech.com/wiki/fastjson 80 | 81 | Zookeeper: 82 | 83 | * LICENSE: 84 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 85 | * HOMEPAGE: 86 | * http://zookeeper.apache.org 87 | 88 | Jedis: 89 | 90 | * LICENSE: 91 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 92 | * HOMEPAGE: 93 | * http://code.google.com/p/jedis 94 | 95 | XMemcached: 96 | 97 | * LICENSE: 98 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 99 | * HOMEPAGE: 100 | * http://code.google.com/p/xmemcached 101 | 102 | Jetty: 103 | 104 | * LICENSE: 105 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 106 | * HOMEPAGE: 107 | * http://jetty.mortbay.org 108 | 109 | Thrift: 110 | 111 | * LICENSE: 112 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 113 | * HOMEPAGE: 114 | * http://thrift.apache.org 115 | 116 | CXF: 117 | 118 | * LICENSE: 119 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 120 | * HOMEPAGE: 121 | * http://cxf.apache.org 122 | 123 | ZKClient: 124 | 125 | * LICENSE: 126 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 127 | * HOMEPAGE: 128 | * https://github.com/sgroschupf/zkclient 129 | 130 | Curator 131 | 132 | * LICENSE: 133 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 134 | * HOMEPAGE: 135 | * https://github.com/Netflix/curator 136 | 137 | JFreeChart: 138 | 139 | * LICENSE: 140 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 141 | * HOMEPAGE: 142 | * http://www.jfree.org 143 | 144 | HibernateValidator: 145 | 146 | * LICENSE: 147 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 148 | * HOMEPAGE: 149 | * http://www.hibernate.org/subprojects/validator.html 150 | 151 | CommonsLogging: 152 | 153 | * LICENSE: 154 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 155 | * HOMEPAGE: 156 | * http://commons.apache.org/logging 157 | 158 | SLF4J: 159 | 160 | * LICENSE: 161 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 162 | * HOMEPAGE: 163 | * http://www.slf4j.org 164 | 165 | Log4j: 166 | 167 | * LICENSE: 168 | * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0) 169 | * HOMEPAGE: 170 | * http://log4j.apache.org 171 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/leader/SimpleLeaderManager.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.leader; 17 | 18 | import io.mykit.delay.common.autoconfigigure.RegistryProperties; 19 | import io.mykit.delay.common.utils.BlockUtils; 20 | import org.apache.curator.framework.CuratorFramework; 21 | import org.apache.curator.framework.CuratorFrameworkFactory; 22 | import org.apache.curator.framework.recipes.leader.LeaderLatch; 23 | import org.apache.curator.framework.recipes.leader.LeaderLatchListener; 24 | import org.apache.curator.retry.ExponentialBackoffRetry; 25 | import org.apache.curator.utils.CloseableUtils; 26 | import org.assertj.core.util.Lists; 27 | import org.slf4j.Logger; 28 | import org.slf4j.LoggerFactory; 29 | 30 | import java.util.List; 31 | import java.util.concurrent.atomic.AtomicBoolean; 32 | 33 | /** 34 | * @author liuyazhuang 35 | * @version 1.0.0 36 | * @date 2019/5/29 37 | * @description 38 | */ 39 | public class SimpleLeaderManager implements LeaderManager { 40 | public static final Logger LOGGER = LoggerFactory.getLogger(SimpleLeaderManager.class); 41 | 42 | private LeaderLatch leaderLatch; 43 | 44 | private CuratorFramework framework; 45 | 46 | private String serverName = ""; 47 | 48 | private volatile AtomicBoolean isLatch = new AtomicBoolean(false); 49 | private List listeners = Lists.newArrayList(); 50 | private RegistryProperties properties; 51 | 52 | public void init() { 53 | CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder() 54 | .connectString(properties.getServerList()) 55 | .retryPolicy(new ExponentialBackoffRetry(properties.getBaseSleepTimeMilliseconds(), 56 | properties.getMaxRetries(), 57 | properties.getMaxSleepTimeMilliseconds())) 58 | .namespace(ServerNode.NAMESPACE); 59 | framework = builder.build(); 60 | framework.start(); 61 | leaderLatch = new LeaderLatch(framework, ServerNode.LEADERLATCH, serverName, LeaderLatch.CloseMode.NOTIFY_LEADER); 62 | for (LeaderLatchListener listener : listeners) { 63 | leaderLatch.addListener(listener); 64 | } 65 | LOGGER.info("starting Queue Master Slave Model ..."); 66 | start(); 67 | } 68 | 69 | 70 | @Override 71 | public void start() { 72 | if (isLatch.compareAndSet(false, true)) { 73 | try { 74 | LOGGER.info("starting latch...."); 75 | leaderLatch.start(); 76 | } catch (Exception e) { 77 | LOGGER.error(e.getMessage(), e); 78 | throw new RuntimeException(e); 79 | } 80 | } 81 | 82 | } 83 | 84 | @Override 85 | public void stop() { 86 | if (isLatch.compareAndSet(true, false)) { 87 | try { 88 | BlockUtils.sleep(500); 89 | LOGGER.info("stop latch...."); 90 | CloseableUtils.closeQuietly(leaderLatch); 91 | //CloseableUtils.closeQuietly(framework); 92 | } catch (Exception e) { 93 | LOGGER.error(e.getMessage(), e); 94 | throw new RuntimeException(e); 95 | } 96 | } 97 | } 98 | 99 | @Override 100 | public boolean isRunning() { 101 | return isLatch.get(); 102 | } 103 | 104 | @Override 105 | public boolean isLeader() { 106 | return leaderLatch.hasLeadership(); 107 | } 108 | 109 | public void setProperties(RegistryProperties properties) { 110 | this.properties = properties; 111 | } 112 | 113 | public void addListener(LeaderLatchListener leaderLatchListener) { 114 | if (!listeners.contains(leaderLatchListener)) { 115 | listeners.add(leaderLatchListener); 116 | } 117 | 118 | } 119 | 120 | public void setServerName(String serverName) { 121 | this.serverName = serverName; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/common/autoconfigigure/message/MessageProducer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.autoconfigigure.message; 17 | 18 | import com.alibaba.rocketmq.client.exception.MQBrokerException; 19 | import com.alibaba.rocketmq.client.exception.MQClientException; 20 | import com.alibaba.rocketmq.client.producer.DefaultMQProducer; 21 | import com.alibaba.rocketmq.client.producer.SendResult; 22 | import com.alibaba.rocketmq.common.message.Message; 23 | import com.alibaba.rocketmq.remoting.exception.RemotingException; 24 | import com.google.common.util.concurrent.*; 25 | import io.mykit.delay.common.utils.Constants; 26 | import io.mykit.delay.queue.JobMsg; 27 | import io.mykit.delay.queue.core.Job; 28 | import org.slf4j.Logger; 29 | import org.slf4j.LoggerFactory; 30 | import org.springframework.util.Assert; 31 | import org.springframework.util.StringUtils; 32 | 33 | import java.io.Closeable; 34 | import java.io.IOException; 35 | import java.io.Serializable; 36 | import java.nio.charset.Charset; 37 | import java.util.concurrent.Callable; 38 | import java.util.concurrent.ExecutorService; 39 | import java.util.concurrent.Executors; 40 | 41 | /** 42 | * @author liuyazhuang 43 | * @version 1.0.0 44 | * @date 2019/5/29 45 | * @description 消息生产者 46 | */ 47 | public class MessageProducer implements Closeable { 48 | public static final Logger LOGGER = LoggerFactory.getLogger(MessageProducer.class); 49 | public static final ExecutorService EXECUTORS = Executors.newFixedThreadPool(2); 50 | private static DefaultMQProducer PRODUCER; 51 | private String namesrvAddr; 52 | 53 | /** 54 | * @return 55 | */ 56 | public static boolean send(Job msg) { 57 | Assert.notNull(msg, "参数错误"); 58 | Message message = new Message(); 59 | message.setTopic(msg.getTopic()); 60 | if (!StringUtils.isEmpty(msg.getSubtopic())) { 61 | message.setTags(msg.getSubtopic()); 62 | } 63 | message.setKeys(msg.getBizKey()); 64 | Serializable data = msg.getBody(); 65 | if (data != null) { 66 | message.setBody(((String) data).getBytes(Charset.forName(Constants.CODE_UTF8))); 67 | } else { 68 | message.setBody("".getBytes(Charset.forName(Constants.CODE_UTF8))); 69 | } 70 | 71 | try { 72 | SendResult send = PRODUCER.send(message); 73 | } catch (MQClientException | MQBrokerException | RemotingException | InterruptedException e) { 74 | LOGGER.error(String.format("消息发送失败[%s]", message.toString()), e); 75 | return false; 76 | } 77 | return true; 78 | } 79 | 80 | //guava异步发送mq 81 | public static void sendAsyncMessage(final JobMsg job) { 82 | 83 | ListeningExecutorService guavaExecutor = MoreExecutors.listeningDecorator(EXECUTORS); 84 | 85 | final ListenableFuture listenableFuture = guavaExecutor.submit(new Callable() { 86 | 87 | @Override 88 | public Boolean call() throws Exception { 89 | return MessageProducer.send(job); 90 | } 91 | }); 92 | Futures.addCallback(listenableFuture, new FutureCallback() { 93 | @Override 94 | public void onSuccess(Boolean mqMessageStatus) { 95 | } 96 | 97 | @Override 98 | public void onFailure(Throwable throwable) { 99 | LOGGER.error(throwable.getMessage()); 100 | } 101 | }); 102 | } 103 | 104 | public String getNamesrvAddr() { 105 | return namesrvAddr; 106 | } 107 | 108 | public void setNamesrvAddr(String namesrvAddr) { 109 | this.namesrvAddr = namesrvAddr; 110 | } 111 | 112 | protected void init() { 113 | if (PRODUCER == null) { 114 | PRODUCER = new DefaultMQProducer("Producer"); 115 | PRODUCER.setNamesrvAddr(namesrvAddr); 116 | try { 117 | PRODUCER.start(); 118 | } catch (MQClientException e) { 119 | LOGGER.error("消息发送端初始化失败", e); 120 | throw new RuntimeException(e); 121 | } 122 | } 123 | } 124 | 125 | /** 126 | * 关闭消息发送端,同时释放资源,由容器自动处理,程序中不能调用此方法 127 | */ 128 | @Override 129 | public void close() throws IOException { 130 | if (PRODUCER != null) { 131 | LOGGER.info("shutdowing mq..."); 132 | PRODUCER.shutdown(); 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/redis/bucket/BucketQueueManager.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.redis.bucket; 17 | 18 | import com.google.common.collect.Maps; 19 | 20 | import io.mykit.delay.common.utils.NamedUtil; 21 | import io.mykit.delay.queue.redis.JobOperationService; 22 | import io.mykit.delay.queue.redis.support.DistributedLock; 23 | import io.mykit.delay.queue.redis.support.Lifecycle; 24 | import io.mykit.delay.queue.redis.support.RedisQueueProperties; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | import java.util.Map; 29 | import java.util.Timer; 30 | import java.util.concurrent.atomic.AtomicBoolean; 31 | 32 | /** 33 | * @author liuyazhuang 34 | * @version 1.0.0 35 | * @date 2019/5/30 36 | * @description Bucket 队列管理器 37 | */ 38 | public class BucketQueueManager implements Lifecycle { 39 | public static final Logger LOGGER = LoggerFactory.getLogger(BucketQueueManager.class); 40 | public static final String THREAD_NAME = "mykit-delay-queue-%s"; 41 | public boolean daemon = true; 42 | private volatile AtomicBoolean isRuning = new AtomicBoolean(false); 43 | private RedisQueueProperties properties; 44 | private Map HOLD_TIMES = Maps.newConcurrentMap(); 45 | private JobOperationService jobOperationService; 46 | private DistributedLock lock = null; 47 | 48 | private int checkBucketNum(int bucketSize) { 49 | if (bucketSize <= 0) { 50 | bucketSize = 1; 51 | } 52 | return bucketSize; 53 | } 54 | 55 | // public static void main(String[] args) { 56 | // BucketQueueManager manager=new BucketQueueManager(); 57 | // RedisQueueProperties redisQueueProperties=new RedisQueueProperties(); 58 | // manager.setProperties(redisQueueProperties); 59 | // manager.start(); 60 | // try { 61 | // Thread.sleep(10000L); 62 | // } catch (InterruptedException e) { 63 | // e.printStackTrace(); 64 | // } 65 | // System.out.println(manager.isRunning()); 66 | // manager.stop(); 67 | // System.out.println(manager.isRunning()); 68 | // } 69 | 70 | 71 | @Override 72 | public void start() { 73 | int bucketSize = checkBucketNum(properties.getBucketSize()); 74 | if (isRuning.compareAndSet(false, true)) { 75 | for (int i = 1; i <= bucketSize; i++) { 76 | String bName = NamedUtil.buildBucketName(properties.getPrefix(), properties.getName(), i); 77 | BucketTask task = new BucketTask(bName); 78 | task.setJobOperationService(jobOperationService); 79 | task.setPoolName(NamedUtil.buildPoolName(properties.getPrefix(), properties.getName(), properties.getOriginPool())); 80 | task.setReadyName(NamedUtil.buildPoolName(properties.getPrefix(), properties.getName(), properties.getReadyName())); 81 | task.setProperties(properties); 82 | task.setLock(lock); 83 | String threadName = String.format(THREAD_NAME, i); 84 | Timer timer = new Timer(threadName, daemon); 85 | timer.schedule(task, 500, properties.getBuckRoundRobinTime()); 86 | HOLD_TIMES.put(threadName, timer); 87 | LOGGER.info(String.format("Starting Bucket Thead %s ....", threadName)); 88 | } 89 | 90 | } 91 | } 92 | 93 | @Override 94 | public void stop() { 95 | if (isRuning.compareAndSet(true, false)) { 96 | if (HOLD_TIMES != null && HOLD_TIMES.size() > 0) { 97 | for (Map.Entry entry : HOLD_TIMES.entrySet()) { 98 | String n = entry.getKey(); 99 | Timer timer = entry.getValue(); 100 | timer.cancel(); 101 | LOGGER.info(String.format("stoping timer %s .....", n)); 102 | } 103 | } 104 | } 105 | } 106 | 107 | @Override 108 | public boolean isRunning() { 109 | return isRuning.get(); 110 | } 111 | 112 | public void setProperties(RedisQueueProperties properties) { 113 | this.properties = properties; 114 | } 115 | 116 | public void setDaemon(boolean daemon) { 117 | this.daemon = daemon; 118 | } 119 | 120 | public void setJobOperationService(JobOperationService jobOperationService) { 121 | this.jobOperationService = jobOperationService; 122 | } 123 | 124 | public void setLock(DistributedLock lock) { 125 | this.lock = lock; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/common/autoconfigigure/redis/RedisQueueAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.common.autoconfigigure.redis; 17 | 18 | import com.alibaba.druid.pool.DruidDataSource; 19 | import io.mykit.delay.common.autoconfigigure.db.DruidConfig; 20 | import io.mykit.delay.queue.redis.*; 21 | import io.mykit.delay.queue.redis.bucket.BucketQueueManager; 22 | import io.mykit.delay.queue.redis.event.JobEventBus; 23 | import io.mykit.delay.queue.redis.event.JobEventListener; 24 | import io.mykit.delay.queue.redis.event.RedisJobEventListener; 25 | import io.mykit.delay.queue.redis.ready.ReadyQueueManager; 26 | import io.mykit.delay.queue.redis.support.RedisDistributedLock; 27 | import io.mykit.delay.queue.redis.support.RedisQueueProperties; 28 | import io.mykit.delay.queue.redis.support.RedisSupport; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | import org.springframework.beans.factory.annotation.Autowired; 32 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 33 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 34 | import org.springframework.context.annotation.Bean; 35 | import org.springframework.context.annotation.Configuration; 36 | import org.springframework.data.redis.core.StringRedisTemplate; 37 | import redis.clients.jedis.Jedis; 38 | 39 | /** 40 | * @author liuyazhuang 41 | * @version 1.0.0 42 | * @date 2019/5/29 43 | * @description Redis队列配置 44 | */ 45 | @Configuration 46 | @EnableConfigurationProperties(RedisQueueProperties.class) 47 | @ConditionalOnClass(value = {Jedis.class, RedisQueue.class}) 48 | public class RedisQueueAutoConfiguration { 49 | public static final Logger LOGGER = LoggerFactory.getLogger(RedisQueueAutoConfiguration.class); 50 | @Autowired 51 | private DruidConfig druidConfig; 52 | @Autowired 53 | private RedisQueueProperties properties; 54 | @Autowired 55 | private StringRedisTemplate template; 56 | 57 | private JobOperationService jobOperationService; 58 | 59 | 60 | @Bean 61 | public RedisSupport redisSupport() { 62 | RedisSupport support = new RedisSupport(); 63 | support.setTemplate(template); 64 | return support; 65 | } 66 | 67 | /** 68 | * 分布式锁 69 | */ 70 | @Bean 71 | @Autowired 72 | public RedisDistributedLock redisDistributedLock(RedisSupport redisSupport) { 73 | return new RedisDistributedLock(redisSupport); 74 | } 75 | 76 | @Bean 77 | @Autowired 78 | public JobOperationService JobOperationService(RedisSupport redisSupport) { 79 | JobOperationServiceImpl jobOperationService = new JobOperationServiceImpl(); 80 | jobOperationService.setRedisSupport(redisSupport); 81 | jobOperationService.setProperties(properties); 82 | return jobOperationService; 83 | } 84 | 85 | @Bean 86 | @Autowired 87 | public BucketQueueManager BucketQueueManager(JobOperationService jobOperationService, RedisDistributedLock lock) { 88 | BucketQueueManager manager = new BucketQueueManager(); 89 | manager.setProperties(properties); 90 | manager.setJobOperationService(jobOperationService); 91 | manager.setLock(lock); 92 | return manager; 93 | } 94 | 95 | @Bean 96 | public RdbStore rdbStore() { 97 | try { 98 | DruidDataSource ds = (DruidDataSource) druidConfig.newInstanceDruidDataSource(); 99 | return new RdbStore(ds); 100 | } catch (Exception e) { 101 | LOGGER.error(e.getMessage()); 102 | throw new RuntimeException(e); 103 | } 104 | } 105 | 106 | @Bean 107 | @Autowired 108 | public JobEventListener jobEventListener(RdbStore store) { 109 | RedisJobEventListener eventListener = new RedisJobEventListener(); 110 | eventListener.setStore(store); 111 | JobEventBus.getInstance().register(eventListener); 112 | return eventListener; 113 | } 114 | 115 | @Bean 116 | @Autowired 117 | public ReadyQueueManager readyQueueManager(JobOperationService jobOperationService, RedisDistributedLock lock) { 118 | ReadyQueueManager manager = new ReadyQueueManager(); 119 | manager.setProperties(properties); 120 | manager.setJobOperationService(jobOperationService); 121 | manager.setLock(lock); 122 | return manager; 123 | } 124 | 125 | @Bean 126 | @Autowired 127 | public RedisQueue redisQueue(JobOperationService jobOperationService, BucketQueueManager bucketQueueManager, ReadyQueueManager readyQueueManager) { 128 | RedisQueue redisQueue = new RedisQueueImpl(); 129 | redisQueue.setProperties(properties); 130 | redisQueue.setJobOperationService(jobOperationService); 131 | redisQueue.setBucketQueueManager(bucketQueueManager); 132 | redisQueue.setReadyQueueManager(readyQueueManager); 133 | readyQueueManager.setDelayQueue(redisQueue); 134 | return redisQueue; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /mykit-delay-queue/src/main/java/io/mykit/delay/queue/extension/ExtensionLoader.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2999 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.mykit.delay.queue.extension; 17 | 18 | import io.mykit.delay.queue.core.ConsumeQueueProvider; 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | import org.springframework.util.StringUtils; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | import java.util.Map; 26 | import java.util.ServiceLoader; 27 | import java.util.concurrent.ConcurrentHashMap; 28 | 29 | /** 30 | * @author liuyazhuang 31 | * @version 1.0.0 32 | * @date 2019/5/29 33 | * @description 扩展类加载器 34 | */ 35 | public final class ExtensionLoader { 36 | 37 | private static final Logger LOGGER = LoggerFactory.getLogger(ExtensionLoader.class); 38 | 39 | private static volatile Map, Object> extensionMap = new ConcurrentHashMap<>(); 40 | 41 | private static volatile Map, List> extensionListMap = new ConcurrentHashMap<>(); 42 | 43 | private ExtensionLoader() { 44 | } 45 | 46 | public static T getExtension(Class clazz) { 47 | T extension = (T) extensionMap.get(clazz); 48 | if (extension == null) { 49 | extension = newExtension(clazz); 50 | if (extension != null) { 51 | extensionMap.put(clazz, extension); 52 | } 53 | } 54 | return extension; 55 | } 56 | 57 | public static List getExtensionList(Class clazz) { 58 | List extensions = (List) extensionListMap.get(clazz); 59 | if (extensions == null) { 60 | extensions = newExtensionList(clazz); 61 | if (!extensions.isEmpty()) { 62 | extensionListMap.put(clazz, extensions); 63 | } 64 | } 65 | return extensions; 66 | } 67 | 68 | public static T newExtension(Class clazz) { 69 | String defaultImp = getDefaultSPI(clazz); 70 | if (StringUtils.isEmpty(defaultImp)) { 71 | throw new RuntimeException(String.format("请配置 %s SPI默认实现", clazz.getName())); 72 | } 73 | LOGGER.debug("默认的SPI为===>>>" + defaultImp); 74 | ServiceLoader serviceLoader = ServiceLoader.load(clazz); 75 | for (T service : serviceLoader) { 76 | if (service.getClass().isAnnotationPresent(ExtNamed.class) 77 | && defaultImp.equalsIgnoreCase(getExNamed(service.getClass()))) { 78 | return service; 79 | } 80 | } 81 | return null; 82 | } 83 | 84 | private static String getDefaultSPI(Class clazz) { 85 | String spi = System.getProperty(clazz.getName()); 86 | if (!StringUtils.isEmpty(spi)) { 87 | return spi; 88 | } 89 | if (clazz.isAnnotationPresent(SPI.class)) { 90 | SPI annotation = clazz.getAnnotation(SPI.class); 91 | return annotation.value(); 92 | } 93 | return null; 94 | } 95 | 96 | private static String getExNamed(Class clazz) { 97 | if (clazz.isAnnotationPresent(ExtNamed.class)) { 98 | ExtNamed annotation = clazz.getAnnotation(ExtNamed.class); 99 | return annotation.value(); 100 | } 101 | return null; 102 | } 103 | 104 | public static void main(String[] args) { 105 | System.out.println(ExtensionLoader.getExtension(ConsumeQueueProvider.class)); 106 | System.out.println(ExtensionLoader.getExtension(ConsumeQueueProvider.class)); 107 | System.out.println(ExtensionLoader.getExtension(ConsumeQueueProvider.class)); 108 | } 109 | 110 | public static List newExtensionList(Class clazz) { 111 | ServiceLoader serviceLoader = ServiceLoader.load(clazz); 112 | List extensions = new ArrayList<>(); 113 | for (T service : serviceLoader) { 114 | extensions.add(service); 115 | } 116 | return extensions; 117 | } 118 | 119 | // /** 120 | // * @param namespaceFun 命名空间函数 121 | // * @param namespaceValue 指定命名空间的值 122 | // */ 123 | // public static T getExtension(Class clazz, String namespaceFun, String namespaceValue) { 124 | // List lst = ExtensionLoader.getExtensionList(clazz); 125 | // if (lst == null || lst.size() == 0) { 126 | // throw new RuntimeException(String.format("请配置 %s 厂商实现", clazz.getName())); 127 | // } 128 | // if (lst != null && lst.size() > 0) { 129 | // for (T ext : lst) { 130 | // Method method = ReflectionUtils.findMethod(clazz, namespaceFun); 131 | // Assert.notNull(method, String.format("厂商接口 %s 没有找到命名空间函数 %s", clazz.getName(), namespaceFun)); 132 | // String namespaceValue_ = Objects.toString(ReflectionUtils.invokeMethod(method, ext)); 133 | // if (namespaceValue_.equalsIgnoreCase(namespaceValue)) { 134 | // 135 | // return ext; 136 | // } 137 | // } 138 | // } 139 | // return null; 140 | // } 141 | } 142 | --------------------------------------------------------------------------------