PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/htest/stormtest/src/main/java/com/alibaba/jstorm/kafka/KafkaConsumer.java

https://gitlab.com/zhengdingke/htest
Java | 250 lines | 205 code | 35 blank | 10 comment | 39 complexity | 303ad27ecf7767856c992b922611c620 MD5 | raw file
  1. package com.alibaba.jstorm.kafka;
  2. import java.io.IOException;
  3. import java.net.ConnectException;
  4. import java.net.SocketTimeoutException;
  5. import java.nio.channels.UnresolvedAddressException;
  6. import java.util.Collections;
  7. import java.util.HashMap;
  8. import java.util.LinkedList;
  9. import java.util.List;
  10. import java.util.Map;
  11. import kafka.api.FetchRequest;
  12. import kafka.api.FetchRequestBuilder;
  13. import kafka.api.PartitionOffsetRequestInfo;
  14. import kafka.cluster.BrokerEndPoint;
  15. import kafka.common.ErrorMapping;
  16. import kafka.common.KafkaException;
  17. import kafka.common.TopicAndPartition;
  18. import kafka.javaapi.FetchResponse;
  19. import kafka.javaapi.OffsetRequest;
  20. import kafka.javaapi.PartitionMetadata;
  21. import kafka.javaapi.TopicMetadata;
  22. import kafka.javaapi.TopicMetadataRequest;
  23. import kafka.javaapi.consumer.SimpleConsumer;
  24. import kafka.javaapi.message.ByteBufferMessageSet;
  25. import org.apache.log4j.Logger;
  26. /**
  27. *
  28. * @author feilaoda
  29. *
  30. */
  31. public class KafkaConsumer {
  32. private static Logger LOG = Logger.getLogger(KafkaConsumer.class);
  33. public static final int NO_OFFSET = -1;
  34. private int status;
  35. private SimpleConsumer consumer = null;
  36. private KafkaSpoutConfig config;
  37. private LinkedList<Host> brokerList;
  38. private int brokerIndex;
  39. private BrokerEndPoint leaderBroker;
  40. private short fetchResponseCode = 0;
  41. public KafkaConsumer(KafkaSpoutConfig config) {
  42. this.config = config;
  43. this.brokerList = new LinkedList<Host>(config.brokers);
  44. this.brokerIndex = 0;
  45. }
  46. public ByteBufferMessageSet fetchMessages(int partition, long offset) throws IOException {
  47. String topic = config.topic;
  48. FetchRequest req = new FetchRequestBuilder().clientId(config.clientId).addFetch(topic, partition, offset, config.fetchMaxBytes)
  49. .maxWait(config.fetchWaitMaxMs).build();
  50. FetchResponse fetchResponse = null;
  51. SimpleConsumer simpleConsumer = null;
  52. try {
  53. simpleConsumer = findLeaderConsumer(partition);
  54. if (simpleConsumer == null) {
  55. // LOG.error(message);
  56. return null;
  57. }
  58. fetchResponse = simpleConsumer.fetch(req);
  59. } catch (Exception e) {
  60. if (e instanceof ConnectException || e instanceof SocketTimeoutException || e instanceof IOException
  61. || e instanceof UnresolvedAddressException) {
  62. LOG.warn("Network error when fetching messages:", e);
  63. if (simpleConsumer != null) {
  64. String host = simpleConsumer.host();
  65. int port = simpleConsumer.port();
  66. simpleConsumer = null;
  67. throw new KafkaException("Network error when fetching messages: " + host + ":" + port + " , " + e.getMessage(), e);
  68. }
  69. } else {
  70. throw new RuntimeException(e);
  71. }
  72. }
  73. if (fetchResponse.hasError()) {
  74. fetchResponseCode = fetchResponse.errorCode(topic, partition);
  75. if (fetchResponseCode == ErrorMapping.OffsetOutOfRangeCode()) {
  76. }
  77. // if (code == ErrorMapping.OffsetOutOfRangeCode() && config.resetOffsetIfOutOfRange) {
  78. // long startOffset = getOffset(topic, partition, config.startOffsetTime);
  79. // offset = startOffset;
  80. // }
  81. if(leaderBroker != null) {
  82. LOG.error("fetch data from kafka topic[" + config.topic + "] host[" + leaderBroker.host() + ":" + leaderBroker.port() + "] partition["
  83. + partition + "] error:" + fetchResponseCode);
  84. }else {
  85. }
  86. return null;
  87. } else {
  88. ByteBufferMessageSet msgs = fetchResponse.messageSet(topic, partition);
  89. return msgs;
  90. }
  91. }
  92. public short getAndResetFetchResponseCode(){
  93. short code = this.fetchResponseCode;
  94. this.fetchResponseCode = 0;
  95. return code;
  96. }
  97. private SimpleConsumer findLeaderConsumer(int partition) {
  98. try {
  99. if (consumer != null) {
  100. return consumer;
  101. }
  102. PartitionMetadata metadata = findLeader(partition);
  103. if (metadata == null) {
  104. leaderBroker = null;
  105. consumer = null;
  106. return null;
  107. }
  108. leaderBroker = metadata.leader();
  109. consumer = new SimpleConsumer(leaderBroker.host(), leaderBroker.port(), config.socketTimeoutMs, config.socketReceiveBufferBytes,
  110. config.clientId);
  111. return consumer;
  112. } catch (Exception e) {
  113. LOG.error(e.getMessage(), e);
  114. }
  115. return null;
  116. }
  117. protected PartitionMetadata findLeader(int partition) {
  118. PartitionMetadata returnMetaData = null;
  119. int errors = 0;
  120. int size = brokerList.size();
  121. Host brokerHost = brokerList.get(brokerIndex);
  122. try {
  123. if (consumer == null) {
  124. consumer = new SimpleConsumer(brokerHost.getHost(), brokerHost.getPort(), config.socketTimeoutMs, config.socketReceiveBufferBytes,
  125. config.clientId);
  126. }
  127. } catch (Exception e) {
  128. LOG.warn(e.getMessage(), e);
  129. consumer = null;
  130. }
  131. int i = brokerIndex;
  132. loop: while (i < size && errors < size + 1) {
  133. Host host = brokerList.get(i);
  134. i = (i + 1) % size;
  135. brokerIndex = i; // next index
  136. try {
  137. if (consumer == null) {
  138. consumer = new SimpleConsumer(host.getHost(), host.getPort(), config.socketTimeoutMs, config.socketReceiveBufferBytes,
  139. config.clientId);
  140. }
  141. List<String> topics = Collections.singletonList(config.topic);
  142. TopicMetadataRequest req = new TopicMetadataRequest(topics);
  143. kafka.javaapi.TopicMetadataResponse resp = null;
  144. try {
  145. resp = consumer.send(req);
  146. } catch (Exception e) {
  147. errors += 1;
  148. LOG.error("findLeader error, broker:" + host.toString() + ", will change to next broker index:" + (i + 1) % size);
  149. if (consumer != null) {
  150. consumer.close();
  151. consumer = null;
  152. }
  153. continue;
  154. }
  155. List<TopicMetadata> metaData = resp.topicsMetadata();
  156. for (TopicMetadata item : metaData) {
  157. for (PartitionMetadata part : item.partitionsMetadata()) {
  158. if (part.partitionId() == partition) {
  159. returnMetaData = part;
  160. break loop;
  161. }
  162. }
  163. }
  164. } catch (Exception e) {
  165. LOG.error("Error communicating with Broker:" + host.toString() + ", find Leader for partition:" + partition);
  166. } finally {
  167. if (consumer != null) {
  168. consumer.close();
  169. consumer = null;
  170. }
  171. }
  172. }
  173. return returnMetaData;
  174. }
  175. public long getOffset(String topic, int partition, long startOffsetTime) {
  176. SimpleConsumer simpleConsumer = findLeaderConsumer(partition);
  177. if (simpleConsumer == null) {
  178. LOG.error("Error consumer is null get offset from partition:" + partition);
  179. return -1;
  180. }
  181. TopicAndPartition topicAndPartition = new TopicAndPartition(topic, partition);
  182. Map<TopicAndPartition, PartitionOffsetRequestInfo> requestInfo = new HashMap<TopicAndPartition, PartitionOffsetRequestInfo>();
  183. requestInfo.put(topicAndPartition, new PartitionOffsetRequestInfo(startOffsetTime, 1));
  184. OffsetRequest request = new OffsetRequest(requestInfo, kafka.api.OffsetRequest.CurrentVersion(), simpleConsumer.clientId());
  185. long[] offsets = simpleConsumer.getOffsetsBefore(request).offsets(topic, partition);
  186. if (offsets.length > 0) {
  187. return offsets[0];
  188. } else {
  189. return NO_OFFSET;
  190. }
  191. }
  192. public void close() {
  193. if (consumer != null) {
  194. consumer.close();
  195. }
  196. }
  197. public SimpleConsumer getConsumer() {
  198. return consumer;
  199. }
  200. public void setConsumer(SimpleConsumer consumer) {
  201. this.consumer = consumer;
  202. }
  203. public int getStatus() {
  204. return status;
  205. }
  206. public void setStatus(int status) {
  207. this.status = status;
  208. }
  209. public BrokerEndPoint getLeaderBroker() {
  210. return leaderBroker;
  211. }
  212. public void setLeaderBroker(BrokerEndPoint leaderBroker) {
  213. this.leaderBroker = leaderBroker;
  214. }
  215. }