0

我正在使用 Apache Storm 1.1.2、Apache Kafka 0.10、Zookeeper 和 Docker Compose 编写一个 dockerized Java 9 Spring 应用程序。

我的拓扑完全在我的 dockerized 服务内的本地集群上运行,但现在我将它移动到生产集群,出现了一个问题。

我为 Storm 集群创建提交拓扑的服务似乎工作正常,并且代码在 PostConstruct 内部看起来大多像这样

KafkaSpoutConfig<String,String> spoutConf = 
KafkaSpoutConfig.builder("kafka:9092", "topic")
  .setProp(ConsumerConfig.GROUP_ID_CONFIG, "my-group-id")
  .setProp(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, MyDeserializer.class)
.build();

TopologyBuilder builder = new TopologyBuilder();
builder.setSpout("kafkaSpoutId", new KafkaSpout<String,String>(spoutConf));
builder.setBolt("boltId", new MyBolt()).shuffleGrouping("kafkaSpoutId");

Config conf = new Config();
conf.setNumWorkers(2);
conf.put(Config.STORM_ZOOKEEPER_SERVERS, List.of("zookeeper"));
conf.put(Config.STORM_ZOOKEEPER_PORT, 2181);

conf.put(Config.NIMBUS_SEEDS, List.of("nimbus"));
conf.put(Config.NIMBUS_THRIFT_PORT, 6627);

System.setProperty("storm.jar","/opt/app.jar");
StormSubmitter.submitTopology("topology-id", conf, builder.createTopology());

我的 docker compose 文件看起来像这样。

version: "2.1"

services:
  my-service:
  image: my-service
  mem_limit: 4G
  memswap_limit: 4G
  networks:
    - default
  environment:
    - SPRING_PROFILES_ACTIVE=local

nimbus:
  image: storm:1.1.2
  container_name: nimbus
  command: >
    storm nimbus
      -c storm.zookeeper.servers="[\"zookeeper\"]"
      -c nimbus.seeds="[\"nimbus\"]"
  networks:
    - default
  ports:
    - 6627:6627

supervisor:
  image: storm:1.1.2
  container_name: supervisor
  command: >
    storm supervisor
      -c storm.zookeeper.servers="[\"zookeeper\"]"
      -c nimbus.seeds="[\"nimbus\"]"
  networks:
    - default
  depends_on:
    - nimbus
  links:
    - nimbus
  restart: always
  ports:
    - 6700
    - 6701
    - 6702
    - 6703

ui:
  image: storm:1.1.2
  command: storm ui -c nimbus.seeds="[\"nimbus\"]"
  networks: 
    - default
  ports:
    - 8081:8080

networks:
  default:
    external:
      name: myNetwork

所有的容器都起来了。在 UI 中,我可以看到在 post 构造中创建的拓扑,但没有正在处理 Kafka 消息,并且应该使用本地 Kafka 生产者来生成聚合的 Bolt 没有发布。

在主管容器中,/logs/worker-artifact/topology-id****/6700/worker.log我可以看到重复的两个异常。

第一个(我认为更重要)是ClassNotFoundException: org.apache.storm.kafka.spout.KafkaSpout

第二个例外是org.apache.storm.shade.org.jboss.netty.channel.ChannelException: Failed to bind to: 0.0.0.0/0.0.0.0:6700

更新

不幸的是,我不能发布我的整个 pom,但这是我的 Storm 依赖项

 <dependency>
        <groupId>org.apache.storm</groupId>
        <artifactId>storm-core</artifactId>
        <version>${storm.version}</version>
    </dependency>

    <dependency>
        <groupId>org.apache.storm</groupId>
        <artifactId>storm-kafka-client</artifactId>
        <version>${storm.version}</version>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
    </dependency>

这是我的spring-boot-maven-plugin。我虽然添加配置以使复制到我的容器的 jar 不可执行,但可以解决问题。当我检查容器中的 jar 时,它看起来包含依赖项的行 jar 但也有大量乱码

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
              <executable>false</executable>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
        </plugin>
    </plugins>
</build>

这是我的大部分 dockerfile

FROM ${docker.repository}/openjdk:9.0.1

EXPOSE 80 1099

WORKDIR /opt

ENTRYPOINT ["java", \
    "-Dinfo.serviceName=${project.artifactId}", \
    "-Dinfo.serviceVersion=${project.version}"]

CMD ["-jar", "app.jar"]

LABEL VERSION="${project.version}" DESCRIPTION="${project.description}"

COPY ${project.build.finalName}-exec.jar /opt/app.jar
4

1 回答 1

0

我想到了。问题是我正在形成一个不可执行的罐子,但不是一个真正的胖罐子。我在我的 pom 中添加了以下插件

<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <descriptorRefs>
      <descriptorRef>jar-with-dependencies</descriptorRef>
    </descriptorRefs>
  </configuration>
</plugin>
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <source>1.8</source>
    <target>1.8</target>
  </configuration>
</plugin>

接下来我将 System 属性更改为 System.setProperty("storm.jar", "/opt/storm.jar");

并将以下行添加到我的 Dockerfile

COPY ${project.build.finalName}-jar-with-dependencies.jar /opt/storm.jar

最后,我将首先运行,mvn comiple assembly:single然后将具有依赖项的项目 jar 从 target/ 复制到 target/docker-ready,就像从项目目录 cp target/project-jar-with-dependencies.jar target/docker-ready/中一样,最后运行mvn verify docker:build

于 2018-09-12T17:06:44.933 回答