RabbitMQ消息队列集群

  • 消息队列/中间件
  • RabbitMQ详解
    • RabbitMQ单机部署
    • RabbitMQ集群部署

消息队列/中间件

一、前言

  • 在我们秒杀抢购商品的时候,系统会提醒我们稍等排队中,而不是像几年前一样页面卡死或报错给用户
  • 像这种排队结算就用到了消息队列机制,放入通道里面一个一个结算处理,而不是某个时间断突然涌入大批量的查询新增把数据库给搞宕机
  • 所以RabbitMQ本质上起到的作用就是削峰填谷,为业务保驾护航。


二、MQ简介

  • MQ全称为Message Queue,消息队列。是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消息传递指的是程序之间,通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信。队列的使用除去了接收和发送应用程序,同时执行的要求。
  • 在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式,大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量,

三、核心功能

  • 解耦(将不同的系统分离开)将PHP于数据库之间解耦
  • 冗余(存储)
  • 扩展性
  • 削峰
  • 可恢复性
  • 顺序保证
  • 缓存
  • 异步通信

四、MQ的分类

p2p模式(安全,点到点)

point to point (p2p)

  • p2p模式包含的三个角色

消息队列自身(Queue)
发送者(Sender)
接受者(Receiver)
每个消息都被发送到一个特定的队列,接受者从队列中获取消息,队列保留着消费信息,直到他们被消费或超时

  • p2p特点如下:

每一个消息只有一个消费者(Consumer),即一旦被消费,消息就不再消息队列中
发送者和接受者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接受者有没有正在运行它不会影响到消息被发送到队列
接受者在成功接收消息之后,需向队列应答成功
如果希望发送的每个消息都会被成功处理,那么需要p2p模式

Pub/Sub模式(并发)

Publish/Subscribe

  • Pub/Sub模式包含三个角色:主题.( Topic )、发布者( Publisher )、订阅者(Subscriber )。多个者将消息发送到Topic,系统将这些消息传递给多个订阅者。Pub/Sub的特点如下︰

每个消息可以有多个消费者
发布者和订阅者之间有时间上的依赖性。针对某个主题( Topic )的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息
为了消费消息,订阅者必须保持运行的状态
如果希望发送的消息可以不被做任何处理、或者只被一个消息者处理、或者可以被多个消费者处理的话,那么可以采用Pub/Sub模型

五、 同类产品

  • Kafka

Kafka是LinkedIn开源的分布式发布-订阅消息系统,目前归属于Apache顶级项目。Kafka主要特点是基于Pul的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输。0.8版本开始支持复制,不支持事务,对消息的重复、丢失、错误没有严格要求,适合产生大量数据的互联网服务的数据收集业务。一般应用在大数据日志处理或对实时性(少量延迟),可靠性(少量丢数据)要求稍低的场景使用,比如ELK日志收集。

  • ★RabbitMQ★

RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。RabbitMQ比Kafka可靠

  • RocketMQ

RocketMQ是阿里开源的消息中间件,它是纯ava开发,具有高吞吐星、高可用性、适合大规模分布式系统应用的特点。RocketMQ思路起源于Kafka,但并不是Kafka的一个Copy,它对消息的可靠传输及事务性做了优化,目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景。

RabbitMQ详解

一、 RabbitMQ简介

  • RabbitMQ是一个在AMQP ( Advanced Message Queuing Protocol )基础上实现的,可复用的企业消息系统。它可以用于大型软件系统,各个模块之间的高效通信,支持高并发,支持可扩展。它支持多种客户端如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX,持久化,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。
  • RabbitMQ是使用Erlang编写的一个开源的消息队列,本身支持很多的协议︰AMQP,XMPP, SMTP, STOMP,也正是如此,使的它变的非常重星级,更适合于企业级的开发。它同时实现了一个Broker构架,这意味着消息在发送给客户端时先在中心队列排队,对路由(Routing)、负载均衡(Load balance)或者数据持久化都有很好的支持。

二、RabbitMQ特点

  • 可靠性
  • 灵活的路由
  • 扩展性
  • 高可用性
  • 多种协议
  • 多语言客户端
  • 管理界面
  • 插件机制

三、AMQP介绍

  • AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。

四、RabbitMQ应用场景

