dubbo是阿里巴巴公司开发的一个开源分布式应用框架,基于服务的发布者和订阅者,服务者启动服务向注册中心发布自己的服务;消费者(订阅者)启动服务器向注册中心订阅所需要的服务。注册中心将订阅的服务注册列表返回给订阅者。注册中心会感应服务的提供者的变化,如果服务的提供者发生变化,注册中心会立即通知消费者及时变更服务信息数据;dubbo并且带有审计功能--监控中心,服务的发布者和服务的消费者每分钟间隔都会向监控中心发送自己的统计情况如:调用次数 或者调用时间等(这些数据是保存在内存中以每分钟为单位向监控中心进行发送数据)。监控中心宕机不影响使用,只是减少部分采样的数据,对等的集群任意一台服务宕机,会自动切换到其他对等的机器,注册中心宕机,对服务没有影响,订阅者自己本地会缓存服务提供者的列表信息,由此可见dubbo的健壮性还是可以的。

dubbo有很多非常好的特性:负载均衡、集群容错等

集群容错策略:

failover :失败重连;

failfast:只发起一次请求;

failsafe:失败直接忽略;

failback:失败返回定时发送;、

forking:并发执行 只要有一台成功立即返回;

broadcast:调用所有提供者任意一台报错就报错)。

负载均衡:

随机按照权重概率选择

轮循,按公约后的权重设置轮循比率

  • 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
  • 一致哈希:相同的请求参数会请求同一个服务提供者。

支持多协议:

dubbo、thrift、rmi、jms、redis 等。

下面我们看下下载地址 dubbo的一直哈希策略的实现源代码:默认有160个虚拟节点 这样让服务列表更加均匀分布,命中更均匀。

