• 关于

    执行流程分析

    的搜索结果

问题

性能测试流程是什么

猫饭先生 2019-12-01 21:26:03 998 浏览量 回答数 0

回答

转自:知乎 链接:https://www.zhihu.com/question/22508677/answer/141334678 普通人: 我今天要买一斤苹果。 程序员: 我今天要买一斤苹果。 因为我只喜欢红富士苹果,所以我只买红富士苹果。 我能接受的最高价格是10元/斤。 正常情况下一斤苹果用一个袋子能装下,但是为防万一,我会带两个袋子。 我知道附近的3家水果店,所以我会依次访问这3家水果店。 根据上述条件,我设计出以下的买苹果的流程: 买苹果流程开始 对水果店0、水果店1、水果店2依次执行: 拜访一家水果店流程开始 走到此水果店 如果此水果店没有开门,则结束当前的“拜访一家水果店流程” 如果此水果店没有苹果,则结束当前的“拜访一家水果店流程” 如果此水果店的苹果当中没有红富士苹果,则结束当前的“拜访一家水果店流程” 如果此水果店的红富士苹果剩余不到一斤,则结束当前的“拜访一家水果店流程” 如果此水果店的红富士苹果的价格高于10元/斤,则执行3次: 讲价流程开始 询问店主是否愿意将价格降到10元/斤或更低 如果店主愿意,则跳过剩余的“讲价流程” 讲价流程结束 如果此水果店的红富士苹果的价格仍然高于10元/斤,则结束当前的“拜访一家水果店流程” 打开一个袋子,将其作为当前的袋子 重复执行以下流程,直到总重量大于一斤: 装袋一个苹果流程开始 从所有的不在袋子中的红富士苹果中选出最好的一个 如果此苹果能装入当前的袋子,则将此苹果装入当前的袋子,否则执行: 换袋子流程开始 如果我有剩余的袋子,则从中任意选出一个并作为当前的袋子,否则执行: 向店主要袋子流程开始 向店主索要一个袋子 如果店主拒绝给我袋子,则将我的所有袋子里的所有苹果取出,然后结束当前的“拜访一家水果店流程” 将店主给我的袋子作为当前的袋子 向店主要袋子流程结束 换袋子流程结束 测量我的所有袋子里的所有苹果的总重量 装袋一个苹果流程结束 根据我的所有袋子里的所有苹果的总重量和店主给出的价格,计算我应付的价格 向店主询问我应付的价格 如果我不接受店主索要的价格,则执行3次: 校对流程开始 向店主解释我计算出的价格,并询问其是否同意 如果店主同意,则跳过剩余的“校对流程” 校对流程结束 如果我仍然不接受店主索要的价格,则将我的所有袋子里的所有苹果取出,然后结束当前的“拜访一家水果店流程” 如果我没带钱,则将我的所有袋子里的所有苹果取出,然后结束当前的“拜访一家水果店流程” 付钱拿走苹果 跳过剩余的“拜访一家水果店流程” 拜访一家水果店流程结束 买苹果流程结束 这个流程怎么样?我来设计一些测试样例,测试一下这个流程。 测试发现一个问题:如果水果店0和水果店1都有红富士苹果并且价格都低于10元/斤,而且水果店1的价格比水果店0更低,那么我希望买水果店1的苹果,但我设计的流程会让我买水果店0的苹果。 为了解决这个问题,我应该先询问所有水果店的价格,然后去价格最低的那一家买苹果。 经过修改,我重新设计出以下的买苹果的流程: 买苹果流程开始 对水果店0、水果店1、水果店2依次执行: 询问一家水果店的红富士价格流程开始 走到此水果店 如果此水果店没有开门,则视此水果店的红富士价格为无穷大元/斤,并结束当前的“询问一家水果店的红富士价格流程” 如果此水果店没有苹果,则视此水果店的红富士价格为无穷大元/斤,并结束当前的“询问一家水果店的红富士价格流程” 如果此水果店的苹果当中没有红富士苹果,则视此水果店的红富士价格为无穷大元/斤,并结束当前的“询问一家水果店的红富士价格流程” 如果此水果店的红富士苹果剩余不到一斤,则视此水果店的红富士价格为无穷大元/斤,并结束当前的“询问一家水果店的红富士价格流程” 向店主询问此水果店的红富士苹果价格并记录 询问一家水果店的红富士价格流程结束 从3家水果店中选出红富士价格最低的一家(如果有并列则随机选择),将其作为目标水果店 如果目标水果店的红富士苹果价格为无穷大元/斤,则结束当前的“买苹果流程” 走到目标水果店 如果此水果店的红富士苹果的价格高于10元/斤,则执行3次: 讲价流程开始 询问店主是否愿意将价格降到10元/斤或更低 如果店主愿意,则跳过剩余的“讲价流程” 讲价流程结束 如果此水果店的红富士苹果的价格仍然高于10元/斤,则结束当前的“买苹果流程” 打开一个袋子,将其作为当前的袋子 重复执行以下流程,直到总重量大于一斤: 装袋一个苹果流程开始 从所有的不在袋子中的红富士苹果中选出最好的一个 如果此苹果能装入当前的袋子,则将此苹果装入当前的袋子,否则执行: 换袋子流程开始 如果我有剩余的袋子,则从中任意选出一个并作为当前的袋子,否则执行: 向店主要袋子流程开始 向店主索要一个袋子 如果店主拒绝给我袋子,则将我的所有袋子里的所有苹果取出,然后结束当前的“买苹果流程” 将店主给我的袋子作为当前的袋子 向店主要袋子流程结束 换袋子流程结束 测量我的所有袋子里的所有苹果的总重量 装袋一个苹果流程结束 根据我的所有袋子里的所有苹果的总重量和店主给出的价格,计算我应付的价格 向店主询问我应付的价格 如果我不接受店主索要的价格,则执行3次: 校对流程开始 向店主解释我计算出的价格,并询问其是否同意 如果店主同意,则跳过剩余的“校对流程” 校对流程结束 如果我仍然不接受店主索要的价格,则将我的所有袋子里的所有苹果取出,然后结束当前的“买苹果流程” 如果我没带钱,则将我的所有袋子里的所有苹果取出,然后结束当前的“买苹果流程” 付钱拿走苹果 买苹果流程结束 现在这个流程是不是完美了呢?不是,我还能发现很多问题。 如果3家水果店都有红富士苹果但都不到一斤,但是三家店加起来能达到一斤,那么我不应该结束流程回家,而是应该把三家店的红富士苹果都买下来。 如果我向水果店询问价格的时候这家店还有红富士苹果,但我询问完所有水果店的价格后这家店的红富士苹果卖完了,那么我的流程会让我试图处理不存在的红富士苹果。 我走路的过程中可能会遇到突发事件,比如发现了新的水果店,比如袋子破掉了苹果掉一地,对于这些情况我的流程都无法进行处理。 啊!问题太多了我懒得再改流程了。我还是去X宝买吧。那么接下来我要设计一个在X宝买红富士苹果的流程…… 这篇回答并不是讲述在生活中程序员如何买苹果,而是以买苹果为例说明程序员如何解决问题。程序员需要对问题进行透彻的分析,理清其涉及的所有细节,预测可能发生的所有意外与非意外的情况,列出解决方案的所有步骤,以及对解决方案进行尽量全面的测试。 而这正是我认为编程难的地方。任何一点遗漏都会成为bug,轻则导致挨骂,重则导致经济损失甚至危害安全。 注意这些难点全部和语言无关。和编程所需要的绝对严密的逻辑相比,语言实在是太简单了。(某些自带代码混淆效果的语言除外)

茶什i 2020-01-03 11:46:51 0 浏览量 回答数 0

回答

介绍 GTX-FPGA产品是由未来实验室 GTX-Laboratory开发的全基因组分析加速工具,采用CPU和FPGA协同工作的异构加速技术,利用各自的特性进行基因数据的高性能计算。可以将30X的全基因组数据分析时间从30小时缩短至30分钟;将100X全外显子数据分析时间从6小时缩短至5分钟完成。 GTX-FPGA 分析主要包括:index(构建索引)、align(基因组对比)、 vc(突变检测)、wgs(整合,将alin 和 vc 整合到一起,下文中的 GTX one也是指该步骤)等步骤。 本文主要介绍如果通过阿里云批量计算直接使用 GTX-FPGA 产品,实现全基因组数据分析、全外显子数据分析作业一键式运行。 使用约束 GTX-FPGA 产品目前只支持阿里云 F3 型 ECS 实例类型。同时每个实例类型需要配置一定容量的 SSD 数据盘,容量大小和fasta大小有关;其中 align 需要的磁盘大小是 2 个 fastq 文件大小的和再乘以 2(例如:需要计算的 fastq1 是 40G,fastq2 是 42G, 需要的数据盘空间大小是 164G);wgs需要的计算空间大小是 fasta 文件大小的8倍(例如human30x.fasta数据大小是 3.4G,则需要的数据盘大小是 252G)。针对人类基因组数据盘大小可以采用下文中 demo 示例的设置默认值。 GTX-FPGA 产品目前只支持 北京 区域测试。 GTX-FPGA 产品目前处于公测阶段,公测阶段 GTX-FPGA 产品不收取费用,只收取作业所需要的实例以及相关存储费用。 前置条件 登录阿里云,并确保账号余额大于100元,以便体验完整分析流程。 开通批量计算服务,用于执行分析任务。 开通OSS对象存储, 用于上传用户自己的测序数据,保存分析结果。创建bucket,例如 gtx-wgs-demo 查看或者创建的AccessKey, 如果您使用的是子账号,请确认具有以上批量计算和OSS的产品使用权限,参考快速开始文档。复制AccessKey ID(如LTAI8xxxxx), Access Key Secret(如vVGZVE8qUNjxxxxxxxx) 备用。 使用说明 GTX-FPGA 支持WDL模式运行以及DAG作业模式运行。 1 GTX 命令格式 gtxcmd 2 WDL模式运行 WDL 模式使用方式请参考文档 3 DAG作业模式 3.1 示例脚本 下载 DAG 作业示例代码。 其中: genGtxIndexCmd 则是对应 GTX 的建索引命令;命令使用方法可以参考代码中帮助信息。genGtxWgsCmd 则是对应 GTX one的命令;命令使用方法可以参考代码中帮助信息。genGtxAlignCmd 则是对应 GTX 基因组对比命令;命令使用方法可以参考代码中帮助信息。genGtxVcCmd 则是对应 GTX 突变检测命令;命令使用方法可以参考代码中帮助信息。 可以自定义以上步骤中每项 GTX 参数,也可以按默认值来执行。 建索引操作是非必选项目,本 demo 示例默认索引构建完成;若需要构建索引在执行脚本时需要增加参数(isNeedIndex)描述。 read_group_header 可以通过命令行传入也可以使用默认值。 示例代码默认运行 GTX one流程,一次性执行对比以及编译检测流程;若需要按分步骤执行则需要设置对应参数。 更新批量计算python SDK到最新版本 “pip install —upgrade batchcompute”。 3.1 执行命令 python test.py --reference oss://xxx/ref/hg19.fa --fastq1 oss://xxx/input/human30x_10m_1.fastq --fastq2 oss://xxxx/_input/human30x_10m_2.fastq --output oss://xxx/testoutput/ 3.2 执行结果 gtxonegtxret