对于一个大型的软件系统来说,它会有很多的组件或者说模块或者说子系统( subsystem or Component or submodule )。那么这些模块的如何通信?这和传统的IPC有很大的区别。传统的IPC很多都是在单一系统上的,模块耦合性很大,不适合扩展(Scalability );如果使用socket那么不同的模块的确可以部署到不同的机器上,但是还是有很多问题需要解决。比如:

  • 信息的发送者和接收者如何维持这个连接,如果一方的连接中断,这期间的数据会不会丢失?
  • 如何降低发送者和接收者的耦合度?
  • 如何让优先级高的接收者先接到数据?
  • 如何做到load balance ?有效均衡接收者的负载?
  • 如何有效的将数据发送到相关的接收者?也就是说将接收者subscribe处理不同的数据,如何做有效的filter。
  • 如何做到可扩展,甚至将这个通信模块发到cluster上?
  • 如何保证接收者接收到了完整,正确的数据?AMQP协议解决了以上的问题,而RabbitMO实现了AMOP

五、RabbitMQ架构图示

  • RabbitMQ从整体上来看是一个典型的生产者消费者模型,主要负责接收、存储和转发消息

六、RabbitMQ常用术语

  • Message:消息,是有消息头和消息体组成的。消息体是不透明的,消息体是由一些可选属性组成的,包括路由键(routing-key)、优先级(priority)、持久性存储(delivery-mode)等
  • publisher:消息生产者,是向交换器发送消息的客户端程序,我们可以简单理解为就是一个Java程序
  • Exchange:交换器,用来接收生产者发送的消息,并将这些消息路由发送给服务器中的队列。消息要先经过交换器(exchange),再到队列中去。
  • Queue:消息队列,用来保存消息,直接发送给消费者,消息的容器,也是消息的终点,一个消息可投入一个或多个队列,消息一致在队列里面,等待消费者连接者连接到这个队列将其取走
  • Bingding:绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键,将交换器和消息队列连接起来的路由规则,所以可以将交换器理解为一个由绑定构成的路由表
  • Virtual Host:虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加h密环境的独立服务器区域,每个vhost本质上就是一个mini版的RabbitMQ服务器,拥有自己的队列、交换器、绑定和权限机制,vhost是AMQP概念的基础,必须再连接时指定,RabbitMQ默认的vhost是"/"
  • Broker:可以理解为rabbitmq的服务器实体,可以理解为在Linux上创建的虚拟机实体
  • Connection:连接,我们可以理解为rabbitmq服务器和app服务建立的TCP的连接。
  • Channel:信道,也可以成为管道。是TCP里的虚拟连接。-条TCP连接,可以包含很多条的Channel。例如∶电缆相当与TCP,信道是—条独立光纤束,一条TCP连接上创建多少条信道是没有限制的,TCP一旦打开,就会创建AMQP信道,无论是发布消息、接收消息、订阅消息,这些动作都是通过信道完成的
  • Consumer:消息的消费者,表示一个从消息队列中取得消息的客户端应用程序,和Producer类似,我们可以简单理解为就是一个Java程序

RabbitMQ单机部署

#环境
192.168.100.10 rabbitmq1
192.168.100.11 rabbitmq2
192.168.100.12 rabbitmq3#域名解析
[root@rabbitmq1 ~]# vim /etc/hosts
192.168.100.10 rabbitmq1
192.168.100.11 rabbitmq2
192.168.100.12 rabbitmq3
[root@rabbitmq1 ~]# scp -r /etc/hosts 192.168.100.11:/etc/
[root@rabbitmq1 ~]# scp -r /etc/hosts 192.168.100.12:/etc/
  • 安装Erlang
    RabbitMQ是由Erlang语言编写
[root@rabbitmq1 ~]# yum -y install erlang-21.3.8.6-1.el7.x86_64-2.rpm
  • 安装RabbitMQ
[root@rabbitmq1 ~]# yum -y install rabbitmq-server-3.7.13-1.el7.noarch.rpm
  • 修改配置文件
