Dubbo(二)
六:dubbo用法示例
1.version版本控制
eg:
1.
2.
3.
对于其中注解@EnableAutoConfiguration的作用:
帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot,并创建对应配置类的Bean,并把该Bean实体交给IoC容器进行管理。
2.指定protocol协议
1.
2.
细节记录:
3.使用rest协议使用dubbo框架的服务
1.当我们在服务提供者配置文件中提供了多个协议选择
2.服务提供者中进行选择使用哪一种协议
3.使用rest协议之后,进行启动服务提供者,那么就可以使用postman直接进行路径请求访问:
此时根据rest协议,我们开启了一个8083端口号的服务等待请求进行访问:
测试:
细节记录:
出现的问题【第4点会解决这个问题】
4.消费者通过url直连指定的服务提供者
1.把多个协议都改为dubbo
2.服务提供者还是不指定协议,但是服务消费者指定url路径
3.那么服务提供者由于消费者的url指定,遵循的协议就是协议1
5.服务超时
这个还是比较复杂,记录一下。
结论:服务提供者和服务消费者都可以进行配置服务超时时间(默认超时时间为1秒)
服务提供者的超时时间:
执行该服务整个过程所设定的超时时间。如果超时,则会进行打印超时日志(warn警告),但是服务会正常执行完毕 !
服务消费者的超时时间:
从服务消费者发起服务调用到收到服务提供者响应的整个过程的时间。如果超时,则默认进行两次重试,重试如果都失败则会抛出异常
具体实践中分为两种情况:
1.只在服务提供者和消费者二者中的一个进行配置timeout超时时间。那么最终的效果为:该超时时间会在二者中都生效 !
2.在服务提供者和消费者二者中的都进行配置timeout超时时间
(1)当服务提供者在超时时间内 没有完成对应代码任务的话,我们不会报错异常,而只是会进行warn警告日志打印
(2)但是当服务消费者发出向服务提供者索要服务资源的请求后,没有在超时时间内获取到服务提供者的响应
服务消费者对应控制台会进行报错
6.集群容错
集群的概念:
集群容错的机制
dubbo为集群调用提供了多种容错方案:
我们默认推荐使用failover这种方案:
(1)当服务消费者订阅了zookeeper注册中心之后,获取了服务提供者对应的所有地址。
(2)此时会进行一个负载均衡然后看进行请求哪一台服务消费者对应的服务器。
(3)如果说请求的第一台服务器出错,此时我们就需要请求其他几台处于这个集群地址中的服务器 默认重试两次。
(4)直到重试两次之后,还是出错,那么就真的失败啦 !
细节记录:
我们对于failover这种容错方案下大多进行的是读的操作,为什么?
原因:
假设说当用户进行支付(写的操作)的过程中,发生网络动荡,那么此时会出现幂等性问题。并且此时用户正在付款(写的操作),意思就是说用户以为点了一次之后返回的结果为网络异常,然后用户又进行了多次点击请求,最终造成多次消费执行 最终事与愿违 !
但是如果只是读某个东西的话,出现幂等性问题之后,多次点击,最终结果没有什么影响。
幂等性问题的解决方法:推荐使用悲观锁或乐观锁。回想一下Zookeeper以及Redis中所学知识吧 !
幂等性概念:
幂等性:就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。举个最简单的例子,那就是支付,用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额发现多扣钱了,流水记录也变成了两条。在以前的单应用系统中,我们只需要把数据操作放入事务中即可,发生错误立即回滚,但是再响应客户端的时候也有可能出现网络中断或者异常等等。
7.服务降级
服务降级的使用场景【双11秒杀】:
服务降级实例演示【含双11秒杀屏蔽鸡肋功能的方案】:
1.mock=fail:return+“ ” :
消费者类:
2.mock=force:return+" " ;[双11鸡肋功能屏蔽的解决方案]
消费者类:
8.本地存根
远程服务后,客户端(即服务消费者)通常只剩下接口,而实现的过程全在我们请求的服务端(即服务提供者)。
但是需求出现:
服务提供者有的时候想要在客户端执行部分逻辑代码。如:ThreadLocal缓存,提前验证参数,调用失败后伪造容错数据等。。
解决需求:
此时就需要在API中带上Stub,客户端生成Proxy实例,会把Proxy 通过构造函数传给Stub 1,然后把Stub暴露给用户,Stub 可以决定要不要去调Proxy。
直接演示这个过程:
1.首先我们要在服务消费者获取服务提供者的代理对象的注解上面进行加上一个字段stub,并且设置为true
2.先启动服务提供者端
3.再启动服务消费者端
4.此时客户端(即服务消费者端会生成一个SiteServiceSub的类),这个新生成的类是和SiteService接口处于同一个包下的 !
5.
6.最终结果输出为:stub:leomessi
9.参数回调
参数回调方式与调用本地callback或listener相同,只需要在Spring的配置文件中进行声明哪个参数是callback类型即可。Dubbo将基于长连接生成反向代理,这样
就可以从服务器端(服务提供者)调用客户端(服务消费者)逻辑
一句话:就是服务端(服务提供者)可以调用客户端(服务消费者)的逻辑
如图:
在服务消费者可以提供一个入口,该入口可以允许服务提供者进行调用服务消费者的逻辑
过程演示:
1.服务消费者
2..服务提供者
3.总结:回调其实就是:服务提供者可以进行调用服务消费者的逻辑(方法)
10.异步调用
如果都是同步调用:
如果其中第二步改为异步调用:
此时,即使说第二步执行失败,执行不过去,我们照样可以进行执行最后的步骤3 !这就是异步执行
步骤演示:
1.
2.
3.
4.测试结果
七:dubbo的负载均衡策略
最少活跃调用数的实现
接着这个图来说:该第四步了:
(4) 假设先进行服务第一个服务提供者对应的服务器,那么active先+1,此时第一个服务提供者的active为1。
(5)在第一个请求没有执行完毕时,第二个请求进来了,如果还是访问第一个服务提供者,那么active继续+1,此时第一个服务提供者的active=2
(6)此时第一个服务提供者对应的服务器承受的请求压力已经有两个了,active=2
当这两个请求依次执行完毕后,active-1-1=0。此时可得出访问提供者1的计数差为2,说明请求压过去的多。
(7)此时再有请求分配过来,我们优先分配给后面两个服务提供者,因为它们的active都还为0,说明前后计数差为0,相比于两个请求为结束时的第一台服务器的前
后计数差要小的多,所以优先分配给后面的两台服务器 !
八:安装Dubbo admin监管平台
九:Dubbo的SPI可扩展机制
模拟一下Java的SPI机制:
1.启动测试
2.
3.
4.找到指定的对应文件com.qf.cat之后,该文件中对应的类就会被加载了 !
输出结果:
Java的SPI实际案例:Mysql与JDBC:
1.
2.需要找到Driver类对应的包路径地址
3.在项目的资源中进行寻找java.sql.Driver文件,然后加载该文件中的类
Java的SPI的缺点:
文件中的所有类都会被加载且被实例化。没有办法指定某一个类 来加载和实力化。此时dubbo的SP可以解决
dubbo的SPI机制可以解决Java中的缺点:
体会SPI的AOP效果:
1.
2.找到与Cat类包名相同的文件
3.
4.展现AOP切入功能的逻辑
十:Dubbo源码剖析
1. Dubbo服务调用过程
注:
invoker调用器:理解成为一个调用一个访问提供者需要的完整的细节,封装成为的一个对象
DubboInvoker:这个invoker使用的是dubbo协议,那么就是DubboInvoker
(1)先通过JavassistProxyFactory工厂对象进行生成Proxy代理对象
(2)这个代理对象会进行调用AbstractClusterinvoker类,这个类会去进行调用自己的invoke方法。
这个invoke方法是如何执行的呢?
是通过RegistryDirectory这个类拿到多个invoker调用器,再对多个invoker调用器进行一次负载均衡选取出一个invoker调用器。
如果注册中心为Zookeeper,那么RegistryDirectory类内部会进行封装一个ZookeeperRegistry,ZookeeperRegistry进行真正作用拿到invoker调用器
(3)然后再进行封装这个invoker调用器,封装为一个RpcInvocation对象
(4) 底层再通过DubboInvoker进行调用到相对应的服务提供者