Commit d5146b0d92e03ea9acc573a6db30594e03066087
Merge remote-tracking branch 'upstream/develop/2.5.5' into fix/ttlCleanUpServices
Showing
13 changed files
with
68 additions
and
41 deletions
... | ... | @@ -197,19 +197,21 @@ public class TelemetryController extends BaseController { |
197 | 197 | @RequestMapping(value = "/{entityType}/{entityId}/values/timeseries", method = RequestMethod.GET, params = {"keys", "startTs", "endTs"}) |
198 | 198 | @ResponseBody |
199 | 199 | public DeferredResult<ResponseEntity> getTimeseries( |
200 | - @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr, | |
200 | + @PathVariable("entityType") String entityType, | |
201 | + @PathVariable("entityId") String entityIdStr, | |
201 | 202 | @RequestParam(name = "keys") String keys, |
202 | 203 | @RequestParam(name = "startTs") Long startTs, |
203 | 204 | @RequestParam(name = "endTs") Long endTs, |
204 | 205 | @RequestParam(name = "interval", defaultValue = "0") Long interval, |
205 | 206 | @RequestParam(name = "limit", defaultValue = "100") Integer limit, |
206 | 207 | @RequestParam(name = "agg", defaultValue = "NONE") String aggStr, |
208 | + @RequestParam(name= "orderBy", defaultValue = "DESC") String orderBy, | |
207 | 209 | @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException { |
208 | 210 | return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, |
209 | 211 | (result, tenantId, entityId) -> { |
210 | 212 | // If interval is 0, convert this to a NONE aggregation, which is probably what the user really wanted |
211 | 213 | Aggregation agg = interval == 0L ? Aggregation.valueOf(Aggregation.NONE.name()) : Aggregation.valueOf(aggStr); |
212 | - List<ReadTsKvQuery> queries = toKeysList(keys).stream().map(key -> new BaseReadTsKvQuery(key, startTs, endTs, interval, limit, agg)) | |
214 | + List<ReadTsKvQuery> queries = toKeysList(keys).stream().map(key -> new BaseReadTsKvQuery(key, startTs, endTs, interval, limit, agg, orderBy)) | |
213 | 215 | .collect(Collectors.toList()); |
214 | 216 | |
215 | 217 | Futures.addCallback(tsService.findAll(tenantId, entityId, queries), getTsKvListCallback(result, useStrictDataTypes), MoreExecutors.directExecutor()); | ... | ... |
... | ... | @@ -29,6 +29,8 @@ |
29 | 29 | |
30 | 30 | <!-- <logger name="org.thingsboard.server.service.queue" level="TRACE" />--> |
31 | 31 | <!-- <logger name="org.thingsboard.server.service.transport" level="TRACE" />--> |
32 | +<!-- <logger name="org.thingsboard.server.queue.memory.InMemoryStorage" level="DEBUG" />--> | |
33 | + | |
32 | 34 | |
33 | 35 | <logger name="com.microsoft.azure.servicebus.primitives.CoreMessageReceiver" level="OFF" /> |
34 | 36 | ... | ... |
... | ... | @@ -594,6 +594,10 @@ swagger: |
594 | 594 | |
595 | 595 | queue: |
596 | 596 | type: "${TB_QUEUE_TYPE:in-memory}" # in-memory or kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ) |
597 | + in_memory: | |
598 | + stats: | |
599 | + # For debug lvl | |
600 | + print-interval-ms: "${TB_QUEUE_IN_MEMORY_STATS_PRINT_INTERVAL_MS:60000}" | |
597 | 601 | kafka: |
598 | 602 | bootstrap.servers: "${TB_KAFKA_SERVERS:localhost:9092}" |
599 | 603 | acks: "${TB_KAFKA_ACKS:all}" |
... | ... | @@ -613,11 +617,11 @@ queue: |
613 | 617 | security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}" |
614 | 618 | other: |
615 | 619 | topic-properties: |
616 | - rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
617 | - core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
618 | - transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
619 | - notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
620 | - js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600}" | |
620 | + rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
621 | + core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
622 | + transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
623 | + notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
624 | + js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100}" | |
621 | 625 | aws_sqs: |
622 | 626 | use_default_credential_provider_chain: "${TB_QUEUE_AWS_SQS_USE_DEFAULT_CREDENTIAL_PROVIDER_CHAIN:false}" |
623 | 627 | access_key_id: "${TB_QUEUE_AWS_SQS_ACCESS_KEY_ID:YOUR_KEY}" | ... | ... |
... | ... | @@ -37,6 +37,7 @@ public class TbKafkaAdmin implements TbQueueAdmin { |
37 | 37 | private final AdminClient client; |
38 | 38 | private final Map<String, String> topicConfigs; |
39 | 39 | private final Set<String> topics = ConcurrentHashMap.newKeySet(); |
40 | + private final int numPartitions; | |
40 | 41 | |
41 | 42 | private final short replicationFactor; |
42 | 43 | |
... | ... | @@ -50,6 +51,13 @@ public class TbKafkaAdmin implements TbQueueAdmin { |
50 | 51 | log.error("Failed to get all topics.", e); |
51 | 52 | } |
52 | 53 | |
54 | + String numPartitionsStr = topicConfigs.get("partitions"); | |
55 | + if (numPartitionsStr != null) { | |
56 | + numPartitions = Integer.parseInt(numPartitionsStr); | |
57 | + topicConfigs.remove("partitions"); | |
58 | + } else { | |
59 | + numPartitions = 1; | |
60 | + } | |
53 | 61 | replicationFactor = settings.getReplicationFactor(); |
54 | 62 | } |
55 | 63 | |
... | ... | @@ -59,7 +67,7 @@ public class TbKafkaAdmin implements TbQueueAdmin { |
59 | 67 | return; |
60 | 68 | } |
61 | 69 | try { |
62 | - NewTopic newTopic = new NewTopic(topic, 1, replicationFactor).configs(topicConfigs); | |
70 | + NewTopic newTopic = new NewTopic(topic, numPartitions, replicationFactor).configs(topicConfigs); | |
63 | 71 | createTopic(newTopic).values().get(topic).get(); |
64 | 72 | topics.add(topic); |
65 | 73 | } catch (ExecutionException ee) { | ... | ... |
... | ... | @@ -23,27 +23,21 @@ import java.util.Collections; |
23 | 23 | import java.util.List; |
24 | 24 | import java.util.concurrent.BlockingQueue; |
25 | 25 | import java.util.concurrent.ConcurrentHashMap; |
26 | -import java.util.concurrent.Executors; | |
27 | 26 | import java.util.concurrent.LinkedBlockingQueue; |
28 | -import java.util.concurrent.ScheduledExecutorService; | |
29 | -import java.util.concurrent.TimeUnit; | |
30 | 27 | |
31 | 28 | @Slf4j |
32 | 29 | public final class InMemoryStorage { |
33 | 30 | private static InMemoryStorage instance; |
34 | 31 | private final ConcurrentHashMap<String, BlockingQueue<TbQueueMsg>> storage; |
35 | - private static ScheduledExecutorService statExecutor; | |
36 | 32 | |
37 | 33 | private InMemoryStorage() { |
38 | 34 | storage = new ConcurrentHashMap<>(); |
39 | - statExecutor = Executors.newSingleThreadScheduledExecutor(); | |
40 | - statExecutor.scheduleAtFixedRate(this::printStats, 60, 60, TimeUnit.SECONDS); | |
41 | 35 | } |
42 | 36 | |
43 | - private void printStats() { | |
37 | + public void printStats() { | |
44 | 38 | storage.forEach((topic, queue) -> { |
45 | 39 | if (queue.size() > 0) { |
46 | - log.debug("Topic: [{}], Queue size: [{}]", topic, queue.size()); | |
40 | + log.debug("[{}] Queue Size [{}]", topic, queue.size()); | |
47 | 41 | } |
48 | 42 | }); |
49 | 43 | } |
... | ... | @@ -90,9 +84,4 @@ public final class InMemoryStorage { |
90 | 84 | storage.clear(); |
91 | 85 | } |
92 | 86 | |
93 | - public void destroy() { | |
94 | - if (statExecutor != null) { | |
95 | - statExecutor.shutdownNow(); | |
96 | - } | |
97 | - } | |
98 | 87 | } | ... | ... |
... | ... | @@ -17,6 +17,7 @@ package org.thingsboard.server.queue.provider; |
17 | 17 | |
18 | 18 | import lombok.extern.slf4j.Slf4j; |
19 | 19 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
20 | +import org.springframework.scheduling.annotation.Scheduled; | |
20 | 21 | import org.springframework.stereotype.Component; |
21 | 22 | import org.thingsboard.server.common.msg.queue.ServiceType; |
22 | 23 | import org.thingsboard.server.gen.js.JsInvokeProtos; |
... | ... | @@ -28,6 +29,7 @@ import org.thingsboard.server.queue.common.TbProtoJsQueueMsg; |
28 | 29 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
29 | 30 | import org.thingsboard.server.queue.discovery.PartitionService; |
30 | 31 | import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; |
32 | +import org.thingsboard.server.queue.memory.InMemoryStorage; | |
31 | 33 | import org.thingsboard.server.queue.memory.InMemoryTbQueueConsumer; |
32 | 34 | import org.thingsboard.server.queue.memory.InMemoryTbQueueProducer; |
33 | 35 | import org.thingsboard.server.queue.settings.TbQueueCoreSettings; |
... | ... | @@ -47,6 +49,7 @@ public class InMemoryMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE |
47 | 49 | private final TbQueueRuleEngineSettings ruleEngineSettings; |
48 | 50 | private final TbQueueTransportApiSettings transportApiSettings; |
49 | 51 | private final TbQueueTransportNotificationSettings transportNotificationSettings; |
52 | + private final InMemoryStorage storage; | |
50 | 53 | |
51 | 54 | public InMemoryMonolithQueueFactory(PartitionService partitionService, TbQueueCoreSettings coreSettings, |
52 | 55 | TbQueueRuleEngineSettings ruleEngineSettings, |
... | ... | @@ -59,6 +62,7 @@ public class InMemoryMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE |
59 | 62 | this.ruleEngineSettings = ruleEngineSettings; |
60 | 63 | this.transportApiSettings = transportApiSettings; |
61 | 64 | this.transportNotificationSettings = transportNotificationSettings; |
65 | + this.storage = InMemoryStorage.getInstance(); | |
62 | 66 | } |
63 | 67 | |
64 | 68 | @Override |
... | ... | @@ -120,4 +124,9 @@ public class InMemoryMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE |
120 | 124 | public TbQueueRequestTemplate<TbProtoJsQueueMsg<JsInvokeProtos.RemoteJsRequest>, TbProtoQueueMsg<JsInvokeProtos.RemoteJsResponse>> createRemoteJsRequestTemplate() { |
121 | 125 | return null; |
122 | 126 | } |
127 | + | |
128 | + @Scheduled(fixedRateString = "${queue.in_memory.stats.print-interval-ms:60000}") | |
129 | + private void printInMemoryStats() { | |
130 | + storage.printStats(); | |
131 | + } | |
123 | 132 | } | ... | ... |
... | ... | @@ -25,7 +25,7 @@ kafka: |
25 | 25 | # Kafka Bootstrap Servers |
26 | 26 | servers: "localhost:9092" |
27 | 27 | replication_factor: "1" |
28 | - topic_properties: "retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600" | |
28 | + topic_properties: "retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100" | |
29 | 29 | use_confluent_cloud: false |
30 | 30 | confluent: |
31 | 31 | sasl: | ... | ... |
... | ... | @@ -34,7 +34,7 @@ function KafkaProducer() { |
34 | 34 | this.send = async (responseTopic, scriptId, rawResponse, headers) => { |
35 | 35 | |
36 | 36 | if (!topics.includes(responseTopic)) { |
37 | - let createResponseTopicResult = await createTopic(responseTopic); | |
37 | + let createResponseTopicResult = await createTopic(responseTopic, 1); | |
38 | 38 | topics.push(responseTopic); |
39 | 39 | if (createResponseTopicResult) { |
40 | 40 | logger.info('Created new topic: %s', requestTopic); |
... | ... | @@ -88,7 +88,18 @@ function KafkaProducer() { |
88 | 88 | kafkaAdmin = kafkaClient.admin(); |
89 | 89 | await kafkaAdmin.connect(); |
90 | 90 | |
91 | - let createRequestTopicResult = await createTopic(requestTopic); | |
91 | + let partitions = 1; | |
92 | + | |
93 | + for (let i = 0; i < configEntries.length; i++) { | |
94 | + let param = configEntries[i]; | |
95 | + if (param.name === 'partitions') { | |
96 | + partitions = param.value; | |
97 | + configEntries.splice(i, 1); | |
98 | + break; | |
99 | + } | |
100 | + } | |
101 | + | |
102 | + let createRequestTopicResult = await createTopic(requestTopic, partitions); | |
92 | 103 | |
93 | 104 | if (createRequestTopicResult) { |
94 | 105 | logger.info('Created new topic: %s', requestTopic); |
... | ... | @@ -121,10 +132,11 @@ function KafkaProducer() { |
121 | 132 | } |
122 | 133 | })(); |
123 | 134 | |
124 | -function createTopic(topic) { | |
135 | +function createTopic(topic, partitions) { | |
125 | 136 | return kafkaAdmin.createTopics({ |
126 | 137 | topics: [{ |
127 | 138 | topic: topic, |
139 | + numPartitions: partitions, | |
128 | 140 | replicationFactor: replicationFactor, |
129 | 141 | configEntries: configEntries |
130 | 142 | }] | ... | ... |
... | ... | @@ -77,11 +77,11 @@ queue: |
77 | 77 | security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}" |
78 | 78 | other: |
79 | 79 | topic-properties: |
80 | - rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
81 | - core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
82 | - transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
83 | - notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
84 | - js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600}" | |
80 | + rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
81 | + core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
82 | + transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
83 | + notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
84 | + js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100}" | |
85 | 85 | aws_sqs: |
86 | 86 | use_default_credential_provider_chain: "${TB_QUEUE_AWS_SQS_USE_DEFAULT_CREDENTIAL_PROVIDER_CHAIN:false}" |
87 | 87 | access_key_id: "${TB_QUEUE_AWS_SQS_ACCESS_KEY_ID:YOUR_KEY}" | ... | ... |
... | ... | @@ -70,11 +70,11 @@ queue: |
70 | 70 | security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}" |
71 | 71 | other: |
72 | 72 | topic-properties: |
73 | - rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
74 | - core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
75 | - transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
76 | - notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
77 | - js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600}" | |
73 | + rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
74 | + core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
75 | + transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
76 | + notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
77 | + js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100}" | |
78 | 78 | aws_sqs: |
79 | 79 | use_default_credential_provider_chain: "${TB_QUEUE_AWS_SQS_USE_DEFAULT_CREDENTIAL_PROVIDER_CHAIN:false}" |
80 | 80 | access_key_id: "${TB_QUEUE_AWS_SQS_ACCESS_KEY_ID:YOUR_KEY}" | ... | ... |
... | ... | @@ -98,11 +98,11 @@ queue: |
98 | 98 | security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}" |
99 | 99 | other: |
100 | 100 | topic-properties: |
101 | - rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
102 | - core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
103 | - transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
104 | - notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
105 | - js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600}" | |
101 | + rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
102 | + core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
103 | + transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
104 | + notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
105 | + js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100}" | |
106 | 106 | aws_sqs: |
107 | 107 | use_default_credential_provider_chain: "${TB_QUEUE_AWS_SQS_USE_DEFAULT_CREDENTIAL_PROVIDER_CHAIN:false}" |
108 | 108 | access_key_id: "${TB_QUEUE_AWS_SQS_ACCESS_KEY_ID:YOUR_KEY}" | ... | ... |