赞
踩
主流的注册中心:
Zookeeper应用及原理_MG-net的博客-CSDN博客
rpc是一种协议,一种远程过程调用协议,规定了双方通信采用什么格式、以及数据如何传输。
总结,RPC解决的问题:
dubbo除了提供RPC协议,还提供了服务发现和注册、流量调度、可视化服务治理和运维、智能容错和负载均衡。所以dubbo是一个服务框架。

1、服务提供者配置

在zk中,可以看到相关的节点文件:

2、服务消费者

服务代理的过程:

可以看出,在dubbo中,服务提供者把提供的服务注册到注册中心中,消费者可以在像使用自己本地的Bean一样使用远程的提供者的服务。dubbo底层采用netty框架进行网络通信。

1、服务提供者
double的pom依赖:
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-spring-boot-starter</artifactId>
- <version>3.0.6</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-registry-zookeeper</artifactId>
- <version>3.0.6</version>
- </dependency>
在启动类上增加注解:@EnableDubbo
在实现类上增加注解:@DubboService
配置文件配置dubbo的相关信息:
- server:
- port: 9001
- dubbo:
- application:
- name: dubbo_provider
- protocol:
- name: dubbo
- port: 20882
- registry:
- address: zookeeper://127.0.0.1:2181
启动后,服务提供着就自动注册到zk中了。
2、服务消费者
引入pom依赖:
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-spring-boot-starter</artifactId>
- <version>3.0.6</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-registry-zookeeper</artifactId>
- <version>3.0.6</version>
- </dependency>
在启动类上增加注解:@EnableDubbo
注入类的时候,使用注解:@DubboReference,这个注解做了2件事
配置文件中配置dubbo信息:
- server:
- port: 8001
- dubbo:
- application:
- name: consumer
- registry:
- address: zookeeper://127.0.0.1:2181
3、@EnableDubbo的用法
注解流程:
@EnableDubbo->@EnableDubboConfig、@DubboCompentScan

服务提供者可以指定版本号,这样消费者可以调用需要指定的版本号即可。


dubbo协议可支持的协议:
在配置文件:

在配置文件中,可以使用 protocols 进行多协议配置。

在提供者或者消费者端配置需要使用的协议即可:

如果配置服务未指定协议,但是配置文件配置了多个协议,那么就会生成配置个数的服务,例如配置了2种协议dubbo、rest,那么就会生成2个服务一个是dubbo协议、一个是rest协议。

需要注意依赖的引入。使用到jboss的依赖
- <!-- Dubbo rest protocol -->
- <dependency>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>resteasy-jaxrs</artifactId>
- <version>3.15.1.Final</version>
- </dependency>
-
- <dependency>
- <groupId>javax.validation</groupId>
- <artifactId>validation-api</artifactId>
- <version>1.1.0.Final</version>
- </dependency>
同时需要注意,使用服务器,tomcat

如果服务提供者配置了多个协议,那么在启动服务的时候,就会根据不同的协议提供多个服务。
如果在消费者这边 指明消费某个服务,需要配置:
- @RestController
- @RequestMapping("site")
- public class SiteContorller {
-
- //订阅服务
- //生成代理对象
- @DubboReference(version = "v2", url = "dubbo://127.0.0.1:20882/com.mg.boot.api.SiteService")
- private SiteService siteService;
-
- @GetMapping("getName")
- public String getName(String name){
- return siteService.getName(name);
- }
-
- }
服务超时,就是调用接口超过服务消费者设置的最长时间。
在dubbo中,直接使用timeout,设置服务的超时时间。
服务提供者:如果超时,会打印超时日志,并且会执行完毕。
- @DubboService(version = "timeout", timeout = 4000)
- public class TimeOutSiteSerivce implements SiteService {
-
- @Override
- public String getName(String name) {
- try {
- Thread.sleep(5000);
- }catch (Exception e){}
- System.out.println("服务。。。。");
- return "timeout service " + name;
- }
- }
服务消费者:如果超时,则进行重试,重试失败抛出异常。
- @DubboReference(version = "timeout", timeout = 6000)
- private SiteService siteService;
服务提供者在任何情况下,都会执行业务逻辑。重试2次,就会执行3次(第一次是正常调用)。
@DubboReference(version = "timeout", timeout = 3000, cluster = "failover", retries = 1)
dubbo提供的集群容错方案:
结论:使用dubbo的时候,不推荐把重试关闭,在非幂等操作场景下,服务提供者需要提供幂等解决方案。
所谓的服务降级,就是当达到流量高峰的时候,需要保留核心业务的使用。
mock:接口提供假数据的功能。
- @DubboReference(version = "timeout", timeout = 3000, mock = "fail:return timeout")
- private SiteService siteService;
本地存根,就是在服务消费者执行部分逻辑。
首先在消费方开启本地存根功能:
- @DubboReference(version = "timeout", timeout = 1000, stub = "true")
- private SiteService siteService;
同时在接口的相同包下建立存根类,这样就会在注入接口的时候,在封装一层存根类的逻辑:
- public class SiteServiceStub implements SiteService {
-
- private final SiteService siteService;
-
- public SiteServiceStub(SiteService siteService) {
- this.siteService = siteService;
- }
-
-
- @Override
- public String getName(String name) {
- try {
- return siteService.getName(name);
- }catch (Exception e){
- return "stub" + name;
- }
- }
- }

