dubbo_实现Hessian的远程调用协议
1.优点
- 连接个数:多连接
- 连接方式:短连接
- 传输协议:HTTP
- 传输方式:同步传输
- 序列化:Hessian二进制序列化
- 适用范围:传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件。
- 适用场景:页面传输,文件传输,或与原生hessian服务互操作
约束:
参数及返回值需实现Serializable接口
参数及返回值不能自定义实现List, Map, Number, Date, Calendar等接口,只能用JDK自带的实现,因为hessian会做特殊处理,自定义实现类中的属性值都会丢失。
2.Hessian
Hessian是Caucho开源的一个RPC框架:http://hessian.caucho.com,其通讯效率高于WebService和Java自带的序列化。
Hessian协议用于集成Hessian的服务,Hessian底层采用Http通讯,采用Servlet暴露服务,Dubbo缺省内嵌Jetty作为服务器实现。
依赖:
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.7</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.26</version>
</dependency>
3.provider
3.1.Jetty Server: (default):
<dubbo:protocol name="hessian" port="8080" server="jetty" />
<dubbo:service interface="cn.com.hello.UserService" ref="userService" path="dubbo/users" />
<bean id="userService" class="cn.com.hello.provider.impl.UserServiceImpl" />
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "hello-provider.xml" });
context.start();
System.in.read();
}
3.2.Servlet Bridge Server: (recommend)
<dubbo:protocol ... server="servlet" />
web.xml:
<servlet>
<servlet-name>dubbo</servlet-name>
<servlet-class>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dubbo</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
注意,如果使用servlet派发请求:
协议的端口<dubbo:protocol port="8080" />必须与servlet容器的端口相同,
协议的上下文路径<dubbo:protocol contextpath="foo" />必须与servlet应用的上下文路径相同。
4.consumer
4.1.提供方用标准Hessian暴露服务,消费方用Dubbo的Hessian协议调用
<dubbo:reference id="userService" interface="cn.com.hello.UserService" url="hessian://10.20.153.10:8080/dubbo/users" />
方法一:
package cn.com.hello; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:dubbo-consumer.xml") public class HelloTest { @Autowired private UserService userService; @Test public void sayHello() throws Exception { String hello = userService.sayHello("guoxue"); System.out.println(hello); } @Test public void getUsers() { List<?> list = userService.getUsers(); if (list != null && list.size() > 0) { for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } } } }
方法二:
package cn.com.hello.consumer; import java.util.concurrent.Callable; import org.springframework.context.support.AbstractXmlApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.com.hello.UserService; public class HelloConsumer { private AbstractXmlApplicationContext context; private UserService userService; public HelloConsumer(Callable<AbstractXmlApplicationContext> call) { super(); try { context = call.call(); context.start(); userService = (UserService) context.getBean("userService"); } catch (Exception e) { e.printStackTrace(); } } private String sayHello(final String name) { return userService.sayHello(name); } public static void main(String[] args) { final String beanXML = "dubbo-consumer.xml"; final String config = beanXML; HelloConsumer consumer = new HelloConsumer(new Callable<AbstractXmlApplicationContext>() { public AbstractXmlApplicationContext call() throws Exception { final AbstractXmlApplicationContext context = new ClassPathXmlApplicationContext(config); return context; } }); String result = consumer.sayHello("dengzy"); System.out.println(result); } }
4.2.提供者用Dubbo的Hessian协议暴露服务,消费者直接用标准Hessian接口调用
public static void main(String[] args) throws Throwable { String serviceUrl = "http://192.168.0.5:8080/dubbo/users"; HessianProxyFactory factory = new HessianProxyFactory(); UserService userService = (UserService) factory.create(UserService.class, serviceUrl); String result = userService.sayHello("dengzhiying"); System.out.println(result); List<?> list = userService.getUsers(); if (list != null && list.size() > 0) { for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } } }