编写自己的storm任务

需要实现的目标是:
订单数统计,下单用户统计

1、创建maven工程(具体您可以百度)
2、pom.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.wsz.stormd</groupId>
    <artifactId>StormD11</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.storm</groupId>
            <artifactId>storm-core</artifactId>
            <version>1.0.3</version>
            <!--设置该属性编译时依赖该jar,打包后相关配置不依赖-->
            <scope>provided</scope>

        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.2.4</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>com.wsz.stormd.topology.PaymentTopologyMain</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

3、PaymentInfo

package com.wsz.stormd.entity;

import java.util.Date;
import java.util.Random;
import java.util.UUID;

/**
 * Created by wsz on 2017/3/31.
 */
public class PaymentInfo {

    private String orderId; // 订单编号
    private Date createOrderTime; // 订单创建时间
    private String paymentId; // 支付编号
    private Date paymentTime; // 支付时间
    private String productId; // 商品编号
    private String productName; // 商品名称
    private long productPrice; // 商品价格
    private long promotionPrice; // 商品促销价
    private String shopId; // 商铺编号
    private String shopName; // 商铺名称
    private String shopMobile; // 商铺手机
    private long payPrice; // 订单价格
    private int num; // 商品数量

    private Random random;

    public PaymentInfo() {
        random();
    }

    public PaymentInfo(String orderId, Date createOrderTime, String paymentId, Date paymentTime, String productId, String productName, long productPrice, long promotionPrice, String shopId, String shopName, String shopMobile, long payPrice, int num) {
        this.orderId = orderId;
        this.createOrderTime = createOrderTime;
        this.paymentId = paymentId;
        this.paymentTime = paymentTime;
        this.productId = productId;
        this.productName = productName;
        this.productPrice = productPrice;
        this.promotionPrice = promotionPrice;
        this.shopId = shopId;
        this.shopName = shopName;
        this.shopMobile = shopMobile;
        this.payPrice = payPrice;
        this.num = num;
        random();
    }

    // 赋值
    public void random() {
        random = new Random();
        this.orderId = UUID.randomUUID().toString().replace("-" , "");
        this.createOrderTime = new Date();
        this.paymentId = UUID.randomUUID().toString().replace("-" , "");
        this.paymentTime = new Date();

        this.productId = UUID.randomUUID().toString().replace("-" , "");
        this.productName = String.valueOf(random.nextInt(899)+100);


        this.num = random.nextInt(9)+1;

        this.productPrice = 300;
        this.promotionPrice = 208;

        this.payPrice = this.promotionPrice;
    }

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    public Date getCreateOrderTime() {
        return createOrderTime;
    }

    public void setCreateOrderTime(Date createOrderTime) {
        this.createOrderTime = createOrderTime;
    }

    public String getPaymentId() {
        return paymentId;
    }

    public void setPaymentId(String paymentId) {
        this.paymentId = paymentId;
    }

    public Date getPaymentTime() {
        return paymentTime;
    }

    public void setPaymentTime(Date paymentTime) {
        this.paymentTime = paymentTime;
    }

    public String getProductId() {
        return productId;
    }

