Apache Camel系列(4)----Akka Camel

Akka是一個高性能,高容錯的的分佈式框架,並且對Camel也提供了很好的支持,下面創建一個Akka Camel的demo,運行環境:CentOS7 + IntelliJ + JDK8。這個demo分別創建一個Producer和Consumer,實現Redis的pub/sub功能。
 
1,創建Maven工程,加入dependencies,pom.xml文件如下:
 
複製代碼
<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-core</artifactId>
            <version>2.17.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-spring</artifactId>
            <version>2.17.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-spring-redis</artifactId>
            <version>2.17.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-stream</artifactId>
            <version>2.17.0</version>
        </dependency>
        <dependency>
            <groupId>com.typesafe.akka</groupId>
            <artifactId>akka-actor_2.11</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.typesafe.akka</groupId>
            <artifactId>akka-camel_2.11</artifactId>
            <version>2.4.0</version>
        </dependency>
    </dependencies>
複製代碼
2,分別創建MyRedisProducer和MyRedisConsumer類,這兩個類分別繼承akka提供的UntypedProducerActor和UntypedConsumerActor,用於產生和消費消息,代碼如下:
 
 
複製代碼
/**
 * Created by sam on 5/9/16.
 */
public class MyRedisProducer extends UntypedProducerActor {

    public void preStart() {
        super.preStart();
    }


    @Override
    public String getEndpointUri() {
        return "spring-redis://localhost:9999?connectionFactory=#connectionFactory&serializer=#serializer";
    }

    @Override
    public void onRouteResponse(Object message) {
        System.out.println("response from route:{}" + message);
    }

    @Override
    public Object onTransformOutgoingMessage(Object message) {
        if (message instanceof CamelMessage) {
            CamelMessage camelMessage = (CamelMessage) message;
            return camelMessage;
        } else {
            Map<String, Object> headers = new HashMap<String, Object>();
            headers.put("CamelRedis.Command", "PUBLISH");
            headers.put("CamelRedis.Channel", "testChannel");
            headers.put("CamelRedis.Message", message.toString());
            CamelMessage camelMessage = new CamelMessage(message, headers);
            return camelMessage;
        }
    }
}
複製代碼
在MyRedisProducer類中,需要預處理收到的消息,爲消息設置headers屬性,Camel Redis組件是根據headers屬性類執行命令的。
getEndpointUri中用到的connectionFactory和serializer,會在創建actor的時候進行定義。
 
 
複製代碼
/**
 * Created by sam on 5/9/16.
 */
public class MyRedisConsumer extends UntypedConsumerActor {


    @Override
    public String getEndpointUri() {
        return "spring-redis://localhost:9999?connectionFactory=#connectionFactory&serializer=#serializer&channels=testChannel&command=SUBSCRIBE";
    }

    @Override
    public void onReceive(Object o) throws Exception {
        System.out.println(o);
        if (o instanceof CamelMessage) {
            CamelMessage msg = (CamelMessage) o;
            System.out.println(msg.getBodyAs(String.class, getCamelContext()));
        }
    }
}
複製代碼
MyRedisConsumer會將接收到的消息放在message body中。
 
3,創建Actor,代碼如下:
複製代碼
/**
 * Created by sam on 5/9/16.
 */
public class RedisTest {
    public static void main(String[] args) throws Exception {
        ActorSystem system = ActorSystem.create("redis-actor");
        Camel camel = CamelExtension.get(system); // 獲取Camel對象,該對象可以直接操作Camel,比如獲取CamelContext對象等。
        PropertyPlaceholderDelegateRegistry delegateRegistry = (PropertyPlaceholderDelegateRegistry) camel.context().getRegistry();
        JndiRegistry registry = (JndiRegistry) delegateRegistry.getRegistry(); // Apache Camel默認使用JndiRegistry來註冊類信息。
        if (registry.lookup("connectionFactory") == null && registry.lookup("serializer") == null) {
            // 添加beans
            JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
            connectionFactory.setHostName("localhost");
            connectionFactory.setPassword("1234567890");
            connectionFactory.setPort(9999);
            // call this method to initialize connection factory
            connectionFactory.afterPropertiesSet();
            registry.bind("connectionFactory", connectionFactory);

            registry.bind("serializer", new StringRedisSerializer());
        }


        // 創建producer和consumer
        ActorRef producer = system.actorOf(Props.create(MyRedisProducer.class), "redisProducer");
        ActorRef consumer = system.actorOf(Props.create(MyRedisConsumer.class), "redisConsumer");


        while (true) {
            Thread.sleep(1000);
            producer.tell(new Date().toString(), ActorRef.noSender());
        }
    }
}
複製代碼
在這段代碼中,先獲得默認的JndiRegistry對象,並註冊connectionFactory和serializer beans,注意使用JndiRegistry時,需要在資源文件中添加jndi.properties文件,內容如下:
 
java.naming.factory.initial = org.apache.camel.util.jndi.CamelInitialContextFactory
最後使用producer來發送消息,在consumer中,會得到輸出,結果如下:
複製代碼
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
response from route:{}CamelMessage(null, Map())
CamelMessage(Thu May 12 09:38:04 CST 2016, Map(MessageExchangeId -> ID-localhost-localdomain-33258-1463017082575-0-2, breadcrumbId -> ID-localhost-localdomain-33258-1463017082575-0-1, CamelRedis.Channel -> testChannel, CamelRedis.Pattern -> [B@5910162e))
Thu May 12 09:38:04 CST 2016
response from route:{}CamelMessage(null, Map())
CamelMessage(Thu May 12 09:38:05 CST 2016, Map(MessageExchangeId -> ID-localhost-localdomain-33258-1463017082575-0-4, breadcrumbId -> ID-localhost-localdomain-33258-1463017082575-0-3, CamelRedis.Channel -> testChannel, CamelRedis.Pattern -> [B@4154c5ce))
Thu May 12 09:38:05 CST 2016
response from route:{}CamelMessage(null, Map())
CamelMessage(Thu May 12 09:38:06 CST 2016, Map(MessageExchangeId -> ID-localhost-localdomain-33258-1463017082575-0-6, breadcrumbId -> ID-localhost-localdomain-33258-1463017082575-0-5, CamelRedis.Channel -> testChannel, CamelRedis.Pattern -> [B@2cb03be0))
Thu May 12 09:38:06 CST 2016
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章