分类 默认分类 下的文章

RabbitMQ 安装使用极简指导(Windows/macOS/Linux通用)

核心逻辑:先装Erlang(RabbitMQ依赖)→ 装RabbitMQ → 启动服务 → 可视化管理 → 简单收发消息。

一、安装准备(必做)

1. 安装Erlang

  • 原因:RabbitMQ基于Erlang开发,必须先装且版本匹配(官网有版本对照表,新手直接装最新版即可)。
  • 下载:Erlang官网,按系统选安装包(Windows双击安装,mac用brew install erlang,Linux用apt/yum install erlang)。
  • 验证:终端输入 erl -v,显示版本号即成功。

2. 安装RabbitMQ

  • 下载:RabbitMQ官网,选对应系统安装包(Windows/mac/Linux均有一键安装包)。
  • 关键步骤:

    • Windows:安装后默认路径 C:\Program Files\RabbitMQ Server\,需配置环境变量(将sbin目录加入PATH)。
    • macOS:brew install rabbitmq,安装后路径 /usr/local/Cellar/rabbitmq/
    • Linux(Ubuntu):sudo apt-get install rabbitmq-server,自动启动服务。

二、启动与基础配置

1. 启动RabbitMQ服务

  • Windows:以管理员身份打开终端,输入 rabbitmq-server start(启动),rabbitmq-server stop(停止)。
  • macOS/Linux:sudo rabbitmq-server start(启动),sudo rabbitmqctl stop(停止)。
  • 验证:终端输入 rabbitmqctl status,无报错即服务正常。

2. 启用管理插件(可视化界面,必开)

  • 终端输入 rabbitmq-plugins enable rabbitmq_management,启用后访问 http://localhost:15672
  • 默认账号密码:guest/guest(仅本地访问可用,远程访问需新建账号)。

3. 新建远程访问账号(可选,跨设备连接用)

  • 终端执行3条命令:

    1. rabbitmqctl add_user 用户名 密码(创建账号)
    2. rabbitmqctl set_permissions -p / 用户名 ".*" ".*" ".*"(授予所有权限)
    3. rabbitmqctl set_user_tags 用户名 administrator(设为管理员角色)

三、快速使用(以Python为例,实现消息收发)

1. 安装Python客户端库

  • 终端输入 pip install pika(RabbitMQ的Python驱动)。

2. 步骤1:创建生产者(往队列发消息)

import pika

# 连接RabbitMQ服务(本地默认地址+端口,远程需改host为RabbitMQ服务器IP)
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

# 声明队列(不存在则创建, durable=True 设为持久化,防止服务重启消息丢失)
channel.queue_declare(queue='test_queue', durable=True)

# 发送消息(body为消息内容,需转字节)
channel.basic_publish(
    exchange='',
    routing_key='test_queue',  # 队列名,与声明一致
    body='这是一条测试消息!',
    properties=pika.BasicProperties(delivery_mode=2)  # 消息持久化
)

print("消息发送成功!")
connection.close()  # 关闭连接

3. 步骤2:创建消费者(订阅队列,接收推送消息)

import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='test_queue', durable=True)  # 与生产者队列名一致

# 消息回调函数(RabbitMQ主动推送消息时触发)
def callback(ch, method, properties, body):
    print(f"收到推送消息:{body.decode('utf-8')}")
    ch.basic_ack(delivery_tag=method.delivery_tag)  # 手动确认消息已处理

# 注册订阅(auto_ack=False 关闭自动确认,需手动ack)
channel.basic_consume(queue='test_queue', on_message_callback=callback, auto_ack=False)
# 设置预取数(每次只推1条,处理完再推下一条,防止过载)
channel.basic_qos(prefetch_count=1)

print("等待接收消息...(按Ctrl+C退出)")
channel.start_consuming()  # 持续监听队列,接收推送

4. 测试流程

  1. 启动RabbitMQ服务(rabbitmq-server start)。
  2. 运行消费者程序(开始监听队列)。
  3. 运行生产者程序(发送消息)。
  4. 消费者终端会立即收到RabbitMQ主动推送的消息。

需要我帮你排查 安装失败问题,或生成 Java/Go语言的收发消息代码,亦或是配置 RabbitMQ集群(高可用) 吗?

