当前位置: 首页 > news >正文

Storm学习之使用官方Docker镜像快速搭建Storm运行环境

文章目录

  • 0.前言
    • 搭建完的效果
  • 1.教程
    • 1.1.docker 安装 zookeeper
    • 1.2. 安装 storm nimbus
    • 1.3.docker 安装 supervisor
    • 1.4.docker 安装 storm-ui
    • 1.5.查看已经启动的容器
    • 1.6.提交topology到 storm集群
  • 2.总结
  • 3.参考文档

0.前言

Apache Storm 官方也出了Docker 镜像 https://hub.docker.com/_/storm/
本文我们就基于官方镜像搭建一个 Apache Storm 2.4 版本的运行环境,供大家后续学习。
有问题可以参考issue 解决,我的安装过程一路都很顺畅。所以基本上没有看下面是我的详细操作和截图
可以说网上的乱七八糟的教程不如官方文档来的实在。
如果想用虚拟机搭建,请参考我的上一篇文章《Centos7搭建Apache Storm 集群运行环境》

搭建完的效果

Storm UI虽然是Storm 的非必须组件,但是是非常有用,基本上离不开的组件,它可以展示很多信息,对我们平时排查问题很有帮助,
在这里插入图片描述

  1. 拓扑列表:显示当前在Storm集群中运行的所有拓扑的列表。每个拓扑通常会显示其名称、ID、状态和所属的用户。

  2. 拓扑摘要:提供了关于选定拓扑的详细信息,包括拓扑的名称、ID、状态、拓扑图和组件列表。还可能包括拓扑的启动时间、运行时长和错误信息。

  3. 组件视图:显示了拓扑中的各个组件及其实例的信息。对于每个组件,它通常会显示组件的ID、类型、输入输出流以及处理该组件的工作进程和任务数量。

  4. 工作进程视图:提供有关工作进程的详细信息,包括工作进程的ID、主机名、端口号、启动时间、堆内存使用情况、线程数等。

  5. 任务视图:显示有关任务的信息,包括任务的ID、工作进程、组件、执行状态、错误信息等。可以查看每个任务的日志和统计数据。

  6. 错误视图:列出了拓扑中发生的任何错误或异常。这包括组件的失败、任务的错误、工作进程的故障等。通常会显示错误的时间戳、类型和详细描述。

  7. 日志视图:显示了拓扑中各个组件和任务的日志输出。可以查看实时日志或按时间范围过滤日志。

  8. 统计视图:提供了关于拓扑的性能统计数据。这可能包括拓扑的吞吐量、处理延迟、执行时间、错误计数等指标的图表或表格。

  9. 配置视图:显示了拓扑的配置参数和属性。可以查看拓扑使用的配置文件以及运行时配置的值。

  10. 集群概述:提供了有关整个Storm集群的概览信息,包括集群状态、拓扑数量、工作进程数量、任务数量等。

请注意,具体的Storm UI页面内容可能会根据不同的版本和配置有所变化,上述内容仅为一般情况下的解释。

1.教程

1.1.docker 安装 zookeeper

我们选择最新版本的zookeeper

$ docker run -itd --restart always --name ice-zookeeper zookeeper

在这里插入图片描述

1.2. 安装 storm nimbus

创建一个名为ice-nimbus的容器,并在其中运行Storm的Nimbus组件。该容器将与一个名为ice-zookeeper的Zookeeper容器相链接,以便Storm Nimbus可以与Zookeeper进行通信。
这一步耗时稍微较长,需要下载镜像。

$ docker run -itd --restart always --name ice-nimbus --link ice-zookeeper:zookeeper storm storm nimbus

在这里插入图片描述

1.3.docker 安装 supervisor

创建一个名为ice-supervisor的容器,并在其中运行Storm的Supervisor组件。该容器将与一个名为ice-zookeeper的Zookeeper容器和一个名为ice-nimbus的Nimbus容器相链接,以便Storm Supervisor可以与Zookeeper和Nimbus进行通信。通过--restart always选项,当容器退出时,Docker将自动重新启动该容器,确保Supervisor组件一直处于运行状态。