    public void setProductId(String productId) {
        this.productId = productId;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public long getProductPrice() {
        return productPrice;
    }

    public void setProductPrice(long productPrice) {
        this.productPrice = productPrice;
    }

    public long getPromotionPrice() {
        return promotionPrice;
    }

    public void setPromotionPrice(long promotionPrice) {
        this.promotionPrice = promotionPrice;
    }

    public String getShopId() {
        return shopId;
    }

    public void setShopId(String shopId) {
        this.shopId = shopId;
    }

    public String getShopName() {
        return shopName;
    }

    public void setShopName(String shopName) {
        this.shopName = shopName;
    }

    public String getShopMobile() {
        return shopMobile;
    }

    public void setShopMobile(String shopMobile) {
        this.shopMobile = shopMobile;
    }

    public long getPayPrice() {
        return payPrice;
    }

    public void setPayPrice(long payPrice) {
        this.payPrice = payPrice;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    @Override
    public String toString() {
        return "PaymentInfo{" +
                "orderId='" + orderId + '\'' +
                ", createOrderTime=" + createOrderTime +
                ", paymentId='" + paymentId + '\'' +
                ", paymentTime=" + paymentTime +
                ", productId='" + productId + '\'' +
                ", productName='" + productName + '\'' +
                ", productPrice=" + productPrice +
                ", promotionPrice=" + promotionPrice +
                ", shopId='" + shopId + '\'' +
                ", shopName='" + shopName + '\'' +
                ", shopMobile='" + shopMobile + '\'' +
                ", payPrice=" + payPrice +
                ", num=" + num +
                ", random=" + random +
                '}';
    }
}

4、topology

package com.wsz.stormd.topology;

import org.apache.storm.Config;
import org.apache.storm.LocalCluster;
import org.apache.storm.StormSubmitter;
import org.apache.storm.topology.TopologyBuilder;

/**
 * Created by wsz on 2017/3/31.
 */
public class PaymentTopologyMain {

    public static void main(String []args ) throws Exception{

        TopologyBuilder topologyBuilder = new TopologyBuilder();

        topologyBuilder.setSpout("paymentInfo" , new PaymentInfoSpout());

        // 设置用于过滤订单的bolt,它订阅了PaymentInfoSpout
        topologyBuilder.setBolt("filter" , new FilterMessageBolt()).shuffleGrouping("paymentInfo");

        // 设置用于保存数据的bolt,它订阅了FilterMessageBolt
        topologyBuilder.setBolt("save" , new Save2RedisBolt()).shuffleGrouping("filter");

        Config config = new Config();
        config.setDebug(true);

        // 集群下的运行方式
        if(null != args && args.length > 0) {

            config.setNumWorkers(1);
            StormSubmitter.submitTopologyWithProgressBar(args[0] , config , topologyBuilder.createTopology());

        } else {
            // 本地运行方式
            config.setMaxTaskParallelism(1);
            new LocalCluster();
            StormSubmitter.submitTopology("test" , config , topologyBuilder.createTopology());
        }


    }

}

5、bolt
该bolt主要是用于过滤掉,不是今天的订单,不记录统计。

package com.wsz.stormd.topology;

import com.google.gson.Gson;
import com.wsz.stormd.entity.PaymentInfo;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.BasicOutputCollector;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseBasicBolt;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Tuple;
import org.apache.storm.tuple.Values;

import java.util.Calendar;
import java.util.Map;

/**
 * 用于过滤掉不是今天下的单,值统计今天的订单数
 *
 * Created by wsz on 2017/3/31.
 */
public class FilterMessageBolt extends BaseBasicBolt {

    private Gson gson;
    private Calendar calendar;
    @Override
    public void prepare(Map stormConf, TopologyContext context) {

        this.gson = new Gson();
        calendar = Calendar.getInstance();

        super.prepare(stormConf, context);
    }

    public void execute(Tuple tuple, BasicOutputCollector basicOutputCollector) {
        // 获取由spout吐过来的数据
        String value = tuple.getStringByField("payment");

        if(null == value || "".equals(value)) {
            return ;
        }

        PaymentInfo paymentInfo = gson.fromJson(value, PaymentInfo.class);

        calendar.setTime(paymentInfo.getPaymentTime());

        // 判断是不是今天下的单(今天是2017.3.31)
        if(calendar.get(Calendar.DATE ) == 31) {
            basicOutputCollector.emit(new Values(value));
        }
    }

    // 设置用于传输的字段
    public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
        outputFieldsDeclarer.declare(new Fields("payment"));
    }
}

6、统计订单数的bolt

package com.wsz.stormd.topology;

import com.google.gson.Gson;
import com.wsz.stormd.entity.PaymentInfo;
import org.apache.storm.state.KeyValueState;
import org.apache.storm.state.State;
import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.base.BaseStatefulBolt;
import org.apache.storm.tuple.Tuple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 *
 * 把数据保存到KeyValueState中
 * Created by wsz on 2017/3/31.
 */
public class Save2RedisBolt extends BaseStatefulBolt<KeyValueState>{

