写点什么

dubbo + zookeeper + spring 分布式系统

  • 2022-11-16
    江西
  • 本文字数:7975 字

    阅读完需:约 26 分钟

dubbo + zookeeper + spring 分布式系统

demo 地址 git clone   http://git.oschina.net/shirenchuang/dubbo-project

或者直接下载   http://download.csdn.net/detail/u010634066/9788109

一. demo 结构图

image.png

image.png

image.png

image.png

结构说明:

一般大的项目都会分成好几个服务,比如 有 用户服务,订单服务,红包服务..等等;然后各个服务之间也会互相调用,但是都是通过 facade 来调用的;这样就隐藏了服务的实现,降低耦合度;

所以我在本 demo 中 模拟了 4 个服务;每个服务是提供者 ,也是其他服务的消费者;

dubbo-facade-project  接口层  定义接口;供 提供者 和 消费者 共同使用;

dubbo-service-project 服务层   实现接口

dubbo-web-project      控制层

注意:在新建服务层的时候,因为 里面的服务 既是提供者  又可能是消费者 ,并且以后它们是要打包部署到 tomcat 中的;

新增服务

image.png

image.png

image.png

image.png

这样新增成功的 才能打成 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();}
复制代码

12. 将 facade 的项目 引入到 实现类中

    <dependency>            <groupId>com.dubbo</groupId>            <artifactId>dubbo-service3-facade</artifactId>            <version>1.0-SNAPSHOT</version>        </dependency>
复制代码

23.实现 接口

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......" ;    }}
复制代码

34.配置 配置文件


image.png


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>
复制代码

45.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(); // 按任意键退出    }}
复制代码

55.2 也可以部署到 tomcat 中去;那就要配置一下 web.xml 文件了

例如:看 dubbo-service1_1-project 的配置文件

image.png

image.png

里面的那些配置文件就不贴出来了 ;下载源代码看就行了 ;

最好可以打包成 war 部署到 tomcat 中 也是一样的效果

66.步骤 5.1 或者 5.2 部署成功之后的效果 ,打开 dubbo-admin 查看

image.png

image.png

  1. 服务注册成功了 ,那么怎么使用呢?

三 . 如何消费 提供者提供的服务----消费者

刚刚发布了 service3 ,并且保持它一直在启动状态(不要把 provder3 停止就行了)

可以在 dubbo-admin 看到它是没有消费者的,现在我们在 Controller 层来消费它;

  1. Controller 的配置

image.png

image.png

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();    }
复制代码

72.1 tomcat 启动服务......

请求接口....

image.png

image.png

启动完了可以看到的是  服务 显示正常 表示 有提供者 又有消费者呢 ;

注意  如果注册中心 没有注册成功的话 启动会报错

82.2 本地 测试调用远程服务

image.png

image.png

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. */@Servicepublic 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>
复制代码

92.配置完了 然后启动

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.......");    }
复制代码

Part1 五. 本地 一下注册所有的服务 ;

一般开发的时候 ,我们希望本地就能够测试 服务;不想改一个东西  就要重新部署到 开发环境去;

然后我想在本地把所有的服务一下在都注册到注册中心去;怎么搞呢?

image.png

image.png

end

分布式 dubbo + zookeeper + spring 分布式系统(二) 结构 大概就是这样了;

把每一个服务都独立出来;减小耦合度,通过 dubbo 远程调用 ;

现在 只是用到了 dubbo 的 rpc 的功能;dubbo 中还有很多其他的功能 ;

dubbo + zookeeper + spring +mybatis  就是 再加入 mybatis 的配置就行了;

发布于: 刚刚阅读数: 3
用户头像

关注公众号: 石臻臻的杂货铺 获取最新文章 2019-09-06 加入

进高质量滴滴技术交流群,只交流技术不闲聊 加 szzdzhp001 进群 20w字《Kafka运维与实战宝典》PDF下载请关注公众号:石臻臻的杂货铺

评论

发布
暂无评论
dubbo + zookeeper + spring 分布式系统_spring_石臻臻的杂货铺_InfoQ写作社区