1934890530796658 2020-03-28 21:41:48 0 浏览量 回答数 0

Quick BI 数据可视化分析平台

2020年入选全球Gartner ABI魔力象限,为中国首个且唯一入选BI产品

问题

面向服务的ERP可重构开发模型

hua2012h 2019-12-01 20:13:41 7876 浏览量 回答数 0

回答

GATK 软件分析流程由阿里云和 Broad Institute 合作提供。Broad Institute 提供的 GATK 流程最佳实践用 工作流定义语言(WDL) 编写,通过批量计算集成的 Cromwell 工作流引擎解析执行。用户将为作业运行时实际消耗的计算和存储资源付费,不需要支付资源之外的附加费用。 Broad Institute GATK 网站和论坛为 GATK 工具和 WDL 提供了更完整的背景信息,文档和支持。 如果需要执行用 WDL 编写的通用工作流程,请参考 cromwell 工作流引擎和 WDL 支持的 APP 。 准备 A) 使用 OSS 存储 要在批量计算上运行 GATK,输入、输出文件都需要保存在 OSS。所以,需要先开通 OSS 并创建好 Bucket。 注意:创建 Bucket 的区域,需要和运行批量计算的 GATK 区域一致。 B) 安装 batchcompute-cli 命令行工具 pip install batchcompute-cli 安装完成后,还需要 配置 。 注意:当前最佳实践中使用的 GATK 相关软件版本信息如下: GATK: 4.0.0.0 picard: 2.13.2 genomes-in-the-cloud: 2.3.0-1501082129 2. 快速运行 本示例中,运行 Broad Institute 提供的 GATK4 版本全基因分析流程,该流程分为两步: 第一步为 gatk4-data-processing 。 第二步为 gatk4-germline-snps-indels 。 在配置好 bcs 工具后,执行如下命令: bcs gen ./demo -t gatk cd demo/gatk4-data-processing sh main.sh # 运行gatk4-data-processing 流程 cd ../gatk4-germline-snps-indels sh main.sh # 运行gatk4-germline-snps-indels 流程 这样您就在批量计算上运行了以上两个 GATK4 流程。 命令详解 A) 生成示例 执行如下命令生成示例: bcs gen ./demo -t gatk 它将生成以下目录结构: demo |-- Readme.md |-- gatk4-data-processing | |-- main.sh | |-- src | |-- LICENSE | |-- README.md | |-- generic.batchcompute-papi.options.json | |-- processing-for-variant-discovery-gatk4.hg38.wgs.inputs.json | |-- processing-for-variant-discovery-gatk4.hg38.wgs.inputs.30x.json | |-- processing-for-variant-discovery-gatk4.wdl |-- gatk4-germline-snps-indels |-- main.sh |-- src |-- LICENSE |-- README.md |-- generic.batchcompute-papi.options.json |-- haplotypecaller-gvcf-gatk4.hg38.wgs.inputs.json |-- haplotypecaller-gvcf-gatk4.hg38.wgs.inputs.30x.json |-- haplotypecaller-gvcf-gatk4.wdl gatk4-data-processing 目录中包括了运行 gatk4-data-processing 流程所需的所有配置和脚本。 gatk4-germline-snps-indels 目录中包括了运行 gatk4-germline-snps-indels 流程所需的所有配置和脚本。 每个目录下面的 main.sh 脚本封装了使用 bcs 工具提交作业的命令。 src 目录下面包括了工作流实现代码。 B) 运行 gatk4-data-processing 流程 进入 demo/gatk4-data-processing 目录,运行 main.sh,该文件内容如下: #!/bin/bash bcs asub cromwell -h for more bcs asub cromwell gatk-job --config ClassicNetwork=false --input_from_file_WDL src/processing-for-variant-discovery-gatk4.wdl --input_from_file_WORKFLOW_INPUTS src/processing-for-variant-discovery-gatk4.hg38.wgs.inputs.json --input_from_file_WORKFLOW_OPTIONS src/generic.batchcompute-papi.options.json --input_WORKING_DIR oss://demo-bucket/cli/gatk4_worker_dir/ --output_OUTPUTS_DIR oss://demo-bucket/cli/gatk4_outputs/ -t ecs.sn1.large -d cloud_efficiency 其中,部分参数描述为: input_from_file_WDL: WDL 流程描述文件路径。 input_from_file_WORKFLOW_INPUTS:WDL 流程输入文件。 input_from_file_WORKFLOW_OPTIONS:WDL 流程选项文件。 input_WORKING_DIR:OSS上的目录,用来存储 WDL 流程中各个步骤生成的文件,bcs 会自动给您生成一个默认的路径。 output_OUTPUTS_DIR:OSS 上的目录,用来存储 WDL 流程结束后生成的 metadata 文件,bcs 会自动给您生成一个默认的路径。 其他参数,请参考 bcs asub -h 命令。 如果希望使用此流程来运行自己的数据,需要修改 src/processing-for-variant-discovery-gatk4.hg38.wgs.inputs.json 文件中的 PreProcessingForVariantDiscovery_GATK4.flowcell_unmapped_bams_list 参数,指定存储在 OSS 上的 ubam 文件。 注意:该示例中的流程输入文件不是 FASTQ 格式,而是 unaligned BAM 文件。 C) 运行 gatk4-germline-snps-indels 流程 该流程的运行与 gatk4-data-processing 流程类似,参考上述章节。 如果希望使用此流程来运行自己的数据,需要修改 src/haplotypecaller-gvcf-gatk4.hg38.wgs.inputs.json 文件中的 HaplotypeCallerGvcf_GATK4.input_bam 参数,修改为 gatk4-data-processing 流程输出的 bam 文件路径。 将 HaplotypeCallerGvcf_GATK4.input_bam_index 参数修改为相应的索引文件路径。 4. 作业状态查询与日志 在提交作业后,如果看到以下信息,说明提交成功 Job created: job-0000000059DC658400006822000001E3 job-0000000059DC658400006822000001E3 即是当次提交作业的 ID。 查看作业状态: bcs j # 获取作业列表 bcs j job-0000000059DC658400006822000001E3 # 查看作业详情 查看作业日志: bcs log job-0000000059DC658400006822000001E3 5. 验证结果 查看 OSS 空间中的输出数据: bcs o ls oss://demo-bucket/cli/gatk4_worker_dir/ 查看 metadata 文件: bcs o ls oss://demo-bucket/cli/gatk4_outputs/ 6. 如何分析 30X 的全基因组数据 A) 生成配置文件 执行上述步骤生成本示例时,会同时生成一个适用 30X 全基因组数据分析的配置: processing-for-variant-discovery-gatk4.hg38.wgs.inputs.30x.json haplotypecaller-gvcf-gatk4.hg38.wgs.inputs.30x.json B) 修改 processing-for-variant-discovery-gatk4 配置文件 为分析 30X 样本,需要将 processing-for-variant-discovery-gatk4.hg38.wgs.inputs.30x.json 文件中的PreProcessingForVariantDiscovery_GATK4.flowcell_unmapped_bams_list 参数改为OSS 文件路径,该文件包括了需要分析的 30X 样本在 OSS 上的路径列表。 注意,30X 数据样本,格式为 unaligned BAM 文件。 C)修改 gatk4-data-processing 流程文件 找到 gatk4-data-processing 流程的 main.sh 文件,将其中的 --input_from_file_WORKFLOW_INPUTS 参数,修改为 src/processing-for-variant-discovery-gatk4.hg38.wgs.inputs.30x.json,加上 --timeout 172800 参数,并提交作业。 D) 修改 haplotypecaller-gvcf-gatk4 配置文件 将 haplotypecaller-gvcf-gatk4.hg38.wgs.inputs.30x.json 中的 HaplotypeCallerGvcf_GATK4.input_bam 参数修改为gatk4-data-processing 流程输出的 bam 文件路径。 将 HaplotypeCallerGvcf_GATK4.input_bam_index 参数修改为相应的索引文件路径。 E) 修改 gatk4-germline-snps-indels 流程文件 找到 gatk4-germline-snps-indels 流程的 main.sh,将其中的 --input_from_file_WORKFLOW_INPUTS 参数修改为 src/haplotypecaller-gvcf-gatk4.hg38.wgs.inputs.30x.json,加上 --timeout 172800 参数,并最后提交作业。 如遇到 QuotaExhausted 错误,请通过工单调整 Quota。

1934890530796658 2020-03-28 20:47:40 0 浏览量 回答数 0

回答

