簡體   English   中英

將Kafka與應用程序分離

[英]Decoupling Kafka from an Application

我有一個接收大量GET請求的應用程序(5分鍾內約250000個)。 該應用程序解析查詢參數並將其發布到Kafka。 要發布的代碼如下:

public class KafkaProcessor {

  private static final String BATCH_SIZE = "batch.size";
  private static final String REQUEST_REQUIRED_ACKS = "request.required.acks";
  private static final String PRODUCER_TYPE = "producer.type";
  private static final String VALUE_SERIALIZER = "value.serializer";
  private static final String KEY_SERIALIZER = "key.serializer";
  private static final String METADATA_BROKER_LIST = "bootstrap.servers";
  private static final String MAX_BLOCK_MS = "max.block.ms";
  private static final String KAFKA_ENABLED = "enabled";

  private static Properties props = new Properties();
  private static KafkaProducer<String, String> producer;
  private static ProducerRecord<String, String> producerRecord;
  private static String topic;


  static {
    boolean isEnabled = Boolean.parseBoolean(ResourceProps.INSTANCE.getKafkaProps(KAFKA_ENABLED));
    if (isEnabled) {
      //Setting up a producer configuration.
      props.put(METADATA_BROKER_LIST, "x.x.x.x:9092,y.y.y.y:9092");
      props.put(KEY_SERIALIZER, "org.apache.kafka.common.serialization.StringSerializer");
      props.put(VALUE_SERIALIZER, "org.apache.kafka.common.serialization.StringSerializer");
      props.put(PRODUCER_TYPE, "async");
      props.put(REQUEST_REQUIRED_ACKS, "1");
      props.put(BATCH_SIZE, "1000");
      props.put(MAX_BLOCK_MS, "10000");
      producer = new KafkaProducer<>(props);
      topic = "pixel-server";
    }
  }


  private static void publishToKafka(JSONObject data) {
      producerRecord = new ProducerRecord<String, String>(topic, data.toString());
      producer.send(producerRecord, new Callback() {
        @Override public void onCompletion(RecordMetadata recordMetadata, Exception exception) {
          if (exception != null) {
            exception.printStackTrace();
          }
        }
      });
  }
}

我的應用程序托管在一個AWS實例中。 Kafka服務器也位於另一台AWS機器中。

但是,如果kafka關閉或由於任何原因kafka響應緩慢,則我的應用程序凍結,無法進一步處理任何請求。 我想知道如何使我的應用程序獨立於Kafka,這意味着,如果kafka掉線(或響應速度很慢),那么它就不會影響我的應用程序。

我嘗試了幾種方法,例如,如果kafka給出了超時,然后計算超時異常的數量並停止發布到kafka,但是由於請求量非常大,所以到那時,我收到任何超時異常,我的應用程序凍結了。

任何幫助或指針,將不勝感激。

我正在使用Kafka 0.8.2。 我的服務器在Vertx中。 Ubuntu中使用的操作系統。 ulimit設置為max。

假設您的Kafka集群中有三個或更多節點(這對於任何高負載應用程序都是至關重要的),則可以嘗試一些技巧:

  1. 嘗試將acks producer config設置為0 這將影響您的應用程序的一致性(某些消息可能會在生產者端被丟棄,並將永遠丟失)。 文檔說:

    如果設置為零,那么生產者將完全不等待服務器的任何確認。 該記錄將立即添加到套接字緩沖區中並視為已發送。 在這種情況下,不能保證服務器已收到記錄

  2. 設置max.block.ms生產者配置為0 這將導致您的應用程序在每次發送到Kafka集群的每次發送時立即引發TimeoutException,而不會發生任何阻塞, 而只會在內存緩沖區溢出時發生 請注意,它僅影響客戶端阻止,而不影響網絡調用!

  3. request.timeout.ms減小為較小的值(例如10100 )。 這將導致Kafka客戶端在任何花費時間超過request.timeout.ms網絡操作上引發TimeoutException。

還有更多建議:

  1. 將您的Kafka實例更新到最新版本,以獲得更穩定的集群;

  2. 為了高可用性,您的Kafka群集必須至少包含三個節點(並且節點數始終為奇數,以避免出現裂腦情況

  3. 您應該嘗試使用max.batch.sizelinger.ms生產者配置,以達到應用程序的最佳延遲吞吐量比

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM