zoukankan      html  css  js  c++  java
  • Dubbo分布式服务框架入门使用和跟事务共同使用时提供者(Provider)没能发布到注册中心解决方案

    一、Dubbo入门写个demo

    概念:

    Provider
    暴露服务方称之为“服务提供者”。
    Consumer
    调用远程服务方称之为“服务消费者”。
    Registry
    服务注册与发现的中心目录服务称之为“服务注册中心”。
    Monitor
    统计服务的调用次数和调用时间的日志服务称之为“服务监控中心”。

    想了解更为深层的概念推荐详细解说杨老师:

      https://www.cnblogs.com/yjmyzz/p/dubbox-demo.html

    服务定义
    服务是围绕服务提供方和服务消费方的,服务提供方实现服务,而服务消费方调用服务。

    服务注册
    对于服务提供方,它需要发布服务,而且由于应用系统的复杂性,服务的数量、类型也不断膨胀;对于服务消费方,它最关心如何获取到它所需要的服务,而面对复杂的应用系统,需要管理大量的服务调用。而且,对于服务提供方和服务消费方来说,他们还有可能兼具这两种角色,即既需要提供服务,有需要消费服务。
    通过将服务统一管理起来,可以有效地优化内部应用对服务发布/使用的流程和管理。服务注册中心可以通过特定协议来完成服务对外的统一。Dubbo提供的注册中心有如下几种类型可供选择:

    • Multicast注册中心
    • Zookeeper注册中心
    • Redis注册中心
    • Simple注册中心

    服务监控
    无论是服务提供方,还是服务消费方,他们都需要对服务调用的实际状态进行有效的监控,从而改进服务质量。

    以下皆是个人理解,如若有错误,还望指出,谢谢!

       dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架(告别Web Service模式中的WSdl,以服务者与消费者的方式在dubbo上注册)

    下面就来说说入门使用dubbo,本文使用的注册中心是Zookeeper注册中心,在Linux系统下,开发工具是Intellij Idea,使用springboot微服务框架

      准备工作:下载注册中心Zookeeper,下载地址 http://www.apache.org/dyn/closer.cgi/zookeeper/ 

    第一步:

      启动注册中心Zookeeper

      windows下

        直接找到文件apach-zookeeper-3.4.5in,目录下的zkServer.cmd双击启动

      linux下

        同样找到文件目录 ,本人的是在 /usr/java/zookeeper/bin       使用 ./zkServer.sh start启动 ,启动需要一定时间,所以可以反复查看运行状态,输入 ./zkServer.sh status

    第二步:

      访问Dubbo

      widows下

        直接访问http://localhost:8080即可

      linux下

        关闭防火墙 service iptables stop

        启动注册中心

        启动Tomcat,找到安装目录输入./startup.sh

        访问http://装有注册中心的linux系统IP:8080

        

      到这里已经可以查看登陆到Zookeeper注册中心:

        1,首先可以先查看下tomcate猫的启动状态 ,输入  http://当前启动注册中心的机器ip地址:8080                                    ( tomcat默认8080端口)

        2,输入  http://当前启动注册中心的机器ip地址:8080/dubbo-admin/  进入到注册中心

        3,注册中心会提示你输入密码 默认账号是root,密码是root,登陆成功后进入以下界面

        

        4,登陆注册中心后,什么都没有,下面就开始写代码

        4.1 服务提供者

            4.1.1在pom.xml中加入依赖

          <dubbo.version>2.5.3</dubbo.version>                                
             <zookeeper.version>3.4.7</zookeeper.version>                        
             <zkclient.version>0.1</zkclient.version>                        
                                    
           <!-- dubbo相关 -->                                
                <dependency>                    
                    <groupId>com.alibaba</groupId>                
                    <artifactId>dubbo</artifactId>                
                    <version>${dubbo.version}</version>                
                </dependency>                    
                <dependency>                    
                    <groupId>org.apache.zookeeper</groupId>                
                    <artifactId>zookeeper</artifactId>                
                    <version>${zookeeper.version}</version>                
                </dependency>                    
                <dependency>                    
                    <groupId>com.github.sgroschupf</groupId>                
                    <artifactId>zkclient</artifactId>                
                    <version>${zkclient.version}</version>                
           </dependency>                    

         4.1.2  

           逻辑代码还是像平时一样,该怎么写就怎么写,但要注意:

              服务提供者必须把Interface接口写成一个包,并且暴露出来

             在本项目中再去实现service的接口,并且注入的@service必须为 alibaba下提供的service,但是这有弊端,就是不能跟事务@Transactional共同使用,具体解释看文章结尾,

             例如:

               import com.alibaba.dubbo.config.annotation.Service;//引入的包是albaba提供的bean
               @Service
                  public class StudentService implements StudentService{
                  //实现本项目下接口包的方法
               }

         4.1.3  向注册中心中给提供者的注册下

          如果你使用是springboot微服务框架

          在application.properties总配置文件中加入 注册

    #注册到zookeeper 中服务的名字
    spring.dubbo.application.name=lwh_provider
    #注册中心的地址,ip为启动了zookeeper的linux服务器的ip,2181是注册中心的默认端口
    spring.dubbo.registry.address=zookeeper://192.168.25.129:2181
    #使用dubbo协议
    spring.dubbo.protocol.name=dubbo
    #dubbo服务在哪个端口暴露
    spring.dubbo.protocol.port=20880
    #去哪里扫描dubbo的服务组件,这是你service接口的实现类的包名,也就是上面提到的为什么把接口暴露出来
    spring.dubbo.scan=com.lwh.service.impl

           如果你使用是spring,那就再spring配置中加入 注册

    <?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-admin 或 dubbo-monitor 会显示这个名字,方便辨识-->
        <dubbo:application name="demotest-provider" owner="programmer" organization="dubbox"/>
        <!--使用 zookeeper 注册中心暴露服务,注意要先开启 zookeeper-->
        <dubbo:registry address="zookeeper://localhost:2181"/>
        <!-- 用dubbo协议在20880端口暴露服务 -->
        <dubbo:protocol name="dubbo" port="20880" />
        <!--使用 dubbo 协议实现定义好的 api.PermissionService 接口-->
        <dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" protocol="dubbo" />
        <!--具体实现该接口的 bean-->
        <bean id="demoService" class="com.alibaba.dubbo.demo.impl.DemoServiceImpl"/>
    </beans>

        5 服务消费者

         5.1 跟提供者一样,加入依赖

         5.2 代码依旧跟以前一样写

          但是注意的是写action时:你使用的service接口中的方法是提供者暴露出来的那个接口,所以,注入不能是@Autowired按类型注入了

          而是使用 alibaba提供的@Reference注入,例如:

    1 import com.alibaba.dubbo.config.annotation.Reference;
    2 
    3 @Controller
    4 public class StudentAction {
    5     @Reference
    6     private StudentService studentService;
    7 
    8 
    9 }

         5.3 向注册中心中给消费者的注册下

          如果你使用是springboot微服务框架

          在application.properties总配置文件中加入 注册

    #消费者 在注册中心注册的名字
    spring.dubbo.application.name=lwh_Consumer
    #注册中心的地址
    spring.dubbo.registry.address=zookeeper://192.168.25.129:2181
    #去哪里扫描消费者
    spring.dubbo.scan=com.lwh.action

             如果你使用是spring,那就再spring配置中加入 注册

    <?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="demotest-consumer" owner="programmer" organization="dubbox"/>
        <!--向 zookeeper 订阅 provider 的地址,由 zookeeper 定时推送-->
        <dubbo:registry address="zookeeper://localhost:2181"/>
        <!--使用 dubbo 协议调用定义好的 api.PermissionService 接口-->
        <dubbo:reference id="permissionService" interface="com.alibaba.dubbo.demo.DemoService"/>
    </beans>

     然后让两个项目跑起来后,再去登陆注册中心会发现自己发布的已经注册到注册中心去了

    提供者

     

    消费者

     到此为止,dubbo的入门就结束了,实际中有多提供者多消费者情况,比这要复杂的多,当然只有这样才能体现dubbo的特性。

    二、下面来说说关于Dubbo使用alibaba下的@Service注入发布Dubbo服务时,同时使用了@Transactional注解加入事务后Dubbo服务不能发布的问题,

    也就是说不能同时使用@com.alibaba.dubbo.config.annotation.Service和@Transactional

      原因:因为当你使用事务后,spring bean中事务是使用事务代理的,简单说就是执行者不是本体,而是代理类,那么,问题来了,这个时候Dubbo的AnnotationBean扫描类执行扫描代码时,就获取不到对应的注解,自然而然就发布不服务了

      解决方案

         经过网络上再三寻找方法,发现有四种解决方案,但是个人觉得可执行的只有两种:

         方法一(个人认为实用型):

          使用了@Transactional注解加入事务后,就不要使用@com.alibaba.dubbo.config.annotation.Service提供的@Service注解了,使用spring提供的@Service,然后自己写个xml文件去配置Dubbo的服务

    dubbo.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:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    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-4.2.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.2.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util-4.2.xsd
    http://code.alibabatech.com/schema/dubbo
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 配置包扫描器 -->
    <context:component-scan base-package="com.lwh"/>
    <!-- 使用dubbo发布服务 -->
    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="dubbo_p" />
    <dubbo:registry protocol="zookeeper"
    address="192.168.25.129:2181" />
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" />
    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="com.lwh.provider.service.UserService" ref="UserServiceImpl" timeout="600000"/>
    </beans>

        方法二(反正我试了没用)

                     接着使用alibaba提供的dubbo@Service发布dubbo服务,但是不使用spring提供的@Transactioncal注解加入的事务,使用自己配置的方式去加入事务,这里就不提供代码了

        方法三(简直疯了,居然改源码)

           修改Dubbo的源码,也就是让注解的事务代理,强制去让他自己处理

        

            

     以上是个人所理解,技术有限,如若有错误,希望能够提出交流,谢谢!

  • 相关阅读:
    [转]使用@Test 也可以从spring容器中获取依赖注入
    idea/ecipse中使用maven集成springmvc相关jar包时候,出错:java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet
    mongodb 权限设置--用户名、密码、端口
    java中import static和import的区别【转】
    python 数字的四舍五入的问题
    数据库——索引(面试、笔试必会)
    Python 中的那些坑总结——持续更新
    python2和python3的区别——持续更新
    常用的排序算法的时间复杂度和空间复杂度
    Libpacp 深度剖析
  • 原文地址:https://www.cnblogs.com/lwh-note/p/9013150.html
Copyright © 2011-2022 走看看