storm七之storm java示例

2023-10-30

通过前面6个章节,我们大致了解apache storm的核心细节了,现在我们开始写一些简单的代码,来感受下storm的魅力。

场景——移动呼叫日志分析

移动电话呼叫号及其持续时间将作为Apache stormd输入,storm根据拨号方和接收方之间的电话号码以及通话次数进行分组

 

 

 

Spout Creation

Spoutstorm用于数据生成一个组件,。

通常,Spout实现一个IRichSpout接口。

IRichSpout接口有以下重要的方法

1.open−提供Spout以及spout执行环境。executors运行这个方法来初始化spout

2.nextTuple通过收集器发送产生的数据

3.close关闭Spout时调用close方法

4.declareOutputFields声明输出元组schema

5.ack处理特定的元组

6.fail指定一个特定的不处理和再加工元组。

 

open

open方法签名如下:

open(map conf,TopologyContext context,SpoutOutputCollectorcollector)

参数解析:

confSpout提供storm配置。

context:topology中提供Spout的完整信息,包括:任务id,输入输出信息

collector:保证我们发送的数据能被bolt处理

 

nextTuple

nextTuple方法签名如下:

nextTuple()

nextTuple()定期方法定期的被相同循环中的ack()方法和fail()方法调用

当没有工作要做的时候必须释放线程,以保证其他方法有机会被调用。

因此,nextTuple首先要检查处理是否已经完成。

如果完成,在结果返回之前,为了降低处理器的负载,该线程应该至少睡1毫秒。

 

 

close

Close方法签名如下:

close()

declareOutputFields

declareOutputFields方法前面如下:

declareOutputFields(OutputFieldsDeclarer declarer)

参数说明:

Declarer声明输出流ids,输出字段,等等。

这个方法用于指定tuple输出的shema

 

ack

ack方法的签名如下:

ack(Object msgId)

这个方法表明指定的tuple已经被处理过。

 

fail

fail方法签名如下:

fail(Object msgId)

表明spout发送出的数据并没有被完全处理,storm会重新处理这个数据。

FakeCallLogReaderSpout

现在我们要收集手机日志的详细信息,包含:

1.主叫号码

2.被叫号码

3.通话时长

因为我们没有实时通话记录信息,那么我们就自己模拟通话记录。

Random随机类产生模拟的通话信息。

完整的程序代码如下所示。

Coding FakeCallLogReaderSpout.java

 

 

import java.util.*;

//import storm tuple packages

import backtype.storm.tuple.Fields;

import backtype.storm.tuple.Values;

 

//import Spout interface packages

import backtype.storm.topology.IRichSpout;

import backtype.storm.topology.OutputFieldsDeclarer;

import backtype.storm.spout.SpoutOutputCollector;

import backtype.storm.task.TopologyContext;

 

//Create a class FakeLogReaderSpout which implement IRichSpout interface

   to access functionalities

public class FakeCallLogReaderSpout implements IRichSpout {

   //Create instance for SpoutOutputCollector which passes tuples to bolt.

   private SpoutOutputCollector collector;

   private boolean completed = false;

   //Create instance for TopologyContext which contains topology data.

   private TopologyContext context;

   //Create instance for Random class.

   private Random randomGenerator = new Random();

   private Integer idx = 0;

 

   @Override

   public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {

      this.context = context;

      this.collector = collector;

   }

 

   @Override

   public void nextTuple() {

      if(this.idx <= 1000) {

         List<String> mobileNumbers = new ArrayList<String>();

         mobileNumbers.add("1234123401");

         mobileNumbers.add("1234123402");

         mobileNumbers.add("1234123403");

         mobileNumbers.add("1234123404");

 

         Integer localIdx = 0;

         while(localIdx++ < 100 && this.idx++ < 1000) {

            String fromMobileNumber = mobileNumbers.get(randomGenerator.nextInt(4));

            String toMobileNumber = mobileNumbers.get(randomGenerator.nextInt(4));

            while(fromMobileNumber == toMobileNumber) {

               toMobileNumber = mobileNumbers.get(randomGenerator.nextInt(4));

            }

            Integer duration = randomGenerator.nextInt(60);

            this.collector.emit(new Values(fromMobileNumber, toMobileNumber, duration));

         }

      }

   }

 

