服务注册与服务发现

一、linkerd+consul

1.服务发现

如上,客户端直接调用各个服务的话,对服务的维护比较艰难,需要很大的一个配置,而且可能服务变化后,还需要修改配置。总结就是服务多了,配置很麻烦。

 

引入服务发现:

服务发现大概流程:各个服务A-N把当前自己的网络位置注册到服务发现模块(这里注册的意思就是告诉),服务发现就以K-V的方式记录下,K一般是服务名,V就是IP:PORT。服务发现模块定时的轮询查看这些服务能不能访问的了(这就是健康检查)。客户端在调用服务A-N的时候,就跑去服务发现模块问下它们的网络位置,然后再调用它们的服务。这样就解决了上面的问题,客户端完全不需要记录这些服务网络位置,客户端和服务端完全解耦!

 

2.linkerd

Linkerd 是 Service Mesh(服务网格)技术的一个实现,Linkerd 技术最早由 Twitter 公司贡献。

主要特性:

  • 负载均衡:linkerd提供了多种负载均衡算法,它们使用实时性能指标来分配负载并减少整个应用程序的尾部延迟。
  • 熔断:linkerd包含自动熔断,将停止将流量发送到被认为不健康的实例,从而使他们有机会恢复并避免连锁反应故障。
  • 服务发现:linkerd 与各种服务发现后端集成,通过删除特定的(ad-hoc)服务发现实现来帮助您降低代码的复杂性。
  • 动态请求路由:linkerd 启用动态请求路由和重新路由,允许您使用最少量的配置来设置分段服务(staging service),金丝雀(canaries),蓝绿部署(blue-green deploy),跨DC故障切换和黑暗流量(dark traffic)。
  • 重试机制:linkerd可以在某些故障时自动重试请求,并且可以在指定的时间段之后让请求超时。
  • TLS:linkerd 可以配置为使用 TLS 发送和接收请求,您可以使用它来加密跨主机边界的通信,而不用修改现有的应用程序代码。
  • HTTP 代理:linkerd 可以作为 HTTP 代理,几乎所有现代 HTTP 客户端都广泛支持,使其易于集成到现有应用程序中。
  • 透明代理:您可以在主机上使用 iptables 规则,设置通过 linkerd 的透明代理。
  • gRPC:linkerd 支持 HTTP/2 和 TLS,允许它路由 gRPC 请求,支持高级 RPC 机制,如双向流,流程控制和结构化数据负载。
  • 分布式追踪:linkerd 支持分布式跟踪和度量仪器,可以提供跨越所有服务的统一的可观察性。
  • 仪表化:linkerd 提供了通信延迟和有效载荷大小的详细直方图以及成功率和负载均衡统计信息,以人类可读和机器可解析的格式

 

参考:https://blog.csdn.net/buxiaoxia/article/details/69788114

https://blog.csdn.net/zl1zl2zl3/article/details/78678460

 

二、Dubbo

1.如何暴露服务

在根据配置文件解析读取装配成bean之后, 初始化, 根据配置协议, 找到注册中心(如Zookeeper)注册, 找到对应服务Protocol(如DubboProtocol)暴露服务。

Dubbo利用Zookeeper进行服务注册。

 

Servlet和Spring Bean生命周期

一、Servlet生命周期

实例化、初始init、接收请求service、销毁destroy。

启动的时候进行初始化servlet,以后接到请求,新建httpRequest和httpResponse对象,调用service。

 

二、Spring Bean的生命周期

1. 实例化一个Bean,也就是我们通常说的new

2. 按照Spring上下文对实例化的Bean进行配置,也就是IOC注入

3. 如果这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的是Spring配置文件中Bean的ID

4. 如果这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(),传递的是Spring工厂本身(可以用这个方法获取到其他Bean)

5. 如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文,该方式同样可以实现步骤4,但比4更好,以为ApplicationContext是BeanFactory的子接口,有更多的实现方法

6. 如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用After方法,也可用于内存或缓存技术

7. 如果这个Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法

8. 如果这个Bean关联了BeanPostProcessor接口,将会调用postAfterInitialization(Object obj, String s)方法

注意:以上工作完成以后就可以用这个Bean了,那这个Bean是一个single的,所以一般情况下我们调用同一个ID的Bean会是在内容地址相同的实例

9. 当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean接口,会调用其实现的destroy方法

10. 最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法

Hadoop

Hadoop是在分布式服务器集群上存储海量数据并运行分布式分析应用的一种方法。即使某台服务器甚至集群宕机了,运行其上的大数据分析应用也不会中断。

 

