1.dubbo简介
Dubbo是阿里巴巴公司开源的一个高性能、轻量级的JavaRPC框架,致力于提供高性能和透明化
的RPC远程服务调用方案,以及SOA服务治理方案
dubbo官网:
2.dubbo架构
官方文档提供的dubbo架构
Provider 服务的提供方
Container 容器
Consumer 服务消费方
Registry 注册中心
Monitor 监控者
init 初始化创建
async 异步
sync 同步
流程:
1. Provider在一个容器中(比如:tomcat)由容器进行Provider的创建(步骤0)
2. Provider将自己的ip地址、端口号、发布的url地址等一些信息放在注册中心进行注册(步骤1)
3. Consumer想要Provider提供的服务,向注册中心发送请求发现服务(步骤2)
4. 注册中心将Providerr的ip地址、端口号、发布的url地址等一些信息发生给Consumer(步骤3)
5. Consumer进行调用Provider(步骤4)
6. 步骤5是进行服务调用的监控
3.dubbo搭建
3.1本地本地搭建service和web模块
1. 创建两个maven模块
2. 导入依赖和版本坐标
<properties> <spring.version>5.1.9.RELEASE</spring.version> <dubbo.version>2.7.4.1</dubbo.version> <zookeeper.version>4.0.0</zookeeper.version> </properties> <dependencies> <!-- servlet3.0规范的坐标--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!--spring的坐标--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- 日志--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.21</version> </dependency> <!--Dubbo的起步依赖,版本2.7之后统一为org.apache.dubbo--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>${dubbo.version}</version> </dependency> <!--ZooKeeper客户端实现--> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>${zookeeper.version}</version> </dependency> <!--ZooKeeper客户端实现--> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>${zookeeper.version}</version> </dependency> </dependencies>
dubbo-web的pom.xml除了上述依赖包外还需要导入tomcat编译插件和打包方式war包
<packaging>war</packaging> <build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <!-- 端口号--> <port>8000</port> <!-- 路径--> <path>/</path> </configuration> </plugin> </plugins> </build>
dubbo-web模块下
controller层
@RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @RequestMapping("/demo") public String demo(){ return userService.demo(); } }
springmvc.xml配置
<!-- 开启注解驱动--> <mvc:annotation-driven/> <!-- 扫描controller包--> <context:component-scan base-package="com.xue.controller"/>
web.xml配置
<!-- spring --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring/applicationContext*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Springmvc --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
dubbo-service模块下
UserServiceImpl类
@Service public class UserServiceImpl implements UserService { @Override public String demo() { return "hello,Dubbo"; } }
UserService接口
public interface UserService { /** * 测试方法 * @return */ public String demo(); }
配置applicationContext
<!-- 包扫描--> <context:component-scan base-package="com.xue.service"/>
最后关联一下dubbo-service到dubbo-web中,在dubbo-web的pom.xml导入dubbo-service依赖
<dependency> <groupId>com.xue</groupId> <artifactId>dubbo-service</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
maven管理中install一下dubbo-service模块,然后在dubbo-web的maven管理中选择tomcat7:run插件进行启动
在浏览器访问 localhost:8000/user/demo
出现 hello,Dubbo
以上这只是本地启动,而不是远程,也就是说还没有用到dubbo
3.2dubbo搭建
改造服务提供者
1.修改UserServiceImpl中的service注解
import org.apache.dubbo.config.annotation.Service; //@Service //将该类的对象创建出来,放到spring的IOC容器中 bean定义 @Service //dubbo中的service注解 将该类提供的方法(服务)对外发布,将访问的地址、ip、端口、路径注册到注册中心
2.在applicationContext.xml配置文件中新增
<!--dubbo的配置 --> <!-- 1.配置项目的名称,唯一--> <dubbo:application name="dubbo-service"/> <!-- 2.配置注册中心的地址--> <dubbo:registry address="zookeeper://(zookeeper的IP地址):2181"/> <!-- 3.配置dubbo包扫描--> <dubbo:annotation package="com.xue.service.impl"/>
3.将dubbo-web中的webapp放到dubbo-service中,需要在文件结构project structure中faces中给dubbo-service添加web服务,并修改路径到 包结构+\dubb-web\src\main\webapp\WEB-INF\web.xml
4.把tomcat7插件导入pom文件中,注意端口号不要和web中的冲突,并配置打包方式为war包
在IDEA右侧maven管理中对dubbo-service模块进行package然后选择tomcat7:run插件进行启动
改造服务消费者dubbo-web
1. 删掉pom文件中对dubbo-service的依赖,因为我们要模拟远程交互,但是两个模块在同一台主
机上,所以要删除依赖,让两个模块进行远程交互
2. 这个时候UserController类肯定就报错了,因为我们之前是直接进行关联,web模块可以与service模块进行交互,但是删掉依赖之后就无法进行本地交互了。我们可以在web模块创建一个UserService接口,先让它不报错,但是@Autowired还是报错,因为本地没有这个bean无法进行spring注入,因此我们需要进行远程注入
//@Autowired //本地注入 /** * 1.从zookeeper注册中心获取userService的访问url * 2.进行远程调用RPC * 3.将结果封装成一个代理对象,给变量赋值 */ @Reference //远程注入 private UserService userService;
3.配置springmvc配置文件与service的dubbo配置相同,只是修改下dubbo包扫描
<!--dubbo的配置 --> <!-- 1.配置项目的名称,唯一--> <dubbo:application name="dubbo-web"/> <!-- 2.配置注册中心的地址--> <dubbo:registry address="zookeeper://主机ip:2181"/> <!-- 3.配置dubbo包扫描--> <dubbo:annotation package="com.xue.controller"/>
4.删除web.xml中spring的配置原理与第二步相同
<!-- spring --> <!-- <context-param>--> <!-- <param-name>contextConfigLocation</param-name>--> <!-- <param-value>classpath*:spring/applicationContext*.xml</param-value>--> <!-- </context-param>--> <!-- <listener>--> <!-- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>--> <!-- </listener>-->
5.tomcat7:run插件进行启动
然后完美访问:
虽然能正常访问,但是控制台日志信息,有一个异常
RROR 2022-03-09 10:46:59,104 org.apache.dubbo.qos.server.Server: [DUBBO] qos-server can not bind localhost:22222, dubbo version: 2.7.4.1, current host: 主机IP java.net.BindException: Address already in use: bind
这个异常很常见,是端口冲突,qos服务的端口22222被占用了。qos是dubbo自带的用于监控的组件,我们在同一台主机上模拟远程交互,启动了消费者和提供者两方,因此就造成了端口冲突,在实际多台主机交互中不会出现此问题
如果在一台主机上解决此问题需要在任一方修改下配置 (比如dubbo-web模块),配置下此模块qos的端口为另一个就欧克了!
<!-- 1.配置项目的名称,唯一--> <dubbo:application name="dubbo-web"> <dubbo:parameter key="qos.port" value="33333"/> </dubbo:application>
dubbo小案例就完成了!!!
3.3优化dubbo搭建
web和service远程交互为了能使用spring注入UserService接口,我们之前解决方案是在web中也创
建一个UserService接口。如果有大量的接口我们都需要重新创建,而且要保证与service中的接口
完全相同。我们自己本地测试可以直接复制过来,但是我们是在模拟远程交互,因此service和web
模块是不同的人不同的主机负责的,我们怎么能很好的保证接口相同呢?
一个解决办法就是将接口抽取成新的公共模块,此模块包含所有接口,在使用时导入关联依赖。
其他模块都有一份此模块,保证了相同,实现了service开发和web开发的分离(不需要进行接口
的协商)
1.新建一个模块dubbo-interface,将UserService接口放在此模块中。web和service都要导入dubbo-interface的依赖
<!-- 依赖service模块--> <dependency> <groupId>com.xue</groupId> <artifactId>dubbo-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
2.删掉web和service中的UserService接口
3.maven管理中lifecycle->install一下dubbo-interface,然后tomcat7:run插件分别启动dubbo-
service和dubbo-web
成功!!!
如果在配置dubbo上有什么疑问可以私信我,需要源码的伙伴也可以私信我!