   @Override

   public void declareOutputFields(OutputFieldsDeclarer declarer) {

      declarer.declare(new Fields("from", "to", "duration"));

   }

 

   //Override all the interface methods

   @Override

   public void close() {}

 

   public boolean isDistributed() {

      return false;

   }

 

   @Override

   public void activate() {}

 

   @Override

   public void deactivate() {}

 

   @Override

   public void ack(Object msgId) {}

 

   @Override

   public void fail(Object msgId) {}

 

   @Override

   public Map<String, Object> getComponentConfiguration() {

      return null;

   }

}

 

 

Bolt Creation

Bolt是一个以元组作为输入处理元组产生新的元组作为输出的组件

Bolt通常需要实现IRichBolt接口。

在这个程序中,两个boltCallLogCreatorBolt和CallLogCounterBolt用来执行的操作处理

 

IRichBolt接口有如下方法:

1.prepare 准备−提供bolt以及bolt执行环境。

executors会执行这个方法去初始化bolt

2.execute处理输入的单个tuple

3.cleanup 要关闭bolt时被调用

4.declareOutputFields声明输出元组schema

Prepare

prepare方法的签名如下:

prepare(Map conf, TopologyContext context, OutputCollector collector)

参数说明:

Conf:为bolt提供配置

Context:topology提供完整bolt位置信息,包括它的任务id,输入和输出信息等。

Collector:保证处理过的tuple能被发送出去。

Execute

execute方法签名如下:

execute(Tuple tuple)//这里的tuple是将被处理的输入tuple

execute方法每次处理一个元组。

通过tuple的getValue方法访问元组的数据。

输入元组不是必须立即处理的,可以过一会再处理

可以处理多个元组处理后产生单个tuple作为输出tuple

处理过的tuple可以使用OutputCollector类发送出去

 

Cleanup

cleanup方法签名如下:

Cleanup()

 

declareOutputFields

declareOutputFields方法签名如下:

declareOutputFields(OutputFieldsDeclarer declarer)//这里的declarer用来声明输出流的ids,输出字段等信息

这个方法用来指定tuple的输出shema

Call log Creator Bolt

Call log creator bolt 接收通话日志tuple

通话日志tuple包含主叫号码,被叫号码和通话时长

 

This bolt simply creates a new value by combining the caller number and the receiver number.

这个螺栓简单地创建了一个新值通过调用者数量和接收方号码。

格式化后的新值字段叫call,格式是Caller number – Receiver number

完整的代码如下所示:

//import util packages

import java.util.HashMap;

import java.util.Map;

 

import backtype.storm.tuple.Fields;

import backtype.storm.tuple.Values;

import backtype.storm.task.OutputCollector;

import backtype.storm.task.TopologyContext;

 

//import Storm IRichBolt package

import backtype.storm.topology.IRichBolt;

import backtype.storm.topology.OutputFieldsDeclarer;

import backtype.storm.tuple.Tuple;

 

//Create a class CallLogCreatorBolt which implement IRichBolt interface

public class CallLogCreatorBolt implements IRichBolt {

   //Create instance for OutputCollector which collects and emits tuples to produce output

   private OutputCollector collector;

 

   @Override

   public void prepare(Map conf, TopologyContext context, OutputCollector collector) {

      this.collector = collector;

   }

 

   @Override

   public void execute(Tuple tuple) {

      String from = tuple.getString(0);

      String to = tuple.getString(1);

      Integer duration = tuple.getInteger(2);

      collector.emit(new Values(from + " - " + to, duration));

   }

 

   @Override

   public void cleanup() {}

 

   @Override

   public void declareOutputFields(OutputFieldsDeclarer declarer) {

      declarer.declare(new Fields("call", "duration"));

   }

   @Override

   public Map<String, Object> getComponentConfiguration() {

      return null;

   }

}

 

Call log Counter Bolt

