From c3e5e4cafad82c85c67c6cb433cdade6639851c2 Mon Sep 17 00:00:00 2001 From: pyh_uestc <664254320@qq.com> Date: Fri, 24 May 2019 15:19:07 +0800 Subject: [PATCH 1/4] fix thread-unsafe in NacosRefreshHistory --- .../cloud/alibaba/nacos/refresh/NacosRefreshHistory.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/refresh/NacosRefreshHistory.java b/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/refresh/NacosRefreshHistory.java index ec5a83ca..eeac91a1 100644 --- a/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/refresh/NacosRefreshHistory.java +++ b/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/refresh/NacosRefreshHistory.java @@ -27,10 +27,15 @@ public class NacosRefreshHistory { private LinkedList records = new LinkedList<>(); - private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + private ThreadLocal dateFormat = new ThreadLocal(){ + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + }; public void add(String dataId, String md5) { - records.addFirst(new Record(dateFormat.format(new Date()), dataId, md5)); + records.addFirst(new Record(dateFormat.get().format(new Date()), dataId, md5)); if (records.size() > MAX_SIZE) { records.removeLast(); } From 6fbb0fb1f4fa670759aa81af3214614f44b6abe8 Mon Sep 17 00:00:00 2001 From: pyh_uestc <664254320@qq.com> Date: Fri, 24 May 2019 17:11:55 +0800 Subject: [PATCH 2/4] fix thread-unsafe about SimpleDateFormat --- .../alibaba/nacos/endpoint/NacosConfigEndpoint.java | 9 +++++++-- .../cloud/alicloud/acm/endpoint/AcmEndpoint.java | 9 +++++++-- .../cloud/alicloud/acm/refresh/AcmRefreshHistory.java | 9 +++++++-- .../alicloud/sms/base/DefaultAlicomMessagePuller.java | 11 ++++++++--- .../cloud/alicloud/sms/base/TokenGetterForAlicom.java | 4 ++-- 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/endpoint/NacosConfigEndpoint.java b/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/endpoint/NacosConfigEndpoint.java index 1160db1b..a8e81b56 100644 --- a/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/endpoint/NacosConfigEndpoint.java +++ b/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/endpoint/NacosConfigEndpoint.java @@ -41,7 +41,12 @@ public class NacosConfigEndpoint { private final NacosRefreshHistory refreshHistory; - private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + private ThreadLocal dateFormat = new ThreadLocal(){ + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + }; public NacosConfigEndpoint(NacosConfigProperties properties, NacosRefreshHistory refreshHistory) { @@ -60,7 +65,7 @@ public class NacosConfigEndpoint { for (NacosPropertySource ps : all) { Map source = new HashMap<>(16); source.put("dataId", ps.getDataId()); - source.put("lastSynced", dateFormat.format(ps.getTimestamp())); + source.put("lastSynced", dateFormat.get().format(ps.getTimestamp())); sources.add(source); } result.put("Sources", sources); diff --git a/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/endpoint/AcmEndpoint.java b/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/endpoint/AcmEndpoint.java index 0133fe24..35d7699e 100644 --- a/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/endpoint/AcmEndpoint.java +++ b/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/endpoint/AcmEndpoint.java @@ -44,7 +44,12 @@ public class AcmEndpoint { private final AcmPropertySourceRepository propertySourceRepository; - private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + private ThreadLocal dateFormat = new ThreadLocal(){ + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + }; public AcmEndpoint(AcmProperties properties, AcmRefreshHistory refreshHistory, AcmPropertySourceRepository propertySourceRepository) { @@ -65,7 +70,7 @@ public class AcmEndpoint { for (AcmPropertySource ps : all) { Map source = new HashMap<>(); source.put("dataId", ps.getDataId()); - source.put("lastSynced", dateFormat.format(ps.getTimestamp())); + source.put("lastSynced", dateFormat.get().format(ps.getTimestamp())); sources.add(source); } runtime.put("sources", sources); diff --git a/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/refresh/AcmRefreshHistory.java b/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/refresh/AcmRefreshHistory.java index 439e6360..cd8f3173 100644 --- a/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/refresh/AcmRefreshHistory.java +++ b/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/refresh/AcmRefreshHistory.java @@ -30,10 +30,15 @@ public class AcmRefreshHistory { private LinkedList records = new LinkedList<>(); - private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + private ThreadLocal dateFormat = new ThreadLocal(){ + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + }; public void add(String dataId, String md5) { - records.addFirst(new Record(dateFormat.format(new Date()), dataId, md5)); + records.addFirst(new Record(dateFormat.get().format(new Date()), dataId, md5)); if (records.size() > MAX_SIZE) { records.removeLast(); } diff --git a/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/DefaultAlicomMessagePuller.java b/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/DefaultAlicomMessagePuller.java index 4d23ccff..587dd309 100755 --- a/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/DefaultAlicomMessagePuller.java +++ b/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/DefaultAlicomMessagePuller.java @@ -15,6 +15,7 @@ */ package org.springframework.cloud.alicloud.sms.base; +import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -158,11 +159,15 @@ public class DefaultAlicomMessagePuller { if (!polling) { popMsg = queue.popMessage(); if (debugLogOpen) { - SimpleDateFormat format = new SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss"); + ThreadLocal format = new ThreadLocal(){ + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + }; log.info("PullMessageTask_popMessage:" + Thread.currentThread().getName() + "-popDone at " - + "," + format.format(new Date()) + " msgSize=" + + "," + format.get().format(new Date()) + " msgSize=" + (popMsg == null ? 0 : popMsg.getMessageId())); } if (popMsg == null) { diff --git a/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/TokenGetterForAlicom.java b/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/TokenGetterForAlicom.java index 3daf1c83..2b44e63e 100755 --- a/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/TokenGetterForAlicom.java +++ b/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/TokenGetterForAlicom.java @@ -77,7 +77,7 @@ public class TokenGetterForAlicom { } private TokenForAlicom getTokenFromRemote(String messageType) - throws ServerException, ClientException, ParseException { + throws ClientException, ParseException { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); df.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); QueryTokenForMnsQueueRequest request = new QueryTokenForMnsQueueRequest(); @@ -109,7 +109,7 @@ public class TokenGetterForAlicom { public TokenForAlicom getTokenByMessageType(String messageType, String queueName, String mnsAccountEndpoint) - throws ServerException, ClientException, ParseException { + throws ClientException, ParseException { TokenForAlicom token = tokenMap.get(messageType); Long now = System.currentTimeMillis(); if (token == null || (token.getExpireTime() - now) < bufferTime) {// 过期时间小于2分钟则重新获取,防止服务器时间误差 From 2cb7327a78f68bc2981fcecc697612f3d50032f0 Mon Sep 17 00:00:00 2001 From: pyh_uestc <664254320@qq.com> Date: Fri, 24 May 2019 17:16:01 +0800 Subject: [PATCH 3/4] fix thread-unsafe about SimpleDateFormat --- .../alicloud/sms/base/DefaultAlicomMessagePuller.java | 5 ++--- .../cloud/alicloud/sms/base/TokenGetterForAlicom.java | 11 ++++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/DefaultAlicomMessagePuller.java b/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/DefaultAlicomMessagePuller.java index 587dd309..dec7d9e0 100755 --- a/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/DefaultAlicomMessagePuller.java +++ b/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/DefaultAlicomMessagePuller.java @@ -15,7 +15,6 @@ */ package org.springframework.cloud.alicloud.sms.base; -import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -159,9 +158,9 @@ public class DefaultAlicomMessagePuller { if (!polling) { popMsg = queue.popMessage(); if (debugLogOpen) { - ThreadLocal format = new ThreadLocal(){ + ThreadLocal format = new ThreadLocal(){ @Override - protected DateFormat initialValue() { + protected SimpleDateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); } }; diff --git a/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/TokenGetterForAlicom.java b/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/TokenGetterForAlicom.java index 2b44e63e..6f410cd3 100755 --- a/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/TokenGetterForAlicom.java +++ b/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/TokenGetterForAlicom.java @@ -78,8 +78,13 @@ public class TokenGetterForAlicom { private TokenForAlicom getTokenFromRemote(String messageType) throws ClientException, ParseException { - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - df.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); + ThreadLocal df = new ThreadLocal(){ + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + }; + df.get().setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); QueryTokenForMnsQueueRequest request = new QueryTokenForMnsQueueRequest(); request.setAcceptFormat(FormatType.JSON); request.setMessageType(messageType); @@ -94,7 +99,7 @@ public class TokenGetterForAlicom { TokenForAlicom token = new TokenForAlicom(); String timeStr = dto.getExpireTime(); token.setMessageType(messageType); - token.setExpireTime(df.parse(timeStr).getTime()); + token.setExpireTime(df.get().parse(timeStr).getTime()); token.setToken(dto.getSecurityToken()); token.setTempAccessKeyId(dto.getAccessKeyId()); token.setTempAccessKeySecret(dto.getAccessKeySecret()); From ccaae6aad7d19129bbaf6a36b4a34ab17a8d8862 Mon Sep 17 00:00:00 2001 From: pyh_uestc <664254320@qq.com> Date: Mon, 27 May 2019 19:27:18 +0800 Subject: [PATCH 4/4] fix thread-unsafe about SimpleDateFormat --- .../nacos/endpoint/NacosConfigEndpoint.java | 2 +- .../nacos/refresh/NacosRefreshHistory.java | 2 +- .../cloud/alicloud/acm/endpoint/AcmEndpoint.java | 2 +- .../alicloud/acm/refresh/AcmRefreshHistory.java | 2 +- .../sms/base/DefaultAlicomMessagePuller.java | 10 +++------- .../alicloud/sms/base/TokenGetterForAlicom.java | 15 +++++---------- 6 files changed, 12 insertions(+), 21 deletions(-) diff --git a/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/endpoint/NacosConfigEndpoint.java b/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/endpoint/NacosConfigEndpoint.java index a8e81b56..34ddd2a0 100644 --- a/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/endpoint/NacosConfigEndpoint.java +++ b/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/endpoint/NacosConfigEndpoint.java @@ -41,7 +41,7 @@ public class NacosConfigEndpoint { private final NacosRefreshHistory refreshHistory; - private ThreadLocal dateFormat = new ThreadLocal(){ + private ThreadLocal dateFormat = new ThreadLocal() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); diff --git a/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/refresh/NacosRefreshHistory.java b/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/refresh/NacosRefreshHistory.java index eeac91a1..149453b6 100644 --- a/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/refresh/NacosRefreshHistory.java +++ b/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/refresh/NacosRefreshHistory.java @@ -27,7 +27,7 @@ public class NacosRefreshHistory { private LinkedList records = new LinkedList<>(); - private ThreadLocal dateFormat = new ThreadLocal(){ + private ThreadLocal dateFormat = new ThreadLocal() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); diff --git a/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/endpoint/AcmEndpoint.java b/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/endpoint/AcmEndpoint.java index 35d7699e..6952fa89 100644 --- a/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/endpoint/AcmEndpoint.java +++ b/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/endpoint/AcmEndpoint.java @@ -44,7 +44,7 @@ public class AcmEndpoint { private final AcmPropertySourceRepository propertySourceRepository; - private ThreadLocal dateFormat = new ThreadLocal(){ + private ThreadLocal dateFormat = new ThreadLocal() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); diff --git a/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/refresh/AcmRefreshHistory.java b/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/refresh/AcmRefreshHistory.java index cd8f3173..19197b89 100644 --- a/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/refresh/AcmRefreshHistory.java +++ b/spring-cloud-alicloud-acm/src/main/java/org/springframework/cloud/alicloud/acm/refresh/AcmRefreshHistory.java @@ -30,7 +30,7 @@ public class AcmRefreshHistory { private LinkedList records = new LinkedList<>(); - private ThreadLocal dateFormat = new ThreadLocal(){ + private ThreadLocal dateFormat = new ThreadLocal() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); diff --git a/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/DefaultAlicomMessagePuller.java b/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/DefaultAlicomMessagePuller.java index dec7d9e0..4d23ccff 100755 --- a/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/DefaultAlicomMessagePuller.java +++ b/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/DefaultAlicomMessagePuller.java @@ -158,15 +158,11 @@ public class DefaultAlicomMessagePuller { if (!polling) { popMsg = queue.popMessage(); if (debugLogOpen) { - ThreadLocal format = new ThreadLocal(){ - @Override - protected SimpleDateFormat initialValue() { - return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - } - }; + SimpleDateFormat format = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); log.info("PullMessageTask_popMessage:" + Thread.currentThread().getName() + "-popDone at " - + "," + format.get().format(new Date()) + " msgSize=" + + "," + format.format(new Date()) + " msgSize=" + (popMsg == null ? 0 : popMsg.getMessageId())); } if (popMsg == null) { diff --git a/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/TokenGetterForAlicom.java b/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/TokenGetterForAlicom.java index 6f410cd3..3daf1c83 100755 --- a/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/TokenGetterForAlicom.java +++ b/spring-cloud-alicloud-sms/src/main/java/org/springframework/cloud/alicloud/sms/base/TokenGetterForAlicom.java @@ -77,14 +77,9 @@ public class TokenGetterForAlicom { } private TokenForAlicom getTokenFromRemote(String messageType) - throws ClientException, ParseException { - ThreadLocal df = new ThreadLocal(){ - @Override - protected SimpleDateFormat initialValue() { - return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - } - }; - df.get().setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); + throws ServerException, ClientException, ParseException { + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + df.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); QueryTokenForMnsQueueRequest request = new QueryTokenForMnsQueueRequest(); request.setAcceptFormat(FormatType.JSON); request.setMessageType(messageType); @@ -99,7 +94,7 @@ public class TokenGetterForAlicom { TokenForAlicom token = new TokenForAlicom(); String timeStr = dto.getExpireTime(); token.setMessageType(messageType); - token.setExpireTime(df.get().parse(timeStr).getTime()); + token.setExpireTime(df.parse(timeStr).getTime()); token.setToken(dto.getSecurityToken()); token.setTempAccessKeyId(dto.getAccessKeyId()); token.setTempAccessKeySecret(dto.getAccessKeySecret()); @@ -114,7 +109,7 @@ public class TokenGetterForAlicom { public TokenForAlicom getTokenByMessageType(String messageType, String queueName, String mnsAccountEndpoint) - throws ClientException, ParseException { + throws ServerException, ClientException, ParseException { TokenForAlicom token = tokenMap.get(messageType); Long now = System.currentTimeMillis(); if (token == null || (token.getExpireTime() - now) < bufferTime) {// 过期时间小于2分钟则重新获取,防止服务器时间误差