学习网址一

springboot 整合 dubbo

1、定义

是个远程服务调用的分布式框架(告别Web Service模式中的WSdl,以服务者与消费者的方式在dubbo上注册)

2、分布式和集群的区别

小饭店原来只有一个厨师,切菜洗菜备料炒菜全干。后来客人多了,厨房一个厨师忙不过来,又请了个厨师,两个厨师都能炒一样的菜,这两个厨师的关系是集群。为了让厨师专心炒菜,把菜做到极致,又请了个配菜师负责切菜,备菜,备料,厨师和配菜师的关系是分布式,一个配菜师也忙不过来了,又请了个配菜师,两个配菜师关系是集群

3、功能

  • 透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何api侵入。
  • 软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点、
  • 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址。并且能够平滑添加或删除服务提供者。

4、框架

image.png

节点角色说明:

  • Provider:暴露服务的服务提供方。
  • Consumer: 调用远程服务的服务消费方。
  • Registry:服务注册与发现的注册中心。
  • Monitor:统计服务的调用次数和调用时间的监控中心。
  • Container:服务运行容器

运行步骤:

  • 服务容器负责启动,加载,运行服务提供者。
  • 服务提供者在启动时,向注册中心注册自己提供的服务。
  • 服务消费者在启动时,向注册中心订阅自己所需的服务。
  • 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  • 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  • 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

5、使用方法

Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。如果不想使用Spring配置,可以通过API的方式进行调用(注解式,不推荐使用)

6、注册中心zookeeper(不建议使用multicast)

6.1、windows版

下载地址

使用方法:下载解压即可,进入解压目录运行zkServer.cmd启动注册服务中心
截图:
image.png

6.2、MacOS

下载地址
使用方法:下载解压即可,进入解压目录运行zkServer.sh start启动注册服务中心

6.3、Linux

下载地址
使用方法:下载解压即可,进入解压目录运行zkServer.sh start启动注册服务中心

7、服务提供者

7.1、定义服务接口

该接口需单独打包,在服务提供方和消费方共享

  1. package org.apache.dubbo.demo;
  2. public interface DemoService {
  3. String sayHello(String name);
  4. }

7.2、服务提供方实现接口

对服务消费方隐藏实现

  1. package org.apache.dubbo.demo.provider;
  2. import org.apache.dubbo.demo.DemoService;
  3. public class DemoServiceImpl implements DemoService {
  4. public String sayHello(String name) {
  5. return "Hello " + name;
  6. }
  7. }

7.3、用Spring配置声明暴露服务

dubbo-provider.xml:

  1. ?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
  6. <!-- 提供方应用信息,用于计算依赖关系 -->
  7. <dubbo:application name="hello-world-app" />
  8. <!-- 使用multicast广播注册中心暴露服务地址 -->
  9. <dubbo:registry address="multicast://224.5.6.7:1234" />
  10. <!-- dubbo协议在20880端口暴露服务 -->
  11. <dubbo:protocol name="dubbo" port="20880" />
  12. <!-- 声明需要暴露的服务接口 -->
  13. <dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService" />
  14. <!-- 和本地bean一样实现服务 -->
  15. <bean id="demoService" class="org.apache.dubbo.demo.provider.DemoServiceImpl" />
  16. </beans>

7.4、加载Spring配置,启动服务

  1. import org.springframework.context.support.ClassPathXmlApplicationContext;
  2. public class Provider {
  3. public static void main(String[] args) throws Exception {
  4. ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"spring/dubbo-provider.xml"});
  5. context.start();
  6. System.in.read(); // 按任意键退出
  7. }
  8. }

或者使用springBoot启动

  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. import org.springframework.context.annotation.ImportResource;
  4. @SpringBootApplication
  5. @ImportResource("spring/dubbo-provider.xml")
  6. public class DubboProviderApplication {
  7. public static void main(String[] args) throws Exception {
  8. SpringApplication.run(DubboProviderApplication.class, args);
  9. }
  10. }

8、服务消费者

applicationContext-dubbo.xml 中注册自己需要调用的接口。

8.1、通过Spring配置引用远程服务

dubbo-consumer.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
  6. <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
  7. <dubbo:application name="consumer-of-helloworld-app" />
  8. <!-- 使用multicast广播注册中心暴露发现服务地址 -->
  9. <dubbo:registry address="multicast://224.5.6.7:1234" />
  10. <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
  11. <dubbo:reference id="demoService" interface="org.apache.dubbo.demo.DemoService" />
  12. </beans>

8.2、加载Spring配置,并调用远程服务

  1. import org.springframework.context.support.ClassPathXmlApplicationContext;
  2. import org.apache.dubbo.demo.DemoService;
  3. public class Consumer {
  4. public static void main(String[] args) throws Exception {
  5. ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"spring/dubbo-consumer.xml"});
  6. context.start();
  7. DemoService demoService = (DemoService)context.getBean("demoService"); // 获取远程服务代理
  8. String hello = demoService.sayHello("world"); // 执行远程方法
  9. System.out.println( hello ); // 显示调用结果
  10. }
  11. }

