最基本的Dubbo 工程由服务提供方,消费方,服务接口组成,接口工程中编写所提供服务的接口(interface)由服务提供方实现具体业务逻辑并注册服务,消费方则基于接口工程中所规定的服务接口进行调用,各工程之间基于maven管理依赖。
注册中心:dubbo 支持多种注册中心,其中zookeeper 最为可靠,zookeeper 是apache Hadoop 的子项目,主要是用来解决分布式应用中经常遇到的一些数据管理问题。如:统一命名服务,状态同步服务,集群管理,分布式应用配置项的管理等。
从官网下载zookeeper:http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.12/
改动配置文件:C:\tools\zookeeper\zookeeper-3.4.12\conf---》zoo_sample.cfg【重命名:zoo.cfg】
配置如下: | |
tickTime: | 服务器之间或客户端与服务器之间维持心跳的时间间隔。 |
initLimit: | 配置在集群中与其他zookeeper的链接最大心跳时间间隔数。 |
syncLimit: | 标识Leader 与Follower 之间发送消息时请求和应答的时间长度,规定了在此期间最长不能超过多少各心跳数。 |
dataDir: | 保存数据的目录。 |
clientPort: | 客户端链接服务器的端口,zookeeper会监听这个端口,接受客户端的访问请求。 |
admin.serverPort: | jetty服务的舰艇端口,默认是8080 |
启动:C:\tools\zookeeper\zookeeper-3.4.12\bin---》zkServer.cmd
如果启动不成功,在zkServer.cmd里面最后新起一行加上pause,再次启动,报具体错误,如下,就是java 环境变量没配置好。
仔细检查环境变量:cmd-->java -version 看Java版本是否正确
[win8,win10可能还报这个错:
zkEnv.cmd 编辑,手动指定Java路径:
set JAVA=C:\Program Files\Java\jdk1.8.0_73\bin\java
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_73
]
重新启动---》启动成功
[解决问题参考:zookeeper报错 JAVA_HOME is not set - 白壮丽 - 博客园]
集群配置:
server.A:B:C:D,其中A表示服务器编号,B表示服务器的IP地址,C和D是两个TCP的端口号,分别用于仲裁和leader 选举。
server.1:192.169.1.22:2222:2223
server.2:192.169.1.23:2222:2223
示例表示当前的Zookeeper 与IP为22和23的zookeeper组成集群,如果IP相同,则用于仲裁和选举的端口号需要区分。
Dubbo的@Service 注解用于暴露服务,其可配置的属性如下:
version: | 指定该服务的版本。 |
group: | 服务所属分组,当一个接口有多种实现时,可以用group区分。 |
cache: | 该服务的缓存策略。 lru:基于“最近最少”使用原则删除多余缓存,保持最热的数据被缓存。 thread local:当前线程缓存,比如一个页面渲染,用到很多portal,每个portal都要去查用户信息,通过线程缓存,可以减少这种多余访问。 |
async: | 基于NIO的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务的功能,相对多线程开销较小。 |
delay: | 延迟暴露服务,如果你的服务需要warmup时间,比如初始化缓存,等待相关资源就位等,可以使用delay进行延迟暴露。为-1时,则表示延迟到spring初始化完成后,再暴露服务(基于spring的contextRefreshedEvent事件触发暴露)。 |
timeout: | 调用服务时的超时时间,单位为秒。 |
mock: | 设为true,表示使用缺省mock类名,即接口名+mock后缀,服务接口调用mock实现类,该mock类必须有一个无参构造函数,与local的区别在于,local总是被执行,而mock只在出现非业务异常(比如超时,网络异常等)时的执行。local在远程调用之前执行,mock在远程调用之后执行 |
retries: | 远程服务调用重试次数,不包括第一次调用,不需要重试设为0 |
token: | 令牌验证。如果为空,表示不开启;如果为true,表示随机生成动态令牌;否则使用静态令牌。令牌的作用时防止消费者绕过注册中心直接访问,保证注册中心的授权功能有效,如果使用点对点调用,需关闭令牌功能。 |
dynamic: | 服务是否动态注册,如果设为false,注册后将显示disable状态,需人工启用,并且服务提供者停止时,也不会自动取消注册,需人工禁用。 |
register: | 该协议的服务是否注册到注册中心。 |
deprecated: | 服务是否过时,如果设为true,消费者引用时将打印服务过时警告error日志。 |
access log: | 设为true,将向logger中输出访问日志,也可填写访问日志文件路径,直接把访问日志输出到指定文件。 |
executes : | 在暴露服务中的每个方法服务器端并发执行(或占用线程池中的线程数) |
actives: | 在暴露服务中的每个方法客户端并发执行(或占用链接的请求数) |
loadbalance: | 负载均衡策略,可选值:random,roundrobin,leastactive, 分别表示随机,轮循,最少活跃调用(此参数均为小写)。 |
connections: | 限制客户端服务使用连接数(如果是长链接,比如dubbo协议,connections表示该服务对每个提供者简历的长连接数) |
protocol: | 该服务所使用的协议,不同服务在性能上使用不同协议进行传输,比如大数据用短链接协议,小数据大并发用长连接协议,默认为dubbo。 |
各种协议
dubbo 协议 | 采用单一长连接和NIO异步通信,适用于“小数据量大并发”的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。 |
hessian协议 | 传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传输文件。 |
rmi协议 | 采用JDK标准的Java。rmi实现,常规远程方法调用,与原声RMI服务互相操作。 |
Http协议 | 可用浏览器查看,通过表单或URL传入参数。 |
webservice协议 | soap文本序列化,多用于系统集成,跨语言调用。 |
thrif协议 | 对thrift(Facebook 的rpc框架)的原生协议的扩展。 |
spring.dubbo.application.name: | 当前应用名称,用于注册中心计算应用间依赖关系 |
spring.dubbo.application.version: | 当前应用的版本。 |
spring.dubbo.application.logger: | 日志输出方式,可选:slf4j,jcl,log4j,jdk |
spring.dubbo.registry.address: | 服务所使用的注册中心,A://B:C,其中A为注册中心类型,B为注册中心所在IP地址,C为注册宗信端口号。配置集群时以逗号分隔。例如:A://B:C,A://B2:C2 |
zookeeper注册中心: | 使用zookeeper作为注册中心。 |
multicast 注册中心: | 以广播的方式在地址段224.0.0.0-239.255.255.255实现服务的注册与发现。适合小规模使用,或开发阶段使用。 |
redis 注册中心: | 使用redis作为注册中心,通过心跳的方式检测脏数据,服务器时间必须相同,并且对服务器又一定压力。 |
simple注册中心: | 注册中心本身就是一个普通的dubbo服务,可以减少第三方依赖,使整体通信方式一样。 |
spring.dubbo.registry.username: | 登陆注册中心用户名,如果注册中心不需要验证可不填 |
spring.dubbo.registry.password: | 登陆注册中心密码,如果注册中心不需要验证可不填 |
spring.dubbo.registry.timeout: | 注册中心请求超时时间(毫秒) |
spring.dubbo.registry.register: | 是否向注册中心注册服务,如果设为false,将只订阅,不注册 |
spring.dubbo.registry.subscribe: | 是否向注册中心订阅服务,如果设为false,将只注册,不订阅 |
spring.dubbo.registry.transporter: | 网络传输方式,可选mina,netty |
spring.dubbo.protocol.name: | 服务所使用的协议名称。 |
spring.dubbo.protocol.port: | 服务提供方所暴露的端口号,多个服务提供方不可重复 dubbo协议缺省端口为20880, RMI协议缺省端口号为1099, HTTP和hessian 协议缺省端口为80, 如果配置为-1或者没有配置,则会分配一个没有被占用的端口。 |
spring.dubbo.scan: | 扫描服务所在包路径 |
spring.dubbo.protocol.threadpool: | 线程池类型,可选fixed,cached |
spring.dubbo.protocol.threads: | 服务线程池大小(固定大小) |
spring.dubbo.protocol.iothreads: | IO线程池大小(固定大小) |
spring.dubbo.protocol.accepts: | 服务提供方最大可接受连接数 |
spring.dubbo.protocol.payload: | 请求及响应数据包大小限制,单位为字节,默认为(8M) |
spring.dubbo.protocol.serialization: | 协议序列化方式,当协议支持多种序列化方式时是哟ing,比如:dubbo,hessian2,java原生,以及HTTP协议的json等。 |
Dubbo 的@Reference注解可以用于生成远程服务代理,其可配置属性如下:
version: | 服务版本,与服务提供者的版本一致 |
group: | 服务分组,当一个接口有多个实现时,可以用分组区分,必须和服务提供方一致。 |
timeout: | 服务方法调用超时时间(毫秒) |
retries: | 远程服务调用重试次数,不包括第一次调用,不需要重试设为0 |
connections: | 设置提供者的最大连接数 |
loadbalance: | 负载均衡策略,可选值为:random,roundrobin,leastactive,分别表示:随机,轮询,最少活跃调用(此参数均为小写) |
async: | 是否异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程。 |
check: | 启动时检查提供者是否存在,true报错,false忽略 |
init: | 是否等到有服务注入或引用该实例时再初始化。 |
protocol: | 只调用指定协议的服务提供方,其他协议忽略。 |
cache: | 以调用参数为key,缓存返回结果,可选:lru,threadlocal,jcache等。 |
在application.properties文件配置dubbo:
spring.dubbo.application.name=consumer
spring.dubbo.registry.address = zookeeper://127.0.0.1:2181
spring.dubbo.scan=org.book
与服务提供方的配置一致,指定与服务提供方一致的注册中心地址,并提供不同的application.name便可完成调用端的配置。
测试:启动zookeeper--service---client,控制台显示调用信息。
网关:模块之间相互调用时,为了降低由网络波动带来不确定性因素并提升系统安全性,生产环境中所有模块一般都运行在内网环境中,并单独提供一个工程作为网关服务,开放固定端口代理所有模块提供的服务,并通过拦截器验证所有外部请求已达到权限管理的目的。外部应用有可能时app,网站或桌面客户端,为了达到通用性,网关服务一般为web服务,通过HTTP协议提供restful 风格的api接口。
spring-boot-starter-web支持web应用开发,包含tomcat 和springmvc
网关服务只负责调用模块的服务,通过spring.dubbo.registry.register=false限制只调用服务,并不注册。
server.port:网络服务所访问端口号
使用@RestController表示当前类为一个servlet,并通过注解@RequestMapping映射请求,相当于servlet在web.xml中配置。
@RestController继承自@Controller,它将自动把response 的返回结果进行json序列化,并且可以为请求链接增加.json或.xml后缀来指定序列化方式。如果想使用@Controller达到返回json结构的结果,则需要为每个@RequestMapping增加ResponseBody注解。
dubbo 中所暴露的接口由网关服务转为HTTP协议的api调用,这些接口通常需要安全检查。
实现HandlerInterceptor 接口后,spring提供了3个方法用于不同阶段满足过滤的需求。
aferCompletion():当前对应的Interceptor的preHandle方法返回true时执行,主要用于资源清理工作。
postHandle():当前请求进行处理之后,主要用于日志记录,权限检查,性能监控,通用行为等。
preHandle():在请求处理之前执行,主要用于权限验证,参数过滤等。
spring 允许多个拦截器同时存在,通过拦截器链管理。返回值为true时执行下一个拦截器,直到所有拦截器执行完,再运行被拦截的controller。返回false时不再执行后续的拦截器链及被拦截的controller.
WebMvcConfigurerAdapter用于webmvc环境中的相关配置,通过对addInterceptors()方法称谢可以事之前编写好的拦截器生效。@Configuration 注解则用于标识当前一个配置类,在spring boot 启动时会被加载。
使用addPathPatterns方法设置拦截器规则,而excludePathPatterns方法则可以设置排除的拦截规则。
此处设置的addPathPatterns("/**")表示拦截所有的请求,如果只拦截account目录下的请求,则写成/account/**
测试:zookeeper---服务提供方---网关应用
访问http://localhost:8081 和http:localhost:8081?token=1
监控中心:dubbo 官方提供了dubbo-admin子项目,主要用于路由规则,动态配置,服务降级,访问控制,权重调整,负载均衡等管理。
从官网下载dubbo源码:
也可从我的网址下载dubbo源码:dubbo监控界面_dubbo服务监控-群集服务工具类资源-CSDN下载
把dubbo-admin源码导入到idea 中编译,编译成功后,进入target目录,将编译好的dubbo-admin-2.5.5.war复制到tomcat 下:E:\tools\tomcat\apache-tomcat-7.0.65\webapps\ROOT【之前将下面的所有文件删除掉】,然后解压war 包,删除war包。
war 包解压命令: jar xvf cmd.war
dubbo的配置文件如下:
E:\tools\tomcat\apache-tomcat-7.0.65\webapps\ROOT\WEB-INF\dubbo.properties
测试:依次启动zookeeper,dubbo,打开浏览器访问:http://localhost:8080
注意:tomcat 启动报错:neither the java_home nor the jar_home environment varable is defined
解决,在startup.bat 末尾加:pause[查看原因],如报上错:
原因:因为启动tomcat会调用tomcat安装文件中的startup.bat,而它调用了catalina.bat则调用了setclasspath.bat。因此需要在setclasspath.bat的开头手动声明环境变量。
解决方案:
用vim打开tomcat的bin目录下的setclasspath.sh,添加JAVA_HOME和JRE_HOME两个环境变量(下图红色方框内),两个环境变量路径为您安装的java JDK的路径。
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_73
set jre_home=C:\Program Files\Java\jre1.8.0_73
服务管理:启动服务提供方或消费方项目,便可在服务治理目录下的提供者和消费者页面中查看对应项。
服务:服务提供方所暴露的具体服务,与注解@Service 相关
应用:服务提供方或消费者的名称,由application.properties配置文件中的spring.dubbo.application.name参数设置。
机器:服务提供方或消费方所运行的环境,由IP地址与端口号进行区分。一个机器可以部署多个应用,而一个应用可以提供多个服务。
负载均衡:当并发请求与计算的需求越来越大,一台机器难以处理时,将提供该服务的应用部署在多个机器上,共同向注册中心提交服务,用户发起请求调用服务时,则从注册中心根据负载均衡策略寻找服务提供方,最终稿完成此次调用。
为了适应不同的场景,dubbo负载均衡策略:dubbo提供了4种负载均衡策略,并可以通过实现com.alibaba.dubbo.rpc.cluster.loadbalance接口扩展自定义策略。配置策略时可以在服务提供方@Service 与 消费方@Reference 修改LoadBalance参数,也可以在dubbo-admin中使用图形化界面完成配置。当同时配置了不同的策略时,dubbo-admin优先级大于@Feference ,最后为@Service。dubbo-admin 配置负载均衡位于服务治理下的负载均衡页面。新增配置并提供服务名称,方法名成,负载策略,保存后便可完成配置。
Random LoadBalance : | 随机,按权重设置随机概率。默认策略。 |
RoundRobin LoadBalance : | 轮询,按公约后的权重设置轮询比率。 |
LeastActive LoadBalance : | 最少活跃调用数,相同活跃数指调用前后计数差。 |
ConsistentHash LoadBalance : | 一致性hash ,相同参数的请求总是发给同一提供者。 |
服务降级:分布式环境下服务之间存在一定依赖关系,当整个依赖链中的某个服务崩溃或网络不通时,远程服务无法调用成功并抛出RPCException 异常,为了避免由一个服务崩溃而引起的连锁反应以及保持主业务的正常运行,可以对服务进行降级处理,在调用失败后返回默认数据。
dubbo 通过mock实现服务降级,并提供了两种配置方式
简单降低:设置服务消费方@Reference注解的mock参数为return null,表示当远程调用失败时直接返回null,或者其他默认值(return something).
示例:
@Reference(mock="return null")
private IHello hello;
复杂降级:mock可以指定一个具体的类,当调用失败时执行,以满足复杂的业务逻辑,mock类需要实现服务接口,类名规范为:接口名+Mock。
public class IHelloMock implements IHello{
public String say(String msg){
return "降级数据";
}
}
在服务提供方,配置注解@Service 指定mock类所在位置:
@Service(mock = "org.book.service.IHelloMock")
public class HelloImple implements IHello {
@Override
public String say(String s) {
try{
Thread.sleep(10*1000);
}catch (Exception e){
e.printStackTrace();
}
return s;
}
}
在服务调用方,配置注解@Reference设置mock 为true 开启降级
@Reference(mock="return null")
private IHello hello;
集群容错:为了提供系统可用性,将服务提供方部署成多个组成服务集群,在消费方调用服务失败或超时,Dubbo可以配置多种策略重新调用集群中的其他服务提供方。
在提供方的@Service 和消费方的@Reference注解中配置cluster参数,或者用application.properties 中的spring.dubbo.service.cluster参数来指定容错策略。
FailLover Cluster : | 失败自动切换,当出现失败时,重试其他服务 器(默认),通常用于读操作,但重试会带来更长延时。可以通过服务提供方的@Service 和消费方的@Reference注解设置retries参数来指定重试次数(不含第一次)。 失败自动切换,当出现失败时,重试其他服务 器(默认) 使用场景:通常用于读操作,但重试会带来更长延时。可以通过服务提供方的@Service 和消费方的@Reference注解设置retries参数来指定重试次数(不含第一次) |
Failfast Cluster: | 快速 失败,指发起一次调用,失败立即报错。 使用场景:通常由于非幂等性的写操作,比如新增记录 |
Failsafe Cluster: | 失败安全,出现异常时,直接忽略。 使用场景:通常用于写入审计日志等操作 |
Failback Cluster: | 失败自动恢复,后台记录失败请求,定时重发。 使用场景:通常用于消息通知操作。 |
Forking Cluster: | 并行调用多个服务器,只要一个成功及返回。 使用场景:通常用于实时性要求较高的读操作,但需要浪费更多服务资源。 |
Broadcast Cluster: | 广播调用所有提供者,逐个调用,任意一台报错则报错。 使用场景:通常用于通知所有提供者更新缓存或日志等本地资源信息 |
项目展示[dubbo-api]:dubbo-api服务_dubboapi-Java代码类资源-CSDN下载
项目展示[dubbo-service]:dubbo-service实现-Java代码类资源-CSDN下载
项目展示[dubbo-client]:dubbo-client客户端_dubbo客户端,java实现dubbo客户端-Java代码类资源-CSDN下载
项目展示[dubbo-getway]:https://download.csdn.net/download/qq_35781178/10542302
项目展示[完整]:GitHub - waitforyouwtt/dubbo