    private static final Logger LOG = LoggerFactory.getLogger(Save2RedisBolt.class);

    private KeyValueState<String , Long> state;

    private OutputCollector collector;

    private Gson gson;

    @Override
    public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
        this.collector = collector;
        this.gson = new Gson();
        super.prepare(stormConf, context, collector);
    }

    public void execute(Tuple tuple) {
        String value = tuple.getStringByField("payment");

        PaymentInfo paymentInfo = gson.fromJson(value, PaymentInfo.class);

        // 订单总数
        if(null == state.get("orderTotalNum")) {
            state.put("orderTotalNum" , (long)1);
        } else {
            state.put("orderTotalNum" , state.get("orderTotalNum")+1);
        }

        // 销售额
        if(null == state.get("totalSaleroom")) {
            state.put("totalSaleroom" , paymentInfo.getProductPrice());
        } else {
            state.put("totalSaleroom" , state.get("totalSaleroom")+paymentInfo.getProductPrice());
        }

        // 交易额
        if(null == state.get("orderTotalRealPay")) {
            state.put("orderTotalRealPay" , paymentInfo.getPayPrice());
        } else {
            state.put("orderTotalRealPay" , state.get("orderTotalRealPay")+paymentInfo.getPayPrice());
        }

        // 下单用户(不考虑去重)
        if(null == state.get("userNum")) {
            state.put("userNum" , Long.valueOf(1));
        } else {
            state.put("userNum", state.get("userNum") + 1);
        }

        LOG.info("orderTotalNum:"+state.get("orderTotalNum"));
        LOG.info("totalSaleroom:"+state.get("totalSaleroom"));
                    LOG.info("orderTotalRealPay:"+state.get("orderTotalRealPay"));
        LOG.info("userNum:"+state.get("userNum"));

        // 表示数据处理完成,可靠性
        collector.ack(tuple);
    }

    public void initState(KeyValueState keyValueState) {
        this.state = keyValueState;
    }
}

7、进入到pom.xml文件同级目录(Windows用命令提示符进入)
执行命令:mvn package -Dmaven.test.skip=true

8、在target目录下该StormD11-1.0-SNAPSHOT-jar-with-dependencies.jar包上传到nimbus机器上

9、运行jar
需配置好STORM_HOME
执行命令:
storm jar StormD11-1.0-SNAPSHOT-jar-with-dependencies.jar com.wsz.stormd.topology.PaymentTopologyMain wordcountpn

10、查看运行结果
进入到运行worker的机器上
进入到${STORM_HOME}/logs/workers-artifacts/wordcountpn-4-1490965507/6705目录下(这个路径不一定和其一致,从logs目录一直对应进入即可,每一个任务workers-artifacts都有自己的日志文件夹,wordcountpn-4-1490965507以拓扑名称开头)

执行命令:tail -100 worker.log

2017-03-31 21:07:48.978 c.w.s.t.Save2RedisBolt Thread-12-save-executor[5 5] [INFO] orderTotalNum:310
2017-03-31 21:07:48.979 c.w.s.t.Save2RedisBolt Thread-12-save-executor[5 5] [INFO] totalSaleroom:93000
2017-03-31 21:07:48.979 c.w.s.t.Save2RedisBolt Thread-12-save-executor[5 5] [INFO] rderTotalRealPay:64480
2017-03-31 21:07:48.979 c.w.s.t.Save2RedisBolt Thread-12-save-executor[5 5] [INFO] userNum:310
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值