#将默认示例配置文件复制至工作路径下作为配置文件
[root@rabbitmq1 ~]# cp /usr/share/doc/rabbitmq-server-3.7.13/rabbitmq.config.example /etc/rabbitmq/rabbitmq.config
[root@rabbitmq1 ~]# vim /etc/rabbitmq/rabbitmq.config
61    {loopback_users, []}                                                  #配置文件61行去除%%和,开通默认测试账号
  • 安装插件并启动服务
[root@rabbitmq1 ~]# rabbitmq-plugins enable rabbitmq_management             #WEB界面管理工具
[root@rabbitmq1 ~]# systemctl restart rabbitmq-server                       #插件安装完成后重启
[root@rabbitmq1 ~]# rabbitmqctl cluster_status                              #rabbitmq集群查看工具,查看节点信息
Cluster status of node rabbit@rabbitmq1 ...                                 #集群状态在这个节点上rabbit@rabbitmq1
[{nodes,[{disc,[rabbit@rabbitmq1]}]},{running_nodes,[rabbit@rabbitmq1]},                                        #运行{cluster_name,<<"rabbit@rabbitmq1">>},                                     #集群名称{partitions,[]},                                                           #集群位置{alarms,[{rabbit@rabbitmq1,[]}]}]                                          #单机部署,如集群部署会显示多个主机
  • 访问测试
http://192.168.100.10:15672

  • 登陆后主页面

  • 设置虚拟主机与添加用户

  • 命令行添加用户,设置tags(标签)

[root@rabbitmq1 ~]# rabbitmqctl list_queues                                      #查看所有队列
[root@rabbitmq1 ~]# rabbitmqctl reset                                            #清除所有队列
[root@rabbitmq1 ~]# rabbitmqctl add_user pakho pakho                             #添加用户及密码
[root@rabbitmq1 ~]# rabbitmqctl set_user_tags pakho administrator                #设置用户为超管
[root@rabbitmq1 ~]# rabbitmqctl add_vhost vhost_pakho                            #新增虚拟主机
[root@rabbitmq1 ~]# rabbitmqctl set_permissions -p vhost_pakho pakho "." "." "." #将虚拟主机授权给新用户(后面3个点代表拥有配置、写、读全部权限)

RabbitMQ集群部署

  • 消息中间件RabbitMQ,一般以集群方式部署,主要提供消息的接受和发送,实现各微服务之间的消息异步,
  • 以下将以Rabbit+HA方式进行部署
  • Cookie:RabbitMQ底层是通过Erlang架构来实现的,所以rabbitmqctl会启动Erlang节点,并基于Erlang节点来使用Erlang系统连接RabbitMQ节点,在连接过程中需要正确的Erlang Cookie和节点名称,Erlang节点通过交换Erlang Cookie以获得认证来实现布式,所以部署Rabbitmq分布式集群时要先安装Erlang,并把其中一个服务的cookie复制到另外的节点。
  • 内存节点和磁盘节点:RabbitMQ集群中,各个RabbitMQ为对等节点,即每个节点均提供给客户端连接,进行消息的接收和发送。节点分为内存节点和磁盘节点,一般都建立为磁盘节点,为了防止机器重启后的消息消失
  • 普通模式和镜像模式:RabbitMQ的Cluster集群模式一般分为两种,普通模式和镜像模式。消息队列通过RabbitMO HA镜像队列进行消息队列实体复制。
#环境
所有节点需要在同一局域网内
所有节点需要有相同的erlang cookie,否则不能通信,为了实现cookie一致,采用scp方式
#域名解析:略 同上#将软件包使用scp拷贝至其余两台服务器
[root@rabbitmq1 ~]# scp -r erlang-21.3.8.6-1.el7.x86_64-2.rpm rabbitmq2:/usr/src/
[root@rabbitmq1 ~]# scp -r rabbitmq-server-3.7.13-1.el7.noarch.rpm rabbitmq2:/usr/src/[root@rabbitmq1 ~]# scp -r erlang-21.3.8.6-1.el7.x86_64-2.rpm rabbitmq3:/usr/src/
[root@rabbitmq1 ~]# scp -r rabbitmq-server-3.7.13-1.el7.noarch.rpm rabbitmq3:/usr/src/
  • 安装Erlang
[root@rabbitmq2 src]# yum -y install erlang-21.3.8.6-1.el7.x86_64-2.rpm
[root@rabbitmq3 src]# yum -y install erlang-21.3.8.6-1.el7.x86_64-2.rpm
  • 安装RabbitMQ
[root@rabbitmq2 src]# yum -y install rabbitmq-server-3.7.13-1.el7.noarch.rpm
[root@rabbitmq3 src]# yum -y install rabbitmq-server-3.7.13-1.el7.noarch.rpm
  • 修改配置文件
#rabbitmq2
[root@rabbitmq2 ~]# cp /usr/share/doc/rabbitmq-server-3.7.13/rabbitmq.config.example /etc/rabbitmq/rabbitmq.config
[root@rabbitmq2 ~]# vim /etc/rabbitmq/rabbitmq.config
61    {loopback_users, []}                                                  #配置文件61行去除%%和,开通默认测试账号#rabbitmq3
[root@rabbitmq3 ~]# cp /usr/share/doc/rabbitmq-server-3.7.13/rabbitmq.config.example /etc/rabbitmq/rabbitmq.config
[root@rabbitmq3 ~]# vim /etc/rabbitmq/rabbitmq.config
61    {loopback_users, []}                                                  #配置文件61行去除%%和,开通默认测试账号
  • 安装插件
[root@rabbitmq2 ~]# rabbitmq-plugins enable rabbitmq_management             #WEB界面管理工具[root@rabbitmq3 ~]# rabbitmq-plugins enable rabbitmq_management             #WEB界面管理工具
  • 设置Erlang运行节点并运行
    一定要保证三台机器的cookie内容一致

    • 找到erlang cookie文件的位置,源码包部署一般会存在.erlang.cookie文件; rpm包部署一般是在/var/lib/rabbitmq/).erlang.cookie。将node1的该文件使用rsync或者是scp复制到node2、node3,文件权限需要是400。
