随着互联网的不断发展,系统应用的规模也在不断扩大,常规的垂直类型应用架构已经无法较好的应对,所以分布式服务架构以及流动计算机架构的趋势越来越明显。在这种大规模类型的服务化架构到来之前,可能只是通过rmi,hessian等工具来进行简单的服务引用的处理,但是当规模量逐渐提升之后,过多的服务也带来了一定的繁琐问题,例如说对于服务url的管理。
当不同服务的调用量逐渐提升之后,服务的容量问题也越来越不明确。
对于错综复杂的服务调度关系,越来越繁琐,不利于统筹管理。
基于上述的一些情况,dubbo服务架构开始横空出世,其基本架构如下所示:
说了这么多的背景介绍,我们还是直接用个案例来进行介绍会比较好:
首先需要在ide里面搭建好相应的maven结构:
然后导入相应的pom依赖:
dubbo-root:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.sise</groupId> <artifactId>dubbo-root</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>dubbo-provide</module> <module>dubbo-api</module> <module>dubbo-consumer</module> </modules> <properties> <motan.version>0.3.0</motan.version> <!-- 在阿里巴巴内部广泛使用的GA版本为:2.4.9,强烈推荐此版本 --> <dubbo.version>2.5.3</dubbo.version> <dubbox.version>2.8.4</dubbox.version> <spring.version>4.3.6.RELEASE</spring.version> <java.version>1.7</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <!-- spring相关 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.6.11</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.6.11</version> </dependency> </dependencies> </project> 复制代码
provider:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>dubbo-root</artifactId> <groupId>com.sise</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>dubbo-provide</artifactId> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <artifactId>dubbo-api</artifactId> <groupId>com.sise</groupId> <version>1.0-SNAPSHOT</version> <!--<scope>provided</scope>--> </dependency> </dependencies> </project> 复制代码
consumer:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>dubbo-root</artifactId> <groupId>com.sise</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <artifactId>dubbo-consumer</artifactId> <dependencies> <dependency> <artifactId>dubbo-api</artifactId> <groupId>com.sise</groupId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project> 复制代码
api:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>dubbo-root</artifactId> <groupId>com.sise</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>dubbo-api</artifactId> </project> 复制代码
这个案例的思路是,我们在api模块中编写rpc服务接口,在provider里面对服务进行实现,最后在consumer里面调用服务进行测试。
api里面的接口如下:
package com.sise.service; /** * 作者:idea * 日期:2018/8/11 * 描述: */ public interface UserRpcService { /** * 获取用户username的rpc服务 * @param username * @return */ String getUserName(String username) throws InterruptedException; } 复制代码
关于provider部分的接口实现内容如下所示:
package com.lh.pro.rpc; import com.sise.service.UserRpcService; import org.springframework.stereotype.Service; /** * 作者:idea * 日期:2018/8/11 * 描述:用户service服务调度 */ @Service("userService") public class UserService implements UserRpcService{ /** * 返回用户名的服务 * @param username * @return */ public String getUserName(String username) throws InterruptedException { return username+" hello ! this is app222"; } } 复制代码
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" 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="dubbo_provider" /> <!-- 使用zookeeper注册中心暴露服务地址 --> <dubbo:registry address="zookeeper://127.0.0.1:2181" /> <dubbo:provider proxy="jdk" ></dubbo:provider> <!-- 用dubbo协议在20880端口暴露服务 --> <dubbo:protocol name="dubbo" port="20880" /> <!--rpc服务,提供给外界调用--> <dubbo:service interface="com.sise.service.UserRpcService" ref="userService" > <!--设置超时时限500ms,当链接失败后只会再次访问2回--> <dubbo:method name="getUserName" timeout="500" retries="2"></dubbo:method> </dubbo:service> <!--<bean id="userService" class="com.lh.pro.rpc.UserService"></bean>--> </beans> 复制代码
spring配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd" default-autowire="byName"> <aop:aspectj-autoproxy /> <context:component-scan base-package="com.lh.pro" /> <import resource="classpath:dubbo-provider.xml" /> </beans> 复制代码
服务开关:
package com.lh.pro.server; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.io.IOException; /** * 作者:idea * 日期:2018/8/11 * 描述:provider开关 */ public class Application { public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(new String[]{"application-context.xml"}); context.start(); System.out.println("dubbo的服务生产者1开启了"); //长期开启应用 System.in.read(); } } 复制代码
记得,开启dubbo之前需要开启zookeeper服务注册点,注册站点开启之后,所有在dubbo里面出现的服务都会被注册到这个位置上边。
开启服务提供者以后,窗口内容大致如下:
我们开启了dubbo里面的服务之后自然就可以开始对于服务的调度方consumer开始编写了。
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="dubbo_consumer" /> <!--关闭所有的服务时进行检查,当没有服务提供者的时候会报错--> <dubbo:consumer check="false"></dubbo:consumer> <!-- 使用multicast广播注册中心暴露发现服务地址 --> <dubbo:registry protocol="zookeeper" address="zookeeper://127.0.0.1:2181" /> <!-- 生成远程服务代理,可以和本地bean一样使用UserRpcService 其中的init配置是立即加载的含义,有点类似于饿汉式--> <dubbo:reference id="userService" interface="com.sise.service.UserRpcService" cluster="failsafe" check="false" loadbalance="roundrobin"> </dubbo:reference> </beans> 复制代码
spring容器配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd" default-autowire="byName"> <aop:aspectj-autoproxy /> <context:component-scan base-package="com.lh.consume" /> <import resource="classpath:/dubbo-consume.xml" /> </beans> 复制代码
consumer模块部分的代码如下所示:
package com.lh.consume; import com.sise.service.UserRpcService; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.io.IOException; /** * 作者:idea * 日期:2018/7/29 * 描述: */ public class ConsumerTest { public static void main(String[] args) throws InterruptedException { ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(new String[]{"classpath:application-consumer.xml"}); context.start(); UserRpcService userService= (UserRpcService)context.getBean("userService"); System.out.println(userService.getUserName("getUserName test")); try { System.in.read(); } catch (IOException e) { e.printStackTrace(); } } } 复制代码
在这里面,服务的调用者会先去zookeeper里面查找是否有相应的userService这一项服务内容,如果有则会生成一个远程代理对象,在本地进行引用相应服务。
这个时候我们开启消费者进行调用:
好了,一个简单易懂的dubbo入门案例就这样完成了。
下面一章节,我们来讲解如何搭建dubbo的admin管理平台