OSS Object Storage Service 阿里云对象存储 媒体处理服务对用户存储于OSS的媒体文件进行转码,并将转码输出文件保存在MediaBucket中或者OutputBucket中。 Bucket OSS Bucket OSS Bucket 遵守OSS Bucket定义,只能包括小写字母,数字和短横线(-),必须以小写字母或者数字开头,长度必须在3-255字节之间。 Location OSS Location OSS 数据中心 遵守OSS Location定义。 Object OSS Object OSS Object 遵守OSS Object定义,使用UTF-8编码,长度必须在1-1023字节之间,不能以“/”或者“\”字符开头。 LocalFile Local File 本地媒体文件 用户本地存储的媒体文件,还没有上传到OSS。 Input Job Input 作业输入 作业输入,包括InputFile以及其它一些转码作业输入配置参数 InputFile Input File 输入文件 本地文件上传到OSS后,就转变成一个输入文件。 Output Job Output 作业输出配置 作业输出配置由模板ID、水印列表、OutputFile、输出文件等属性构成。 OutputFile Output File 输出文件 作业输出文件,存储于OSS上,由OutputLocation、OutputBucket、OutputObject唯一标识一个输出文件。 OutputBucket Output Bucket 转码输出Bucket 用户指定的转码输出Bucket,“OSS文件转码流程”中提交作业时需要指定的参数,用户必须通过媒体处理服务的控制台资源管理页面的Bucket授权频道授予OutputBucket给媒体处理服务有写权限。 OutputLocation Output Location 转码输出Bucket所在的OSS Location 转码输出Bucket所在的数据中心,“OSS文件转码流程”中提交转码作业时可以指定的参数。 Template Transcode Template 自定义模板 自定义模板是指用户自行定义转码参数的转码模板,它是转码参数(音频、视频、容器等)的集合。每个自定义模板有一个唯一ID。 PresetTemplate Preset Transcode Template 预置模板 预置模版是媒体处理服务内置的智能转码模板,能根据输入文件的特点动态调整转码设置,从而为用户提供在一定带宽条件下的最优转码输出。由于输入文件本身有差异(分辨率、码率等),不一定所有的预置模板都适合于该输入文件。输入文件的转码使用预置模板时,需要调用“提交模板分析作业”接口(SubmitAnalysisJob)来触发模板分析;调用“查询模板分析作业”接口(QueryAnalysisJobList)来获取该输入文件可用的预置模板列表。媒体转码服务支持的预置模板详见附录 预置模板。 WaterMarkTemplate WaterMark Template 水印模板 水印包括两部分参数:水印内容为可变参数;水印位置、偏移量、大小等为相对稳定的参数;相对稳定的参数构成水印模板,每个水印模板有一个唯一的ID。 Job Transcode Job 转码作业 转码作业,一个转码作业由一路输入及一路输出构成,作业会被加入到管道中,管道中的作业会被调度引擎调度到转码系统进行转码。 AnalysisJob Analysis Job 预置模板分析作业 预置模板分析作业由输入文件及分析配置构成,分析得到可用的预置模板。 SnapshotJob Snapshot Job 截图作业 截图作业由输入文件及截图配置构成,得到输入文件按截图配置截取的图片。 MediaInfoJob MediaInfo Job 媒体信息作业 媒体信息作业需指定输入文件,得到输入文件的媒体信息。 Pipeline Job pipeline 管道 管道是一作业队列,转码作业加入到管道中,才会被媒体处理服务调度到转码执行;如果管道中作业数量过多,会排队等待。管道有激活、暂停两种状态;管道被暂停时,媒体转码服务不再调度此管道中的作业执行转码,直到管道被重新激活为止,已经在执行转码的作业不受影响。 MediaRepository Media Repository 媒体库 所有媒体的集合。 Media Media Resource 媒体 媒体是媒体库的最小管理单元。包含一个输入(视频/音频的多媒体文件)和相关的所有输出(例如,转码/截图)。由MediaId唯一标识,并且多媒体输入文件和媒体是一一对应的。 MediaWorkflow Media Workflow 媒体工作流 媒体工作流是生产媒体的工厂。从输入媒体Bucket的多媒体文件开始,执行自定义的处理流程,把处理结果存储到输出媒体Bucket。由MediaWorkflowId唯一标识。 Activity Media Workflow Activity 媒体工作流活动 媒体工作流的组成单位。媒体工作流的处理流程实际是一个有向无环的拓扑图,图中的每个节点叫活动,支持的活动有:转码、截图、元信息获取等。每个媒体工作流中的活动有唯一的名字标识。 MediaWorkflowExecution Media Workflow Execution Instance 媒体工作流执行实例 媒体工作流的每次执行叫媒体工作流执行实例。由实例执行的Id(RunId)唯一标识。 MediaBucket Media Bucket 媒体Bucket 媒体库关联多个媒体Bucket,所有媒体相关的文件都保存在媒体Bucket中。媒体Bucket又分为输入媒体bucket和输出媒体bucket,输入和输出之间不能重叠,必须是独立的OSS Bucket。 InputMediaBucket Input Media Bucket 输入媒体Bucket 在输入媒体Bucket中新增的多媒体文件,会自动加入媒体库,如果匹配了媒体工作流的输入条件,会自动触发媒体工作流的执行。 OutputMediaBucket Output Media Bucket 输出媒体Bucket 存储媒体工作流处理后的输出文件。

保持可爱mmm 2020-03-30 10:28:49 0 浏览量 回答数 0

回答

两阶段提交协议是一种经典的强一致性中心化副本控制协议。虽然在工程中该协议有较多 的问题,但研究该协议能很好的理解分布式系统的几个典型问题。 流程描述 两阶段提交协议是一种典型的“中心化副本控制”协议。在该协议中,参与的 节点分为两类:一个中心化协调者节点(coordinator)和N 个参与者节点(participant)。每个参与 者节点即上文背景介绍中的管理数据库副本的节点。 两阶段提交的思路比较简单,在第一阶段,协调者询问所有的参与者是否可以提交事务(请参 与者投票),所有参与者向协调者投票。在第二阶段,协调者根据所有参与者的投票结果做出是否事 务可以全局提交的决定,并通知所有的参与者执行该决定。在一个两阶段提交流程中,参与者不能 改变自己的投票结果。两阶段提交协议的可以全局提交的前提是所有的参与者都同意提交事务,只 要有一个参与者投票选择放弃(abort)事务,则事务必须被放弃。 流程:两阶段提交协调者流程 写本地日志“begin_commit”, 并进入WAIT 状态; 向所有参与者发送“prepare 消息”; 等待并接收参与者发送的对“prepare 消息”的响应; 3.1 若收到任何一个参与者发送的“vote-abort 消息”; 3.1.1 写本地“global-abort”日志,进入ABORT; 3.1.2 向所有的参与者发送“global-abort 消息”; 3.1.3 进入ABORT 状态; 3.2 若收到所有参与者发送的“vote-commit”消息; 3.2.1 写本地“global-commit”日志,进入COMMIT 状态; 3.1.2 向所有的参与者发送“global-commit 消息”; 等待并接收参与者发送的对“global-abort 消息”或“global-commit 消息”的确认响应消息, 一旦收到所有参与者的确认消息,写本地“end_transaction” 日志流程结束。 流程:两阶段提交协调者流程 写本地日志“init”记录,进入INIT 状态 等待并接受协调者发送的“prepare 消息”,收到后 2.1 若参与者可以提交本次事务 2.1.1 写本地日志“ready”,进入READY 状态 2.1.2 向协调者发送“vote-commit”消息 2.1.4 等待协调者的消息 2.1.4.1 若收到协调者的“global-abort”消息 2.1.4.1.1 写本地日志“abort”,进入ABORT 状态 2.1.4.1.2 向协调者发送对“global-abort”的确认消息 2.1.4.2 若收到协调者的“global-commit”消息 2.1.4.1.1 写本地日志“commit”,进入COMMIT 状态 2.1.4.1.2 向协调者发送对“global-commit”的确认消息 2.2 若参与者无法提交本次事务 2.2.1 写本地日志“abort”,进入ABORT 状态 2.2.2 向协调者发送“vote-abort”消息 2.2.3 流程对该参与者结束 2.2.4 若后续收到协调者的“global-abort”消息可以响应 即使流程结束,但任何时候收到协调者发送的“global-abort”消息或“global-commit”消息 也都要发送一个对应的确认消息。 异常处理 宕机恢复 协调者宕机恢复 协调者宕机恢复后,首先通过日志查找到宕机前的状态。 如果日志中最后是“begin_commit”记录,说明宕机前协调者处于WAIT 状态,协调者可能已经 发送过“prepare 消息”也可能还没发送,但协调者一定还没有发送过“global-commit 消息”或 “global-abort 消息”,即事务的全局状态还没有确定。此时,协调者可以重新发送“prepare 消息” 继续两阶段提交流程,即使参与者已经发送过对“prepare 消息”的响应,也不过是再次重传之前的 响应而不会影响协议的一致性。 如果日志中最后是“global-commit”或“global-abort”记录,说明宕机前协调者处于COMMIT 或ABORT 状态。此时协调者只需重新向所有的参与者发送“global-commit 消息”或“global-abort 消息”就可以继续两阶段提交流程。 参与者宕机恢复 参与者宕机恢复后,首先通过日志查找宕机前的状态。 如果日志中最后是“init”记录,说明参与者处于INIT 状态,还没有对本次事务做出投票选择, 参与者可以继续流程等待协调者发送的“prepare 消息”。 如果日志中最后是“ready”记录,说明参与者处于REDAY 状态,此时说明参与者已经就本次 事务做出了投票选择,但宕机前参与者是否已经向协调者发送“vote-commit”消息并不可知。所以 此时参与者可以向协调者重发“vote-commit”,并继续协议流程。 如果日志中最后是“commit”或“abort”记录,说明参与者已经收到过协调者的“global-commit 消息”(处于COMMIT 状态)或者“global-abort 消息”(处于ABORT 状态)。至于是否向协调者发 送过对“global-commit”或“global-abort”的确认消息则未知。但即使没有发送过确认消息,由于 协调者会不断重发“global-commit”或“global-abort”,只需在收到这些消息时发送确认消息既可, 不影响协议的全局一致性。 协议分析 两阶段提交协议在工程实践中真正使用的较少,主要原因有以下几点: 两阶段提交协议的容错能力较差。从上文的分析可以看出,两阶段提交协议在某些情况 下存在流程无法执行下去的情况,且也无法判断流程状态。在工程中好的分布式协议往往总是可以 在即使发生异常的情况下也能执行下去。例如,回忆Lease 机制(2.3 ),一旦lease 发出,无论出 现任何异常,Lease 服务器节点总是可以通过时间判定出Lease 是否有效,也可以用等待Lease 超时 的方法收回Lease 权限,整个Lease 协议的流程不存在任何流程被阻塞而无法执行下去的情况。与 Lease 机制的简单有效相比,两阶段提交的协议显得较为复杂且容错能力差。 两阶段提交协议的性能较差。一次成功的两阶段提交协议流程中,协调者与每个参与者 之间至少需要两轮交互4 个消息“prepare”、“vote-commit”、“global-commit”、“确认global-commit”。 过多的交互次数会降低性能。另一方面,协调者需要等待所有的参与者的投票结果,一旦存在较慢 的参与者,会影响全局流程执行速度。 虽然存在一些改进的两阶段提交协议可以提高容错能力和性能,然而这类协议依旧是在工程中 使用较少的一类协议,其理论价值大于实践意义。

