加密软件VMProtect教程:使用Windows、Net 、UNIX 秘钥生成器

news2024/11/16 9:44:28

VMProtect是新一代软件保护实用程序。VMProtect支持德尔菲、Borland C Builder、Visual C/C++、Visual Basic(本机)、Virtual Pascal和XCode编译器。

同时,VMProtect有一个内置的反汇编程序,可以与Windows和Mac OS X可执行文件一起使用,并且还可以链接编译器创建的MAP文件,以快速选择要保护的代码片段。

为了轻松实现应用程序保护任务的自动化,VMProtect实现了内置脚本语言。VMProtect完全支持Windows系列的32/64位操作系统(从Windows 2000开始)和Mac OSX(从版本10.6开始)。重要的是,无论目标平台如何,VMProtect都支持所有范围的可执行文件,即Windows版本可以处理Mac OS X版本的文件,反之亦然。

VMProtect最新版下载(qun:766135708)icon-default.png?t=N4P3https://www.evget.com/product/1859/download

VMProtect 是保护应用程序代码免遭分析和破解的可靠工具,但只有在正确构建应用程序内保护机制并且没有可能破坏整个保护的典型错误的情况下才能最有效地使用。

序列号生成器

有什么用?

除了 VMProtect,其他软件也可以生成序列号。这是自动发送序列号所必需的。客户购买产品,电子商务代理向供应商网站发送 HTTP 查询,生成器在服务器上运行并根据客户数据生成序列号。序列号被发送给客户和供应商。然后,供应商使用导入许可证对话框手动将序列号添加到 VMProtect。

怎么运行

VMProtect 的许可系统基于非对称算法,这就是为什么需要秘密产品密钥来生成序列号的原因。您可以在项目属性窗口中导出此密钥,并以任何合适的方式将其传递给生成器。

电子商务代理使用 HTTP 查询调用生成器。可以直接调用 PHP 生成器,基于 DLL 的生成器 - 间接调用,但原理是相同的:

  • 从电子商务代理接收用户数据
  • 添加供应商指定的所有必需信息
  • 生成序列号
  • 使用其中一种算法对其进行加密
  • 将结果发送给电商代理

有现成的序列号产生器么?

许可系统带有三个随时可用的序列号生成器作为 DLL,用于 .Net 平台和PHP。

是否可以自己创建?

是的你可以。序列号的格式在这里,序列号的加密算法在这里描述。

安全吗?

一般来说,可以,但是,您应循以下建议:

  • 使用 HTTPS——如果您的电子商务提供商可以发送 HTTPS 查询,并且您的网络托管提供商可以回答此类请求——您应该更喜欢这种变体而不是典型的 HTTP,因为在这种情况下,所有数据都以加密形式传输,生成的序列无法截取号码。
  • “隐藏”你的发电机——确保没有人可以偶尔打开发电机。www.site.com/keygen.php 地址是个坏主意。虽然 www.site.com/abc123.php 要好得多。确保您没有放置任何指向密钥生成器的外部链接,它没有列在网站目录中,也没有将它放入任何服务文件(如 robot.txt)中。对发电机的位置了解得越少越好。或者,您甚至可以将生成器放在另一个网站上。
  • 确保调用生成器的是电子商务代理——处理来自代理的查询的程序应该检查调用者的 IP 地址。电子商务提供商通常会发布用于查询序列号生成器的 IP 范围。在您的代理处找到该列表并在程序中添加支票。如果发送查询的 IP 地址超出指定的 IP 范围,则不要生成可理解的错误消息。要么不返回任何内容,要么生成一个简单的 404。不要提供任何有关查询失败原因的线索。
  • 检查输入参数——电子商务代理控制面板中的产品设置通常允许您指定代理为接收许可证而应进行的查询字符串。例如,您想要接收用户名、电子邮件地址、购买日期和订单 ID。因此,请确保所有这些参数都已传递并且所有参数都具有正确的格式。不要对错误的查询做出任何响应。每当对生成器进行错误查询时,向您自己的电子邮件发送消息。这应该有助于调查问题。
  • 添加“密码”指定电子商务代理发送的查询中的附加参数,即密码。它应该有一个不明显的名称和值。从接收方检查此参数。如果值错误或未指定参数 – 不生成序列号。

序号生成器

  • Windows版本
  • Net版本
  • UNIX 版本
  • 序列号格式
  • 序列号加密算法

Windows 密钥生成器

