springBoot整合Dubbo的使用
Zookeeper
ZooKeeper是一种为分布式应用所设计的高可用、高性能且一致的开源协调服务,它提供了一项基本服务:分布式锁服务。由于ZooKeeper的开源特性,后来我们的开发者在分布式锁的基础上,摸索了出了其他的使用方法:配置维护、组服务、分布式消息队列、分布式通知/协调等。
建议使用zookeeper3.4.5及以上版本注册中心。
Zookeeper是Apache Hadoop的子项目,强度相对较好,建议生产环境使用该注册中心。
Dubbo未对Zookeeper服务器端做任何侵入修改,只需安装原生的Zookeeper服务器即可,所有注册中心逻辑适配都在调用Zookeeper客户端时完成。
Zookeeper配置
1、下载zookeeper
2、然后修conf/zoo.cfg
dataDir=D:\zookeeper-3.3.6\\data
dataLogDir=D:\zookeeper-3.3.6\\log
3、执行zkServer.cmd,启动Zookeeper
监控中心
监控中心的主要使用就是查看dubbo提供者和消费者的信息,以及他们的调用情况。
监控中心配置
1、下载dubbo-monitor
2、然后修conf/dubbo.properties
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.jetty.port=28080
3、执行start.bat,启动监控中心
监控中心界面
在浏览器输入 http://localhost:8080,就可以进入监控中心

构建API模块
项目结构:
springbootdubboapi 
springbootdubboclient
springbootdubboservice
api模块中就一个接口,然后将api模块打包(maven→Lifecycle→install)双击install
public interface TestServiceApi { String sayHello(String name); }
Dubbo服务提供者
Pom.xml添加dubbo依赖
<!-- spring web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 整合dubbo--> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <!-- zookeeper客户端--> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.11</version> </dependency> <!-- 打包的api路径 --> <dependency> <groupId>com.test</groupId> <artifactId>springbootdubbo_api</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
application.yml配置dubbo注册中心
server: port: 8081 # 端口号 spring: dubbo: # Dubbo服务提供者配置 application: name: provider # 服务名称 registry: address: zookeeper://127.0.0.1:2181 # 注册中心地址 protocol: name: dubbo # dubbo协议 port: 28081 # dubbo协议端口
提供服务
@Service //注意是com.alibaba.dubbo.config.annotation.Service包的service @Component public class ITestService implements TestServiceApi { @Override public String sayHello(String s) { return "Hello" + s; } }
启动服务
注意加上@EnableDubboConfiguration注解
@SpringBootApplication @ComponentScan(basePackages = "com.Test.*") @EnableDubboConfiguration public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
监控中心可查看到发布的服务

