demo 地址 git clone http://git.oschina.net/shirenchuang/dubbo-project
或者直接下载 http://download.csdn.net/detail/u010634066/9788109
一. demo 结构图
结构说明:
一般大的项目都会分成好几个服务,比如 有 用户服务,订单服务,红包服务..等等;然后各个服务之间也会互相调用,但是都是通过 facade 来调用的;这样就隐藏了服务的实现,降低耦合度;
所以我在本demo中 模拟了4个服务;每个服务是提供者 ,也是其他服务的消费者;
dubbo-facade-project 接口层 定义接口;供 提供者 和 消费者 共同使用;
dubbo-service-project 服务层 实现接口
dubbo-web-project 控制层
注意:在新建服务层的时候,因为 里面的服务 既是提供者 又可能是消费者 ,并且以后它们是要打包部署到tomcat 中的;
新增服务
这样新增成功的 才能打成war包 部署;(0.0)
引入 zk + spring + dubbo 等 等pom文件
贴出dubbo-service-project 项目 等pom.xml文件
呃~~ 太不多 不贴了 0.0
二.将服务注册到注册中心去
1. facade 定义接口
package com.dubbo.service3; /** * Created by shirenchuang on 2017/3/16. */ public interface Test1Service3 { public String test1Service3_1(); }
2. 将 facade 的项目 引入到 实现类中
<dependency> <groupId>com.dubbo</groupId> <artifactId>dubbo-service3-facade</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
3.实现 接口
package com.dubbo.service3.impl; import com.alibaba.dubbo.config.annotation.Service; import com.dubbo.service3.Test1Service3; /** * Created by shirenchuang on 2017/3/16. */ public class Test1Service3Impl implements Test1Service3{ public String test1Service3_1() { return "test1Service3_1......" ; } }
4.配置 配置文件
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:p="http://www.springframework.org/schema/p" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 提供方应用信息,用于计算依赖关系 --> <dubbo:application name="service3_provider" /> <!-- 使用zookeeper注册中心暴露服务地址 --> <dubbo:registry address="zookeeper://120.25.162.6:2181" /> <!-- 用dubbo协议在20880端口暴露服务 --> <!-- 一台机器同时启动多个服务 要区分开端口号--> <dubbo:protocol name="dubbo" port="20884" /> <!-- 和本地bean一样实现服务 --> <bean id="test1Service3" class="com.dubbo.service3.impl.Test1Service3Impl" /> <!-- 声明需要暴露的服务接口 --> <dubbo:service interface="com.dubbo.service3.Test1Service3" ref="test1Service3" /> </beans>
5.1 启动spring 容器 ;java代码启动
provder3.java
import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Created by shirenchuang on 2017/3/16. */ public class Provider3 { public static void main(String[] args) throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( new String[] {"provider.xml"}); context.start(); System.in.read(); // 按任意键退出 } }
5.2 也可以部署到tomcat 中去;那就要配置一下 web.xml 文件了
例如:看 dubbo-service1_1-project 的配置文件
里面的那些配置文件就不贴出来了 ;下载源代码看就行了 ;
最好可以打包成war 部署到tomcat 中 也是一样的效果
6.步骤5.1 或者5.2 部署成功之后的效果 ,打开dubbo-admin 查看
7. 服务注册成功了 ,那么怎么使用呢?
三 . 如何消费 提供者提供的服务----消费者
刚刚发布了 service3 ,并且保持它一直在启动状态(不要把provder3 停止就行了)
可以在dubbo-admin 看到它是没有消费者的,现在我们在 Controller 层来消费它;
1. Controller 的配置
web.xml
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet>
spring-mvc.xml 开启自动扫描
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> <context:component-scan base-package="com.dubbo" /> <mvc:annotation-driven /> </beans>
dubbo-config.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="test_consumer" /> <!-- 使用zookeeper注册中心暴露服务地址 --> <dubbo:registry address=" " /> <!-- 用dubbo协议在20880端口暴露服务 --> <!--dubbo:protocol name="dubbo" port="20880" /--> <!-- 声明需要暴露的服务接口 --> <dubbo:reference interface="com.dubbo.service3.Test1Service3" id="test1Service3" check="false" /> </beans>
配置 了需要消费的服务 service3 ;然后在Controller 中 就可以自己 通过注解 @Autowired 使用
@Autowired private Test1Service3 test1Service3; @RequestMapping(value = "/test3") @ResponseBody public String test3(){ return test1Service3.test1Service3_1(); }
2.1 tomcat启动服务......
请求接口....
启动完了可以看到的是 服务 显示正常 表示 有提供者 又有消费者呢 ;
注意 如果注册中心 没有注册成功的话 启动会报错
2.2 本地 测试调用远程服务
comsumer.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="service2_consumer" /> <!-- 使用multicast广播注册中心暴露发现服务地址 --> <dubbo:registry address="zookeeper://120.25.162.6:2181" /> <!-- 生成远程服务代理,可以和本地bean一样使用Service --> <!-- --> <!-- <dubbo:reference id="test1Service1" interface="com.dubbo.service1.Test1Service1" /> <dubbo:reference id="test2Service1" interface="com.dubbo.service1.Test2Service1" /> --> <dubbo:reference id="test1Service3" interface="com.dubbo.service3.Test1Service3" /> </beans>
comsumer2.java
public class Consumer2 { public static void main(String[] args) throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"consumer.xml"}); context.start(); Test1Service3 test1Service3 = (Test1Service3)context.getBean("test1Service3"); // 获取远程服务代理 String s = test1Service3.test1Service3_1(); // 执行远程方法 System.out.print("end......."+s); } }
执行main方法 可以在
String s = test1Service3.test1Service3_1();
打个断点,然后去dubbo-admin 看 可以发现 出现消费者;
放掉断点 ,消费者消失;并且 打印结果:end.......test1Service3_1......
四. 服务之间相互调用,每个服务既是消费者 又是提供者
1. 整体怎么配置
看服务 service1 ; 既是提供者 ,又是消费者 ;
Test1Service1Impl 文件
package com.dubbo.service1.impl; import com.dubbo.service1.Test1Service1; import com.dubbo.service1.Test2Service1; import com.dubbo.service2.Test1Service2; import com.dubbo.service3.Test1Service3; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * Created by shirenchuang on 2017/3/16. */ @Service public class Test1Service1Impl implements Test1Service1{ @Autowired private Test1Service3 test1Service3; @Autowired private Test2Service1 test2Service1 ; public String test1Service1_1() { String s = test1Service3.test1Service3_1(); return s+"test1Service1_1......"; } public String test1Service1_2() { return "test1Service1_2......"; } public String test11_21(){ String s = test2Service1.test2Service1_1(); return "Test1Service1Impl 测试本地服务 是调用本地还是调用 远程:"+s; } }
看代码 可以知道 它 消费了 服务 Service3 ,还有服务Service1 中的 Test2Service1Impl (同一个服务中有多个 类 ,这里不去谈论 它是本地调用还是 远程调用的问题)
我们来看看所有的配置
we b.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>dubbo-service1_1-project</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> </web-app>
applicationContext.xml
<import resource="dubbo-consumer.xml" /> <import resource="dubbo-provider.xml" /> <import resource="spring-mvc.xml" />
dubbo-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:p="http://www.springframework.org/schema/p" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 提供方应用信息,用于计算依赖关系 --> <dubbo:application name="service1_provider" /> <!-- 使用multicast广播注册中心暴露服务地址 --> <dubbo:registry address="zookeeper://120.25.162.6:2181" /> <!-- 用dubbo协议在20880端口暴露服务 --> <dubbo:protocol name="dubbo" port="20886" /> <!-- 和本地bean一样实现服务 --> <bean id="test1Service1" class="com.dubbo.service1.impl.Test1Service1Impl" /> <!-- 声明需要暴露的服务接口 --> <dubbo:service interface="com.dubbo.service1.Test1Service1" ref="test1Service1" /> <!-- 和本地bean一样实现服务 --> <bean id="test2Service1" class="com.dubbo.service1.impl.Test2Service1Impl" /> <!-- 声明需要暴露的服务接口 --> <dubbo:service interface="com.dubbo.service1.Test2Service1" ref="test2Service1" /> </beans>
dubbo-consumer.xml
配置自己所有需要消费的服务
注意下面的药注释掉
<dubbo:application name="service2_consumer" /> <!– 使用multicast广播注册中心暴露发现服务地址 –> <dubbo:registry address="zookeeper://120.25.162.6:2181" />
因为在provider中已经配置了 ,不能配置两个;
<?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"> <!--如果是spring xml 启动方式 那么下面的就注释掉;因为provider已经存在了 --> <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 --> <!-- <dubbo:application name="service2_consumer" /> <!– 使用multicast广播注册中心暴露发现服务地址 –> <dubbo:registry address="zookeeper://120.25.162.6:2181" />--> <!-- 生成远程服务代理,可以和本地bean一样使用Service --> <!-- --> <dubbo:reference id="test1Service3" interface="com.dubbo.service3.Test1Service3" /> <dubbo:reference id="test2Service1" interface="com.dubbo.service1.Test2Service1" /> </beans>
2.配置完了 然后启动
2.1 可以 部署到tomcat 中 ;
Test1Service1Impl 的 test1Service1_1 的时候会自动装载 test1Service3 的服务(前提是 这个服务已经注册了)
public String test1Service1_1() { String s = test1Service3.test1Service3_1(); return s+"test1Service1_1......"; }
2.2 可以本地代码测试
可以新建一个Consumer1 的类 来本地测试 ;加载 spring容器
public static void main(String[] args) throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml"}); context.start(); Test1Service1 test1Service1 = (Test1Service1)context.getBean("test1Service1Impl"); // 获取远程服务代理 String s0 = test1Service1.test1Service1_1(); // 执行远程方法 String s = test1Service1.test11_21(); Test2Service1 test2Service1 = (Test2Service1)context.getBean("test2Service1"); // 获取远程服务代理 String s1 = test2Service1.test2Service1_1(); System.out.print(s0+s+"end......."); }
五. 本地 一下注册所有的服务 ;
一般开发的时候 ,我们希望本地就能够测试 服务;不想改一个东西 就要重新部署到 开发环境去;
然后我想在本地把所有的服务一下在都注册到注册中心去;怎么搞呢?
end
分布式 dubbo + zookeeper + spring 分布式系统(二) 结构 大概就是这样了;
把每一个服务都独立出来;减小耦合度,通过dubbo 远程调用 ;
现在 只是用到了 dubbo 的rpc 的功能;dubbo中还有很多其他的功能 ;
dubbo + zookeeper + spring +mybatis 就是 再加入 mybatis 的配置就行了;