Windows 密钥生成器是用于 x86 和 x64 平台的 DLL 文件、一个 C 语言头文件和一个 MSVC 兼容的库文件。因此,库既可以静态链接也可以动态加载。

生成器的所有文件都位于Keygen\DLL文件夹中。生成序列号的测试应用程序也在那里。

生成器 API

生成器仅导出两个函数:第一个函数生成一个序列号,而第二个函数释放第一个函数分配的内存。让我们从第一个也是主要的开始:

VMProtectErrors __stdcall VMProtectGenerateSerialNumber (
VMProtectProductInfo * pProductInfo,
VMProtectSerialNumberInfo * pSerialInfo,
char ** pSerialNumber
);

第一个参数是指向VMProtectProductInfo结构的指针,其内容已上传到 VMProtect(请参阅导出产品参数)。该结构包含产品私钥、使用的算法和产品的标识符。有关填充此结构的更多详细信息如下。

第二个参数是指向VMProtectSerialNumberInfo结构的指针,其内容被移动到生成的序列号中。该结构包含序列号的所有字段和定义应将哪些字段写入序列号的位掩码。

struct VMProtectSerialNumberInfo
{
        INT              flags;
        wchar_t *        pUserName;
        wchar_t *        pEMail;
        DWORD            dwExpDate;
        DWORD            dwMaxBuildDate;
        BYTE             nRunningTimeLimit;
        char *           pHardwareID;
        size_t           nUserDataLength;
        BYTE *           pUserData;
}; 

flags字段包VMProtectSerialNumberFlags中的位标志,该集合在结构之前进行了描述:

  • HAS_USER_NAME – 将pUserName变量中的用户名放入序列号中。
  • HAS_EMAIL – 将pEMail变量中的电子邮件放入序列号中。
  • HAS_EXP_DATE – 序列号将在dwExpDate变量中指定的日期之后过期。
  • HAS_MAX_BUILD_DATE – 序列号仅适用于在dwMaxBuildDate变量中指定的日期之前构建的产品版本 。
  • HAS_TIME_LIMIT – 程序在nRunningTimeLimit变量指定的时间到期后停止工作(时间以分钟为单位指定,不应超过 255)。
  • HAS_HARDWARE_ID – 该程序仅适用于具pHardwar变量中指定的 ID 的硬件。
  • HAS_USER_DATA – 将nUserDataLength长度的自定义用户数据放在pUserData的地址到序列号。

第三个参数是指向指针的指针。生成的序列号的地址写在那里。生成序列号后,应该复制它,地址必须传递给生成器的第二个 API 函数,该函数将释放序列号占用的内存。

void __stdcall VMProtectFreeSerialNumberMemory ( char * pSerialNumber);

VMProtectGenerateSerialNumber函数返回一个VMProtectErrors值,如果成功生成序列号,则该值包含 0,或者包含一个错误代码可能的错误代码是:

  • ALL_RIGHT – 没有错误,序列号已生成。
  • UNSUPPORTED_ALGORITHM – 在函数的第一个参数中传递了不正确的密钥加密算法。
  • UNSUPPORTED_NUMBER_OF_BITS – 在函数的第一个参数中传递了不正确的位数。
  • USER_NAME_IS_TOO_LONG – UTF-8 编码的用户名长度超过 255 字节。
  • EMAIL_IS_TOO_LONG – UTF-8 编码的用户电子邮件的长度超过 255 字节。
  • USER_DATA_IS_TOO_LONG – 用户数据的长度超过 255 字节。
  • HWID_HAS_BAD_SIZE – 硬件标识符的大小不正确。
  • PRODUCT_CODE_HAS_BAD_SIZE – 在函数的第一个参数中传递的产品标识符大小不正确。
  • SERIAL_NUMBER_TOO_LONG – 序列号太长,无法满足算法中指定的位数。
  • BAD_PRODUCT_INFO – 函数的第一个参数不正确或为 NULL。
  • BAD_SERIAL_NUMBER_INFO – 函数的第二个参数不正确或为 NULL。
  • BAD_SERIAL_NUMBER_CONTAINER – 该函数的第三个参数未指向要写入序列号地址的内存。
  • NOT_EMPTY_SERIAL_NUMBER_CONTAINER – 函数的第三个参数不指向空内存单元,该单元必须为 NULL。
  • BAD_PRIVATE_EXPONENT – 函数的第一个参数包含不正确的私有指数值。
  • BAD_MODULUS – 函数的第一个参数包含不正确的模数值。