MySQL 计算经纬度半径内最近商家,核心用 Haversine 公式(球面距离计算),结合索引优化提升查询效率,以下是完整实现方案:

一、核心公式(Haversine)

计算两点(用户经纬度 vs 商家经纬度)的球面距离(单位:公里):

6371 * 2 * ASIN(
    SQRT(
        POWER(SIN((用户纬度 - 商家纬度) * PI() / 180 / 2), 2) +
        COS(用户纬度 * PI() / 180) * COS(商家纬度 * PI() / 180) *
        POWER(SIN((用户经度 - 商家经度) * PI() / 180 / 2), 2)
    )
) AS distance
  • 6371 是地球平均半径(公里),需米则换为 6371000。
  • 经纬度需先转弧度( * PI() / 180 ),避免计算误差。

二、完整查询示例(返回半径 5 公里内最近商家)

  1. 表结构假设(商家表  merchant )

    CREATE TABLE merchant (
     id INT PRIMARY KEY AUTO_INCREMENT,
     name VARCHAR(50) COMMENT '商家名称',
     lat DECIMAL(10,6) NOT NULL COMMENT '纬度(如:39.9042)',
     lng DECIMAL(10,6) NOT NULL COMMENT '经度(如:116.4074)',
     address VARCHAR(200) COMMENT '地址'
    );
  2. 查询 SQL(用户经纬度:39.9042, 116.4074)

    SELECT 
     id, name, lat, lng, address,
     -- 计算距离(公里)
     6371 * 2 * ASIN(
         SQRT(
             POWER(SIN((39.9042 - lat) * PI() / 180 / 2), 2) +
             COS(39.9042 * PI() / 180) * COS(lat * PI() / 180) *
             POWER(SIN((116.4074 - lng) * PI() / 180 / 2), 2)
         )
     ) AS distance
    FROM merchant
    -- 筛选 5 公里内(先粗筛,提升效率)
    WHERE 
     lat BETWEEN 39.9042 - 5 / 111.12 AND 39.9042 + 5 / 111.12  -- 纬度每度约 111.12 公里
     AND lng BETWEEN 116.4074 - 5 / (111.12 * COS(39.9042 * PI() / 180)) AND 116.4074 + 5 / (111.12 * COS(39.9042 * PI() / 180))
    -- 按距离排序(最近在前)
    ORDER BY distance ASC
    -- 限制返回数量
    LIMIT 10;

三、性能优化(大数据量必备)

  1. 添加空间索引(MySQL 5.7+ 支持)

    -- 方式 1:创建经纬度联合索引(基础优化)
    CREATE INDEX idx_merchant_lat_lng ON merchant(lat, lng);
    
    -- 方式 2:创建空间索引(高效,支持 GIS 函数)
    ALTER TABLE merchant ADD COLUMN location POINT NOT NULL COMMENT '经纬度空间点' AFTER lng;
    -- 更新空间点数据(lat 纬度,lng 经度,注意顺序)
    UPDATE merchant SET location = POINT(lng, lat);
    -- 创建空间索引
    CREATE SPATIAL INDEX idx_merchant_location ON merchant(location);
  2. 空间索引查询(更高效)

    SELECT 
     id, name, lat, lng, address,
     -- ST_Distance_Sphere 直接计算球面距离(米),MySQL 8.0+ 支持
     ST_Distance_Sphere(POINT(116.4074, 39.9042), location) / 1000 AS distance  -- 转公里
    FROM merchant
    -- 筛选 5 公里内(空间范围查询)
    WHERE ST_DWithin(
     location,
     POINT(116.4074, 39.9042),
     5000  -- 半径(米)
    )
    ORDER BY distance ASC
    LIMIT 10;

四、关键注意事项

1. 经纬度格式:确保存储为  DECIMAL(10,6) (保留 6 位小数,精度约 10 厘米),避免用  FLOAT (精度丢失)。
2. 粗筛逻辑:未用空间索引时,先通过  BETWEEN  筛选大致经纬度范围,减少计算量。
3. 版本支持: ST_Distance_Sphere  是 MySQL 8.0+ 函数,5.7 及以下用 Haversine 公式。

