ð§ åè½ð¨ éæ±åºæ¯ð¥ User Guideð Java API Docsð?ª Mavenä¾?èµð¨ å ³äºç¼è¯æå»ºä¸IDE
å¼å?â? FAQ⨠使ç¨TTL
ç好å¤ä¸å¿ è¦?æ§ð¿ æ´å¤ææ¡£ð ç¸å ³èµæð? Who usedð· Contributors
ð§ åè½
TransmittableThreadLocal
(TTL
)ï¼å¨ä½¿ç¨çº¿ç¨æ± ç伿± åå¤?ç¨çº¿ç¨çæ§è¡ç»ä»¶æ
åµä¸ï¼æ??ä¾ThreadLocal
å¼çä¼ éåè½ï¼è§£å³å¼æ¥æ§è¡æ¶ä¸ä¸æä¼ éçé®é¢ãä¸ä¸ªJava
æ ååºæ¬åºä¸ºæ¡æ¶/ä¸é´ä»¶è®¾æ½å¼å?æ??ä¾çæ é
?è½åï¼æ¬åºåè½è?ç¦ & 0ä¾?èµï¼æ¯æ?Java
17/16/15/14/13/12/11/10/9/8/7/6ã
JDK
çInheritableThreadLocal
ç±»å?¯ä»¥å®æ?ç¶çº¿ç¨å°å?线ç¨çå¼ä¼ éãä½å¯¹äºä½¿ç¨çº¿ç¨æ± ç伿± åå¤?ç¨çº¿ç¨çæ§è¡ç»ä»¶çæ
åµï¼çº¿ç¨ç±çº¿ç¨æ± å建好ï¼å¹¶ä¸çº¿ç¨æ¯æ± åèµ·æ?¥å??å¤?使ç¨çï¼è¿æ¶ç¶å?线ç¨å
³ç³»çThreadLocal
å¼ä¼ éå·²ç»?没ææ?ä¹ï¼åºç¨éè¦?çå®é
䏿¯æ 任塿??交ç»çº¿ç¨æ± æ¶çThreadLocal
å¼ä¼ éå° ä»»å¡æ§è¡æ¶ã
æ¬åºæ??ä¾çTransmittableThreadLocal
类继æ¿å¹¶å 强InheritableThreadLocal
ç±»ï¼è§£å³ä¸è¿°çé®é¢ï¼ä½¿ç¨è¯¦è§? User Guideã
æ´ä¸ªTransmittableThreadLocal
åºçæ ¸å¿åè½ï¼ç¨æ·API
䏿¡æ¶/ä¸é´ä»¶çéæ?API
ã?çº¿ç¨æ± ExecutorService
/ForkJoinPool
/TimerTask
å?å
¶çº¿ç¨å·¥åçWrapper
ï¼ï¼å?ªæ ~1000 SLOC
代ç ?è¡ï¼é?常精å°?ã
欢è¿
- 建议åæ??é®ï¼æ??交 Issue
- è´¡ç®åæ¹è¿ï¼Fork å?æ??éè¿ Pull Request è´¡ç®ä»£ç ?
ð¨ éæ±åºæ¯
ThreadLocal
çéæ±åºæ¯å?³TransmittableThreadLocal
çæ½å¨éæ±åºæ¯ï¼å¦æä½ çä¸å¡éè¦?ãå¨ä½¿ç¨çº¿ç¨æ± ç伿± åå¤?ç¨çº¿ç¨çæ§è¡ç»ä»¶æ
åµä¸ä¼ éThreadLocal
å¼ã?忝TransmittableThreadLocal
ç®æ åºæ¯ã
ä¸é?¢æ¯å ä¸ªå ¸ååºæ¯ä¾å?ã
- åå¸å¼?è·è¸ªç³»ç» æ å ¨é¾è·¯åæµï¼å?³é¾è·¯ææ ï¼
- æ¥å¿æ¶éè®°å½ç³»ç»ä¸ä¸æ
Session
级Cache
- åºç¨å®¹å¨æä¸å±æ¡æ¶è·¨åºç¨ä»£ç ?ç»ä¸å±
SDK
ä¼ éä¿¡æ?¯
å?ä¸ªåºæ¯çå±å¼è¯´æå?è§?å?ææ¡£ éæ±åºæ¯ã
ð¥ User Guide
使ç¨ç±»TransmittableThreadLocal
æ?¥ä¿?åå¼ï¼å¹¶è·¨çº¿ç¨æ± ä¼ éã
TransmittableThreadLocal
ç»§æ¿InheritableThreadLocal
ï¼ä½¿ç¨æ¹å¼?ä¹ç±»ä¼¼ãç¸æ¯InheritableThreadLocal
ï¼æ·»å äº
copy
æ¹æ³
ç¨äºå®å¶ 任塿??交ç»çº¿ç¨æ± æ¶ çThreadLocal
å¼ä¼ éå° ä»»å¡æ§è¡æ¶ çæ·è´?è¡ä¸ºï¼ç¼ºç?æ¯ç®å?çèµå¼ä¼ éã- 注æ?ï¼å¦æä¼ éçæ¯ä¸ä¸ªå¯¹è±¡ï¼å¼ç¨ç±»åï¼ä¸æ²¡æå?æ·±æ·è´?ï¼å¦ç´æ¥ä¼ éå¼ç¨ææ¯æµ
æ·è´?ï¼é£ä¹
- 跨线ç¨ä¼ éèä¸?å?æçº¿ç¨å°?éï¼ä¼ é对象å¨å¤ä¸ªçº¿ç¨ä¹é´æ¯æå ±äº«çï¼
- ä¸
InheritableThreadLocal.childValue
䏿 ·ï¼ä½¿ç¨è /ä¸å¡é»è¾è¦?注æ?ä¼ é对象ç线ç¨å®å ¨ã
- 注æ?ï¼å¦æä¼ éçæ¯ä¸ä¸ªå¯¹è±¡ï¼å¼ç¨ç±»åï¼ä¸æ²¡æå?æ·±æ·è´?ï¼å¦ç´æ¥ä¼ éå¼ç¨ææ¯æµ
æ·è´?ï¼é£ä¹
protected
çbeforeExecute
/afterExecute
æ¹æ³
æ§è¡ä»»å¡(Runnable
/Callable
)çå?/å?ççå½å¨æåè°ï¼ç¼ºç?æ¯ç©ºæ?ä½ã
å ³äº
copy
æ¹æ³ ç å±å¼è¯´æ
严谨å°è¯´ï¼åºè¯¥æ¯ãä¼ éè¡ä¸ºã?ï¼èä¸?æ¯ãæ·è´?è¡ä¸ºã?ï¼ç¸åºçï¼è¿ä¸ªæ¹æ³åºè¯¥å½å??æ?
transmiteeValue
ï¼ä¸InheritableThreadLocal.childValue
æ¹æ³æä¸è´çå½å??飿 ¼ãä½å¤æ°æ åµä¸ï¼ä¼ éçæ¯ä¸ä¸ªå¤?æ?ç对象ï¼ä¹ æ¯ä¸ä¼å æ³å°çæ¯å¦ä½å?æ·è´?ï¼å¦æ·±æ·è´?ã?æµ æ·è´?ï¼å½å??æ?
copy
å??èæ´å®¹æç?è§£è¿ä¸ªè¿ç¨ä¸è¡ä¸ºäºãð å ³äºæè¯?å?ç¼
er
ä¸ee
ç说æï¼
transmit
æ¯å¨è¯?ä¼ éï¼transmitter
å¨ä½çæ§è¡è /䏻卿¹ï¼ètransmitee
å¨ä½çæ¥æ¶è /è¢«å¨æ¹ãer
ä¸ee
å?ç¼ç常è§?è¯?æ¯employer
ï¼é主ï¼/employee
ï¼éåï¼ã?caller
ï¼è°ç¨è ï¼/callee
ï¼è¢«è°ç¨è ï¼ã
å ·ä½ä½¿ç¨æ¹å¼?è§?ä¸é?¢ç说æã
1. ç®å?使ç¨
ç¶çº¿ç¨ç»å?线ç¨ä¼ éå¼ã
示ä¾ä»£ç ?ï¼
TransmittableThreadLocal<String> context = new TransmittableThreadLocal<>();
// =====================================================
// å¨ç¶çº¿ç¨ä¸è®¾ç½®
context.set("value-set-in-parent");
// =====================================================
// å¨å?线ç¨ä¸å?¯ä»¥è¯»å?ï¼å¼æ¯"value-set-in-parent"
String value = context.get();
# 宿´å?¯è¿?è¡çDemo代ç ?å?è§?SimpleDemo.kt
ã
è¿å
¶å®æ¯InheritableThreadLocal
çåè½ï¼åºè¯¥ä½¿ç¨InheritableThreadLocal
æ?¥å®æ?ã
ä½å¯¹äºä½¿ç¨çº¿ç¨æ± ç伿± åå¤?ç¨çº¿ç¨çæ§è¡ç»ä»¶çæ
åµï¼çº¿ç¨ç±çº¿ç¨æ± å建好ï¼å¹¶ä¸çº¿ç¨æ¯æ± åèµ·æ?¥å??å¤?使ç¨çï¼è¿æ¶ç¶å?线ç¨å
³ç³»çThreadLocal
å¼ä¼ éå·²ç»?没ææ?ä¹ï¼åºç¨éè¦?çå®é
䏿¯æ 任塿??交ç»çº¿ç¨æ± æ¶çThreadLocal
å¼ä¼ éå° ä»»å¡æ§è¡æ¶ã
è§£å³æ¹æ³å?è§?ä¸é?¢çè¿å ç§?ç¨æ³ã
2. ä¿?è¯?çº¿ç¨æ± ä¸ä¼ éå¼
Runnable
åCallable
2.1 修饰使ç¨TtlRunnable
åTtlCallable
æ?¥ä¿®é¥°ä¼ å
¥çº¿ç¨æ± çRunnable
åCallable
ã
示ä¾ä»£ç ?ï¼
TransmittableThreadLocal<String> context = new TransmittableThreadLocal<>();
// =====================================================
// å¨ç¶çº¿ç¨ä¸è®¾ç½®
context.set("value-set-in-parent");
Runnable task = new RunnableTask();
// é¢?å¤çå¤ç?ï¼çæ?修饰äºç对象ttlRunnable
Runnable ttlRunnable = TtlRunnable.get(task);
executorService.submit(ttlRunnable);
// =====================================================
// Taskä¸å?¯ä»¥è¯»å?ï¼å¼æ¯"value-set-in-parent"
String value = context.get();
注æ?ï¼
å?³ä½¿æ¯å?ä¸ä¸ªRunnable
ä»»å¡å¤æ¬¡æ??交å°çº¿ç¨æ± æ¶ï¼æ¯?次æ??交æ¶é½éè¦?éè¿ä¿®é¥°æ?ä½ï¼å?³TtlRunnable.get(task)
ï¼ä»¥æå?è¿æ¬¡æ??交æ¶çTransmittableThreadLocal
ä¸ä¸æçå¼ï¼å?³å¦æå?ä¸ä¸ªä»»å¡ä¸ä¸æ¬¡æ??交æ¶ä¸?æ§è¡ä¿®é¥°èä»?ç¶ä½¿ç¨ä¸ä¸æ¬¡çTtlRunnable
ï¼åæ??交çä»»å¡è¿?è¡æ¶ä¼æ¯ä¹å?修饰æ?使æå?çä¸ä¸æã示ä¾ä»£ç ?å¦ä¸ï¼
// ç¬¬ä¸æ¬¡æ??交
Runnable task = new RunnableTask();
executorService.submit(TtlRunnable.get(task));
// ...ä¸å¡é»è¾ä»£ç ?ï¼
// å¹¶ä¸ä¿®æ¹äº TransmittableThreadLocalä¸ä¸æ ...
// context.set("value-modified-in-parent");
// å?次æ??交
// é?æ°æ§è¡ä¿®é¥°ï¼ä»¥ä¼ éä¿®æ¹äºç TransmittableThreadLocalä¸ä¸æ
executorService.submit(TtlRunnable.get(task));
ä¸é?¢æ¼ç¤ºäºRunnable
ï¼Callable
çå¤ç?类似
TransmittableThreadLocal<String> context = new TransmittableThreadLocal<>();
// =====================================================
// å¨ç¶çº¿ç¨ä¸è®¾ç½®
context.set("value-set-in-parent");
Callable call = new CallableTask();
// é¢?å¤çå¤ç?ï¼çæ?修饰äºç对象ttlCallable
Callable ttlCallable = TtlCallable.get(call);
executorService.submit(ttlCallable);
// =====================================================
// Callä¸å?¯ä»¥è¯»å?ï¼å¼æ¯"value-set-in-parent"
String value = context.get();
# 宿´å?¯è¿?è¡çDemo代ç ?å?è§?TtlWrapperDemo.kt
ã
æ´ä¸ªè¿ç¨ç宿´æ¶åº?å¾
2.2 ä¿®é¥°çº¿ç¨æ±
ç?廿¯?次Runnable
åCallable
ä¼ å
¥çº¿ç¨æ± æ¶ç修饰ï¼è¿ä¸ªé»è¾å?¯ä»¥å¨çº¿ç¨æ± ä¸å®æ?ã
éè¿å·¥å
·ç±»com.alibaba.ttl.threadpool.TtlExecutors
宿?ï¼æä¸é?¢çæ¹æ³ï¼
getTtlExecutor
ï¼ä¿®é¥°æ¥å?£Executor
getTtlExecutorService
ï¼ä¿®é¥°æ¥å?£ExecutorService
getTtlScheduledExecutorService
ï¼ä¿®é¥°æ¥å?£ScheduledExecutorService
示ä¾ä»£ç ?ï¼
ExecutorService executorService = ...
// é¢?å¤çå¤ç?ï¼çæ?修饰äºç对象executorService
executorService = TtlExecutors.getTtlExecutorService(executorService);
TransmittableThreadLocal<String> context = new TransmittableThreadLocal<>();
// =====================================================
// å¨ç¶çº¿ç¨ä¸è®¾ç½®
context.set("value-set-in-parent");
Runnable task = new RunnableTask();
Callable call = new CallableTask();
executorService.submit(task);
executorService.submit(call);
// =====================================================
// Taskææ¯Callä¸å?¯ä»¥è¯»å?ï¼å¼æ¯"value-set-in-parent"
String value = context.get();
# 宿´å?¯è¿?è¡çDemo代ç ?å?è§?TtlExecutorWrapperDemo.kt
ã
Java Agent
�修饰JDK
çº¿ç¨æ± å®ç°ç±»
2.3 使ç¨è¿ç§?æ¹å¼?ï¼å®ç°çº¿ç¨æ± çä¼ éæ¯é?æçï¼ä¸å¡ä»£ç ?䏿²¡æä¿®é¥°Runnable
ææ¯çº¿ç¨æ± ç代ç ?ãå?³å?¯ä»¥å?å°åºç¨ä»£ç ? æ ä¾µå
¥ã
# å
³äº æ ä¾µå
¥ çæ´å¤è¯´æå?è§?ææ¡£Java Agent
æ¹å¼?对åºç¨ä»£ç ?æ ä¾µå
¥ã
示ä¾ä»£ç ?ï¼
// ## 1. æ¡æ¶ä¸å±é»è¾ï¼å?ç»æµ?ç¨æ¡æ¶è°ç¨ä¸å¡ ##
TransmittableThreadLocal<String> context = new TransmittableThreadLocal<>();
context.set("value-set-in-parent");
// ## 2. åºç¨é»è¾ï¼å?ç»æµ?ç¨ä¸å¡è°ç¨æ¡æ¶ä¸å±é»è¾ ##
ExecutorService executorService = Executors.newFixedThreadPool(3);
Runnable task = new RunnableTask();
Callable call = new CallableTask();
executorService.submit(task);
executorService.submit(call);
// ## 3. æ¡æ¶ä¸å±é»è¾ ##
// Taskææ¯Callä¸å?¯ä»¥è¯»å?ï¼å¼æ¯"value-set-in-parent"
String value = context.get();
Demoå?è§?AgentDemo.kt
ãæ§è¡å·¥ç¨ä¸çèæ¬scripts/run-agent-demo.sh
å?³å?¯è¿?è¡Demoã
ç®å?TTL Agent
ä¸ï¼ä¿®é¥°äºçJDK
æ§è¡å¨ç»ä»¶ï¼å?³å¦çº¿ç¨æ± ï¼å¦ä¸ï¼
java.util.concurrent.ThreadPoolExecutor
åjava.util.concurrent.ScheduledThreadPoolExecutor
- 修饰å®ç°ä»£ç ?å¨
JdkExecutorTtlTransformlet.java
ã
- 修饰å®ç°ä»£ç ?å¨
java.util.concurrent.ForkJoinTask
ï¼å¯¹åºçæ§è¡å¨ç»ä»¶æ¯java.util.concurrent.ForkJoinPool
ï¼- 修饰å®ç°ä»£ç ?å¨
ForkJoinTtlTransformlet.java
ãä»çæ¬2.5.1
å¼å§æ¯æ?ã - 注æ?ï¼
Java 8
å¼å ¥çCompletableFuture
ä¸ï¼å¹¶è¡æ§è¡çï¼Stream
åºå±æ¯éè¿ForkJoinPool
æ?¥æ§è¡ï¼æä»¥æ¯æ?ForkJoinPool
å?ï¼TTL
ä¹å°±é?ææ¯æ?äºCompletableFuture
ä¸Stream
ãð
- 修饰å®ç°ä»£ç ?å¨
java.util.TimerTask
çå?ç±»ï¼å¯¹åºçæ§è¡å¨ç»ä»¶æ¯java.util.Timer
ï¼- 修饰å®ç°ä»£ç ?å¨
TimerTaskTtlTransformlet.java
ãä»çæ¬2.7.0
å¼å§æ¯æ?ã - 注æ?ï¼ä»
2.11.2
çæ¬å¼å§ç¼ºç?å¼å?¯TimerTask
ç修饰ï¼å 为ä¿?è¯?æ£ç¡®æ§æ¯ç¬¬ä¸ä½?ï¼èä¸?æ¯æä½³å®è·µãä¸?æ¨è??使ç¨TimerTask
ã?:ï¼ï¼2.11.1
çæ¬å?å ¶ä¹å?ççæ¬æ²¡æç¼ºç?å¼å?¯TimerTask
ç修饰ã - 使ç¨
Agent
å?æ°ttl.agent.enable.timer.task
å¼å?¯/å ³éTimerTask
ç修饰ï¼-javaagent:path/to/transmittable-thread-local-2.x.y.jar=ttl.agent.enable.timer.task:true
-javaagent:path/to/transmittable-thread-local-2.x.y.jar=ttl.agent.enable.timer.task:false
- æ´å¤å
³äº
TTL Agent
å?æ°çé ?置说æè¯¦è§?TtlAgent.java
çJavaDocã
- 修饰å®ç°ä»£ç ?å¨
å ³äº
java.util.TimerTask
/java.util.Timer
ç å±å¼è¯´æ
Timer
æ¯JDK 1.3
çè?ç±»ï¼ä¸?æ¨è??使ç¨Timer
ç±»ãæ¨è??ç¨
ScheduledExecutorService
ã
ScheduledThreadPoolExecutor
å®ç°æ´å¼ºå£®ï¼å¹¶ä¸åè½æ´ä¸°å¯ã 妿¯æ?é ?ç½®çº¿ç¨æ± ç大å°?ï¼Timer
å?ªæä¸ä¸ªçº¿ç¨ï¼ï¼Timer
å¨Runnable
䏿åºå¼å¸¸ä¼ä¸æ¢å®æ¶æ§è¡ãæ´å¤è¯´æå?è§? 10. Mandatory Run multiple TimeTask by using ScheduledExecutorService rather than Timer because Timer will kill all running threads in case of failing to catch exceptions. - Alibaba Java Coding Guidelinesã
Java Agent
çå?¯å¨å?æ°é
?ç½®
å¨Java
çå?¯å¨å?æ°å ä¸ï¼-javaagent:path/to/transmittable-thread-local-2.x.y.jar
ã
注æ?ï¼
- å¦æä¿®æ¹äºä¸è½½ç
TTL
çJar
çæä»¶å??ï¼transmittable-thread-local-2.x.y.jar
ï¼ï¼åéè¦?èªå·±æå¨éè¿-Xbootclasspath JVM
å?æ°æ?¥æ¾å¼?é ?ç½®ã
æ¯å¦ä¿®æ¹æä»¶å??æ?ttl-foo-name-changed.jar
ï¼åè¿éè¦?å ä¸Java
çå?¯å¨å?æ°ï¼-Xbootclasspath/a:path/to/ttl-foo-name-changed.jar
ã - æä½¿ç¨
v2.6.0
ä¹å?ççæ¬ï¼å¦v2.5.1
ï¼ï¼åä¹éè¦?èªå·±æå¨éè¿-Xbootclasspath JVM
å?æ°æ?¥æ¾å¼?é ?ç½®ï¼å°±å?TTL
ä¹å?ççæ¬çå?æ³ä¸æ ·ï¼ã
å ä¸Java
çå?¯å¨å?æ°ï¼-Xbootclasspath/a:path/to/transmittable-thread-local-2.5.1.jar
ã
Java
å½ä»¤è¡ç¤ºä¾å¦ä¸ï¼
java -javaagent:path/to/transmittable-thread-local-2.x.y.jar \
-cp classes \
com.alibaba.demo.ttl.agent.AgentDemo
# å¦æä¿®æ¹äºTTL jaræä»¶å?? æ TTLçæ¬æ¯ 2.6.0 ä¹å?
# åè¿éè¦?æ¾å¼?设置 -Xbootclasspath å?æ°
java -javaagent:path/to/ttl-foo-name-changed.jar \
-Xbootclasspath/a:path/to/ttl-foo-name-changed.jar \
-cp classes \
com.alibaba.demo.ttl.agent.AgentDemo
java -javaagent:path/to/transmittable-thread-local-2.5.1.jar \
-Xbootclasspath/a:path/to/transmittable-thread-local-2.5.1.jar \
-cp classes \
com.alibaba.demo.ttl.agent.AgentDemo
å ³äº
boot class path
ç å±å¼è¯´æ
å 为修饰äº
JDK
æ ååºçç±»ï¼æ ååºç±bootstrap class loader
å è½½ï¼ä¿®é¥°å?çJDK
ç±»å¼ç¨äºTTL
ç代ç ?ï¼æä»¥Java Agent
ä½¿ç¨æ¹å¼?ä¸TTL Jar
æä»¶éè¦?é ?ç½®å°boot class path
ä¸ã
TTL
ä»v2.6.0
å¼å§ï¼å è½½TTL Agent
æ¶ä¼èªå¨è®¾ç½®TTL Jar
å°boot class path
ä¸ã
注æ?ï¼ä¸?è½ä¿®æ¹ä»Maven
åºä¸è½½çTTL Jar
æä»¶å??ï¼å½¢å¦transmittable-thread-local-2.x.y.jar
ï¼ã å¦æä¿®æ¹äºï¼åéè¦?èªå·±æå¨éè¿-Xbootclasspath JVM
å?æ°æ?¥æ¾å¼?é ?ç½®ï¼å°±å?TTL
ä¹å?ççæ¬çå?æ³ä¸æ ·ï¼ãèªå¨è®¾ç½®
TTL Jar
å°boot class path
çå®ç°æ¯éè¿æå®TTL Java Agent Jar
æä»¶émanifest
æä»¶ï¼META-INF/MANIFEST.MF
ï¼çBoot-Class-Path
屿§ï¼
Boot-Class-Path
A list of paths to be searched by the bootstrap class loader. Paths represent directories or libraries (commonly referred to as JAR or zip libraries on many platforms). These paths are searched by the bootstrap class loader after the platform specific mechanisms of locating a class have failed. Paths are searched in the order listed.
æ´å¤è¯¦è§?
ð Java API Docs
å½å?çæ¬çJava APIææ¡£å°å?ï¼ https://alibaba.github.io/transmittable-thread-local/apidocs/
ð?ª Mavenä¾?èµ
示ä¾ï¼
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>2.12.6</version>
</dependency>
å?¯ä»¥å¨ search.maven.org æ¥çå?¯ç¨ççæ¬ã
ð¨ å
³äºç¼è¯æå»ºä¸IDE
å¼å?
ç¼è¯æå»ºçç¯å¢è¦?æ±ï¼ JDK 8~11
ï¼ç¨Maven
常è§çæ¹å¼?æ§è¡ç¼è¯æå»ºå?³å?¯ï¼
# å¨å·¥ç¨ä¸å·²ç»?å
å?«äºç¬¦å?çæ¬è¦?æ±çMaven
ï¼ç´æ¥è¿?è¡ å·¥ç¨æ ¹ç®å½ä¸çmvnw
ï¼å¹¶ä¸?éè¦?å
æå¨èªå·±å®è£
好Maven
ã
# è¿?è¡æµè¯Case
./mvnw test
# ç¼è¯æå
./mvnw package
# è¿?è¡æµè¯Caseã?ç¼è¯æå
ã?å®è£
TTLåºå°Mavenæ¬å°
./mvnw install
#####################################################
# å¦æä½¿ç¨ä½ èªå·±å®è£
ç mavenï¼çæ¬è¦?æ±ï¼maven 3.3.9+
mvn install
å¦ä½ç¨IDE
æ?¥å¼å?æ¶æ³¨æ?ç¹ï¼æ´å¤è¯´æå?è§? ææ¡£ å¦ä½ç¨IDE
å¼å? - Developer Guideã
â? FAQ
Q1. TTL Agent
ä¸å
¶å®Agent
ï¼å¦Skywalking
ã?Promethues
ï¼é
?å?ä½¿ç¨æ¶ä¸?çæï¼
é
?ç½®TTL Agent
卿å?çä½?ç½®ï¼å?¯ä»¥é?¿å
?ä¸å
¶å®å
¶å®Agent
é
?å?ä½¿ç¨æ¶ï¼TTL Agent
å?¯è½çä¸?çæé®é¢ãé
?置示ä¾ï¼
java -javaagent:path/to/transmittable-thread-local-2.x.y.jar \
-javaagent:path/to/skywalking-agent.jar \
-jar your-app.jar
åå æ¯ï¼
- å?
Skywalking
è¿æ ·çAgent
çå ¥å?£é»è¾ï¼premain
ï¼å å?«äºçº¿ç¨æ± çå?¯å¨ã - 妿é
?ç½®å¨è¿æ ·ç
Agent
é ?ç½®å¨å?é?¢ï¼å°äºTTL Agent
ï¼çpremain
ï¼æ¶ï¼TTL
éè¦?å 强ççº¿ç¨æ± 类已ç»?å è½½ï¼load
ï¼äºã TTL Agent
çTtlTransformer
æ¯å¨ç±»å è½½æ¶è§¦å?ç±»çå¢å¼ºï¼å¦æç±»å·²ç»?å è½½äºä¼è·³è¿TTL Agent
çå¢å¼ºé»è¾ã
æ´å¤è®¨è®ºå?è§? Issueï¼TTL agent
ä¸å
¶ä»Agent
çå
¼å®¹æ§é®é¢ #226ã
Q2. MacOS
ä¸ï¼ä½¿ç¨Java Agent
ï¼å?¯è½ä¼æ¥JavaLaunchHelper
çåºéä¿¡æ?¯
JDK Bug: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8021205
å?¯ä»¥æ?¢ä¸ä¸ªçæ¬çJDK
ãæçå¼å?æºä¸1.7.0_40
æè¿ä¸ªé®é¢ï¼1.6.0_51
ã?1.7.0_45
å?¯ä»¥è¿?è¡ã
# 1.7.0_45
è¿æ¯æJavaLaunchHelper
çåºéä¿¡æ?¯ï¼ä½ä¸?å½±å?è¿?è¡ã
⨠使ç¨TTL
ç好å¤ä¸å¿
è¦?æ§
注ï¼ä¸?读è¿ä¸èï¼å¹¶ä¸?ä¼å½±å?ä½ ä½¿ç¨
TTL
æ?¥è§£å³ä½ 碰å°çé®é¢ï¼å?¯ä»¥æ¾å¿è·³è¿ï¼è¯»äº User Guide å°±å?¯ä»¥å¿«éç¨èµ·æ?¥äºï½ð è¿ä¸èä¿¡æ?¯å¯åº¦è¾é«ä¸?æè¯»ã
好å¤ï¼é?æä¸èªå¨å®æ?ææå¼æ¥æ§è¡ä¸ä¸æçå?¯å®å¶ã?è§èåçæ?æ?ä¸ä¼ éã
è¿ä¸ªå¥½å¤ä¹æ¯TransmittableThreadLocal
çç®æ ã
å¿ è¦?æ§ï¼é?ç?åºç¨çåå¸å¼?å¾®æ?å¡å并使ç¨å?ç§?ä¸é´ä»¶ï¼è¶æ?¥è¶å¤çåè½ä¸ç»ä»¶ä¼æ¶å?ä¸?å?çä¸ä¸æï¼é»è¾æµ?ç¨ä¹è¶æ?¥è¶é¿ï¼ä¸ä¸æé®é¢å®é 䏿¯ä¸ªå¤§çæéçæ¶æé®é¢ï¼éè¦?ç»ä¸ç对ä¸å¡é?æçè§£å³æ¹æ¡ã
使ç¨ThreadLocal
ä½ä¸ºä¸å¡ä¸ä¸æä¼ éçç»?å
¸ææ¯ææ®µå¨ä¸é´ä»¶ã?ææ¯ä¸ä¸å¡æ¡æ¶ä¸å¹¿æ³å¤§é?使ç¨ãè对äºç产åºç¨ï¼å ä¹ä¸å®ä¼ä½¿ç¨çº¿ç¨æ± ç弿¥æ§è¡ç»ä»¶ï¼ä»¥é«ææ¯æçº¿ä¸å¤§æµ?é?ãä½ä½¿ç¨ThreadLocal
å?å
¶set/remove
çä¸ä¸æä¼ 鿍¡å¼?ï¼å¨ä½¿ç¨çº¿ç¨æ± ç弿¥æ§è¡ç»ä»¶æ¶ï¼åå¨å¤æ¹é?¢çé®é¢ï¼
1. ä»ä¸å¡ä½¿ç¨è è§åº¦æ?¥ç
- ç¹?ç??
- ä¸å¡é»è¾è¦?ç¥é?ï¼æåªäºä¸ä¸æï¼å?个ä¸ä¸ææ¯å¦ä½è·å?çã
- å¹¶éè¦?ä¸å¡é»è¾å»ä¸ä¸ªä¸ä¸ªå°æ?æ?ä¸ä¼ éã
- ä¾?èµ
- éè¦?ç´æ¥ä¾?èµä¸?å?
ThreadLocal
ä¸ä¸æå?èªçè·å?çé»è¾æç±»ã - å?
RPC
çä¸ä¸æï¼å¦Dubbo
çRpcContext
ï¼ã?å ¨é¾è·¯è·è¸ªçä¸ä¸æï¼å¦SkyWalking
çContextManager
ï¼ã?ä¸?å?ä¸å¡æ¨¡å?ä¸çä¸å¡æµ?ç¨ä¸ä¸æï¼ççã
- éè¦?ç´æ¥ä¾?èµä¸?å?
- é?æ?ï¼ææ¼?ï¼
- å 为è¦? äºå ç¥é?æåªäºä¸ä¸æï¼å¦æç³»ç»åºç°äºä¸ä¸ªæ°çä¸ä¸æï¼ä¸å¡é»è¾å°±è¦?ä¿®æ¹æ·»å 䏿°ä¸ä¸æä¼ éçå è¡ä»£ç ?ãä¹å°±æ¯è¯´å ç³»ç»ç ä¸ä¸ææ°å¢ï¼ä¸å¡ç é»è¾å°±è·è¿è¦?ä¿®æ¹ã
- è对äºä¸å¡æ?¥è¯´ï¼ä¸?å ³å¿ç³»ç»çä¸ä¸æï¼å?³å¾å¾å°±å?¯è½é?æ¼?ï¼ä¼æ¯çº¿ä¸æ éäºã
- é?ç?åºç¨çåå¸å¼?å¾®æ?å¡å并使ç¨å?ç§?ä¸é´ä»¶ï¼è¶æ?¥è¶å¤çåè½ä¸ç»ä»¶ä¼æ¶å?ä¸?å?çä¸ä¸æï¼é»è¾æµ?ç¨ä¹è¶æ?¥è¶é¿ï¼ä¸ä¸æé®é¢å®é 䏿¯ä¸ªå¤§çæéçæ¶æé®é¢ï¼éè¦?ç»ä¸ç对ä¸å¡é?æçè§£å³æ¹æ¡ã
- å®å¶æ§
- å 为éè¦?ä¸å¡é»è¾æ?¥å®æ?æ?æ?ä¸ä¼ éï¼ä¸å¡è¦?å ³æ³¨ãä¸ä¸æçä¼ éæ¹å¼?ã?ï¼ç´æ¥ä¼ å¼ç¨ï¼è¿æ¯æ·è´?ä¼ å¼ï¼æ·è´?æ¯æ·±æ·è´?è¿æ¯æµ æ·è´?ï¼å¨ä¸?å?çä¸ä¸æä¼éè¦?ä¸?å?çå?æ³ã
- ãä¸ä¸æçä¼ éæ¹å¼?ã?å¾å¾æ¯ ä¸ä¸æçæ??ä¾è ï¼æè¯´æ¯ä¸å¡é»è¾çæ¡æ¶é¨åï¼æ?è½å³çå¤ç?好çï¼è ä¸ä¸æç使ç¨è ï¼æè¯´æ¯ä¸å¡é»è¾çåºç¨é¨åï¼å¾å¾ä¸?ï¼ææï¼ç¥é?ä¸ä¸æçä¼ éæ¹å¼?ãè¿ä¹å?¯ä»¥ç?è§£æ?æ¯ ä¾?èµï¼å?³ä¸å¡é»è¾ ä¾?èµ/å ³æ³¨/å®ç°äº ç³»ç»/æ¶æçãä¸ä¸æçä¼ éæ¹å¼?ã?ã
2. 仿´ä½æµ?ç¨å®ç°è§åº¦æ?¥ç
å ³æ³¨çæ¯ ä¸ä¸æä¼ éæµ?ç¨çè§èåãä¸ä¸æä¼ éå°äºå?线ç¨è¦?å?好 æ¸ ç?ï¼ææ´åç¡®å°è¯´æ¯è¦? æ?¢å¤? æ?ä¹å?çä¸ä¸æï¼ï¼éè¦?ä¸å¡é»è¾å»å¤ç?好ã妿ä¸å¡é»è¾å¯¹æ¸ ç?çå¤ç?ä¸?æ£ç¡®ï¼æ¯å¦ï¼
- 妿æ¸
ç?æ?使¼?äºï¼
- ä¸ä¸æ¬¡æ§è¡å?¯è½æ¯ä¸æ¬¡çï¼å?³ãä¸ä¸æç 污æ/串å?·ã?ï¼ä¼å¯¼è´ä¸å¡é»è¾é误ã
- ãä¸ä¸æç æ³æ¼?ã?ï¼ä¼å¯¼è´å åæ³æ¼?é®é¢ã
- å¦ææ¸ ç?æ?ä½å?å¤äºï¼ä¼åºç°ä¸ä¸æ 丢失ã
ä¸é?¢çé®é¢ï¼å¨ä¸å¡å¼å?ä¸å¼å?çBug
çæ¯å±¡è§?ä¸?é² ï¼?æ¬è´¨åå æ¯ï¼ThreadLocal
çset/remove
çä¸ä¸æä¼ 鿍¡å¼? å¨ä½¿ç¨çº¿ç¨æ± ç弿¥æ§è¡ç»ä»¶çæ
åµä¸ä¸?å?æ¯ææçã常è§?çå
¸åä¾å?ï¼
- å½çº¿ç¨æ± 满äºä¸çº¿ç¨æ± ç
RejectedExecutionHandler
使ç¨çæ¯CallerRunsPolicy
æ¶ï¼æ??交å°çº¿ç¨æ± çä»»å¡ä¼å¨æ??交线ç¨ä¸ç´æ¥æ§è¡ï¼ThreadLocal.remove
æ?使¸ ç?æ??交线ç¨çä¸ä¸æå¯¼è´ä¸ä¸æä¸¢å¤±ã - 类似çï¼ä½¿ç¨
ForkJoinPool
ï¼å å?«å¹¶è¡æ§è¡Stream
ä¸CompletableFuture
ï¼åºå±ä½¿ç¨ForkJoinPool
ï¼çåºæ¯ï¼å±å¼çForkJoinTask
ä¼å¨ä»»å¡æ??交线ç¨ä¸ç´æ¥æ§è¡ãå?æ ·å¯¼è´ä¸ä¸æä¸¢å¤±ã
æä¹è®¾è®¡ä¸ä¸ªãä¸ä¸æä¼ éæµ?ç¨ã?æ¹æ¡ï¼å?³ä¸ä¸æççå½å¨æï¼ï¼ä»¥ä¿?è¯?没æä¸é?¢çé®é¢ï¼
ææï¼ä¸ä¸æçå½å¨æçæ?ä½ä»ä¸å¡é»è¾ä¸åç¦»åºæ?¥ãä¸å¡é»è¾ä¸?æ¶å?çå½å¨æï¼å°±ä¸?伿ä¸å¡ä»£ç ?å¦ç?忽æ¸
ç?èå¼å?çé®é¢äºãæ´ä¸ªä¸ä¸æçä¼ éæµ?ç¨æè¯´çå½å¨æå?¯ä»¥è§èåæ?ï¼æ?æ?ã?åæ¾åæ?¢å¤?è¿3个æ?ä½ï¼å?³CRR(capture/replay/restore)
模å¼?ãæ´å¤è®¨è®ºå?è§? Issueï¼è½å¨è¯¦ç»è®²è§£ä¸ä¸replay
ã?restore
ç设计ç?念å?ï¼#201ã
æ»ç»ä¸é?¢ç说æï¼å¨ç产åºç¨ï¼å ä¹ä¸å®ä¼ä½¿ç¨çº¿ç¨æ± ç弿¥æ§è¡ç»ä»¶ï¼ä¸ï¼ä½¿ç¨ThreadLocal
å?å
¶set/remove
çä¸ä¸æä¼ 鿍¡å¼?å ä¹ä¸å®æ¯æé®é¢çï¼å?ªæ¯å¨çä¸ä¸ªåºBug
çæºä¼ã
æ´å¤TTL
好å¤ä¸å¿
è¦?æ§çå±å¼è®¨è®ºå?è§? Issueï¼è¿ä¸ªåºå¸¦æ?¥ææ ·ç好å¤åä¼å¿ï¼ #128ï¼æ¬¢è¿ç»§ç»è®¨è®º
ð¿ æ´å¤ææ¡£
ð¨ éæ±åºæ¯è¯´æâ?¤ï¸? å°?ä¼ä¼´å?å¦ä»¬åçTTL
使ç¨åºæ¯ ä¸ è®¾è®¡å®ç°è§£æ?çæç« ï¼åå¾é½å¾å¥½ï¼?ï¼ - Issue #123ð Developer Guideâ æ§è½æµè¯
ð ç¸å
³èµæ
JDK Core Classes
ð? Who used
使ç¨äºTTL
çä¸é¨å弿º?项ç®ï¼
- ä¸é´ä»¶
sofastack/sofa-rpc
SOFARPC is a high-performance, high-extensibility, production-level Java RPC frameworkdromara/hmily
Distributed transaction solutionsacmenlt/dynamic-threadpool
强大ç卿?çº¿ç¨æ± ï¼éå¸¦çæ§æ¥è¦åè½ï¼æ²¡æä¾?èµä¸é´ä»¶ï¼ï¼å®å ¨é?µå¾ªé¿éå·´å·´ç¼ç ?è§èlyh200/dynamic-tp
è½»é?çº§å¨æ?çº¿ç¨æ± ï¼å ç½®çæ§åè¦åè½ï¼æ¯æ?çº¿ç¨æ± ä¸ä¸æä¼ éï¼åºäºä¸»æµ?é ?ç½®ä¸å¿ï¼å·²æ¯æ?Nacosã?Apolloï¼Zookeeperï¼å?¯éè¿SPIèªå®ä¹å®ç°ï¼siaorg/sia-gateway
å¾®æ?å¡è·¯ç±ç½å ³ï¼zuul-plusï¼ZTO-Express/zms
ZTO Message Servicetuya/connector
The connector framework maps cloud APIs to local APIs based on simple configurations and flexible extension mechanisms.
- ä¸é´ä»¶/æ°æ?®
ppdaicorp/das
æ°æ?®åºè®¿é®æ¡æ¶(data access service)ï¼å æ¬æ°æ?®åºæ§å¶å?°das consoleï¼æ°æ?®åºå®¢æ·ç«¯das clientåæ°æ?®åºæ?å¡ç«¯das serverä¸é¨åSimonAlong/Neo
Ormæ¡æ¶ï¼åºäºActiveRecordæ?æ³å¼å?çè³ç®åä¸åè½å¾å ¨çOrmæ¡æ¶didi/ALITA
a layer-based data analysis tooldidi/daedalus
å®ç°å¿«éåå»ºæ°æ?®æé æµ?ç¨ï¼æ°æ?®æé æµ?ç¨çå?¯è§åã?线ä¸åã?æ?ä¹ åã?æ ååaiwenmo/DataLink
a new open source solution to bring Flink development to data center
- ä¸é´ä»¶/æµ?ç¨å¼æ
dromara/liteflow
a lightweight and practical micro-process frameworkalibaba/bulbasaur
A pluggable, scalable process engine
- ä¸é´ä»¶/æ¥å¿
dromara/TLog
Lightweight distributed log label tracking frameworkfayechenlong/plumelog
ä¸ä¸ªjavaåå¸å¼?æ¥å¿ç»ä»¶ï¼æ¯æ?ç¾äº¿çº§å«minbox-projects/minbox-logging
åå¸å¼?é¶ä¾µå ¥å¼?ã?é¾è·¯å¼?è¯·æ±æ¥å¿åæ?æ¡æ¶ãæ??ä¾Admin端ç¹è¿è¡é鿥å¿ã?åæ?æ¥å¿ã?æ¥å¿åè¦éç¥ã?æ?塿§è½åæ?çãéè¿Admin Uiå?¯æ¥ç宿¶é¾è·¯æ¥å¿ä¿¡æ?¯ã?å¨çº¿ä¸å¡æ?å¡å表minbox-projects/api-boot
为æ¥å?£æ?å¡èççï¼åºäºâ SpringBootâ?宿?æ©å±åèªå¨é ?ç½®ï¼å é¨å°?è£ äºä¸ç³»åçå¼ç®±å?³ç¨Starters
ofpay/logback-mdc-ttl
logbackæ©å±ï¼éæ?transmittable-thread-localæ¯æ?è·¨çº¿ç¨æ± çmdcè·è¸ªoldratlee/log4j2-ttl-thread-context-map
Log4j2 TTL ThreadContextMap, Log4j2 extension integrated TransmittableThreadLocal to MDC
- ä¸é´ä»¶/åèç ?
ymm-tech/easy-byte-coder
Easy-byte-coder is a non-invasive bytecode injection framework based on JVM
- ä¸å¡æ?塿平å?°åºç¨
OpenBankProject/OBP-API
An open source RESTful API platform for banks that supports Open Banking, XS2A and PSD2 through access to accounts, transactions, counterparties, payments, entitlements and metadata - plus a host of internal banking and management APIsJoolun/JooLun-wx
JooLun微信ååyangzongzhuan/RuoYi-Cloud
åºäºSpring Bootã?Spring Cloud & Alibabaçåå¸å¼?å¾®æ?塿¶ææ?é?管ç?ç³»ç»somowhere/albedo
åºäº Spring Boot ã?Spring Securityã?Mybatis çRBACæ?é?管ç?ç³»ç»tengshe789/SpringCloud-miaosha
ä¸ä¸ªåºäºspring cloud Greenwichçç®å?ç§æ?çµå?åå项ç®
- å·¥å
·äº§å?
ssssssss-team/spider-flow
æ°ä¸ä»£ç¬è«å¹³å?°ï¼ä»¥å¾å½¢åæ¹å¼?å®ä¹ç¬è«æµ?ç¨ï¼ä¸?å代ç ?å?³å?¯å®æ?ç¬è«nekolr/slime
ð?° ä¸ä¸ªå?¯è§åçç¬è«å¹³å?°zjcscut/octopus
é¿é¾æ¥å缩为ç龿¥çæ?å¡xggz/mqr
èèQQæºå¨äººï¼ç®ç§°MQRï¼ï¼éç¨miraiçAndroidå??è®®å®ç°çQQæºå¨äººæ?å¡ï¼éè¿webæ§å¶æºå¨äººçå?¯å?åé ?ç½®
- æµè¯è§£å³æ¹æ¡æå·¥å
·
alibaba/jvm-sandbox-repeater
A Java server-side recording and playback solution based on JVM-Sandbox, å½å¶/åæ¾éç¨è§£å³æ¹æ¡alibaba/testable-mock
æ?¢ç§?æ?è·¯åMockï¼è®©å?å æµè¯æ´ç®å?shulieTech/Takin
å ¨é¾è·¯åæµå¹³å?°ï¼measure online environmental performance test for full-links, Especially for microservicesshulieTech/LinkAgent
a Java-based open-source agent designed to collect data and control Functions for Java applications through JVM bytecode, without modifying applications codes
alibaba/virtual-environment
Route isolation with service sharing, é¿éæµè¯ç¯å¢æ?å¡é离åè?è°æºå¶çKubernetes
çå®ç°
Spring Cloud
/Spring Boot
çæ¡æ¶æ¹æ¡/èææ¶zlt2000/microservices-platform
åºäºSpringBoot2.xã?SpringCloudåSpringCloudAlibabaå¹¶éç¨å?å?端å离çä¼?ä¸çº§å¾®æ?å¡å¤ç§æ·ç³»ç»æ¶æzuihou/lamp-cloud
åºäºJdk11 + SpringCloud + SpringBoot çå¾®æ?å¡å¿«éå¼å?å¹³å?°ï¼å ¶ä¸çå?¯é ?ç½®çSaaSåè½å°¤å ¶éªèï¼ å ·å¤RBACåè½ã?ç½å ³ç»ä¸é´æ?ã?Xssé²è·¨ç«æ»å»ã?èªå¨ä»£ç ?çæ?ã?å¤ç§?åå¨ç³»ç»ã?åå¸å¼?äºå¡ã?åå¸å¼?宿¶ä»»å¡çå¤ä¸ªæ¨¡å?ï¼æ¯æ?å¤ä¸å¡ç³»ç»å¹¶è¡å¼å?ï¼ æ¯æ?夿?å¡å¹¶è¡å¼å?ï¼å?¯ä»¥ä½ä¸ºå?端æ?å¡çå¼å?èææ¶zuihou/lamp-util
æé ä¸å¥å ¼é¡¾ SpringBoot å SpringCloud 项ç®çå ¬å ±å·¥å ·ç±»
YunaiV/ruoyi-vue-pro
ä¸å¥å ¨é¨å¼æº?çä¼?ä¸çº§çå¿«éå¼å?å¹³å?°ãåºäº Spring Boot + MyBatis Plus + Vue & Element å®ç°çå?å?°ç®¡ç?ç³»ç» + 微信å°?ç¨åº?ï¼æ¯æ? RBAC 卿?æ?é?ã?æ°æ?®æ?é?ã?SaaS å¤ç§æ·ã?Activiti + Flowable 工使µ?ã?䏿¹ç»å½ã?æ¯ä»ã?çä¿¡ã?ååçåè½ãmatevip/matecloud
䏿¬¾åºäºSpring Cloud Alibabaçå¾®æ?塿¶ægavenwangcn/vole
SpringCloud å¾®æ?å¡ä¸å¡èææ¶liuweijw/fw-cloud-framework
åºäºspringcloudå ¨å®¶æ¡¶å¼å?åå¸å¼?æ¡æ¶ï¼æ¯æ?oauth2认è¯?ææ?ã?SSOç»å½ã?ç»ä¸ä¸å?ã?å¾®ä¿¡å ¬ä¼å?·æ?å¡ã?Shardingdbcååºå表ã?常è§?æ?å¡çæ§ã?é¾è·¯çæ§ã?弿¥æ¥å¿ã?redisç¼åçåè½ï¼ï¼å®ç°åºäºVueå ¨å®¶æ¡¶çå?å?端å离项ç®å·¥ç¨liuht777/Taroco
æ´å?Nacosã?Spring Cloud Alibabaï¼æ??ä¾äºä¸ç³»åstarterç»ä»¶ï¼ å?æ¶æ??便?塿²»ç?ã?æ?å¡çæ§ã?OAuth2æ?é?认è¯?ï¼æ¯æ?æ?å¡é?级/çæã?æ?塿?é?mingyang66/spring-parent
æ°æ?®åºå¤æ°æ?®æº?ã?Redis夿°æ?®æº?ã?æ¥å¿ç»ä»¶ã?å ¨é¾è·¯æ¥å¿è¿½è¸ªã?åç¹æ©å±ç¹ã?Nettyã?å¾®æ?å¡ã?å¼å?åºç¡æ¡æ¶æ¯æ?ã?å¼å¸¸ç»ä¸å¤ç?ã?è¿åå¼ã?è·¨åã?APIè·¯ç±ã?çæ§çyzcheng90/ms
ä¸ä¸ªå?å?å离çåå¸å¼? spring cloud æ¡æ¶(å ¨å®¶æ¡¶)ï¼è¿éæç»ä¸è®¤è¯?ï¼ç»ä¸ç½å ³ççåè½ï¼æ¯ä¸ä¸ªé?å¸¸ç®æ´?çå¾®æ?å¡èææ¶fafeidou/fast-cloud-nacos
è´åäºæé ä¸ä¸ªåºäºnacos为注åä¸å¿ï¼ç»å?ä¼?ä¸å¼å?ä¹ æ¯ï¼æ»ç»çä¸äºåºæ¬çå®ç°æ¹å¼?HongZhaoHua/jstarcraft-core
ç®æ æ¯æ??ä¾ä¸ä¸ªéç¨çJavaæ ¸å¿ç¼ç¨æ¡æ¶,ä½ä¸ºæ?å»ºå ¶å®æ¡æ¶æè 项ç®çåºç¡. 让ç¸å ³é¢åçç å?人åè½å¤ä¸æ³¨é«å±è®¾è®¡èä¸?ç¨å ³æ³¨åºå±å®ç°. æ¶µçäºç¼å,ç¼è§£ç ?,é讯,äºä»¶,è¾å ¥/è¾åº,çæ§,åå¨,é ?ç½®,èæ¬åäºå¡10个æ¹é?¢budwk/budwk
BudWk
åå??NutzWk
ï¼åºäºå½äº§æ¡æ¶ nutz å? nutzboot å¼å?ç弿º?Webåºç¡é¡¹ç®ï¼éæ?é?ä½ç³»ã?ç³»ç»å?æ°ã?æ°æ?®åå ¸ã?ç«å æ¶æ?¯ã?宿¶ä»»å¡ã?CMSã?微信çæå¸¸ç¨åè½ï¼ä¸?åºæ?ã?ä¸?é?¢é?¢ä¿±å°ï¼ä½¿å ¶å ·æä¸æå®¹æã?å¼å?便æ?·ã?æ©å±ç?µæ´»çç¹æ§ï¼ç¹å«éå?å?类大ä¸å°?åå®å¶å项ç®éæ±
yinjihuan/spring-cloud
ãSpring Cloudå¾®æ?å¡-å ¨æ ææ¯ä¸æ¡ä¾è§£æ?ãåãSpring Cloudå¾®æ?å¡ å ¥é¨ å®æä¸è¿é¶ãé ?奿º?ç ?louyanfeng25/ddd-demo
ãæ·±å ¥æµ åºDDDãè®²è§£çæ¼ç¤ºé¡¹ç®ï¼ä¸ºäºè½å¤æ´å¥½çç?è§£Demoä¸çåå±ä¸é»è¾å¤ç?ï¼æå¼ºçå»ºè®®ä½ é ?å?å°?åæ?¥æ·±å ¥äºè§£DDDã
æ´å¤ä½¿ç¨TTL
ç弿º?é¡¹ç® å?è§?
ð· Contributors
- Jerry Lee <oldratlee at gmail dot com> @oldratlee
- Yang Fang <snoop.fy at gmail dot com> @driventokill
- Zava Xu <zava.kid at gmail dot com> @zavakid
- wuwen <wuwen.55 at aliyun dot com> @wuwen5
- Xiaowei Shi <179969622 at qq dot com> @xwshiustc
- David Dai <351450944 at qq dot com> @LNAmp
- Your name here :-)