或者使用springBoot启动

  1. import org.apache.dubbo.common.logger.Logger;
  2. import org.apache.dubbo.common.logger.LoggerFactory;
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5. import org.springframework.context.annotation.ImportResource;
  6. @SpringBootApplication
  7. @ImportResource("spring/dubbo-consumer.xml")
  8. public class DubboConsumerApplicaiton {
  9. public static final Logger logger = LoggerFactory.getLogger(DubboConsumerApplicaiton.class);
  10. public static void main(String[] args) {
  11. SpringApplication.run(DubboConsumerApplicaiton.class, args);
  12. }
  13. }

并添加对应的restful接口提供接口访问

  1. @RequestMapping("/demo")
  2. public ModelAndView testDemo() {
  3. ModelAndView modelAndView = new ModelAndView("index");
  4. org.apache.dubbo.rpc.RpcContext.getContext().setAttachment(Constants.TAG_KEY, "gray");
  5. modelAndView.addObject("result", demoService.sayHello("Dubbo Meetup"));
  6. return modelAndView;
  7. }

修改对应index页面

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>Vertical centering in valid CSS</title>
  6. <style type="text/css">
  7. .text{text-align:center; }
  8. </style>
  9. </head>
  10. <body>
  11. <div class="text" style="margin-top:300px;font-size: 50px;">${result.msg}</div>
  12. <div class="text" style="margin-top:30px;font-size: 35px;color:#5079bb;">From : ${result.userName}</div>
  13. </body>
  14. </html>

9、dubbo管理页面

下载地址
启动后访问 http://localhost:8080/dubbo-admin/
输入账号密码root/root
image.png
image.png

应用页面:

image.png
提供者页面:
image.png

消费者页面:
image.png

服务页面:

image.png
测试是否成功,只要看状态是否正常,就ok了 ….
image.png

provider-log:

  1. 2019-07-04 11:37:49,326 [DubboServerHandler-192.168.0.46:20880-thread-2] INFO org.apache.dubbo.demo.impl.DemoServiceImpl (DemoServiceImpl.java:31) - [DUBBO] [11:37:49] Hello Alterem., request from consumer: /192.168.0.46:52031, dubbo version: 2.7.0, current host: 192.168.0.46

10、使用Dubbo遇到的问题

10.1、org.springframework.beans.factory.BeanCreationException

原因分析:

  1. Error creating bean with name 'mgmtFactoryInoutDetailsController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'goodsInoutServiceImpl' available
  2. at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:321)

解决方案
在dubbo-provider.xml添加对应的声明暴露服务

  1. <dubbo:service interface="ue.biz.service.biz.GoodsInoutService" ref="goodsInoutServiceImpl"/>

在dubbo-consumer.xml添加对应的服务订阅

  1. <dubbo:reference id="goodsInoutServiceImpl" interface="ue.biz.service.biz.GoodsInoutService"/>

10.2、org.apache.dubbo.rpc.RpcException

原因分析

  1. No provider available from registry 120.79.246.86:2181 for service ue.biz.service.bas.EnterpriseUserService on consumer 192.168.0.63 use dubbo version 2.7.0, please check status of providers

解决方案
可能是因为providers没有启动,或者是provider对应暴露的服务被禁用,启动providers或者解除禁用即可

10.3、java.lang.IllegalStateException

原因分析

  1. this web application instance has been stopped already.
  2. 所以,需要重启Tomcat的情况下才有可能发上,这是第一个出错条件。
  3. Could not load [io.netty.channel.nio.NioEventLoop].
  4. 看这个不能直接推出问题产生条件,但是很明显是关于加载的。

解决方案
总结以上两点,通俗点讲,就是重启了工程(可能是因为直接修改代码,工程reload了), 并且,连过了数据库(登录等),才出现了上述报错信息。 原因是因为在tomcat重启的时候,之前的tomcat的线程还没有完全关闭,最新启动tomcat就会报这个异常。

10.4、org.apache.dubbo.remoting.TimeoutException


原因分析

  1. org.apache.dubbo.remoting.TimeoutException: Waiting server-side response timeout by scan timer. start time: 2019-07-04 15:05:41.363, end time: 2019-07-04 15:05:51.388, client elapsed: 94 ms, server elapsed: 9931 ms, timeout: 10000 ms, request: Request [id=0, version=2.0.2, twoway=true, event=false, broken=false, data=RpcInvocation [methodName=find, parameterTypes=[class ue.biz.entity.sys.Permission$Type], arguments=[url], attachments={path=ue.biz.service.sys.PermissionService

解决方案
在dubbo-provider.xml增加超时时间

  1. <dubbo:provider delay="-1" timeout="10000" retries="0"/>