$ docker run -d --restart always --name ice-supervisor --link ice-zookeeper:zookeeper --link ice-nimbus:nimbus storm storm supervisor

在这里插入图片描述

1.4.docker 安装 storm-ui

$ docker run -d -p 8980:8080 --restart always --name ui --link ice-nimbus:nimbus storm storm ui

在这里插入图片描述

1.5.查看已经启动的容器

docker ps -a

在这里插入图片描述

1.6.提交topology到 storm集群

$ docker run --link ice-nimbus:nimbus -it --rm -v $(pwd)/topology.jar:/topology.jar storm storm jar /topology.jar org.apache.storm.starter.WordCountTopology topology

在这里插入图片描述

在这里插入图片描述
我们可以在StormUI的最后面看到 Nimbus配置参数:

  • worker.profiler.enabled: 是否启用工作进程的性能分析器。在给定的配置中,该值为false,表示禁用性能分析器。

  • worker.profiler.command: 用于启动性能分析器的命令。在给定的配置中,命令为"flight.bash"。

  • worker.profiler.childopts: 传递给性能分析器的JVM参数。在给定的配置中,参数为"-XX:+UnlockCommercialFeatures -XX:+FlightRecorder",用于解锁商业特性并启用Flight Recorder。

  • worker.metrics: 工作进程的度量指标配置。提供了一组度量指标的名称和相应的类。在给定的配置中,包括CGroup内存使用、CGroup内存限制、CGroup CPU使用、CGroup CPU保证等度量指标。

  • worker.max.timeout.secs: 工作进程的最大超时时间,以秒为单位。在给定的配置中,超时时间为600秒。

  • worker.log.level.reset.poll.secs: 重新设置工作进程日志级别的轮询间隔,以秒为单位。在给定的配置中,轮询间隔为30秒。

  • worker.heartbeat.frequency.secs: 工作进程发送心跳的频率,以秒为单位。在给定的配置中,心跳频率为1秒。

  • worker.heap.memory.mb: 工作进程的堆内存大小,以MB为单位。在给定的配置中,堆内存大小为768MB。

  • worker.gc.childopts: 传递给垃圾收集器的JVM参数。在给定的配置中,参数为空字符串,表示没有额外的垃圾收集器参数。

  • worker.childopts: 工作进程的启动选项,包括JVM参数。在给定的配置中,包括一些JVM参数,例如堆内存大小、GC日志的输出路径和格式、堆外内存溢出时的堆转储等。

  • ui.port: Storm UI的端口号。在给定的配置中,端口号为8080。

  • ui.childopts: Storm UI的启动选项,包括JVM参数。在给定的配置中,只指定了最大堆内存大小为768MB。

  • topology.workers: 拓扑的工作进程数。在给定的配置中,工作进程数为1,表示拓扑将在一个工作进程中执行。

  • topology.worker.shared.thread.pool.size: 拓扑工作进程共享线程池的大小。在给定的配置中,线程池大小为4。

  • topology.worker.receiver.thread.count: 拓扑工作进程接收器线程的数量。在给定的配置中,接收器线程数为1。

  • topology.worker.max.heap.size.mb: 拓扑工作进程的最大堆内存大小,以MB为单位。在给定的配置中,最大堆内存大小为768MB。

  • topology.worker.logwriter.childopts: 拓扑工作进程日志写入器的启动选项,包括JVM参数。在给定的配置中,只指定了最大堆内存大小为64MB。

  • topology.tuple.serializer: 拓扑元组的序列化器。在给定的配置中,序列化器为"org.apache.storm.serialization.types.ListDelegateSerializer"。

  • topology.trident.batch.emit.interval.millis: Trident拓扑批量发射间隔的时间间隔,以毫秒为单位。在给定的配置中,间隔为500毫秒。

  • topology.transfer.buffer.size: 拓扑传输缓冲区的大小。在给定的配置中,缓冲区大小为1000。

  • topology.transfer.batch.size: 拓扑传输批量大小。在给定的配置中,批量大小为1。

  • topology.stats.sample.rate: 拓扑配置项解释:

  • worker.profiler.enabled: 是否启用工作进程的性能分析器。在给定的配置中,该值为false,表示禁用性能分析器。

  • worker.profiler.command: 用于启动性能分析器的命令。在给定的配置中,命令为"flight.bash"。

  • worker.profiler.childopts: 传递给性能分析器的JVM参数。在给定的配置中,参数为"-XX:+UnlockCommercialFeatures -XX:+FlightRecorder",用于解锁商业特性并启用Flight Recorder。

  • worker.metrics: 工作进程的度量指标配置。提供了一组度量指标的名称和相应的类。在给定的配置中,包括CGroup内存使用、CGroup内存限制、CGroup CPU使用、CGroup CPU保证等度量指标。

  • worker.max.timeout.secs: 工作进程的最大超时时间,以秒为单位。在给定的配置中,超时时间为600秒。

  • worker.log.level.reset.poll.secs: 重新设置工作进程日志级别的轮询间隔,以秒为单位。在给定的配置中,轮询间隔为30秒。

  • worker.heartbeat.frequency.secs: 工作进程发送心跳的频率,以秒为单位。在给定的配置中,心跳频率为1秒。

  • worker.heap.memory.mb: 工作进程的堆内存大小,以MB为单位。在给定的配置中,堆内存大小为768MB。

  • worker.gc.childopts: 传递给垃圾收集器的JVM参数。在给定的配置中,参数为空字符串,表示没有额外的垃圾收集器参数。

  • worker.childopts: 工作进程的启动选项,包括JVM参数。在给定的配置中,包括一些JVM参数,例如堆内存大小、GC日志的输出路径和格式、堆外内存溢出时的堆转储等。

  • ui.port: Storm UI的端口号。在给定的配置中,端口号为8080。

  • ui.childopts: Storm UI的启动选项,包括JVM参数。在给定的配置中,只指定了最大堆内存大小为768MB。

  • topology.workers: 拓扑的工作进程数。在给定的配置中,工作进程数为1,表示拓扑将在一个工作进程中执行。

  • topology.worker.shared.thread.pool.size: 拓扑工作进程共享线程池的大小。在给定的配置中,线程池大小为4。

  • topology.worker.receiver.thread.count: 拓扑工作进程接收器线程的数量。在给定的配置中,接收器线程数为1。

  • topology.worker.max.heap.size.mb: 拓扑工作进程的最大堆内存大小,以MB为单位。在给定的配置中,最大堆内存大小为768MB。

  • topology.worker.logwriter.childopts: 拓扑工作进程日志写入器的启动选项,包括JVM参数。在给定的配置中,只指定了最大堆内存大小为64MB。

  • topology.tuple.serializer: 拓扑元组的序列化器。在给定的配置中,序列化器为"org.apache.storm.serialization.types.ListDelegateSerializer"。

  • topology.trident.batch.emit.interval.millis: Trident拓扑批量发射间隔的时间间隔,以毫秒为单位。在给定的配置中,间隔为500毫秒。

  • topology.transfer.buffer.size: 拓扑传输缓冲区的大小。在给定的配置中,缓冲区大小为1000。

  • topology.transfer.batch.size: 拓扑传输批量大小。在给定的配置中,批量大小为1。

  • topology.stats.sample.rate: 拓扑统计信息的