消费者为服务提供者提供一个回调接口,也就是参数回调。
- package com.mg.boot.api;
-
- public interface SiteServiceCallBack {
-
- String siteName(String name);
-
- default String siteName(String name , String key, SiteServiceCallBackListener siteServiceCallBackListener){
- return null;
- }
- }
-
- import java.io.Serializable;
-
- public class SiteServiceCallBackListenerImpl implements SiteServiceCallBackListener, Serializable {
- @Override
- public String change(String data) {
- System.out.println("change:" + data);
- return "change:" + data;
- }
- }
- @DubboService(version = "callback", methods = {@Method(name="siteName", arguments = {@Argument(index = 2, callback = true)})}, callbacks = 3)
- public class SiteServiceCallBackImpl implements SiteServiceCallBack {
-
-
- @Override
- public String siteName(String name) {
- return null;
- }
-
- @Override
- public String siteName(String name , String key, SiteServiceCallBackListener siteServiceCallBackListener){
- siteServiceCallBackListener.change("p data");
- return "cc:" + name;
- }
-
- }

- @DubboReference(version = "callback")
- private SiteServiceCallBack siteServiceCallBack;
-
- @GetMapping("getName")
- public String getName(String name){
- return siteServiceCallBack.siteName(name, "key", new SiteServiceCallBackListenerImpl());
- }
主要使用 CompletableFuture 接口进行一步数据的返回。
- @Override
- public CompletableFuture<String> siteNameAsync(String name){
- System.out.println("data:" + name);
- return CompletableFuture.supplyAsync(()->{
- return siteName(name);
- });
- }
官方提供的集中负载均衡的策略:
可以使用本地安装,也可以使用docker安装。这里介绍受用docker安装方式。
docker run --name dubbo-admin -d -p 7001:7001 dubbo-admin:1.0
在admin中,可以配置相关权重、方法路由规则等等。
典型的使用sip,就是jdbc。java内部之约定了jdbc的接口,并没有提供具体实现。当需要连接mysql数据库的时候,就需要mysql实现这套jdbc的接口。这就是java中的sip机制。
如mysql jdbc:

java的DriverManager就会读取这个文件,获取实现类的全路径。
简单理解就是定义一套规范,实现来自不同的供应者,当需要使用哪个供应者的相关内容,引入即可。


自己实现的时候,就使用SeviceLoader 进行加载 配置文件中配置的实现类。
可以看出java中sip存在,当配置多个实现类的时候,使用ServiceLoader可以获取多个,没有办法指定某一个,不够灵活。


可以看到,在dubbo中,可以指明需要哪个实现类。
在dubbo中,有很多地方使用spi,例如服务调用协议的部分,根据配置文件中的配置,进行协议的使用。
同时,还可以在spi实现类中实现AOP的效果,其实就是在实现代码的时候,在前面或者后面增加相关功能。



a、服务消费者获取代理对象
b、 在注册中心获取服务集群(缓存在消费者本地的地址列表),使用ZookeeperRegistry
c、使用服务器集群中的Invoker调用器,Invoker封装了一次调用流程的整体内容
d、参数、方法名称等封装在RpcInvcation中,使用DubboInvoker进行调用
通过源码可以看出,Invoker调用采用的是装饰着模式,每一层封装不同的功能。

权重轮训就是根据权重去轮训相关内容,例如A、B、C三台权重6、2、2,那调用应该是ABACA的顺序。

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。