dubbo的基础使用搭建
为什么写这个呢?现在大多数用的是提供给我们的springcloud,但是在公司用到的是Dubbo,当然进公司之后,虽然不用自己搭建,但是写多了接口,我就想尝试一次对dubbo的搭建,这次写了一个小的demo。
官网:http://dubbo.apache.org/en-us/
微服务的一些认识
我大致对dubbo的一点认识是这样的(画的不好):
当我们的从Controller过来到消费者,然后消费者去找到我们需要的rpc接口,rpc接口再走相应的提供者,最后一步一步返回,用一个模块将我们需要暴露的接口来进行存放。
安装zookeeper
dubbo可以依赖于zookeeper,也就是注册中心,把我们需要的服务注册进去,然后用的时候再去提供出来。
1.下载zookeeper的安装包
下载地址为:https://mirrors.cnnic.cn/apache/zookeeper/
2.解压下载的压缩包,修改配置文件
修改目录下zookeeper-3.4.10\conf\zoo_sample.cfg文件内容,并将文件名修改为zoo.cfg。
实际上只需要修改dataDir和dataLogDir两个地方即可,dataDir为Zookeeper 保存数据的目录,dataLogDir为Zookeeper 保存日志文件的目录。
下面是我的本地配置:
(这两个需要进行修改)
dataDir=D:/work_to_space/zookeeper/data
dataLogDir=D://work_to_space/zookeeper/log
3.启动zookeeper
找到目录\bin,双击zkServer.cmd,直接运行(一般情况下都会正常启动)
创建项目
我用的是idea,所以使用的是下面的Spring Initializr(其实也就是建一个maven项目比较好管理):
新建一个项目,然后在项目下新建相应的model。
外层项目的pom.xml中
以及需要进行相关的model,这里只需要放相关联的model就行了,因为我这次写的案例和其他的关联在一起,所以就不单独写了,本篇文章只是简单的入门。
common_service-facade中写对应需要暴露的接口方法
package com.yqx.wfw_common_service_facade.rpc.user;
import com.yqx.wfw_common_service_facade.entity.UserEntity;
import java.util.List;
/**
* 用户接口
*
* @author YangChingyu-k
* @date 2019/8/26 15:48
*/
public interface UserService {
/**
* 测试dubbo是否成功
*/
String sayHello();
}
实现类在另一个userModel中,这就是到我们调用需要用到的接口时,会去找到我们关联的实现
package com.yqx.wfw_user.service;
import com.alibaba.dubbo.config.annotation.Service;
import com.yqx.wfw_common_service_facade.entity.UserEntity;
import com.yqx.wfw_common_service_facade.rpc.user.UserService;
import com.yqx.wfw_user.dao.UserDao;
import javax.annotation.Resource;
import java.util.List;
/**
* 用户接口Provide
*
* @author YangChingyu-k
* @date 2019/8/26 16:18
*/
@Service
public class UserServiceProvide implements UserService {
@Override
public String sayHello() {
String str = "Say hello!";
return str;
}
}
provider的配置文件xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- provider's application name, used for tracing dependency relationship -->
<dubbo:application name="user-provider"/>
<dubbo:registry address="zookeeper://localhost:2181"/>
<!-- use dubbo protocol to export service on port 20880 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- service implementation, as same as regular local bean -->
<bean id="userService" class="com.yqx.wfw_user.service.UserServiceProvide"/>
<!-- declare the service interface to be exported -->
<dubbo:service interface="com.yqx.wfw_common_service_facade.rpc.user.UserService" ref="userService"/>
</beans>
consumer的配置xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- consumer's application name, used for tracing dependency relationship (not a matching criterion),
don't set it same as provider -->
<dubbo:registry address="zookeeper://localhost:2181"/>
<dubbo:application name="consumer"/>
<!-- user -->
<dubbo:reference id="userService" check="false" interface="com.yqx.wfw_common_service_facade.rpc.user.UserService"/>
</beans>
provider的启动:
package com.yqx.wfw_user;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
@MapperScan("com.yqx.wfw_user.dao")
@SpringBootApplication
public class WfwUserApplication {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"\\WEB-INF\\spring\\user-provide.xml"});
context.start();
System.out.println("------- UserService服务已启动 -------");
}
}
consumer的启动:
package com.yqx.wfw_controller;
import com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;
import com.yqx.wfw_common_service_facade.rpc.user.UserService;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@DubboComponentScan(basePackages = "com.yqx.wfw_common_service_facade.rpc")
@SpringBootApplication
public class WfwControllerApplication {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"\\WEB-INF\\spring\\consumer.xml"});
context.start();
UserService userService = (UserService) context.getBean("userService");
// 测试服务调用是否成功
while (true) {
try {
Thread.sleep(1000);
String str = userService.sayHello();
System.out.println("--- 调用服务 ---");
System.out.println("---" + str + "---");
} catch (Exception e){
e.printStackTrace();
}
}
// SpringApplication.run(WfwControllerApplication.class, args);
}
}
测试是否成功
启动过程:
手动启动zookeeper(这是肯定的,不然你接口从哪里拿);
provider启动;
consumer启动。
放一个测试的结果:
zookeeper的启动没有报错
provide启动:
最后结果:
题外
这知识一个简单的搭建,可以看出在不同的模块,我们引入的不在同一model下的"资源",然后测试的时候调用的接口和实现也不在同一模块下,这就是一个简单的理解,模块与模块之间的关联以及调用和实现,另外还放一段配置,上面的简单搭建是没有用到数据库的,那么如果我们用到的话需要再配置中写点东西,也就是让服务暴露在外。
在propertise中加入以下(具体加的和我们之前xml中的相关):
spring.dubbo.application.name=user-provider # 本服务的名称
spring.dubbo.registry.address=zookeeper://localhost:2181 # ZooKeeper所在服务器的IP和端口号
spring.dubbo.protocol.name=dubbo # RPC通信所采用的协议
spring.dubbo.protocol.port=20880 # 本服务对外暴露的端口号
spring.dubbo.scan=com.yqx.wfw_common_service_facade.rpc.user.UserService # 服务实现类所在的路径
末尾
我这里只是提供一下简单的搭建,具体的用法还是要看具体场景,并不是说一定就去调用模块之外的方法,如果只是对自身有用,那就可以不需要暴露在外,这是一点点理解和看法,如果有其他的看法,可以一起讨论,欢迎评论,有问题指出,哪里不对就改哪里,希望可以共同进步,加油吧!