./*
2. * Copyright 1999-2012 Alibaba Group.
3. *
4. * Licensed under the Apache License, Version 2.0 (the "License");
5. * you may not use this file except in compliance with the License.
6. * You may obtain a copy of the License at
7. *
8. * http://www.apache.org/licenses/LICENSE-2.0
9. *
10. * Unless required by applicable law or agreed to in writing, software
11. * distributed under the License is distributed on an "AS IS" BASIS,
12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13. * See the License for the specific language governing permissions and
14. * limitations under the License.
15. */
.package com.alibaba.dubbo.rpc.cluster.loadbalance;
.
.import java.io.UnsupportedEncodingException;
.import java.security.MessageDigest;
.import java.security.NoSuchAlgorithmException;
.import java.util.List;
.import java.util.SortedMap;
.import java.util.TreeMap;
.import java.util.concurrent.ConcurrentHashMap;
.import java.util.concurrent.ConcurrentMap;
.
.import com.alibaba.dubbo.common.Constants;
.import com.alibaba.dubbo.common.URL;
.import com.alibaba.dubbo.rpc.Invocation;
.import com.alibaba.dubbo.rpc.Invoker;
.
./**
33. * ConsistentHashLoadBalance
34. *
35. * @author william.liangf
36. */
.public class ConsistentHashLoadBalance extends AbstractLoadBalance {
.
. private final ConcurrentMap<String, ConsistentHashSelector<?>> selectors = new ConcurrentHashMap<String, ConsistentHashSelector<?>>();
.
. @SuppressWarnings("unchecked")
. @Override
. protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
. String key = invokers.get().getUrl().getServiceKey() + "." + invocation.getMethodName();
. int identityHashCode = System.identityHashCode(invokers);
. ConsistentHashSelector<T> selector = (ConsistentHashSelector<T>) selectors.get(key);
. if (selector == null || selector.getIdentityHashCode() != identityHashCode) {
. selectors.put(key, new ConsistentHashSelector<T>(invokers, invocation.getMethodName(), identityHashCode));
. selector = (ConsistentHashSelector<T>) selectors.get(key);
. }
. return selector.select(invocation);
. }
.
. private static final class ConsistentHashSelector<T> {
.
. private final TreeMap<Long, Invoker<T>> virtualInvokers;
.
. private final int replicaNumber;
.
. private final int identityHashCode;
.
. private final int[] argumentIndex;
.
. public ConsistentHashSelector(List<Invoker<T>> invokers, String methodName, int identityHashCode) {
. this.virtualInvokers = new TreeMap<Long, Invoker<T>>();
. this.identityHashCode = System.identityHashCode(invokers);
. URL url = invokers.get().getUrl();
. this.replicaNumber = url.getMethodParameter(methodName, "hash.nodes", );
. String[] index = Constants.COMMA_SPLIT_PATTERN.split(url.getMethodParameter(methodName, "hash.arguments", ""));
. argumentIndex = new int[index.length];
. for (int i = ; i < index.length; i ++) {
. argumentIndex[i] = Integer.parseInt(index[i]);
. }
. for (Invoker<T> invoker : invokers) {
. for (int i = ; i < replicaNumber / ; i++) {
. byte[] digest = md5(invoker.getUrl().toFullString() + i);
. for (int h = ; h < ; h++) {
. long m = hash(digest, h);
. virtualInvokers.put(m, invoker);
. }
. }
. }
. }
.
. public int getIdentityHashCode() {
. return identityHashCode;
. }
.
. public Invoker<T> select(Invocation invocation) {
. String key = toKey(invocation.getArguments());
. byte[] digest = md5(key);
. Invoker<T> invoker = sekectForKey(hash(digest, ));
. return invoker;
. }
.
. private String toKey(Object[] args) {
. StringBuilder buf = new StringBuilder();
. for (int i : argumentIndex) {
. if (i >= && i < args.length) {
. buf.append(args[i]);
. }
. }
. return buf.toString();
. }
.
. private Invoker<T> sekectForKey(long hash) {
. Invoker<T> invoker;
. Long key = hash;
. if (!virtualInvokers.containsKey(key)) {
. SortedMap<Long, Invoker<T>> tailMap = virtualInvokers.tailMap(key);
. if (tailMap.isEmpty()) {
. key = virtualInvokers.firstKey();
. } else {
. key = tailMap.firstKey();
. }
. }
. invoker = virtualInvokers.get(key);
. return invoker;
. }
.
. private long hash(byte[] digest, int number) {
. return (((long) (digest[ + number * ] & 0xFF) << )
. | ((long) (digest[ + number * ] & 0xFF) << )
. | ((long) (digest[ + number * ] & 0xFF) << )
. | (digest[ + number * ] & 0xFF))
. & 0xFFFFFFFFL;
. }
.
. private byte[] md5(String value) {
. MessageDigest md5;
. try {
. md5 = MessageDigest.getInstance("MD5");
. } catch (NoSuchAlgorithmException e) {
. throw new IllegalStateException(e.getMessage(), e);
. }
. md5.reset();
. byte[] bytes = null;
. try {
. bytes = value.getBytes("UTF-8");
. } catch (UnsupportedEncodingException e) {
. throw new IllegalStateException(e.getMessage(), e);
. }
. md5.update(bytes);
. return md5.digest();
. }
.
. }
.
.}

