dubbo集成zookeeper rpc远程调用
Posted Lyf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dubbo集成zookeeper rpc远程调用相关的知识,希望对你有一定的参考价值。
注:下面使用dubbo依赖的是zookeeper注册中心,这里没有详细的介绍。在配置之前,请自行准备好zookeeper环境。
后续如果写zookeeper的配置会补放链接
添加Gradle依赖
compile group: \'com.alibaba\', name: \'dubbo\', version: \'2.5.10\'//dubbo compile group: \'org.apache.zookeeper\', name: \'zookeeper\', version: \'3.3.3\'//zookeeper compile group: \'com.github.sgroschupf\', name: \'zkclient\', version: \'0.1\'//zkclient
服务端provider
目录结构
实体类
//这里实体对象实现了Serializable接口,dubbo规定,在远程调用实体对象时必须要实现Serializable接口以保证实体对象能够被序列化,如不实现会报错 public class Student implements Serializable { private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } public Student() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
service方法
public interface TestService { //返回字符串测试 String hello(String word); //返回实体对象测试,注意实体类要实现 Serializable 接口 List<Student> selectAllStudent(); }
实现service方法
//给service起个名字 别人调用提供接口方法时就是来实现本实现类的方法,和xml配置文件中所对应,让spring IOC 注入所管理 @Service("testService") public class TestServiceImpl implements TestService { @Autowired private GoodsStoreMapper goodsStoreMapper; @Override public String hello(String word) { return "提供者:"+word; } @Override public List<Student> selectAllStudent() { System.out.println("------被调用了------"); List<Student> list = new ArrayList<Student>(); list.add(new Student("张三" , 1)); list.add(new Student("李四" , 2)); list.add(new Student("王五" , 3)); return list; } }
applicationContext.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"> <!-- 提供方应用信息,用于计算依赖关系--> <!--name给当前服务起一个名字--> <dubbo:application name="springBootProvider"></dubbo:application> <!--protocol指定注册中心类型 这里用的是zookeeper--> <!--address注册中心地址 ip地址端口号--> <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" /> <!-- 用dubbo协议在20880端口暴露服务--> <dubbo:protocol name="dubbo" port="20880" /> <!-- 声明需要暴露的服务接口--> <dubbo:service interface="cn.appsys.service.TestService" ref="testService" /> </beans>
启动类
@SpringBootApplication //读取配置文件 @ImportResource(locations = {"classpath:config/applicationContext.xml"}) public class Start { public static void main(String[] args) { SpringApplication.run(Start.class , args); } }
运行服务端,首先先启动zookeeper注册中心
启动启动类,注意zookeeper的变化
这里看到 在配置文件中外放的接口已经被注册进来了,调用方想调用就要通过此节点来调用服务。
客户端customer
目录结构
客户端 实体 方法都和服务端的保持一致
注意:方法所在的包也要和服务端保持一致,接口名都需要和服务端保持一致
applicationContext.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="springBootConsumer"></dubbo:application> <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" /> <!--包名 接口名 必须要和服务提供方保持一致--> <dubbo:reference id="testService" interface="cn.appsys.service.TestService" ></dubbo:reference> </beans>
启动测试类
@SpringBootApplication //读取配置文件 @ImportResource(locations = {"classpath:config/applicationContext.xml"}) public class Start { public static void main(String[] args) { //SpringApplication.run返回一个ApplicationContext对象 ApplicationContext ac = SpringApplication.run(Start.class , args); //通过ApplicationContext对象的getBean获取实现方法 TestService testService = ac.getBean(TestService.class); //调用方法 String s = testService.hello("aaaaaaaa"); System.out.println(s); List<Student> stus = testService.selectAllStudent(); for (Student stu : stus) { System.out.println(stu.getName()); } } }
启动运行
调用成功,再看一下服务端的变化
成功!
这里在放上如果不在服务端实体类不实现Serializable接口的报错信息
Exception in thread "main" com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method selectAllStudent in the service cn.appsys.service.TestService. Tried 3 times of the providers [192.168.1.104:20880] (1/1) from the registry 127.0.0.1:2181 on the consumer 192.168.1.104 using the dubbo version 2.0.1. Last error is: Failed to invoke remote method: selectAllStudent, provider: dubbo://192.168.1.104:20880/cn.appsys.service.TestService?anyhost=true&application=springBootConsumer&check=false&dubbo=2.0.1&generic=false&interface=cn.appsys.service.TestService&methods=hello,login,selectAllStudent&pid=8928®ister.ip=192.168.1.104&remote.timestamp=1533373429375&side=consumer×tamp=1533373564236, cause: Failed to send response: Response [id=3, version=2.0.0, status=20, event=false, error=null, result=RpcResult [result=[cn.appsys.entity.Student@45a35c25, cn.appsys.entity.Student@419cd049, cn.appsys.entity.Student@49e561e], exception=null]], cause: java.lang.IllegalStateException: Serialized class cn.appsys.entity.Student must implement java.io.Serializable java.lang.IllegalStateException: Serialized class cn.appsys.entity.Student must implement java.io.Serializable
dubbo在远程调用时注意事项
1)序列化
我们所有需要用来传输数据的实体一定要实现序列化,不然一定会报错
2)业务注入不进来
例如我们在Controller中注入了一个业务,@Controller使用的是Spring注解,@Reference使用的是Dubbo,如果Spring先进行扫描,那么业务一定是注入不进去的。如所有我们dubbo也要扫描controller。
3)超时设置
根据业务来设定不同的超时配置,如果一个服务很庞大处理的时间相对来说时间会比较长,可以会一直引起超时错误。
以上是关于dubbo集成zookeeper rpc远程调用的主要内容,如果未能解决你的问题,请参考以下文章
Dubbo的RPC远程过程调用+Dubbo的负载均衡+Zookeeper注册中心