kun坤 2020-04-24 15:32:58 0 浏览量 回答数 0

问题

测试平台对持续集成的支持(之四)——测试代码维护与调试

云效平台 2019-12-01 21:17:55 3105 浏览量 回答数 1

问题

上海大数据数据分析课程

chen2007 2019-12-01 21:15:59 8476 浏览量 回答数 2

回答

初识 MyBatis MyBatis 是第一个支持自定义 SQL、存储过程和高级映射的类持久框架。MyBatis 消除了大部分 JDBC 的样板代码、手动设置参数以及检索结果。MyBatis 能够支持简单的 XML 和注解配置规则。使 Map 接口和 POJO 类映射到数据库字段和记录。 MyBatis 的特点 那么 MyBatis 具有什么特点呢?或许我们可以从如下几个方面来描述 MyBatis 中的 SQL 语句和主要业务代码分离,我们一般会把 MyBatis 中的 SQL 语句统一放在 XML 配置文件中,便于统一维护。 解除 SQL 与程序代码的耦合,通过提供 DAO 层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。SQL 和代码的分离,提高了可维护性。 MyBatis 比较简单和轻量 本身就很小且简单。没有任何第三方依赖,只要通过配置 jar 包,或者如果你使用 Maven 项目的话只需要配置 Maven 以来就可以。易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。 屏蔽样板代码 MyBatis 回屏蔽原始的 JDBC 样板代码,让你把更多的精力专注于 SQL 的书写和属性-字段映射上。 编写原生 SQL,支持多表关联 MyBatis 最主要的特点就是你可以手动编写 SQL 语句,能够支持多表关联查询。 提供映射标签,支持对象与数据库的 ORM 字段关系映射 ORM 是什么?对象关系映射(Object Relational Mapping,简称ORM) ,是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。 提供 XML 标签,支持编写动态 SQL。 你可以使用 MyBatis XML 标签,起到 SQL 模版的效果,减少繁杂的 SQL 语句,便于维护。 MyBatis 整体架构 MyBatis 最上面是接口层,接口层就是开发人员在 Mapper 或者是 Dao 接口中的接口定义,是查询、新增、更新还是删除操作;中间层是数据处理层,主要是配置 Mapper -> XML 层级之间的参数映射,SQL 解析,SQL 执行,结果映射的过程。上述两种流程都由基础支持层来提供功能支撑,基础支持层包括连接管理,事务管理,配置加载,缓存处理等。 接口层 在不与Spring 集成的情况下,使用 MyBatis 执行数据库的操作主要如下: InputStream is = Resources.getResourceAsStream("myBatis-config.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(is); sqlSession = factory.openSession(); 其中的SqlSessionFactory,SqlSession是 MyBatis 接口的核心类,尤其是 SqlSession,这个接口是MyBatis 中最重要的接口,这个接口能够让你执行命令,获取映射,管理事务。 数据处理层 配置解析 在 Mybatis 初始化过程中,会加载 mybatis-config.xml 配置文件、映射配置文件以及 Mapper 接口中的注解信息,解析后的配置信息会形成相应的对象并保存到 Configration 对象中。之后,根据该对象创建SqlSessionFactory 对象。待 Mybatis 初始化完成后,可以通过 SqlSessionFactory 创建 SqlSession 对象并开始数据库操作。 SQL 解析与 scripting 模块 Mybatis 实现的动态 SQL 语句,几乎可以编写出所有满足需要的 SQL。 Mybatis 中 scripting 模块会根据用户传入的参数,解析映射文件中定义的动态 SQL 节点,形成数据库能执行的SQL 语句。 SQL 执行 SQL 语句的执行涉及多个组件,包括 MyBatis 的四大核心,它们是: Executor、StatementHandler、ParameterHandler、ResultSetHandler。SQL 的执行过程可以用下面这幅图来表示 MyBatis 层级结构各个组件的介绍(这里只是简单介绍,具体介绍在后面): SqlSession: ,它是 MyBatis 核心 API,主要用来执行命令,获取映射,管理事务。接收开发人员提供 Statement Id 和参数。并返回操作结果。Executor :执行器,是 MyBatis 调度的核心,负责 SQL 语句的生成以及查询缓存的维护。StatementHandler : 封装了JDBC Statement 操作,负责对 JDBC Statement 的操作,如设置参数、将Statement 结果集转换成 List 集合。ParameterHandler : 负责对用户传递的参数转换成 JDBC Statement 所需要的参数。ResultSetHandler : 负责将 JDBC 返回的 ResultSet 结果集对象转换成 List 类型的集合。TypeHandler : 用于 Java 类型和 JDBC 类型之间的转换。MappedStatement : 动态 SQL 的封装SqlSource : 表示从 XML 文件或注释读取的映射语句的内容,它创建将从用户接收的输入参数传递给数据库的 SQL。Configuration: MyBatis 所有的配置信息都维持在 Configuration 对象之中。 基础支持层 反射模块 Mybatis 中的反射模块,对 Java 反射进行了很好的封装,提供了简易的 API,方便上层调用,并且对反射操作进行了一系列的优化,比如,缓存了类的 元数据(MetaClass)和对象的元数据(MetaObject),提高了反射操作的性能。 类型转换模块 Mybatis 的别名机制,能够简化配置文件,该机制是类型转换模块的主要功能之一。类型转换模块的另一个功能是实现 JDBC 类型与 Java 类型的转换。在 SQL 语句绑定参数时,会将数据由 Java 类型转换成 JDBC 类型;在映射结果集时,会将数据由 JDBC 类型转换成 Java 类型。 日志模块 在 Java 中,有很多优秀的日志框架,如 Log4j、Log4j2、slf4j 等。Mybatis 除了提供了详细的日志输出信息,还能够集成多种日志框架,其日志模块的主要功能就是集成第三方日志框架。 资源加载模块 该模块主要封装了类加载器,确定了类加载器的使用顺序,并提供了加载类文件和其它资源文件的功能。 解析器模块 该模块有两个主要功能:一个是封装了 XPath,为 Mybatis 初始化时解析 mybatis-config.xml配置文件以及映射配置文件提供支持;另一个为处理动态 SQL 语句中的占位符提供支持。 数据源模块 Mybatis 自身提供了相应的数据源实现,也提供了与第三方数据源集成的接口。数据源是开发中的常用组件之一,很多开源的数据源都提供了丰富的功能,如连接池、检测连接状态等,选择性能优秀的数据源组件,对于提供ORM 框架以及整个应用的性能都是非常重要的。 事务管理模块 一般地,Mybatis 与 Spring 框架集成,由 Spring 框架管理事务。但 Mybatis 自身对数据库事务进行了抽象,提供了相应的事务接口和简单实现。 缓存模块 Mybatis 中有一级缓存和二级缓存,这两级缓存都依赖于缓存模块中的实现。但是需要注意,这两级缓存与Mybatis 以及整个应用是运行在同一个 JVM 中的,共享同一块内存,如果这两级缓存中的数据量较大,则可能影响系统中其它功能,所以需要缓存大量数据时,优先考虑使用 Redis、Memcache 等缓存产品。 Binding 模块 在调用 SqlSession 相应方法执行数据库操作时,需要制定映射文件中定义的 SQL 节点,如果 SQL 中出现了拼写错误,那就只能在运行时才能发现。为了能尽早发现这种错误,Mybatis 通过 Binding 模块将用户自定义的Mapper 接口与映射文件关联起来,系统可以通过调用自定义 Mapper 接口中的方法执行相应的 SQL 语句完成数据库操作,从而避免上述问题。注意,在开发中,我们只是创建了 Mapper 接口,而并没有编写实现类,这是因为 Mybatis 自动为 Mapper 接口创建了动态代理对象。 MyBatis 核心组件 在认识了 MyBatis 并了解其基础架构之后,下面我们来看一下 MyBatis 的核心组件,就是这些组件实现了从 SQL 语句到映射到 JDBC 再到数据库字段之间的转换,执行 SQL 语句并输出结果集。首先来认识 MyBatis 的第一个核心组件 SqlSessionFactory 对于任何框架而言,在使用该框架之前都要经历过一系列的初始化流程,MyBatis 也不例外。MyBatis 的初始化流程如下 String resource = "org/mybatis/example/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); sqlSessionFactory.openSession(); 上述流程中比较重要的一个对象就是SqlSessionFactory,SqlSessionFactory 是 MyBatis 框架中的一个接口,它主要负责的是 MyBatis 框架初始化操作 为开发人员提供SqlSession 对象 SqlSessionFactory 有两个实现类,一个是 SqlSessionManager 类,一个是 DefaultSqlSessionFactory 类 DefaultSqlSessionFactory : SqlSessionFactory 的默认实现类,是真正生产会话的工厂类,这个类的实例的生命周期是全局的,它只会在首次调用时生成一个实例(单例模式),就一直存在直到服务器关闭。 SqlSessionManager : 已被废弃,原因大概是: SqlSessionManager 中需要维护一个自己的线程池,而使用MyBatis 更多的是要与 Spring 进行集成,并不会单独使用,所以维护自己的 ThreadLocal 并没有什么意义,所以 SqlSessionManager 已经不再使用。 ####SqlSessionFactory 的执行流程 下面来对 SqlSessionFactory 的执行流程来做一个分析 首先第一步是 SqlSessionFactory 的创建 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 1 从这行代码入手,首先创建了一个 SqlSessionFactoryBuilder 工厂,这是一个建造者模式的设计思想,由 builder 建造者来创建 SqlSessionFactory 工厂 然后调用 SqlSessionFactoryBuilder 中的 build 方法传递一个InputStream 输入流,Inputstream 输入流中就是你传过来的配置文件 mybatis-config.xml,SqlSessionFactoryBuilder 根据传入的 InputStream 输入流和environment、properties属性创建一个XMLConfigBuilder对象。SqlSessionFactoryBuilder 对象调用XMLConfigBuilder 的parse()方法,流程如下。 XMLConfigBuilder 会解析/configuration标签,configuration 是 MyBatis 中最重要的一个标签,下面流程会介绍 Configuration 标签。 MyBatis 默认使用 XPath 来解析标签,关于 XPath 的使用,参见 https://www.w3school.com.cn/xpath/index.asp 在 parseConfiguration 方法中,会对各个在 /configuration 中的标签进行解析 重要配置 说一下这些标签都是什么意思吧 properties,外部属性,这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。 <properties> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/test" /> <property name="username" value="root" /> <property name="password" value="root" /> </properties> 一般用来给 environment 标签中的 dataSource 赋值 <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${driver}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> </dataSource> </environment> 还可以通过外部属性进行配置,但是我们这篇文章以原理为主,不会介绍太多应用层面的操作。 settings ,MyBatis 中极其重要的配置,它们会改变 MyBatis 的运行时行为。 settings 中配置有很多,具体可以参考 https://mybatis.org/mybatis-3/zh/configuration.html#settings 详细了解。这里介绍几个平常使用过程中比较重要的配置 一般使用如下配置 <settings> <setting name="cacheEnabled" value="true"/> <setting name="lazyLoadingEnabled" value="true"/> </settings> typeAliases,类型别名,类型别名是为 Java 类型设置的一个名字。 它只和 XML 配置有关。 <typeAliases> <typeAlias alias="Blog" type="domain.blog.Blog"/> </typeAliases> 当这样配置时,Blog 可以用在任何使用 domain.blog.Blog 的地方。 typeHandlers,类型处理器,无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。 在 org.apache.ibatis.type 包下有很多已经实现好的 TypeHandler,可以参考如下 你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。 具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很方便的类 org.apache.ibatis.type.BaseTypeHandler, 然后可以选择性地将它映射到一个 JDBC 类型。 objectFactory,对象工厂,MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现。 public class ExampleObjectFactory extends DefaultObjectFactory { public Object create(Class type) { return super.create(type); } public Object create(Class type, List constructorArgTypes, List constructorArgs) { return super.create(type, constructorArgTypes, constructorArgs); } public void setProperties(Properties properties) { super.setProperties(properties); } public boolean isCollection(Class type) { return Collection.class.isAssignableFrom(type); } } 然后需要在 XML 中配置此对象工厂 <objectFactory type="org.mybatis.example.ExampleObjectFactory"> <property name="someProperty" value="100"/> </objectFactory> plugins,插件开发,插件开发是 MyBatis 设计人员给开发人员留给自行开发的接口,MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。MyBatis 允许使用插件来拦截的方法调用包括:Executor、ParameterHandler、ResultSetHandler、StatementHandler 接口,这几个接口也是 MyBatis 中非常重要的接口,我们下面会详细介绍这几个接口。 environments,MyBatis 环境配置,MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中 使用相同的 SQL 映射。 这里注意一点,虽然 environments 可以指定多个环境,但是 SqlSessionFactory 只能有一个,为了指定创建哪种环境,只要将它作为可选的参数传递给 SqlSessionFactoryBuilder 即可。 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties); databaseIdProvider ,数据库厂商标示,MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 <databaseIdProvider type="DB_VENDOR"> <property name="SQL Server" value="sqlserver"/> <property name="DB2" value="db2"/> <property name="Oracle" value="oracle" /> </databaseIdProvider> mappers,映射器,这是告诉 MyBatis 去哪里找到这些 SQL 语句,mappers 映射配置有四种方式 上面的一个个属性都对应着一个解析方法,都是使用 XPath 把标签进行解析,解析完成后返回一个 DefaultSqlSessionFactory 对象,它是 SqlSessionFactory 的默认实现类。这就是 SqlSessionFactoryBuilder 的初始化流程,通过流程我们可以看到,初始化流程就是对一个个 /configuration 标签下子标签的解析过程。 SqlSession 在 MyBatis 初始化流程结束,也就是 SqlSessionFactoryBuilder -> SqlSessionFactory 的获取流程后,我们就可以通过 SqlSessionFactory 对象得到 SqlSession 然后执行 SQL 语句了。具体来看一下这个过程‘ 在 SqlSessionFactory.openSession 过程中我们可以看到,会调用到 DefaultSqlSessionFactory 中的 openSessionFromDataSource 方法,这个方法主要创建了两个与我们分析执行流程重要的对象,一个是 Executor 执行器对象,一个是 SqlSession 对象。执行器我们下面会说,现在来说一下 SqlSession 对象 SqlSession 对象是 MyBatis 中最重要的一个对象,这个接口能够让你执行命令,获取映射,管理事务。SqlSession 中定义了一系列模版方法,让你能够执行简单的 CRUD 操作,也可以通过 getMapper 获取 Mapper 层,执行自定义 SQL 语句,因为 SqlSession 在执行 SQL 语句之前是需要先开启一个会话,涉及到事务操作,所以还会有 commit、 rollback、close 等方法。这也是模版设计模式的一种应用。 MapperProxy MapperProxy 是 Mapper 映射 SQL 语句的关键对象,我们写的 Dao 层或者 Mapper 层都是通过 MapperProxy 来和对应的 SQL 语句进行绑定的。下面我们就来解释一下绑定过程 这就是 MyBatis 的核心绑定流程,我们可以看到 SqlSession 首先调用 getMapper 方法,我们刚才说到 SqlSession 是大哥级别的人物,只定义标准(有一句话是怎么说的来着,一流的企业做标准,二流的企业做品牌,三流的企业做产品)。 SqlSession 不愿意做的事情交给 Configuration 这个手下去做,但是 Configuration 也是有小弟的,它不愿意做的事情直接甩给小弟去做,这个小弟是谁呢?它就是 MapperRegistry,马上就到核心部分了。MapperRegistry 相当于项目经理,项目经理只从大面上把握项目进度,不需要知道手下的小弟是如何工作的,把任务完成了就好。最终真正干活的还是 MapperProxyFactory。看到这段代码 Proxy.newProxyInstance ,你是不是有一种恍然大悟的感觉,如果你没有的话,建议查阅一下动态代理的文章,这里推荐一篇 (https://www.jianshu.com/p/95970b089360) 也就是说,MyBatis 中 Mapper 和 SQL 语句的绑定正是通过动态代理来完成的。 通过动态代理,我们就可以方便的在 Dao 层或者 Mapper 层定义接口,实现自定义的增删改查操作了。那么具体的执行过程是怎么样呢?上面只是绑定过程,别着急,下面就来探讨一下 SQL 语句的执行过程。 MapperProxyFactory 会生成代理对象,这个对象就是 MapperProxy,最终会调用到 mapperMethod.execute 方法,execute 方法比较长,其实逻辑比较简单,就是判断是 插入、更新、删除 还是 查询 语句,其中如果是查询的话,还会判断返回值的类型,我们可以点进去看一下都是怎么设计的。 很多代码其实可以忽略,只看我标出来的重点就好了,我们可以看到,不管你前面经过多少道关卡处理,最终都逃不过 SqlSession 这个老大制定的标准。 我们以 selectList 为例,来看一下下面的执行过程。 这是 DefaultSqlSession 中 selectList 的代码,我们可以看到出现了 executor,这是什么呢?我们下面来解释。 Executor 还记得我们之前的流程中提到了 Executor(执行器) 这个概念吗?我们来回顾一下它第一次出现的位置。 由 Configuration 对象创建了一个 Executor 对象,这个 Executor 是干嘛的呢?下面我们就来认识一下 Executor 的继承结构 每一个 SqlSession 都会拥有一个 Executor 对象,这个对象负责增删改查的具体操作,我们可以简单的将它理解为 JDBC 中 Statement 的封装版。 也可以理解为 SQL 的执行引擎,要干活总得有一个发起人吧,可以把 Executor 理解为发起人的角色。 首先先从 Executor 的继承体系来认识一下 如上图所示,位于继承体系最顶层的是 Executor 执行器,它有两个实现类,分别是BaseExecutor和 CachingExecutor。 BaseExecutor 是一个抽象类,这种通过抽象的实现接口的方式是适配器设计模式之接口适配 的体现,是Executor 的默认实现,实现了大部分 Executor 接口定义的功能,降低了接口实现的难度。BaseExecutor 的子类有三个,分别是 SimpleExecutor、ReuseExecutor 和 BatchExecutor。 SimpleExecutor : 简单执行器,是 MyBatis 中默认使用的执行器,每执行一次 update 或 select,就开启一个Statement 对象,用完就直接关闭 Statement 对象(可以是 Statement 或者是 PreparedStatment 对象) ReuseExecutor : 可重用执行器,这里的重用指的是重复使用 Statement,它会在内部使用一个 Map 把创建的Statement 都缓存起来,每次执行 SQL 命令的时候,都会去判断是否存在基于该 SQL 的 Statement 对象,如果存在 Statement 对象并且对应的 connection 还没有关闭的情况下就继续使用之前的 Statement 对象,并将其缓存起来。因为每一个 SqlSession 都有一个新的 Executor 对象,所以我们缓存在 ReuseExecutor 上的 Statement作用域是同一个 SqlSession。 BatchExecutor : 批处理执行器,用于将多个 SQL 一次性输出到数据库 CachingExecutor: 缓存执行器,先从缓存中查询结果,如果存在就返回之前的结果;如果不存在,再委托给Executor delegate 去数据库中取,delegate 可以是上面任何一个执行器。 Executor 的创建和选择 我们上面提到 Executor 是由 Configuration 创建的,Configuration 会根据执行器的类型创建,如下 这一步就是执行器的创建过程,根据传入的 ExecutorType 类型来判断是哪种执行器,如果不指定 ExecutorType ,默认创建的是简单执行器。它的赋值可以通过两个地方进行赋值: 可以通过 标签来设置当前工程中所有的 SqlSession 对象使用默认的 Executor <settings> <!--取值范围 SIMPLE, REUSE, BATCH --> <setting name="defaultExecutorType" value="SIMPLE"/> </settings> 另外一种直接通过Java对方法赋值的方式 session = factory.openSession(ExecutorType.BATCH); Executor 的具体执行过程 Executor 中的大部分方法的调用链其实是差不多的,下面是深入源码分析执行过程,如果你没有时间或者暂时不想深入研究的话,给你下面的执行流程图作为参考。 我们紧跟着上面的 selectList 继续分析,它会调用到 executor.query 方法。 当有一个查询请求访问的时候,首先会经过 Executor 的实现类 CachingExecutor ,先从缓存中查询 SQL 是否是第一次执行,如果是第一次执行的话,那么就直接执行 SQL 语句,并创建缓存,如果第二次访问相同的 SQL 语句的话,那么就会直接从缓存中提取。 上面这段代码是从 selectList -> 从缓存中 query 的具体过程。可能你看到这里有些觉得类都是什么东西,我想鼓励你一下,把握重点,不用每段代码都看,从找到 SQL 的调用链路,其他代码想看的时候在看,看源码就是很容易发蒙,容易烦躁,但是切记一点,把握重点。 上面代码会判断缓存中是否有这条 SQL 语句的执行结果,如果没有的话,就再重新创建 Executor 执行器执行 SQL 语句,注意, list = doQuery 是真正执行 SQL 语句的过程,这个过程中会创建我们上面提到的三种执行器,这里我们使用的是简单执行器。 到这里,执行器所做的工作就完事了,Executor 会把后续的工作交给 StatementHandler 继续执行。下面我们来认识一下 StatementHandler 上面代码会判断缓存中是否有这条 SQL 语句的执行结果,如果没有的话,就再重新创建 Executor 执行器执行 SQL 语句,注意, list = doQuery 是真正执行 SQL 语句的过程,这个过程中会创建我们上面提到的三种执行器,这里我们使用的是简单执行器。 到这里,执行器所做的工作就完事了,Executor 会把后续的工作交给 StatementHandler 继续执行。下面我们来认识一下 StatementHandler StatementHandler 的继承结构 有没有感觉和 Executor 的继承体系很相似呢?最顶级接口是四大组件对象,分别有两个实现类 BaseStatementHandler 和 RoutingStatementHandler,BaseStatementHandler 有三个实现类, 他们分别是 SimpleStatementHandler、PreparedStatementHandler 和 CallableStatementHandler。 RoutingStatementHandler : RoutingStatementHandler 并没有对 Statement 对象进行使用,只是根据StatementType 来创建一个代理,代理的就是对应Handler的三种实现类。在MyBatis工作时,使用的StatementHandler 接口对象实际上就是 RoutingStatementHandler 对象。 BaseStatementHandler : 是 StatementHandler 接口的另一个实现类,它本身是一个抽象类,用于简化StatementHandler 接口实现的难度,属于适配器设计模式体现,它主要有三个实现类 SimpleStatementHandler: 管理 Statement 对象并向数据库中推送不需要预编译的SQL语句。PreparedStatementHandler: 管理 Statement 对象并向数据中推送需要预编译的SQL语句。CallableStatementHandler:管理 Statement 对象并调用数据库中的存储过程。 StatementHandler 的创建和源码分析 我们继续来分析上面 query 的调用链路,StatementHandler 的创建过程如下 MyBatis 会根据 SQL 语句的类型进行对应 StatementHandler 的创建。我们以预处理 StatementHandler 为例来讲解一下 执行器不仅掌管着 StatementHandler 的创建,还掌管着创建 Statement 对象,设置参数等,在创建完 PreparedStatement 之后,我们需要对参数进行处理了。 如 如果用一副图来表示一下这个执行流程的话我想是这样 这里我们先暂停一下,来认识一下第三个核心组件 ParameterHandler ParameterHandler - ParameterHandler 介绍 ParameterHandler 相比于其他的组件就简单很多了,ParameterHandler 译为参数处理器,负责为 PreparedStatement 的 sql 语句参数动态赋值,这个接口很简单只有两个方法 ParameterHandler 只有一个实现类 DefaultParameterHandler , 它实现了这两个方法。 getParameterObject: 用于读取参数setParameters: 用于对 PreparedStatement 的参数赋值ParameterHandler 的解析过程 上面我们讨论过了 ParameterHandler 的创建过程,下面我们继续上面 parameterSize 流程 这就是具体参数的解析过程了,下面我们来描述一下 下面用一个流程图表示一下 ParameterHandler 的解析过程,以简单执行器为例 我们在完成 ParameterHandler 对 SQL 参数的预处理后,回到 SimpleExecutor 中的 doQuery 方法 上面又引出来了一个重要的组件那就是 ResultSetHandler,下面我们来认识一下这个组件 ResultSetHandler - ResultSetHandler 简介 ResultSetHandler 也是一个非常简单的接口 ResultSetHandler 是一个接口,它只有一个默认的实现类,像是 ParameterHandler 一样,它的默认实现类是DefaultResultSetHandler ResultSetHandler 解析过程 MyBatis 只有一个默认的实现类就是 DefaultResultSetHandler,DefaultResultSetHandler 主要负责处理两件事 处理 Statement 执行后产生的结果集,生成结果列表 处理存储过程执行后的输出参数 按照 Mapper 文件中配置的 ResultType 或 ResultMap 来封装成对应的对象,最后将封装的对象返回即可。 其中涉及的主要对象有: ResultSetWrapper : 结果集的包装器,主要针对结果集进行的一层包装,它的主要属性有 ResultSet : Java JDBC ResultSet 接口表示数据库查询的结果。 有关查询的文本显示了如何将查询结果作为java.sql.ResultSet 返回。 然后迭代此ResultSet以检查结果。 TypeHandlerRegistry: 类型注册器,TypeHandlerRegistry 在初始化的时候会把所有的 Java类型和类型转换器进行注册。 ColumnNames: 字段的名称,也就是查询操作需要返回的字段名称 ClassNames: 字段的类型名称,也就是 ColumnNames 每个字段名称的类型 JdbcTypes: JDBC 的类型,也就是 java.sql.Types 类型 ResultMap: 负责处理更复杂的映射关系 在 DefaultResultSetHandler 中处理完结果映射,并把上述结构返回给调用的客户端,从而执行完成一条完整的SQL语句。 内容转载自:CSDN博主:cxuann 原文链接:https://blog.csdn.net/qq_36894974/article/details/104132876?depth_1-utm_source=distribute.pc_feed.none-task&request_id=&utm_source=distribute.pc_feed.none-task

