Nepxion-Thunder(QQ 群 471164539)发布在https://github.com/Nepxion/
点对点模型实现,主要是用于Netty & Hessian。结构图如下:
点击查看大图
-
1 Netty框架
1.1 工作原理
1)Spring扫描线程扫描到一个Service节点后,就开启一个服务端Netty NioSocketChannel通道(绑定服务端口),并开启Redis的对该Service的订阅
2)Spring扫描线程扫描到一个Reference节点后,就开启一个调用端Netty NioSocketChannel通道(根据ApplicationEntity里的host和hort,与对应服务端进行长连接)
3)当调用端通过Spring Aop进行同步/异步远程调用时,先从缓存获取ChannelFuture对象,把ProtocolRequest请求通过ChannelFuture.writeAndFlush发送到服务端,服务端处理完毕后,通过ChannelHandlerContext.writeAndFlush把ProtocolResponse返回 到调用端,调用端收到响应后,如果是异步调用Callback方式完成调用,如果是同步通过CyclicBarrier的线程等待返回值,最后完成调用
4)当调用端通过Spring Aop进行广播远程调用时,把ProtocolRequest发布到Redis,服务端订阅监听该ProtocolRequest后,进行处理,不返回结果
1.2 类结构
1)NettyServerExecutor.java - 继承AbstractServerExecutor.java,实现服务端对Netty NioSocketChannel的阻塞式初始化,通过通过ChannelFuture和本地端口进行绑定提供通道服务,以及数据通道关闭的监听,
开启Redis的订阅
2)NettyServerHandler.java - 继承SimpleChannelInboundHandler.java,通过同步队列的线程池实现服务端对Netty通道的数据读取和写入,以及数据通道关闭的异常捕捉
3)NettyClientExecutor.java - 继承AbstractClientExecutor.java,实现调用端对Netty NioSocketChannel的阻塞式初始化,通过ChannelFuture和服务端的通道建立长连接,并实现对服务上下线的处理(上线时,把ChannelFuture加入缓存;下线时,把ChannelFuture移出缓存)
4)NettyClientHandler.java - 继承SimpleChannelInboundHandler.java,通过同步队列的线程池实现服务端对Netty通道的数据读取和写入,以及数据通道关闭的异常捕捉,心跳机制的实现
5)NettyClientInterceptor.java - 继承AbstractClientInterceptor.java,实现如下调用方式:
异步调用:调用负载均衡器获得可连接的ApplicationEntity(服务),如果获得的Application所在的服务器,恰巧下线了(服务下线到注册中心下线,一般会有一段时间间隔),那么采用重复调用继续做负载均衡去获取可连服务(ChannelFuture)。采用Callback异步返回
同步调用:同异步调用,采用返回值返回
广播调用:支持两种方式,默认是Redis的发布。如果Redis服务没起,采用轮循发送,就是往注册中心所有注册的相关服务循环发送一遍广播消息
6)NettyHeartbeat.java - 心跳实现
7)NettyObjectDecoder.java - 对序列化对象的解码
8)NettyObjectEncoder.java - 对序列化对象的编码
9)NettyException.java - Netty异常类
-
2 Hessian
2.1 工作原理
1)Hessian服务器在启动的时候,会把服务端配置的XML解析成hessian-servlet.xml,根据web.xml配置的上下文启动Hessian服务
例如服务端配置的XML叫hessian-server-context.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:thunder="http://www.nepxion.com/schema/thunder" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.nepxion.com/schema/thunder http://www.nepxion.com/schema/thunder/thunder-1.0.xsd"> <thunder:application id="application" application="APP-IOS" group="MY_GROUP" cluster="HessianServerCluster" port="8080"/> <thunder:protocol id="protocol" type="hessian"/> <thunder:registry id="registry" type="zookeeper" address="localhost:2181" config="remote"/> <thunder:strategy id="strategy" loadbalance="consistentHash"/> <thunder:service id="userServiceImpl" interface="com.nepxion.thunder.test.service.UserService" ref="_userServiceImpl"/> <bean name="_userServiceImpl" class="com.nepxion.thunder.test.service.UserServiceImpl"/> <thunder:service id="animalServiceImpl" interface="com.nepxion.thunder.test.service.AnimalService" ref="_animalServiceImpl"/> <bean name="_animalServiceImpl" class="com.nepxion.thunder.test.service.AnimalServiceImpl"/> </beans>
动态解析成hessian-servlet.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean name="/com.nepxion.thunder.test.service.AnimalService" class="com.nepxion.thunder.protocol.hessian.HessianAuthServiceExporter"> <property name="serviceInterface" value="com.nepxion.thunder.test.service.AnimalService"/> <property name="service" ref="_animalServiceImpl"/> </bean> <bean name="_animalServiceImpl" class="com.nepxion.thunder.test.service.AnimalServiceImpl"/> <bean name="/com.nepxion.thunder.test.service.UserService" class="com.nepxion.thunder.protocol.hessian.HessianAuthServiceExporter"> <property name="serviceInterface" value="com.nepxion.thunder.test.service.UserService"/> <property name="service" ref="_userServiceImpl"/> </bean> <bean name="_userServiceImpl" class="com.nepxion.thunder.test.service.UserServiceImpl"/> </beans>
web.xml,内容如下:<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:hessian-server-context.xml</param-value> </context-param> <listener> <listener-class>com.nepxion.thunder.framework.context.ThunderContextLoaderListener</listener-class> </listener> <!-- Only limited for Hessian --> <servlet> <servlet-name>hessian</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:hessian-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>hessian</servlet-name> <url-pattern>/hessian/*</url-pattern> </servlet-mapping> </web-app>
2)Spring扫描线程扫描到一个Service节点后,就开启Redis的对该Service的订阅
3)Spring扫描线程扫描到一个Reference节点后,由HessianAuthProxyFactory创建Proxy对象,并进入ProxyMap缓存
4)当调用端通过Spring Aop进行同步/异步远程调用时,先从缓存获取Proxy对象,把ProtocolRequest请求分解,通过method.invoke(proxy, arguments)调用Hessian服务器,服务端同步处理完毕后,返回值
5)当调用端通过Spring Aop进行广播远程调用时,把ProtocolRequest发布到Redis,服务端订阅监听该ProtocolRequest后,进行处理,不返回结果
2.2 类结构
1)HessianServerExecutor.java - 继承AbstractServerExecutor.java,开启Redis的订阅
2)HessianClientExecutor.java - 继承AbstractClientExecutor.java,由HessianAuthProxyFactory创建Proxy对象,并进入ProxyMap缓存。并实现对服务上下线的处理(上线时,把Proxy加入ProxyMap缓存;下线时,把Proxy移出ProxyMap缓存)
3)HessianClientInterceptor.java - 继承AbstractClientInterceptor.java,实现如下调用方式:
异步调用:调用负载均衡器获得可连接的ApplicationEntity(服务),如果获得的Application所在的服务器,恰巧下线了(服务下线到注册中心下线,一般会有一段时间间隔),那么采用重复调用继续做负载均衡去获取可连服务(Proxy)。采用线程池Callback异步返回
同步调用:同异步调用,采用返回值返回。Hessian默认调用方式
广播调用:支持两种方式,默认是Redis的发布。如果Redis服务没起,采用轮循发送,就是往注册中心所有注册的相关服务循环发送一遍广播消息
重复调用:从上一次的调用返回异常是否为ConnectException来判断是否要发起重复调用,同时一旦出现ConnectException,调用端把Proxy对象从ProxyMap中移除
4)HessianAuthProxyFactory.java - 继承HessianProxyFactory.java,覆盖createHessianConnectionFactory方法,拦截创建HessianConnection的方法,把调用端的密钥和版本信息通过Header方式发到服务端
5)HessianAuthServiceExporter.java - 继承HessianServiceExporter.java,实现ApplicationContextAware.java,覆盖handleRequest方法,在服务端进入调用之前,进行限流,密钥,版本控制
6)HessianServletGenerator.java - 动态创建hessian-servlet.xml
7)HessianUrlUtil.java - Hessian Url工具类
8)HessianUtil.java - Hessian工具类
-
3 Redis
3.1 工作原理
由于Netty和Hessian本身不带广播(发布/订阅)功能,所以采用Redis作为辅助插件来实现。如果Redis服务不可用,那Netty和Hessian会采用轮循式方式进行广播发送
1)服务端和调用端读取配置文件,初始化RedisSentinelPoolFactory里的JedisSentinelPool
2)服务端从JedisSentinelPool获取Jedis对象,启动订阅(Subscribe)阻塞式线程,一旦连接到Redis的连接断掉,阻塞式线程结束,并发起重连,再次进入阻塞时线程,直到连接成功
3)调用端从JedisSentinelPool获取Jedis对象,通过线程池启动发布(Publish)线程
4)对于订阅/发布的通道(Channel)名称是 group + "/" + application + "/" + interfaze,防止不同类型的应用,重名接口接入到同一个Redis服务器
3.2 类结构
哨兵实现,用于发布/订阅
1)RedisHierachy.java - Redis结构
2)RedisPublisher.java - 继承RedisHierachy.java,实现发布功能
3)RedisSubscriber.java - 继承RedisHierachy.java,实现订阅功能
4)RedisSentinelPoolFactory.java - JedisSentinelPool连接池工厂类
5)RedisDestinationUtil.java - RedisDestination工具类
集群实现
6)RedisClusterFactory - Redis集群工厂类
相关推荐
Nepxion Thunder是一个基于Java的分布式RPC框架,集成了Netty、Hessian、Kafka、ActiveMQ、Tibco、Zookeeper、Redis、Spring Web MVC、Spring Boot和Docker等技术。它支持多协议、多组件和多序列化,为开发者提供了...
Coroutine是基于Kilim/Promise JDeferred的协程式驱动框架,基于Apache Zookeeper的分布式规则存储和动态规则变更通知。 主要特性: 1. 基于微服务框架理念设计 2. 支持同步/异步调用 3. 支持串行/并行调用 4....
Nepxion Thunder是一款基于Netty + Hessian + Kafka + ActiveMQ + Tibco + Zookeeper(Curator Framework) + Redis + FST + Spring + Spring Web MVC + Spring Boot + Docker分布式RPC调用框架。架构思想主要是来自...
yinheli/docker-thunder-xware:latest 镜像打包下载 群晖 NAS DSM 系统,只要三步使用 Docker 安装迅雷远程下载
在压缩包"thunder-master"中,包含了Thunder框架的源码和其他相关资源。开发者可以通过查看源码,了解其内部实现原理,也可以直接使用它来快速搭建自己的GraphQL服务。在实际开发过程中,结合Go语言的标准库和第三方...
该项目是一款基于Kilim、Promise JDeferred、Zookeeper和Spring Boot技术的协程驱动分布式...该框架支持Nepxion Thunder、Dubbo和Motan等RPC调用的集成,并通过规则配置实现调用聚合,适用于构建高性能的分布式系统。
wine-thunder_0.6-2_all.deb用于在linux系统下,使用wine直接按装的迅雷软件,实现高速下载,在ubunut,fedora等linux版本中,实现直接点击安装
"thunder-master"这个压缩包子文件名可能代表项目的主分支或主代码库,这在Git等版本控制系统中很常见,"master"通常指的是默认分支,存放着项目的最新稳定版本。解压后,用户可以访问到项目的源代码、文档、构建...
Go-Thunder是一个基于BoltDB数据库的交互式Shell工具,主要设计用于方便地与BoltDB数据库进行交互,提供了一种命令行界面来操作和管理数据。BoltDB本身是Go语言实现的一个轻量级、文件存储的键值对数据库,它以其...
【压缩包子文件的文件名称列表】"thunder-oms" 这个文件名可能代表“Thunder Operation Management System”(迅雷运营管理系统),或者是一种特定的模块或服务。它可能包含了项目的源代码、配置文件、测试脚本等,...
A10-Thunder_1030S方案白皮书.pdf
标题中的“系统工具-文件下载-thunder_3.4.0.4338.zip”表明这是一款系统工具,具体来说是与文件下载相关的。这里的“thunder”很可能指的是迅雷,一个在中国广为人知的下载管理软件。版本号“3.4.0.4338”指示这是...
在使用Thunder时,用户应首先下载并解压“muesli-thunder.zip”文件,得到“thunder-master”目录。然后按照项目提供的安装指南编译并安装Thunder,最后通过命令行启动Thunder,开始探索和操作BoltDB数据库。对于...
A10-Thunder_6430S方案白皮书.pdf
3D-Thunder-Lightning.zip,受航母指令启发的开源未来动作飞行模拟器游戏,3D建模使用专门的软件来创建物理对象的数字模型。它是3D计算机图形的一个方面,用于视频游戏,3D打印和VR,以及其他应用程序。
A10 Thunder 930还提供了多项高级功能,包括GSLB、aFlex流量控制和aXAPI管理等,可以对各种应用进行优化,支持Microsoft、SFDA、cnyL、egnahcxE、tnioPerahSOracle、DNS等等。同时,A10 Thunder 930也提供了经济有效...
docker pull yinheli/docker-thunder-xware:latest 创建一个下载目录. 用于挂载卷 mkdir data 运行 docker run -d \ --name=xware \ --net=host \ -v $(pwd)/data:/app/TDDOWNLOAD \ yinheli/docker-thunder-...
通过负载均衡,Thunder 5430S能够有效地分散用户请求到多个后端服务器,避免单点故障,同时确保服务质量(QoS)。 负载均衡技术主要包括以下几大核心概念: 1. **会话亲和性**:保证特定用户的请求总是被定向到...
Thunderbird是一款由Mozilla基金会开发的开源邮件客户端,它集成了电子邮件、新闻组、RSS阅读器和日历功能,为用户提供了一站式的通信解决方案。Thunderbird91.0b4是该软件的一个版本,其中“91.0b4”表示的是版本号...
Thunder Android OkHttp util package let response callback at MainThread(UIThread), also it‘s lifecycle safety. ⚠️ Thunder‘s code is based on SugarTask(Very nice code