[root@rabbitmq1 ~]# scp -r /var/lib/rabbitmq/.erlang.cookie rabbitmq2:/var/lib/rabbitmq/.erlang.cookie
[root@rabbitmq1 ~]# scp -r /var/lib/rabbitmq/.erlang.cookie rabbitmq3:/var/lib/rabbitmq/.erlang.cookie
cat /var/lib/rabbitmq/.erlang.cookie                                         #拷贝完成后检查对比是否一致
[root@rabbitmq2 ~]# systemctl restart rabbitmq-server
[root@rabbitmq3 ~]# systemctl restart rabbitmq-server#关闭rabbitmq2和rabbitmq3集群功能
[root@rabbitmq2 ~]# rabbitmqctl stop
[root@rabbitmq3 ~]# rabbitmqctl stop#设置2.3独立运行节点,warning提示不用理会
[root@rabbitmq2 ~]# rabbitmq-server -detached
[root@rabbitmq3 ~]# rabbitmq-server -detached
Warning: PID file not written; -detached was passed.#查看各节点状态
[root@rabbitmq1 ~]# rabbitmqctl cluster_status                               #查看node1节点,其他节点也均为独立
Cluster status of node rabbit@rabbitmq1 ...
[{nodes,[{disc,[rabbit@rabbitmq1]}]},{running_nodes,[rabbit@rabbitmq1]},{cluster_name,<<"rabbit@rabbitmq1">>},{partitions,[]},{alarms,[{rabbit@rabbitmq1,[]}]}]                                           #每台主机只有一个server信息未组成集群
  • 添加用户并设置密码
    加入集群
  • 由于guest这个用户,只能在本地访问,所以我们要在每个节点上,新增一个用户并赋予对/的所有权限,然后添加到管理员组中,让此用户能够远程访问
[root@rabbitmq1 ~]# rabbitmqctl add_user admin admin
[root@rabbitmq1 ~]# rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"#为admin用户设置虚拟主机并将整个/赋予admin身份可读可写可配置
[root@rabbitmq1 ~]# rabbitmqctl set_user_tags admin administrator          #设置admin为管理员身份,但仅限本机登陆

需要给node2和node3配置相同的账号

[root@rabbitmq2 ~]# rabbitmqctl add_user admin admin
[root@rabbitmq2 ~]# rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
[root@rabbitmq2 ~]# rabbitmqctl set_user_tags admin administrator
[root@rabbitmq3 ~]# rabbitmqctl add_user admin admin
[root@rabbitmq3 ~]# rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
[root@rabbitmq3 ~]# rabbitmqctl set_user_tags admin administrator
  • 访问测试