问问小秘 2020-03-05 15:44:27 0 浏览量 回答数 0

问题

pyflame Uber 开源的 Python 性能分析工具,可在不修改代码的情况下分析性能

huc_逆天 2020-05-21 19:12:03 16 浏览量 回答数 1

回答

精选几个Java测试工具,希望能帮到你:1.Arquillian Arquillian是JVM一个高度创新性和可扩展的测试平台,支持Java开发人员轻松创建自动化集合的,功能性的和验收的测试。Arquillian允许在运行时间执行测试。Arquillian可以用来管理单个或多个容器的生命周期,捆扎测试用例,从属类和资源。它还能够部署归档到容器中,在容器中执行测试、捕获结果,并创建报告。 Arquillian集成了常见的测试框架,如JUnit 4、TestNG 5,并允许使用现有的IDE发布测试,并且由于其模块化的设计使得能够运行Ant和Maven测试插件。2.JTest JTest也被称为“Parasoft JTest”,是一款通过Parasoft制作的自动化的Java软件测试和静态分析软件。JTest包含的功能有:单元测试情况下的生成和执行、静态代码分析、数据流的静态分析、度量分析、回归测试、运行时错误检测。 此外,它还具备了同行代码审查流程自动化和运行时错误检测的功能,如:竞态条件、异常、资源和内存泄漏、安全漏洞攻击。3.The Grinder “The Grinder”是一个Java负载测试框架,不但运行简单,而且其分布式测试采用了许多负载注入机器。只要有Java API,The Grinder就可以负载测试。这包括HTTP Web服务器、SOAP和REST Web服务器、应用程序服务器、以及用强大的Jython和Clojure语言写的包含了自定义协议的测试脚本。The Grinder的GUI控制台允许对多个负载注射器进行监测和控制,并自动管理客户端连接和cookies、SSL、代理感知和节流连接。 The Grinder在BSD风格的开源许可下是免费的。 4.TestNG TestNG是一款为Java编程语言设计的测试框架,灵感来自于JUnit和NUnit。 TestNG的主要功能是覆盖范围更广的测试分类,如单元、功能性、端到端,一体化等。它还有一些新的功能,可以使之更强大和更容易使用,如:注解、具备大型线程池各种策略的运行测试、多线程的代码测试、灵活的测试配置、参数化数据驱动的测试支持,等等。 TestNG支持各种各样的工具和插件,比如Eclipse、IDEA、Maven等等。 5.JUnit JUnit是一个为Java编程语言设计的单元测试框架。 JUnit为测试驱动开发框架的发展发挥了重要作用。它是现在被统称为xUnit的单元测试框架大家庭的组成成员之一,源于SUnit。 在编译时,JUnit可以连接作为JAR,用于编写可重复的测试。6.Powermock PowerMock是一款支持单元测试源代码的Java框架。虽然PowerMock可以作为Mocking框架,例如Mockito和EasyMock的扩展而运行,但是它具备了更强大的能力。PowerMock利用自定义的类加载器和字节码操纵器,来确保静态方法的模拟、静态初始化的删除、函数构造、最终的类和方法以及私有方法。它的主要目的是通过最少的方法和注释来扩展现有的API,以获得额外的功能。7.CucumberCucumber 是 BDD 模式下实现可执行规范(Executable Specifications)的开源工具,但是它的使命并不局限于做自动化验收测试,更加重要的在于其能够在团队成员之间构建统一的交流基础(feature 文件)、规范交流用语(Domain Specific Language)、提高各个利益相关方(Business Stakeholders)沟通效率和效果,从而达到提升产品质量、做成客户期望得到的产品这一最终目标

