+ 使用临时节点可以方便地支持集群环境下的动态扩容与缩容,新的服务提供者上线或者旧的提供者下线,都能迅速反映到服务注册中心,进而使得消费者能及时感知并调整访问策略。
Dubbo协议异步单一长连接原理与优势
2. 异步单一长连接原理
2.1 异步通信
Dubbo协议采用异步通信模型,即客户端发送请求后不需要等待服务端响应,可以立即进行其他操作。这种模型的核心在于使用了NIO(Non-blocking I/O)技术,通过事件驱动和回调机制来实现请求的并发处理。
具体来说,客户端在发送请求后,将请求信息注册到事件多路复用器上。当服务端响应到达时,事件多路复用器会触发相应的回调函数进行处理。这样一来,客户端就可以异步地处理多个请求,提高了系统的并发能力和吞吐量。
2.2 单一长连接
Dubbo协议使用单一长连接的方式来进行通信。所谓单一长连接,就是指客户端与服务端之间只建立一个TCP连接,并保持长时间的有效性。
这种设计方案有以下几个优势:
2.2.1 连接复用
由于只有一个TCP连接,不需要频繁地建立和关闭连接,避免了TCP连接的三次握手和四次挥手的开销。同时,连接的复用还可以减轻网络设备的负担,提高网络的利用率。
2.2.2 减少资源消耗
每个TCP连接都会占用一定的系统内存和CPU资源,如果每个请求都需要建立新的连接,那么系统资源开销将会非常大。而采用单一长连接的方式,可以大幅度降低资源的消耗,提高系统的稳定性和可伸缩性。
2.2.3 保证顺序性
由于Dubbo协议仅使用一个连接,发送的请求和接收的响应不会交错。这意味着请求和响应可以按照发送的顺序进行处理,不会出现乱序的情况。这在一些有序性要求较高的场景中非常重要。
3. 异步单一长连接的优势
异步单一长连接作为Dubbo协议的核心设计,具有以下几个显著的优势:
3.1 减少网络开销
采用异步通信模型和单一长连接方式可以减少网络的开销,避免了频繁地建立和关闭连接带来的额外开销。这对于海量请求的场景尤为重要,可以提升系统的性能和吞吐量。
3.2 提高系统的稳定性和可伸缩性
由于单一长连接减少了资源消耗,系统的稳定性和可伸缩性得到了提高。在高并发情况下,系统能够更好地承受请求的压力,同时也降低了系统崩溃的风险。
3.3 简化系统维护和监控
采用单一长连接的方式简化了系统的维护和监控工作。只需要关注一个TCP连接的状态和性能指标,而不需要管理多个独立的连接。这有助于提高运维效率和降低维护成本。
3.4 保证请求顺序性
由于异步通信模型和单一长连接的特性,Dubbo协议能够保证请求和响应的顺序性。这对于某些有序性要求的业务场景非常重要,例如金融交易系统中的订单处理。
长链接中断的情况:
- 服务端或客户端主动断开连接。
- 网络故障导致连接中断。
- 客户端(如消费方应用)或者服务端进程终止。
代理技术
JDK Proxy原理
//JDK的动态代理
public class JdkProxyTest {
public static void main(String[] args) {
//会将生成的class保存在工程根目录下的 com/sun/proxy 目录里面
System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
BookService bookService=(BookService) Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(), //类加载器
new Class[]{BookService.class}, //要动态代理实现的方法
new Handler() //要调用的方法实现
);
Book book=bookService.findById("100");
System.out.println(book);
}
static class Handler implements InvocationHandler{
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//发起远程网络调用
System.out.println("模拟发起网络远程调用");
Book book=new Book();
book.setId(args[0].toString());
book.setName("斗破苍穹");
book.setTitle("玄幻");
book.setTag("玄幻");
book.setContent("爽文");
return book;
}
}
}
查看其代理类:
public final class $Proxy0 extends Proxy implements BookService {
private static Method m1;
private static Method m2;
private static Method m0;
private static Method m3;
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final Book findById(String var1) throws {
try {
return (Book)super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
m3 = Class.forName("BookService").getMethod("findById", Class.forName("java.lang.String"));
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
对上述代码精简一下:
public final class $Proxy0 extends Proxy implements BookService {
private static Method m1;
private static Method m2;
private static Method m0;
private static Method m3; //findById方法
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final Book findById(String var1) throws {
try {
return (Book)super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
m3 = Class.forName("BookService").getMethod("findById", Class.forName("java.lang.String"));
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
super(var1);//查看一下这个函数,如下
protected InvocationHandler h;
protected Proxy(InvocationHandler h) {
Objects.requireNonNull(h);
this.h = h;
}
public final Book findById(String var1) throws {
try {
return (Book)super.h.invoke(this, m3, new Object[]{var1}); //这里的h就是我们传递过来的Handler方法,也就是直接调用我们自己实现的handler方法
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
其他动态代理的解决方案
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数大数据工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上大数据开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注大数据获取)
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
95%以上大数据开发知识点,真正体系化!**
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注大数据获取)
[外链图片转存中…(img-2lfypVyI-1712987685785)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!