备注:源码的分析是基于2.5.4版本
1.主机绑定
可以参考:https://dubbo.apache.org/zh-cn/docs/user/demos/hostname-binding.html
在发布一个Dubbo服务的时候,会生成一个dubbo://ip:port的协议地址,那么这个IP是根据什么生成的呢?大家可以在ServiceConfig.java代码中找到如下代码;可以发现,在生成绑定的主机的时候,会通过一层一层的判断,直到获取到合法的ip地址。
在ServiceConfig类中doExportUrlsFor1Protocol可以看到
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
String name = protocolConfig.getName();
if (name == null || name.length() == 0) {
name = "dubbo";
}
//得到协议配置的地址
String host = protocolConfig.getHost();
if (provider != null && (host == null || host.length() == 0)) {
host = provider.getHost();
}
boolean anyhost = false;
//地址是否有效 localhost或者0.0.0.0,127开头的地址无效
if (NetUtils.isInvalidLocalHost(host)) {
anyhost = true;
try {
//得到本机的地址
host = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
logger.warn(e.getMessage(), e);
}
//如果无效,通过了解注册中心的地址来获取本机的地址
if (NetUtils.isInvalidLocalHost(host)) {
if (registryURLs != null && registryURLs.size() > 0) {
for (URL registryURL : registryURLs) {
try {
Socket socket = new Socket();
try {
//组装祖册中心的地址
SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());
socket.connect(addr, 1000);
//从socket拿到本机的地址
host = socket.getLocalAddress().getHostAddress();
break;
} finally {
try {
socket.close();
} catch (Throwable e) {}
}
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
}
if (NetUtils.isInvalidLocalHost(host)) {
// 如果还是无效,则遍历本地网卡,返回第一个合理的IP。
host = NetUtils.getLocalHost();
}
}
}
....
2.集群容错
可以参考官网: https://dubbo.apache.org/zh-cn/docs/user/demos/fault-tolerent-strategy.html
-
什么是容错机制
容错机制指的是某种系统控制在一定范围内的一种允许或包容犯错情况的发生,举个简单例子,我们在电脑上运行一个程序,有时候会出现无响应的情况,然后系统会弹出一个提示框让我们选择,是立即结束还是继续等待,然后根据我们的选择执行对应的操作,这就是“容错”。
在分布式架构下,网络、硬件、应用都可能发生故障,由于各个服务之间可能存在依赖关系,如果一条链路中的其中一个节点出现故障,将会导致雪崩效应。为了减少某一个节点故障的影响范围,所以我们才需要去构建容错服务,来优雅的处理这种中断的响应结果
dubbo的容错机制
Dubbo提供了6种容错机制,分别如下
-
failsafe
: 失败安全,可以认为是把错误吞掉(记录日志) -
failover(默认)
: 重试其他服务器; retries(2),加上第一次连接,共三次 -
failfast
: 快速失败, 失败以后立马报错 -
failback
: 失败后自动恢复。 -
forking
: 设置并行数 -
broadcast
: 广播,任意一台报错,则执行的方法报错
配置方式如下,通过cluster方式,配置指定的容错方案
<dubbo:reference id="helloImpl" interface="com.sunkang.dubbo.IHello" cluster="failsafe" />
3.服务降级
降级的目的是为了保证核心服务可用
。
降级可以有几个层面的分类: 自动降级和人工降级
;
按照功能可以分为:读服务降级和写服务降级
;
1.对一些非核心服务进行人工降级
,在大促之前通过降级开关关闭哪些推荐内容、评价等对主流程没有影响的功能
2.故障降级
,比如调用的远程服务挂了,网络故障、或者RPC服务返回异常。 那么可以直接降级,降级的方案比如设置默认值、采用兜底数据(系统推荐的行为广告挂了,可以提前准备静态页面做返回)等等
3.限流降级
,在秒杀这种流量比较集中并且流量特别大的情况下,因为突发访问量特别大可能会导致系统支撑不了。这个时候可以采用限流来限制访问量。当达到阀值时,后续的请求被降级,比如进入排队页面,比如跳转到错误页(活动太火爆,稍后重试等)
dubbo的降级方式:Mock
可以参考:
服务降级:https://dubbo.apache.org/zh-cn/docs/user/demos/service-downgrade.html
本地伪装: https://dubbo.apache.org/zh-cn/docs/user/demos/local-mock.html
4.配置优先级别
可以参考:
XML 配置:https://dubbo.apache.org/zh-cn/docs/user/configuration/xml.html
以timeout为例,显示了配置的查找顺序,其它retries, loadbalance等类似。
方法级优先,接口级次之,全局配置再次之
如果级别一样,则消费方优先,提供方次之
其中,服务提供方配置,通过URL经由注册中心传递给消费方。
建议由服务提供方设置超时
,因为一个方法需要执行多长时间,服务提供方更清楚,如果一个消费方同时引用多个服务,就不需要关心每个服务的超时设置。
网友评论