华为云用户手册

  • 可能原因 ECS实例的网络配置为DHCP(Dynamic Host Configuration Protocol,动态主机设置协议)方式。 以CentOS 7的ECS为例,如果网络配置为DHCP方式,当ECS实例启动时,Linux系统的NetworkManager服务会启动dhclient进程,dhclient进程会向DHCP服务器请求分配IP地址,并获得IP地址租约到期时间。 正常情况下,dhclient进程会定期向DHCP服务器更新租约到期时间,以确保实例IP地址的可用性,如下图: 图2 正常情况 当用户误操作停止了NetworkManager服务,并清理了dhclient进程时,会导致ECS实例无法自动更新IP地址的续租到期时间。当租约到期后,ECS实例的IP地址会被释放,导致网络不通。
  • 解决方案 远程登录ECS实例。 执行以下命令,重启NetworkManager服务,并设置为开启自启动。 systemctl restart NetworkManager systemctl enable NetworkManager 执行以下命令,查看NetworkManager服务状态。 systemctl status NetworkManager 图3 查看NetworkManager服务状态 执行以下命令,查看网络状态。 ip ad 图4 查看网络状态 若出现如图4所示结果,表示ECS实例的网络恢复正常。
  • 问题描述 Linux操作系统的ECS实例内存充足,但是在执行命令或启动服务时,出现错误提示“Cannot allocate memory”。 命令及执行结果如下: root@localhost:~# free -m total used free shared buffers/cached availableMem: 3890 125 3179 2 504 3463Swap: 0 0 0root@localhost:~# uname -a-bash: fork: Cannot allocate memory
  • 附录 常见操作系统的默认网络服务配置,建议不修改,直接采用默认值。 表1 常见操作系统的默认网络服务配置 操作系统 网络服务 是否内置DHCP功能 CentOS 6 Network 否,有单独的dhclient进程 CentOS 7 NetworkManager 否,有单独的dhclient进程 CentOS 8 NetworkManager 是 Ubuntu 16.04 NetworkManager 否,有单独的dhclient进程 Ubuntu 18.04 NetworkManager 否,有单独的dhclient进程 Ubuntu 20.04 NetworkManager 是 Ubuntu 22.04 NetworkManager 是
  • 问题描述 执行chmod -R 777 / 导致CentOS云服务器根目录权限设置成777,系统中的大部分服务以及命令无法使用。此时可通过系统自带的getfacl命令来拷贝和还原系统权限,本节操作介绍误操作导致根目录设置成777权限的补救措施。 对文件或目录设置777权限代表它将对所有用户都是可读、可写和可执行的,根目录设置777权限后存在安全风险。本节操作是临时的补救措施,恢复目录权限后,建议您备份数据,重装操作系统,避免777权限后续带来的安全风险问题。
  • 解决方案 远程登录ECS实例。 执行以下命令,查看ECS实例内核参数kernel.unknown_nmi_panic的值。 sysctl -n kernel.unknown_nmi_panic 如果内核参数的取值为1,说明是由于内核参数配置错误引起的ECS实例异常重启。 图1 排查结果 执行以下命令,查看是否存在内核参数kernel.unknown_nmi_panic相关配置。 vim /etc/sysctl.conf 在/etc/sysctl.conf文件中,排查是否存在kernel.unknown_nmi_panic的相关配置。 如果存在kernel.unknown_nmi_panic=1的配置,将该配置改为kernel.unknown_nmi_panic=0 如果不存在kernel.unknown_nmi_panic=1的配置,增加kernel.unknown_nmi_panic=0 图2 查看/etc/sysctl.conf文件 按“Esc”,输入:wq保存并退出。 执行以下命令,使配置生效。 sysctl –p 图3 配置生效 该修复方案热生效,无需重启ECS。
  • 防火墙添加例外端口 CentOS 6添加防火墙例外端口。 以添加23端口为例,执行以下命令,添加防火墙例外端口:tcp协议23端口。 iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 23 -j ACCEPT 保存新配置。 service iptables save (可选)设置防火墙开机自启动。 chkconfig iptables on 可执行以下命令关闭防火墙开机自启动。 chkconfig iptables off CentOS 6启动防火墙时可能会出现"iptables"no config file"错误 ,原因是未找到配置文件iptables。解决方法如下: 新建一条规则。 iptables -P OUTPUT ACCEPT 保存配置。 service iptables save 再次启动防火墙。 service iptables start 以CentOS 7添加防火墙例外端口及防火墙常用操作。 查看防火墙状态。 systemctl status firewalld 或 firewall-cmd --state 如果防火墙关闭可以执行以下命令开启。 systemctl start firewalld 如果开启命令执行后提示“Failed to start firewalld.service: Unit is masked.”请执行以下命令后再重新执行开启防火墙的命令。systemctl unmask firewalld 重新检查防火墙状态是否打开。 firewall-cmd --state 回显信息: [root@ecs-centos7 ~]# firewall-cmd --staterunning 以添加23端口为例,执行以下命令,添加防火墙例外端口:tcp协议23端口。 firewall-cmd --zone=public --add-port=23/tcp --permanent 回显信息如下说明设置成功: [root@ecs-centos7 ~]# firewall-cmd --zone=public --add-port=23/tcp --permanentsuccess 重新加载策略配置,使新配置生效。 firewall-cmd --reload 可以执行以下命令查看开启的所有端口。 firewall-cmd --list-ports [root@ecs-centos7 ~]# firewall-cmd --list-ports23/tcp (可选)设置防火墙开机自启动。 systemctl enable firewalld.service 查看防火墙设置开机自启是否成功。 systemctl is-enabled firewalld.service;echo $? 回显信息如下说明已设置成功: [root@ecs-centos7 ~]# systemctl is-enabled firewalld.service;echo $?enabled0 可执行以下命令关闭防火墙开机自启动。 systemctl disable firewalld.service
  • 问题描述 Linux操作系统的ECS实例发生异常重启事件,错误提示如下: Kernel panic - not syncing: NMI: Not continuing 同时,内核日志打印如下信息: [645683.754132] Uhhuh. NMI received for unknown reason 20 on CPU 1.[645683.754133] Do you have a strange power saving mode enabled?[645683.754133] Kernel panic - not syncing: NMI: Not continuing
  • 可能原因 如果Linux操作系统ECS实例的内核参数kernel.unknown_nmi_panic配置为1,则ECS会在系统收到NMI中断时主动通过panic系统重启。 通常情况下,内核参数kernel.unknown_nmi_panic配置为1的目的是为了通过触发NMI中断主动通过panic系统进行定位。由于个别型号的CPU会在正常业务流程中产生NMI中断,在这种情况下如果将内核参数kernel.unknown_nmi_panic配置为1,将会导致ECS产生非预期的异常重启事件。
  • 处理方法 建议不要安装来源不明的软件,使用正版软件,推荐使用Windows2012操作系统。 如果是通过外部镜像创建的服务器,请参考《镜像服务用户指南》中“优化Windows私有镜像”章节优化私有镜像。 排查是否是因为CPU占用过高导致的蓝屏,如果是请参考以下操作降低CPU使用率: 可以通过把一些暂时不使用的进程关掉后再尝试。 或者可以尝试重启云服务器。 如果重装系统,请先备份重要数据。 如果服务器有重要数据不能重装,可以通过挂载磁盘方式拷贝数据,需要先备份,再卸载磁盘,然后挂载盘拷贝数据。 如果需要分析蓝屏原因,需要确认是否有配置内存转储文件(crash dump)的收集,系统会自动生成蓝屏dump日志到指定的目录。 由于蓝屏日志的分析非常耗时,建议客户在遇到蓝屏的情况,重启云服务器后,参考如上的可能原因进行排查。一般第三方杀毒软件、系统故障和CPU占用过高是导致云服务器蓝屏最常见的原因。
  • 配置新用户并加入远程桌面用户组 如果配置“多个用户同时登录的多用户登录”,那么在创建完新用户后需要将其加入远程桌面用户组。本小节操作介绍创建新用户并添加用户到远程桌面用户组的操作步骤。 在运行中输入lusrmgr.msc,打开本地用户和组,进行新用户创建。 图15 lusrmgr.msc 单击“用户”,在空白处右键选择新用户。 图16 选择新用户 填写新用户信息,单击“创建”。 图17 填写新用户信息 单击“组”,双击打开Remote Desktop Users组,单击“添加”。 图18 Remote Desktop Users组 进入选择用户界面,单击“高级”。 图19 选择用户界面 在新的选择用户界面,单击“立即查找”,在下方搜索结果中选中需要远程登录的用户,并单击“确定”,完成添加,即可远程登录。 图20 选择用户 单击“确定”,添加用户到Remote Desktop Users组。 图21 确认成员信息
  • 操作须知 请确保云服务器带宽资源充足,避免由于多用户同时操作负载过高导致云服务器卡顿或登录异常。 所在安全组入方向已开放云服务器登录使用的端口,默认使用3389端口。 云服务器已经绑定弹性公网IP。 配置多用户登录后,不同的用户登录云服务器操作互相之间无影响。 Windows Server 2012版本操作系统安装桌面会话主机和远程桌面授权时操作步骤与Windows Server 2008版本不同,如果您使用的是Windows Server 2012操作系统请参考Windows云服务器如何配置多用户登录?(Windows 2012)。 完成本节操作的配置后可以实现多个用户同时远程登录或同一用户多个远程登录。但是远程桌面授权仅支持120天,过期后将因缺失远程桌面授权服务器许可证而导致多用户登录无法使用。如需激活远程桌面授权请参考申请多用户会话授权的license并激活云服务器。 远程桌面授权仅支持120天,过期后远程连接服务器时会提示“没有远程桌面授权服务器可以提供许可证”,请参考远程连接Windows云服务器云主机报错:没有远程桌面授权服务器可以提供许可证,删除远程桌面服务。 配置多用户登录后,可能会出现多用户登录Windows主机时无法打开浏览器的问题,解决方法请参考多用户登录Windows主机时无法打开浏览器。
  • DMS for RabbitMQ自定义策略样例 示例1:授权用户删除实例和重启实例 { "Version": "1.1", "Statement": [ { "Effect": "Allow", "Action": [ "dms:instance:modifyStatus", "dms:instance:delete" ] } ]} 示例2:拒绝用户删除实例 拒绝策略需要同时配合其他策略使用,否则没有实际作用。用户被授予的策略中,一个授权项的作用如果同时存在Allow和Deny,则遵循Deny优先。 如果您给用户授予DMS FullAccess的系统策略,但不希望用户拥有DMS FullAccess中定义的删除实例权限,您可以创建一条拒绝删除实例的自定义策略,然后同时将DMS FullAccess和拒绝策略授予用户,根据Deny优先原则,则用户可以对DMS for RabbitMQ执行除了删除实例外的所有操作。拒绝策略示例如下: { "Version": "1.1", "Statement": [ { "Effect": "Deny", "Action": [ "dms:instance:delete" ] } ]}
  • LVS的心跳超时时间 RabbitMQ集群实例使用LVS进行负载均衡,如图1所示,单节点实例不涉及LVS。 图1 集群实例的负载均衡 LVS对客户端连接设置了心跳超时时间,默认为90秒。如果客户端在90秒内没有向LVS发送心跳(AMQP心跳帧或消息收发),LVS会主动断开与客户端的连接,此时客户端需要重新连接。 如果存在消息收发时间间隔大于90秒的场景,请在客户端开启心跳并设置小于90秒的心跳超时时间。
  • 客户端如何配置心跳超时时间 在Java客户端配置心跳超时时间。 在创建连接前使用ConnectionFactory#setRequestedHeartbeat进行设置,示例如下: ConnectionFactory cf = new ConnectionFactory(); // 将心跳超时时间设置为60秒cf.setRequestedHeartbeat(60); 在.NET客户端配置心跳超时时间,示例如下。 var cf = new ConnectionFactory();// 将心跳超时设置为60秒cf.RequestedHeartbeat = TimeSpan.FromSeconds(60); 在Python pika客户端配置心跳超时时间,示例如下。 # 设置心跳时间为60秒params = pika.ConnectionParameters(host='host', heartbeat=60, credentials=pika.PlainCredentials('username', 'passwd'))connection = pika.BlockingConnection(params)while True: channel.basic_publish(exchange='', routing_key='hello', body='Hello World!') print(" [x] Sent 'Hello World!'") # 生产者需要使用connection.sleep()才能触发心跳,使用time.sleep()不会触发心跳 connection.sleep(200)
  • 什么是心跳 RabbitMQ实例提供了心跳功能,以确保应用程序层及时发现中断的连接和完全无响应的对端。心跳还可以防止某些网络设备在一段时间内由于没有活动而中断TCP连接。开启心跳的方法为在连接上指定心跳超时时间。 心跳超时时间定义了对等TCP连接在多长时间后被服务端和客户端视为关闭。服务端和客户端会对配置的心跳超时时间进行协商,客户端必须配置该值来发送心跳。RabbitMQ官方团队维护的3个客户端(Java、.NET、Erlang语言)的心跳超时时间协商逻辑如下: 服务端和客户端设置的心跳超时时间都不为0时,两者间较小的值生效。 服务端和客户端任意一端设置的心跳超时时间为0,另一端不为0时,非0的值生效。 服务端和客户端的心跳超时时间都设置为0时,表示禁用心跳。 配置心跳超时时间后,RabbitMQ服务端和客户端都会向对方发送AMQP心跳帧作为心跳,发送的时间间隔为心跳超时时间的一半。客户端在两次错过心跳后,会被认为是不可达的,TCP连接将被关闭。当客户端检测到服务端由于心跳而无法访问时,需要重新连接。 一些客户端(如C语言客户端)没有发送心跳的逻辑,即使配置了心跳超时时间,开启了心跳,仍然无法发送心跳。此时需要额外启动一个线程,编写发送心跳的逻辑。
  • 云审计服务支持的DMS for RabbitMQ操作列表 通过云审计服务,您可以记录与分布式消息服务RabbitMQ版相关的操作事件,便于日后的查询、审计和回溯。 表1 云审计服务支持的DMS for RabbitMQ操作列表 操作名称 资源类型 事件名称 删除后台任务成功 rabbitmq deleteDMSBackendJobSuccess 删除后台任务失败 rabbitmq deleteDMSBackendJobFailure 创建DMS实例订单成功 rabbitmq createDMSInstanceOrderSuccess 创建DMS实例订单失败 rabbitmq createDMSInstanceOrderFailure 修改DMS实例订单成功 rabbitmq modifyDMSInstanceOrderSuccess 修改DMS实例订单失败 rabbitmq modifyDMSInstanceOrderFailure 扩容实例成功 rabbitmq extendDMSInstanceSuccess 扩容实例失败 rabbitmq extendDMSInstanceFailure 重置DMS实例密码成功 rabbitmq resetDMSInstancePasswordSuccess 重置DMS实例密码失败 rabbitmq resetDMSInstancePasswordFailure 删除创建失败的DMS实例成功 rabbitmq deleteDMSCreateFailureInstancesSuccess 删除创建失败的DMS实例失败 rabbitmq deleteDMSCreateFailureInstancesFailure 重启DMS实例成功 rabbitmq restartDMSInstanceSuccess 重启DMS实例失败 rabbitmq restartDMSInstanceFailure 批量删除DMS实例成功 rabbitmq batchDeleteDMSInstanceSuccess 批量删除DMS实例失败 rabbitmq batchDeleteDMSInstanceFailure 批量重启DMS实例成功 rabbitmq batchRestartDMSInstanceSuccess 批量重启DMS实例失败 rabbitmq batchRestartDMSInstanceFailure 修改DMS实例信息成功 rabbitmq modifyDMSInstanceInfoSuccess 修改DMS实例信息失败 rabbitmq modifyDMSInstanceInfoFailure 批量删除DMS实例任务 rabbitmq batchDeleteDMSInstanceTask 解冻DMS实例任务成功 rabbitmq unfreezeDMSInstanceTaskSuccess 解冻DMS实例任务失败 rabbitmq unfreezeDMSInstanceTaskFailure 冻结DMS实例任务成功 rabbitmq freezeDMSInstanceTaskSuccess 冻结DMS实例任务失败 rabbitmq freezeDMSInstanceTaskFailure 删除DMS实例任务成功 rabbitmq deleteDMSInstanceTaskSuccess 删除DMS实例任务失败 rabbitmq deleteDMSInstanceTaskFailure 创建DMS实例任务成功 rabbitmq createDMSInstanceTaskSuccess 创建DMS实例任务失败 rabbitmq createDMSInstanceTaskFailure 扩容DMS实例任务成功 rabbitmq extendDMSInstanceTaskSuccess 扩容DMS实例任务失败 rabbitmq extendDMSInstanceTaskFailure 重启DMS实例任务成功 rabbitmq restartDMSInstanceTaskSuccess 重启DMS实例任务失败 rabbitmq restartDMSInstanceTaskFailure 批量重启DMS实例任务成功 rabbitmq batchRestartDMSInstanceTaskSuccess 批量重启DMS实例任务失败 rabbitmq batchRestartDMSInstanceTaskFailure 修改DMS实例信息任务成功 rabbitmq modifyDMSInstanceInfoTaskSuccess 修改DMS实例信息任务失败 rabbitmq modifyDMSInstanceInfoTaskFailure 父主题: 云审计服务支持的关键操作
  • 命令行模式连接实例 登录弹性云服务器。 安装Java JDK或JRE,并配置JAVA_HOME与PATH环境变量。在用户家目录下修改.bash_profile,添加如下行,路径以实际为准。 export JAVA_HOME=/opt/java/jdk1.8.0_151 export PATH=$JAVA_HOME/bin:$PATH 执行source .bash_profile命令使修改生效。 ECS虚拟机默认自带的JDK可能不符合要求,例如OpenJDK,需要配置为Oracle的JDK,可至Oracle官方下载页面下载Java Development Kit 1.8.111及以上版本。 下载RabbitMQ-Tutorial.zip示例工程代码。 $ wget https://dms-demo.obs.cn-north-1.myhuaweicloud.com/RabbitMQ-Tutorial.zip 解压RabbitMQ-Tutorial.zip压缩包。 $ unzip RabbitMQ-Tutorial.zip 进入RabbitMQ-Tutorial目录,该目录下包含预编译好的jar文件。 $ cd RabbitMQ-Tutorial 运行生产消息示例。 $ java -cp .:rabbitmq-tutorial.jar Send host port user password 其中,host表示RabbitMQ实例的连接地址,port为RabbitMQ实例的监听端口(默认为5672),user表示RabbitMQ用户名,password表示用户名对应的密码。 图1 运行生产消息示例 使用Ctrl+C命令退出。 运行消费消息示例。 $ java -cp .:rabbitmq-tutorial.jar Recv host port user password 其中,host表示RabbitMQ实例的连接地址,port为RabbitMQ实例的监听端口(默认为5672),user表示RabbitMQ用户名,password表示用户名对应的密码。 图2 运行消费消息示例 如需停止消费使用Ctrl+C命令退出。
  • 示例代码(Java) 连接实例并生产消息 ConnectionFactory factory = new ConnectionFactory(); factory.setHost(host); factory.setPort(port); factory.setUsername(user); factory.setPassword(password); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.queueDeclare(QUEUE_NAME, false, false, false, null); String message = "Hello World!"; channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8")); System.out.println(" [x] Sent '" + message + "'"); channel.close(); connection.close(); 连接实例并消费消息 ConnectionFactory factory = new ConnectionFactory(); factory.setHost(host); factory.setPort(port); factory.setUsername(user); factory.setPassword(password); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.queueDeclare(QUEUE_NAME, false, false, false, null); System.out.println(" [*] Waiting for messages. To exit press CTRL+C"); Consumer consumer = new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body, "UTF-8"); System.out.println(" [x] Received '" + message + "'"); } }; channel.basicConsume(QUEUE_NAME, true, consumer);
  • 命令行模式连接实例 登录弹性云服务器,如开启公网访问,则直接登录执行主机。 安装Java JDK或JRE,并配置JAVA_HOME与PATH环境变量,使用执行用户在用户家目录下修改.bash_profile,添加如下行,路径以实际为准。 export JAVA_HOME=/opt/java/jdk1.8.0_151 export PATH=$JAVA_HOME/bin:$PATH 执行source .bash_profile命令使修改生效。 ECS虚拟机默认自带的JDK可能不符合要求,例如OpenJDK,需要配置为Oracle的JDK,可至Oracle官方下载页面下载Java Development Kit 1.8.111及以上版本。 下载RabbitMQ-Tutorial-SSL.zip示例工程代码。 $ wget https://dms-demo.obs.cn-north-1.myhuaweicloud.com/RabbitMQ-Tutorial.zip 解压RabbitMQ-Tutorial-SSL.zip压缩包。 $ unzip RabbitMQ-Tutorial-SSL.zip 进入RabbitMQ-Tutorial-SSL目录,该目录下包含预编译好的jar文件。 $ cd RabbitMQ-Tutorial-SSL 运行生产消息示例。 $ java -cp .:rabbitmq-tutorial-sll.jar Send host port user password 其中,host表示RabbitMQ实例的连接地址,port为RabbitMQ实例的监听端口(默认为5671),user表示RabbitMQ用户名,password表示用户名对应的密码。 图1 生产消息示例 使用Ctrl+C命令退出。 运行消费消息示例。 $ java -cp .:rabbitmq-tutorial-sll.jar Recv host port user password 其中,host表示RabbitMQ实例的连接地址,port为RabbitMQ实例的监听端口(默认为5671),user表示RabbitMQ用户名,password表示用户名对应的密码。 图2 消费消息示例 如需停止消费使用Ctrl+C命令退出。
  • 示例代码(Java) 连接实例并生产消息 ConnectionFactory factory = new ConnectionFactory(); factory.setHost(host); factory.setPort(port); factory.setUsername(user); factory.setPassword(password); factory.useSslProtocol(); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.queueDeclare(QUEUE_NAME, false, false, false, null); String message = "Hello World!"; channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8")); System.out.println(" [x] Sent '" + message + "'"); channel.close(); connection.close(); 连接实例并消费消息 ConnectionFactory factory = new ConnectionFactory(); factory.setHost(host); factory.setPort(port); factory.setUsername(user); factory.setPassword(password); factory.useSslProtocol(); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.queueDeclare(QUEUE_NAME, false, false, false, null); System.out.println(" [*] Waiting for messages. To exit press CTRL+C"); Consumer consumer = new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body, "UTF-8"); System.out.println(" [x] Received '" + message + "'"); } }; channel.basicConsume(QUEUE_NAME, true, consumer);
  • 操作步骤 登录RabbitMQ实例的Web UI。 在菜单栏,选择“Admin”。 图1 选择Admin菜单 (可选)选择右侧导航栏“Virtual Hosts”,然后输入“Name”,单击“Add virtual host”,创建Vhost。 如果您需要设置指定Vhost,请执行本步骤;如果不需要,请直接执行4。 图2 创建Vhost 选择右侧导航栏“Policies”,为Vhost设置规则。 如果为指定的Vhost设置,请在“Virtual Host”选择3创建的Vhost;如果没有,则默认为“/”。 图3 设置Vhost规则 参数解释如下: Name: policy的名称,用户自定义。 Pattern: queue的匹配模式(正则表达式)。 Definition: 镜像定义,包括三个部分ha-sync-mode、ha-mode、ha-params。 ha-sync-mode: 表示镜像队列中消息的同步方式,有效取值范围为:automatic和manually。 automatic:表示自动向master同步数据。 manually:表示手动向master同步数据。 ha-mode: 指明镜像队列的模式,有效取值范围为:all、exactly和nodes。 all:表示在集群所有的节点上进行镜像。 exactly:表示在指定个数的节点上进行镜像,节点的个数由ha-params指定。 nodes:表示在指定的节点上进行镜像,节点名称通过ha-params指定。 ha-params: ha-mode模式需要用到的参数。 Priority: 可选参数,policy的优先级。 单击“Add policy”。 规则添加成功后如下图所示。 图4 Vhost规则
  • 使用场景 默认情况下,RabbitMQ生产者生产的消息存储在内存中,当需要释放内存时,会将内存中的消息换页至磁盘中。换页操作会消耗较长的时间,且换页过程中队列无法处理消息。 如果生产速度过快(例如执行批处理任务),或者消费者由于各种原因(例如消费者下线、宕机)长时间内无法消费消息,导致消息大量堆积,使得内存使用率过高,换页频繁,可能会影响其他队列的消息收发。这种场景下,建议您启用惰性队列。 惰性队列(Lazy Queue)会尽可能的将消息存入磁盘中,在消费者消费到相应的消息时才会被加载到内存中,这样可以减少内存的消耗,但是会增加I/O的使用,影响单个队列的吞吐量。惰性队列的一个重要的设计目标是能够支持更长的队列,即支持更多的消息存储/消息堆积。 在以下情况下,推荐使用惰性队列: 队列可能会产生消息堆积 队列对性能(吞吐量)的要求不是非常高,例如TPS 1万以下的场景 希望队列有稳定的生产消费性能,不受内存影响而波动 处于以下情况时,无需使用惰性队列: RabbitMQ需要高性能的场景 队列总是很短(即队列中没有消息堆积) 设置了最大长度策略 更多关于惰性队列的说明,请参考Lazy Queues。
  • 使用场景 默认情况下,RabbitMQ生产者生产的消息存储在内存中,当节点宕机或重启时,如何确保消息不丢失呢?RabbitMQ通过持久化机制实现,持久化包括Exchange持久化、Queue持久化和Message持久化。持久化是将内存中的消息写入到磁盘中,以防异常情况导致内存中的消息丢失。但是磁盘的读写速度远不如内存,开启消息持久化后,RabbitMQ的性能会下降。与惰性队列不同,持久化消息会在磁盘和内存中各存储一份,只有在内存空间不够时,才会将内存中的消息删除,存储到磁盘中。 非持久化Queue、Exchange在重启之后会丢失。 非持久化Message在重启之后会丢失(经过持久化Queue/Exchange的消息不会自动变为持久化消息)。 持久化消息在尚未完成持久化时,如果服务器重启,消息会丢失。
  • 消费者确认 消费者确认是指服务端通过确认消息是否成功被消费者接收,来判断是否删除队列中的此消息。 消费者确认对数据可靠性十分重要,接收重要消息的消费应用程序在未处理完消息前不应确认消息,以便消费者有足够的时间处理消息,无需担心消息处理过程中由于消费者进程异常(如工作程序崩溃、重启等)导致消息丢失。 消费者确认在客户端上配置,通过配置basicConsume方法启用确认。在channel中启用消费者确认适用于大多数场景。 以下示例演示在Java客户端配置消费者确认(使用Channel#basicAck设置basic.ack为肯定): // this example assumes an existing channel instanceboolean autoAck = false;channel.basicConsume(queueName, autoAck, "a-consumer-tag", new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { long deliveryTag = envelope.getDeliveryTag(); // positively acknowledge a single delivery, the message will // be discarded channel.basicAck(deliveryTag, false); } }); 未确认的消息缓存在内存中,如果未确认的消息过多,会导致内存使用率过高,此时可以在客户端配置预取值来限制消费者预取的消息数量,具体方法请参见预取值。
  • 使用场景 生产者在发布消息后,怎么确认消息已正确发布到服务器端?服务器端又怎么确认消息已成功被消费?RabbitMQ提供的消息确认机制可以解决此问题。 在使用RabbitMQ时,生产者确认和消费者确认对于确保数据可靠性至关重要。如果连接失败,传输中的消息可能会丢失,需要重新传输。确认机制可以让服务器和客户端知道何时重新传输消息。客户端可以在收到消息时确认消息,也可以在客户端完全处理完消息后确认。生产者确认会影响性能,如果需要很高的吞吐量,应禁用生产者确认。注意,不使用生产者确认会导致可靠性下降。 更多关于消息确认机制的说明,请参考Consumer Acknowledgements and Publisher Confirms。
  • 使用场景 单一活跃消费者(Single Active Consumer)表示队列中可以注册多个消费者,但是只允许一个消费者消费消息,只有在此消费者出现异常时,才会自动转移到另一个消费者进行消费。单一活跃消费者适用于需要保证消息消费顺序性,同时提供高可靠能力的场景。 分布式消息服务RabbitMQ版3.8.35版本才提供单一活跃消费者特性。 图1 单一活跃消费者消费流程 如图1所示,Producer生产9条消息,由于队列设置了单一活跃消费者特性,只有Consumer 1在消费消息。 更多关于单一活跃消费者的说明,请参考Single Active Consumer。
  • 生产者确认 生产者确认,即服务端在收到来自生产者的消息时进行确认。 以下示例演示在Java客户端配置生产者确认: try {channel.confirmSelect() ; //将信道置为publisher confirm模式//之后正常发送消息channel . basicPublish( "exchange " , " routingKey" , null , "publisher confirm test " .getBytes());if (!channel.waitForConfirms()) {System.out.println( "send message failed " ) ;// do something else....}} catch (InterruptedException e) {e.printStackTrace() ;} 调用channel .waitForConfirms方法之后,会等待服务端确认,这是一种同步等待的方式,会对性能产生影响。如果生产者要满足at least once,就必须使用同步等待方式。
  • DMS for RabbitMQ请求条件 您可以在创建自定义策略时,通过添加“请求条件”(Condition元素)来控制策略何时生效。请求条件包括条件键和运算符,条件键表示策略语句的 Condition元素,分为全局级条件键和服务级条件键。全局级条件键(前缀为g:)适用于所有操作,服务级条件键(前缀为服务缩写,如dms:)仅适用于对应服务的操作。运算符与条件键一起使用,构成完整的条件判断语句。 DMS for RabbitMQ通过IAM预置了一组条件键,例如,您可以先使用dms:ssl条件键检查RabbitMQ实例是否开启SSL,然后再允许执行操作。下表显示了适用于DMS for RabbitMQ服务特定的条件键。 表1 DMS for RabbitMQ请求条件 DMS for RabbitMQ条件键 运算符 描述 dms:publicIP Bool IsNullOrEmpty BoolIfExists 是否开启公网 dms:ssl Bool IsNullOrEmpty BoolIfExists 是否开启SSL 父主题: 权限管理
  • 使用场景 设置预取值可以限制未被确认的消息个数,一旦消费者中未被确认的消息数量达到设置的预取值,服务端将不再向此消费者发送消息,除非至少有一个未被确认的消息被确认。设置预取值本质上是一种对消费者进行流控的方法。 设置预取值时,需要考虑多种因素: 预取值设置太小可能会损害性能,RabbitMQ会一直在等待获得发送消息的权限。 预取值设置太大可能会导致从队列中取出大量消息传递给一个消费者,而使其他消费者处于空闲状态。另外还需要考虑消费者的配置,消费者在处理消息时会将所有消息保存在内存中,太大的预取值会对消费者的性能产生负面影响,甚至可能会导致消费者崩溃。 更多关于预取值的说明,请参考Consumer Prefetch。
共100000条