tama_test 2019-12-02 01:55:29 0 浏览量 回答数 0

问题

分析接口配置

反向一觉 2019-12-01 21:06:56 1330 浏览量 回答数 0

问题

如何做好系统测试

云效平台 2019-12-01 21:38:08 3055 浏览量 回答数 1

回答

数据挖掘有很多不同的实施方法,如果只是把数据拉到Excel表格中计算一下,那只是数据分析,不是数据挖掘。CRISP-DM和SEMMA是两种常用的数据挖掘流程。 从数据本身来考虑,数据挖掘通常需要有信息收集、数据集成、数据规约、数据清理、数据变换、数据挖掘实施过程、模式评估和知识表示8个步骤。 步骤(1)信息收集:根据确定的数据分析对象,抽象出在数据分析中所需要的特征信息,然后选择合适的信息收集方法,将收集到的信息存入数据库。对于海量数据,选择一个合适的数据存储和管理的数据仓库是至关重要的。 步骤(2)数据集成:把不同来源、格式、特点性质的数据在逻辑上或物理上有机地集中,从而为企业提供全面的数据共享。 步骤(3)数据规约:如果执行多数的数据挖掘算法,即使是在少量数据上也需要很长的时间,而做商业运营数据挖掘时数据量往往非常大。数据规约技术可以用来得到数据集的规约表示,它小得多,但仍然接近于保持原数据的完整性,并且规约后执行数据挖掘结果与规约前执行结果相同或几乎相同。 步骤(4)数据清理:在数据库中的数据有一些是不完整的(有些感兴趣的属性缺少属性值)、含噪声的(包含错误的属性值),并且是不一致的(同样的信息不同的表示方式),因此需要进行数据清理,将完整、正确、一致的数据信息存入数据仓库中。不然,挖掘的结果会差强人意。 步骤(5)数据变换:通过平滑聚集、数据概化、规范化等方式将数据转换成适用于数据挖掘的形式。对于有些实数型数据,通过概念分层和数据的离散化来转换数据也是重要的一步。 步骤(6)数据挖掘过程:根据数据仓库中的数据信息,选择合适的分析工具,应用统计方法、事例推理、决策树、规则推理、模糊集,甚至神经网络、遗传算法的方法处理信息,得出有用的分析信息。 步骤(7)模式评估:从商业角度,由行业专家来验证数据挖掘结果的正确性。 步骤(8)知识表示:将数据挖掘所得到的分析信息以可视化的方式呈现给用户,或作为新的知识存放在知识库中,供其他应用程序使用。 数据挖掘过程是一个反复循环的过程,每一个步骤如果没有达到预期目标,都需要回到前面的步骤,重新调整并执行。不是每件数据挖掘的工作都需要这里列出的每一步,例如在某个工作中不存在多个数据源的时候,步骤(2)便可以省略。 步骤(3)数据规约、步骤(4)数据清理、步骤(5)数据变换又合称数据预处理。在数据挖掘中,至少60%的费用可能要花在步骤(1)信息收集阶段,而其中至少60%以上的精力和时间花在了数据预处理过程中

