使用 Kafka 优化物流系统的实践与思考

在现代物流系统中,订单处理、仓储管理、运输调度等环节复杂且实时性要求高。为了满足异步解耦、高吞吐、高可用、事件驱动和数据可靠性等需求,Kafka 作为分布式消息队列和流处理平台,成为了我们的首选。本文将分享我们在物流系统中使用 Kafka 的设计方案、优化实践以及遇到的问题和解决方案。

一、系统背景和需求

物流系统涉及多个业务模块,如订单处理、仓储管理、运输调度和状态跟踪等。为了实现模块间的异步解耦,避免同步调用阻塞,我们需要一个高吞吐、高可用的事件驱动架构。同时,消息的可靠性和顺序性也是我们关注的重点,以确保数据不丢失并保持一致性。

二、Kafka 在物流系统中的角色

在我们的物流系统中,Kafka 扮演了以下角色:

  • 事件总线:各业务模块通过 Kafka 交换事件消息,实现松耦合。
  • 异步缓冲:通过削峰填谷,缓解高峰压力。
  • 数据管道:将业务数据流转到分析、监控、告警系统。
  • 解耦中间件:模块间松耦合,方便独立扩展和维护。

三、核心业务场景与事件流

1. 订单创建与处理

用户下单后,订单服务发送订单创建事件,仓储服务和运输服务消费该事件,进行备货和运输调度。

订单创建事件流示例

订单服务发送订单创建事件:

from kafka import KafkaProducer
import jsondef create_order_producer():return KafkaProducer(bootstrap_servers='localhost:9092',value_serializer=lambda v: json.dumps(v).encode('utf-8'))def send_order_created_event(producer, order_id, order_details):event = {'order_id': order_id,'details': order_details}producer.send('order-events', key=order_id.encode('utf-8'), value=event)# 示例调用
producer = create_order_producer()
send_order_created_event(producer, '12345', {'item': 'Laptop', 'quantity': 1})
producer.flush()
producer.close()

2. 仓储管理

仓库的入库、出库和库存变更事件通过 Kafka 发送,库存服务和财务服务消费这些事件。

仓储事件流示例

仓储服务发送库存变更事件:

from kafka import KafkaProducer
import jsondef create_warehouse_producer():return KafkaProducer(bootstrap_servers='localhost:9092',value_serializer=lambda v: json.dumps(v).encode('utf-8'))def send_inventory_update_event(producer, product_id, change):event = {'product_id': product_id,'change': change}producer.send('warehouse-events', key=product_id.encode('utf-8'), value=event)# 示例调用
producer = create_warehouse_producer()
send_inventory_update_event(producer, '98765', {'change': -10})
producer.flush()
producer.close()

3. 运输调度与跟踪

运输任务的创建和状态更新事件由运输服务发送,订单服务和客户通知服务消费。

运输事件流示例

运输服务发送运输状态更新事件:

from kafka import KafkaProducer
import jsondef create_shipping_producer():return KafkaProducer(bootstrap_servers='localhost:9092',value_serializer=lambda v: json.dumps(v).encode('utf-8'))def send_shipping_status_event(producer, shipment_id, status):event = {'shipment_id': shipment_id,'status': status}producer.send('shipment-events', key=shipment_id.encode('utf-8'), value=event)# 示例调用
producer = create_shipping_producer()
send_shipping_status_event(producer, '54321', {'status': 'in_transit'})
producer.flush()
producer.close()

4. 异常处理与告警

异常事件通过 Kafka 发送,告警服务和客服系统消费这些事件。

异常事件流示例

告警服务发送异常事件:

from kafka import KafkaProducer
import jsondef create_alert_producer():return KafkaProducer(bootstrap_servers='localhost:9092',value_serializer=lambda v: json.dumps(v).encode('utf-8'))def send_alert_event(producer, alert_id, alert_details):event = {'alert_id': alert_id,'details': alert_details}producer.send('alert-events', key=alert_id.encode('utf-8'), value=event)# 示例调用
producer = create_alert_producer()
send_alert_event(producer, 'alert123', {'type': 'delay', 'description': 'Shipment delayed'})
producer.flush()
producer.close()