错误可以分为两类:由不正确的参数或第一个参数的不正确值引起的错误,以及其他所有错误。第一类错误很少见,它们表示结构配置不正确。您应该重新上传产品信息并检查结构是否填写正确。可以在下面找到正确填充结构的示例。

第二类错误是由于尝试向键中放入超过其大小所能容纳的更多数据而引起的。在这种情况下,我们建议向电子商务提供商发送一条消息,其中包含“密钥将在 24 小时内发送”之类的文本,而不是实际的序列号,并将所有必需的信息发送到您自己的电子邮箱。在这种情况下,密钥是在 VMProtect 中手动生成的,一些数据被截断以适应最大密钥大小的所有关键信息。

使用示例

下面是调用上述函数并生成序列号的代码示例。注意最开始的代码块。在您将其替换为从 VMProtect 为您的产品导出的示例之前,该示例将不起作用:

//
// !!! this block should be generated by VMProtect !!! ///
//
VMProtectAlgorithms g_Algorithm = ALGORITHM_RSA;
size_t g_nBits = 0;
byte g_vModulus[1];
byte g_vPrivate[1];
byte g_vProductCode[1];
//
//
int _tmain(int argc, _TCHAR* argv[])
{
VMProtectProductInfo pi;
pi.algorithm = g_Algorithm;
pi.nBits = g_nBits;
pi.nModulusSize = sizeof(g_vModulus);
pi.pModulus = g_vModulus;
pi.nPrivateSize = sizeof(g_vPrivate);
pi.pPrivate = g_vPrivate;
pi.nProductCodeSize = sizeof(g_vProductCode);
pi.pProductCode = g_vProductCode;

VMProtectSerialNumberInfo si = {0};
si.flags = HAS_USER_NAME | HAS_EMAIL;
si.pUserName = L"John Doe";
si.pEMail = L"john@doe.com";
char * pBuf = NULL;
VMProtectErrors res = VMProtectGenerateSerialNumber(&pi, &si, &pBuf);
if (res == ALL_RIGHT)
{
printf("Serial number:\n%s\n", pBuf);
VMProtectFreeSerialNumberMemory(pBuf);
}
else
{
printf("Error: %d\n", res);
}
return 0;

这是来自Keygen\DLL\Example的 Microsoft Visual Studio 示例项目。下面是代码中最有趣的部分以及我们的评论。

main函数的第一行使用从 VMProtect 导出的数据填充VMProtectProductInfo结构。此代码是典型的,不应更改以避免错误。然后我们创建VMProtectSerialNumberInfo结构并将用户名和电子邮件的位组合插入标志字段。在下一行中,我们将用户名和密码放入结构中的相应字段。请注意,值在 UNICODE 编码中被接受。密钥生成器会将它们转换为 UTF-8。

然后,我们初始化一个指针变量,用于存储生成的密钥的地址,并调用VMProtectGenerateSerialNumber,然后分析返回码。如果没有错误,生成的密钥将输出到控制台,并调用免费序列号记忆功能。

VMprotectSerialNumberInfo 结构的其余字段

结构的某些字段可能需要一些额外的解释。例如,dwExpDate和dwMaxBuildDate字段包含特定格式的日期:0xYYYYMMDD,即年存储在高位字中,月和日分别存储在低位字的高低字节中。为了产生这样的数字,使用了以下宏:MAKEDATE(y, m, d)。您可以这样称呼它:MAKEDATE(2010, 05, 12)。

pHardwareID字段应包含指向许可 SDK的VMProtectGetCurrentHWID方法返回的字符串的指针。

.Net 秘钥生成器

.Net密钥生成器 是包含生成序列号所需的所有内容的构建。源代码在Keygen\Net中作为两个项目:KeyGen(密钥生成器本身)和 Usage(密钥生成器的使用示例)。

密钥生成器在源代码中提供,以便在给定版本的 .Net Framework 下快速构建,但是我们强烈建议不要对代码应用任何更改。在 VMProtect 的未来版本中,可能会向生成器添加一些新的可能性,这可能会导致重复修改代码。此外,这可能会导致非常难以定位的错误。如果您在生成器的原始代码中发现错误或想提出改进建议,请联系支持团队。

使用生成器
以Usage项目中的代码为基础,然后将指向 VMProtect.KeyGen.dll 构建的链接添加到您的项目中。之后,您将能够在您的应用程序中生成序列号。为了正常运行,生成器必须“知道”您为哪个产品生成序列号。为此,在 VMProtect 中打开“Project | 导出密钥对”对话框并选择“KeyGen.Net 的参数”选项。下面的文本区域将包含文本信息,您应该将其作为字符串常量复制并粘贴到您的应用程序中。

下面是调用生成器的示例代码:

try
{
string data = @""; // put the exported data here
Generator g = new Generator(data);
g.UserName = "John Doe";
g.EMail = "john@doe.com";
g.ExpirationDate = DateTime.Now.AddMonths(1);
g.MaxBuildDate = DateTime.Now.AddYears(1);
g.RunningTimeLimit = 15;
g.HardwareID = "AQIDBAgHBgU=";
g.UserData = new byte[] { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
string serial = g.Generate();
Console.WriteLine("Serial number:\n{0}\n", serial);
}
catch (Exception ex)
{
Console.WriteLine("Error: {0}", ex);
}

您从 VMProtect 复制的字符串应该放在作为参数传递给序列号类构造函数的数据变量中。如果在解析产品数据时出现任何问题,构造函数将抛出包含问题描述的异常。如果构造函数成功完成其工作,则生成器已准备好生成序列号。

序列号可以包含使用生成器属性指定的各种信息。上面的示例显示了如何填写序列号的所有字段。某些领域有限制。例如,用户名和电子邮件不能接受超过 255 个字符的 UTF-8 编码字符串。如果提供的数据不正确,属性会抛出包含问题描述的异常。

生成器设置完成后,将调用Generate()方法。此方法生成一个序列号。在此步骤中,将序列号的所有数据合并,计算校验和并加密数据。如果数据量超过允许的长度,该方法将抛出异常。

如果需要生成多个序列号,可以连续多次使用生成器类,而不需要从头开始创建。要清除生成器的任何给定属性,只需为其分配一个空值即可

UNIX 密钥生成器

UNIX 版本的密钥生成器是一个 PHP 文件,其中包含生成序列号所需的所有信息。该文件位于Keygen\PHP中。下面我们描述使用这种生成器的要点。

配置生成器

在 PHP 文件的开头,设置代码位于:

//
// The following lines should be generated by VMProtect License Manager
$exported_algorithm = "RSA";
$exported_bits = 2048;
$exported_private = "PJvj4kEpoQMIpYK+9wEt......xKeiSZgzdiln8Q==";
$exported_modulus = "rOlny/3QgZb/VmGr3CmY......I6ESAUmtQ+RBqQ==";
$exported_product_code = "oLQdGUn8kVk=";
//

此代码由 VMProtect 自动生成(请参阅导出产品参数)并且对于每个特定产品都是唯一的。准确复制它至关重要,否则生成器将无法正常工作。

密钥的内容

生成器指定一个序列号的内容。这些内容在一个数组中指定,下面列出了密钥的所有可能参数。然而,在实际应用中,其中一些可能会被省略:

$params = array(
user_name => "John Doe", // UTF-8!
email => "john@doe.com",
hwid => "vHGMdMRvGCPjWcCQ", // Exactly as returned by VMProtectGetCurrentHWID
expire_date => array(year => 2009, month => 10, day => 1),
maxbuild_date => array(year => 2009, month => 10, day => 1),
time_limit => 10,
user_data => base64_decode("CGCvRvMWcPHGdMjQ"), // string of bytes
);

成功的密钥生成处理函数

您可以在下面看到成功生成序列号时调用的最简单的函数。发送给它的唯一参数是序列号字符串。该函数必须将序列号传递给调用者(电子商务代理),通常使用echo命令。为了方便起见,该字符串被初步拆分为每个 75 个符号的子字符串。此外,此功能可以通过电子邮件将生成的序列号发送给开发人员或将其添加到数据库中。

function OnSerialGenerated($serial)
{
$serial = wordwrap($serial, 75, "\n", true);
echo $serial;
}

密钥生成器错误处理函数

需要我们注意的代码的最后一部分是出现问题时调用的函数。此函数接收带有错误消息的字符串,完成后调用die()函数。处理程序函数必须做两件事:代替密钥,向电子商务代理返回一条消息,说明将手动发送密钥。并向开发人员发送有关错误的详尽信息以修复它并手动生成密钥。

function OnSerialGenerationFailed($details)
{
echo "You will receive serial number in the next 24 hours"; // message to the customer
// mail("support@vendor.com", "Houston, we have a problem", $details); // message to vendor
}

有几种可能的错误原因:算法参数不正确,密钥参数不正确,用户名或电子邮件太长,或者序列号太长不适合算法中指定的位数. 这就是为什么OnSerialGenerationFailed函数必须向开发人员发送有关该问题的详细信息,以便他可以生成序列号并将其发送给客户。

其他需要考虑的事情

示例包含密钥生成器的简化版本。它没有考虑开发网络生成器的建议。它不检查调用方的 IP 地址,也不分析输入参数。在开发自己的生成器时请注意这一点。

用户名和电子邮件必须作为 UTF-8 字符串传递。确保您的电子商务代理以 UTF-8 编码发送这些数据,如果不是这样,则对信息进行转码。错误的编码不会导致生成错误的序列号,但这样的序列号显示的注册名可能与真实用户名不同,所以他或她可能会在“关于”窗口中看到它时感到惊讶。应用

非对称加密是一个复杂的数学过程。如果使用纯PHP实现,没有任何第三方库,生成序列号可能需要几十秒。生成器在可用时使用gmp_powm、bi_powmod、bcpowod函数。如果在您的主机上生成序列号的时间太长,我们建议要求主机提供商启用这些功能。例如,gmp_powm函数的运行速度是bcpowmod的十倍。

以上便是关于几个秘钥生成器的分享,如果您有任何疑问欢迎私聊我~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/642571.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VMware虚拟机和主机传输文件

原文链接 虚拟机为Linux系统 使用vm-tools即可。 卸载旧工具: vmware-uninstall-tools.pl安装新工具: apt-get install open-vm-tools-desktop重启系统: reboot此时可以使用CtrlC、CtrlV的方式在主机和Linux虚拟机之间传输文件。 虚拟…

【网络原理】TCP协议如何实现可靠传输(确认应答机制)

🥊作者:一只爱打拳的程序猿,Java领域新星创作者,CSDN、阿里云社区优质创作者。 🤼专栏收录于:计算机网络原理 本篇主要讲解:TCP协议段格式,TCP的序列号,SYN、ACK标志位&a…

操作系统(王道)

1.1_1_操作系统概念 裸机(硬件只听得懂二进制指令)——>操作系统(属于软件,提供良好交互界面)——>应用软件——>用户使用 操作系统是指控制和管理整个计算机系统的硬件和软件资源,并合理地组织…

Python技术自学的方式

Python是一种高级编程语言,被广泛用于软件开发、数据分析、人工智能和科学计算等领域。它于1991年由Guido van Rossum创建,并且其简洁、易读的语法以及丰富的标准库使得它成为了初学者和专业开发人员的首选语言之一。 一、Python技术介绍 学习Python技术…

css响应式布局

这里写自定义目录标题 1.效果展示2.使用grid布局3.使用flex布局 1.效果展示 2.使用grid布局 <!DOCTYPE html> <html><head><meta name"viewport" content"widthdevice-width, initial-scale1.0, maximum-scale1.0, user-scalableno"…

ASEMI代理安森美MOS管FQL40N50参数,FQL40N50描述

编辑-Z FQL40N50参数描述&#xff1a; 型号&#xff1a;FQL40N50 漏源电压VDSS&#xff1a;500V 漏极电流ID&#xff1a;40A 漏极电流-脉冲IDM&#xff1a;160A 栅极-源极电压VGSS&#xff1a;30V 功耗PD&#xff1a;460W 操作和储存温度范围TJ, TSTG&#xff1a;-55 t…

Rust in Action笔记 第六章 内存

Option<T>类型在Rust中使用了空指针优化&#xff08;null pointer optimization&#xff09;来保证该类型在编译后的二进制文件中占用0个字节。None变量是通过一个空指针null pointer来表示&#xff1b;内存地址、指针、引用的区别&#xff0c;内存地址是指在内存中的一个…

SpringBatch从入门到实战(三):多步骤控制

一&#xff1a;if else案例 案例&#xff1a;如果开始步骤成功了就执行成功步骤&#xff0c;否则执行失败步骤。 // 伪代码 String exitStatus helloWorldJob(); if("FAILED".equals(exitStatus)){failStep(); }else{successStep(); }Configuration public class …

01 面向对象方法的概念

面向对象方法的概念 1、什么是面向对象? 面向对象不仅仅是一种程序开发方法 使用面向对象程序设计语言 使用对象、类、继承、封装、消息等基本概念进 行编程 面向对象是一种软件方法学 如何看待软件系统与现实世界的关系 以什么观点进行求解 如何进行系统构造 2、面向对象方…

chatgpt赋能python:Python导入自己写的包详解

Python导入自己写的包详解 在Python中&#xff0c;我们可以将代码封装成包来重复利用&#xff0c;也可以将自己写的包分享给其他人使用。但是&#xff0c;在使用自己写的包时&#xff0c;如何进行导入呢&#xff1f; 什么是包&#xff1f; 在Python中&#xff0c;包是一个有…

计算机网络(更新中)

本文是个人笔记&#xff0c;都是概念&#xff0c;没基础不建议看。 绪论 计算机网络的定义 最简单的定义&#xff1a;计算机网络是一些互相连接的、自治的计算机的集合因特网&#xff08;Internet&#xff09;是“网络的网络” 计算机网络的组成&#xff08;物理组成&#x…

git从http切换到ssh

git从http切换到ssh 之前项目代码git clone的http的git地址&#xff0c;后来禁用了http协议&#xff0c;只能用ssh协议。 1. 生成ssh公钥 进入Git Bash Here, 执行以下命令 ssh-keygen -m PEM -t rsa -b 4096 -C "your.emailemail.com"一直Enter直到完成。 2. 添加…

个人对几个IDE的看法

&#xff08;说明&#xff1a;本文仅表达个人看法&#xff0c;实际上文中的几个IDE功能不同&#xff0c;不能互相取代。截图上的程序均已发布&#xff09; 个人认为一款IDE在功能完整的前提下&#xff0c;应当做到操作简便。另外&#xff0c;对缩放的兼容性也会影响观感。以下…

微服务springcloud 01 sts环境,maven管理,和springcloud简介,通用模块commons

01.使用的环境是sts和maven。 02.介绍springcloud springcloud是一个大的微服务框架。 03.Spring cloud对比Dubbo Dubbo Dubbo只是一个远程调用(RPC)框架;默认基于长连接,支持多种序列化格式 Spring Cloud 框架集&#xff0c;提供了一整套微服务解决方案(全家桶);基于http调用…

【数据挖掘实战】——科大讯飞:跨境广告ROI预测

&#x1f935;‍♂️ 个人主页&#xff1a;Lingxw_w的个人主页 ✍&#x1f3fb;作者简介&#xff1a;计算机科学与技术研究生在读 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4a…

云服务器上使用Docker Compose创建Redis三主三从集群

一、环境 云服务器Ubuntu20.4Dokcer 24.0.2 二、步骤 目录结构是这样&#xff1a; 绿色的目录是用来存储容器中的文件&#xff0c;不需要我们手动创建&#xff0c;将路径配置在配置文件中即可。褐色的目录和文件需要自己手动创建。 我们一共创建7个容器&#xff1a; redis…

RabbitMq消息堆积问题及惰性队列

消息堆积问题 当生产者发送消息的速度超过了消费者处理的速度&#xff0c;就会导致队列的消息堆积&#xff0c;知道队列存储消息达到上限。最早接受的消息&#xff0c;可能就会成为死信&#xff0c;会被丢弃&#xff0c;这就是消息堆积问题。 解决消费对接问题 1.增加更多的消…

Hive执行计划之只有map阶段SQL性能分析和解读

文章目录 概述1.不带函数操作的select-from-where型简单SQL1.1执行示例1.2 运行逻辑分析1.3 伪代码解释 2.带普通函数和运行操作符的普通型SQL执行计划解读2.1 执行计划解读2.2 伪代码解释逻辑 概述 可能所有的SQLboy刚接触SQL语句的时候都是select xxx from xxx where xxx。在…

如何分析问题、找到性能瓶颈、掌握性能调优?一文讲懂性能测试

背景 当下云计算、大数据盛行的背景下&#xff0c;大并发和大吞吐量的需求已经是摆在企业面前的问题了&#xff0c;其中网络的性能要求尤为关键&#xff0c;除了软件本身需要考虑到性能方面的要求&#xff0c;一些硬件上面的优化也是必不可少的。 作为一名测试工作者&#xf…

Ubuntu18.04 离线安装gcc,g++,make依赖包

1. 离线安装背景 因为项目现场的服务器无法连接互联网&#xff0c;只有内网环境&#xff0c;但是需要安装redis和nginx&#xff0c;所以需要安装gcc,g,make等依赖包。 2. 如何获取依赖包 需要准备一台可以连接互联网的电脑&#xff08;如&#xff1a;个人电脑上的虚拟机安装一…