五、应用层整合(如 PHP)

将用户经纬度(前端获取)传入 SQL,示例(Laravel):

$userLat = 39.9042; // 用户纬度(前端定位获取)
$userLng = 116.4074; // 用户经度
$radius = 5; // 搜索半径(公里)

$merchants = DB::table('merchant')
    ->selectRaw("
        id, name, lat, lng, address,
        6371 * 2 * ASIN(
            SQRT(
                POWER(SIN(($userLat - lat) * PI() / 180 / 2), 2) +
                COS($userLat * PI() / 180) * COS(lat * PI() / 180) *
                POWER(SIN(($userLng - lng) * PI() / 180 / 2), 2)
            )
        ) AS distance
    ")
    ->whereRaw("
        lat BETWEEN ? - ? / 111.12 AND ? + ? / 111.12
        AND lng BETWEEN ? - ? / (111.12 * COS(? * PI() / 180)) AND ? + ? / (111.12 * COS(? * PI() / 180))
    ", [$userLat, $radius, $userLat, $radius, $userLng, $radius, $userLat, $userLng, $radius, $userLat])
    ->orderBy('distance')
    ->limit(10)
    ->get();
 

“数据库对转义字符处理不当”,简单说就是:你按规则对用户输入的特殊字符(如单引号、斜杠)做了转义,但数据库在解析这些转义字符时,没有按预期处理,导致原本的转义失效,让恶意输入重新具备攻击能力。这本质是“转义规则不匹配”或“数据库配置异常”引发的漏洞,下面用具体场景讲清楚:

一、先理解“转义”的核心目的(防SQL注入的基础)

SQL注入的核心是“用户输入的特殊字符打乱SQL语句结构”。比如用户输入 ' OR '1'='1,如果直接拼接到SQL中:

SELECT * FROM user WHERE username = '' OR '1'='1'

原本的“查询指定用户”会变成“查询所有用户”(因为 '1'='1 恒为真)。

“转义”就是把这些特殊字符(如单引号 ')变成“无特殊意义的普通字符”。比如标准转义会把 ' 变成 ''(两个单引号),让SQL变成:

SELECT * FROM user WHERE username = ''' OR ''1''=''1'

此时数据库会把 '' OR ''1''=''1 当作“一个完整的用户名”来查询,而非恶意SQL片段——这是正常转义的效果。

二、“处理不当”的3种典型场景(用例子看懂)

当数据库的“转义解析规则”和你代码中的“转义规则”不匹配时,转义就会失效,具体有3种常见情况:

1. 转义字符被数据库“二次解析”(最常见)

你代码中对单引号 ' 做了一次转义(变成 ''),但数据库在解析时,额外多做了一次处理——把 '' 又还原成了 ',导致恶意输入“复活”。

示例

  • 你代码转义后:用户输入 ' OR '1'='1 → 转义为 '' OR ''1''=''1
  • 数据库处理不当:把 '' 解析成 '(错误地认为“两个单引号是输入错误,应该合并成一个”);
  • 最终执行的SQL:SELECT * FROM user WHERE username = '' OR '1'='1'(注入成功)。

这种情况常出现在:数据库配置了“自动去除重复转义符”,或使用了不兼容的SQL驱动(如旧版MySQL驱动)。

2. 数据库编码与转义编码不匹配

你按 UTF-8 编码对特殊字符转义,但数据库实际用的是 GBK 编码——两种编码对“转义字符的二进制存储”不同,导致数据库无法识别转义,把转义后的字符当作正常内容解析。

示例

  • UTF-8 中,单引号 ' 转义后是 ''(两个字节 0x27 0x27);
  • 数据库用 GBK 编码解析时,可能把 0x27 0x27 误识别为“一个特殊字符”(而非两个普通单引号);
  • 最终SQL结构被打乱,注入漏洞触发。

3. 数据库“关闭了转义功能”(配置异常)

部分数据库(如MySQL)支持通过配置关闭“转义字符解析”(如 sql_mode 中禁用 NO_BACKSLASH_ESCAPES),此时你代码中用反斜杠 \ 做的转义(如 \'),会被数据库当作“普通反斜杠+单引号”处理,完全失去转义效果。

示例

  • 你代码转义后:\' OR \'1\'=\'1(用 \ 转义单引号);
  • 数据库关闭转义功能:把 \' 解析成“\ + '”(而非“一个转义后的单引号”);
  • 最终SQL:SELECT * FROM user WHERE username = '\' OR \'1\'=\'1' → 语法错误或注入成功。

三、为什么“依赖转义防SQL注入不可靠”?

正是因为“数据库对转义的处理可能异常”,再加上不同数据库(MySQL、PostgreSQL、SQL Server)的转义规则本身就有差异(比如MySQL用 ''\',SQL Server只用 ''),导致“纯靠转义防注入”的方案本质上是脆弱的——你永远无法保证代码的转义规则和所有环境的数据库配置100%匹配。

这也是为什么之前强调:必须用Yii2的AR/查询构建器(参数绑定) ——参数绑定的核心是“把用户数据和SQL语句彻底分离”:SQL语句的结构由你控制,用户数据只是“一个待填充的参数”,数据库会直接把它当作“纯值”处理,根本不需要依赖转义,从根源避免了“转义处理不当”的风险。

总结

“数据库对转义字符处理不当”,本质是“代码转义规则”与“数据库解析规则”不匹配,导致转义失效,恶意输入重新具备攻击能力。

而参数绑定(Yii2 AR/查询构建器)的优势在于:不依赖任何转义规则,直接让用户数据“脱离SQL语句结构”,无论数据库如何配置,都不会触发SQL注入——这也是为什么它是防SQL注入的“黄金标准”。

Percona XtraBackup,可以做哪些事情?这是免费工具还是收费工具?
Percona XtraBackup是一款免费的开源工具,专为InnoDB/XtraDB引擎设计,主要用于MySQL、MariaDB和Percona Server数据库的备份与恢复 。它具有以下功能 :

  • 在线热备份:在备份过程中不会阻塞数据库的读写操作,确保业务的连续性,适用于对高可用性要求较高的场景。
  • 增量备份:可以只备份自上次备份以来发生变化的数据,节省存储空间和备份时间,适合数据量较大且变化频繁的数据库。
  • 压缩备份:支持将备份数据进行压缩,减少备份文件占用的磁盘空间和网络传输带宽,便于备份数据的存储和传输。
  • 快速恢复:通过应用事务日志(Redo Log)来保证数据的一致性,能够快速将数据库恢复到指定的时间点,提高了数据恢复的效率。
  • 创建复制副本:可以轻松地创建新的MySQL复制从库,为数据库的复制架构提供了便利。
  • 表级迁移:能够在线将表从一个MySQL服务器移动到另一个服务器,无需停机,方便进行数据库的架构调整和数据迁移。

用这款工具复制从库,数据迁移,它的耗时是多长时间?它不停机迁移备份的原理是什么?

  1. 迁移耗时:无固定值,核心看3个因素
  • 数据量:100GB全量备份+恢复约30分钟-2小时(机械硬盘慢,SSD快);增量备份仅需备份变化数据,耗时可缩短50%-80%。
  • 硬件性能:磁盘IO(SSD比机械硬盘快3-5倍)、CPU算力、网络带宽(跨服务器迁移时,10G网卡比1G网卡快10倍)。
  • 业务负载:备份时主库读写压力大,会轻微拖慢备份速度(但不影响业务),低峰期迁移耗时可减少20%-30%。
  1. 不停机迁移备份原理(大白话拆解)

核心是 “热备份+事务日志追赶”,类似“抄作业不耽误写新作业”:

  • 第一步:启动备份时,先记录当前主库的binlog位置(相当于“作业抄到哪一页”的标记)。
  • 第二步:后台并行复制InnoDB数据文件(.ibd),此时主库仍能正常读写(新写入的数据会记录到Redo Log和binlog)。
  • 第三步:数据文件复制完成后,立即复制备份期间产生的Redo Log(相当于“抄作业时,新写的答案单独记在草稿纸”)。
  • 第四步:备份结束后,通过Redo Log回放(把草稿纸上的新答案补到抄好的作业里),确保备份数据与主库完全一致。
  • 迁移到从库时,先恢复全量备份,再基于之前记录的binlog位置,同步后续新增数据,全程主库无需停机。

主从数据不同步核心解决思路:先定位差异→紧急兜底→修复同步→预防复发,操作分3步,精准高效:

  1. 快速定位差异(5分钟内搞定)
  • 用 pt-table-checksum (Percona工具)扫描主从表数据,生成差异报告(精准到行);
  • 查看从库 show slave status :重点看 Seconds_Behind_Master (延迟)、 Last_Error (同步错误),常见问题如主键冲突、SQL语法不兼容、从库权限不足。
  1. 修复同步(分场景处理)
  • 场景1:小数据差异(单表少量行)
    用 pt-table-sync 工具自动同步差异数据(支持主从双向同步,不影响主库业务),同步后重启从库复制( stop slave; start slave )。
  • 场景2:大数据差异(多表/全库)
    重新搭建从库:主库用 XtraBackup 全量备份→从库恢复备份→基于备份点重新开启binlog同步(避免增量同步遗漏)。
  • 场景3:复制进程中断(Error日志报具体错误)
    先跳过错误(临时应急: set global sql_slave_skip_counter=1; start slave ),再用 pt-table-checksum 校验数据;若频繁报错,需排查主库SQL是否兼容从库(如主库用高版本函数,从库版本低)。
  1. 预防复发(关键步骤)
  • 主从数据库版本保持一致,禁用从库写操作(只读权限);
  • 定期(如每日凌晨)用 pt-table-checksum 做全量校验,设置延迟监控告警(延迟>3秒触发通知);
  • 主库执行DDL/DML语句前,先在测试环境验证从库兼容性(避免因SQL语法问题导致同步中断)。

需要我提供 pt-table-checksum 和 pt-table-sync 的具体执行命令(含参数说明)吗?

pt-table-checksum和pt-table-sync是Percona Toolkit工具包中的工具,由Percona公司开发 。Percona Toolkit是一组高级命令行工具的集合,用于执行各种复杂的MySQL和系统任务。

这两个工具的应用场景较多,主要包括以下几个方面 :

  • 数据迁移前后校验:在数据库进行迁移后,可使用pt-table-checksum检查迁移后的数据与原数据是否一致,确保数据迁移的准确性。
  • 主从复制问题修复:当主从复制出现问题,如网络故障、服务器宕机等导致数据不一致时,可先通过pt-table-checksum检测差异,再利用pt-table-sync进行修复。
  • 误操作后数据修复:如果不小心将从库当成主库进行了数据更新,产生了“脏数据”,或者出现其他误操作导致主从数据不一致的情况,可以使用这两个工具来检查和修复数据。

Percona Toolkit是开源免费的,用户可以自由下载和使用,但其部分高级功能或技术支持可能需要购买Percona公司的商业服务。

Percona Toolkit功能丰富,涵盖数据归档与清理、在线Schema变更、数据一致性管理等多个方面,以下是一些主要功能及高级功能介绍 :

  • 数据归档与清理: pt-archiver 可在不影响在线业务的情况下,安全高效地归档历史数据,如电商订单历史数据归档。
  • 在线Schema变更: pt-online-schema-change 通过原子替换实现零锁表结构变更,解决了传统 ALTER TABLE 操作会导致表级锁的难题,适用于在7×24小时服务的表中添加字段等场景。
  • 数据一致性管理: pt-table-checksum 用于校验主从复制一致性, pt-table-sync 可高效同步表数据,确保主从数据的一致性,常用于金融交易系统主从校验等场景。
  • 性能分析与优化: pt-query-digest 可分析慢查询日志或 SHOW PROCESSLIST 输出,生成性能报告,帮助定位慢查询根源; pt-duplicate-key-checker 能查找重复或冗余的索引, pt-index-usage 可分析日志中索引使用情况,助力索引优化。
  • 配置与监控: pt-config-diff 可对比配置文件和参数, pt-mysql-summary 能对MySQL配置和状态进行汇总,快速生成MySQL实例的健康报告。
  • 连接与锁管理: pt-kill 可Kill掉符合条件的SQL,防止慢查询拖垮DB; pt-deadlock-logger 能提取和记录MySQL死锁信息,用于事务死锁分析。