阿里巴巴的分布式应用框架-dubbo负载均衡策略--- 一致哈希算法的更多相关文章

  1. dubbo负载均衡策略和集群容错策略都有哪些

    dubbo负载均衡策略 random loadbalance 默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重,会按照权 ...

  2. dubbo负载均衡策略和集群容错策略

    dubbo负载均衡策略 random loadbalance 默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重,会按照权 ...

  3. 3.dubbo 负载均衡策略和集群容错策略都有哪些?动态代理策略呢?

    作者:中华石杉 面试题 dubbo 负载均衡策略和集群容错策略都有哪些?动态代理策略呢? 面试官心理分析 继续深问吧,这些都是用 dubbo 必须知道的一些东西,你得知道基本原理,知道序列化是什么协议 ...

  4. 分布式的几件小事(四)dubbo负载均衡策略和集群容错策略

    1.dubbo负载均衡策略 ①random loadbalance 策略 默认情况下,dubbo是random loadbalance 随机调用实现负载均衡,可以对provider不同实例设置不同的权 ...

  5. Dubbo入门到精通学习笔记(十一):Dubbo服务启动依赖检查、Dubbo负载均衡策略、Dubbo线程模型(结合Linux线程数限制配置的实战分享)

    文章目录 Dubbo服务启动依赖检查 Dubbo负载均衡策略 Dubbo线程模型(结合Linux线程数限制配置的实战分享) 实战经验分享( ** 属用性能调优**): Dubbo服务启动依赖检查 Du ...

  6. 面试系列24 dubbo负载均衡策略和集群容错策略

    (1)dubbo负载均衡策略 1)random loadbalance 默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重 ...

  7. 面试系列16 dubbo负载均衡策略和集群容错策略都有哪些?动态代理策略呢

    (1)dubbo负载均衡策略 1)random loadbalance 默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重 ...

  8. dubbo负载均衡策略和集群容错策略都有哪些?动态代理策略呢?

    (1)dubbo负载均衡策略 1)random loadbalance 默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重 ...

  9. 一文讲透Dubbo负载均衡之最小活跃数算法

    本文是对于Dubbo负载均衡策略之一的最小活跃数算法的详细分析.文中所示源码,没有特别标注的地方均为2.6.0版本. 为什么没有用截止目前的最新的版本号2.7.4.1呢?因为2.6.0这个版本里面有两 ...

随机推荐

  1. 【转载】Fragment 全解析(1):那些年踩过的坑

    http://www.jianshu.com/p/d9143a92ad94 Fragment系列文章:1.Fragment全解析系列(一):那些年踩过的坑2.Fragment全解析系列(二):正确的使 ...

  2. PostgreSQL中的数组与Any

    建立表: CREATE TABLE sal_emp ( name text, pay_by_quarter integer[], schedule text[][] ); 插入数据: INSERT I ...

  3. CSS实现标题右侧“更多”

    HTML < h2>< a h ref="#" >标题< /a> < span>更多…< /span> < /h2 ...

  4. hotfix分析

    使用System Update Readiness Tool for Windows Server 2008 R2 x64 可以分析hotfix是否有安装失败的情况 示例:http://blogs.t ...

  5. IOS 7 Study - Manipulating a Navigation Controller’s Array of View

    ProblemYou would like to directly manipulate the array of view controllers associated with aspecific ...

  6. SpringMVC 源码深度解析&lt;context:component-scan&gt;(扫描和注冊的注解Bean)

    我们在SpringMVC开发项目中,有的用注解和XML配置Bean,这两种都各有自己的优势,数据源配置比較经经常使用XML配置.控制层依赖的service比較经经常使用注解等(在部署时比較不会改变的) ...

  7. [Ember] Ember.js Templates

    In this lesson, we'll go over some of the basics of Ember.js templates and how they work with contro ...

  8. XCode4中的文本查找和文本替换功能

    转自:http://blog.csdn.net/zhuzhihai1988/article/details/7843186 1.如果是在打开的文档范围内:       查找: Command+ F   ...

  9. 深入理解 CSS 中的行高与基线

    1.基本概念 1.  基线.底线.顶线.中线 注意:基线(base line)并不是汉字文字的下端沿,而是英文字母“x”的下端沿. 2. 内容区 内容区是指底线和顶线包裹的区域(行内元素display ...

  10. 全栈一路坑之使用django创建博客

    最近在看一篇全栈增长工程师实战,然后学习里面的项目,结果发现作者用的技术太过老旧,好多东西都已经被抛弃了,所以结合着官方文档和自己的一些理解将错误的信息替换一下,边写边学习 准备工作和工具 作者说需要 ...