微服务相关概念

服务治理基本概念

  1. 服务的伸缩控制
  2. 身份验证与授权 *
  3. 服务注册与发现 *
  4. 反向代理与负载均衡
  5. 路由控制 *
  6. 流量切换 *
  7. 日志管理 *
  8. 性能度量、监控与调优 *
  9. 分布式跟踪 *
  10. 过载保护 *
  11. 服务降级 *
  12. 服务部署与版本升级策略支持 *
  13. 错误处理 *
  14. 国际化

服务的伸缩控制

身份验证与授权

服务注册与发现

  1. dubbo zookeeper

反向代理与负载均衡

  1. vertx
  2. nginx

二分法查找及扩展

二分法查找

给一个有序数组,查找出k所在位置

/**
* @author Aaron
* @since 6.2
*/
public class TheFirstLessThan100 {
public static int find(int[] array, int value) {

int low = 0;
int high = array.length - 1;
int count = 0;
while (low <= high) {
int middle = (low + high) >>> 1;
int middleValue = array[middle];
count++;
if (middleValue < value) {
low = middle + 1;
} else if (middleValue > value) {
high = middle - 1;
} else {
System.out.printf("times:%d,index:%d,value:%d\n", count, middle, value);
return middle;
}
}
return -1;
}


public static void main(String[] args) {
int[] array = new int[]{1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 8, 9, 10, 14, 17, 19, 20};
for (int i = 0; i < array.length; i++) {
int index = find(array, array[i]);
}
}
}

查出第一个大于N的位置

从有序的数组中,找出第一个大于N的数字的位置


public static int findFirstBigIndex(int[] array, int value) {

int lastBigIndex=-1;

int low = 0;
int high = array.length - 1;
int count = 0;

while (low <= high) {
int middle = (low + high) >>> 1;
int middleValue = array[middle];
count++;
if (middleValue <= value) {
low = middle + 1;
} else if (middleValue > value) {
high = middle - 1;
lastBigIndex=middle;
System.out.printf("times:%d,index:%d,value:%d,middle:%d\n", count, middle, value,middleValue);
}
}
return lastBigIndex;
}



public static int findFirstBigIndex1(int[] array, int value) {

int low = 0;
int high = array.length - 1;
int count = 0;

while (low <= high) {
int middle = (low + high) >>> 1;
int middleValue = array[middle];
count++;
if (middleValue <= value) {
low = middle + 1;
} else if (middleValue > value) {
high = middle - 1;
System.out.printf("times:%d,index:%d,value:%d,middle:%d\n", count, middle, value,middleValue);
}
}
return low;
}

public static void main(String[] args) {
int[] array = new int[]{1, 2, 3, 4, 5, 6, 8, 9, 10, 14, 17, 19, 20,21,22,34,324,546};
for (int i = 0; i < array.length; i++) {
int index = findFirstBigIndex1(array, i);
int index2 = findFirstBigIndex(array, i);
System.out.println(index+"--"+index2);
}
}

微信头像九宫格算法

分别计算1-9个头像在九宫格中的位置


public static List<ImageCell> createMergeCell(int n, int totalWidth) {
int totalRow = (int) Math.ceil(Math.sqrt(n));
int outline = 5;
int width = ((totalWidth - outline) / totalRow);
int border = width / 20;
if (n == 1) {
return Lists.newArrayList(new ImageCell(border, border, width - 2 * border));
}
int lastAloneNum = n % totalRow;
int totalFullRow = n / totalRow;
int lastRow = totalRow - totalFullRow - 1;

int firstStartX = (totalWidth - lastAloneNum * width) / 2;
int firstStartY = lastRow * width;

int otherSpace = (totalWidth - totalRow * width) / 2;
int yOffset = 0;
if (totalRow != totalFullRow + (lastAloneNum != 0 ? 1 : 0)) {
yOffset = -width / 2;
}
List<ImageCell> imageCells = Lists.newArrayList();
for (int i = 0; i < n; i++) {
int x = 0, y = firstStartY;
if (i < lastAloneNum) {
x = firstStartX + i * width;
} else {
x = (i - lastAloneNum) % totalRow * width;
y = firstStartY + ((i - lastAloneNum) / totalRow + 1) * width;
}
imageCells.add(new ImageCell(x + border + otherSpace, y + border + otherSpace + yOffset, width - 2 * border));
}
return imageCells;
}