http://192.168.100.11:15672/                                               #均使用root账号登录
http://192.168.100.12:15672/


  • 组成集群

    • rabbitmq-server启动时,会一起启动:节点和应用,它预先设置RabbitMQ应用为standalone (脱机)模式。要将一个节点加入到现有的集群中,你需要停止这个应用并将节点设置为原始状态。如果使用rabbitmqctl stop,应用和节点都将被关闭。所使用rabbitmqctl stop_app仅仅关闭应用。(停应用,不停止节点)
#将node2和node3加入node1中组成集群#                               <!--           使用磁盘节点              -->#rabbitmq2
[root@rabbitmq2 ~]# rabbitmqctl stop_app                                   #关闭节点应用
[root@rabbitmq2 ~]# rabbitmqctl join_cluster rabbit@rabbitmq1              #连接集群rabbitmq1
Clustering node rabbit@rabbitmq2 with rabbit@rabbitmq1                     #群集节点rabbit@rabbitmq2 与rabbit@rabbitmq1
[root@rabbitmq2 ~]# rabbitmqctl start_app                                  #启动节点应用#rabbitmq3
[root@rabbitmq3 ~]# rabbitmqctl stop_app                                   #关闭节点应用
[root@rabbitmq3 ~]# rabbitmqctl join_cluster rabbit@rabbitmq1              #连接集群rabbitmq1
Clustering node rabbit@rabbitmq3 with rabbit@rabbitmq1                     #群集节点rabbit@rabbitmq2 与rabbit@rabbitmq1
[root@rabbitmq3 ~]# rabbitmqctl start_app                                  #启动节点应用
  • 在任意节点查看集群状态
