vert.x筆記:5.vert.x集成dubbo服務

原文及更多文章請見我的博客:http://heartlifes.comjava

vert.xgit

基礎介紹:

dubbo是阿里巴巴內部的rpc遠程調用框架,和spring無縫對接,自帶loadbalance,是用來搭建soa服務架構的利器,惋惜據說在阿里內部鬥爭中,已經被hsf幹掉了。可是,對於咱們這種小企業來講,dubbo仍是搭建高可用服務的不二選擇。dubbo官方地址:http://dubbo.iogithub

vert.x+dubbo能夠搭建一個逼格很高的微服務架構,即vert.x用於發佈服務,經過事件總線,調用後端的dubbo業務處理服務。從而完成rest服務與業務代碼的完美解耦。web

本章基用到前序章節的全部知識,而且這裏將不會介紹dubbo服務的開發,默認你會玩dubbo服務。spring

pom中加入如下依賴:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>${dubbo.version}</version>
    <exclusions>
            <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.3.6</version>
    <exclusions>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>com.github.sgroschupf</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.1</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.1.41</version>
</dependency>
<dependency>
        <groupId>org.jboss.netty</groupId>
    <artifactId>netty</artifactId>
    <version>3.2.5.Final</version>
</dependency>

引用一個dubbo服務:

所謂集成dubbo,從本質來說就是配置dubbo服務,而且以xml形式集成spring。
咱們假設後臺有這麼一個dubbo服務,如今要在vert.x中調用,那麼咱們的作法和普通的dubbo consumer同樣,申明一個spring配置文件,並引用該服務。配置文件以下:數據庫

<?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:dubbo="http://code.alibabatech.com/schema/dubbo"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://code.alibabatech.com/schema/dubbo 
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd ">

    <!-- 使用Annotation自動註冊Bean,解決事物失效問題:在主容器中不掃描@Controller註解,在SpringMvc中只掃描@Controller註解。 -->
    <context:component-scan base-package="com"/>
    <dubbo:application name="demo-consumer" />
    <dubbo:registry address="multicast://224.5.6.7:1234" />
    <dubbo:protocol name="dubbo" host="127.0.0.1" port="20802"
        serialization="hessian2" threadpool="cached" threads="1000" />
    <!-- dubbo引用的服務 -->
    <dubbo:reference id="dubboService"
        interface="com.heartlifes.dubbo.DubboService" />
</beans>

建立SpringVerticle:

package com.heartlifes.vertx.demo.dubbo;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Handler;
import io.vertx.core.eventbus.Message;

import org.springframework.context.ApplicationContext;

public class SpringVerticle extends AbstractVerticle {

    private DubboService service;

    public static final String PRINT_MSG_SERVICE_ADDRESS = "print_msg_service_address";

    public static final String GET_MSG_SERVICE_ADDRESS = "get_msg_service_address";

    public SpringVerticle(ApplicationContext ctx) {
        // 從spring上下文獲取service
        this.service = (DubboService) ctx.getBean("dubboService");
    }

    @Override
    public void start() throws Exception {
        // 喚起事件總線,註冊一個事件處理者,或者直譯叫事件消費者
        vertx.eventBus().<String> consumer(PRINT_MSG_SERVICE_ADDRESS)
                .handler(msg -> {
                    // 獲取事件內容後,調用service服務
                    // 這裏是非阻塞式調用
                        service.printMsg("Asynchronous call dubbo service!!!");
                        msg.reply("success");
                    });

        vertx.eventBus().<String> consumer(GET_MSG_SERVICE_ADDRESS, printMsg());
    }

    // 模擬dubbo服務要從後臺數據庫獲取數據,因此這裏就是vert.x中的阻塞式調用
    // vert.x中規定,全部調用不能夠阻塞其eventloop,因此當有數據庫調用、thread.sleep等可能會阻塞線程的服務調動時
    // 須要使用vertx接口中的阻塞式調用接口
    private Handler<Message<String>> printMsg() {
        return msg -> {
            System.out.println("bus msg body is:" + msg.body());
            // 阻塞式接口調用
            vertx.<String> executeBlocking(future -> {
                // 經過future等待調用返回結果
                    String dubboMsg = "";
                    try {
                        dubboMsg = this.service.getMsg();
                    } catch (Exception e) {
                        e.printStackTrace();
                        future.fail(e);
                    }
                    // 把結果放到result中
                    future.complete(dubboMsg);
                }, result -> {
                    // 判斷接口調用結果,成功的話講結果放到事件總線的msg中傳遞給server端展現
                    if (result.succeeded()) {
                        System.out.println("msg from dubbo service is: "
                                + result.result());
                        msg.reply(result.result());
                    }
                    if (result.failed()) {
                        msg.fail(400, result.cause().getMessage());
                    }
                });
        };
    }

}

建立SpringVerticle:

package com.heartlifes.vertx.demo.dubbo;

import io.vertx.core.AbstractVerticle;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;

/**
 * 基本代碼註釋,請參見vert.x筆記:3.使用vert.x發佈restful接口
 * 
 * @author john
 *
 */
public class ServerVerticle extends AbstractVerticle {

    @Override
    public void start() throws Exception {
        Router router = Router.router(vertx);
        router.route().handler(BodyHandler.create());
        router.route("/dubbo/get").handler(
        // 喚起vert.x的事件總線,併發送一個簡單消息
                ctx -> vertx.eventBus().<String> send(
                        SpringVerticle.GET_MSG_SERVICE_ADDRESS,// 消息地址
                        "event bus calls dubbo service",// 消息內容
                        result -> {// 異步結果處理
                            if (result.succeeded()) {
                                // 成功的話,返回處理結果給前臺,這裏的處理結果就是service返回的一段字符串
                                ctx.response()
                                        .putHeader("content-type",
                                                "application/json")
                                        .end(result.result().body());
                            } else {
                                ctx.response().setStatusCode(400)
                                        .end(result.cause().toString());
                            }
                        }));
        router.route("/dubbo/print").handler(
        // 喚起vert.x的事件總線,併發送一個簡單消息
                ctx -> vertx.eventBus().<String> send(
                        SpringVerticle.PRINT_MSG_SERVICE_ADDRESS,// 消息地址
                        "event bus calls dubbo service",// 消息內容
                        result -> {// 異步結果處理
                            if (result.succeeded()) {
                                // 成功的話,返回處理結果給前臺
                                ctx.response()
                                        .putHeader("content-type",
                                                "application/json")
                                        .end("success");
                            } else {
                                ctx.response().setStatusCode(400)
                                        .end(result.cause().toString());
                            }
                        }));
        vertx.createHttpServer().requestHandler(router::accept).listen(8080);
    }
}

建立啓動器:

package com.heartlifes.vertx.demo.dubbo;

import io.vertx.core.Vertx;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringMain {

    public static void main(String[] args) {
        // 配置文件方式
        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "dubbo-consumer.xml");
        Vertx vertx = Vertx.vertx();
        // 部署spring模塊
        vertx.deployVerticle(new SpringVerticle(ctx));
        // 部署服務器模塊
        vertx.deployVerticle(new ServerVerticle());
    }

}
相關文章
相關標籤/搜索