手把手教你如何玩转消息中间件(ActiveMQ)

手把手教你如何玩转消息中间件(ActiveMQ)

                版权声明:本文为博主原创文章,未经博主允许不得转载。                    https://blog.csdn.net/Cs_hnu_scw/article/details/81040834                </div>
                      <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-cd6c485e8b.css">
                          <div id="content_views" class="markdown_views">
        <!-- flowchart 箭头图标 勿删 -->
        <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
          <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
        </svg>
        <h1 id="情景引入"><a name="t0"></a>情景引入</h1>

小白:起床起床起床起床。。。。快起床~
我:怎么了又,大惊小怪,吓到我了。
小白:我有事有事想找你,十万火急呢~~
我:你能有什么事?反正我不信。。那你说说看~~
小白:就是我有两个小表弟,叫大白和二白,他们现在每天睡觉之前都要分别和我聊天,让我给他们讲故事,如果不讲他们就不睡觉。但是,如果一个个的跟他们轮流来说的话,我就需要每天说两遍,而且我还要找准他们的时间点,这个有时候我有事情都无法实现这个问题,他们就会很生气。。。
我:这不是挺好的嘛,小孩子就是爱听故事的呀。。。
小白:我也愿意讲,但是时间这个不是很好控制,有没有类似,比如我可以之前就描述好了,然后定点给他们两个一起发消息,而可以抛开时间和其他因素的影响呢?
我:这个嘛,很简单呀,你可以让他们关注你的一个公众号,这样你再定时的推送给他们故事不就可以了嘛。。或者,你可以拉他们进你的一个群这样,就方便了呀~
小白:这样是可以,但是如果以后还有小表妹要听我讲,我就要如此反复的做。。感谢好麻烦好麻烦。。。
我:emmm,我理解你的意思,你就想实现一种很多人都能够进行类似一种消息推送的方式嘛。。。
小白:对的对的。。就是这样一种,,,我记得我们在技术方面好像也有一种类似的技术,这个叫做什么去了呢?
我:这就是消息中间件,一种生产者和消费者的关系。
小白:我也想学我也想学,,你快给我讲讲,给我讲讲呗。。
我:真拿你没办法,好吧。。。下面我就给你讲一下这方面的知识。

情景分析

其实,小白的这个问题,是一种比较普遍的问题。既然我们作为技术人员,当然我们就要从技术成分去分析如何解决了。这里面其实就是包含着一种消息中间件的技术。它也是最近技术层面用得非常非常多的,这也是非常值得我们进行学习。。这在如今的秒杀系统,推荐系统等等,都有广泛的应用。。所以,这章我就主要来跟大家说说这方面的知识。

基本概念的引导

本模块主要讲解关于消息中间件的相关基础知识,也是方便我们后面的学习。

什么是中间件?

非操作系统软件,非业务应用软件,不是直接给最终用户使用,不能直接给用户带来价值的软件,我们就可以称为中间件(比如Dubbo,Tomcat,Jetty,Jboss都是属于的)。

什么是消息中间件?

百度百科解释:消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间的通信。
关键点:关注于数据的发送和接受,利用高效可靠的异步消息机制传递机制集成分布式系统。
先简单的用下面这个图说明:
这里写图片描述

为什么要使用消息中间件

举几个例子,我想你就会明白了。(其实使用消息中间件主要就是为了解耦合和异步两个作用)
1:微博,都用过吧。那么,当我们新关注一个用户,那么系统会相应的推送消息给我们,并且还做了很多关于我们关注的处理。这就是消息中间件的异步。
2:秒杀系统。100件商品,几十万个人在抢,那这个怎么弄呢?总不能就把服务器给宕机了吧。那么就可以把用户的请求进行缓存,然后再异步处理。
3:系统A给系统B进行通信,而系统B需要对A的消息进行相应处理之后才能给A反馈,这时候,总不能让A就傻傻等着吧。那么,这就是异步的功能。

什么是JMS?

Java消息服务(Java Message Service)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。
总结起来说就是:Java对于应用程序之间进行信息交互的API(而且是异步)。
里面有下面的概念需要理解,对后续有帮助:

  • 提供者:实现JMS的消息服务中间件服务器。
  • 客户端:发送或接受消息的应用。
  • 生产者/发布者:创建并发送消息的客户端。
  • 消费者/订阅者:接受并处理消息的客户端。
  • 消息:应用程序之间传递的数据。
  • 消息模式:在客户端之间传递消息的模式,JMS主要是队列模式和主体模式。
  • 队列模式特点:
    (1)客户端包括生产者和消费者。
    (2)队列中的一个消息只能被一个消费者使用。
    (3)消费者可以随时取消息。
  • 主体模式特点:
    (1)客户端包括发布者和订阅者。
    (2)主题中的消息可以被所有订阅者消费。
    (3)消费者不能消费订阅之前发送的消息。

什么是AMQP?

AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。
简单点说:就是对于消息中间件所接受的消息传输层的协议(不懂传输层,那么就需要多看看计算机网络相关知识了,OSI的层次划分),只有这样才能保证客户端和消息中间件能够进行交互(换位思考:HTTP和HTTPS甚至说是TCP/IP与UDP协议都要的道理)。
emmm,比较一下JMS和AMQP的不同吧。。

  • JMS是定义与Java,而AMQP是一种传输层协议。
  • JMS是属于Java的API,而AMQP是跨语言的。
  • JMS消息类型只有两种(主题和队列,后续会说),而AMQP是有五种。
  • JMS主要就是针对Java的开发的Client,而AMQP是面向消息,队列,路由。

什么是ActiveMQ呢?

ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。
简单点说:不就是为了实现我上述所想要的需求嘛。然后它就是一种实现的方式。就比如,Tomcat是什么?不就是为了实现一种client与服务器之间的交互的一种产品嘛。。所以,不需要死记概念,自己理解就好。

ActiveMQ的安装

环境:Windows

步骤:
(1)登录到ActiveMQ的官网,下载安装包。http://activemq.apache.org/activemq-5154-release.html
(2)下载Zip文件
这里写图片描述
(3)解压Zip文件,目录如下
这里写图片描述
(4)启动ActiveMQ服务(注意:要右键以管理员身份进行运行)
这里写图片描述
注意:有两种方式,第一种就是类似tomcat启动,那么启动图会一直显示。
而第二种的话,就是把这个ActiveMQ注册到服务列表中,这样更方便我们进行操作。(推荐使用这种)
(5)登录,验证是否启动成功
这里写图片描述
(6)进入管理页面
这里写图片描述
OK,进入之后就可以看我们的管理页面啦。。。是不是很简单呢?

环境:Linux

步骤:(多余的我就不多说了。。。请看windows的步骤)
(1)同样需要下载对应的文件。后缀为tar.gz的这样的。其实可以直接通过下面的这个命令下载,快速一点,免得要移动到Linux(注意:如果是通过ssh连接的方式的话)。

wget https://mirrors.tuna.tsinghua.edu.cn/apache//activemq/5.15.4/apache-activemq-5.15.4-bin.tar.gz
 
 
  • 1

(2)然后解压下载的文件
(3)同样进入相对应的目录,运行

./activemq start
 
 
  • 1

(4)然后再访问相同的地址就可以看到啦。(具体看windows安装步骤)

ActiveMQ的使用(基于Maven)

首先要再回头看看JMS中的一些关键接口。

  • ConnectionFactory:用于创建连接到消息中间件的连接工厂。
  • Connection:代表了应用程序和服务之间的连接通路。
  • Destination:指消息发布的地点,包括队列模式和主体模式。
  • Session:表示一个单线程的上下文,用于发送和接受消息。
  • MessageConsumer:由会话创建,用于接受发送到目的的消息。
  • MessageProducer:由会话创建,用于发送消息。
  • Message:是在消费者和生产者之间传递的对象,消息头,一组消息属性,和一个消息体。
    这里写图片描述
    环境:IDEA
    步骤:
    1. 使用IDEA创建一个Maven项目,最简单的骨架即可(quick)
    2. 导入ActiveMq的依赖
