2016年8月24日星期三

EAP_052:默认加载了哪些 modules ?

环境:OS X EI Capitan 10.11.6 + JBoss EAP 6.4.0 + Redis 3.2.3

从上一篇文章,我们知道 JBoss EAP 默认加载了 resteasy module,从而导致了问题的出现。
那么,JBoss EAP 默认都加载了哪些 modules 呢?

修改 standalone.xml,在日志部分增加如下内容:
<logger category="org.jboss.as.server.deployment">
              <level name="DEBUG"/>
</logger>

在 server.log 中会看到类似下面的信息:
1:32:00,249 DEBUG [org.jboss.as.server.deployment] (MSC service thread 1-3) Adding dependency ModuleDependency [identifier=javax.ejb.api:main, moduleLoader=local module loader @5fa0f02a (finder: local module finder @3ef78672 (roots:

参考文献:
1. https://access.redhat.com/solutions/257633

Redis_001:MAC 下安装与启动

环境:MAC OS X 10.11.6 + Redis 3.2.3

1. Redis 官网:http://redis.io/

2. 安装 Redis
(1)tar xzf redis-3.2.3.tar.gz
(2)ln -s redis-3.2.3 redis
(3)cd redis
(4)make test
(5)make install

3. 运行 Redis
$ redis-server 
76457:C 24 Aug 20:05:36.134 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
76457:M 24 Aug 20:05:36.135 * Increased maximum number of open files to 10032 (it was originally set to 256).
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 3.2.3 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 76457
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

76457:M 24 Aug 20:05:36.136 # Server started, Redis version 3.2.3
76457:M 24 Aug 20:05:36.136 * The server is now ready to accept connections on port 6379


2016年8月19日星期五

ActiveMQ_043:设置 String Property 作为消息选择器

环境:MAC OS X 10.11.6 + ActiveMQ 5.13.4

发送消息时,message.setStringProperty() 方法可以设置某个属性及其值。
接收消息时,可以指定接收符合属性及其值的消息。

1. Queue_Selector_Sender_AutoAck_Peresistent.java

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;

public class Queue_Selector_Sender_AutoAck_Peresistent {

    //private static final int SEND_NUMBER = 1209600; // 每秒发送2条,发送7天
    private static final int SEND_NUMBER = 200; // 每秒发送2条,发送7天

    public static void main(String[] args) {

        // ConnectionFactory:连接工厂,JMS用它创建连接
        ConnectionFactory connectionFactory;
        // Connection:JMS客户端到JMS Provider的连接
        Connection connection = null;
        // Session:一个发送或接收消息的线程
        Session session;
        // Destination:消息的目的地
        Destination destination;
        // MessageProducer: 消息生产者
        MessageProducer producer;
        //构造ConnectionFactory实例对象,此处采用ActiveMq的实现
        connectionFactory = new ActiveMQConnectionFactory(
                "admin",
                "admin",
                "failover:(tcp://127.0.0.1:61616)");
            try {
            connection = connectionFactory.createConnection();
            connection.start();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            destination = session.createQueue("FirstQueue");
            producer = session.createProducer(destination);
            producer.setDeliveryMode(DeliveryMode.PERSISTENT);
            sendMessage(session, producer);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != connection) {
                    connection.close();
                }
            } catch (Throwable ignore) {
            }
        }
    }

    public static void sendMessage(Session session, MessageProducer producer)
            throws Exception {
        for (int i = 1; i <= SEND_NUMBER; i++) {
            TextMessage message = session
                    .createTextMessage("#### ActiveMq发送的消息" + i);
            if (i % 2 == 0) {
                message.setStringProperty("MessageGroupID", "A");
            } else {
                message.setStringProperty("MessageGroupID", "B");  

            }
            System.out.println(System.currentTimeMillis() + " 发送消息:" + "ActiveMq 发送的消息" + i);
            producer.send(message);        
        }
    }
}

2. Queue_Selector_Receiver_AutoAck_Async.java

import java.io.IOException;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;

public class Queue_Selector_Receiver_AutoAck_Async {

    public static void main(String[] args) {

        // ConnectionFactory:连接工厂,JMS用它创建连接
        ConnectionFactory connectionFactory;
        // Connection:JMS客户端到JMS Provider的连接
        Connection connection = null;
        // Session:一个发送或接收消息的线程
        Session session;
        // Destination:消息的目的地;消息发送给谁.
        Destination destination;
        // MessageConsumer:消息消费者
        MessageConsumer consumerA, consumerB;

        connectionFactory = new ActiveMQConnectionFactory(
                "admin",
                "admin",
                "failover:(tcp://127.0.0.1:61616)");
        try {
            connection = connectionFactory.createConnection();
            connection.start();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            destination = session.createQueue("FirstQueue");
           
            consumerA = session.createConsumer(destination, "MessageGroupID='A'");
            consumerA.setMessageListener(new MessageListener() {
                public void onMessage(Message message) {
                    TextMessage tm = (TextMessage) message;
                    try {
                        System.out.println("consumerA Received message: " + tm.getText());
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                }
            });
           
            consumerB = session.createConsumer(destination, "MessageGroupID='B'");
            consumerB.setMessageListener(new MessageListener() {
                public void onMessage(Message message) {
                    TextMessage tm = (TextMessage) message;
                    try {
                        System.out.println("consumerB Received message: " + tm.getText());
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                }
            });

            try {
                System.in.read();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != connection) {
                    connection.close();
                }
            } catch (Throwable ignore) {
            }
        }
    }
}

参考文献:
1. http://activemq.apache.org/selectors.html
2. http://blog.csdn.net/e_wsq/article/details/50053981
3. http://timjansen.github.io/jarfiller/guide/jms/selectors.xhtml

ActiveMQ_042:使用 RESTful API 读取消息

环境:MAC OS X 10.11.6 + ActiveMQ 5.13.4

ActiveMQ 支持使用 RESTful API 读取消息,因为它内置了一个 api 应用。

1. 启动 ActiveMQ
./bin/activemq start

2. 发送消息到 TEST Queue
(1)curl -u admin:admin -d "body=message" http://localhost:8161/api/message/TEST?type=queue
如果不加 ?type=queue,将会默认发到 TEST Topic 中。
如果想默认发到 Queue 中,需要修改 ./webapps/api/WEB-INF/web.xml:
<servlet>
  <servlet-name>MessageServlet</servlet-name> 
  <servlet-class>org.apache.activemq.web.MessageServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
  <init-param>
     <param-name>topic</param-name>
     <param-value>false</param-value>
  </init-param>
</servlet>

或者,也可以用以下两种方式发送消息:
(2)curl -XPOST -d "body=message" http://admin:admin@localhost:8161/api/message?destination=queue://orders.input
(3)curl -XPOST -d "body=message" http://admin:admin@localhost:8161/api/message?destination=topic://orders.input

3. 接收消息
(1)wget --user admin --password admin --save-cookies cookies.txt --load-cookies cookies.txt --keep-session-cookies  http://localhost:8161/api/message/TEST?type=queue
如果你希望同时有多个消费者使用 REST 消费消息,可以设置 prefetchSize=1,这样所有的消费者机会均等。
需要修改 ./webapps/api/WEB-INF/web.xml:
<servlet>
    <servlet-name>MessageServlet</servlet-name>
    <servlet-class>org.apache.activemq.web.MessageServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    <init-param>
            <param-name>destinationOptions</param-name>
            <param-value>consumer.prefetchSize=1</param-value>
    </init-param>
</servlet>

或者,也可以用以下两种方式接收消息: 
(2)curl -XGET http://admin:admin@localhost:8161/api/message?destination=queue://orders.input
(3)curl -XGET http://admin:admin@localhost:8161/api/message?destination=topic://orders.input

参考文献:
1. http://activemq.apache.org/rest.html

2016年8月13日星期六

Marathonn_010:2016吴哥窟马拉松

凌晨四点的一阵暴雨,让人感到一阵凉意和潮湿。
黑暗中,有人点燃了火把,队伍中有人开始兴奋地尖叫,终于,大部队开始前进了。
湿重的雾气穿过丛林,漫过王城的护城河,热带丛林中的水汽,在喉咙里凝成了水。

高大的乔木直插天空,大地四周的白云仿佛低矮了许多。
妖娆的藤蔓植物如鬼魅一般,缠绕着高大的乔木。
而王的宫殿,已经废弃了800年,被野蛮生长的植被不断侵蚀着,坍塌着。

原始森林中的巨石堆砌的一座座庙宇,千年之后,仍然让人感到神秘而有力量。
著名的吴哥的微笑,千百年来,不知道安抚了多少人的心灵。
五层巨石累积而成的建筑,基座呈波浪纹的外形,仿佛行于大海之上;层与层之间递进有序,每层皆有回廊环绕;最上层的如同佛头一般的金刚塔,有种坚不可摧的感觉;整体建筑风格,远观雄伟,近看精致,既刚且柔,前所未见,让人不由得感叹吴哥的建筑之美。
如同刺绣般的雕刻工艺,纷繁精美到了无以附添的程度,但却是刻在坚硬的石头上,让人不由得赞叹吴哥的雕刻之美。
究竟谁是文明的一方,谁是野蛮的一方?
难怪 1861年1月,法国生物学家亨利·穆奥发现吴哥窟后,这样描述他眼中的吴哥:
“此地庙宇之宏伟,远胜古希腊、罗马遗留给我们的一切,走出森森吴哥庙宇,重返人间,刹那间犹如从灿烂的文明堕入蛮荒。”

太阳升起来了,烈日开始炙烤大地,水气不断蒸腾,森林中湿热的气团开始包裹住我的身体。
终于,吴哥的微笑就在眼前,我抬头望见看见一百多面的笑容,闭上眼,一百多面的笑容浮现在心里。
刹那间,一种无以名状的平静穿胸而过。




行程安排:

2016年8月7日 吴哥窟马拉松

官方网址:http://www.angkorempiremarathon.org/index.php
比赛时间:2016年8月7日
报名时间:2016年5月7日
申请签证:https://www.evisa.gov.kh/
成绩查询:http://www.angkorempiremarathon.org/page.php?id=40

行程安排:

8月3日 北京 -> 广州
航程    航班号    出发城市                    到达城市                    起飞时间            到达当地时间        舱位
1    CZ1309    北京首都T3                广州(新白云)                2016-08-03 18:00    2016-08-03 21:20    经济舱

入住酒店:机场附近酒店 速8酒店(广州白云国际机场精品店)8月3日~8月4日

8月4日 广州 ->  暹粒
航程    航班号    出发城市                    到达城市                    起飞时间            到达当地时间        舱位
1    CZ3053    广州(新白云)                柬埔寨-暹粒(吴哥窟-I号航站楼)    2016-08-04 08:45    2016-08-04 10:25    经济舱

入住酒店:Angkor Paradise Hotel (暹粒吴哥天堂酒店)  8月4日~8月9日
Phum Sala Kanseng, Sangkat Svay Dangkoum, Angkor Paradise Hotel, National Route 6 (Airport Road), Krong Siem Reap 17000

租车联系人:小李(卡卡) 13809719792 微信号 kasia0860

8月4日 接机,下午崩密列
8月5日 吴哥寺日出--塔布笼寺--巴戎寺--吴哥寺--巴肯山及日落
8月6日 豆蔻寺--斑黛喀蒂寺、皇家浴池--比粒寺--塔逊寺--圣剑寺
8月7日 马拉松,博物馆
8月8日 女王宫--荔枝山--高布思滨

8月9日
航程    航班号    出发城市                    到达城市                    起飞时间            到达当地时间        舱位
1    CZ3054    柬埔寨-暹粒(吴哥窟-I号航站楼)    广州(新白云)                2016-08-09 11:30    2016-08-09 15:00    经济舱

广州白云机场 <-> 广州长隆酒店
路线一:地铁三号线→地铁二号线→长隆免费穿梭巴士
到地铁机场南站乘坐地铁三号线到地铁嘉禾望岗站,转乘地铁二号线到地铁会江站A口下,
往后走到长隆穿梭巴士地铁会江站转乘长隆免费穿梭巴士到香江野生动物世界正门(北门)总站下,往前走约120米到香江野生动物世界(正门)。
路线二:地铁3号线北延段→地铁3号线
到机场南站乘坐地铁3号线北延段在体育西路站下车,乘坐地铁3号线在汉溪长隆站下车,乘坐长隆免费巴士到香江动物园南门下车即可到达。

入住酒店:广州长隆酒店   8月9日~8月12日
长隆酒店太贵,建议入住洛溪食街附近性价比高的酒店。

8月12日 广州 ->  北京
航程    航班号    出发城市                    到达城市                    起飞时间            到达当地时间        舱位
1     CA1328     广州新白云                北京首都T3                 8月12日18:25        8月12日21:40         经济舱