当前位置: 首页 > news >正文

网站 多线常州模板建站哪家好

网站 多线,常州模板建站哪家好,名字设计网站,百度网页版入口在线登录一、引言 在分布式系统中#xff0c;Apache Kafka 作为一种高吞吐量的分布式发布订阅消息系统#xff0c;被广泛应用于日志收集、流式处理、消息队列等场景。然而#xff0c;在实际使用过程中#xff0c;可能会遇到消息丢失、乱序、重复消费等问题#xff0c;这些问题可能…一、引言 在分布式系统中Apache Kafka 作为一种高吞吐量的分布式发布订阅消息系统被广泛应用于日志收集、流式处理、消息队列等场景。然而在实际使用过程中可能会遇到消息丢失、乱序、重复消费等问题这些问题可能会影响系统的稳定性和可靠性。本文将深入探讨 Kafka 中这些问题的产生原因并提供有效的解决方案通过详细的示例帮助读者更好地理解和应对这些问题。 二、Kafka 基础概念与架构 一Kafka 的基本概念 主题Topic 主题是 Kafka 中消息的逻辑分类。生产者将消息发送到特定的主题消费者从感兴趣的主题中订阅消息。主题可以看作是一个消息的容器用于组织和管理具有相同类型或用途的消息。分区Partition 分区是主题的物理存储单元。每个主题可以被分为多个分区每个分区都是一个有序的消息序列。分区的主要作用是实现负载均衡提高 Kafka 的吞吐量和可扩展性。生产者Producer 生产者是向 Kafka 主题发送消息的客户端。生产者可以将消息发送到一个或多个主题并可以指定消息的属性和发送方式。生产者的主要作用是将应用程序产生的消息发送到 Kafka 中供消费者进行消费。消费者Consumer 消费者是从 Kafka 主题订阅消息的客户端。消费者可以从一个或多个主题中读取消息并可以按照自己的需求进行处理。消费者的主要作用是从 Kafka 中读取消息并将消息传递给应用程序进行处理。消费者组Consumer Group 消费者组是多个消费者的集合这些消费者共同从一个或多个主题中消费消息。消费者组的主要作用是实现负载均衡和容错当一个消费者出现故障时其他消费者可以继续消费消息保证系统的可用性。 二Kafka 的架构组成 生产者与消费者 生产者负责将消息发送到 Kafka 集群中的主题消费者负责从主题中读取消息并进行处理。生产者和消费者可以是独立的应用程序也可以是同一个应用程序的不同部分。Broker Broker 是 Kafka 集群中的服务器节点负责存储和管理消息。每个 Broker 可以存储多个主题的分区并且可以接收来自生产者的消息和向消费者发送消息。Zookeeper Zookeeper 是一个分布式协调服务用于管理 Kafka 集群的元数据。Zookeeper 存储了 Kafka 集群的配置信息、主题的分区信息、消费者组的信息等。Kafka 集群中的 Broker 和消费者都需要与 Zookeeper 进行通信以获取集群的元数据信息。 三、消息丢失问题及解决方案 一消息丢失的原因分析 生产者端 1未正确配置确认机制 Kafka 生产者可以通过配置确认机制来确保消息被成功发送到 Broker。如果未正确配置确认机制可能会导致消息在发送过程中丢失。例如如果将确认机制设置为 acks0表示生产者不等待 Broker 的确认直接将消息发送出去。这种情况下如果网络出现问题或者 Broker 出现故障消息可能会丢失。2网络故障 在网络不稳定的情况下生产者发送的消息可能会在传输过程中丢失。例如网络中断、数据包丢失等情况都可能导致消息丢失。3Broker 故障 如果 Broker 出现故障生产者发送的消息可能会丢失。例如Broker 磁盘故障、内存不足等情况都可能导致消息丢失。Broker 端 1数据存储故障 Broker 负责存储消息如果 Broker 的磁盘出现故障或者存储系统出现问题可能会导致消息丢失。2副本同步失败 Kafka 通过副本机制来保证数据的可靠性。如果副本同步失败可能会导致消息丢失。例如主副本出现故障从副本无法及时同步数据导致消息丢失。消费者端 1自动提交偏移量 如果消费者使用自动提交偏移量的方式并且在处理消息的过程中出现故障可能会导致已经处理的消息的偏移量被提交而后续重新启动的消费者会从下一个偏移量开始消费从而导致消息丢失。2处理消息失败 如果消费者在处理消息的过程中出现故障并且没有正确处理失败的情况可能会导致消息丢失。 二解决方案 生产者端 1正确配置确认机制 将确认机制设置为 acksall 或 acks-1表示生产者等待所有副本都确认收到消息后才认为消息发送成功。这样可以确保消息在发送过程中不会丢失。例如以下是 Java 生产者的配置示例 Properties props new Properties(); props.put(bootstrap.servers, localhost:9092); props.put(acks, all); props.put(retries, 0); props.put(batch.size, 16384); props.put(linger.ms, 1); props.put(buffer.memory, 33554432); props.put(key.serializer, org.apache.kafka.common.serialization.StringSerializer); props.put(value.serializer, org.apache.kafka.common.serialization.StringSerializer);ProducerString, String producer new KafkaProducer(props);2设置重试机制 在生产者配置中设置重试机制当消息发送失败时自动进行重试。这样可以提高消息发送的成功率减少消息丢失的可能性。例如以下是设置重试机制的配置示例 props.put(retries, 3);3使用事务 如果需要保证消息的原子性可以使用 Kafka 的事务功能。事务可以确保一组消息要么全部成功发送要么全部失败。例如以下是使用事务的 Java 生产者示例 Properties props new Properties(); props.put(bootstrap.servers, localhost:9092); props.put(transactional.id, my-transactional-id); props.put(acks, all); props.put(retries, 3); props.put(batch.size, 16384); props.put(linger.ms, 1); props.put(buffer.memory, 33554432); props.put(key.serializer, org.apache.kafka.common.serialization.StringSerializer); props.put(value.serializer, org.apache.kafka.common.serialization.StringSerializer);KafkaProducerString, String producer new KafkaProducer(props);producer.initTransactions();try {producer.beginTransaction();producer.send(new ProducerRecord(topic, message1));producer.send(new ProducerRecord(topic, message2));producer.commitTransaction(); } catch (ProducerFencedException | OutOfOrderSequenceException | AuthorizationException e) {// 处理异常通常情况下应该中止事务producer.abortTransaction(); }Broker 端 1配置副本数量 增加 Broker 的副本数量可以提高数据的可靠性。如果主副本出现故障从副本可以及时接管避免消息丢失。例如可以在 Broker 的配置文件中设置副本数量 num.replicas32监控副本同步状态 定期监控 Broker 的副本同步状态确保副本能够及时同步数据。如果发现副本同步失败及时采取措施进行修复。可以使用 Kafka 的命令行工具或者监控工具来监控副本同步状态。 消费者端 1手动提交偏移量 消费者可以使用手动提交偏移量的方式确保在处理完消息后再提交偏移量。这样可以避免在处理消息的过程中出现故障导致消息丢失。例如以下是 Java 消费者手动提交偏移量的示例 Properties props new Properties(); props.put(bootstrap.servers, localhost:9092); props.put(group.id, my-group); props.put(enable.auto.commit, false); props.put(key.deserializer, org.apache.kafka.common.serialization.StringDeserializer); props.put(value.deserializer, org.apache.kafka.common.serialization.StringDeserializer);KafkaConsumerString, String consumer new KafkaConsumer(props); consumer.subscribe(Arrays.asList(topic));while (true) {ConsumerRecordsString, String records consumer.poll(Duration.ofMillis(100));for (ConsumerRecordString, String record : records) {// 处理消息System.out.println(record.value());}consumer.commitSync(); }2处理消息失败时的重试策略 当消费者在处理消息的过程中出现故障时可以采取重试策略。例如可以将消息保存到本地队列中等故障恢复后重新处理。以下是一个处理消息失败时的重试策略示例 Properties props new Properties(); props.put(bootstrap.servers, localhost:9092); props.put(group.id, my-group); props.put(enable.auto.commit, false); props.put(key.deserializer, org.apache.kafka.common.serialization.StringDeserializer); props.put(value.deserializer, org.apache.kafka.common.serialization.StringDeserializer);KafkaConsumerString, String consumer new KafkaConsumer(props); consumer.subscribe(Arrays.asList(topic));while (true) {ConsumerRecordsString, String records consumer.poll(Duration.ofMillis(100));for (ConsumerRecordString, String record : records) {try {// 处理消息System.out.println(record.value());consumer.commitSync();} catch (Exception e) {// 处理消息失败将消息保存到本地队列中saveToLocalQueue(record);}} }private void saveToLocalQueue(ConsumerRecordString, String record) {// 将消息保存到本地队列的逻辑 }四、消息乱序问题及解决方案 一消息乱序的原因分析 生产者端 1多线程发送消息 如果生产者使用多线程发送消息并且没有正确控制消息的发送顺序可能会导致消息在 Broker 中存储的顺序与发送的顺序不一致从而出现消息乱序的问题。2网络延迟 在网络不稳定的情况下消息的发送可能会出现延迟导致消息在 Broker 中存储的顺序与发送的顺序不一致。Broker 端 1分区分配策略 Kafka 的分区分配策略可能会导致消息在不同的分区中存储的顺序不一致从而出现消息乱序的问题。例如如果使用轮询分配策略消息可能会被分配到不同的分区中而不同分区中的消息存储顺序可能不一致。2副本同步延迟 如果副本同步出现延迟可能会导致主副本和从副本中的消息顺序不一致从而出现消息乱序的问题。消费者端 1多线程消费消息 如果消费者使用多线程消费消息并且没有正确控制消息的处理顺序可能会导致消息在处理的顺序与存储的顺序不一致从而出现消息乱序的问题。2消费者组中的消费者数量变化 如果消费者组中的消费者数量发生变化可能会导致分区的重新分配从而影响消息的消费顺序出现消息乱序的问题。 二解决方案 生产者端 1单线程发送消息或使用同步发送 如果对消息的顺序有严格要求可以使用单线程发送消息或者使用同步发送的方式确保消息按照发送的顺序被存储到 Broker 中。例如以下是使用同步发送的 Java 生产者示例 Properties props new Properties(); props.put(bootstrap.servers, localhost:9092); props.put(acks, all); props.put(retries, 0); props.put(batch.size, 16384); props.put(linger.ms, 1); props.put(buffer.memory, 33554432); props.put(key.serializer, org.apache.kafka.common.serialization.StringSerializer); props.put(value.serializer, org.apache.kafka.common.serialization.StringSerializer);ProducerString, String producer new KafkaProducer(props);for (int i 0; i 10; i) {producer.send(new ProducerRecord(topic, Integer.toString(i))).get(); }2设置分区键 如果不能使用单线程发送消息可以通过设置分区键来确保具有相同分区键的消息被发送到同一个分区中从而保证消息的顺序。例如以下是设置分区键的 Java 生产者示例 Properties props new Properties(); props.put(bootstrap.servers, localhost:9092); props.put(acks, all); props.put(retries, 0); props.put(batch.size, 16384); props.put(linger.ms, 1); props.put(buffer.memory, 33554432); props.put(key.serializer, org.apache.kafka.common.serialization.StringSerializer); props.put(value.serializer, org.apache.kafka.common.serialization.StringSerializer);ProducerString, String producer new KafkaProducer(props);for (int i 0; i 10; i) {producer.send(new ProducerRecord(topic, Integer.toString(i), Integer.toString(i))); }Broker 端 1选择合适的分区分配策略 如果对消息的顺序有严格要求可以选择合适的分区分配策略确保消息在分区中的存储顺序与发送的顺序一致。例如可以使用按关键值分配策略确保具有相同关键值的消息被分配到同一个分区中。可以在消费者的配置中设置分区分配策略 Properties props new Properties(); props.put(bootstrap.servers, localhost:9092); props.put(group.id, my-group); props.put(enable.auto.commit, false); props.put(key.deserializer, org.apache.kafka.common.serialization.StringDeserializer); props.put(value.deserializer, org.apache.kafka.common.serialization.StringDeserializer); props.put(partition.assignment.strategy, org.apache.kafka.clients.consumer.RangeAssignor);KafkaConsumerString, String consumer new KafkaConsumer(props); consumer.subscribe(Arrays.asList(topic));2监控副本同步状态 定期监控 Broker 的副本同步状态确保副本中的消息顺序与主副本一致。如果发现副本同步出现问题及时采取措施进行修复。 消费者端 1单线程消费消息或使用顺序消费 如果对消息的顺序有严格要求可以使用单线程消费消息或者使用顺序消费的方式确保消息按照存储的顺序被处理。例如以下是单线程消费消息的 Java 消费者示例 Properties props new Properties(); props.put(bootstrap.servers, localhost:9092); props.put(group.id, my-group); props.put(enable.auto.commit, false); props.put(key.deserializer, org.apache.kafka.common.serialization.StringDeserializer); props.put(value.deserializer, org.apache.kafka.common.serialization.StringDeserializer);KafkaConsumerString, String consumer new KafkaConsumer(props); consumer.subscribe(Arrays.asList(topic));while (true) {ConsumerRecordsString, String records consumer.poll(Duration.ofMillis(100));for (ConsumerRecordString, String record : records) {// 处理消息System.out.println(record.value());}consumer.commitSync(); }2使用消息序号或时间戳 如果不能使用单线程消费消息可以使用消息序号或时间戳来确保消息的顺序。在处理消息时可以根据消息的序号或时间戳来判断消息的顺序并按照顺序进行处理。例如可以在消息中添加序号或时间戳消费者在处理消息时根据序号或时间戳进行排序 Properties props new Properties(); props.put(bootstrap.servers, localhost:9092); props.put(group.id, my-group); props.put(enable.auto.commit, false); props.put(key.deserializer, org.apache.kafka.common.serialization.StringDeserializer); props.put(value.deserializer, org.apache.kafka.common.serialization.StringDeserializer);KafkaConsumerString, String consumer new KafkaConsumer(props); consumer.subscribe(Arrays.asList(topic));while (true) {ConsumerRecordsString, String records consumer.poll(Duration.ofMillis(100));ListConsumerRecordString, String sortedRecords new ArrayList(records);sortedRecords.sort(Comparator.comparingLong(record - Long.parseLong(record.value().split(:)[0])));for (ConsumerRecordString, String record : sortedRecords) {// 处理消息System.out.println(record.value()); } consumer.commitSync(); } 五、消息重复消费问题及解决方案 一消息重复消费的原因分析 消费者端 1自动提交偏移量 如果消费者使用自动提交偏移量的方式并且在处理消息的过程中出现故障可能会导致已经处理的消息的偏移量被提交而后续重新启动的消费者会从下一个偏移量开始消费从而导致消息重复消费。2网络故障 在网络不稳定的情况下消费者可能会出现重复消费的情况。例如消费者在处理消息的过程中网络出现故障导致消费者无法及时向 Broker 提交偏移量。当网络恢复后消费者会重新从上次提交的偏移量开始消费从而导致消息重复消费。3消费者组中的消费者数量变化 如果消费者组中的消费者数量发生变化可能会导致分区的重新分配从而影响消息的消费顺序出现消息重复消费的情况。 二解决方案 消费者端 1手动提交偏移量 消费者可以使用手动提交偏移量的方式确保在处理完消息后再提交偏移量。这样可以避免在处理消息的过程中出现故障导致消息重复消费。例如以下是 Java 消费者手动提交偏移量的示例 Properties props new Properties(); props.put(bootstrap.servers, localhost:9092); props.put(group.id, my-group); props.put(enable.auto.commit, false); props.put(key.deserializer, org.apache.kafka.common.serialization.StringDeserializer); props.put(value.deserializer, org.apache.kafka.common.serialization.StringDeserializer);KafkaConsumerString, String consumer new KafkaConsumer(props); consumer.subscribe(Arrays.asList(topic));while (true) {ConsumerRecordsString, String records consumer.poll(Duration.ofMillis(100));for (ConsumerRecordString, String record : records) {// 处理消息System.out.println(record.value());}consumer.commitSync(); }2处理消息失败时的重试策略 当消费者在处理消息的过程中出现故障时可以采取重试策略。例如可以将消息保存到本地队列中等故障恢复后重新处理。同时需要确保在重新处理消息时不会导致消息重复消费。以下是一个处理消息失败时的重试策略示例 Properties props new Properties(); props.put(bootstrap.servers, localhost:9092); props.put(group.id, my-group); props.put(enable.auto.commit, false); props.put(key.deserializer, org.apache.kafka.common.serialization.StringDeserializer); props.put(value.deserializer, org.apache.kafka.common.serialization.StringDeserializer);KafkaConsumerString, String consumer new KafkaConsumer(props); consumer.subscribe(Arrays.asList(topic));while (true) {ConsumerRecordsString, String records consumer.poll(Duration.ofMillis(100));for (ConsumerRecordString, String record : records) {try {// 处理消息System.out.println(record.value());consumer.commitSync();} catch (Exception e) {// 处理消息失败将消息保存到本地队列中saveToLocalQueue(record);}} }private void saveToLocalQueue(ConsumerRecordString, String record) {// 将消息保存到本地队列的逻辑 }3幂等性处理 如果消费者需要保证对消息的处理是幂等的即多次处理同一条消息的结果是相同的。可以通过在处理消息时使用唯一标识符来判断消息是否已经被处理过。如果消息已经被处理过则直接忽略该消息。例如可以在消息中添加一个唯一标识符消费者在处理消息时根据唯一标识符判断消息是否已经被处理过 Properties props new Properties(); props.put(bootstrap.servers, localhost:9092); props.put(group.id, my-group); props.put(enable.auto.commit, false); props.put(key.deserializer, org.apache.kafka.common.serialization.StringDeserializer); props.put(value.deserializer, org.apache.kafka.common.serialization.StringDeserializer);KafkaConsumerString, String consumer new KafkaConsumer(props); consumer.subscribe(Arrays.asList(topic));SetString processedMessages new HashSet();while (true) {ConsumerRecordsString, String records consumer.poll(Duration.ofMillis(100));for (ConsumerRecordString, String record : records) {String messageId extractMessageId(record.value());if (!processedMessages.contains(messageId)) {// 处理消息System.out.println(record.value());processedMessages.add(messageId);consumer.commitSync();}} }private String extractMessageId(String message) {// 从消息中提取唯一标识符的逻辑return message.split(:)[0]; }生产者端优化 1设置消息的唯一标识 生产者在发送消息时可以为每个消息设置一个唯一的标识。这样即使消息被重复发送消费者也可以通过这个唯一标识来判断是否已经处理过该消息。例如可以在消息中添加一个自增的序列号或者使用 UUID 作为消息的唯一标识。2合理设置重试次数和间隔 生产者在发送消息失败时可以进行重试。但是需要合理设置重试次数和间隔避免过度重试导致消息重复发送。可以根据实际情况逐步增加重试间隔避免在短时间内频繁重试。同时设置一个合理的最大重试次数避免无限重试。 Broker 端配置调整 1设置消息保留时间 可以调整 Broker 上消息的保留时间确保在消息被消费之前不会被过早删除。这样即使消费者出现故障重新启动后也有机会重新消费未处理的消息而不会导致消息丢失或重复消费。例如可以在 Broker 的配置文件中设置 log.retention.hours 参数来调整消息的保留时间。2监控和管理消费者组 Broker 可以通过监控消费者组的状态及时发现消费者的故障和异常情况。例如如果一个消费者长时间没有提交偏移量Broker 可以认为该消费者出现故障并通知其他消费者进行重新分配分区。可以使用 Kafka 的监控工具如 Kafka Manager 或 Burrow来监控消费者组的状态。 六、实际应用案例分析 一电商系统中的消息处理 问题描述 在电商系统中订单处理、库存更新、物流通知等环节都需要使用消息队列进行异步处理。然而在实际应用中可能会出现消息丢失、乱序、重复消费等问题影响系统的稳定性和可靠性。解决方案 1消息丢失问题 在生产者端正确配置确认机制设置重试机制并使用事务确保消息的原子性。在 Broker 端配置副本数量监控副本同步状态。在消费者端手动提交偏移量处理消息失败时采取重试策略。2消息乱序问题 在生产者端使用单线程发送消息或设置分区键确保消息顺序。在 Broker 端选择合适的分区分配策略监控副本同步状态。在消费者端单线程消费消息或使用消息序号 / 时间戳确保消息顺序。3消息重复消费问题 在消费者端手动提交偏移量处理消息失败时采取重试策略并进行幂等性处理。实施步骤 1安装和配置 Kafka 安装 Kafka 集群并根据电商系统的需求进行配置如设置主题、分区数量、副本数量等。2开发生产者和消费者 使用 Kafka 的 Java API 开发生产者和消费者确保正确配置各种参数如确认机制、重试机制、分区键等。3处理消息丢失、乱序和重复消费问题 根据前面提到的解决方案在生产者和消费者中实现相应的逻辑确保消息的可靠性和顺序性。4监控和测试 使用 Kafka 的监控工具如 Kafka Manager、Burrow 等监控 Kafka 集群的运行状态及时发现和解决问题。同时进行充分的测试确保系统在各种情况下都能正确处理消息。 二金融系统中的实时交易处理 问题描述 在金融系统中实时交易处理需要高度的可靠性和准确性。消息队列在金融系统中用于异步处理交易请求、更新账户余额、发送交易通知等。然而消息丢失、乱序、重复消费等问题可能会导致交易错误、资金损失等严重后果。解决方案 1消息丢失问题 在生产者端使用高可靠性的确认机制如 acksall并设置重试机制和事务。在 Broker 端配置高副本数量确保数据的持久性。在消费者端手动提交偏移量处理消息失败时进行重试和恢复。2消息乱序问题 在生产者端使用同步发送或设置严格的分区键确保消息顺序。在 Broker 端选择合适的分区分配策略如按关键值分配保证消息在分区中的顺序。在消费者端使用单线程消费或严格按照消息序号处理消息。3消息重复消费问题 在消费者端手动提交偏移量进行幂等性处理确保对重复消息的正确处理。同时使用交易日志和状态检查来避免重复执行交易。实施步骤 1设计金融系统的消息架构 根据金融系统的业务需求设计合理的消息主题、分区和消费者组确保消息的高效处理和可靠性。2开发可靠的生产者和消费者 使用 Kafka 的 Java API 或其他适合金融系统的开发框架开发高可靠性的生产者和消费者确保消息的正确发送和处理。3处理消息问题 针对消息丢失、乱序和重复消费问题实施相应的解决方案如配置重试机制、监控副本同步、进行幂等性处理等。4进行严格的测试和监控 对金融系统进行全面的测试包括压力测试、故障注入测试等确保系统在各种情况下都能正确处理消息。同时使用监控工具实时监控 Kafka 集群和金融系统的运行状态及时发现和解决问题。 七、总结 Apache Kafka 作为一种强大的分布式消息系统在实际应用中可能会遇到消息丢失、乱序、重复消费等问题。通过深入理解 Kafka 的工作原理正确配置生产者、Broker 和消费者的参数以及采取适当的解决方案可以有效地解决这些问题提高系统的稳定性和可靠性。在实际应用中需要根据具体的业务需求和场景选择合适的解决方案并进行充分的测试和监控确保系统能够正确处理消息。同时随着 Kafka 的不断发展和演进可能会出现新的问题和挑战需要持续关注 Kafka 的最新动态不断学习和探索新的解决方案。
http://www.pierceye.com/news/107100/