<!--添加activemq的依赖-->
    <dependency>
      <groupId>org.apache.activemq</groupId>
      <artifactId>activemq-all</artifactId>
      <version>5.9.0</version>
    </dependency>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

情形一:队列模型的消息

  1. 编写生产者代码(使用队列模型的消息)
package com.hnu.scw.queue;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
/**
 * @ Author     :scw
 * @ Date       :Created in 上午 11:06 2018/7/14 0014
 * @ Description:用于消息的创建类
 * @ Modified By:
 * @Version: $version$
 */
public class MessageProducer {
    //定义ActivMQ的连接地址
    private static final String ACTIVEMQ_URL = "tcp://127.0.0.1:61616";
    //定义发送消息的队列名称
    private static final String QUEUE_NAME = "MyMessage";

    public static void main(String[] args) throws JMSException {
        //创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
       //创建连接
        Connection connection = activeMQConnectionFactory.createConnection();
        //打开连接
        connection.start();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建队列目标
        Destination destination = session.createQueue(QUEUE_NAME);
        //创建一个生产者
        javax.jms.MessageProducer producer = session.createProducer(destination);
        //创建模拟100个消息
        for (int i = 1 ; i <= 100 ; i++){
            TextMessage message = session.createTextMessage("我发送message:" + i);
            //发送消息
            producer.send(message);
            //在本地打印消息
            System.out.println("我现在发的消息是:" + message.getText());
        }
        //关闭连接
        connection.close();
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  1. 查看是否消息产生成功
    这里写图片描述
  2. 编写消费者代码(消费队列模型的消息)
package com.hnu.scw.queue;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
/**
 * @ Author     :scw
 * @ Date       :Created in 上午 11:30 2018/7/14 0014
 * @ Description:消息消费者
 * @ Modified By:
 * @Version: $version$
 */
public class MessageConsumer {
    //定义ActivMQ的连接地址
    private static final String ACTIVEMQ_URL = "tcp://127.0.0.1:61616";
    //定义发送消息的队列名称
    private static final String QUEUE_NAME = "MyMessage";
    public static void main(String[] args) throws JMSException {
        //创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //创建连接
        Connection connection = activeMQConnectionFactory.createConnection();
        //打开连接
        connection.start();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建队列目标
        Destination destination = session.createQueue(QUEUE_NAME);
        //创建消费者
        javax.jms.MessageConsumer consumer = session.createConsumer(destination);
        //创建消费的监听
        consumer.setMessageListener(new MessageListener() {
            @Override
            public void onMessage(Message message) {
                TextMessage textMessage = (TextMessage) message;
                try {
                    System.out.println("获取消息:" + textMessage.getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  1. 查看是否进行了消费
    这里写图片描述
    备注:我上面进行的是队列模式的消息,而且进行的都是单个消费者,那如果我换成同时有两个消费者消费生产者的消息会怎么样呢?(我们只需要运行两个消费者就可以啦。当然,要保证生产者是产生了消息的哦~~~~否则,拿什么消费呢~)
    一个生产者,两个消费者的情况如下:
    切记:先运行两个消费者,然后再运行生产者代码:
    结果如下:
    这里写图片描述
    这里写图片描述

其实,这就是解释了,我之前说的,队列模式的消息,是只会被一个消费者所使用的,而不会被共享,这也就是和主题模型的差别哦~哈哈~~

情形二:主题模型的消息

前面的步骤都一样,只是生产者和消费者的代码有点区别:
3. 编写生产者(这个和队列模型其实很像,稍微修改就可以)

package com.hnu.scw.topic;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/**
 * @ Author     :scw
 * @ Date       :Created in 上午 11:48 2018/7/14 0014
 * @ Description:${description}
 * @ Modified By:
 * @Version: $version$
 */
public class MessageTopicProducer {

    //定义ActivMQ的连接地址
    private static final String ACTIVEMQ_URL = "tcp://127.0.0.1:61616";
    //定义发送消息的主题名称
    private static final String TOPIC_NAME = "MyTopicMessage";

    public static void main(String[] args) throws JMSException {
        //创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //创建连接
        Connection connection = activeMQConnectionFactory.createConnection();
        //打开连接
        connection.start();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建队列目标
        Destination destination = session.createTopic(TOPIC_NAME);
        //创建一个生产者
        javax.jms.MessageProducer producer = session.createProducer(destination);
        //创建模拟100个消息
        for (int i = 1; i <= 100; i++) {
            TextMessage message = session.createTextMessage("当前message是(主题模型):" + i);
            //发送消息
            producer.send(message);
            //在本地打印消息
            System.out.println("我现在发的消息是:" + message.getText());
        }
        //关闭连接
        connection.close();
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  1. 查看生产者的消息
    这里写图片描述
  2. 编写消费者
package com.hnu.scw.topic;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/**
 * @ Author     :scw
 * @ Date       :Created in 上午 11:50 2018/7/14 0014
 * @ Description:${description}
 * @ Modified By:
 * @Version: $version$
 */
public class MessageTopicConsumer {
    //定义ActivMQ的连接地址
    private static final String ACTIVEMQ_URL = "tcp://127.0.0.1:61616";
    //定义发送消息的队列名称
    private static final String TOPIC_NAME = "MyTopicMessage";
    public static void main(String[] args) throws JMSException {
        //创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //创建连接
        Connection connection = activeMQConnectionFactory.createConnection();
        //打开连接
        connection.start();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建队列目标
        Destination destination = session.createTopic(TOPIC_NAME);
        //创建消费者
        javax.jms.MessageConsumer consumer = session.createConsumer(destination);
        //创建消费的监听
        consumer.setMessageListener(new MessageListener() {
            @Override
            public void onMessage(Message message) {
                TextMessage textMessage = (TextMessage) message;
                try {
                    System.out.println("获取消息:" + textMessage.getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  1. 查看是否消费成功
    然而,我们运行消费者代码,发现怎么没有消息消费呢?????????
    其实,这就是主题模型的一个特点,如果消费者是在生产者产生消息之后来的,那么是不会对之前的消息进行消费的哦。。。现在知道它们的区别在哪了吧。
    如果,现在是两个消费者和一个生产者的主题模型又是怎么的结果呢?
    这里写图片描述
    这里写图片描述
    哎哟。。。。这种情况消费者都各自消费了所有的生产者的消息耶。。。。。这就是共享性消息的主题模式,这就是和队列模型的区别,,,大家好好的对比哦~~

ActiveMQ使用(基于Spring)

步骤:
1. 创建一个Maven项目(基于最简单的quick骨架即可)
2. 导入Spring和ActiveMQ的相关依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.hnu.scw</groupId>
  <artifactId>activemq</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>activemq</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <spring.version>4.2.5.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!--添加activemq的依赖-->
    <dependency>
      <groupId>org.apache.activemq</groupId>
      <artifactId>activemq-all</artifactId>
      <version>5.9.0</version>
    </dependency>

    <!--spring整合activemq所需要的依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jms</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.apache.activemq</groupId>
      <artifactId>activemq-core</artifactId>
      <version>5.7.0</version>
      <exclusions>
        <exclusion>
          <artifactId>spring-context</artifactId>
          <groupId>org.springframework</groupId>
        </exclusion>
      </exclusions>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  1. 编写生产者的配置文件.xml,取名为producer.xml
<?xml version="1.0" encoding="UTF-8" ?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd ">

    <context:annotation-config />

    <!--Activemq的连接工厂-->
    <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://127.0.0.1:61616" />
    </bean>
   <!--spring jms为我们提供的连接池 获取一个连接工厂-->
    <bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
        <property name="targetConnectionFactory" ref="targetConnectionFactory" />
    </bean>

    <!-- 消息目的地  点对点的模式-->
    <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg value="SpringActiveMQMsg"/>
    </bean>
    <!-- jms模板  用于进行消息发送-->
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="connectionFactory"/>
    </bean>
</beans>

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  1. 编写生产者的接口
package com.hnu.scw.spring;

/**
 * @ Author     :scw
 * @ Date       :Created in 下午 12:19 2018/7/14 0014
 * @ Description:生产者的接口
 * @ Modified By:
 * @Version: $version$
 */
public interface ProduceService {
    void sendMessage(String msg);
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  1. 编写生产者的实现
package com.hnu.scw.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import javax.annotation.Resource;
import javax.jms.*;

/**
 * @ Author     :scw
 * @ Date       :Created in 下午 2:21 2018/7/15 0015
 * @ Description:生产者的实现类
 * @ Modified By:
 * @Version: $version$
 */

public class ProduceServiceImpl implements ProduceService {
    @Autowired
    private JmsTemplate jmsTemplate;
    @Resource(name = "queueDestination")
    private Destination destination;

    /**
     * 发送消息
     * @param msg
     */
    @Override
    public void sendMessage(final String msg) {
        jmsTemplate.send(destination , new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                TextMessage textMessage = session.createTextMessage(msg);
                return textMessage;
            }
        });
        System.out.println("现在发送的消息为: " + msg);
    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  1. 将生产者的类添加到上述的配置文件中
<!--注入我们的生产者-->
    <bean class="com.hnu.scw.spring.ProduceServiceImpl"/>
 
 
  • 1
  • 2
  1. 编写生产者的测试类
package com.hnu.scw.spring;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @ Author     :scw
 * @ Date       :Created in 下午 2:27 2018/7/15 0015
 * @ Description:生产者的测试
 * @ Modified By:
 * @Version: $version$
 */
public class ProducerTest {
    public static void main(String[] args){
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("producer.xml");
        ProduceService bean = classPathXmlApplicationContext.getBean(ProduceService.class);
        //进行发送消息
        for (int i = 0; i < 100 ; i++) {
            bean.sendMessage("test" + i);
        }
        //当消息发送完后,关闭容器
        classPathXmlApplicationContext.close();
    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  1. 运行测试类,查看生产者是否产生消息成功
    这里写图片描述
    通过上述的界面,就可以看到自己配置的队列模式的消息产生成功。
  2. 编写消费者的消息监听类
  3. 编写消费者的配置文件,命名为consumer.xml
<?xml version="1.0" encoding="UTF-8" ?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd ">

    <context:annotation-config />

    <!--Activemq的连接工厂-->
    <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://127.0.0.1:61616" />
    </bean>
    <!--spring jms为我们提供的连接池 获取一个连接工厂-->
    <bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
        <property name="targetConnectionFactory" ref="targetConnectionFactory" />
    </bean>

    <!-- 消息目的地  点对点的模式-->
    <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg value="SpringActiveMQMsg"/>
    </bean>

    <!-- 配置消息监听器-->
    <bean id="consumerMessageListener" class="com.hnu.scw.spring.ComsumerMessageListener"/>
    <!--配置消息容器-->
    <bean id ="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <!--配置连接工厂-->
        <property name="connectionFactory" ref="connectionFactory"/>
        <!--配置监听的队列-->
        <property name="destination" ref="queueDestination"/>
        <!--配置消息监听器-->
        <property name="messageListener" ref="consumerMessageListener"/>
    </bean>
</beans>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  1. 编写测试文件,测试消费者消费消息是否成功
package com.hnu.scw.spring;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @ Author     :scw
 * @ Date       :Created in 下午 3:13 2018/7/15 0015
 * @ Description:消费者的测试
 * @ Modified By:
 * @Version: $version$
 */
public class ConsumerTest {
    public static void main(String[] args){
        //启动消费者
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("consumer.xml");
    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  1. 查看ActiveMQ网站具体消息情况
    这里写图片描述
    这里写图片描述
  2. ActiveMQ的队列模型就大功告成啦。。。。。。so easy!!!
    备注:上面都是进行的ActiveMQ的队列模型的配置,那么我们如果想进行主题模型的又是如何进行操作呢?其实也很简单,只需要修改生产者的xml文件里面的队列即可。比如如下代码:
<!-- 消息目的地  (主题模式)-->
    <!--<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQTopic">
        &lt;!&ndash;配置队列模型的消息名称&ndash;&gt;
        <constructor-arg value="SpringActiveMQMsgTopic"/>
    </bean>-->
 
 
  • 1
  • 2
  • 3
  • 4
  • 5

将上面的代码替换之前的就可以了。。。
总结:总的来说,基于Spring来使用消息队列还是非常方便的,这比我们正常进行JMS规范操作要简单很多,毕竟很多对象都是通过Spring的IOC进行容器管理了,所以,值得推荐使用哦~~~

ActiveMQ的集群

为什么要进行集群呢?

原因一:实现高可用:以排除单点故障所引起的服务终端。
原因二:实现负载均衡:以提升效率为更多的客户进行服务。

集群的方式有哪些?

方式一:客户端集群:多个客户端消费同一个队列。
方式二:Broker clusters:多个Broker之间同步消息。(实现负载均衡)
这里写图片描述
这个的实现原理主要是通过网络连接器来进行。
网络连接器:用于配置ActiveMQ服务器与服务器之间的网络通讯方式,用于服务器透析消息。主要分为静态连接和动态连接。
方式三:Master Slave :实现高可用。
这种方式的话,可以联想到Mysql的主从配置和Zookeeper的负载均衡的主竞争关系master。
我们在实际的开发中,一般都是将方式二和方式三进行集成,从而实现高可用和负载均衡。下面的话,我也就这样的配置思想来进行讲解:(通过三台服务器来模拟消息集群的实现)
这里写图片描述
其中的NodeB和NodeC就是一张Master/slave的关系。都可以成为主服务器。(只要它们某一个宕机,那么就会其余的一台就进行继续服务)

搭建步骤(基于Windows环境,而Linux环境也是一样的操作)

三台服务器的大体功能和描述:
这里写图片描述
由于自己没有三台服务器,所以就用自己的一台电脑来模拟三台消息服务器,其实这个就是假设有三个不同ActiveMQ消息服务器了。
1. 复制三个ActiveMQ的服务配置到一个公共目录
这里写图片描述
2. 修改activeMQA的配置文件
这里写图片描述
只需要在activemq.xml添加如下内容:

<networkConnectors>
        <networkConnector name="local_network" uri ="static:(tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)" />
    </networkConnectors>
 
 
  • 1
  • 2
  • 3
  1. 修改ActiveMQB的配置文件
    (1)首先在activemq,xml中添加如下内容:
<!--修改服务端口-->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61617?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
<networkConnectors>
       <networkConnector name="networktoA" uri="static:(tcp://127.0.0.1:61616)" />
    </networkConnectors>
<!--并修改下面这个标签的内容 , 作为B和C的共享文件,目录就是自己之前创建的一个文件(可以回看上面的整个结构)-->
<persistenceAdapter>
            <kahaDB directory="D:\Download\MQJiQun\shareDB"/>
        </persistenceAdapter>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

(2)修改jetty.xml内容,修改服务器的服务端口

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
             <!-- the default port number for the web console -->
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8162"/>
    </bean>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  1. 修改ActiveMQC的配置文件(其实类似和B一样,只是服务端口不一样)
    (1)修改activemq.xml中的内容
<!--修改服务端口-->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61618?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
<networkConnectors>
       <networkConnector name="networktoA" uri="static:(tcp://127.0.0.1:61616)" />
    </networkConnectors>
<!--并修改下面这个标签的内容 , 作为B和C的共享文件,目录就是自己之前创建的一个文件(可以回看上面的整个结构)-->
<persistenceAdapter>
            <kahaDB directory="D:\Download\MQJiQun\shareDB"/>
        </persistenceAdapter>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

(2)修改jetty.xml中的内容

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
             <!-- the default port number for the web console -->
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8163"/>
    </bean>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  1. 集群搭建完成~~~~

集群测试(基于IDEA编辑器+Maven)

步骤:
(1)创建Maven项目
(2)导入依赖

<!--添加activemq的依赖-->
    <dependency>
      <groupId>org.apache.activemq</groupId>
      <artifactId>activemq-all</artifactId>
      <version>5.9.0</version>
    </dependency>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

(3)编写生产者代码

package com.hnu.scw.queue;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
/**
 * @ Author     :scw
 * @ Date       :Created in 上午 11:06 2018/7/14 0014
 * @ Description:用于消息的创建类
 * @ Modified By:
 * @Version: $version$
 */
public class MessageProducer {
    //通过集群的方式进行消息服务器的管理(failover就是进行动态转移,当某个服务器宕机,
    // 那么就进行其他的服务器选择,randomize表示随机选择)
    private static final String ACTIVEMQ_URL = "failover:(tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)?randomize=true";
    //定义发送消息的队列名称
    private static final String QUEUE_NAME = "MyMessage";

    public static void main(String[] args) throws JMSException {
        //创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
       //创建连接
        Connection connection = activeMQConnectionFactory.createConnection();
        //打开连接
        connection.start();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建队列目标
        Destination destination = session.createQueue(QUEUE_NAME);
        //创建一个生产者
        javax.jms.MessageProducer producer = session.createProducer(destination);
        //创建模拟100个消息
        for (int i = 1 ; i <= 100 ; i++){
            TextMessage message = session.createTextMessage("当前message是:" + i);
            //发送消息
            producer.send(message);
            //在本地打印消息
            System.out.println("我现在发的消息是:" + message.getText());
        }
        //关闭连接
        connection.close();
    }

}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

(4)编写消费者代码

package com.hnu.scw.queue;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/**
 * @ Author     :scw
 * @ Date       :Created in 上午 11:30 2018/7/14 0014
 * @ Description:消息消费者
 * @ Modified By:
 * @Version: $version$
 */
public class MessageConsumer {
    //通过集群的方式进行消息服务器的管理(failover就是进行动态转移,当某个服务器宕机,
    // 那么就进行其他的服务器选择,randomize表示随机选择)
    private static final String ACTIVEMQ_URL = "failover:(tcp://127.0.0.1:61616,tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)?randomize=true";
    //定义发送消息的队列名称
    private static final String QUEUE_NAME = "MyMessage";

    public static void main(String[] args) throws JMSException {
        //创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //创建连接
        Connection connection = activeMQConnectionFactory.createConnection();
        //打开连接
        connection.start();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建队列目标
        Destination destination = session.createQueue(QUEUE_NAME);
        //创建消费者
        javax.jms.MessageConsumer consumer = session.createConsumer(destination);
        //创建消费的监听
        consumer.setMessageListener(new MessageListener() {
            @Override
            public void onMessage(Message message) {
                TextMessage textMessage = (TextMessage) message;
                try {
                    System.out.println("获取消息:" + textMessage.getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        });
    }

}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

(5)进行查看各自的服务器的消息队列的情况。
1. 首先,是要确保三个ActiveMQ服务器都进行打开。分析:当三个都服务都运行之后,我们从浏览器运行各自的地址,会发现:
比如:我这里的三个服务的地址分别如下:

重点

为什么前面两个都可以访问,而第三个不可以呢?(同样也是按照我的这样的服务器打开方式哦。先打开的服务器A,接着B,最后C)但是,运行的时候,提示都成功了呀。。为什么为什么???
分析:其实很简单,我说过B和C是一种master/slave的方式,当B运行之后就获得了master的权限,那么C服务是可以看到是一种监听的状态,只有当B宕机之后,才有可能获取master的资源权限,所以,这时候C的地址当然就无法访问啦。这就是负载均衡的一种主/从服务的结构。当然,你可以试着先打开C,再打开B,这时候效果就反过来了。欢迎尝试哦~~~

2. 再运行MessageProducer的类,用于产生消息。这时候,大家可以去查看每个服务器的地址,来观察消息的产生情况。我的如下:
这里写图片描述
我的消息是产生在服务器B的里面啦。。。。。。
3. 再运行MessageConsumer的类,用于消费消息。这时候,同样可以去查看每个服务器的地址中的消息队列的情况,来观察消息的消费情况。我的如下:
这里写图片描述
4. 如果,我们在生产者产生了消息之后,服务器B突然宕机了怎么办怎么办??
分析:其实,这时候服务器C就一样有消息保存进行同步了。。是不是这样就是一种高可用的架构了呢????大家,可以试试哦。。把B服务器关掉,再去访问服务器C的地址,就发现如下的结果。
这里写图片描述
这时候服务器C就作为了master,所以,类似zookeeper就是这样的一种方式的哦。~

总结

好了,对于集群方面的简单使用就到这里了。其实已经可以根据这个进行扩展了,所以,小伙伴要好好理解这里面的过程和作用,这样才能够学以致用。。。

其他的消息中间件

其实,类似ActiveMQ这样的消息中间件,用得比较多的还有就是RabbitMQ和Kafka。它们三者各自有各自的优势。大家可以百度进行了解,我就不进行多说了。后面我会同样把这两种消息中间件的使用进行详细的讲解,欢迎大家的关注哦~总的来说,只有适合的场景对应的消息中间件才能发挥最大的作用,没有一种是只有好处而没有坏处的~

总结

  • 主要是对消息中间件的基础知识进行讲解。
  • 主要讲解ActiveMQ的使用
  • 主要讲解了关于ActiveMQ的集群的搭建
  • 稍微提到了类似ActiveMQ消息中间件的其他中间件
  • 我所讲述的内容,够大家进行入门了,如果要进行深入的了解还是需要慢慢的去熟悉和学习的,而且消息中间件是非常重要的一个技术,希望大家去好好的了解。
  • 最后,感谢各位的阅读哦~~~~
<div class="comment-edit-box d-flex">
	<a id="commentsedit"></a>
	<div class="user-img">
		<a href="//me.csdn.net/LeBronJames2" target="_blank">
			<img class="" src="https://avatar.csdn.net/A/8/7/3_lebronjames2.jpg">
		</a>
	</div>
	<form id="commentform">
		<input type="hidden" id="comment_replyId">
		<textarea class="comment-content" name="comment_content" id="comment_content" placeholder="想对作者说点什么"></textarea>
		<div class="opt-box"> <!-- d-flex -->
			<div id="ubbtools" class="add_code">
				<a href="#insertcode" code="code" target="_self"><i class="icon iconfont icon-daima"></i></a>
			</div>
			<input type="hidden" id="comment_replyId" name="comment_replyId">
			<input type="hidden" id="article_id" name="article_id" value="81040834">
			<input type="hidden" id="comment_userId" name="comment_userId" value="">
			<input type="hidden" id="commentId" name="commentId" value="">
			<div style="display: none;" class="csdn-tracking-statistics tracking-click" data-mod="popu_384"><a href="#" target="_blank" class="comment_area_btn">发表评论</a></div>
			<div class="dropdown" id="myDrap">
				<a class="dropdown-face d-flex align-items-center" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
				<div class="txt-selected text-truncate">添加代码片</div>
				<svg class="icon d-block" aria-hidden="true">
					<use xlink:href="#csdnc-triangledown"></use>
				</svg>
				</a>
				<ul class="dropdown-menu" id="commentCode" aria-labelledby="drop4">
					<li><a data-code="html">HTML/XML</a></li>
					<li><a data-code="objc">objective-c</a></li>
					<li><a data-code="ruby">Ruby</a></li>
					<li><a data-code="php">PHP</a></li>
					<li><a data-code="csharp">C</a></li>
					<li><a data-code="cpp">C++</a></li>
					<li><a data-code="javascript">JavaScript</a></li>
					<li><a data-code="python">Python</a></li>
					<li><a data-code="java">Java</a></li>
					<li><a data-code="css">CSS</a></li>
					<li><a data-code="sql">SQL</a></li>
					<li><a data-code="plain">其它</a></li>
				</ul>
			</div>  
			<div class="right-box">
				<span id="tip_comment" class="tip">还能输入<em>1000</em>个字符</span>
				<input type="submit" class="btn btn-sm btn-red btn-comment" value="发表评论">
			</div>
		</div>
	</form>
</div>

	<div class="comment-list-container">
	<a id="comments"></a>
	<div class="comment-list-box">
	</div>
	<div id="commentPage" class="pagination-box d-none"></div>
	
</div>
<div class="recommend-item-box recommend-ad-box"><div id="_0lvrana0whq"><iframe scrolling="no" src="https://pos.baidu.com/s?hei=60&amp;wid=852&amp;di=u3491668&amp;ltu=https%3A%2F%2Fblog.csdn.net%2Fcs_hnu_scw%2Farticle%2Fdetails%2F81040834&amp;psi=e9c46624f4a7deefdb4251341608ba95&amp;ps=30724x402&amp;drs=1&amp;cec=UTF-8&amp;tpr=1560915529891&amp;tcn=1560915530&amp;pcs=1349x632&amp;dc=3&amp;ant=0&amp;cce=true&amp;dri=0&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DEmjQQx4B1SAA0L1DcwtFl5kTl1fDWtnFkSlaJLbcY-z8YKseYeGxChh0rV2qpg9AynuYepmWA3c3qmfSg_84CfBbcT0hvAPrxpXracilbiO%26wd%3D%26eqid%3Db32fc732003aa805000000035d0989aa&amp;psr=1366x768&amp;dtm=HTML_POST&amp;tlm=1560915529&amp;ari=2&amp;chi=2&amp;ccd=24&amp;cja=false&amp;cfv=0&amp;col=zh-CN&amp;exps=111000,110011&amp;dai=2&amp;dis=0&amp;prot=2&amp;cmi=0&amp;pss=1349x31192&amp;par=1366x728&amp;pis=-1x-1&amp;cdo=-1&amp;ti=(8%E6%9D%A1%E6%B6%88%E6%81%AF)%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E5%A6%82%E4%BD%95%E7%8E%A9%E8%BD%AC%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6%EF%BC%88ActiveMQ%EF%BC%89%20-%20Cs_hnu_scw%E7%9A%84%E5%8D%9A%E5%AE%A2%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;cpl=0" width="852" height="60" frameborder="0"></iframe></div><script type="text/javascript" src="//rabc1.iteye.com/production/res/rxjg.js?pkcgstj=jm"></script></div>
<div class="recommend-item-box recommend-ad-box"><div id="_mky0b4g76t"><iframe scrolling="no" src="https://pos.baidu.com/s?hei=60&amp;wid=852&amp;di=u3491668&amp;ltu=https%3A%2F%2Fblog.csdn.net%2Fcs_hnu_scw%2Farticle%2Fdetails%2F81040834&amp;psi=e9c46624f4a7deefdb4251341608ba95&amp;ti=(8%E6%9D%A1%E6%B6%88%E6%81%AF)%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E5%A6%82%E4%BD%95%E7%8E%A9%E8%BD%AC%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6%EF%BC%88ActiveMQ%EF%BC%89%20-%20Cs_hnu_scw%E7%9A%84%E5%8D%9A%E5%AE%A2%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;cpl=0&amp;prot=2&amp;dis=0&amp;cja=false&amp;cfv=0&amp;ps=31205x402&amp;dtm=HTML_POST&amp;col=zh-CN&amp;tlm=1560915529&amp;tcn=1560915530&amp;cdo=-1&amp;tpr=1560915529891&amp;dc=3&amp;dri=1&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DEmjQQx4B1SAA0L1DcwtFl5kTl1fDWtnFkSlaJLbcY-z8YKseYeGxChh0rV2qpg9AynuYepmWA3c3qmfSg_84CfBbcT0hvAPrxpXracilbiO%26wd%3D%26eqid%3Db32fc732003aa805000000035d0989aa&amp;dai=3&amp;pcs=1349x632&amp;chi=2&amp;psr=1366x768&amp;cce=true&amp;ari=2&amp;pss=1349x31259&amp;par=1366x728&amp;cmi=0&amp;drs=1&amp;pis=-1x-1&amp;ant=0&amp;cec=UTF-8&amp;ccd=24&amp;exps=111000,116009,110011" width="852" height="60" frameborder="0"></iframe></div><script type="text/javascript" src="//rabc1.iteye.com/production/res/rxjg.js?pkcgstj=jm"></script></div>
		<div class="recommend-item-box blog-expert-recommend-box" style="">
		<div class="d-flex">
			<div class="blog-expert-recommend">
				<div class="blog-expert">
					<div class="blog-expert-flexbox"></div>
				</div>
			</div>
		</div>
	</div>
<div class="recommend-item-box recommend-ad-box"><div id="_k8xs8jpahg"><iframe scrolling="no" src="https://pos.baidu.com/s?hei=60&amp;wid=852&amp;di=u3491668&amp;ltu=https%3A%2F%2Fblog.csdn.net%2Fcs_hnu_scw%2Farticle%2Fdetails%2F81040834&amp;psi=e9c46624f4a7deefdb4251341608ba95&amp;cfv=0&amp;cdo=-1&amp;exps=111000,110011&amp;prot=2&amp;cpl=0&amp;dtm=HTML_POST&amp;ti=(8%E6%9D%A1%E6%B6%88%E6%81%AF)%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E5%A6%82%E4%BD%95%E7%8E%A9%E8%BD%AC%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6%EF%BC%88ActiveMQ%EF%BC%89%20-%20Cs_hnu_scw%E7%9A%84%E5%8D%9A%E5%AE%A2%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;ari=2&amp;cja=false&amp;drs=1&amp;pcs=1349x632&amp;pss=1349x31739&amp;ant=0&amp;dri=2&amp;dai=4&amp;cce=true&amp;par=1366x728&amp;cec=UTF-8&amp;dis=0&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DEmjQQx4B1SAA0L1DcwtFl5kTl1fDWtnFkSlaJLbcY-z8YKseYeGxChh0rV2qpg9AynuYepmWA3c3qmfSg_84CfBbcT0hvAPrxpXracilbiO%26wd%3D%26eqid%3Db32fc732003aa805000000035d0989aa&amp;tpr=1560915529891&amp;psr=1366x768&amp;tcn=1560915530&amp;tlm=1560915529&amp;cmi=0&amp;dc=3&amp;chi=2&amp;ccd=24&amp;pis=-1x-1&amp;col=zh-CN&amp;ps=31686x402" width="852" height="60" frameborder="0"></iframe></div><script type="text/javascript" src="//rabc1.iteye.com/production/res/rxjg.js?pkcgstj=jm"></script></div>
<div class="recommend-item-box recommend-ad-box"><div><iframe scrolling="no" src="//pos.baidu.com/s?hei=60&amp;wid=852&amp;di=u3491668&amp;ltu=https%3A%2F%2Fblog.csdn.net%2Fcs_hnu_scw%2Farticle%2Fdetails%2F81040834&amp;psi=e9c46624f4a7deefdb4251341608ba95&amp;ant=0&amp;tpr=1560915529891&amp;dc=3&amp;dai=5&amp;cfv=0&amp;ccd=24&amp;exps=111000,110011&amp;psr=1366x768&amp;ti=(8%E6%9D%A1%E6%B6%88%E6%81%AF)%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E5%A6%82%E4%BD%95%E7%8E%A9%E8%BD%AC%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6%EF%BC%88ActiveMQ%EF%BC%89%20-%20Cs_hnu_scw%E7%9A%84%E5%8D%9A%E5%AE%A2%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;col=zh-CN&amp;dis=0&amp;par=1366x728&amp;cpl=0&amp;ps=32167x402&amp;chi=2&amp;drs=1&amp;cdo=-1&amp;cce=true&amp;ari=2&amp;pss=1349x32220&amp;tcn=1560915530&amp;tlm=1560915530&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DEmjQQx4B1SAA0L1DcwtFl5kTl1fDWtnFkSlaJLbcY-z8YKseYeGxChh0rV2qpg9AynuYepmWA3c3qmfSg_84CfBbcT0hvAPrxpXracilbiO%26wd%3D%26eqid%3Db32fc732003aa805000000035d0989aa&amp;dri=3&amp;pcs=1349x632&amp;cmi=0&amp;dtm=HTML_POST&amp;cja=false&amp;prot=2&amp;cec=UTF-8&amp;pis=-1x-1" width="852" height="60" frameborder="0"></iframe></div><script type="text/javascript" src="//rabc1.iteye.com/production/res/rxjg.js?pkcgstj=jm"></script></div>
<div class="recommend-item-box recommend-ad-box"><div id="_wkn5rp0wfu7"><iframe scrolling="no" src="https://pos.baidu.com/s?hei=60&amp;wid=852&amp;di=u3491668&amp;ltu=https%3A%2F%2Fblog.csdn.net%2Fcs_hnu_scw%2Farticle%2Fdetails%2F81040834&amp;psi=e9c46624f4a7deefdb4251341608ba95&amp;tpr=1560915529891&amp;ari=2&amp;pis=-1x-1&amp;cja=false&amp;exps=111000,115009,110011&amp;dc=3&amp;pss=1349x32701&amp;cce=true&amp;tlm=1560915530&amp;prot=2&amp;col=zh-CN&amp;chi=2&amp;dri=4&amp;cfv=0&amp;cdo=-1&amp;ps=32648x402&amp;par=1366x728&amp;ccd=24&amp;cpl=0&amp;cmi=0&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DEmjQQx4B1SAA0L1DcwtFl5kTl1fDWtnFkSlaJLbcY-z8YKseYeGxChh0rV2qpg9AynuYepmWA3c3qmfSg_84CfBbcT0hvAPrxpXracilbiO%26wd%3D%26eqid%3Db32fc732003aa805000000035d0989aa&amp;dai=6&amp;dtm=HTML_POST&amp;dis=0&amp;ant=0&amp;ti=(8%E6%9D%A1%E6%B6%88%E6%81%AF)%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E5%A6%82%E4%BD%95%E7%8E%A9%E8%BD%AC%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6%EF%BC%88ActiveMQ%EF%BC%89%20-%20Cs_hnu_scw%E7%9A%84%E5%8D%9A%E5%AE%A2%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;pcs=1349x632&amp;cec=UTF-8&amp;tcn=1560915530&amp;drs=1&amp;psr=1366x768" width="852" height="60" frameborder="0"></iframe><ins id="nwlkzflaoj" style="display:none;"></ins></div><script type="text/javascript" src="//rabc1.iteye.com/production/res/rxjg.js?pkcgstj=jm"></script></div>
<div class="recommend-item-box recommend-ad-box"><div><iframe scrolling="no" src="//pos.baidu.com/s?hei=60&amp;wid=852&amp;di=u3491668&amp;ltu=https%3A%2F%2Fblog.csdn.net%2Fcs_hnu_scw%2Farticle%2Fdetails%2F81040834&amp;psi=e9c46624f4a7deefdb4251341608ba95&amp;cfv=0&amp;exps=111000,110011&amp;ti=(8%E6%9D%A1%E6%B6%88%E6%81%AF)%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E5%A6%82%E4%BD%95%E7%8E%A9%E8%BD%AC%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6%EF%BC%88ActiveMQ%EF%BC%89%20-%20Cs_hnu_scw%E7%9A%84%E5%8D%9A%E5%AE%A2%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;pcs=1349x632&amp;cce=true&amp;cmi=0&amp;cja=false&amp;dc=3&amp;psr=1366x768&amp;cdo=-1&amp;col=zh-CN&amp;tpr=1560915529891&amp;tlm=1560915530&amp;ant=0&amp;par=1366x728&amp;dai=7&amp;ccd=24&amp;ps=33128x402&amp;tcn=1560915530&amp;chi=2&amp;dtm=HTML_POST&amp;cpl=0&amp;drs=1&amp;dri=5&amp;ari=2&amp;prot=2&amp;dis=0&amp;pis=-1x-1&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DEmjQQx4B1SAA0L1DcwtFl5kTl1fDWtnFkSlaJLbcY-z8YKseYeGxChh0rV2qpg9AynuYepmWA3c3qmfSg_84CfBbcT0hvAPrxpXracilbiO%26wd%3D%26eqid%3Db32fc732003aa805000000035d0989aa&amp;pss=1349x33182&amp;cec=UTF-8" width="852" height="60" frameborder="0"></iframe></div><script type="text/javascript" src="//rabc1.iteye.com/production/res/rxjg.js?pkcgstj=jm"></script></div>
<div class="recommend-item-box recommend-ad-box"><div id="_ppo6bkgccfm"><iframe scrolling="no" src="https://pos.baidu.com/s?hei=60&amp;wid=852&amp;di=u3491668&amp;ltu=https%3A%2F%2Fblog.csdn.net%2Fcs_hnu_scw%2Farticle%2Fdetails%2F81040834&amp;psi=e9c46624f4a7deefdb4251341608ba95&amp;cpl=0&amp;dri=6&amp;pss=1396x33684&amp;chi=2&amp;cce=true&amp;drs=1&amp;col=zh-CN&amp;tpr=1560915529891&amp;psr=1366x768&amp;par=1366x728&amp;ti=(8%E6%9D%A1%E6%B6%88%E6%81%AF)%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E5%A6%82%E4%BD%95%E7%8E%A9%E8%BD%AC%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6%EF%BC%88ActiveMQ%EF%BC%89%20-%20Cs_hnu_scw%E7%9A%84%E5%8D%9A%E5%AE%A2%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;dc=3&amp;cja=false&amp;tcn=1560915530&amp;ant=0&amp;ari=2&amp;dai=8&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DEmjQQx4B1SAA0L1DcwtFl5kTl1fDWtnFkSlaJLbcY-z8YKseYeGxChh0rV2qpg9AynuYepmWA3c3qmfSg_84CfBbcT0hvAPrxpXracilbiO%26wd%3D%26eqid%3Db32fc732003aa805000000035d0989aa&amp;prot=2&amp;dtm=HTML_POST&amp;exps=111000,115009,110011&amp;cec=UTF-8&amp;cdo=-1&amp;tlm=1560915530&amp;pis=-1x-1&amp;dis=0&amp;pcs=1349x615&amp;ccd=24&amp;cmi=0&amp;cfv=0&amp;ps=33630x402" width="852" height="60" frameborder="0"></iframe><div class="cosupbocuw" style="width:0px;height:0px;padding-top:0px;"></div></div><script type="text/javascript" src="//rabc1.iteye.com/production/res/rxjg.js?pkcgstj=jm"></script></div>
<div class="recommend-item-box recommend-ad-box"><div id="_0nch3zave1ph"><iframe scrolling="no" src="https://pos.baidu.com/s?hei=60&amp;wid=852&amp;di=u3491668&amp;ltu=https%3A%2F%2Fblog.csdn.net%2Fcs_hnu_scw%2Farticle%2Fdetails%2F81040834&amp;psi=e9c46624f4a7deefdb4251341608ba95&amp;psr=1366x768&amp;par=1366x728&amp;pss=1396x34186&amp;cpl=0&amp;ti=(8%E6%9D%A1%E6%B6%88%E6%81%AF)%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E5%A6%82%E4%BD%95%E7%8E%A9%E8%BD%AC%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6%EF%BC%88ActiveMQ%EF%BC%89%20-%20Cs_hnu_scw%E7%9A%84%E5%8D%9A%E5%AE%A2%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;ccd=24&amp;tpr=1560915529891&amp;dri=7&amp;dtm=HTML_POST&amp;dc=3&amp;ari=2&amp;ps=34132x402&amp;cfv=0&amp;dai=9&amp;drs=1&amp;prot=2&amp;tcn=1560915530&amp;chi=2&amp;cmi=0&amp;cec=UTF-8&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DEmjQQx4B1SAA0L1DcwtFl5kTl1fDWtnFkSlaJLbcY-z8YKseYeGxChh0rV2qpg9AynuYepmWA3c3qmfSg_84CfBbcT0hvAPrxpXracilbiO%26wd%3D%26eqid%3Db32fc732003aa805000000035d0989aa&amp;col=zh-CN&amp;pcs=1349x615&amp;ant=0&amp;cce=true&amp;tlm=1560915530&amp;cja=false&amp;pis=-1x-1&amp;dis=0&amp;cdo=-1&amp;exps=111000,110011" width="852" height="60" frameborder="0"></iframe></div><script type="text/javascript" src="//rabc1.iteye.com/production/res/rxjg.js?pkcgstj=jm"></script></div>
<div class="recommend-item-box recommend-ad-box"><div id="_1fdvswp30u9" style="width: 100%;"><iframe scrolling="no" src="https://pos.baidu.com/s?hei=60&amp;wid=852&amp;di=u3491668&amp;ltu=https%3A%2F%2Fblog.csdn.net%2Fcs_hnu_scw%2Farticle%2Fdetails%2F81040834&amp;psi=e9c46624f4a7deefdb4251341608ba95&amp;dtm=HTML_POST&amp;par=1366x728&amp;ps=34613x402&amp;tcn=1560915530&amp;cfv=0&amp;pis=-1x-1&amp;dc=3&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DEmjQQx4B1SAA0L1DcwtFl5kTl1fDWtnFkSlaJLbcY-z8YKseYeGxChh0rV2qpg9AynuYepmWA3c3qmfSg_84CfBbcT0hvAPrxpXracilbiO%26wd%3D%26eqid%3Db32fc732003aa805000000035d0989aa&amp;cpl=0&amp;psr=1366x768&amp;tpr=1560915529891&amp;tlm=1560915530&amp;ti=(8%E6%9D%A1%E6%B6%88%E6%81%AF)%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E5%A6%82%E4%BD%95%E7%8E%A9%E8%BD%AC%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6%EF%BC%88ActiveMQ%EF%BC%89%20-%20Cs_hnu_scw%E7%9A%84%E5%8D%9A%E5%AE%A2%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;ccd=24&amp;dai=10&amp;pcs=1349x615&amp;cdo=-1&amp;dis=0&amp;pss=1396x34666&amp;cce=true&amp;drs=1&amp;exps=111000,110011&amp;ant=0&amp;cja=false&amp;chi=2&amp;ari=2&amp;prot=2&amp;col=zh-CN&amp;cmi=0&amp;cec=UTF-8&amp;dri=8" width="852" height="60" frameborder="0"></iframe><span style="display:none;text-align:left;"></span></div><script type="text/javascript" src="//rabc1.iteye.com/production/res/rxjg.js?pkcgstj=jm"></script></div><div class="recommend-item-box baiduSearch recommend-box-ident" data-track-view="{&quot;mod&quot;:&quot;popu_614&quot;,&quot;con&quot;:&quot;,https://blog.csdn.net/Cs_hnu_scw/article/details/79896500,searchFromBaidu1_0,-&quot;}" data-track-click="{&quot;mod&quot;:&quot;popu_614&quot;,&quot;con&quot;:&quot;,https://blog.csdn.net/Cs_hnu_scw/article/details/79896500,searchFromBaidu1_0,-&quot;}" data-flg="true">                <a href="https://blog.csdn.net/Cs_hnu_scw/article/details/79896500" target="_blank">              		<h4 class="text-truncate oneline" style="width: 754px;"><em>手把手</em><em>教你</em><em>如何</em><em>玩转</em>面试(操作系统) - Cs_hnu_scw的博客 - CSDN博客</h4>                  <div class="info-box d-flex align-content-center">                    <p>                      <span class="date">10-22</span>                    </p>                  </div>              		<p class="content oneline" style="width: 852px;">来自: Cs_hnu_scw的博客  下载  手把手教你构建自己的LINUX系统(高清完整版)...手把手教你如何玩转消息中间件(ActiveMQ)  手把手教你如何玩转Redis入门  个人...</p>                </a>            	</div><div class="recommend-item-box baiduSearch" data-track-click="{&quot;mod&quot;:&quot;popu_614&quot;,&quot;con&quot;:&quot;,https://blog.csdn.net/huxiangen/article/details/80997667,searchFromBaidu1_1,-&quot;}" data-flg="true">                <a href="https://blog.csdn.net/huxiangen/article/details/80997667" target="_blank">              		<h4 class="text-truncate oneline" style="width: 762px;"><em>消息中间件</em><em>ActiveMQ</em>简单示例 - 胡献根的博客 - CSDN博客</h4>                  <div class="info-box d-flex align-content-center">                    <p>                      <span class="date">11-7</span>                    </p>                  </div>              		<p class="content oneline" style="width: 852px;">1.下载ActiveMQ&nbsp;&nbsp;http://activemq.apache.org/download-archives.html 2....手把手教你如何玩转消息中间件(ActiveMQ) - cs_hnu_scw的博客(如果,你想学好...</p>                </a>            	</div>
<div class="recommend-item-box recommend-ad-box"><div id="_dbix6bn9t3j"><iframe scrolling="no" src="https://pos.baidu.com/s?hei=60&amp;wid=852&amp;di=u3491668&amp;ltu=https%3A%2F%2Fblog.csdn.net%2Fcs_hnu_scw%2Farticle%2Fdetails%2F81040834&amp;psi=e9c46624f4a7deefdb4251341608ba95&amp;exps=111000,115009,110011&amp;chi=2&amp;cmi=0&amp;cce=true&amp;tpr=1560915529891&amp;prot=2&amp;par=1366x728&amp;pis=-1x-1&amp;cfv=0&amp;dc=3&amp;ant=0&amp;psr=1366x768&amp;dai=11&amp;col=zh-CN&amp;cdo=-1&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DEmjQQx4B1SAA0L1DcwtFl5kTl1fDWtnFkSlaJLbcY-z8YKseYeGxChh0rV2qpg9AynuYepmWA3c3qmfSg_84CfBbcT0hvAPrxpXracilbiO%26wd%3D%26eqid%3Db32fc732003aa805000000035d0989aa&amp;cpl=0&amp;cja=false&amp;ti=(8%E6%9D%A1%E6%B6%88%E6%81%AF)%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E5%A6%82%E4%BD%95%E7%8E%A9%E8%BD%AC%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6%EF%BC%88ActiveMQ%EF%BC%89%20-%20Cs_hnu_scw%E7%9A%84%E5%8D%9A%E5%AE%A2%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;tcn=1560915530&amp;drs=1&amp;dtm=HTML_POST&amp;pcs=1349x615&amp;ari=2&amp;tlm=1560915530&amp;dri=9&amp;ccd=24&amp;dis=0&amp;cec=UTF-8&amp;pss=1396x35147&amp;ps=35094x402" width="852" height="60" frameborder="0"></iframe><span style="width:0px;height:0px;"></span></div><script type="text/javascript" src="//rabc1.iteye.com/production/res/rxjg.js?pkcgstj=jm"></script></div>
python图片处理类之~PIL.Image模块(ios android icon图标自动生成处理)

08-31 阅读数 11万+

1.从pyCharm提示下载PIL包

 http://www.pythonware.com/products/pil/

 

2.解压后,进入到目录下

cd /Users/jianan/Dow…


博文
来自: 专注于cocos+unity+服务器全栈



结果没有显示局域网的IP地址
2.我们去修改网卡配置文件,把网络连接打开
cd /
cd  /etc/sys…


博文
来自: sfeng95的博客



expat介绍文档翻译

03-22 阅读数 7万+

原文地址:http://www.xml.com/pub/a/1999/09/expat/index.html

因为需要用,所以才翻译了这个文档。但总归赖于英语水平很有限,翻译出来的中文有可能…


博文
来自: ymj7150697的专栏



演示效果 ↓

实现歌词动态调整功能
实现动态读取歌…


博文
来自: 月儿圆



微信支付V3微信公众号支付PHP教程(thinkPHP5公众号支付)/JSSDK的使用

02-02 阅读数 18万+

扫二维码关注,获取更多技术分享

本文承接之前发布的博客《 微信支付V3微信公众号支付PHP教程/thinkPHP5公众号支付》必须阅读上篇文章后才可以阅读这篇文章。由于最近一段时间工作比较忙,…


博文
来自: Marswill



Keil(MDK-ARM)系列教程(一)_新建软件工程详细过程

05-26 阅读数 6万+

推荐

分享一个大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到人工智能的队伍中来!http://www.captainbed.net/strongerhuang

推荐…


博文
来自: strongerHuang的专栏



jquery/js实现一个网页同时调用多个倒计时(最新的)

11-25 阅读数 54万+

jquery/js实现一个网页同时调用多个倒计时(最新的)

最近需要网页添加多个倒计时. 查阅网络,基本上都是千遍一律的不好用. 自己按需写了个.希望对大家有用. 有用请赞一个哦!

//js



博文
来自: Websites



VirtualBox COM获取对象失败

04-17 阅读数 4万+

错误详情

  1. 先来看看错误详情
    获取 VirtualBox COM 对象失败.应用程序将被中断.Failed to instantiate CLSID_VirtualBox …


    博文
    来自: 多点折腾少点抱怨

Solaris11挂载光盘

07-15 阅读数 1745

将ISO写入光盘 cdrecord sol-11_1-repo-full.iso

弹出光盘
root@solaris:/media# eject cdrom
cdrom /dev/dsk/c7t0d…


博文
来自: 数据之路-忆梦前程



.NET和java的RSA互通,仅此而已

03-09 阅读数 7万+

RSA .net jva 互通 解决不能互通的问题 博文 来自: lubiaopan的专栏

1…


博文
来自: 河西无名式



IE9 table显示问题,td出现错位的解决方法

01-21 阅读数 5461

IE9 table显示问题

IE9 大数据行table的显示会出现列错位

原因是IE9的BUG

在jsp中使用 table加载大数据量时,td会出现错位,在f…


博文
来自: yzp_soft的专栏



            <div class="recommend-item-box type_hot_word">
                            <div class="content clearfix" style="width: 852px;">
                <div class="word float-left">
                                                        <span>
                    <a href="https://edu.csdn.net/courses/o5329_s5330_k " target="_blank">
                    机器学习教程                    </a></span>
                                                                            <span>
                    <a href="https://edu.csdn.net/courses/o280_s351_k " target="_blank">
                    Objective-C培训                    </a></span>
                                                                            <span>
                    <a href="https://edu.csdn.net/combos/o7115_s388_l0_t " target="_blank">
                    交互设计视频教程                    </a></span>
                                                                            <span>
                    <a href="https://edu.csdn.net/course/play/5599/104252 " target="_blank">
                    颜色模型                    </a></span>
                                                                            <span>
                    <a href="https://edu.csdn.net/combos/o363_l0_t " target="_blank">
                    设计制作学习                    </a></span>
                                                        </div>
            </div>
                                            <div class="content clearfix" style="width: 852px;">
                <div class="float-left">
                                    <span>
                    <a href="https://www.csdn.net/gather_24/MtTaEg3sMDM5MS1ibG9n.html" target="_blank">
                    mysql关联查询两次本表</a>
                </span>
                                    <span>
                    <a href="https://www.csdn.net/gather_10/MtjaIg3sMTUzMy1kb3dubG9hZAO0O0OO0O0O.html" target="_blank">
                    native底部 react</a>
                </span>
                                    <span>
                    <a href="https://www.csdn.net/gather_1b/Ntzagg1sOTU3LWRvd25sb2Fk.html" target="_blank">
                    extjs glyph 图标</a>
                </span>
                                    <span>
                    <a href="https://www.csdn.net/gather_4a/MtzaEg5sOC1lZHUO0O0O.html" target="_blank">
                    手把手教你python</a>
                </span>
                                    <span>
                    <a href="https://www.csdn.net/gather_4a/MtjaQgwsOS1lZHUO0O0O.html" target="_blank">
                    教你学python</a>
                </span>
                                    </div>
            </div>
                            </div><div class="recommend-item-box baiduSearch" data-track-click="{&quot;mod&quot;:&quot;popu_614&quot;,&quot;con&quot;:&quot;,https://blog.csdn.net/tracydragonlxy/article/details/78786786,searchFromBaidu1_2,-&quot;}" data-flg="true">                <a href="https://blog.csdn.net/tracydragonlxy/article/details/78786786" target="_blank">              		<h4 class="text-truncate oneline" style="width: 754px;">Java<em>消息中间件</em>——<em>ActiveMQ</em>的安装教程 - tracy的博客 - CSDN博客</h4>                  <div class="info-box d-flex align-content-center">                    <p>                      <span class="date">11-17</span>                    </p>                  </div>              		<p class="content oneline" style="width: 852px;">手把手教你如何玩转消息中间件(ActiveMQ) - Cs_hnu_scw的博客  07-15 622  情景引入 情景分析 基本概念的引导 本模块主要讲解关于消息中间件的相关基础知识,也...</p>                </a>            	</div><div class="recommend-item-box baiduSearch" data-track-click="{&quot;mod&quot;:&quot;popu_614&quot;,&quot;con&quot;:&quot;,https://blog.csdn.net/cs_hnu_scw/article/details/78302536,searchFromBaidu1_3,-&quot;}" data-flg="true">                <a href="https://blog.csdn.net/cs_hnu_scw/article/details/78302536" target="_blank">              		<h4 class="text-truncate oneline" style="width: 754px;"><em>手把手</em><em>教你</em><em>如何</em><em>玩转</em>Maven - Cs_hnu_scw的博客 - CSDN博客</h4>                  <div class="info-box d-flex align-content-center">                    <p>                      <span class="date">10-16</span>                    </p>                  </div>              		<p class="content oneline" style="width: 852px;">https://blog.csdn.net/Cs_hnu_scw/article/details/78302536  &nbsp; &nbsp; 我...手把手教你如何玩转消息中间件(ActiveMQ)  手把手教你如何玩转Redis入门  手把手...</p>                </a>            	</div>
                        <div class="recommend-loading-box">
            <img src="https://csdnimg.cn/release/phoenix/images/feedLoading.gif">
        </div>
        <div class="recommend-end-box" style="display: block;">
            <p class="text-center">没有更多推荐了,<a href="https://blog.csdn.net/" class="c-blue c-blue-hover c-blue-focus">返回首页</a></p>
        </div>
    </div>
</main>
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值