@Data
@AllArgsConstructor
static class ImageCell {
int x;
int y;
int width;

}

-------------------n=1---------------------
x:7,y:7,width:131




-------------------n=2---------------------
x:6,y:42,width:66
x:78,y:42,width:66




-------------------n=3---------------------
x:45,y:6,width:66
x:6,y:78,width:66
x:78,y:78,width:66




-------------------n=4---------------------
x:6,y:6,width:66
x:78,y:6,width:66
x:6,y:78,width:66
x:78,y:78,width:66




-------------------n=5---------------------
x:32,y:29,width:44
x:80,y:29,width:44
x:5,y:77,width:44
x:53,y:77,width:44
x:101,y:77,width:44




-------------------n=6---------------------
x:5,y:29,width:44
x:53,y:29,width:44
x:101,y:29,width:44
x:5,y:77,width:44
x:53,y:77,width:44
x:101,y:77,width:44




-------------------n=7---------------------
x:56,y:5,width:44
x:5,y:53,width:44
x:53,y:53,width:44
x:101,y:53,width:44
x:5,y:101,width:44
x:53,y:101,width:44
x:101,y:101,width:44




-------------------n=8---------------------
x:32,y:5,width:44
x:80,y:5,width:44
x:5,y:53,width:44
x:53,y:53,width:44
x:101,y:53,width:44
x:5,y:101,width:44
x:53,y:101,width:44
x:101,y:101,width:44




-------------------n=9---------------------
x:5,y:5,width:44
x:53,y:5,width:44
x:101,y:5,width:44
x:5,y:53,width:44
x:53,y:53,width:44
x:101,y:53,width:44
x:5,y:101,width:44
x:53,y:101,width:44
x:101,y:101,width:44

取一个数字二进制中1的个数

  1. 二进制中1的个数

     
    int countBits(int n) {
    int count=0 ;
    while (n>0) {
    count++ ;
    n &= (n - 1) ;
    }
    return count ;
    }
    复杂度: < log2n
  2. 方案二

     
    /**
    * Returns the number of one-bits in the two's complement binary
    * representation of the specified {@code int} value. This function is
    * sometimes referred to as the <i>population count</i>.
    *
    * @param i the value whose bits are to be counted
    * @return the number of one-bits in the two's complement binary
    * representation of the specified {@code int} value.
    * @since 1.5
    */
    public static int bitCount(int i) {
    // HD, Figure 5-2
    i = i - ((i >>> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
    i = (i + (i >>> 4)) & 0x0f0f0f0f;
    i = i + (i >>> 8);
    i = i + (i >>> 16);
    return i & 0x3f;
    }

    复杂度: 1
  3. 方案三

     
    public static int countBit1(int n) {
    int count=0 ;
    int temp=1;
    while (temp<=n) {
    if((temp&n)>0){
    count++ ;
    }
    temp<<=1;
    }
    return count ;
    }

扩展

  1. 给定一个数字n计算从1到n每一个数字的二进制中包含1的个数
        
public static int[] countBits(int num) {
int[] ret = new int[num + 1];

for (int i = 0; i <= num; i++) {
int div = i / 2;
int mod = i % 2;

if (mod == 1) {
ret[i] = ret[div] + 1;
} else {
ret[i] = ret[div];
}
}
return ret;
}

Paxos

作者介绍

1982,Lamport 提出了一种计算机容错理论,并于1900年论证。
这是一种
基于消传递且具有高度容错特性的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一。

时间时钟、面包店算法、拜占庭将军及paxos算法的创建性容错

paxos的目的

提高分布式系统容错性的一致性算法

核心

一致性算法

算法三个角色:

Proposer
Acceptor
Learner

规则

paxos 描述:

参与者之间可以进行通信,可以记录一些信息,来确定最终的值
消息内容不会被篡改

知行学社的分布式系统与Paxos算法 对paxos算法核心思想的描述

  • 在抢占式访问权的基础上引入多acceptor

  • 保证一个epoch,只有一个proposer运行,proposer按照epoch递增的顺序依次运行。

  • 新的epoch的proposer采用后者认同前者的思路运行。

  • 在肯定旧epoch无法生成确定性取值时,新的epoch 会提交自己的取值。不会冲突。

  • 一旦旧epoch形成确定性取值,新epoch肯定可以获取到此取值,并且会认同此取值,不会破坏。