Hadoop有两个主要部分:一个数据处理框架和一个分布式数据存储文件系统(HDFS)。

Java中的~

1.作为操作符:

~符号作为java操作符时,代表一元的逐位取反操作。如:int i=10;i=~i;

10按位取反是-11,1按位取反是-2

2.Intellij中使用:

Set<String> associations = new LinkedHashSet<~>();

means String, which is the same as in the declaration on the left side.

在Intellij中代表:“与声明相同”的简写,并不是java的语法。

Java8出现OOM测试

一、oom设计

private static void test(){
    int i=0;
    List<Object> list = new ArrayList<>();
    while(true){
        System.out.println(i++);
        list.add(new Object());
    }
}

写了如上方法,在main()方法中调用后,发现虽然堆区满了,但是也并没有出现oom,查阅发现java8因为Metaspace,所以并不是堆区满了就出现oom,所以配置如下参数:-Xmx56m -XX:MaxMetaspaceSize=128m  设置最大堆区为56m,设置最大Metaspace为128m,运行程序后,抛出了oom。

二、原因总结

1.JDK8 HotSpot JVM 移除了永久代(方法区),使用本地内存来存储类元数据信息并称之为:元空间(Metaspace),如下图所示:

 

2.java8中metaspace总结:

a.移除了PermGen 空间

b.大部分类元数据(Metaspace )都在本地内存中分配。

默认情况下,类元数据只受可用的本地内存限制

新参数(MaxMetaspaceSize)用于限制本地内存分配给类元数据的大小。如果没有指定这个参数,元空间会在运行时根据需要动态调整(意思是如果不设置MaxMetaspaceSize,则一直可能会占用完所有的物理内存,而物理内存占用过高,可能会被操作系统kill掉)。

 

三、方法区和永久代

1.方法区是所有线程共享的,主要用于存储类的信息、常量池、方法数据、方法代码等。通常又叫“非堆”。

2.PermGen(永久代)

对于 “java.lang.OutOfMemoryError: PermGen space “这个异常。这里的 “PermGen space”其实指的就是方法区。

3.区别和联系

方法区是 JVM 的规范,而“PermGen space”后者则是 JVM 规范的一种实现,而且只有 HotSpot 才有 “PermGen space”,而对于其他类型的虚拟机则没有。

Dubbo

注:一个rpc框架

一、概念

控制中心:控制中心是用来做服务治理的,比如控制服务的权重、服务的路由。

simple监控中心:Monitor也是一个dubbo服务,所以也会有端口和url,监控服务的调用次数、调用关系、响应事件。

二、启动服务检查

如果提供方没有启动的时候,默认会去检测所依赖的服务是否正常提供服务,如果check为false,表示启动的时候不去检查。当服务出现循环依赖的时候,check设置成false。

dubbo:reference  属性: check  默认值是true 、false

dubbo:consumer  check=”false”  没有服务提供者的时候,报错

dubbo:registry  check=false   注册订阅失败报错

dubbo:provider

三、多协议支持

dubbo支持的协议: dubbo、RMI、hessian、webservice、http、Thrift

1.hessian协议演示

1)引入jar包

<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.38</version>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>

<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.26</version>
</dependency>

2)修改provider.xml

3)指定service服务的协议版本号

4)消费端改造

hessian%3A%2F%2F177.1.1.82%3A8090%2Fcom.gupao.vip.mic.dubbo.order.IOrderServices%3Fanyhost%3Dtrue%26application%3Dorder-provider%26dubbo%3D2.5.3%26interface%3Dcom.gupao.vip.mic.dubbo.order.IOrderServices%26methods%3DdoOrder%26owner%3Dmic%26pid%3D3116%26server%3Djetty%26side%3Dprovider%26timestamp%3D1503145940360,

 

dubbo%3A%2F%2F177.1.1.82%3A20880%2Fcom.gupao.vip.mic.dubbo.order.IOrderServices%3Fanyhost%3Dtrue%26application%3Dorder-provider%26dubbo%3D2.5.3%26interface%3Dcom.gupao.vip.mic.dubbo.order.IOrderServices%26methods%3DdoOrder%26owner%3Dmic%26pid%3D3116%26side%3Dprovider%26timestamp%3D1503145950346]

 

hessian://177.1.1.82:8090/com.gupao.vip.mic.dubbo.order.IOrderServices

 

四、多注册中心支持

五、多版本支持