Call log counter bolt 接收上一个bolt call及其持续时间作为一个tuple

boltprepare方法中初始化一个字典(Map)对象。

execute 方法,它检查字典中的tuple并为tuple中的每一个新的call”值创建一个条目entry,并设置字典的值为1

对于字典中现有的条目,则将其值+1

简而言之,这个bolt在字典中保存call和它的数量

如果不保存在字典中,我们也可以把它保存懂啊一个数据源中。

而不是保存调用及其计数在字典里,我们也可以将它保存到一个数据源。

完整的程序代码如下

Coding − CallLogCounterBolt.java

import java.util.HashMap;

import java.util.Map;

 

import backtype.storm.tuple.Fields;

import backtype.storm.tuple.Values;

import backtype.storm.task.OutputCollector;

import backtype.storm.task.TopologyContext;

import backtype.storm.topology.IRichBolt;

import backtype.storm.topology.OutputFieldsDeclarer;

import backtype.storm.tuple.Tuple;

 

public class CallLogCounterBolt implements IRichBolt {

   Map<String, Integer> counterMap;

   private OutputCollector collector;

 

   @Override

   public void prepare(Map conf, TopologyContext context, OutputCollector collector) {

      this.counterMap = new HashMap<String, Integer>();

      this.collector = collector;

   }

 

   @Override

   public void execute(Tuple tuple) {

      String call = tuple.getString(0);

      Integer duration = tuple.getInteger(1);

      if(!counterMap.containsKey(call)){

         counterMap.put(call, 1);

      }else{

         Integer c = counterMap.get(call) + 1;

         counterMap.put(call, c);

      }

      collector.ack(tuple);

   }

 

   @Override

   public void cleanup() {

      for(Map.Entry<String, Integer> entry:counterMap.entrySet()){

         System.out.println(entry.getKey()+" : " + entry.getValue());

      }

   }

 

   @Override

   public void declareOutputFields(OutputFieldsDeclarer declarer) {

      declarer.declare(new Fields("call"));

   }

   @Override

   public Map<String, Object> getComponentConfiguration() {

      return null;

   }

}

 

 

Creating Topology

通常stormtopology是一个Thrift结构。

TopologyBuilder类提供了简单易用的方法来创建复杂的topology

TopologyBuilder类提供了方法来设spout(setSpout)和bolt(setBolt)。

总之,TopologyBuilder createTopology创建topology

下面的代码片段为创建topology的事例:

TopologyBuilder builder = new TopologyBuilder();

builder.setSpout("call-log-reader-spout", new FakeCallLogReaderSpout());

builder.setBolt("call-log-creator-bolt", new CallLogCreatorBolt()).shuffleGrouping("call-log-reader-spout");

builder.setBolt("call-log-counter-bolt", new CallLogCounterBolt()).fieldsGrouping("call-log-creator-bolt", new Fields("call"));

 

shuffleGrouping和fieldsGrouping方法帮助spoutboltstream进行分组。

 

Local Cluster

为了便于开发,我们可以使用“LocalCluster”对象创建一个本地集群,然后使用“LocalCluster”类的“submitTopology”方法提交topology

其中,“submitTopology”的参数之一是Config”类的一个实例。

Config”类的作用是提交topology之前设置配置选项。

 

This configuration option will be merged with the cluster configuration at run time and sent to all task (spout and bolt) with the prepare method.

这种配置选项将合并在运行时间和发送到所有集群配置任务(壶嘴和螺栓)的准备方法。

一旦topology提交到集群,我们需要等待10秒以便集群计算提交topology,然后使用shutdown方法关闭集群。

完整的程序代码如下

Coding − LogAnalyserStorm.java

 

import backtype.storm.tuple.Fields;

import backtype.storm.tuple.Values;

//import storm configuration packages

import backtype.storm.Config;

import backtype.storm.LocalCluster;

import backtype.storm.topology.TopologyBuilder;

 

//Create main class LogAnalyserStorm submit topology.

public class LogAnalyserStorm {

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

      //Create Config instance for cluster configuration

      Config config = new Config();