#node1
[root@rabbitmq1 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq1 ...
[{nodes,[{disc,[rabbit@rabbitmq1,rabbit@rabbitmq2,rabbit@rabbitmq3]}]},{running_nodes,[rabbit@rabbitmq3,rabbit@rabbitmq2,rabbit@rabbitmq1]},{cluster_name,<<"rabbit@rabbitmq1">>},                                     #集群名称rabbit@rabbitmq1{partitions,[]},{alarms,[{rabbit@rabbitmq3,[]},{rabbit@rabbitmq2,[]},{rabbit@rabbitmq1,[]}]}]#node2
[root@rabbitmq2 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq2 ...
[{nodes,[{disc,[rabbit@rabbitmq1,rabbit@rabbitmq2,rabbit@rabbitmq3]}]},{running_nodes,[rabbit@rabbitmq3,rabbit@rabbitmq1,rabbit@rabbitmq2]},{cluster_name,<<"rabbit@rabbitmq1">>},                                     #集群名称rabbit@rabbitmq1{partitions,[]},{alarms,[{rabbit@rabbitmq3,[]},{rabbit@rabbitmq1,[]},{rabbit@rabbitmq2,[]}]}]#node3
[root@rabbitmq3 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq3 ...
[{nodes,[{disc,[rabbit@rabbitmq1,rabbit@rabbitmq2,rabbit@rabbitmq3]}]},{running_nodes,[rabbit@rabbitmq1,rabbit@rabbitmq2,rabbit@rabbitmq3]},{cluster_name,<<"rabbit@rabbitmq1">>},                                     #集群名称rabbit@rabbitmq1{partitions,[]},{alarms,[{rabbit@rabbitmq1,[]},{rabbit@rabbitmq2,[]},{rabbit@rabbitmq3,[]}]}]
  • 设置镜像队列策略
http://192.168.100.10:15672

设置管理员pakho

http://192.168.100.11:15672                                                   #node2

http://192.168.100.12:15672                                                  #node3

消息队列——RabbitMQ消息队列集群相关推荐

  1. dwr消息推送和tomcat集群

    网友的提问: 项目中用到了dwr消息推送.而服务端是通过一个http请求后 触发dwr中的推送方法.而单个tomcat中.服务器发送的http请求和用户都在一个tomcat服务器中.这样就能精准推送到 ...

  2. RabbitMQ学习之集群模式

    由于RabbitMQ是用erlang开发的,RabbitMQ完全依赖Erlang的Cluster,因为erlang天生就是一门分布式语言,集群非常方便,但其本身并不支持负载均衡.Erlang的集群中各 ...

  3. RabbitMQ高可用集群搭建

    RabbitMQ高可用集群搭建 摘要:实际生产应用中都会采用消息队列的集群方案,如果选择RabbitMQ那么有必要了解下它的集群方案原理一般来说,如果只是为了学习RabbitMQ或者验证业务工程的正确 ...

  4. 从零开始搭建高可用RabbitMQ镜像模式集群

    文章目录 RabbitMQ集群模式搭建 准备工作 选取任意一个节点作为master节点, 进行文件同步, 我这里选择138作为master节点 组成集群 配置镜像队列(设置镜像队列策略) 集群配置参数 ...

  5. rabbitmq服务器搭建-集群

    rabbitmq服务器搭建-集群 前言 1.修改主机名 2.开启端口25672和4369 3.配置hosts 文件 4. cookie值同步 5.重启服务 6.将node2加入至node1 7.将no ...

  6. RabbitMQ 高可用集群搭建

    RabbitMQ 高可用集群搭建 1 集群简介 1.1 集群架构 ​ 当单台 RabbitMQ 服务器的处理消息的能力达到瓶颈时,此时可以通过 RabbitMQ 集群来进行扩展,从而达到提升吞吐量的目 ...

  7. RabbitMQ原理及集群的深入剖析

    RabbitMQ原理及集群的深入剖析 说在前面 RabbitMQ应用场景剖析 RabbitMQ的组件剖析 说一说绑定过程: Exchange类型 一些事项 一些思考 关于持久化 RabbitMQ的集群 ...

  8. centos7 rabbitmq 单机部署 集群部署 HAProxy 负载均衡搭建

    准备工作 搭建 RabbitMQ Server 单机版 搭建 RabbitMQ Server 高可用集群 搭建 HAProxy 负载均衡 一.准备工作 节点 系统 版本 ip node1 centos ...

  9. php消费rabbitmq消息QoS,RabbitMQ消息队列-一对多模式

    一对多模式,用图表示如下 一个生产者向消息队列中发送消息,多个消费者同时从消息队列中读取消息,在这个模式下,我们优先考虑的,是解决各个消费者如何读取消息的机制. 下面我们以ThinkPHP的代码来展示 ...

最新文章

  1. c++ 互斥量和条件变量
  2. python支付系统开发,python支付整合开发包
  3. C/C++中函数参数传递
  4. 武汉计算机985211大学有哪些,武汉985211大学有哪些 武汉985211大学有什么
  5. CSP-J NOIP NOI数学与动态规划
  6. python传递变量_在Python中传递变量
  7. laravel 扩展包
  8. 程序员的生活照,最后一个绝了!有同感吗?
  9. mysql多条件批量查询,且数据量大分批查询
  10. 库克:苹果正在开发“会震爆你”的未来产品
  11. python剔除异常值的方法_二维d异常值的剔除方法
  12. 通达OA - 数据备份与恢复指南
  13. dojo实现省份地市级联---省份数据源
  14. 用python实现千图成像工具,快给你的男/女神做一个吧~
  15. 报错解决——ModuleNotFoundError: No module named ‘cython_bbox‘
  16. 将Excel表格导入到数据库中
  17. Java 通过EWS JAVA API发送exchange邮件
  18. PCB 设计 3. 原理图及其封装制作
  19. word研究报告排版要领
  20. 蓝牙耳机与电脑连接篇

热门文章

  1. Linux上silk微信语音转换成mp3格式
  2. 每日一练(三) pointSprite(点精灵)
  3. 2021数学建模国赛B题复盘详细解析
  4. 使用计算机的时正确的开机步骤,电脑启动时选择启动模式的方法步骤图
  5. 工控电脑服务器维修,2U机箱厂家分享:工控计算机电脑主板坏了如何维修?
  6. randon变换(拉东变换)
  7. WIN10 LTSC 2019 安装新版Mircosoft Edge浏览器,解决无法安装问题
  8. 2021年在线教育发展趋势
  9. 对产品经理来说,PMP和NPDP两个证书,哪一个权威性比较大?
  10. uni-app 应用换肤功能