客户端调用的时候

 

hessian%3A%2F%2F177.1.1.82%3A8090%2Fcom.gupao.vip.mic.dubbo.order.IOrderServices%3Fanyhost%3Dtrue%26application%3Dorder-provider%26dubbo%3D2.5.3%26interface%3Dcom.gupao.vip.mic.dubbo.order.IOrderServices%26methods%3DdoOrder%26owner%3Dmic%26pid%3D7704%26revision%3D1.0%26server%3Djetty%26side%3Dprovider%26timestamp%3D1503147499144%26version%3D1.0,

 

hessian%3A%2F%2F177.1.1.82%3A8090%2Fcom.gupao.vip.mic.dubbo.order.IOrderServices2%3Fanyhost%3Dtrue%26application%3Dorder-provider%26dubbo%3D2.5.3%26interface%3Dcom.gupao.vip.mic.dubbo.order.IOrderServices%26methods%3DdoOrder%26owner%3Dmic%26pid%3D7704%26revision%3D2.0%26server%3Djetty%26side%3Dprovider%26timestamp%3D1503147510114%26version%3D2.0

 

六、异步调用

async=”true”表示接口异步返回

hessian协议,使用async异步回调会报错

七、主机绑定

provider://177.1.1.82:20880

通过以下过程依次去拿地址,拿不到依次通过下一步尝试获取。

1.通过<dubbo:protocol host配置的地址去找

2.

3.通过socket发起连接连接到注册中心的地址。再获取连接过去以后本地的ip地址4.host = NetUtils.getLocalHost();

 

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);
host = socket.getLocalAddress().getHostAddress();
break;
} finally {
try {
socket.close();
} catch (Throwable e) {}
}
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
}
if (NetUtils.isInvalidLocalHost(host)) {
host = NetUtils.getLocalHost();
}
}

八、dubbo服务只订阅

九、dubbo服务只注册

只提供服务

<dubbo:registry subscribe=”false”/>

 

十、负载均衡

在集群负载均衡时,Dubbo提供了多种均衡策略,缺省为random随机调用。可以自行扩展负载均衡策略

Random LoadBalance

随机,按权重设置随机概率。

在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

RoundRobin LoadBalance

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

存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

LeastActive LoadBalance

最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。

使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

ConsistentHash LoadBalance

一致性Hash,相同参数的请求总是发到同一提供者。

当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

十一、连接超时timeout

必须要设置服务的处理的超时时间

Java强引用、软引用、弱引用、虚引用

强、软、弱、虚

1、强引用(StrongReference)

强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。比如:

Object o=new Object();   //  强引用

当内存空间不足,会抛出OutOfMemoryError错误。

如果想要释放,则使用o=null;(何时回收取决于垃圾收集器)

o=null;     // 帮助垃圾收集器回收此对象

 

2、软引用(SoftReference)

内存足够时,不会回收该对象,只有在内存不足的时候JVM才会回收该对象。

作用:软引用主要用来做缓存。

String str=new String("abc"); // 强引用
SoftReference<String> softRef=new SoftReference<String>(str); // 软引用

If(JVM.内存不足()) {
str = null; // 转换为软引用
System.gc(); // 垃圾回收器进行回收
}

3.弱引用(WeakReference)

当垃圾收集器工作时,无论是否内存足够,都会回收该对象。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

String str=new String("abc");
WeakReference<String> abcWeakRef = new WeakReference<String>(str);
If(垃圾收集器扫描到) {
str = null;
System.gc(); // 垃圾回收器进行回收
}

4、虚引用(PhantomReference)

如果一个对象仅持有虚引用,在任何时候都可能被垃圾回收器回收。

虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。

主要作用:当对象被回收时,可以收到一个系统通知。

原文地址:https://blog.csdn.net/mazhimazh/article/details/19752475

zookeeper细节

注:zookeeper是一个分布式协调服务。所谓分布式协调主要是来解决分布式系统中多个进程之间的同步控制,让他们有序的去访问某种临界资源,防止出现脏读。

一、zookeeper集群中的读写

在 zookeeper 中,客户端会随机连接到 zookeeper 集群中
的一个节点,如果是读请求,就直接从当前节点中读取数
据,如果是写请求,那么请求会被转发给 leader 提交事务,
然后 leader 会广播事务,只要有超过半数节点写入成功,
那么写请求就会被提交(类 2PC 事务)。

二、Leader选举

serverid : 在配置server集群的时候,给定服务器的标识id(myid)

