基于Dubbo的Hessian协议实现远程调用

前言

创建两个项目,一个provider提供dubbo服务,一个client消费服务。
源码地址:https://gitee.com/qianxunclub/java-demo/tree/master/chapter-2
目录结构如下:

$ tree -I target

chapter-2
├── api
│   ├── pom.xml
│   └── src
│       └── main
│           └── java
│               └── com
│                   └── qianxunclub
│                       └── chapter2
│                           └── api
│                               └── DemoService.java
├── client
│   ├── pom.xml
│   └── src
│       └── main
│           ├── java
│           │   └── com
│           │       └── qianxunclub
│           │           └── chapter2
│           │               └── client
│           │                   └── ClientMain.java
│           └── resource
│               ├── demo-consumer.xml
│               └── log4j.properties
├── pom.xml
└── provider
    ├── pom.xml
    └── src
        └── main
            ├── java
            │   └── com
            │       └── qianxunclub
            │           └── chapter2
            │               └── provider
            │                   ├── DemoServiceImpl.java
            │                   └── ProviderMain.java
            └── resource
                ├── META-INF
                │   └── spring
                │       └── demo-provider.xml
                └── log4j.properties

1、在provider的pom.xml中引入maven包

<dependency>
    <groupId>com.qianxunclub</groupId>
    <artifactId>chapter-2-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>com.caucho</groupId>
    <artifactId>hessian</artifactId>
    <version>4.0.38</version>
</dependency>
<dependency>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>jetty</artifactId>
    <version>6.1.26</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.5.3</version>
</dependency>
<dependency>
    <groupId>com.github.sgroschupf</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.1</version>
</dependency>

2、在provider中添加配置文件

在provider的resource/META-INF/spring下建个xml, 例如:demo-provider.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:dubbo="http://code.alibabatech.com/schema/dubbo"
       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://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.1.xsd">

    <context:annotation-config/>
    <context:component-scan base-package="com.qianxunclub.chapter2.provider"/>
    <!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->
    <dubbo:application name="demo-provider" owner="lily"/>

    <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->
    <dubbo:registry protocol="zookeeper" address="qianxunclub.com:2181"/>

    <!--当前服务发布所依赖的协议;WebService、Thrift、Hessian、http-->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!--增加hessian协议-->
    <dubbo:protocol name="hessian" port="8090" server="jetty" />

</beans>

ps:该xml文件默认需要建在resource/META-INF/spring文件夹下。多说无益,上dubbo源码。
从ProviderMain.java中

Main.main(args);

点进去main方法,查看main方法中Container接口的其中之一的实现类SpringContainer中可以看到默认路径:

public static final String DEFAULT_SPRING_CONFIG = "classpath*:META-INF/spring/*.xml";

也可以自定义路径:

    public void start() {
        String configPath = ConfigUtils.getProperty("dubbo.spring.config");
        if(configPath == null || configPath.length() == 0) {
            configPath = "classpath*:META-INF/spring/*.xml";
        }
        context = new ClassPathXmlApplicationContext(configPath.split("[,\\s]+"));
        context.start();
    }

点进去getProperty方法,一路ctrl下去,可以看到ConfigUtils.java中自定义路径的规则:

    public static Properties getProperties() {
        if(PROPERTIES == null) {
            Class var0 = ConfigUtils.class;
            synchronized(ConfigUtils.class) {
                if(PROPERTIES == null) {
                    String path = System.getProperty("dubbo.properties.file");
                    if(path == null || path.length() == 0) {
                        path = System.getenv("dubbo.properties.file");
                        if(path == null || path.length() == 0) {
                            path = "dubbo.properties";
                        }
                    }
                    PROPERTIES = loadProperties(path, false, true);
                }
            }
        }
        return PROPERTIES;
    }

在resource下创建dubbo.properties文件,内容如下:

#dubbo配置的自定义路径
dubbo.spring.config=classpath*:hello/*.xml

3、在api模块中添加对外抛出的接口

public interface DemoService {
    String sayHello(String name);
}

并在provider中添加该接口的实现类:

import com.qianxunclub.chapter2.api.DemoService;
import org.springframework.stereotype.Service;

@Service("demoService")
public class DemoServiceImpl implements DemoService {
    @Override
    public String sayHello(String name) {
        return "hello:"+name;
    }
}

demo-provider.xml中,添加 对外抛出接口:

        <!--服务发布的配置,需要暴露的服务接口-->
    <dubbo:service
            interface="com.qianxunclub.chapter2.api.DemoService"
            ref="demoService" protocol="hessian"/>

4、调用provider中的main方法

import com.alibaba.dubbo.container.Main;
public class ProviderMain {
    public static void main(String[] args) {
        try {
            Main.main(args);
        } catch (Exception e){
            System.out.println(e);
        }
    }
}

在provider控制台,会打印:

[DUBBO] Register: hessian://192.168.103.163:8090/com.qianxunclub.chapter2.provider.DemoService?anyhost=true&application=demo-provider&dubbo=2.5.3&interface=com.qianxunclub.chapter2.provider.DemoService&methods=sayHello&owner=lily&pid=6656&server=jetty&side=provider&timestamp=1527126914293, dubbo version: 2.5.3, current host: 127.0.0.1

进入zookeeper客户端,查看服务:

扫描二维码关注公众号,回复: 3757358 查看本文章

5、在client的pom.xml中引入maven包

<dependency>
    <groupId>com.qianxunclub</groupId>
    <artifactId>chapter-2-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.5.3</version>
</dependency>

6、在client中添加配置文件

在provider的resource/META-INF下建个xml, 例如:demo-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:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->
    <dubbo:application name="demo-client" owner="mic"/>

    <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->
    <dubbo:registry protocol="zookeeper" address="qianxunclub.com:2181"/>

    <!--当前服务发布所依赖的协议;webserovice、Thrift、Hessain、http-->
    <dubbo:protocol name="dubbo" port="20881"/>

    <!--服务发布的配置,需要暴露的服务接口-->
    <dubbo:reference
            interface="com.qianxunclub.chapter2.api.DemoService"
            id="demoService"/>

</beans>

7、调用client中的main方法

import com.qianxunclub.chapter2.api.DemoService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ClientMain {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("demo-consumer.xml");
        DemoService demoService = context.getBean(DemoService.class);
        String r = demoService.sayHello("zhangsan");
        System.out.println(r);
    }
}

报错:

Unsupported protocol hessian in notified url: hessian://192.168.103.163:8090/com.qianxunclub.chapter2.api.DemoService?anyhost=true&application=demo-provider&dubbo=2.5.3&interface=com.qianxunclub.chapter2.api.DemoService&methods=sayHello&owner=lily&pid=11648&server=jetty&side=provider&timestamp=1527152915485 from registry qianxunclub.com:2181 to consumer 192.168.103.163, supported protocol: [dubbo, injvm, mock, redis, registry, rmi, thrift]


原来是client端少引了个hessian依赖,加上:

<dependency>
    <groupId>com.caucho</groupId>
    <artifactId>hessian</artifactId>
    <version>4.0.38</version>
</dependency>

再次启动,会看到控制台打印了:hello:zhangsan。
大功告成!

猜你喜欢

转载自blog.csdn.net/lilyssh/article/details/82911937