2.总结

本次我们将storm 使用docker 搭建了运行环境,下个章节,我们使用这个运行环境来运行我们拓扑。写一个最简单的 world count。本次我们就先到这里,大家如果需要继续可以开始写拓扑,尝试自己提交运行。

import org.apache.storm.Config;
import org.apache.storm.LocalCluster;
import org.apache.storm.topology.TopologyBuilder;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Values;
import org.apache.storm.utils.Utils;public class WordCountTopology {public static void main(String[] args) {// 创建TopologyBuilder实例TopologyBuilder builder = new TopologyBuilder();// 定义spout(数据源)和bolt(数据处理器)的名称和任务并行度builder.setSpout("word-reader", new WordReaderSpout(), 1);builder.setBolt("word-normalizer", new WordNormalizerBolt(), 2).shuffleGrouping("word-reader");builder.setBolt("word-counter", new WordCounterBolt(), 2).fieldsGrouping("word-normalizer", new Fields("word"));// 创建配置对象并设置一些参数Config config = new Config();config.put("inputFile", "input.txt");config.setDebug(true);// 在本地模式下运行拓扑LocalCluster cluster = new LocalCluster();cluster.submitTopology("word-count-topology", config, builder.createTopology());// 等待一段时间后停止拓扑Utils.sleep(5000);cluster.killTopology("word-count-topology");cluster.shutdown();}
}

3.参考文档

  1. docker hub storm https://hub.docker.com/_/storm
  2. Storm 社区 https://github.com/31z4/storm-docker

相关文章:

Storm学习之使用官方Docker镜像快速搭建Storm运行环境

文章目录 0.前言搭建完的效果 1.教程1.1.docker 安装 zookeeper1.2. 安装 storm nimbus1.3.docker 安装 supervisor1.4.docker 安装 storm-ui1.5.查看已经启动的容器1.6.提交topology到 storm集群 2.总结3.参考文档 0.前言 Apache Storm 官方也出了Docker 镜像 https://hub.do…...

【GTest学习】

1. GTest简介: GTest 就是 Google Test, 它是一个免费开源的测试框架, 用于编写测试用 C语言编写的程序(C 程序也能用, 但是需要用 C编译器编译)。gtest的官方网站是:http://code.google.com/p/googletest/ 2.GTest下载与环境搭建: GTest 下…...

[JAVAee]网络通信基础

目录 IP地址 端口号 网络协议 五元组 TCP/IP五层模型 网络互连之间的目的就是为了相互通信,传输数据,是可以不同进程间的基于网络的数据传输. 而IP就可以确定网络通信的双方. IP地址 IP地址主要用于定位标识网络主机或其他网络设备的网络地址.(就像快递的收货地址一般…...

【HDFS】BlockManager#checkRedundancy方法详解

BlockManager#checkRedundancy这个方法只有一处调用点, 就是FSNamesystem#finalizeINodeFileUnderConstruction方法。 TODO:补充FSNamesystem#finalizeINodeFileUnderConstruction方法的调用点。 checkRedundancy方法的参数的BlockCollection对象bc,解释一下,INodeFile类是…...

c++ 拷贝构造

我们思考一下这个问题&#xff1a; 观察以下代码&#xff0c;在运行的时候会崩溃 想一想为什么 #include<iostream> using namespace std;//栈类 typedef int DataType; class Stack { public://默认构造&#xff1a;Stack(size_t capacity 3){_array (DataType*)ma…...

MISRA 2012学习笔记(1)-Directives

文章目录 说明Directives2 编译与构建Dir 2.1 3 需求可追溯性Dir 3.1 4 代码设计Dir 4.1Dir 4.2Dir 4.3Dir 4.4Dir 4.5Dir 4.6Dir 4.7Dir 4.8Dir 4.9Dir 4.10Dir 4.11Dir 4.12Dir 4.13 说明 以下等级一般分为三种&#xff0c;建议&#xff0c;必要&#xff0c;强制 建议&#…...

升级node版本后vue2的项目node-sass、sass-loader安装报错(14.x升级到16.x)

node升级到16.x版本后&#xff0c;对应的node-sass需要升级到^6.0.0&#xff0c;此时sass-loader的版本需要升级到10.2.0以上 &#xff0c;具体对应版本规则可参考链接: https://github.com/webpack-contrib/sass-loader/releases?page3 vue2通过vue/cli创建的项目&#xff0…...

深入理解CSS选择器:选择正确的方式掌控样式与布局

文章目录 CSS 概括CSS 选择器元素选择器&#xff08;Element Selector&#xff09;类选择器&#xff08;Class Selector&#xff09;ID 选择器&#xff08;ID Selector&#xff09;通用选择器&#xff08;Universal Selector&#xff09;属性选择器&#xff08;Attribute Selec…...

qt设置控件的风格样式

设置tablewidget ui.tableWidget_MaterialLibrary->setStyleSheet("QTableView {""color:#DCDCDC;""background-color: #444444;""border: 1px solid #242424;""alternate-background-color:#525252;""gridline-co…...

简单易懂的Transformer学习笔记

1. 整体概述 2. Encoder 2.1 Embedding 2.2 位置编码 2.2.1 为什么需要位置编码 2.2.2 位置编码公式 2.2.3 为什么位置编码可行 2.3 注意力机制 2.3.1 基本注意力机制 2.3.2 在Trm中是如何操作的 2.3.3 多头注意力机制 2.4 残差网络 2.5 Batch Normal & Layer Narmal 2.…...

C语言经典小游戏之三子棋(超详解释+源码)

“纵有疾风来&#xff0c;人生不言弃&#xff0c;风乍起&#xff0c;合当奋意向此生。” 今天我们一起来学习一下三子棋小游戏用C语言怎么写出来&#xff1f; 三子棋小游戏 1.游戏规则介绍2.游戏准备3.游戏的实现3.1生成菜单3.2游戏的具体实现3.2.1初始化棋盘3.2.2打印棋盘3.2…...

宝塔Linux面板点击SSL闪退打不开?怎么解决?

宝塔Linux面板点击SSL证书闪退如何解决&#xff1f;旧版本的宝塔Linux面板确实存在这种情况&#xff0c;如何解决&#xff1f;升级你的宝塔Linux面板即可。新手站长分享宝塔面板SSL闪退的解决方法&#xff1a; 宝塔面板点击SSL证书闪退解决方法 问题&#xff1a;宝塔Linux面板…...

Problem: 6953. 判断是否能拆分数组

Problem: 6953. 判断是否能拆分数组 文章目录 思路解题方法复杂度Code 思路 针对题目中的以下目标&#xff0c;可以转换寻求数组中是否存在前后两个元素之和>m的情况&#xff0c;如果存在则返回ture&#xff0c;如果不存在则返回false。能这样转换的原因是&#xff0c;如果…...

MobiSys 2023 | 多用户心跳监测的双重成形声学感知

注1:本文系“无线感知论文速递”系列之一,致力于简洁清晰完整地介绍、解读无线感知领域最新的顶会/顶刊论文(包括但不限于 Nature/Science及其子刊; MobiCom, Sigcom, MobiSys, NSDI, SenSys, Ubicomp; JSAC, 雷达学报 等)。本次介绍的论文是:<<MobiSys’23,Multi-User A…...

Netty:ChannelInitializer添加到ChannelPipeline完成任务以后会自动删除自己

说明 io.netty.channel.ChannelInitializer是一个特殊的ChannelInboundHandler。它的主要作用是向 Channel对应的ChannelPipeline中增加ChannelHandler。执行完ChannelInitializer的initChannel(C ch)函数以后&#xff0c;ChannelInitializer就会从ChannelPipeline自动删除自己…...

【VUE】项目本地开启https访问模式(vite4)

在实际开发中&#xff0c;有时候需要项目以https形式进行页面访问/调试&#xff0c;下面介绍下非vue-cli创建的vue项目如何开启https 环境 vue: ^3.2.47vite: ^4.1.4 根据官方文档&#xff1a;开发服务器选项 | Vite 官方中文文档 ps&#xff1a;首次操作&#xff0c;不要被类…...

【状态估计】一维粒子滤波研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

设计模式-迭代器模式在Java中使用示例

场景 为开发一套销售管理系统&#xff0c;在对该系统进行分析和设计时&#xff0c;发现经常需要对系统中的商品数据、客户数据等进行遍历&#xff0c; 为了复用这些遍历代码&#xff0c;开发人员设计了一个抽象的数据集合类AbstractObjectList&#xff0c;而将存储商品和客户…...

Maven入职学习

一、什么是Maven&#xff1f; 概念&#xff1a; Maven是一种框架。它可以用作依赖管理工具、构建工具。 它可以管理jar包的规模、jar包的来源、jar包之间的依赖关系。 它的用途就是管理规模庞大的jar包&#xff0c;脱离IDE环境执行构建操作。 具体使用&#xff1a; 工作机…...

【多音音频测试信号】具有指定采样率和样本数的多音信号,生成多音信号的相位降低波峰因数研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...

rm视觉学习1-自瞄部分

首先先感谢中南大学的开源&#xff0c;提供了很全面的思路&#xff0c;减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接&#xff1a;https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架&#xff1a; 代码框架结构&#xff1a;readme有…...