Dubbo服务消费者
Pom.xml添加dubbo依赖
<!-- spring web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 整合dubbo--> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <!-- zookeeper客户端--> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.11</version> </dependency> <!-- 打包的api路径 --> <dependency> <groupId>com.test</groupId> <artifactId>springbootdubbo_api</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
application.yml配置dubbo注册中心
server: port: 8082 # 端口号 spring: dubbo: # Dubbo服务提供者配置 application: name: provider # 服务名称 registry: address: zookeeper://127.0.0.1:2181 # 注册中心地址 protocol: name: dubbo # dubbo协议 port: 28082 # dubbo协议端口
消费者调用服务
@RestController @RequestMapping(value = "/test") public class DepController { @Reference //注意是com.alibaba.dubbo.config.annotation.Reference包的 private TestServiceApi testServiceApi; @RequestMapping(value = "/sayHello") public String sayHello() { return testServiceApi.sayHello("张三消费者"); } }
启动消费者
注意加上@EnableDubboConfiguration注解
@SpringBootApplication @ComponentScan(basePackages = "com.test.*") @EnableDubboConfiguration public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
监控中心可查看到发布的consumer服务

输入网址就能显示内容了
http://localhost:8082/test/sayHello
超时时间,重试次数配置
timeout:可以设置duboo调用的超时时间(毫秒为单位)
retries :可以设置重试次数
@Service(timeout = 1000, retries = 3, group = "group1")
@Component
服务分组
可以用group属性
示例:
@Service(timeout = 1000, retries = 3, group = "group1") @Component public class IEmpService implements EmpServiceApi { @Override public String sayHello(String s) { return "hello" + s; } } @Service(timeout = 1000, retries = 3, group = "group2") @Component public class IEmpService implements EmpServiceApi { @Override public String sayHello(String s) { return "hello" + s; } } @RestController @RequestMapping(value = "/test") public class EmpController { @Reference(group = "group1", loadbalance = "roundrobin") private TestServiceApi testServiceApi1; @Reference(group = "group2", loadbalance = "roundrobin") private TestServiceApi testServiceApi2; @RequestMapping(value = "/sayHello1") public String sayHello() { return empServiceApi1.sayHello("消费者1"); } @RequestMapping(value = "/sayHello2") public String sayHello() { return empServiceApi2.sayHello("消费者2"); } }
负载均衡算法
random 随机
leastactive 最小活跃值
consistenthash 一致哈希
roundrobin 轮询
配置:

random:权重随机算法,根据权重值进行随机负载。它的算法思想很简单。
假设我们有一组服务器 servers = [A, B, C],他们对应的权重为 weights = [5, 3, 2],权重总和为 10。
现在把这些权重值平铺在一维坐标值上,[0, 5) 区 间属于服务器 A,[5, 8) 区间属于服务器 B,[8, 10) 区间属于服务器 C。
接下来通过 随机数生成器生成一个范围在 [0, 10) 之间的随机数,然后计算这个随机数会落到哪个 区间上。
比如数字 3 会落到服务器 A 对应的区间上,此时返回服务器 A 即可。
权重 越大的机器,在坐标轴上对应的区间范围就越大,因此随机数生成器生成的数字就会 有更大的概率落到此区间内。
只要随机数生成器产生的随机数分布性很好,在经过多 次选择后,每个服务器被选中的次数比例接近其权重比例。
leastactive:最少活跃调用数算法,活跃调用数越小,表明该服务提供者效率越高,单位时间内可处理更多的请求这个是比较科学的负载均衡算法。 
每个服务提供者对应一个活跃数 active。初始情况下,所有服务提供者活跃数均为 0。 每收到一个请求,活跃数加 1,完成请求后则将活跃数减 1。
在服务运行一段时间后, 性能好的服务提供者处理请求的速度更快,因此活跃数下降的也越快,此时这样的服 务提供者能够优先获取到新的服务请求。
consistenthash:hash 一致性算法,相同参数的请求总是发到同一提供者 当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者, 不会引起剧烈变动。
roundrobin:加权轮询算法是指将请求轮流分配给每台服务器。
举个例子,我们有三台服务器 A、B、C。 我们将第一个请求分配给服务器 A,第二个请求分配给服务器 B,第三个请求分配给 服务器 C,第四个请求再次分配给服务器 A。
这个过程就叫做轮询。轮询是一种无状 态负载均衡算法,实现简单,适用于每台服务器性能相近的场景下。
但现实情况下, 我们并不能保证每台服务器性能均相近。
如果我们将等量的请求分配给性能较差的服 务器,这显然是不合理的。
因此,这个时候我们需要对轮询过程进行加权,以调控每 台服务器的负载。经过加权后,每台服务器能够得到的请求数比例,接近或等于他们 的权重比。
比如服务器 A、B、C 权重比为 5:2:1。那么在 8 次请求中,服务器 A 将 收到其中的 5 次请求,服务器 B 会收到其中的 2 次请求,服务器 C 则收到其中的 1次请求。
集群容错
在分布式网络通信中,容错能力是必须要具备的,什么叫容错呢? 从字面意思来看: 容:是容忍, 错:是错误。 就是容忍错误的能力。
我们知道网络通信会有很多不确定因素,比如网络延迟、网络中断、服务异常等,会造成当前这次请求出现失败。当服务通信出现这个问题时,需要采取一定的措施应对。
而 dubbo 中提供了容错机制来优雅处理这种错误,在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。

failover:失败自动切换,当出现失败,重试其它服务器。(缺省) 通常用于读操作,但重试会带来更长延迟。 可通过 retries=“2” 来设置重试次数(不含第一次)。
failfast:快速失败,只发起一次调用,失败立即报错。 通常用于非幂等性的写操作,比如新增记录。
failsafe:失败安全,出现异常时,直接忽略。 通常用于写入审计日志等操作。
failback:失败自动恢复,后台记录失败请求,定时重发。 通常用于消息通知操作。
forking:并行调用多个服务器,只要一个成功即返回。 通常用于实时性要求较高的读操作,但需要浪费更多服务资源。 可通过 forks=“2” 来设置最大并行数。
broadcast:广播调用所有提供者,逐个调用,任意一台报错则报错。(2.1.0 开始支持) 通常用于通知所有提供者更新缓存或日志等本地资源信息。
在实际应用中查询语句容错策略建议使用默认 failover ,而增删改建议使用 failfast 或者使用 failover (retries=”0”) 策略,防止出现数据重复、添加等等其它问题!
建议在设计接口时候把查询接口方法单独做一个接口提供查询。
服务降级
当某个非关键服务出现错误时,可以通过降级功能来临时屏蔽这个服务。降级可以有几个层面的分类: 自动降级和人工降级; 按照功能可以分为:读服务降级和写服务降级; 
1. 对一些非核心服务进行人工降级,在大促之前通过降级开关关闭哪些推荐内容、评 价等对主流程没有影响的功能。
2. 故障降级,比如调用的远程服务挂了,网络故障、或者 RPC 服务返回异常。 
那么 可以直接降级,降级的方案比如设置默认值、采用兜底数据(系统推荐的行为广告 挂了,可以提前准备静态页面做返回)等等 。
3. 限流降级,在秒杀这种流量比较集中并且流量特别大的情况下,因为突发访问量特 别大可能会导致系统支撑不了。
这个时候可以采用限流来限制访问量。当达到阀值 时,后续的请求被降级,比如进入排队页面,比如跳转到错误页(活动太火爆,稍 后重试等)
Dubbo中如何实现服务降级?
Dubbo中提供了一个mock的配置,可以通过 mock来实现当服务提供方出现网络异常或者挂掉以后,客户端不抛出异常,而是通过 Mock数据返回自定义的数据 。
客服端调用服务配置参数,增加mock配置,以及修改timeout=500, 表示本次调用的超时时间是0.5秒,
这样可以模拟出失败的场景 需要配置cluster=failfast,否则因为默认是failover导致客户端会发起3次重试,等待的时间比较长。
 
 
服务端代码,只需要加一个休眠时间让客户端调用超时即可。

启动时检查
Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 check="true"。
可以通过 check="false" 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。


 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号