zxid  : 服务器在运行时产生的数据ID, zxid的值越大,表示数据越新

Epoch: 选举的轮数

server的状态:Looking、 Following、Observering、Leading

1.选举过程概述

(1) 所有在集群中的server都会推荐自己为leader,然后把(myid、zxid、epoch)作为广播信息,广播给集群中的其他server, 然后等待其他服务器返回

myid:server的ID

ZXID:服务的事务ID,越大代表数据越新

 

(2) 接受来自各个服务器的投票

判断该投票的有效性,如检查是否是本轮投票、是否来自LOOKING状态的服务器等。

判断逻辑时钟(Epoch) ,如果Epoch大于自己当前的Epoch,说明自己保存的Epoch是过期。更新Epoch,同时clear其他服务器发送过来的选举数据。判断是否需要更新当前自己的选举情况

如果Epoch小于目前的Epoch,说明对方的epoch过期了,也就意味着对方服务器的选举轮数是过期的。这个时候,只需要讲自己的信息发送给对方

 

(3) 处理投票。

针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK,PK规则如下

· 优先检查ZXID。ZXID比较大的服务器优先作为Leader。

· 如果ZXID相同,那么就比较myid。myid较大的服务器作为Leader服务器。

然后会重新投票。

 

(4)统计投票,判断是否已经有过半机器接受到相同的投票信息,如果有则证明Leader服务器被选出来了

 

(5)改变服务器状态。

一旦确定了Leader,每个服务器就会更新自己的状态,如果是Follower,那么就变更为FOLLOWING,如果是Leader,就变更为LEADING。

 

三、ZAB(Zookeeper atomic broadcast)协议

1.概述

拜占庭问题

paxos协议主要就是如何保证在分布式环网络环境下,各个服务器如何达成一致最终保证数据的一 致性问题

 

ZAB协议,基于paxos协议的一个改进。

 

zab协议为分布式协调服务zookeeper专门设计的一种支持崩溃恢复的原子广播协议

zookeeper并没有完全采用paxos算法, 而是采用zab

 

2.原理

a.在zookeeper 的主备模式下,通过zab协议来保证集群中各个副本数据的一致性

b.zookeeper使用的是单一的主进程来接收并处理所有的事务请求,并采用zab协议,把数据的状态变更以事务请求的形式广播到其他的节点

c.zab协议在主备模型架构中,保证了同一时刻只能有一个主进程来广播服务器的状态变更

d.所有的事务请求必须由全局唯一的服务器来协调处理,这个的服务器叫leader,其他的叫follower,leader节点主要负责把客户端的事务请求转化成一个事务提议(proposal),并分发给集群中的所有follower节点,再等待所有follower节点的反馈。一旦超过半数服务器进行了正确的反馈,那么leader就会commit这条消息

 

3.崩溃恢复

a.什么情况下zab协议会进入崩溃恢复模式

1)当服务器启动时

2)当leader服务器出现网络中断、崩溃或者重启的情况

3)集群中已经不存在过半的服务器与该leader保持正常通信

 

b.zab协议进入崩溃恢复模式会做什么

1) 当leader出现问题,zab协议进入崩溃恢复模式,并且选举出新的leader。当新的leader选举出来以后,如果集群中已经有过半机器完成了leader服务器的状态同步(数据同步),退出崩溃恢复,进入消息广播模式

2)当新的机器加入到集群中的时候,如果已经存在leader服务器,那么新加入的服务器就会自觉进入数据恢复模式,找到leader进行数据同步

四、问题

假设一个事务在leader服务器被提交了,并且已经有过半的follower返回了ack。 在leader节点把commit消息发送给folower机器之前leader服务器挂了怎么办

1.选举新的leader(zxid的最大值)

2.然后将leader的数据同步给其他的folower

五、总结

Maser选举、Leader选举、崩溃恢复、消息广播、ZAB协议

Maser选举(属于zookeeper的应用):在主从模式下,主节点挂掉后,从slave节点选取master节点的过程。利用zookeeper的临时节点特性,多个slave节点同时去注册一个master节点,注册成功的会成为master。

Leader选举(zookeeper内部机制):当Leader挂掉时(这时进入崩溃恢复模式),会从follower进行选取Leader,利用(sid,zxid)大小关系投票选取Leader。当Leader选举出来后,会退出崩溃恢复模式,进行消息广播,将Leader的数据同步给follower。

ZAB协议(Zookeeper Atomic Broadcast):zookeeper原子消息广播协议,是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的原子广播协议。