保持可爱mmm 2019-12-02 03:09:42 0 浏览量 回答数 0

问题

不知何时【系统性能方面问题】变成了找工作的敲门砖 400 请求报错 

kun坤 2020-05-29 10:55:04 5 浏览量 回答数 1

回答

web数据集成技术可以从web上自动获取数据,但是获取的信息存在着大量的脏数据,比如滥用缩写词,惯用语,数据输入错误,重复记录,丢失值,拼写变化,不同的计量单位。这些数据是没有意义的,根本就不可能为以后的数据挖掘决策分析提供任何支持。数据清洗主要是提高数据的可用性,目前,数据清洗主要应用于三个领域: 1 数据仓库(DW) 2数据库中的知识发现(KDD) 3数据质量管理(TDQM) 我在公司里的第一个项目就是数据质量管理,在这里在说下数据质量管理: 通过制定、实施数据质量检核,暴露各系统数据质量问题。持续监控各系统数据质量波动情况及数据质量规则占比分析,定期生成各系统关键数据质量报告,掌握系统数据质量状况。结合系统提供的清洗组件以及数据质量问题处理流程为各系统数据质量提升提供有效支撑。数据质量(DataQuality)管理是贯穿数据生命周期的全过程,覆盖质量评估,数据去噪,数据监控,数据探查,数据清洗,数据诊断等方面。数据度量和变化频度提供了衡量数据质量好坏的手段。数据度量主要包括完整性、唯一性、一致性、准确性、合法性。变化频度主要包括业务系统数据的变化周期和实体数据的刷新周期。数据质量管理准则包括测量、提高组织数据的质量和整合性的方法。数据质量处理包括数据标准化、匹配、生存和质量监测。数据必须具备适当的质量,以解决业务要求问题。 结合大数据的参考框架及数据处理实际需求情况,数据质量管理系统主要功能定位为:数据发现、质量管理、元数据、主数据管理和信息政策管理。在数据生命周期中,数据的获取和使用周期包括系列活动:评估,分析,调整,丢弃数据,目前数据清洗的模型: 基于粗糙集理论数据清洗 基于聚式模式数据清洗 基于模糊匹配数据清洗模型 基于遗传神经网络数据清洗 基于专家系统体系结构等数据校验及转换 数据校验的目的是确保抽取数据本身的正确性和完整性, 数据转换的目的是保证数据的一致性数据清洗流程1数据预处理: 包括数据元素化,保准化 2确定清洗方法: 3校验清洗方法:先验证所用的清洗方法是否合适,抽取小样本进行验证,判断其召回率和准确率 4执行清洗工具: 5数据归档:将新旧数据源进行归档处理,方便以后的清洗一般情况下,模式中反应的元数据对应判断一个数据源的质量远远不够,因此通过具体实例来获得有关数据熟悉和不寻常模式的元数据很重要。这些元数据可以帮助发现数据质量问题,也有助于发现属性间的依赖关系,

xuning715 2019-12-02 01:12:15 0 浏览量 回答数 0

问题

ERP的业务流程解析

hua2012h 2019-12-01 20:14:18 6314 浏览量 回答数 0

回答

排查对应的文件是否是日志文件 1. 查看Bucket是否有开启日志设置。 - 登录OSS管理控制台界面。 - 在左侧存储空间列表中,单击目标存储空间名称,打开该存储空间概览页面。 - 单击 基础设置 页签,找到 日志管理 区域,查看是否有开启日志设置,如果已经开启则执行下一步,如果没开启则那么对应的记录是没有的,建议开启OSS日志,下次出现异常文件,进行定位分析。开启日志请参考设置日志。 排查异常Object资源的文件名称是否符合OSS日志记录的命名规则,即[$TargetPrefix][$SourceBucket]YYYY-mm-DD-HH-MM-SS-[$UniqueString]。 如果异常Object资源符合OSS日志记录的命名规范,并且对应的内容格式符合OSS日志字段的格式,那么该Object资源就是OSS的日志文件。 OSS日志格式说明请参考设置访问日志记录。 OSS日志如何关闭流程:在OSS管理控制台中选择具体Bucket,然后依次单击 基础设置 > 日志管理 > 管理,然后关闭即可。 对应的文件不是OSS的日志文件 分析OSS日志,排查对应的资源是什么IP、什么业务进行上传的,分析下对应的业务是否是正常的业务。 如果不是正常业务操作上传的资源。 排查Bucket是否为公共读写权限,如果是,则应改为公共读或私有。 如果Bucket为私有权限,排查下账户的AccessKeyId密码是否暴露。建议生成新的AccessKeyId密码替换旧的,将旧的删除。

剑曼红尘 2020-03-26 18:56:43 0 浏览量 回答数 0

问题

太航建材行业ERP系统

lovequeen0 2019-12-01 20:17:18 8952 浏览量 回答数 1

问题

云服务器 ECS Linux 系统如何安装图形化桌面

boxti 2019-12-01 22:02:45 6496 浏览量 回答数 0

问题

Cloudera数据分析师上海

漾漾 2019-12-01 22:07:05 6099 浏览量 回答数 0

回答

