-
Notifications
You must be signed in to change notification settings - Fork 276
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
420 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>io.github.dunwu.distributed</groupId> | ||
<artifactId>java-distributed</artifactId> | ||
<version>1.0.0</version> | ||
</parent> | ||
|
||
<groupId>io.github.dunwu.javatech</groupId> | ||
<artifactId>java-distributed-id</artifactId> | ||
<version>1.0.0</version> | ||
<packaging>jar</packaging> | ||
<name>${project.artifactId}</name> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<java.version>1.8</java.version> | ||
<maven.compiler.source>${java.version}</maven.compiler.source> | ||
<maven.compiler.target>${java.version}</maven.compiler.target> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.apache.zookeeper</groupId> | ||
<artifactId>zookeeper</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.curator</groupId> | ||
<artifactId>curator-recipes</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>redis.clients</groupId> | ||
<artifactId>jedis</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>cn.hutool</groupId> | ||
<artifactId>hutool-all</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.projectlombok</groupId> | ||
<artifactId>lombok</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>ch.qos.logback</groupId> | ||
<artifactId>logback-classic</artifactId> | ||
<optional>true</optional> | ||
</dependency> | ||
</dependencies> | ||
</project> |
55 changes: 55 additions & 0 deletions
55
...a-distributed-id/src/main/java/io/github/dunwu/distributed/id/ZookeeperDistributedId.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package io.github.dunwu.distributed.id; | ||
|
||
import cn.hutool.core.collection.CollectionUtil; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.curator.RetryPolicy; | ||
import org.apache.curator.framework.CuratorFramework; | ||
import org.apache.curator.framework.CuratorFrameworkFactory; | ||
import org.apache.curator.retry.ExponentialBackoffRetry; | ||
import org.apache.zookeeper.CreateMode; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* ZK 分布式 ID | ||
* | ||
* @author <a href="mailto:[email protected]">Zhang Peng</a> | ||
* @date 2024-12-20 | ||
*/ | ||
@Slf4j | ||
public class ZookeeperDistributedId { | ||
|
||
public static void main(String[] args) throws Exception { | ||
|
||
// 获取客户端 | ||
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3); | ||
CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy); | ||
|
||
// 开启会话 | ||
client.start(); | ||
|
||
String id1 = client.create() | ||
.creatingParentsIfNeeded() | ||
.withMode(CreateMode.PERSISTENT_SEQUENTIAL) | ||
.forPath("/zkid/id_"); | ||
log.info("id: {}", id1); | ||
|
||
String id2 = client.create() | ||
.creatingParentsIfNeeded() | ||
.withMode(CreateMode.PERSISTENT_SEQUENTIAL) | ||
.forPath("/zkid/id_"); | ||
log.info("id: {}", id2); | ||
|
||
List<String> children = client.getChildren().forPath("/zkid"); | ||
if (CollectionUtil.isNotEmpty(children)) { | ||
for (String child : children) { | ||
client.delete().forPath("/zkid/" + child); | ||
} | ||
} | ||
client.delete().forPath("/zkid"); | ||
|
||
// 关闭客户端 | ||
client.close(); | ||
} | ||
|
||
} |
46 changes: 46 additions & 0 deletions
46
...-distributed-id/src/main/java/io/github/dunwu/distributed/id/ZookeeperDistributedId2.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package io.github.dunwu.distributed.id; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.curator.RetryPolicy; | ||
import org.apache.curator.framework.CuratorFramework; | ||
import org.apache.curator.framework.CuratorFrameworkFactory; | ||
import org.apache.curator.framework.recipes.atomic.AtomicValue; | ||
import org.apache.curator.framework.recipes.atomic.DistributedAtomicLong; | ||
import org.apache.curator.retry.ExponentialBackoffRetry; | ||
|
||
/** | ||
* ZK 分布式 ID | ||
* <p> | ||
* 基于原子计数器生成 ID | ||
* | ||
* @author <a href="mailto:[email protected]">Zhang Peng</a> | ||
* @date 2024-12-20 | ||
*/ | ||
@Slf4j | ||
public class ZookeeperDistributedId2 { | ||
|
||
public static void main(String[] args) throws Exception { | ||
|
||
// 获取客户端 | ||
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3); | ||
CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy); | ||
DistributedAtomicLong atomicLong = new DistributedAtomicLong(client, "/zkid", retryPolicy); | ||
|
||
// 开启会话 | ||
client.start(); | ||
|
||
// 基于原子计数器生成 ID | ||
AtomicValue<Long> id1 = atomicLong.increment(); | ||
log.info("id: {}", id1.postValue()); | ||
|
||
AtomicValue<Long> id2 = atomicLong.increment(); | ||
log.info("id: {}", id2.postValue()); | ||
|
||
// 清理节点 | ||
client.delete().forPath("/zkid"); | ||
|
||
// 关闭客户端 | ||
client.close(); | ||
} | ||
|
||
} |
21 changes: 21 additions & 0 deletions
21
...va-distributed/java-distributed-id/src/main/resources/scripts/fixed_window_rate_limit.lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
-- 缓存 Key | ||
local key = KEYS[1] | ||
-- 访问请求数 | ||
local permits = tonumber(ARGV[1]) | ||
-- 过期时间 | ||
local seconds = tonumber(ARGV[2]) | ||
-- 限流阈值 | ||
local limit = tonumber(ARGV[3]) | ||
|
||
-- 获取统计值 | ||
local count = tonumber(redis.call('GET', key) or "0") | ||
|
||
if count + permits > limit then | ||
-- 请求拒绝 | ||
return -1 | ||
else | ||
-- 请求通过 | ||
redis.call('INCRBY', key, permits) | ||
redis.call('EXPIRE', key, seconds) | ||
return count + permits | ||
end |
39 changes: 39 additions & 0 deletions
39
...va-distributed/java-distributed-id/src/main/resources/scripts/token_bucket_rate_limit.lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
local tokenKey = KEYS[1] | ||
local timeKey = KEYS[2] | ||
|
||
-- 申请令牌数 | ||
local permits = tonumber(ARGV[1]) | ||
-- QPS | ||
local qps = tonumber(ARGV[2]) | ||
-- 桶的容量 | ||
local capacity = tonumber(ARGV[3]) | ||
-- 当前时间(单位:毫秒) | ||
local nowMillis = tonumber(ARGV[4]) | ||
-- 填满令牌桶所需要的时间 | ||
local fillTime = capacity / qps | ||
local ttl = math.min(capacity, math.floor(fillTime * 2)) | ||
|
||
local currentTokenNum = tonumber(redis.call("GET", tokenKey)) | ||
if currentTokenNum == nil then | ||
currentTokenNum = capacity | ||
end | ||
|
||
local endTimeMillis = tonumber(redis.call("GET", timeKey)) | ||
if endTimeMillis == nil then | ||
endTimeMillis = 0 | ||
end | ||
|
||
local gap = nowMillis - endTimeMillis | ||
local newTokenNum = math.max(0, gap * qps / 1000) | ||
local currentTokenNum = math.min(capacity, currentTokenNum + newTokenNum) | ||
|
||
if currentTokenNum < permits then | ||
-- 请求拒绝 | ||
return -1 | ||
else | ||
-- 请求通过 | ||
local finalTokenNum = currentTokenNum - permits | ||
redis.call("SETEX", tokenKey, ttl, finalTokenNum) | ||
redis.call("SETEX", timeKey, ttl, nowMillis) | ||
return finalTokenNum | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>io.github.dunwu.distributed</groupId> | ||
<artifactId>java-distributed</artifactId> | ||
<version>1.0.0</version> | ||
</parent> | ||
|
||
<groupId>io.github.dunwu.distributed</groupId> | ||
<artifactId>java-task</artifactId> | ||
<version>1.0.0</version> | ||
<packaging>jar</packaging> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<java.version>1.8</java.version> | ||
<maven.compiler.source>${java.version}</maven.compiler.source> | ||
<maven.compiler.target>${java.version}</maven.compiler.target> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>cn.hutool</groupId> | ||
<artifactId>hutool-all</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.projectlombok</groupId> | ||
<artifactId>lombok</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>ch.qos.logback</groupId> | ||
<artifactId>logback-classic</artifactId> | ||
<version>1.2.3</version> | ||
<optional>true</optional> | ||
</dependency> | ||
</dependencies> | ||
</project> |
52 changes: 52 additions & 0 deletions
52
...ava-distributed/java-task/src/main/java/io/github/dunwu/local/task/DelayQueueExample.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package io.github.dunwu.local.task; | ||
|
||
import cn.hutool.core.date.DateUtil; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
import java.util.Date; | ||
import java.util.concurrent.BlockingQueue; | ||
import java.util.concurrent.DelayQueue; | ||
import java.util.concurrent.Delayed; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
@Slf4j | ||
public class DelayQueueExample { | ||
|
||
public static void main(String[] args) throws InterruptedException { | ||
BlockingQueue<SampleTask> delayQueue = new DelayQueue<>(); | ||
long now = System.currentTimeMillis(); | ||
delayQueue.put(new SampleTask(now + 1000)); | ||
delayQueue.put(new SampleTask(now + 2000)); | ||
delayQueue.put(new SampleTask(now + 3000)); | ||
for (int i = 0; i < 3; i++) { | ||
log.info("task 执行时间:{}", DateUtil.format(new Date(delayQueue.take().getTime()), "yyyy-MM-dd HH:mm:ss")); | ||
} | ||
} | ||
|
||
static class SampleTask implements Delayed { | ||
|
||
long time; | ||
|
||
public SampleTask(long time) { | ||
this.time = time; | ||
} | ||
|
||
public long getTime() { | ||
return time; | ||
} | ||
|
||
@Override | ||
public int compareTo(Delayed o) { | ||
return Long.compare(this.getDelay(TimeUnit.MILLISECONDS), o.getDelay(TimeUnit.MILLISECONDS)); | ||
} | ||
|
||
@Override | ||
public long getDelay(TimeUnit unit) { | ||
return unit.convert(time - System.currentTimeMillis(), TimeUnit.MILLISECONDS); | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
|
37 changes: 37 additions & 0 deletions
37
...d/java-task/src/main/java/io/github/dunwu/local/task/ScheduledExecutorServiceExample.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package io.github.dunwu.local.task; | ||
|
||
import cn.hutool.core.date.DateUtil; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
import java.util.Date; | ||
import java.util.concurrent.Executors; | ||
import java.util.concurrent.ScheduledExecutorService; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
@Slf4j | ||
public class ScheduledExecutorServiceExample { | ||
|
||
public static void main(String[] args) { | ||
// 创建一个 ScheduledExecutorService 对象,它将使用一个线程池来执行任务 | ||
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); | ||
|
||
// 创建一个 Runnable 对象,这个任务将在 2 秒后执行,并且每 1 秒重复执行一次 | ||
Runnable task = () -> { | ||
log.info("task 执行时间:{}", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); | ||
}; | ||
|
||
// 安排任务在 2 秒后执行,并且每 1 秒重复执行一次 | ||
executor.scheduleAtFixedRate(task, 2, 1, TimeUnit.SECONDS); | ||
|
||
// 主线程等待 10 秒后结束 | ||
try { | ||
Thread.sleep(10000); | ||
} catch (InterruptedException e) { | ||
e.printStackTrace(); | ||
} | ||
|
||
// 关闭 executor,这将停止所有正在执行的任务,并拒绝新任务的提交 | ||
executor.shutdown(); | ||
} | ||
|
||
} |
Oops, something went wrong.