相关文章:

  • 网站的收录情况怎么查企业网银怎么登录
  • 网站开发会计处理wordpress阅读随机增加
  • 兰州做网站公司哪家好公司网站建设是什么意思
  • 小区物业管理网站开发报告deal 网站要怎么做
  • seo站长助手wordpress 注册侧边栏
  • 做网站是要编程吗那些网站是html5做的
  • 网站开发图在网站做电子画册
  • 怎样建一个英文网站wordpress 多用户商城
  • 制作一个自适应网站源码app在线生成器
  • Dw做html网站项目管理软件有哪些
  • 天津网站建设定制软件开发服务公司
  • 做企业网站cms减肥网站源码
  • 建设工程检测预约网站猎头公司怎么找
  • 北京网站手机站建设公司手机网站开发常用工具
  • 太原做网站联系方式论坛的网站开发项目
  • drupal 做的网站网站设计与网站制作
  • 我要表白网站在线制作wordpress朗读句子插件
  • 黑龙江建设网官方怎么提高seo关键词排名
  • 拍卖网站开发多少钱十堰秦楚网招聘公告
  • 区域城市分站网站怎么做慈溪网站开发
  • 广州天河网站制作互联网十创业项目
  • 百度是不是只有在自己的网站发布才会被收录完备的常州网站优化
  • 响应式网站开发需要的条件百度信息流广告推广
  • 英文网站建设推广joomla drupal wordpress
  • 什么网站做简历免费下载怎么申请专线访问国际网络
  • 南三环做网站的公司网站开发开题报告计划进度安排
  • 我想建一个网站怎么建微信 网站提成方案点做
  • 苏中建设集团官方网站网络推广文章的方法
  • 月嫂云商城网站建设切换国外ip的软件
  • 沧州网站建设 凯航怎么样建立一个网站