背景信息 工业大脑产品交付的环节为:数据验证(可行性)> 数据建模(基础过程)> 调优(调试)> 结果统计(成果)。其中数据验证环节是判断客户数据是否能支撑项目落地的第一个环节,它的执行者一般是交付团队或者ISV。在数据验证环节使用到的工具,需要具备支撑交付团队或ISV对数据进行评估、使客户确认产品可以对其业务产生价值收益的能力。 在目前AI创作间可实现的基础上,工业大脑需要一种能够降低POC数据验证环节的操作门槛的操作模式。但现有的测试模式过于复杂,而且不便于大面积推广,因此需要一种线上、标准化的模式用于效果评测,辅助进行项目产品化铺开。 使用流程 交付人员可以通过AI创作间的智能服务功能,完成POC数据验证阶段的工作,不用写代码即可完成全部流程,得到数据评估结果,主要包括以下几方面。 将历史数据按时序进行API进行调用,将每次调用结果进行记录,作为模拟结果值,详情请参见下文的预测结果调用。 将API调用模拟结果值和原始数据的值以趋势图的方式展示,详情请参见下文的预测结果调用。 对原始数据和模拟推荐的值进行统计计算,得到下降和增多的数值,详情请参见下文的结果对比分析。

剑曼红尘 2020-03-24 13:29:18 0 浏览量 回答数 0

问题

运维分享—linux系统Dnat脚本

大象吃豆子 2019-12-01 21:02:15 7353 浏览量 回答数 1

问题

【视频】前端网络(性能)监测工具 berserkJS

随歌 2019-12-01 22:06:18 11102 浏览量 回答数 0

回答

排查对应的文件是否是日志文件 查看Bucket是否有开启日志设置。 登录OSS管理控制台界面。 在左侧存储空间列表中,单击目标存储空间名称,打开该存储空间概览页面。 单击 基础设置 页签,找到 日志管理 区域,查看是否有开启日志设置,如果已经开启则执行下一步,如果没开启则那么对应的记录是没有的,建议开启OSS日志,下次出现异常文件,进行定位分析。开启日志请参考设置日志。 排查异常Object资源的文件名称是否符合OSS日志记录的命名规则,即[$TargetPrefix][$SourceBucket]YYYY-mm-DD-HH-MM-SS-[$UniqueString]。 如果异常Object资源符合OSS日志记录的命名规范,并且对应的内容格式符合OSS日志字段的格式,那么该Object资源就是OSS的日志文件。 OSS日志格式说明请参考设置访问日志记录。 OSS日志如何关闭流程:在OSS管理控制台中选择具体Bucket,然后依次单击 基础设置 > 日志管理 > 管理,然后关闭即可。

问问小秘 2020-02-28 22:23:38 0 浏览量 回答数 0

问题

在 berserkJS 中无缝使用 Wind.js:报错

kun坤 2020-06-07 14:00:40 0 浏览量 回答数 1

问题

基于支付系统真实业务场景的分布式事务处理实例分析:报错

kun坤 2020-06-08 11:12:18 2 浏览量 回答数 1

问题

深入理解Magento - 第二章 - Magento请求分发与控制器 400 请求报错 

kun坤 2020-05-28 16:31:47 5 浏览量 回答数 1

回答

本文主要介绍了Linux和Windows环境下常用的抓包工具以及抓包后提交工单的流程。 详细信息 阿里云提醒您: 如果您对实例或数据有修改、变更等风险操作,务必注意实例的容灾、容错能力,确保数据安全。 如果您对实例(包括但不限于ECS、RDS)等进行配置与数据修改,建议提前创建快照或开启RDS日志备份等功能。 如果您在阿里云平台授权或者提交过登录账号、密码等安全信息,建议您及时修改。 如果源服务器访问目标服务器时出现异常,您可以抓包获取最原始的交互数据,然后反馈至阿里云进行排查分析。在介绍常用的抓包工具以及如何抓包的详细信息前,请参考如下文档进行排查问题和分析问题。 能ping通但端口不通时端口可用性探测说明 丢包或不通时链路测试说明 Linux系统的ECS中没有禁PING却PING不通的解决方法 Linux环境中常用的抓包工具详细信息如下。 Linux环境中的抓包工具 Linux环境中通常使用TCPDump工具进行抓包和分析,TCPDump工具是所有Linux发行版本预装的数据包抓取和分析工具。有关TCPDump工具的获取和安装方法,请参考如下文档。 TCPDump 官方文档 关于TCPDump的用法,请参考如下。 tcpdump [ -AbdDefhHIJKlLnNOpqStuUvxX# ] [ -B buffer_size ] [ -c count ] [ -C file_size ] [ -G rotate_seconds ] [ -F file ] [ -i interface ] [ -j tstamp_type ] [ -m module ] [ -M secret ] [ --number ] [ -Q in|out|inout ] [ -r file ] [ -V file ] [ -s snaplen ] [ -T type ] [ -w file ] [ -W filecount ] [ -E spi@ipaddr algo:secret,... ] [ -y datalinktype ] [ -z postrotate-command ] [ -Z user ] [ --time-stamp-precision=tstamp_precision ] [ --immediate-mode ] [ --version ] [ expression ] 关于tcpdump命令的参数说明如下所示(区分大小写)。 -s:用于设置数据包抓取长度。如果-s为0,则表示自动选择合适的长度来抓取数据包。 -w:用于将抓包结果导出到文件,而不是在控制台进行分析和打印输出。 -i:用于指定需要监听的接口(网卡)。 -vvv:用于输出详细的交互数据。 expression:是一个正则表达式,用于过滤报文。主要包含如下几类。 指定类型的关键字:包括host(主机)、net(网络)和port(端口)。 指定传输方向的关键字:包括src(源)、dst(目标)、dst or src(源或目标)和dst and src(源和目标)。 指定协议的关键字:包括ICMP、IP、ARP、RARP、TCP和UDP等协议类型。 关于其他参数说明及用法请参考如下文档。 tcpdump 的 Manpage 关于tcpdump常见用法和示例输出的详细信息,请参考如下。 执行如下命令,抓取指定网卡指定端口的交互数据。 tcpdump -s 0 -i eth0 port 22 系统显示类似如下。 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes 20:24:59.414951 IP 172.xx.xx.226.ssh > 42.xx.xx.107.43414: Flags [P.], seq 442372:442536, ack 53, win 141, length 164 20:24:59.415002 IP 172.xx.xx.226.ssh > 42.xx.xx.107.43414: Flags [P.], seq 442536:442700, ack 53, win 141, length 164 20:24:59.415052 IP 172.xx.xx.226.ssh > 42.xx.xx.107.43414: Flags [P.], seq 442700:442864, ack 53, win 141, length 164 20:24:59.415103 IP 172.xx.xx.226.ssh > 42.xx.xx.107.43414: Flags [P.], seq 442864:443028, ack 53, win 141, length 164 执行如下命令,抓取指定网卡发送给指定IP上指定端口的交互数据,并在控制台输出详细交互信息。 tcpdump -s 0 -i eth1 -vvv port 22 系统显示类似如下。 tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes 20:24:20.991006 IP (tos 0x10, ttl 64, id 22747, offset 0, flags [DF], proto TCP (6), length 316) 172.xx.xx.226.ssh > 42.xx.xx.107.43414: Flags [P.], cksum 0x2504 (incorrect -> 0x270d), seq 133624:133900, ack 1, win 141, length 276 20:24:20.991033 IP (tos 0x0, ttl 53, id 2348, offset 0, flags [DF], proto TCP (6), length 92) 42.xx.xx.107.43414 > 172.xx.xx.226.ssh: Flags [P.], cksum 0x4759 (correct), seq 1:53, ack 129036, win 15472, length 52 执行如下命令,抓取发送至指定IP的PING交互数据,并在控制台输出详细交互数据。 tcpdump -s 0 -i eth1 -vvv dst 223.xx.xx.5 and icmp 系统显示类似如下。 tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes 20:26:00.368958 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84) 172.xx.xx.226 > public1.alidns.com: ICMP echo request, id 55097, seq 341, length 64 20:26:01.369996 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84) 172.xx.xx.226 > public1.alidns.com: ICMP echo request, id 55097, seq 342, length 64 20:26:02.371058 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84) 172.xx.xx.226 > public1.alidns.com: ICMP echo request, id 55097, seq 343, length 64 20:26:03.372181 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84) 172.xx.xx.226 > public1.alidns.com: ICMP echo request, id 55097, seq 344, length 64 执行如下命令,抓取系统内所有接口数据并保存到指定文件。 tcpdump -i any -s 0 -w test.cap 系统显示类似如下。 tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes Windows环境中常用的抓包工具详细信息如下。 Windows环境中的抓包工具 Windows环境中一般使用免费的较为流行的Wireshark开源工具进行抓包和分析。请参考Wireshark官方网站,获取并安装Wireshark工具,安装方法请参考Windows系统中Wireshark抓包工具的安装使用方法。 以下是Wireshark抓包的操作步骤。 安装并打开Wireshark工具。 单击 捕获 > 选项。 在 WireShark 捕获接口 界面中,根据接口名称或对应的IP地址选择需要进行抓包的网卡,然后单击 开始。 抓取足量数据包后,单击 捕获 > 停止。 单击 文件 > 保存,将抓包结果保存到指定文件。 更多有关Wireshark工具使用和数据分析方法,请参考其官方文档。 以下是抓包和提交工单流程的详细信息。 抓包并提交工单流程 出现异常时,您可以抓取数据包并发送给阿里云售后技术支持。抓包时请确保从源服务器和目标服务器同时并发操作,以便阿里云技术支持进行对比分析。具体操作步骤如下。 确认源服务器和目标服务器进行数据交互通过的网卡。 如果源服务器通过NAT共享方式访问公网,则访问淘宝IP地址库,获取本地网络对应的公网IP地址。 利用前文所述工具,从源服务器对目标服务器地址的目标端口进行抓包,或者进行完整抓包,然后保存抓包数据。 利用前文所述工具,从目标服务器对源服务器地址进行抓包,或者进行完整抓包,然后保存抓包数据。 创建工单并附上抓包数据文件,提交工单后,阿里云技术支持会排查问题并通过工单向您反馈结果。 适用于

1934890530796658 2020-03-25 23:47:27 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站