通过这些详细的陈述和核心代码示例,我们可以更好地理解和应用 Kafka,以支持复杂的物流系统需求。Kafka 的使用不仅提高了系统的灵活性和响应能力,还确保了数据的可靠性和顺序性。

四、Kafka 主题设计

在设计 Kafka 主题时,我们根据业务模块的不同需求划分了多个主题。每个主题都对应一个特定的业务领域,以便于管理和扩展。合理设置主题的分区数和保留时间是确保消息顺序性和系统吞吐量的关键。

主题划分
  • order-events 主题:用于处理订单相关的事件,如订单创建、更新和取消。
  • shipment-events 主题:用于处理运输任务及状态更新事件。
  • warehouse-events 主题:用于处理仓储相关的事件,如库存入库和出库。
  • alert-events 主题:用于处理异常和告警事件。
主题配置示例

在创建主题时,我们需要根据业务需求设置合适的分区数和保留时间。分区数影响并行处理能力,而保留时间决定了消息在 Kafka 中的存储时长。

# 创建 order-events 主题,设置 3 个分区和 7 天的保留时间
kafka-topics.sh --create --topic order-events --bootstrap-server localhost:9092 --partitions 3 --replication-factor 1 --config retention.ms=604800000# 创建 shipment-events 主题,设置 3 个分区和 7 天的保留时间
kafka-topics.sh --create --topic shipment-events --bootstrap-server localhost:9092 --partitions 3 --replication-factor 1 --config retention.ms=604800000# 创建 warehouse-events 主题,设置 3 个分区和 7 天的保留时间
kafka-topics.sh --create --topic warehouse-events --bootstrap-server localhost:9092 --partitions 3 --replication-factor 1 --config retention.ms=604800000# 创建 alert-events 主题,设置 3 个分区和 7 天的保留时间
kafka-topics.sh --create --topic alert-events --bootstrap-server localhost:9092 --partitions 3 --replication-factor 1 --config retention.ms=604800000

五、生产者设计

生产者负责将业务事件发送到相应的 Kafka 主题。为了提高系统的吞吐量和保证消息的顺序性,我们在生产者设计中采用了异步发送和合适的 key 设置。

生产者配置
  • 异步发送:通过异步发送提高消息的吞吐量。
  • key 设置:使用业务实体 ID 作为 key,确保同一实体的消息发送到同一分区,从而保证顺序。
  • 重试机制:配置重试机制,确保在网络抖动或临时故障时能够重试发送。
生产者代码示例

以下是一个生产者的代码示例,展示了如何发送订单事件:

from kafka import KafkaProducer
import jsondef create_producer():return KafkaProducer(bootstrap_servers='localhost:9092',value_serializer=lambda v: json.dumps(v).encode('utf-8'),retries=5,  # 发送失败重试次数acks='all',  # 确保消息被所有副本确认enable_idempotence=True  # 开启幂等性)def send_order_event(producer, order_id, order_details):order_event = {'order_id': order_id,'details': order_details}try:# 使用 order_id 作为 key,确保同一订单的消息顺序future = producer.send('order-events', key=order_id.encode('utf-8'), value=order_event)result = future.get(timeout=10)  # 异步发送print(f"Message sent to {result.topic} partition {result.partition} offset {result.offset}")except Exception as e:print(f"Failed to send message: {e}")# 示例调用
producer = create_producer()
send_order_event(producer, '12345', {'item': 'Laptop', 'quantity': 1})
producer.flush()
producer.close()

六、消费者设计

消费者负责从 Kafka 主题中消费消息并进行处理。为了实现负载均衡和幂等处理,我们在消费者设计中使用了消费者组和消息重试机制。

消费者配置
  • 消费者组:通过消费者组实现负载均衡,多个消费者可以共同消费一个主题的消息。
  • 幂等处理:确保每条消息只被处理一次,避免重复消费。
  • 消息重试和死信队列:在处理失败时支持消息重试或转入死信队列。
消费者代码示例

以下是一个消费者的代码示例,展示了如何消费订单事件:

from kafka import KafkaConsumer
import jsondef create_consumer(group_id, topic):return KafkaConsumer(topic,bootstrap_servers='localhost:9092',group_id=group_id,value_deserializer=lambda m: json.loads(m.decode('utf-8')),enable_auto_commit=False  # 手动提交偏移量)def process_message(message):# 幂等处理逻辑print(f"Processing message: {message}")def consume_events(consumer):for message in consumer:try:process_message(message.value)consumer.commit()  # 手动提交偏移量except Exception as e:print(f"Failed to process message: {e}")# 将消息转入死信队列或重试handle_failed_message(message.value)def handle_failed_message(message):# 处理失败的消息print(f"Handling failed message: {message}")# 示例调用
consumer = create_consumer('order-service-group', 'order-events')
consume_events(consumer)

七、数据流示意

通过 Kafka,我们实现了从用户下单到订单服务、仓储服务、运输服务、异常监控服务和通知服务的完整数据流。以下是数据流的简要描述:

  1. 用户下单后,订单服务发送订单创建事件到 order-events 主题。
  2. 仓储服务和运输服务消费 order-events 主题,进行备货和运输调度。
  3. 运输服务发送运输状态更新事件到 shipment-events 主题。
  4. 异常监控服务消费 shipment-events 主题,监控运输状态。
  5. 通知服务消费 alert-events 主题,向用户发送通知。

八、消息格式设计

我们采用 JSON 格式设计消息结构,包含事件类型、唯一事件 ID、时间戳等信息,方便解析和处理。

消息格式示例
{"event_type": "order_created","event_id": "evt-12345","timestamp": "2023-10-01T12:00:00Z","payload": {"order_id": "12345","customer_id": "cust-67890","items": [{"item_id": "item-001", "quantity": 2},{"item_id": "item-002", "quantity": 1}]}
}

九、容错与高可用设计

为了保证系统的高可用性和容错性,我们部署了多节点 Kafka 集群,并开启了副本机制。生产者和消费者的配置也进行了优化,以确保消息不丢失和幂等处理。

容错与高可用配置
  1. Kafka 集群配置

    • 部署多节点 Kafka 集群,设置副本因子为 3。副本因子决定了每个分区的副本数量,确保在节点故障时仍然可以访问数据。
    • 开启自动 leader 选举,确保节点故障时的高可用性。Kafka 会自动选择新的 leader 来替代故障的 leader,从而保证集群的稳定性。
    # 创建主题时设置副本因子
    kafka-topics.sh --create --topic order-events --bootstrap-server localhost:9092 --partitions 3 --replication-factor 3
    
  2. 生产者配置

    • 设置 retriesacks 参数,确保消息发送的可靠性。retries 参数指定了发送失败时的重试次数,acks 参数确保消息被所有副本确认。
    • 使用幂等性配置(enable.idempotence=true)避免重复消息。幂等性配置确保生产者在重试时不会产生重复的消息。
    from kafka import KafkaProducer
    import jsondef create_producer():return KafkaProducer(bootstrap_servers='localhost:9092',value_serializer=lambda v: json.dumps(v).encode('utf-8'),retries=5,  # 发送失败重试次数acks='all',  # 确保消息被所有副本确认enable_idempotence=True  # 开启幂等性)def send_event(producer, topic, key, event):try:future = producer.send(topic, key=key.encode('utf-8'), value=event)result = future.get(timeout=10)  # 异步发送print(f"Message sent to {result.topic} partition {result.partition} offset {result.offset}")except Exception as e:print(f"Failed to send message: {e}")# 示例调用
    producer = create_producer()
    event = {'event_type': 'order_created', 'order_id': '12345', 'timestamp': '2023-10-01T12:00:00Z'}
    send_event(producer, 'order-events', '12345', event)
    producer.close()
    
  3. 消费者配置

    • 使用消费者组实现负载均衡。消费者组允许多个消费者共同消费一个主题的消息,每个消费者处理不同的分区,从而实现负载均衡。
    • 手动提交偏移量,确保消息处理的幂等性。手动提交偏移量可以确保只有在消息处理成功后才更新偏移量,避免重复消费。
    • 处理失败时,将消息转入死信队列以便后续分析。死信队列用于存储处理失败的消息,方便后续分析和处理。
    from kafka import KafkaConsumer
    import jsondef create_consumer(group_id, topic):return KafkaConsumer(topic,bootstrap_servers='localhost:9092',group_id=group_id,value_deserializer=lambda m: json.loads(m.decode('utf-8')),enable_auto_commit=False  # 手动提交偏移量)def process_message(message):# 实现幂等处理逻辑print(f"Processing message: {message}")def consume_events(consumer):for message in consumer:try:process_message(message.value)consumer.commit()  # 手动提交偏移量except Exception as e:print(f"Failed to process message: {e}")# 可以将消息转入死信队列# 示例调用
    consumer = create_consumer('order-service-group', 'order-events')
    consume_events(consumer)
    
  4. 监控与告警

    • 使用 Kafka 自带的 JMX 指标进行监控。Kafka 提供了丰富的 JMX 指标,可以监控集群的运行状态、消息的吞吐量、延迟等。
    • 配置告警系统,及时处理 Kafka 集群的异常情况。可以使用 Prometheus 和 Grafana 等工具进行监控和告警配置。
    # Prometheus 配置示例
    global:scrape_interval: 15sscrape_configs:- job_name: 'kafka'static_configs:- targets: ['localhost:9092']
    
    # Grafana 告警配置示例
    apiVersion: 1datasources:- name: Prometheustype: prometheusurl: http://localhost:9090alerts:- name: KafkaHighLatencyrules:- alert: KafkaHighLatencyexpr: kafka_producer_latency > 100for: 5mlabels:severity: criticalannotations:summary: "Kafka producer latency is high"description: "Kafka producer latency has exceeded 100ms for more than 5 minutes."
    

通过这些设计和实现,我们可以确保物流系统中各个模块的高效协作和数据的可靠传递。Kafka 的高可用性和容错机制保证了系统的稳定性和可靠性,即使在节点故障或网络异常的情况下,系统仍然能够正常运行。

十、扩展与集成

Kafka的扩展与集成能力使其成为企业级数据处理的核心组件。通过Kafka Connect,我们可以将Kafka中的消息同步到各种数据仓库和分析平台,如数据库、Elasticsearch、Hadoop等。同时,利用Kafka Streams或Flink,我们能够实时处理和分析物流数据。此外,我们支持多系统(如财务系统、客户服务系统)订阅相关事件,实现业务协同。

10.1 Kafka Connect 示例

Kafka Connect是一个用于连接Kafka和其他数据系统的框架。以下是如何使用Kafka Connect将数据同步到Elasticsearch的示例:

{"name": "elasticsearch-sink","config": {"connector.class": "io.confluent.connect.elasticsearch.ElasticsearchSinkConnector","tasks.max": "1","topics": "order-events","key.ignore": "true","connection.url": "http://localhost:9200","type.name": "kafka-connect","name": "elasticsearch-sink"}
}
10.2 Kafka Streams 示例

Kafka Streams是一个用于实时处理数据流的库。以下是一个简单的Kafka Streams应用程序示例,用于处理订单事件:

import org.apache.kafka.streams.KafkaStreams;
import org.apache.kafka.streams.StreamsBuilder;
import org.apache.kafka.streams.StreamsConfig;
import org.apache.kafka.streams.kstream.KStream;import java.util.Properties;public class OrderProcessor {public static void main(String[] args) {Properties props = new Properties();props.put(StreamsConfig.APPLICATION_ID_CONFIG, "order-processor");props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");StreamsBuilder builder = new StreamsBuilder();KStream<String, String> orderStream = builder.stream("order-events");orderStream.foreach((key, value) -> System.out.println("Processing order: " + value));KafkaStreams streams = new KafkaStreams(builder.build(), props);streams.start();}
}

十一、Kafka 使用过程中可能遇到的问题

在使用Kafka的过程中,我们可能会遇到以下问题:

  1. 重复消费:由于消费者宕机或网络抖动,可能导致消息被重复消费。
  2. 消息丢失:生产者或消费者配置不当可能导致消息丢失。
  3. 消息积压:消费者处理速度慢导致消息积压。
  4. 消息顺序错乱:消息在不同分区间可能出现顺序错乱。
  5. 死信消息处理缺失:未处理的消息可能导致系统问题。
  6. 网络抖动或Kafka集群故障:可能导致消息传递失败。
  7. 数据格式不一致或兼容性问题:不同版本的消费者可能无法处理消息。

十二、解决方案

在使用Kafka的过程中,我们可能会遇到各种问题。以下是针对这些问题的详细解决方案,包括具体的代码示例和详细解释。

12.1 保证消息不丢失

为了确保消息不丢失,我们需要在生产者和消费者配置中采取一些措施:

  • 生产者配置

    • 开启幂等性:幂等性确保生产者在重试时不会产生重复的消息。
    • 设置重试机制:重试机制允许生产者在发送失败时进行多次尝试。
    • 设置 acks 参数:acks='all' 确保消息被所有副本确认后才认为发送成功。
    from kafka import KafkaProducer
    import jsondef create_producer():return KafkaProducer(bootstrap_servers='localhost:9092',value_serializer=lambda v: json.dumps(v).encode('utf-8'),retries=5,  # 发送失败重试次数acks='all',  # 确保消息被所有副本确认enable_idempotence=True  # 开启幂等性)producer = create_producer()
    
  • 消费者配置

    • 关闭自动提交 offset:自动提交 offset 可能导致消息在处理失败时被认为已经处理成功。
    • 手动提交 offset:确保只有在消息处理成功后才更新偏移量,避免重复消费。
    from kafka import KafkaConsumer
    import jsondef create_consumer(group_id, topic):return KafkaConsumer(topic,bootstrap_servers='localhost:9092',group_id=group_id,value_deserializer=lambda m: json.loads(m.decode('utf-8')),enable_auto_commit=False  # 手动提交偏移量)consumer = create_consumer('order-service-group', 'order-events')
    
12.2 解决重复消费问题

重复消费问题通常是由于消费者宕机或网络抖动导致的。解决重复消费问题的关键在于实现幂等性处理:

  • 业务层实现幂等性:通过消息的唯一 ID 做幂等判断,确保每条消息只被处理一次。

    processed_events = set()def process_message(message):event_id = message['event_id']if event_id not in processed_events:# 处理消息print(f"Processing message: {message}")processed_events.add(event_id)else:print(f"Duplicate message: {message}")for message in consumer:process_message(message.value)
    
12.3 处理消息积压

消息积压通常是由于消费者处理速度慢导致的。解决消息积压问题的关键在于优化消费者处理逻辑和增加消费者实例:

  • 优化消费者处理逻辑:提高消息处理速度,减少处理时间。

  • 增加消费者实例:通过增加消费者实例,实现消费并行,提升整体消费能力。

    from concurrent.futures import ThreadPoolExecutordef process_message(message):# 优化处理逻辑print(f"Processing message: {message}")def consume_events(consumer):with ThreadPoolExecutor(max_workers=10) as executor:for message in consumer:executor.submit(process_message, message.value)consumer = create_consumer('order-service-group', 'order-events')
    consume_events(consumer)
    
12.4 保证消息顺序

消息顺序错乱通常是由于消息在不同分区间传递导致的。解决消息顺序问题的关键在于使用业务实体 ID 作为 key,确保同一分区:

  • 生产者发送消息时使用业务实体 ID 作为 key:保证同一业务实体的消息发送到同一分区,从而保证顺序。

    def send_event(producer, topic, key, event):try:future = producer.send(topic, key=key.encode('utf-8'), value=event)result = future.get(timeout=10)  # 异步发送print(f"Message sent to {result.topic} partition {result.partition} offset {result.offset}")except Exception as e:print(f"Failed to send message: {e}")event = {'event_type': 'order_created', 'order_id': '12345', 'timestamp': '2023-10-01T12:00:00Z'}
    send_event(producer, 'order-events', 'order_id_12345', event)
    
12.5 死信队列设计

死信队列用于存储处理失败的消息,方便后续分析和处理:

  • 消费失败超过一定次数,将消息发送到死信主题:专门的死信处理服务进行补偿处理。

    def handle_failed_message(message):producer.send('dead-letter-queue', value=message)def consume_events(consumer):for message in consumer:try:process_message(message.value)consumer.commit()  # 手动提交偏移量except Exception as e:print(f"Failed to process message: {e}")handle_failed_message(message.value)consumer = create_consumer('order-service-group', 'order-events')
    consume_events(consumer)
    
12.6 网络和集群故障处理

网络抖动或Kafka集群故障可能导致消息传递失败。解决网络和集群故障问题的关键在于配置合理的重试策略和监控Kafka集群健康:

  • 生产者和消费者配置合理的重试策略:确保在网络抖动或集群故障时能够自动重试。

  • 监控Kafka集群健康:使用监控工具及时发现并处理异常情况。

    producer = KafkaProducer(bootstrap_servers='localhost:9092',retries=5,acks='all'
    )# Prometheus 配置示例
    global:scrape_interval: 15sscrape_configs:- job_name: 'kafka'static_configs:- targets: ['localhost:9092']
    
12.7 消息格式兼容性

数据格式不一致或兼容性问题可能导致不同版本的消费者无法处理消息。解决消息格式兼容性问题的关键在于使用统一的消息格式和版本控制:

  • 使用统一的消息格式(如 Avro、Protobuf):确保消息格式的一致性。

  • 版本控制:确保新版本的消费者能够兼容旧版本的消息格式。

    from confluent_kafka import avroschema_registry = avro.SchemaRegistryClient({'url': 'http://localhost:8081'})schema_str = """
    {"type": "record","name": "OrderEvent","fields": [{"name": "event_type", "type": "string"},{"name": "event_id", "type": "string"},{"name": "timestamp", "type": "string"},{"name": "order_id", "type": "string"}]
    }
    """schema = avro.loads(schema_str)
    

十三、总结

通过合理的主题设计、生产者和消费者配置、容错机制和扩展能力,我们在物流系统中成功应用了Kafka,实现了各业务模块的异步解耦和高效协同。在使用过程中,我们不断优化Kafka的配置和使用策略,解决了常见问题,提升了系统的稳定性和性能。

希望本文的分享能为其他使用Kafka的团队提供一些参考和借鉴。如果你有任何问题或建议,欢迎与我交流。通过这些详细的解释和代码示例,我们可以更好地理解和应用Kafka,以支持复杂的物流系统需求。


通过这些优化,你的博客将更具结构性和可读性,帮助读者更好地理解和应用Kafka。希望这些建议对你有所帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/912468.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/912468.shtml
英文地址,请注明出处:http://en.pswp.cn/news/912468.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Rust中模式匹配let Some(gas_price) = tx.gas_price用法

你问得非常好&#xff0c;let Some(gas_price) tx.gas_price 是 Rust 中的一种模式匹配写法&#xff0c;它用于从 Option 类型中提取值。 ✅ 背景知识&#xff1a;什么是 Option&#xff1f; 在 Rust 中&#xff0c;如果一个值可能存在也可能不存在&#xff0c;就会用 Option…

什么是LLM大语言模型

什么是LLM大语言模型 LLM的全称是&#xff0c;Large Language Model&#xff0c;简称LLM&#xff0c;翻译为大语言模型&#xff0c;其核心是模拟人类语言的复杂规律&#xff0c;实现语义理解、推理分析、文本生成等任务&#xff0c;主要目的是实现能读懂和说出人类语言的模型。…

杂谈-架构时代演进

关于未来 5-10 年软件系统演化方向 1. 云原生 ➝ 超云原生&#xff08;Post Cloud Native&#xff09; Kubernetes 平台自治化&#xff1a; K8s Operator 日益强大&#xff0c;逐步具备自愈、自动扩缩容、自动调优能力。 云厂商与企业私有云逐步融合为一体…

如何查看服务器的运行日志?

&#x1f7e2; 一、Linux服务器 Linux日志都在**/var/log**目录下&#xff0c;最常用的有&#xff1a; &#x1f4c2; 常用日志文件 文件内容/var/log/messages大部分系统日志&#xff08;CentOS常见&#xff09;/var/log/syslog系统消息日志&#xff08;Ubuntu/Debian常见&a…

在幸狐RV1106开发板上用gcc14.2本地编译安装postgresql 17.5数据库

在幸狐RV1106开发板上用gcc14.2本地编译安装postgresql 17.5数据库 编译环境&#xff1a; RV1106G3 Linux luckfox-rv1106 5.10.160 #3 Fri Jun 27 14:16:20 AWST 2025 armv7l GNU/Linux BusyBox v1.36.1 gcc version 14.2.0 (GCC) GNU ld (GNU Binutils) 2.44 GNU Make 4.4 n…

Go语言中map[string]interface{} 和 map[string]string的区别

在 Go 语言中&#xff0c;map[string]interface{} 和 map[string]string 是两种不同类型的 map&#xff0c;它们的主要区别在于值的类型以及这种差异带来的使用场景和灵活性的不同。 1. 值的类型 map[string]interface{}&#xff1a;这里的 interface{} 表示 Go 中的空接口类型…

AdGuard Home 安装及使用

AdGuard Home 是 AdGuard 开源的一个私人 DNS 服务端,只需在网关部署,即可实现全局域网的广告拦截与隐私反追踪。在 DNS 解析的过程中,匹配规则库内的 URL 进行拦截,同时在客户端中,还可以通过自定义过滤规则实现网页 DOM 的拦截。 基于 Golang 编写的 AdGuard Home,官方…

绕过 GraphQL 暴力破解保护

题目要求&#xff1a; 本实验的用户登录机制由 GraphQL API 提供支持。API 终端节点有一个速率限制器&#xff0c;如果它在短时间内收到来自同一源的太多请求&#xff0c;则会返回错误。 要解决实验问题&#xff0c;请暴力破解登录机制以 .使用身份验证实验室密码列表作为密码…

C/C++ 使用rapidjson库 操作Json格式文件(创建、插入、解析、修改、删除)

目录 一、前言 1.简介 2.兼容性 3.下载 4.安装 5.官方文档 6.自述 二、封装Json 1. 创建一个 Document 对象 2. "key":"value" 3. { } 4. [ ] 5. [ { }, { } ] 6. [ [ ], [ ] ] 7. { [ ], [ ] } 8. { { }, { } } 9. 将Document转换为字符串…

免安装一键修复网络诊断 + 权限修复!打印机共享错误工具适配 Win7/10/11

各位打印小能手们&#xff01;你们有没有遇到过共享打印机出问题&#xff0c;搞得自己焦头烂额的情况&#xff1f;比如系统一更新&#xff0c;打印机就连不上&#xff0c;打印任务失败&#xff0c;真的是让人崩溃啊&#xff01;别慌&#xff0c;今天就给大家全面介绍一款打印机…

电脑分屏快捷键5

按window右箭头&#xff1a; 按window左箭头&#xff1a;

nt!CcFlushCache函数分析之nt!CcFindBcb

nt!CcFindBcb函数分析 第一部分&#xff1a; 1: kd> p nt!CcAcquireByteRangeForWrite0x377: 80a13c49 e866e4ffff call nt!CcFindBcb (80a120b4) 1: kd> t nt!CcFindBcb: 80a120b4 55 push ebp 1: kd> kc # 00 nt!CcFindBcb 01 nt!CcAcqu…

矩阵及矩阵快速幂

一.矩阵与模板 【模板】矩阵求和 时间限制&#xff1a;1秒 内存限制&#xff1a;128M 题目描述 给出两个&#x1d45b;行&#x1d45a;列的矩阵&#xff0c;求两个矩阵的和 输入描述 第一行输入两个以空格分隔的整数&#x1d45b;,&#x1d45a;&#xff0c;表示矩…

rk3588获取探维雷达数据

可以在上期部署完 FASTLIO 的工作空间内&#xff0c;继续部署探维雷达的驱动程序。不要问为什么不用 mid360&#xff0c;因为我手上只有探维雷达。 探维雷达的驱动链接&#xff1a;https://github.com/TanwayLab/tanwaylidar_view/blob/main/README.md 下载驱动并编译 因为沿…

HTML简介,初步了解HTML

<html> <body> <h1>我的第一个标题</h1> <p1>我的第一个段落</p1> </body> </html> 什么是HTML HTML是用来描述网页的一种语言。 HTML指的是超文本标记语言。 HTML不是一种编程语言&#xff0c;而是一种标记语言。 标记语…

ARM集群服务器 定义

ARM集群服务器的核心定义可归纳为以下要点&#xff1a; 一、核心定义 ARM集群服务器是将‌多个基于ARM架构的处理器节点‌集成在单一物理机箱内&#xff0c;通过高速网络互联形成的分布式计算系统。每个节点均具备独立的计算单元&#xff08;如CPU、GPU/NPU&#xff09;、内存…

进程和线程的区别?

进程&#xff08;Process&#xff09;和线程&#xff08;Thread&#xff09;是操作系统资源分配和调度的核心概念&#xff0c;它们的区别主要体现在以下几个方面&#xff1a; 1. ​​定义与资源分配​​ ​​进程​​ 是程序的​​一次执行实例​​&#xff0c;拥有独立的地址空…

AR 学习:开启未来学习新视界​

AR 学习&#xff0c;即增强现实学习&#xff0c;是一种创新的学习方式&#xff0c;它巧妙地将增强现实技术融入到教育领域。简单来说&#xff0c;就是利用 AR 技术把虚拟的信息和现实场景完美融合&#xff0c;为学习者打造出一个沉浸式的学习环境。AR 学习打破了传统学习的边界…

C++并发编程-4.unique_lock,共享锁和递归锁

本文介绍C 并发中使用的其他类型的锁&#xff0c;包括unique_lock&#xff0c;shared_lock, 以及recursive_lock等。shared_lock和unique_lock比较常用&#xff0c;而recursive_lock用的不多&#xff0c;或尽可能规避用这种锁。 unique_lock unique_lock和lock_guard基本用法…

stm32 freertos下基于 hal库的模拟I2C驱动实现

一 前言 最近搞了两个项目&#xff0c;调了一版freertos下基于hal库得模拟I2C驱动&#xff0c;非常实用&#xff0c;直接拷贝就能用&#xff0c;这里做下记录&#xff0c;主要用到如下四个文件&#xff1a; delay.cdelay.hi2cc.ci2cc.h 二 代码实现 delay.c #include "…