      config.setDebug(true);

      //

      TopologyBuilder builder = new TopologyBuilder();

      builder.setSpout("call-log-reader-spout", new FakeCallLogReaderSpout());

 

      builder.setBolt("call-log-creator-bolt", new CallLogCreatorBolt())

         .shuffleGrouping("call-log-reader-spout");

 

      builder.setBolt("call-log-counter-bolt", new CallLogCounterBolt())

         .fieldsGrouping("call-log-creator-bolt", new Fields("call"));

      LocalCluster cluster = new LocalCluster();

      cluster.submitTopology("LogAnalyserStorm", config, builder.createTopology());

      Thread.sleep(10000);

      //Stop the topology

      cluster.shutdown();

   }

}

 

Building and Running the Application

完整的应用程序有四个Java代码

1.FakeCallLogReaderSpout.java
2.CallLogCreaterBolt.java
3.CallLogCounterBolt.java
4.LogAnalyerStorm.java

 

应用程序可以使用下面的命令构建:

javac -cp “/path/to/storm/apache-storm-0.9.5/lib/*” *.java

应用程序可以使用以下的命令运行:

java -cp “/path/to/storm/apache-storm-0.9.5/lib/*”:. LogAnalyserStorm

Output

一旦应用程序启动,它将输出完整的集群启动进程的细节,poutbolt处理过程,最后,集群关闭这些处理过程

 "CallLogCounterBolt"代码中,我们打印了callcount的具体信息。

这些信息将显示在控制台如下

1234123402 - 1234123401 : 78
1234123402 - 1234123404 : 88
1234123402 - 1234123403 : 105
1234123401 - 1234123404 : 74
1234123401 - 1234123403 : 81
1234123401 - 1234123402 : 81
1234123403 - 1234123404 : 86
1234123404 - 1234123401 : 63
1234123404 - 1234123402 : 82
1234123403 - 1234123402 : 83
1234123404 - 1234123403 : 86
1234123403 - 1234123401 : 93

JVM外的其他语言

Storm topology通过Thrift接口实现,这使得很容易任何语言去提交topologystorm集群中

Storm支持Ruby、Python和许多其他语言。

让我们看看使用python事例:

Python Binding

Python是一种解释,交互的、面向对象的高级编程语言。

Storm支持Python实现其topology

Python支持 emitting, anchoring, acking, and logging operations

如你所知,bolt可以使用任何语言定义

 

Bolts written in another language are executed as sub-processes, and Storm communicates with those sub-processes with JSON messages over stdin/stdout.

下面来看一个用python编写的bolt来计算单词出现次数的事例:

 

public static class WordCount implements IRichBolt {
public WordSplit() {
super("python", "splitword.py");
}

public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word"));
}
}

 

Here the class WordCount implements the IRichBolt interface and running with python implementation specified super method argument "splitword.py".

现在创建一个名为“splitword.py”的python实现。

import storm
class WordCountBolt(storm.BasicBolt):
def process(self, tup):
words = tup.values[0].split(" ")
for word in words:
storm.emit([word])
WordCountBolt().run()

 

这是Python实现计数的示例。

同样你也可以其他支持语言实现

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

storm七之storm java示例 的相关文章

  • 如何将未知列数的 ResultSet 映射到 List 并将其显示在 HTML 表中?

    我使用 Netbeans GlassFish 和 JavaDB 创建了一个数据库应用程序 现在我的控制器 Servlet 代码执行一些动态 SQL 查询并返回结果集 或者我可以更改 toString 现在 如何以表格格式显示返回的结果集 我
  • 在Java中将*s打印为三角形?

    我在 Java 课程中的作业是制作 3 个三角形 一份左对齐 一份右对齐 一份居中 我必须为什么类型的三角形制作一个菜单 然后输入需要多少行 三角形必须看起来像这样 到目前为止 我能够完成左对齐的三角形 但我似乎无法获得其他两个 我尝试用谷
  • Quarkus 不以编程方式选择 bean

    我试图以编程方式选择 bean 但 quarkus 不会注入 bean 并引发异常 不支持吗 public enum ReportType ONE TWO Qualifier Retention RUNTIME Target METHOD
  • 如何在log4j的配置文件中为文件附加器提供环境变量路径

    我有一个log4j xml配置文件 和一个RollingFileAppender我需要提供用于存储日志的文件路径 问题是我的代码将作为可运行的 jar 部署在 Unix 机器上 所以如果我传递这样的参数 value logs message
  • GET 请求的 Spring 注解

    这两种spring GET方法有什么区别呢 哪一种是首选方法 Component Scope request Path public class TestComponent GET Path hello public String prin
  • 如何在Java中优雅地处理SIGKILL信号

    当程序收到终止信号时如何处理清理 例如 我连接到一个应用程序 希望任何第三方应用程序 我的应用程序 发送finish注销时的命令 发送该信息最好说什么finish当我的应用程序被破坏时的命令kill 9 编辑1 kill 9无法被捕获 谢谢
  • 尝试获取屏幕上绘制的每个随机圆圈的 x、y 坐标

    您好 我正在制作一款游戏 该游戏将在屏幕上创建随机圆圈 随机创建的圆圈的值为红色或绿色 我的问题是 我希望不仅能够确定用户何时单击其中一个圆圈 而且还能够确定他们最终单击的圆圈 红色或绿色 下面是我的代码 我的主要问题是试图找到将要绘制的圆
  • javax.persistence.RollbackException:提交事务时出错],根本原因是 java.lang.StackOverflowError:null

    我有一个使用 Spring Data REST 框架的 Spring Boot API 从 spring boot starter parent 2 1 0 RELEASE 继承的依赖项 我正在尝试执行 PUT 或 PATCH 请求来更新实
  • JTextField 和 JTextArea

    JTextField 和 JTextArea 有什么不同 是否可以在一个班级中使用这两个班级 总之 JTextField 是单行文本字段 而 JTextArea 可以跨越多行 文档中清楚地解释了这些差异 文本区 http docs orac
  • 在 Junit 测试中使用 ReflectionTestUtils.setField()

    我是 JUnittesting 的新手 所以我有一个问题 谁能告诉我为什么我们使用ReflectionTestUtils setField 在我们的 Junit 测试示例中 正如评论中提到的 java 文档很好地解释了用法 但我还想给你们举
  • Android volley使用RequestFuture.get()时出现超时异常

    在我的片段中 我尝试使用 TMDB 的开放电影数据库来获取有关 正在播放 电影的详细信息 如果我使用 RequestFuture get time TimeUnit 方法来执行此齐射请求 我总是会收到超时错误 如果我在 Safari 中手动
  • Java - JPanel 内有边距和 JTextArea

    我想创建这样的东西 主面板有其边距 x 并且 TextArea 位于该面板的中心 几乎填满了面板 底部是另一个具有自定义尺寸 高度 y 的面板 可以使用某些快捷方式将其切换为可见和不可见 底部面板有 FlowLayout 和几个元素 问题是
  • Cucumber DataTable 错误 - io.cucumber.datatable.UndefinedDataTableTypeException:无法将 DataTable 转换为 cucumber.api.DataTable

    尝试使用 cucumber selenium java intelliJ 运行场景 但在其中一个步骤中出现有关 DataTable 的错误 在我开始使用测试运行程序并更改周围的一些内容之前 数据表工作正常并正确转换该步骤的参数 但我就是无法
  • 是否有最新的 Facebook Java SDK? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 好像没找到最近更新的 如果没有 是否有一个好的 Java 库来执行与 Facebook 的 API 交
  • 从 Android 访问云存储

    我一直无法找到任何有关如何从 Android 应用程序使用云存储的具体文档 我确实遇到过这个客户端库 https cloud google com storage docs reference libraries然而 Google Clou
  • Android 解析 JSON 卡在 get 任务上

    我正在尝试解析一些 JSON 数据 我的代码工作了一段时间 我不确定我改变了什么突然破坏了代码 当我运行代码时 我没有收到任何运行时错误或警告 我创建一个新的 AsyncTask 并执行它 当我打电话时 get 在这个新任务中 调试器在此行
  • 使用 HTTPServletRequestWrapper 包装请求参数

    我有一个可以验证 授权 REST 调用的过滤器 该过滤器需要访问请求参数 因此我为此编写了一个自定义 HTTPServletRequestWrapper import java util Collections import java ut
  • java swing:向 JTree 项目添加自定义图形按钮

    我想在 JTree 中的项目右侧添加一个带有小图标的附加按钮 这可以做到吗 如果是这样 怎么办 thanks Clamp 你在这方面成功了吗 我想做同样的事情 但很难让 JButton 响应用户 设置渲染器以显示按钮的过程很顺利 但所有鼠标
  • Java String ReplaceAll 方法给出非法重复错误?

    我有一个字符串 当我尝试运行时replaceAll方法 我收到这个奇怪的错误 String str something op str str replaceAll o n it works fine str str replaceAll n
  • CXF:通过 SOAP 发送对象时如何排除某些属性?

    我使用 Apache CXF 2 4 2 当我将数据库中的某个对象返回给用户时 我想排除一些属性 例如密码 我怎样才能做到这一点无需创建临时的班级 有这方面的注释吗 根据 tomasz nurkiewicz 评论我应该使用 XmlTrans

随机推荐

  • [659]linux安装RabbitMQ

    文章目录 安装Erlang 安装rabbitmq 关闭防火墙 否则非本地设备无法访问RabbitMQ服务 查看RabbitMQ运行状态 设置开机启动 添加用户 删除一个用户 修改用户的密码 设置用户角色 查看用户 设置用户权限 添加虚拟机
  • java 打印 发票_基于Excel和Java自动化:发票生成器

    对于销售人员 使用Excel创建发票是很常见的 但是该过程通常涉及许多容易出错的手动操作 例如输入数据 复制 粘贴等 如何实现一个可以将数据从数据库自动填充到发票Excel模板中 而无需再辛苦手动输入 从繁重的手动录入中解脱出来 并且避免认
  • win10计算器rsh_厉害了我的哥!win10计算器自带程序员模式太强大了!

    生活工作中常常会遇到用计算器的地方 比如算工资 算房贷啦 算卡路里等 一个有诸多功能的计算器能帮你省去大部分时间 你们知道吗 在windows计算器里 竟然还有程序员模式 可进行各种逻辑运算 快来和小编一起来看一下吧 相信大家Windows
  • C++几个关键字总结——const、static、extern、volatile

    1 const const 基本原理 被修饰的对象的值不可以被修改 const 推出的初始目的 正是为了取代预编译指令 消除它的缺点 同时继承它的优点 1 const修饰基本数据类型 表示常量 必须进行初始化 有以下两种初始化的方式 编译时
  • 数据分析中的mysql基础

    引言 之前的博客对mysql的一些入门知识进行了讲解 该博客将对sql的四个分类进行讲解 之前博客地址 https blog csdn net weixin 45696161 article details 106310108 sql的分类
  • python热度图改坐标_python matplotlib imshow热图坐标替换/映射实例

    今天遇到了这样一个问题 使用matplotlib绘制热图数组中横纵坐标自然是图片的像素排列顺序 但是这样带来的问题就是画出来的x y轴中坐标点的数据任然是x y在数组中的下标 实际中我们可能期望坐标点是其他的一个范围 如图 坐标点标出来的是
  • 笔记本关机后耗电严重问题怎么解决?一秒快速解决笔记本电脑关机掉电快的问题

    前言 或许许多使用笔记本的朋友都会遇到一个很头疼的问题 那就是笔记本关机放一段时间后 一周以内或者几个小时 电池电量消耗非常大 那么到底是什么原因导致笔记本关机后耗电快呢 如何解决耗电快的问题呢 下面详细讲述问题点及其解决方法 几个问题点
  • mysql数据库字符集_超详细的MySQL数据库字符集总结,值得收藏

    MySQL支持多种字符集 character set 提供用户存储数据 同时允许用不同排序规则 collation 做比较 下面基于MySQL5 7介绍一下字符集相关变量的使用 一 字符集 字符序的概念与联系 在数据的存储上 MySQL提供
  • c语言负数翻转问题

    1 在项目中 我们经常会用到变量 那么在变量的定义和传递过程中 经常会出现负数的翻转问题 int test funtion return 1 void poll fun unsigned int a while a gt 250 print
  • 你是一名努力工作的程序员,还是懒惰的程序员?

    当人们在进行一项体力工作时 你很容易评估他们工作的努力程度 你可以看到他们的身体动作 看他们流了多少汗水 也可以去看他们的工作成果 砖墙越砌越高 地上的洞越来越大 对努力工作的认可和奖励是人类一个非常基本的本能 这也是为什么我们对耐力运动如
  • 自已动手修改同花顺K线周期的快捷键

    同花顺的1分钟 5分钟 15分钟 30分钟 60分钟的K线周期快捷键为M1 M5 M15 M3 M6 不像大智慧为1 2 3 4 操作很是方便 让我们来把它给改一改 1 下载Restorator http www downxia com d
  • Java批量发带远程附件的邮件2--发送远程附件

    业务背景及需求 公司需要统一发送同类型的邮件给一批人时 比如发送员工个人薪资表分别至个人邮箱 此类邮件标题 内容 发送人等基本一致 且需要带附件 而其附件是收件人的隐私性个人信息 若通过上传文件保存到数据库里然后在发邮件的方式 浪费空间和时
  • WiFi以及天线测试项目详解

    1 相关术语 天线增益 天线增益就是某天线在最大辐射方向上的辐射能量跟点源天线 dBi 或偶极子天线 dBd 在同方向上的辐射能量的比值 天线规格书的几个参数 Gain dBi 在相同的输入功率下 天线在空间某点的辐射功率与理想无方向性点源
  • zabbix详解(十一)——zabbix监控MySQL性能实战

    今天继续给大家介绍Linux运维相关知识 本文主要内容是zabbix监控MySQL性能 一 实战目的 通过在zabbix客户端编写脚本 实现对MySQL数据库的性能进行信息进行提取 并配置成zabbix的监控项 以实现zabbix对MySQ
  • CSDN,这东西我得退了

    断更了那么久 得有个交代了 Albus Dumbledore好我是兄弟们 这一年里很高兴认识大家 CSDN这东西也让我接触到了很多有关技术和编程之类的东西 也收获了很多粉丝 但是 我因为学业及其他原因 这个网站我得先退了 账号我不会注销 说
  • [git]分支操作

    Checkout 相当于切换到该分支 但是因为不能直接操作远程分支 会在本地同步一个完全一样的分支 注意 切换分支前本地先进行提交 add commit 否则有可能代码会丢失 New Branch from Selected 创建一个新的分
  • 多态与多态对象模型

    这里简单介绍下什么是多态 多态的构成条件 多态原理以及多态的对象模型 在介绍多态之前 先简单的介绍下什么是虚函数 虚函数 类的成员函数前面加virtual关键字 则这个成员函数称为虚函数 注 1 除静态成员函数 2 内联函数不能定义为虚函数
  • NetworkManager is not running-liunx nmtui不可用

    NetworkManager 是CentOS 7 下的网络配置工具 如果遇到提示NetworkManager is not running那么需要安装一下 之前在CentOS 6下编辑网卡 直接使用setup工具就可以了 但在新版的Cent
  • error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token

    学会C语言也挺长时间了 当时写的时候就记得经常出现这个错误 在网络上查找感觉原因也林林总总 有时候也挺头疼的 就想着在这里记录一下原因 从字面上看是语法上的错误 缺少一些必要的符号 2019 4 26 在文件中找了很久 没有找到语法错误 后
  • storm七之storm java示例

    通过前面6个章节 我们大致了解apache storm的核心细节了 现在我们开始写一些简单的代码 来感受下storm的魅力 场景 移动呼叫日志分析 移动电话呼叫号及其持续时间将作为Apache stormd的输入流 storm将根据拨号方和